13
13
/// </summary>
14
14
internal static class TypeCollector
15
15
{
16
+ private static readonly HashSet < string > _systemAssemblyNames = new HashSet < string > { "mscorlib" , "System" , "System.Core" } ;
17
+
16
18
/// <summary>
17
19
/// Collects assemblies the type has access to: the type's native assembly and all its referenced assemblies.
18
20
/// </summary>
@@ -25,92 +27,38 @@ internal static class TypeCollector
25
27
/// Additional assemblies may be added using <see cref="TypeOptionsAttribute.IncludeAdditionalAssemblies"/>,
26
28
/// hence the List return type.
27
29
/// </remarks>
28
- public static List < Assembly > GetAssembliesTypeHasAccessTo ( Type type )
29
- {
30
- Assembly typeAssembly ;
31
-
32
- try
33
- {
34
- typeAssembly = type == null ? Assembly . Load ( "Assembly-CSharp" ) : type . Assembly ;
35
- }
36
- catch ( FileNotFoundException )
37
- {
38
- return GetAllAssemblies ( ) ;
39
- }
40
-
41
- var referencedAssemblies = typeAssembly . GetReferencedAssemblies ( ) ;
42
- var assemblies = new List < Assembly > ( referencedAssemblies . Length + 1 ) ;
43
-
44
- for ( int i = 0 ; i < referencedAssemblies . Length ; i ++ )
45
- {
46
- assemblies [ i ] = Assembly . Load ( referencedAssemblies [ i ] ) ;
47
- }
48
-
49
- assemblies [ referencedAssemblies . Length ] = typeAssembly ;
50
- return assemblies ;
51
- }
52
-
53
- public static List < Assembly > GetAssembliesTypeHasAccessTo ( Type type , out bool containsMscorlib )
30
+ public static IEnumerable < Assembly > GetAssembliesTypeHasAccessTo ( Type type , out bool containsSystemAssembly )
54
31
{
55
32
if ( type == null )
56
33
{
57
- containsMscorlib = true ;
34
+ containsSystemAssembly = true ;
58
35
return GetAllAssemblies ( ) ;
59
36
}
60
37
61
- containsMscorlib = false ;
38
+ containsSystemAssembly = false ;
62
39
Assembly typeAssembly = type . Assembly ;
63
40
64
41
var referencedAssemblies = typeAssembly . GetReferencedAssemblies ( ) ;
65
- var assemblies = new List < Assembly > ( referencedAssemblies . Length + 1 ) ;
66
-
67
- for ( int i = 0 ; i < referencedAssemblies . Length ; i ++ )
68
- {
69
- var assemblyName = referencedAssemblies [ i ] ;
70
-
71
- if ( ! containsMscorlib && assemblyName . Name == "mscorlib" )
72
- {
73
- containsMscorlib = true ;
74
- }
75
-
76
- assemblies . Add ( Assembly . Load ( assemblyName ) ) ;
77
- }
78
-
79
- if ( ! containsMscorlib && typeAssembly . FullName . Contains ( "mscorlib" ) )
80
- {
81
- containsMscorlib = true ;
82
- }
83
42
84
- assemblies . Add ( typeAssembly ) ;
85
-
86
- return assemblies ;
43
+ containsSystemAssembly = IsSystemAssembly ( typeAssembly ) || referencedAssemblies . Any ( IsSystemAssembly ) ;
44
+ return referencedAssemblies . Select ( Assembly . Load ) . Append ( typeAssembly ) ;
87
45
}
88
46
89
- private static List < Assembly > GetAllAssemblies ( )
47
+ private static bool IsSystemAssembly ( Assembly assembly )
90
48
{
91
- return new List < Assembly > ( AppDomain . CurrentDomain . GetAssemblies ( ) ) ;
49
+ return IsSystemAssembly ( assembly . GetName ( ) ) ;
92
50
}
93
-
94
- public static List < Type > GetFilteredTypesFromAssemblies (
95
- List < Assembly > assemblies ,
96
- TypeOptionsAttribute filter )
51
+
52
+ private static bool IsSystemAssembly ( AssemblyName assemblyName )
97
53
{
98
- int assembliesCount = assemblies . Count ;
99
-
100
- var types = new List < Type > ( assembliesCount * 20 ) ;
101
-
102
- for ( int i = 0 ; i < assembliesCount ; i ++ )
103
- {
104
- var filteredTypes = GetFilteredTypesFromAssembly ( assemblies [ i ] , filter ) ;
105
- int filteredTypesCount = filteredTypes . Count ;
54
+ return _systemAssemblyNames . Contains ( assemblyName . Name ) ;
55
+ }
106
56
107
- for ( int j = 0 ; j < filteredTypesCount ; j ++ )
108
- {
109
- types . Add ( filteredTypes [ j ] ) ;
110
- }
111
- }
57
+ public static IEnumerable < Assembly > GetAllAssemblies ( ) => AppDomain . CurrentDomain . GetAssemblies ( ) ;
112
58
113
- return types ;
59
+ public static IEnumerable < Type > GetFilteredTypesFromAssemblies ( IEnumerable < Assembly > assemblies , TypeOptionsAttribute filter )
60
+ {
61
+ return assemblies . SelectMany ( assembly => GetFilteredTypesFromAssembly ( assembly , filter ) ) ;
114
62
}
115
63
116
64
public static Assembly TryLoadAssembly ( string assemblyName )
@@ -140,66 +88,37 @@ public static Assembly TryLoadAssembly(string assemblyName)
140
88
return assembly ;
141
89
}
142
90
143
- private static List < Type > GetFilteredTypesFromAssembly ( Assembly assembly , TypeOptionsAttribute filter )
91
+ private static IEnumerable < Type > GetFilteredTypesFromAssembly ( Assembly assembly , TypeOptionsAttribute filter )
144
92
{
145
- List < Type > assemblyTypes ;
146
-
147
- assemblyTypes = filter . AllowInternal
148
- ? GetAllTypesFromAssembly ( assembly )
149
- : GetVisibleTypesFromAssembly ( assembly ) ;
150
-
151
- var filteredTypes = new List < Type > ( ) ;
152
- int visibleTypesCount = assemblyTypes . Count ;
93
+ var assemblyTypes = GetAllTypesFromAssembly ( assembly ) ;
153
94
154
- for ( int i = 0 ; i < visibleTypesCount ; i ++ )
155
- {
156
- Type type = assemblyTypes [ i ] ;
157
- if ( FilterConstraintIsSatisfied ( filter , type ) )
158
- {
159
- filteredTypes . Add ( type ) ;
160
- }
161
- }
95
+ // Don't allow internal types of mscorlib even if the AllowInternal property is set to true because it leads
96
+ // to a lot of garbage in the dropdown while it's almost impossible users will need a System internal class.
97
+ bool allowInternal = filter . AllowInternal && ! IsSystemAssembly ( assembly ) ;
162
98
163
- return filteredTypes ;
99
+ return assemblyTypes . Where ( type => ( allowInternal || type . IsVisible ) && FilterConstraintIsSatisfied ( filter , type ) ) ;
164
100
}
165
101
166
- private static List < Type > GetVisibleTypesFromAssembly ( Assembly assembly )
102
+ private static IEnumerable < Type > GetAllTypesFromAssembly ( Assembly assembly )
167
103
{
168
104
try
169
105
{
170
- var assemblyTypes = assembly . GetTypes ( ) ;
171
- var visibleTypes = new List < Type > ( assemblyTypes . Length ) ;
172
-
173
- foreach ( Type type in assemblyTypes )
174
- {
175
- if ( type . IsVisible )
176
- visibleTypes . Add ( type ) ;
177
- }
178
-
179
- return visibleTypes ;
180
- }
181
- catch ( ReflectionTypeLoadException e )
182
- {
183
- Debug . LogError ( $ "Types could not be extracted from assembly { assembly } : { e . Message } ") ;
184
- return new List < Type > ( 0 ) ;
185
- }
186
- }
187
-
188
- private static List < Type > GetAllTypesFromAssembly ( Assembly assembly )
189
- {
190
- try
191
- {
192
- return assembly . GetTypes ( ) . ToList ( ) ;
106
+ return assembly . GetTypes ( ) ;
193
107
}
194
108
catch ( ReflectionTypeLoadException e )
195
109
{
196
110
Debug . LogError ( $ "Types could not be extracted from assembly { assembly } : { e . Message } ") ;
197
- return new List < Type > ( 0 ) ;
111
+ return Enumerable . Empty < Type > ( ) ;
198
112
}
199
113
}
200
114
201
115
private static bool FilterConstraintIsSatisfied ( TypeOptionsAttribute filter , Type type )
202
116
{
117
+ string typeFullName = type . FullName ;
118
+
119
+ if ( typeFullName == null || typeFullName . StartsWith ( "<" ) || type . Name . StartsWith ( "<" ) )
120
+ return false ;
121
+
203
122
return filter == null || filter . MatchesRequirements ( type ) ;
204
123
}
205
124
}
0 commit comments