Author: jonpryor
Date: 2007-05-29 07:37:33 -0400 (Tue, 29 May 2007)
New Revision: 78109
Modified:
trunk/monodoc/tools/ChangeLog
trunk/monodoc/tools/monodocer.cs
Log:
* monodocer.cs: Invert ECMA documentation importing -- instead of
iterating
over the monodoc XML and importing ECMA docs as encountered
(randomly),
iterate over the ECMA docs in-order and access the monodoc types
randomly.
This significantly improves access as the ECMA docs are ~7.2MB in
size,
while the monodoc XML types 10's-100's of KB (randomly accessing a
7.2 MB
XML document == BAD; randomly accessing a several hundred KB document
is
better). This cuts down a -type:System.Array import from ~4 minutes
to
< ~20s. Alas, it appears to miss a few members as well, so it's not
done.
Modified: trunk/monodoc/tools/ChangeLog
===================================================================
--- trunk/monodoc/tools/ChangeLog 2007-05-29 11:23:57 UTC (rev 78108)
+++ trunk/monodoc/tools/ChangeLog 2007-05-29 11:37:33 UTC (rev 78109)
@@ -1,3 +1,14 @@
+2007-05-29 Jonathan Pryor <[EMAIL PROTECTED]>
+
+ * monodocer.cs: Invert ECMA documentation importing -- instead of
iterating
+ over the monodoc XML and importing ECMA docs as encountered
(randomly),
+ iterate over the ECMA docs in-order and access the monodoc types
randomly.
+ This significantly improves access as the ECMA docs are ~7.2MB in
size,
+ while the monodoc XML types 10's-100's of KB (randomly accessing a
7.2 MB
+ XML document == BAD; randomly accessing a several hundred KB document
is
+ better). This cuts down a -type:System.Array import from ~4 minutes
to
+ < ~20s. Alas, it appears to miss a few members as well, so it's not
done.
+
2007-05-19 Jonathan Pryor <[EMAIL PROTECTED]>
* monodocer.cs: Create diff(1)-friendly output for -importecmadocs.
Modified: trunk/monodoc/tools/monodocer.cs
===================================================================
--- trunk/monodoc/tools/monodocer.cs 2007-05-29 11:23:57 UTC (rev 78108)
+++ trunk/monodoc/tools/monodocer.cs 2007-05-29 11:37:33 UTC (rev 78109)
@@ -319,16 +319,44 @@
throw new InvalidOperationException("Error loading " +
typefile + ": " + e.Message, e);
}
+ XmlNode ecmaDocsType = GetEcmaDocsType (basefile);
if (dest == null) {
- DoUpdateType2(basefile, type, typefile);
+ DoUpdateType2(basefile, type, typefile, ecmaDocsType);
} else if (dest == "-") {
- DoUpdateType2(basefile, type, null);
+ DoUpdateType2(basefile, type, null, ecmaDocsType);
} else {
- DoUpdateType2(basefile, type, dest + "/" +
type.Namespace + "/" + typename2 + ".xml");
+ DoUpdateType2(basefile, type, dest + "/" +
type.Namespace + "/" + typename2 + ".xml", ecmaDocsType);
}
}
+ private static XmlNode GetEcmaDocsType (XmlNode source)
+ {
+ return GetEcmaDocsMember ("//[EMAIL PROTECTED]"{0}\"]", source,
"//Type/@FullName");
+ }
+
+ private static XmlNode GetEcmaDocsType (Type type)
+ {
+ return GetEcmaDocsMember ("//[EMAIL PROTECTED]"" +
type.FullName + "\"]");
+ }
+ private static XmlNode GetEcmaDocsMember (string xpathFormat, XmlNode
source, params string[] args)
+ {
+ if (ecmadocs == null)
+ return null;
+ string [] nargs = new string [args.Length];
+ for (int i = 0; i < nargs.Length; ++i) {
+ nargs [i] = source.SelectSingleNode (args [i]).Value;
+ }
+ return ecmadocs.SelectSingleNode (string.Format (xpathFormat,
nargs));
+ }
+
+ private static XmlNode GetEcmaDocsMember (string xpath)
+ {
+ if (ecmadocs == null)
+ return null;
+ return ecmadocs.SelectSingleNode (xpath);
+ }
+
public static void DoUpdateNS(string ns, string nspath, string outpath)
{
Hashtable seenTypes = new Hashtable();
Assembly assembly = assemblies [0];
@@ -352,7 +380,7 @@
}
seenTypes[type] = seenTypes;
- DoUpdateType2(basefile, type, outpath + "/" +
file.Name);
+ DoUpdateType2(basefile, type, outpath + "/" +
file.Name, GetEcmaDocsType (basefile));
}
// Stub types not in the directory
@@ -361,7 +389,7 @@
if (type.Namespace != ns || seenTypes.ContainsKey(type))
continue;
- XmlElement td = StubType(type);
+ XmlElement td = StubType(type, GetEcmaDocsType (type));
if (td == null) continue;
Console.Error.WriteLine("New Type: " + type.FullName);
@@ -487,10 +515,10 @@
throw new
InvalidOperationException("Error loading " + typefile + ": " + e.Message, e);
}
- DoUpdateType2(basefile, type, dest + "/" +
type.Namespace + "/" + typename + ".xml");
+ DoUpdateType2(basefile, type, dest + "/" +
type.Namespace + "/" + typename + ".xml", GetEcmaDocsType (basefile));
} else {
// Stub
- XmlElement td = StubType(type);
+ XmlElement td = StubType(type, GetEcmaDocsType
(type));
if (td == null) continue;
System.IO.DirectoryInfo dir = new
System.IO.DirectoryInfo(dest + "/" + type.Namespace);
@@ -576,20 +604,21 @@
}
}
- public static void DoUpdateType2(XmlDocument basefile, Type type,
string output) {
+ public static void DoUpdateType2(XmlDocument basefile, Type type,
string output, XmlNode ecmaDocsType) {
Console.Error.WriteLine("Updating: " + type.FullName);
Hashtable seenmembers = new Hashtable();
// Update type metadata
- UpdateType(basefile.DocumentElement, type, false);
+ UpdateType(basefile.DocumentElement, type, false, ecmaDocsType);
// Update existing members. Delete member nodes that no longer
should be there,
// and remember what members are already documented so we don't
add them again.
if (!ignoremembers) {
ArrayList todelete = new ArrayList ();
- foreach (XmlElement oldmember in
basefile.SelectNodes("Type/Members/Member")) {
- MemberInfo oldmember2 = GetMember(type,
oldmember);
+ foreach (DocsNodeInfo info in GetMembers (basefile,
type, ecmaDocsType)) {
+ XmlElement oldmember = info.Node;
+ MemberInfo oldmember2 = info.Member;
string sig = oldmember2 != null ?
MakeMemberSignature(oldmember2) : null;
// Interface implementations and overrides are
deleted from the docs
@@ -620,7 +649,7 @@
}
// Update signature information
- UpdateMember(oldmember, oldmember2);
+ UpdateMember(info);
seenmembers[sig] = 1;
}
@@ -673,6 +702,41 @@
WriteXml(basefile.DocumentElement, writer);
writer.Close();
}
+
+ private static
+#if NET_1_0
+ IEnumerable
+#else
+ IEnumerable<DocsNodeInfo>
+#endif
+ GetMembers (XmlDocument basefile, Type type, XmlNode
ecmaDocsType)
+ {
+ if (ecmadocs == null) {
+ foreach (XmlElement oldmember in
basefile.SelectNodes("Type/Members/Member"))
+ yield return new DocsNodeInfo (oldmember,
GetMember (type, oldmember));
+ }
+ else {
+ foreach (XmlElement ecmaDocsMember in
ecmaDocsType.SelectNodes ("Members/Member")) {
+ string xp = GetXPathForMember (ecmaDocsMember);
+ XmlElement oldmember = (XmlElement)
basefile.SelectSingleNode (xp);
+ MemberInfo m;
+ if (oldmember == null) {
+ m = GetMember (type, ecmaDocsMember);
+ if (m == null) {
+ Console.Error.WriteLine ("Could
not import ECMA docs for {1}'s `{0}': MemberInfo not found.",
+
ecmaDocsMember.SelectSingleNode ("[EMAIL PROTECTED]"C#\"]/@Value").Value,
type.FullName);
+ continue;
+ }
+ oldmember = (XmlElement) CopyNode
(ecmaDocsMember, basefile.SelectSingleNode ("/Types/Members"));
+ }
+ else
+ m = GetMember (type, oldmember);
+ DocsNodeInfo node = new DocsNodeInfo
(oldmember, m);
+ node.EcmaDocs = ecmaDocsMember.SelectSingleNode
("Docs");
+ yield return node;
+ }
+ }
+ }
private static bool MemberDocsHaveUserContent(XmlElement e) {
e = (XmlElement)e.SelectSingleNode("Docs");
@@ -776,14 +840,14 @@
// CREATE A STUB DOCUMENTATION FILE
- public static XmlElement StubType(Type type) {
+ public static XmlElement StubType(Type type, XmlNode ecmaDocsType) {
string typesig = MakeTypeSignature(type);
if (typesig == null) return null; // not publicly visible
XmlDocument doc = new XmlDocument();
XmlElement root = doc.CreateElement("Type");
- UpdateType(root, type, true);
+ UpdateType(root, type, true, ecmaDocsType);
if (since != null) {
XmlNode docs = root.SelectSingleNode("Docs");
@@ -802,7 +866,7 @@
// STUBBING/UPDATING FUNCTIONS
- public static void UpdateType(XmlElement root, Type type, bool
addmembers) {
+ public static void UpdateType(XmlElement root, Type type, bool
addmembers, XmlNode ecmaDocsType) {
root.SetAttribute("Name", GetDocTypeName (type));
root.SetAttribute("FullName", GetDocTypeFullName (type));
@@ -948,7 +1012,9 @@
#endif
}
- private static void UpdateMember(XmlElement me, MemberInfo mi) {
+ private static void UpdateMember(DocsNodeInfo info) {
+ XmlElement me = (XmlElement) info.Node;
+ MemberInfo mi = info.Member;
WriteElementAttribute(me, "[EMAIL PROTECTED]'C#']", "Language",
"C#");
WriteElementAttribute(me, "[EMAIL PROTECTED]'C#']", "Value",
MakeMemberSignature(mi));
@@ -962,7 +1028,8 @@
if (mi is FieldInfo && GetFieldConstValue((FieldInfo)mi, out
fieldValue))
WriteElementText(me, "MemberValue", fieldValue);
- MakeDocNode (new DocsNodeInfo (WriteElement (me, "Docs"), mi));
+ info.Node = WriteElement (me, "Docs");
+ MakeDocNode (info);
}
private static bool GetFieldConstValue(FieldInfo field, out string
value) {
@@ -1010,10 +1077,11 @@
node.InnerText = value;
}
- private static void CopyNode (XmlNode source, XmlNode dest)
+ private static XmlNode CopyNode (XmlNode source, XmlNode dest)
{
XmlNode copy = dest.OwnerDocument.ImportNode (source, true);
dest.AppendChild (copy);
+ return copy;
}
private static void WriteElementInitialText(XmlElement parent, string
element, string value) {
@@ -1457,7 +1525,7 @@
XmlElement me = doc.CreateElement("Member");
me.SetAttribute("MemberName", GetMemberName (mi));
- UpdateMember(me, mi);
+ UpdateMember(new DocsNodeInfo (me, mi));
if (since != null) {
XmlNode docs = me.SelectSingleNode("Docs");
@@ -1544,6 +1612,17 @@
public DocsNodeInfo (XmlElement node, Type type)
: this (node)
{
+ SetType (type);
+ }
+
+ public DocsNodeInfo (XmlElement node, MemberInfo member)
+ : this (node)
+ {
+ SetMemberInfo (member);
+ }
+
+ public void SetType (Type type)
+ {
GenericParameters = DocUtils.GetGenericArguments (type);
if (type.DeclaringType != null) {
Type[] declGenParams =
DocUtils.GetGenericArguments (type.DeclaringType);
@@ -1563,14 +1642,13 @@
ReturnType =
type.GetMethod("Invoke").ReturnType;
}
SetSlashDocs (type);
- SetEcmaDocs (type);
}
- public DocsNodeInfo (XmlElement node, MemberInfo member)
- : this (node)
+ public void SetMemberInfo (MemberInfo member)
{
ReturnIsReturn = true;
AddRemarks = true;
+ Member = member;
if (member is MethodInfo || member is ConstructorInfo) {
Parameters = ((MethodBase)
member).GetParameters ();
@@ -1596,58 +1674,18 @@
if (member.DeclaringType != null &&
member.DeclaringType.IsEnum)
AddRemarks = false;
SetSlashDocs (member);
- SetEcmaDocs (member);
}
private void SetSlashDocs (MemberInfo member)
{
+ if (slashdocs == null)
+ return;
+
string slashdocsig = slashdocFormatter.GetDeclaration
(member);
- if (slashdocs != null && slashdocsig != null)
+ if (slashdocsig != null)
SlashDocs = slashdocs.SelectSingleNode
("doc/members/[EMAIL PROTECTED]'" + slashdocsig + "']");
}
- private void SetEcmaDocs (MemberInfo member)
- {
- if (ecmadocs == null)
- return;
-
- string xpath;
-
- if (member is Type) {
- xpath = "//[EMAIL PROTECTED]"" +
GetDocTypeFullName ((Type) member)+ "\"]/Docs";
- }
- else {
- // Create e.g.:
- // //Members/[EMAIL
PROTECTED]"CopyTo"]/Parameters[count(Parameter) = 2
- // and Parameter[1]/@Type="System.Array" and
- // Parameter[2]/@Type="System.Int64"]/../Docs'
- StringBuilder sb = new StringBuilder ();
- sb.Append ("//[EMAIL PROTECTED]"")
- .Append (GetDocTypeFullName
(member.DeclaringType))
- .Append ("\"]");
- sb.Append ("/Members/[EMAIL PROTECTED]"");
- if (member is ConstructorInfo)
- sb.Append (".ctor");
- else
- sb.Append (GetMemberName (member));
- sb.Append ("\"]");
- if (member is MethodBase) {
- sb.Append ("/Parameters[");
- ParameterInfo[] parameters =
((MethodBase) member).GetParameters ();
- sb.Append ("count(Parameter) =
").Append (parameters.Length);
- for (int i = 0; i < parameters.Length;
++i) {
- sb.Append (" and
Parameter[").Append (i+1).Append ("]/@Type=\"")
- .Append
(GetDocTypeFullName (parameters [i].ParameterType))
- .Append ("\"");
- }
- sb.Append ("]/..");
- }
- sb.Append ("/Docs");
- xpath = sb.ToString ();
- }
- EcmaDocs = ecmadocs.SelectSingleNode (xpath);
- }
-
public Type ReturnType;
public Type[] GenericParameters;
public ParameterInfo[] Parameters;
@@ -1656,7 +1694,32 @@
public bool AddRemarks = true;
public XmlNode SlashDocs;
public XmlNode EcmaDocs;
+ public MemberInfo Member;
}
+
+ public static string GetXPathForMember (XmlNode member)
+ {
+ StringBuilder xpath = new StringBuilder ();
+ xpath.Append ("//[EMAIL PROTECTED]"")
+ .Append (member.SelectSingleNode
("../../@FullName").Value)
+ .Append ("\"]/");
+ xpath.Append ("Members/[EMAIL PROTECTED]"")
+ .Append (member.SelectSingleNode ("@MemberName").Value)
+ .Append ("\"]");
+ XmlNodeList parameters = member.SelectNodes
("Parameters/Parameter");
+ if (parameters.Count > 0) {
+ xpath.Append ("/Parameters[count(Parameter) = ")
+ .Append (parameters.Count);
+ for (int i = 0; i < parameters.Count; ++i) {
+ xpath.Append (" and Parameter [").Append
(i+1).Append ("]/@Type=\"");
+ xpath.Append (member.SelectSingleNode (
+ "Parameters/Parameter["
+ (i+1) + "]/@Type").Value);
+ xpath.Append ("\"");
+ }
+ xpath.Append ("]/..");
+ }
+ return xpath.ToString ();
+ }
}
static class DocUtils {
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches