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:
authorJoel Martinez <joelmartinez@gmail.com>2017-09-28 23:20:38 +0300
committerJoel Martinez <joelmartinez@gmail.com>2017-10-02 23:41:00 +0300
commit8822f7729c04ba22acbe9a9f1141d181ed725b6a (patch)
tree83f3e3c99e6cca9a1080c003e5c273e86eb1be8a /mdoc/Mono.Documentation/Updater/Frameworks
parente7b7f22e6a82a7ec02962b8a18700fe4616839df (diff)
mdoc: reformatting the MDocUpdater source code.
We are changing our coding standards, and starting with the update subcommand. This moves many classes into their own code files and namespaces to better organize the source code.
Diffstat (limited to 'mdoc/Mono.Documentation/Updater/Frameworks')
-rw-r--r--mdoc/Mono.Documentation/Updater/Frameworks/AssemblySet.cs111
-rw-r--r--mdoc/Mono.Documentation/Updater/Frameworks/FrameworkEntry.cs52
-rw-r--r--mdoc/Mono.Documentation/Updater/Frameworks/FrameworkIndex.cs91
-rw-r--r--mdoc/Mono.Documentation/Updater/Frameworks/FrameworkTypeEntry.cs80
-rw-r--r--mdoc/Mono.Documentation/Updater/Frameworks/UwpResolver.cs25
5 files changed, 359 insertions, 0 deletions
diff --git a/mdoc/Mono.Documentation/Updater/Frameworks/AssemblySet.cs b/mdoc/Mono.Documentation/Updater/Frameworks/AssemblySet.cs
new file mode 100644
index 00000000..524e39a7
--- /dev/null
+++ b/mdoc/Mono.Documentation/Updater/Frameworks/AssemblySet.cs
@@ -0,0 +1,111 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Mono.Cecil;
+
+namespace Mono.Documentation.Updater.Frameworks
+{
+ /// <summary>
+ /// Represents a set of assemblies that we want to document
+ /// </summary>
+ class AssemblySet : IDisposable
+ {
+ readonly DefaultAssemblyResolver resolver = new Frameworks.UwpResolver ();
+ HashSet<string> assemblyPaths = new HashSet<string> ();
+ HashSet<string> assemblySearchPaths = new HashSet<string> ();
+ HashSet<string> forwardedTypes = new HashSet<string> ();
+ IEnumerable<string> importPaths;
+ public IEnumerable<DocumentationImporter> Importers { get; private set; }
+
+ public AssemblySet (IEnumerable<string> paths) : this ("Default", paths, new string[0], null) { }
+
+ public AssemblySet (string name, IEnumerable<string> paths, IEnumerable<string> resolverSearchPaths, IEnumerable<string> imports)
+ {
+ Name = name;
+
+ foreach (var path in paths)
+ assemblyPaths.Add (path);
+
+ // add default search paths
+ var assemblyDirectories = paths
+ .Where (p => p.Contains (Path.DirectorySeparatorChar))
+ .Select (p => Path.GetDirectoryName (p));
+
+ foreach (var searchPath in resolverSearchPaths.Union (assemblyDirectories))
+ assemblySearchPaths.Add (searchPath);
+
+ char oppositeSeparator = Path.DirectorySeparatorChar == '/' ? '\\' : '/';
+ Func<string, string> sanitize = p =>
+ p.Replace (oppositeSeparator, Path.DirectorySeparatorChar);
+
+ foreach (var searchPath in assemblySearchPaths.Select (sanitize))
+ resolver.AddSearchDirectory (searchPath);
+
+ this.importPaths = imports;
+ if (this.importPaths != null)
+ {
+ this.Importers = this.importPaths.Select (p => MDocUpdater.Instance.GetImporter (p, supportsEcmaDoc: false));
+ }
+ else
+ this.Importers = new DocumentationImporter[0];
+ }
+
+ public string Name { get; private set; }
+
+ public IEnumerable<AssemblyDefinition> Assemblies { get { return this.LoadAllAssemblies ().Where(a => a != null); } }
+ public IEnumerable<string> AssemblyPaths { get { return this.assemblyPaths; } }
+
+ /// <summary>Adds all subdirectories to the search directories for the resolver to look in.</summary>
+ public void RecurseSearchDirectories()
+ {
+ var directories = resolver
+ .GetSearchDirectories ()
+ .Select(d => new DirectoryInfo (d))
+ .Where (d => d.Exists)
+ .Select(d => d.FullName)
+ .ToDictionary(d => d, d => d);
+
+ var subdirs = directories.Keys
+ .SelectMany (d => Directory.GetDirectories (d, ".", SearchOption.AllDirectories))
+ .Where (d => !directories.ContainsKey (d));
+
+ foreach (var dir in subdirs)
+ resolver.AddSearchDirectory (dir);
+ }
+
+ /// <returns><c>true</c>, if in set was contained in the set of assemblies, <c>false</c> otherwise.</returns>
+ /// <param name="name">An assembly file name</param>
+ public bool Contains (string name)
+ {
+ return assemblyPaths.Any (p => Path.GetFileName (p) == name);
+ }
+
+ /// <summary>Tells whether an already enumerated AssemblyDefinition, contains the type.</summary>
+ /// <param name="name">Type name</param>
+ public bool ContainsForwardedType (string name)
+ {
+ return forwardedTypes.Contains (name);
+ }
+
+ public void Dispose () => resolver.Dispose ();
+
+ public override string ToString ()
+ {
+ return string.Format ("[AssemblySet: Name={0}, Assemblies={1}]", Name, assemblyPaths.Count);
+ }
+
+ IEnumerable<AssemblyDefinition> LoadAllAssemblies ()
+ {
+ foreach (var path in this.assemblyPaths) {
+ var assembly = MDocUpdater.Instance.LoadAssembly (path, this.resolver);
+ if (assembly != null) {
+ foreach (var type in assembly.MainModule.ExportedTypes.Where (t => t.IsForwarder).Select (t => t.FullName))
+ forwardedTypes.Add (type);
+ }
+ yield return assembly;
+ }
+ }
+ }
+}
diff --git a/mdoc/Mono.Documentation/Updater/Frameworks/FrameworkEntry.cs b/mdoc/Mono.Documentation/Updater/Frameworks/FrameworkEntry.cs
new file mode 100644
index 00000000..c6684d51
--- /dev/null
+++ b/mdoc/Mono.Documentation/Updater/Frameworks/FrameworkEntry.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Mono.Cecil;
+using Mono.Cecil.Rocks;
+
+namespace Mono.Documentation.Updater.Frameworks
+{
+ class FrameworkEntry
+ {
+ SortedSet<FrameworkTypeEntry> types = new SortedSet<FrameworkTypeEntry> ();
+
+ List<FrameworkEntry> allframeworks;
+
+ public FrameworkEntry (List<FrameworkEntry> frameworks)
+ {
+ allframeworks = frameworks;
+ if (allframeworks == null)
+ allframeworks = new List<FrameworkEntry> (0);
+ }
+
+ public string Name { get; set; }
+
+ public IEnumerable<DocumentationImporter> Importers { get; set; }
+
+ public ISet<FrameworkTypeEntry> Types { get { return this.types; } }
+
+ public IEnumerable<FrameworkEntry> Frameworks { get { return this.allframeworks; } }
+
+ public static readonly FrameworkEntry Empty = new EmptyFrameworkEntry () { Name = "Empty" };
+
+ public virtual FrameworkTypeEntry ProcessType (TypeDefinition type)
+ {
+
+ var entry = types.FirstOrDefault (t => t.Name.Equals (type.FullName));
+ if (entry == null) {
+ var docid = DocCommentId.GetDocCommentId (type);
+ entry = new FrameworkTypeEntry (this) { Id = docid, Name = type.FullName, Namespace = type.Namespace };
+ types.Add (entry);
+ }
+ return entry;
+ }
+
+ public override string ToString () => this.Name;
+
+ class EmptyFrameworkEntry : FrameworkEntry
+ {
+ public EmptyFrameworkEntry () : base (null) { }
+ public override FrameworkTypeEntry ProcessType (TypeDefinition type) { return FrameworkTypeEntry.Empty; }
+ }
+ }
+}
diff --git a/mdoc/Mono.Documentation/Updater/Frameworks/FrameworkIndex.cs b/mdoc/Mono.Documentation/Updater/Frameworks/FrameworkIndex.cs
new file mode 100644
index 00000000..e392f585
--- /dev/null
+++ b/mdoc/Mono.Documentation/Updater/Frameworks/FrameworkIndex.cs
@@ -0,0 +1,91 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Xml;
+using System.Xml.Linq;
+
+using Mono.Cecil;
+
+namespace Mono.Documentation.Updater.Frameworks
+{
+
+ class FrameworkIndex
+ {
+ List<FrameworkEntry> frameworks = new List<FrameworkEntry> ();
+ string path;
+
+ public FrameworkIndex (string pathToFrameworks)
+ {
+ path = pathToFrameworks;
+ }
+
+ public IList<FrameworkEntry> Frameworks {
+ get {
+ return this.frameworks;
+ }
+ }
+
+ public FrameworkEntry StartProcessingAssembly (AssemblyDefinition assembly, IEnumerable<DocumentationImporter> importers)
+ {
+ if (string.IsNullOrWhiteSpace (this.path))
+ return FrameworkEntry.Empty;
+
+ string assemblyPath = assembly.MainModule.FileName;
+ var frameworksDirectory = this.path.EndsWith ("frameworks.xml", StringComparison.OrdinalIgnoreCase)
+ ? Path.GetDirectoryName (this.path) : this.path;
+ string relativePath = assemblyPath.Replace (frameworksDirectory, string.Empty);
+ string shortPath = Path.GetDirectoryName (relativePath);
+ if (shortPath.StartsWith (Path.DirectorySeparatorChar.ToString (), StringComparison.InvariantCultureIgnoreCase))
+ shortPath = shortPath.Substring (1, shortPath.Length - 1);
+
+
+ var entry = frameworks.FirstOrDefault (f => f.Name.Equals (shortPath));
+ if (entry == null) {
+ entry = new FrameworkEntry (frameworks) { Name = shortPath, Importers = importers };
+ frameworks.Add (entry);
+ }
+ return entry;
+ }
+
+ /// <summary>Writes the framework indices to disk.</summary>
+ /// <param name="path">The folder where one file for every FrameworkEntry will be written.</param>
+ public void WriteToDisk (string path)
+ {
+ if (string.IsNullOrWhiteSpace (this.path))
+ return;
+
+ string outputPath = Path.Combine (path, "FrameworksIndex");
+ if (!Directory.Exists (outputPath))
+ Directory.CreateDirectory (outputPath);
+
+ foreach (var fx in this.frameworks) {
+
+ XDocument doc = new XDocument (
+ new XElement("Framework",
+ new XAttribute ("Name", fx.Name),
+ fx.Types
+ .GroupBy(t => t.Namespace)
+ .Select(g => new XElement("Namespace",
+ new XAttribute("Name", g.Key),
+ g.Select (t => new XElement ("Type",
+ new XAttribute ("Name", t.Name),
+ new XAttribute("Id", t.Id),
+ t.Members.Select (m =>
+ new XElement ("Member",
+ new XAttribute ("Id", m)))))))));
+
+ // now save the document
+ string filePath = Path.Combine (outputPath, fx.Name + ".xml");
+
+ if (File.Exists (filePath))
+ File.Delete (filePath);
+
+ var settings = new XmlWriterSettings { Indent = true };
+ using (var writer = XmlWriter.Create (filePath, settings)) {
+ doc.WriteTo (writer);
+ }
+ }
+ }
+ }
+}
diff --git a/mdoc/Mono.Documentation/Updater/Frameworks/FrameworkTypeEntry.cs b/mdoc/Mono.Documentation/Updater/Frameworks/FrameworkTypeEntry.cs
new file mode 100644
index 00000000..67bcee86
--- /dev/null
+++ b/mdoc/Mono.Documentation/Updater/Frameworks/FrameworkTypeEntry.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Collections.Generic;
+using Mono.Cecil;
+using Mono.Cecil.Rocks;
+
+namespace Mono.Documentation.Updater.Frameworks
+{
+ class FrameworkTypeEntry : IComparable<FrameworkTypeEntry>
+ {
+ SortedSet<string> members = new SortedSet<string> ();
+ SortedSet<string> memberscsharpsig = new SortedSet<string> ();
+
+ ILFullMemberFormatter formatter = new ILFullMemberFormatter ();
+
+ FrameworkEntry fx;
+
+ public static FrameworkTypeEntry Empty = new EmptyTypeEntry (FrameworkEntry.Empty) { Name = "Empty" };
+
+ public FrameworkTypeEntry (FrameworkEntry fx)
+ {
+ this.fx = fx;
+ }
+
+ public string Id { get; set; }
+ public string Name { get; set; }
+ public string Namespace { get; set; }
+ public FrameworkEntry Framework { get { return fx; } }
+
+ public ISet<string> Members {
+ get {
+ return this.members;
+ }
+ }
+
+ public virtual void ProcessMember (MemberReference member)
+ {
+ var resolvedMember = member.Resolve ();
+ if (resolvedMember != null) {
+ var docid = DocCommentId.GetDocCommentId (resolvedMember);
+ members.Add (docid);
+ }
+ else
+ members.Add (member.FullName);
+
+ // this is for lookup purposes
+ try {
+ memberscsharpsig.Add(formatter.GetDeclaration(member));
+ }
+ catch {}
+ }
+
+ public bool ContainsCSharpSig (string sig)
+ {
+ return memberscsharpsig.Contains (sig);
+ }
+
+ public override string ToString () => $"{this.Name} in {this.fx.Name}";
+
+ public int CompareTo (FrameworkTypeEntry other)
+ {
+ if (other == null) return -1;
+ if (this.Name == null) return 1;
+
+ return string.Compare (this.Name, other.Name, StringComparison.CurrentCulture);
+ }
+
+ public override bool Equals (object obj)
+ {
+ FrameworkTypeEntry other = obj as FrameworkTypeEntry;
+ if (other == null) return false;
+ return this.Name.Equals (other.Name);
+ }
+
+ class EmptyTypeEntry : FrameworkTypeEntry
+ {
+ public EmptyTypeEntry (FrameworkEntry fx) : base (fx) { }
+ public override void ProcessMember (MemberReference member) { }
+ }
+ }
+}
diff --git a/mdoc/Mono.Documentation/Updater/Frameworks/UwpResolver.cs b/mdoc/Mono.Documentation/Updater/Frameworks/UwpResolver.cs
new file mode 100644
index 00000000..4dbbec82
--- /dev/null
+++ b/mdoc/Mono.Documentation/Updater/Frameworks/UwpResolver.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Microsoft.Win32;
+using Mono.Cecil;
+
+namespace Mono.Documentation.Updater.Frameworks
+{
+ /// <summary>Mono.Cecil resolver for the windows universal platform</summary>
+ class UwpResolver : DefaultAssemblyResolver
+ {
+ public override AssemblyDefinition Resolve (AssemblyNameReference name)
+ {
+ var ver = name.Version;
+ if (ver.Major == 255 && ver.Minor == 255 && ver.Revision == 255 && name.Name == "mscorlib")
+ {
+ var v = new Version (4, 5, 0);
+ var anr = new AssemblyNameReference (name.Name, v);
+ return base.Resolve (anr);
+ }
+ else
+ return base.Resolve (name);
+ }
+ }
+} \ No newline at end of file