1010using Internal . TypeSystem . Ecma ;
1111
1212using DependencyList = ILCompiler . DependencyAnalysisFramework . DependencyNodeCore < ILCompiler . DependencyAnalysis . NodeFactory > . DependencyList ;
13+ using DependencyListEntry = ILCompiler . DependencyAnalysisFramework . DependencyNodeCore < ILCompiler . DependencyAnalysis . NodeFactory > . DependencyListEntry ;
14+ using CombinedDependencyList = System . Collections . Generic . List < ILCompiler . DependencyAnalysisFramework . DependencyNodeCore < ILCompiler . DependencyAnalysis . NodeFactory > . CombinedDependencyListEntry > ;
15+ using CombinedDependencyListEntry = ILCompiler . DependencyAnalysisFramework . DependencyNodeCore < ILCompiler . DependencyAnalysis . NodeFactory > . CombinedDependencyListEntry ;
1316using MethodAttributes = System . Reflection . MethodAttributes ;
1417
1518namespace ILCompiler . DependencyAnalysis
@@ -20,27 +23,35 @@ namespace ILCompiler.DependencyAnalysis
2023 /// </summary>
2124 internal static class CustomAttributeBasedDependencyAlgorithm
2225 {
23- public static void AddDependenciesDueToCustomAttributes ( ref DependencyList dependencies , NodeFactory factory , EcmaMethod method )
26+ private static IMethodNode GetMetadataApiDependency ( NodeFactory factory , string entityName , string propertyName )
27+ => factory . MethodEntrypoint ( factory . TypeSystemContext . SystemModule . GetType ( "Internal.Metadata.NativeFormat" , entityName ) . GetMethod ( propertyName , null ) ) ;
28+
29+ private static IMethodNode GetMetadataApiDependency ( NodeFactory factory , string entityName )
30+ => GetMetadataApiDependency ( factory , entityName , "get_CustomAttributes" ) ;
31+
32+ public static void AddDependenciesDueToCustomAttributes ( ref CombinedDependencyList dependencies , NodeFactory factory , EcmaMethod method )
2433 {
2534 MetadataReader reader = method . MetadataReader ;
2635 MethodDefinitionHandle methodHandle = method . Handle ;
2736 MethodDefinition methodDef = reader . GetMethodDefinition ( methodHandle ) ;
2837
2938 // Handle custom attributes on the method
30- AddDependenciesDueToCustomAttributes ( ref dependencies , factory , method . Module , methodDef . GetCustomAttributes ( ) , method ) ;
39+ AddDependenciesDueToCustomAttributes ( ref dependencies , GetMetadataApiDependency ( factory , "Method" ) , factory , method . Module , methodDef . GetCustomAttributes ( ) , method ) ;
3140
3241 // Handle custom attributes on method parameters
42+ object parameterCondition = GetMetadataApiDependency ( factory , "Parameter" ) ;
3343 foreach ( ParameterHandle parameterHandle in methodDef . GetParameters ( ) )
3444 {
3545 Parameter parameter = reader . GetParameter ( parameterHandle ) ;
36- AddDependenciesDueToCustomAttributes ( ref dependencies , factory , method . Module , parameter . GetCustomAttributes ( ) , method ) ;
46+ AddDependenciesDueToCustomAttributes ( ref dependencies , parameterCondition , factory , method . Module , parameter . GetCustomAttributes ( ) , method ) ;
3747 }
3848
3949 // Handle custom attributes on generic method parameters
50+ object genericParameterCondition = GetMetadataApiDependency ( factory , "GenericParameter" ) ;
4051 foreach ( GenericParameterHandle genericParameterHandle in methodDef . GetGenericParameters ( ) )
4152 {
4253 GenericParameter parameter = reader . GetGenericParameter ( genericParameterHandle ) ;
43- AddDependenciesDueToCustomAttributes ( ref dependencies , factory , method . Module , parameter . GetCustomAttributes ( ) , method ) ;
54+ AddDependenciesDueToCustomAttributes ( ref dependencies , genericParameterCondition , factory , method . Module , parameter . GetCustomAttributes ( ) , method ) ;
4455 }
4556
4657 // We don't model properties and events as separate entities within the compiler, so ensuring
@@ -50,6 +61,7 @@ public static void AddDependenciesDueToCustomAttributes(ref DependencyList depen
5061 // As a performance optimization, we look for associated events and properties only
5162 // if the method is SpecialName. This is required for CLS compliance and compilers we
5263 // care about emit accessors like this.
64+ object propertyCondition = GetMetadataApiDependency ( factory , "Property" ) ;
5365 if ( ( methodDef . Attributes & MethodAttributes . SpecialName ) != 0 )
5466 {
5567 TypeDefinition declaringType = reader . GetTypeDefinition ( methodDef . GetDeclaringType ( ) ) ;
@@ -60,50 +72,52 @@ public static void AddDependenciesDueToCustomAttributes(ref DependencyList depen
6072 PropertyAccessors accessors = property . GetAccessors ( ) ;
6173
6274 if ( accessors . Getter == methodHandle || accessors . Setter == methodHandle )
63- AddDependenciesDueToCustomAttributes ( ref dependencies , factory , method . Module , property . GetCustomAttributes ( ) , new PropertyPseudoDesc ( ( EcmaType ) method . OwningType , propertyHandle ) ) ;
75+ AddDependenciesDueToCustomAttributes ( ref dependencies , propertyCondition , factory , method . Module , property . GetCustomAttributes ( ) , new PropertyPseudoDesc ( ( EcmaType ) method . OwningType , propertyHandle ) ) ;
6476 }
6577
78+ object eventCondition = GetMetadataApiDependency ( factory , "Event" ) ;
6679 foreach ( EventDefinitionHandle eventHandle in declaringType . GetEvents ( ) )
6780 {
6881 EventDefinition @event = reader . GetEventDefinition ( eventHandle ) ;
6982 EventAccessors accessors = @event . GetAccessors ( ) ;
7083
7184 if ( accessors . Adder == methodHandle || accessors . Remover == methodHandle || accessors . Raiser == methodHandle )
72- AddDependenciesDueToCustomAttributes ( ref dependencies , factory , method . Module , @event . GetCustomAttributes ( ) , new EventPseudoDesc ( ( EcmaType ) method . OwningType , eventHandle ) ) ;
85+ AddDependenciesDueToCustomAttributes ( ref dependencies , eventCondition , factory , method . Module , @event . GetCustomAttributes ( ) , new EventPseudoDesc ( ( EcmaType ) method . OwningType , eventHandle ) ) ;
7386 }
7487 }
7588 }
7689
77- public static void AddDependenciesDueToCustomAttributes ( ref DependencyList dependencies , NodeFactory factory , EcmaType type )
90+ public static void AddDependenciesDueToCustomAttributes ( ref CombinedDependencyList dependencies , NodeFactory factory , EcmaType type )
7891 {
7992 MetadataReader reader = type . MetadataReader ;
8093 TypeDefinition typeDef = reader . GetTypeDefinition ( type . Handle ) ;
81- AddDependenciesDueToCustomAttributes ( ref dependencies , factory , type . EcmaModule , typeDef . GetCustomAttributes ( ) , type ) ;
94+ AddDependenciesDueToCustomAttributes ( ref dependencies , GetMetadataApiDependency ( factory , "TypeDefinition" ) , factory , type . EcmaModule , typeDef . GetCustomAttributes ( ) , type ) ;
8295
8396 // Handle custom attributes on generic type parameters
97+ object genericParameterCondition = GetMetadataApiDependency ( factory , "GenericParameter" ) ;
8498 foreach ( GenericParameterHandle genericParameterHandle in typeDef . GetGenericParameters ( ) )
8599 {
86100 GenericParameter parameter = reader . GetGenericParameter ( genericParameterHandle ) ;
87- AddDependenciesDueToCustomAttributes ( ref dependencies , factory , type . EcmaModule , parameter . GetCustomAttributes ( ) , type ) ;
101+ AddDependenciesDueToCustomAttributes ( ref dependencies , genericParameterCondition , factory , type . EcmaModule , parameter . GetCustomAttributes ( ) , type ) ;
88102 }
89103 }
90104
91- public static void AddDependenciesDueToCustomAttributes ( ref DependencyList dependencies , NodeFactory factory , EcmaField field )
105+ public static void AddDependenciesDueToCustomAttributes ( ref CombinedDependencyList dependencies , NodeFactory factory , EcmaField field )
92106 {
93107 FieldDefinition fieldDef = field . MetadataReader . GetFieldDefinition ( field . Handle ) ;
94- AddDependenciesDueToCustomAttributes ( ref dependencies , factory , field . Module , fieldDef . GetCustomAttributes ( ) , field ) ;
108+ AddDependenciesDueToCustomAttributes ( ref dependencies , GetMetadataApiDependency ( factory , "Field" ) , factory , field . Module , fieldDef . GetCustomAttributes ( ) , field ) ;
95109 }
96110
97- public static void AddDependenciesDueToCustomAttributes ( ref DependencyList dependencies , NodeFactory factory , EcmaAssembly assembly )
111+ public static void AddDependenciesDueToCustomAttributes ( ref CombinedDependencyList dependencies , NodeFactory factory , EcmaAssembly assembly )
98112 {
99113 AssemblyDefinition asmDef = assembly . MetadataReader . GetAssemblyDefinition ( ) ;
100- AddDependenciesDueToCustomAttributes ( ref dependencies , factory , assembly , asmDef . GetCustomAttributes ( ) , assembly ) ;
114+ AddDependenciesDueToCustomAttributes ( ref dependencies , GetMetadataApiDependency ( factory , "ScopeDefinition" ) , factory , assembly , asmDef . GetCustomAttributes ( ) , assembly ) ;
101115
102116 ModuleDefinition moduleDef = assembly . MetadataReader . GetModuleDefinition ( ) ;
103- AddDependenciesDueToCustomAttributes ( ref dependencies , factory , assembly , moduleDef . GetCustomAttributes ( ) , assembly ) ;
117+ AddDependenciesDueToCustomAttributes ( ref dependencies , GetMetadataApiDependency ( factory , "ScopeDefinition" , "get_ModuleCustomAttributes" ) , factory , assembly , moduleDef . GetCustomAttributes ( ) , assembly ) ;
104118 }
105119
106- private static void AddDependenciesDueToCustomAttributes ( ref DependencyList dependencies , NodeFactory factory , EcmaModule module , CustomAttributeHandleCollection attributeHandles , TypeSystemEntity parent )
120+ private static void AddDependenciesDueToCustomAttributes ( ref CombinedDependencyList dependencies , object condition , NodeFactory factory , EcmaModule module , CustomAttributeHandleCollection attributeHandles , TypeSystemEntity parent )
107121 {
108122 MetadataReader reader = module . MetadataReader ;
109123 var mdManager = ( UsageBasedMetadataManager ) factory . MetadataManager ;
@@ -134,9 +148,14 @@ private static void AddDependenciesDueToCustomAttributes(ref DependencyList depe
134148
135149 if ( AddDependenciesFromCustomAttributeBlob ( caDependencies , factory , constructor . OwningType , decodedValue ) )
136150 {
137- dependencies ??= new DependencyList ( ) ;
138- dependencies . AddRange ( caDependencies ) ;
139- dependencies . Add ( factory . CustomAttributeMetadata ( new ReflectableCustomAttribute ( module , caHandle ) ) , "Attribute metadata" ) ;
151+ dependencies ??= new CombinedDependencyList ( ) ;
152+
153+ foreach ( DependencyListEntry caDependency in caDependencies )
154+ {
155+ dependencies . Add ( new CombinedDependencyListEntry ( caDependency . Node , condition , caDependency . Reason ) ) ;
156+ }
157+
158+ dependencies . Add ( new CombinedDependencyListEntry ( factory . CustomAttributeMetadata ( new ReflectableCustomAttribute ( module , caHandle ) ) , condition , "Attribute metadata" ) ) ;
140159 }
141160 }
142161 catch ( TypeSystemException )
0 commit comments