Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/api-doc-tools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'mdoc/Mono.Documentation/Updater/EcmaDocumentationEnumerator.cs')
-rw-r--r--mdoc/Mono.Documentation/Updater/EcmaDocumentationEnumerator.cs169
1 files changed, 169 insertions, 0 deletions
diff --git a/mdoc/Mono.Documentation/Updater/EcmaDocumentationEnumerator.cs b/mdoc/Mono.Documentation/Updater/EcmaDocumentationEnumerator.cs
new file mode 100644
index 00000000..86cce337
--- /dev/null
+++ b/mdoc/Mono.Documentation/Updater/EcmaDocumentationEnumerator.cs
@@ -0,0 +1,169 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Xml;
+
+using Mono.Cecil;
+
+using Mono.Documentation.Util;
+
+namespace Mono.Documentation.Updater
+{
+ class EcmaDocumentationEnumerator : DocumentationEnumerator
+ {
+
+ XmlReader ecmadocs;
+ MDocUpdater app;
+
+ public EcmaDocumentationEnumerator (MDocUpdater app, XmlReader ecmaDocs)
+ {
+ this.app = app;
+ this.ecmadocs = ecmaDocs;
+ }
+
+ public override IEnumerable<TypeDefinition> GetDocumentationTypes (AssemblyDefinition assembly, List<string> forTypes)
+ {
+ HashSet<string> seen = new HashSet<string> ();
+ return GetDocumentationTypes (assembly, forTypes, seen)
+ .Concat (base.GetDocumentationTypes (assembly, forTypes, seen));
+ }
+
+ new IEnumerable<TypeDefinition> GetDocumentationTypes (AssemblyDefinition assembly, List<string> forTypes, HashSet<string> seen)
+ {
+ int typeDepth = -1;
+ while (ecmadocs.Read ())
+ {
+ switch (ecmadocs.Name)
+ {
+ case "Type":
+ {
+ if (typeDepth == -1)
+ typeDepth = ecmadocs.Depth;
+ if (ecmadocs.NodeType != XmlNodeType.Element)
+ continue;
+ if (typeDepth != ecmadocs.Depth) // nested <TypeDefinition/> element?
+ continue;
+ string typename = ecmadocs.GetAttribute ("FullName");
+ string typename2 = MDocUpdater.GetTypeFileName (typename);
+ if (forTypes != null &&
+ forTypes.BinarySearch (typename) < 0 &&
+ typename != typename2 &&
+ forTypes.BinarySearch (typename2) < 0)
+ continue;
+ TypeDefinition t;
+ if ((t = assembly.GetType (typename)) == null &&
+ (t = assembly.GetType (typename2)) == null)
+ continue;
+ seen.Add (typename);
+ if (typename != typename2)
+ seen.Add (typename2);
+ Console.WriteLine (" Import: {0}", t.FullName);
+ if (ecmadocs.Name != "Docs")
+ {
+ int depth = ecmadocs.Depth;
+ while (ecmadocs.Read ())
+ {
+ if (ecmadocs.Name == "Docs" && ecmadocs.Depth == depth + 1)
+ break;
+ }
+ }
+ if (!ecmadocs.IsStartElement ("Docs"))
+ throw new InvalidOperationException ("Found " + ecmadocs.Name + "; expecting <Docs/>!");
+ yield return t;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+
+ public override IEnumerable<DocsNodeInfo> GetDocumentationMembers (XmlDocument basefile, TypeDefinition type)
+ {
+ return GetMembers (basefile, type)
+ .Concat (base.GetDocumentationMembers (basefile, type));
+ }
+
+ private IEnumerable<DocsNodeInfo> GetMembers (XmlDocument basefile, TypeDefinition type)
+ {
+ while (ecmadocs.Name != "Members" && ecmadocs.Read ())
+ {
+ // do nothing
+ }
+ if (ecmadocs.IsEmptyElement)
+ yield break;
+
+ int membersDepth = ecmadocs.Depth;
+ bool go = true;
+ while (go && ecmadocs.Read ())
+ {
+ switch (ecmadocs.Name)
+ {
+ case "Member":
+ {
+ if (membersDepth != ecmadocs.Depth - 1 || ecmadocs.NodeType != XmlNodeType.Element)
+ continue;
+ DocumentationMember dm = new DocumentationMember (ecmadocs);
+
+ string xp = MDocUpdater.GetXPathForMember (dm);
+ XmlElement oldmember = (XmlElement)basefile.SelectSingleNode (xp);
+ MemberReference m;
+ if (oldmember == null)
+ {
+ m = GetMember (type, dm);
+ if (m == null)
+ {
+ app.Warning ("Could not import ECMA docs for `{0}'s `{1}': Member not found.",
+ type.FullName, dm.MemberSignatures["C#"]);
+ // SelectSingleNode (ecmaDocsMember, "MemberSignature[@Language=\"C#\"]/@Value").Value);
+ continue;
+ }
+ // oldmember lookup may have failed due to type parameter renames.
+ // Try again.
+ oldmember = (XmlElement)basefile.SelectSingleNode (MDocUpdater.GetXPathForMember (m));
+ if (oldmember == null)
+ {
+ XmlElement members = MDocUpdater.WriteElement (basefile.DocumentElement, "Members");
+ oldmember = basefile.CreateElement ("Member");
+ oldmember.SetAttribute ("MemberName", dm.MemberName);
+ members.AppendChild (oldmember);
+ foreach (string key in MDocUpdater.Sort (dm.MemberSignatures.Keys))
+ {
+ XmlElement ms = basefile.CreateElement ("MemberSignature");
+ ms.SetAttribute ("Language", key);
+ ms.SetAttribute ("Value", (string)dm.MemberSignatures[key]);
+ oldmember.AppendChild (ms);
+ }
+ oldmember.SetAttribute ("__monodocer-seen__", "true");
+ Console.WriteLine ("Member Added: {0}", oldmember.SelectSingleNode ("MemberSignature[@Language='C#']/@Value").InnerText);
+ app.additions++;
+ }
+ }
+ else
+ {
+ m = GetMember (type, new DocumentationMember (oldmember));
+ if (m == null)
+ {
+ app.Warning ("Could not import ECMA docs for `{0}'s `{1}': Member not found.",
+ type.FullName, dm.MemberSignatures["C#"]);
+ continue;
+ }
+ oldmember.SetAttribute ("__monodocer-seen__", "true");
+ }
+ DocsNodeInfo node = new DocsNodeInfo (oldmember, m);
+ if (ecmadocs.Name != "Docs")
+ throw new InvalidOperationException ("Found " + ecmadocs.Name + "; expected <Docs/>!");
+ yield return node;
+ break;
+ }
+ case "Members":
+ if (membersDepth == ecmadocs.Depth && ecmadocs.NodeType == XmlNodeType.EndElement)
+ {
+ go = false;
+ }
+ break;
+ }
+ }
+ }
+ }
+} \ No newline at end of file