diff options
author | Joel Martinez <joelmartinez@gmail.com> | 2017-11-17 22:56:43 +0300 |
---|---|---|
committer | Joel Martinez <joelmartinez@gmail.com> | 2017-11-17 23:20:35 +0300 |
commit | c81fe8a0d7b61aeb43f7ede411a0c6bc405c7ee5 (patch) | |
tree | 754b17cc68f2136ee0dc7977cb1ad1f6003e76cf | |
parent | fc2661c8c8662143c9d12f0b92eede9b40bad933 (diff) |
mdoc: Improved importer performance and error handling.
Closes #163.
5 files changed, 88 insertions, 54 deletions
diff --git a/mdoc/Mono.Documentation/MDocUpdater.cs b/mdoc/Mono.Documentation/MDocUpdater.cs index 915adfca..d8d61ab3 100644 --- a/mdoc/Mono.Documentation/MDocUpdater.cs +++ b/mdoc/Mono.Documentation/MDocUpdater.cs @@ -1398,7 +1398,7 @@ namespace Mono.Documentation var sigvalue = sigFromXml.GetAttribute ("Value"); Func<FrameworkEntry, bool> findTypes = fx => { - var tInstance = fx.Types.FirstOrDefault (t => t.Equals (typeEntry)); + var tInstance = fx.FindTypeEntry (typeEntry.Name); if (tInstance != null) { return tInstance.ContainsCSharpSig (sigvalue); diff --git a/mdoc/Mono.Documentation/Updater/Frameworks/AssemblySet.cs b/mdoc/Mono.Documentation/Updater/Frameworks/AssemblySet.cs index 28a46ce3..fd7934e4 100644 --- a/mdoc/Mono.Documentation/Updater/Frameworks/AssemblySet.cs +++ b/mdoc/Mono.Documentation/Updater/Frameworks/AssemblySet.cs @@ -7,69 +7,85 @@ using Mono.Cecil; namespace Mono.Documentation.Updater.Frameworks { - /// <summary> - /// Represents a set of assemblies that we want to document - /// </summary> - class AssemblySet : IDisposable - { + /// <summary> + /// Represents a set of assemblies that we want to document + /// </summary> + class AssemblySet : IDisposable + { readonly BaseAssemblyResolver resolver = new Frameworks.MDocResolver (); IAssemblyResolver cachedResolver; - HashSet<string> assemblyPaths = new HashSet<string> (); - HashSet<string> assemblySearchPaths = new HashSet<string> (); - HashSet<string> forwardedTypes = new HashSet<string> (); + HashSet<string> assemblyPaths = new HashSet<string> (); + Dictionary<string, bool> assemblyPathsMap = new Dictionary<string, bool> (); + HashSet<string> assemblySearchPaths = new HashSet<string> (); + HashSet<string> forwardedTypes = new HashSet<string> (); IEnumerable<string> importPaths; - public IEnumerable<DocumentationImporter> Importers { get; private set; } + public IEnumerable<DocumentationImporter> Importers { get; private set; } - public AssemblySet (IEnumerable<string> paths) : this ("Default", paths, new string[0], null) { } + 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) - { + { this.cachedResolver = new CachedResolver (this.resolver); - Name = name; + Name = name; - foreach (var path in paths) - assemblyPaths.Add (path); + foreach (var path in paths) + { + assemblyPaths.Add (path); + string pathName = Path.GetFileName (path); + if (!assemblyPathsMap.ContainsKey (pathName)) + assemblyPathsMap.Add (pathName, true); + } - // add default search paths - var assemblyDirectories = paths - .Where (p => p.Contains (Path.DirectorySeparatorChar)) - .Select (p => Path.GetDirectoryName (p)); + // 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); + foreach (var searchPath in resolverSearchPaths.Union (assemblyDirectories)) + assemblySearchPaths.Add (searchPath); - char oppositeSeparator = Path.DirectorySeparatorChar == '/' ? '\\' : '/'; - Func<string, string> sanitize = p => - p.Replace (oppositeSeparator, Path.DirectorySeparatorChar); + char oppositeSeparator = Path.DirectorySeparatorChar == '/' ? '\\' : '/'; + Func<string, string> sanitize = p => + p.Replace (oppositeSeparator, Path.DirectorySeparatorChar); - foreach (var searchPath in assemblySearchPaths.Select (sanitize)) - resolver.AddSearchDirectory (searchPath); + foreach (var searchPath in assemblySearchPaths.Select (sanitize)) + resolver.AddSearchDirectory (searchPath); - this.importPaths = imports; + this.importPaths = imports; if (this.importPaths != null) { - this.Importers = this.importPaths.Select (p => MDocUpdater.Instance.GetImporter (p, supportsEcmaDoc: false)); + this.Importers = this.importPaths.Select (p => MDocUpdater.Instance.GetImporter (p, supportsEcmaDoc: false)).ToArray (); } else this.Importers = new DocumentationImporter[0]; - } + } - public string Name { get; private set; } + 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; } } + IEnumerable<AssemblyDefinition> assemblies; + public IEnumerable<AssemblyDefinition> Assemblies + { + get + { + if (this.assemblies == null) + this.assemblies = this.LoadAllAssemblies ().Where (a => a != null).ToArray (); + + return this.assemblies; + } + } + 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() + public void RecurseSearchDirectories () { var directories = resolver .GetSearchDirectories () - .Select(d => new DirectoryInfo (d)) + .Select (d => new DirectoryInfo (d)) .Where (d => d.Exists) - .Select(d => d.FullName) + .Select (d => d.FullName) .Distinct () - .ToDictionary(d => d, d => d); + .ToDictionary (d => d, d => d); var subdirs = directories.Keys .SelectMany (d => Directory.GetDirectories (d, ".", SearchOption.AllDirectories)) @@ -79,21 +95,25 @@ namespace Mono.Documentation.Updater.Frameworks 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); - } + /// <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 assemblyPathsMap.ContainsKey (name);//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); - } + /// <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 () => cachedResolver.Dispose (); + public void Dispose () + { + this.assemblies = null; + cachedResolver.Dispose(); + } public override string ToString () { diff --git a/mdoc/Mono.Documentation/Updater/Frameworks/FrameworkEntry.cs b/mdoc/Mono.Documentation/Updater/Frameworks/FrameworkEntry.cs index bfda63e5..2df62fa0 100644 --- a/mdoc/Mono.Documentation/Updater/Frameworks/FrameworkEntry.cs +++ b/mdoc/Mono.Documentation/Updater/Frameworks/FrameworkEntry.cs @@ -24,6 +24,13 @@ namespace Mono.Documentation.Updater.Frameworks public IEnumerable<DocumentationImporter> Importers { get; set; } public ISet<FrameworkTypeEntry> Types { get { return this.types; } } + Dictionary<string, FrameworkTypeEntry> typeMap = new Dictionary<string, FrameworkTypeEntry> (); + + public FrameworkTypeEntry FindTypeEntry (string name) { + FrameworkTypeEntry entry; + typeMap.TryGetValue (name, out entry); + return entry; + } public IEnumerable<FrameworkEntry> Frameworks { get { return this.allframeworks; } } @@ -31,11 +38,14 @@ namespace Mono.Documentation.Updater.Frameworks public virtual FrameworkTypeEntry ProcessType (TypeDefinition type) { - var entry = types.FirstOrDefault (t => t.Name.Equals (type.FullName, StringComparison.Ordinal)); - if (entry == null) { + FrameworkTypeEntry entry; + + if (!typeMap.TryGetValue (type.FullName, out entry)) { var docid = DocCommentId.GetDocCommentId (type); entry = new FrameworkTypeEntry (this) { Id = docid, Name = type.FullName, Namespace = type.Namespace }; types.Add (entry); + + typeMap.Add (entry.Name, entry); } return entry; } diff --git a/mdoc/Mono.Documentation/Updater/Frameworks/FrameworkTypeEntry.cs b/mdoc/Mono.Documentation/Updater/Frameworks/FrameworkTypeEntry.cs index 67bcee86..fd54734f 100644 --- a/mdoc/Mono.Documentation/Updater/Frameworks/FrameworkTypeEntry.cs +++ b/mdoc/Mono.Documentation/Updater/Frameworks/FrameworkTypeEntry.cs @@ -9,6 +9,7 @@ namespace Mono.Documentation.Updater.Frameworks { SortedSet<string> members = new SortedSet<string> (); SortedSet<string> memberscsharpsig = new SortedSet<string> (); + Dictionary<string, bool> sigMap = new Dictionary<string, bool> (); ILFullMemberFormatter formatter = new ILFullMemberFormatter (); @@ -44,14 +45,17 @@ namespace Mono.Documentation.Updater.Frameworks // this is for lookup purposes try { - memberscsharpsig.Add(formatter.GetDeclaration(member)); + var sig = formatter.GetDeclaration (member); + memberscsharpsig.Add(sig); + if (!sigMap.ContainsKey (sig)) + sigMap.Add (sig, true); } catch {} } public bool ContainsCSharpSig (string sig) { - return memberscsharpsig.Contains (sig); + return sigMap.ContainsKey (sig); } public override string ToString () => $"{this.Name} in {this.fx.Name}"; diff --git a/mdoc/Mono.Documentation/Updater/MsxdocDocumentationImporter.cs b/mdoc/Mono.Documentation/Updater/MsxdocDocumentationImporter.cs index ab94d07a..e8f061e7 100644 --- a/mdoc/Mono.Documentation/Updater/MsxdocDocumentationImporter.cs +++ b/mdoc/Mono.Documentation/Updater/MsxdocDocumentationImporter.cs @@ -130,7 +130,7 @@ namespace Mono.Documentation.Updater .Select (n => new { Xml = n.OuterXml, - Overwrite = n.Attributes["overwrite"] + Overwrite = n.Attributes != null ? n.Attributes["overwrite"] : null }); string sourceXml = child.OuterXml; |