1+ using System ;
2+ using System . Collections . Generic ;
3+ using System . Linq ;
4+ using System . Reflection ;
5+ using Mono . Cecil ;
6+ using NetArchTest . Rules . Dependencies . DataStructures ;
7+ using NetArchTest . Rules . Extensions ;
8+
9+ namespace NetArchTest . Rules . Assemblies
10+ {
11+ internal sealed class TypeSource
12+ {
13+ private static readonly List < string > exclusionList = new List < string > { "System" , "Microsoft" , "Mono.Cecil" , "netstandard" , "NetArchTest.Rules" , "<Module>" , "xunit" , "<PrivateImplementationDetails>" } ;
14+ private static readonly NamespaceTree exclusionTree = new NamespaceTree ( exclusionList ) ;
15+
16+
17+
18+ public static IEnumerable < IType > FromAssemblies ( IEnumerable < Assembly > assemblies , IEnumerable < string > searchDirectories = null )
19+ {
20+ foreach ( var assembly in assemblies )
21+ {
22+ if ( exclusionTree . GetAllMatchingNames ( assembly . FullName ) . Any ( ) || assembly . IsDynamic )
23+ {
24+ continue ;
25+ }
26+
27+ foreach ( var type in ReadTypes ( assembly . Location ) )
28+ {
29+ yield return type ;
30+ }
31+ }
32+ }
33+ public static IEnumerable < IType > FromFiles ( IEnumerable < string > fileNames , IEnumerable < string > searchDirectories = null )
34+ {
35+ foreach ( var fileName in fileNames )
36+ {
37+ foreach ( var type in ReadTypes ( fileName ) )
38+ {
39+ yield return type ;
40+ }
41+ }
42+ }
43+
44+ private static IEnumerable < IType > ReadTypes ( string assemblyLocation , IEnumerable < string > searchDirectories = null )
45+ {
46+ ReaderParameters readerParameters = null ;
47+
48+ if ( searchDirectories ? . Any ( ) == true )
49+ {
50+ var assemblyResolver = new DefaultAssemblyResolver ( ) ;
51+ foreach ( var searchDirectory in searchDirectories )
52+ {
53+ assemblyResolver . AddSearchDirectory ( searchDirectory ) ;
54+ }
55+
56+ readerParameters = new ReaderParameters { AssemblyResolver = assemblyResolver } ;
57+ }
58+
59+ var assemblyDefinition = ReadAssemblyDefinition ( assemblyLocation , readerParameters ) ;
60+
61+ if ( assemblyDefinition != null )
62+ {
63+ if ( exclusionTree . GetAllMatchingNames ( assemblyDefinition . FullName ) . Any ( ) == false )
64+ {
65+ foreach ( var type in GetAllTypes ( assemblyDefinition . Modules . SelectMany ( t => t . Types ) ) )
66+ {
67+ yield return type ;
68+ }
69+ }
70+ }
71+ }
72+ private static AssemblyDefinition ReadAssemblyDefinition ( string path , ReaderParameters readerParameters = null )
73+ {
74+ try
75+ {
76+ if ( readerParameters == null )
77+ {
78+ return AssemblyDefinition . ReadAssembly ( path ) ;
79+ }
80+ else
81+ {
82+ return AssemblyDefinition . ReadAssembly ( path , readerParameters ) ;
83+ }
84+ }
85+ catch ( BadImageFormatException )
86+ {
87+ return null ;
88+ }
89+ }
90+ private static IEnumerable < IType > GetAllTypes ( IEnumerable < TypeDefinition > types )
91+ {
92+ foreach ( var type in types )
93+ {
94+ if ( exclusionTree . GetAllMatchingNames ( type . FullName ) . Any ( ) || type . IsCompilerGenerated ( ) )
95+ {
96+ continue ;
97+ }
98+
99+ yield return new TypeImpl ( type ) ;
100+
101+ if ( type . NestedTypes ? . Any ( ) == true )
102+ {
103+ foreach ( var nestedType in GetAllTypes ( type . NestedTypes ) )
104+ {
105+ yield return nestedType ;
106+ }
107+ }
108+ }
109+ }
110+ }
111+ }
0 commit comments