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

AssemblySet.cs « Frameworks « Updater « Mono.Documentation « mdoc - github.com/mono/api-doc-tools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 6affe4cdb5f4deedd79da6939d675ecdcd0cc192 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
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
    {
        static readonly BaseAssemblyResolver resolver = new Frameworks.MDocResolver ();
        static IAssemblyResolver cachedResolver;
        static IMetadataResolver metadataResolver;

        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 AssemblySet (IEnumerable<string> paths) : this ("Default", paths, new string[0]) { }

        public AssemblySet (string name, IEnumerable<string> paths, IEnumerable<string> resolverSearchPaths, IEnumerable<string> imports = null, string version = null, string id = null)
        {
            cachedResolver = cachedResolver ?? new CachedResolver (resolver);
            metadataResolver = metadataResolver ?? new Frameworks.MDocMetadataResolver (cachedResolver);

            Name = name;
            Version = version;
            Id = id;

            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));

            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)).ToArray ();
            }
            else
                this.Importers = new DocumentationImporter[0];
        }

        public string Name { get; private set; }
        public string Version { get; private set; }
        public string Id { get; private set; }

        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 ()
        {
            var directories = resolver
                .GetSearchDirectories ()
                .Select (d => new DirectoryInfo (d))
                .Where (d => d.Exists)
                .Select (d => d.FullName)
                .Distinct ()
                .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 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);
        }

        public void Dispose () 
        {
            this.assemblies = null;
            cachedResolver.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, metadataResolver, cachedResolver);
				if (assembly != null) {
					foreach (var type in assembly.MainModule.ExportedTypes.Where (t => t.IsForwarder).Select (t => t.FullName))
						forwardedTypes.Add (type);
				}
				yield return assembly;
			}
		}
	}
}