@@ -343,19 +343,8 @@ internal void MarkEntireType (TypeDefinition type, in DependencyInfo reason, Mes
343343
344344 MarkGenericParameterProvider ( type , origin ) ;
345345
346- if ( type . HasFields ) {
347- foreach ( FieldDefinition field in type . Fields ) {
348- MarkFieldVisibleToReflection ( field , new DependencyInfo ( DependencyKind . MemberOfType , type ) , origin ) ;
349- }
350- }
351-
352- if ( type . HasMethods ) {
353- foreach ( MethodDefinition method in type . Methods ) {
354- if ( IsFullyPreservedAction ( Annotations . GetAction ( type . Module . Assembly ) ) )
355- Annotations . SetAction ( method , MethodAction . ForceParse ) ;
356- MarkMethodVisibleToReflection ( method , new DependencyInfo ( DependencyKind . MemberOfType , type ) , origin ) ;
357- }
358- }
346+ MarkFieldsVisibleToReflection ( type , new DependencyInfo ( DependencyKind . MemberOfType , type ) , origin ) ;
347+ MarkMethodsVisibleToReflection ( type , new DependencyInfo ( DependencyKind . MemberOfType , type ) , origin ) ;
359348
360349 if ( type . HasProperties ) {
361350 foreach ( var property in type . Properties ) {
@@ -1897,11 +1886,47 @@ internal void MarkMethodVisibleToReflection (MethodReference method, in Dependen
18971886 }
18981887 }
18991888
1889+ bool MarkMethodsVisibleToReflection ( TypeDefinition type , in DependencyInfo reason , MessageOrigin origin )
1890+ {
1891+ if ( ! type . HasMethods )
1892+ return false ;
1893+
1894+ foreach ( MethodDefinition method in type . Methods ) {
1895+ if ( IsFullyPreservedAction ( Annotations . GetAction ( type . Module . Assembly ) ) )
1896+ Annotations . SetAction ( method , MethodAction . ForceParse ) ;
1897+ MarkMethodVisibleToReflection ( method , reason , origin ) ;
1898+ }
1899+ return true ;
1900+ }
1901+
19001902 internal void MarkFieldVisibleToReflection ( FieldReference field , in DependencyInfo reason , in MessageOrigin origin )
19011903 {
19021904 MarkField ( field , reason , origin ) ;
19031905 }
19041906
1907+ bool MarkFieldsVisibleToReflection ( TypeDefinition type , in DependencyInfo reason , MessageOrigin origin , bool markBackingFieldsOnlyIfPropertyMarked = false )
1908+ {
1909+ if ( ! type . HasFields )
1910+ return false ;
1911+
1912+ foreach ( FieldDefinition field in type . Fields ) {
1913+ if ( markBackingFieldsOnlyIfPropertyMarked && field . Name . EndsWith ( ">k__BackingField" , StringComparison . Ordinal ) ) {
1914+ // We can't reliably construct the expected property name from the backing field name for all compilers
1915+ // because csc shortens the name of the backing field in some cases
1916+ // For example:
1917+ // Field Name = <IFoo<int>.Bar>k__BackingField
1918+ // Property Name = IFoo<System.Int32>.Bar
1919+ //
1920+ // instead we will search the properties and find the one that makes use of the current backing field
1921+ var propertyDefinition = SearchPropertiesForMatchingFieldDefinition ( field ) ;
1922+ if ( propertyDefinition != null && ! Annotations . IsMarked ( propertyDefinition ) )
1923+ continue ;
1924+ }
1925+ MarkFieldVisibleToReflection ( field , reason , origin ) ;
1926+ }
1927+ return true ;
1928+ }
1929+
19051930 internal void MarkPropertyVisibleToReflection ( PropertyDefinition property , in DependencyInfo reason , in MessageOrigin origin )
19061931 {
19071932 // Marking the property itself actually doesn't keep it (it only marks its attributes and records the dependency), we have to mark the methods on it
@@ -2257,33 +2282,28 @@ void MarkTypeWithDebuggerDisplayAttributeValue (TypeDefinition type, CustomAttri
22572282
22582283 MethodDefinition ? method = GetMethodWithNoParameters ( type , methodName ) ;
22592284 if ( method != null ) {
2260- MarkMethod ( method , new DependencyInfo ( DependencyKind . ReferencedBySpecialAttribute , attribute ) , origin ) ;
2285+ MarkMethodVisibleToReflection ( method , new DependencyInfo ( DependencyKind . ReferencedBySpecialAttribute , attribute ) , origin ) ;
22612286 continue ;
22622287 }
22632288 } else {
22642289 FieldDefinition ? field = GetField ( type , realMatch ) ;
22652290 if ( field != null ) {
2266- MarkField ( field , new DependencyInfo ( DependencyKind . ReferencedBySpecialAttribute , attribute ) , origin ) ;
2291+ MarkFieldVisibleToReflection ( field , new DependencyInfo ( DependencyKind . ReferencedBySpecialAttribute , attribute ) , origin ) ;
22672292 continue ;
22682293 }
22692294
22702295 PropertyDefinition ? property = GetProperty ( type , realMatch ) ;
22712296 if ( property != null ) {
2272- if ( property . GetMethod != null ) {
2273- MarkMethod ( property . GetMethod , new DependencyInfo ( DependencyKind . ReferencedBySpecialAttribute , attribute ) , origin ) ;
2274- }
2275- if ( property . SetMethod != null ) {
2276- MarkMethod ( property . SetMethod , new DependencyInfo ( DependencyKind . ReferencedBySpecialAttribute , attribute ) , origin ) ;
2277- }
2297+ MarkPropertyVisibleToReflection ( property , new DependencyInfo ( DependencyKind . ReferencedBySpecialAttribute , attribute ) , origin ) ;
22782298 continue ;
22792299 }
22802300 }
22812301
22822302 while ( true ) {
22832303 // Currently if we don't understand the DebuggerDisplayAttribute we mark everything on the type
22842304 // This can be improved: dotnet/linker/issues/1873
2285- MarkMethods ( type , new DependencyInfo ( DependencyKind . KeptForSpecialAttribute , attribute ) , origin ) ;
2286- MarkFields ( type , includeStatic : true , new DependencyInfo ( DependencyKind . ReferencedBySpecialAttribute , attribute ) , origin ) ;
2305+ MarkMethodsVisibleToReflection ( type , new DependencyInfo ( DependencyKind . KeptForSpecialAttribute , attribute ) , origin ) ;
2306+ MarkFieldsVisibleToReflection ( type , new DependencyInfo ( DependencyKind . ReferencedBySpecialAttribute , attribute ) , origin ) ;
22872307 if ( Context . TryResolve ( type . BaseType ) is not TypeDefinition baseType )
22882308 break ;
22892309 type = baseType ;
@@ -2311,8 +2331,8 @@ void MarkTypeWithDebuggerTypeProxyAttribute (TypeDefinition type, CustomAttribut
23112331 MarkType ( proxyTypeReference , new DependencyInfo ( DependencyKind . ReferencedBySpecialAttribute , attribute ) , origin ) ;
23122332
23132333 if ( Context . TryResolve ( proxyTypeReference ) is TypeDefinition proxyType ) {
2314- MarkMethods ( proxyType , new DependencyInfo ( DependencyKind . ReferencedBySpecialAttribute , attribute ) , origin ) ;
2315- MarkFields ( proxyType , includeStatic : true , new DependencyInfo ( DependencyKind . ReferencedBySpecialAttribute , attribute ) , origin ) ;
2334+ MarkMethodsVisibleToReflection ( proxyType , new DependencyInfo ( DependencyKind . ReferencedBySpecialAttribute , attribute ) , origin ) ;
2335+ MarkFieldsVisibleToReflection ( proxyType , new DependencyInfo ( DependencyKind . ReferencedBySpecialAttribute , attribute ) , origin ) ;
23162336 }
23172337 }
23182338 }
@@ -2781,16 +2801,16 @@ void ApplyPreserveInfo (TypeDefinition type)
27812801
27822802 switch ( preserve ) {
27832803 case TypePreserve . All :
2784- MarkFields ( type , true , di , typeOrigin ) ;
2785- MarkMethods ( type , di , typeOrigin ) ;
2804+ MarkFieldsVisibleToReflection ( type , di , typeOrigin ) ;
2805+ MarkMethodsVisibleToReflection ( type , in di , typeOrigin ) ;
27862806 return ;
27872807
27882808 case TypePreserve . Fields :
2789- if ( ! MarkFields ( type , true , di , typeOrigin , true ) )
2809+ if ( ! MarkFieldsVisibleToReflection ( type , di , typeOrigin , markBackingFieldsOnlyIfPropertyMarked : true ) )
27902810 Context . LogWarning ( type , DiagnosticId . TypeHasNoFieldsToPreserve , type . GetDisplayName ( ) ) ;
27912811 break ;
27922812 case TypePreserve . Methods :
2793- if ( ! MarkMethods ( type , di , typeOrigin ) )
2813+ if ( ! MarkMethodsVisibleToReflection ( type , in di , typeOrigin ) )
27942814 Context . LogWarning ( type , DiagnosticId . TypeHasNoMethodsToPreserve , type . GetDisplayName ( ) ) ;
27952815 break ;
27962816 }
@@ -2802,18 +2822,18 @@ void ApplyPreserveInfo (TypeDefinition type)
28022822 if ( type . HasMethods ) {
28032823 foreach ( var m in type . Methods ) {
28042824 if ( ( members & TypePreserveMembers . Visible ) != 0 && IsMethodVisible ( m ) ) {
2805- MarkMethod ( m , di , typeOrigin ) ;
2825+ MarkMethodVisibleToReflection ( m , di , typeOrigin ) ;
28062826 continue ;
28072827 }
28082828
28092829 if ( ( members & TypePreserveMembers . Internal ) != 0 && IsMethodInternal ( m ) ) {
2810- MarkMethod ( m , di , typeOrigin ) ;
2830+ MarkMethodVisibleToReflection ( m , di , typeOrigin ) ;
28112831 continue ;
28122832 }
28132833
28142834 if ( ( members & TypePreserveMembers . Library ) != 0 ) {
28152835 if ( IsSpecialSerializationConstructor ( m ) || HasOnSerializeOrDeserializeAttribute ( m ) ) {
2816- MarkMethod ( m , di , typeOrigin ) ;
2836+ MarkMethodVisibleToReflection ( m , di , typeOrigin ) ;
28172837 continue ;
28182838 }
28192839 }
@@ -2823,12 +2843,12 @@ void ApplyPreserveInfo (TypeDefinition type)
28232843 if ( type . HasFields ) {
28242844 foreach ( var f in type . Fields ) {
28252845 if ( ( members & TypePreserveMembers . Visible ) != 0 && IsFieldVisible ( f ) ) {
2826- MarkField ( f , di , typeOrigin ) ;
2846+ MarkFieldVisibleToReflection ( f , di , typeOrigin ) ;
28272847 continue ;
28282848 }
28292849
28302850 if ( ( members & TypePreserveMembers . Internal ) != 0 && IsFieldInternal ( f ) ) {
2831- MarkField ( f , di , typeOrigin ) ;
2851+ MarkFieldVisibleToReflection ( f , di , typeOrigin ) ;
28322852 continue ;
28332853 }
28342854 }
@@ -2876,27 +2896,14 @@ void ApplyPreserveMethods (MethodDefinition method, MessageOrigin origin)
28762896 MarkMethodCollection ( list , new DependencyInfo ( DependencyKind . PreservedMethod , method ) , origin ) ;
28772897 }
28782898
2879- protected bool MarkFields ( TypeDefinition type , bool includeStatic , in DependencyInfo reason , MessageOrigin origin , bool markBackingFieldsOnlyIfPropertyMarked = false )
2899+ protected bool MarkFields ( TypeDefinition type , bool includeStatic , in DependencyInfo reason , MessageOrigin origin )
28802900 {
28812901 if ( ! type . HasFields )
28822902 return false ;
28832903
28842904 foreach ( FieldDefinition field in type . Fields ) {
28852905 if ( ! includeStatic && field . IsStatic )
28862906 continue ;
2887-
2888- if ( markBackingFieldsOnlyIfPropertyMarked && field . Name . EndsWith ( ">k__BackingField" , StringComparison . Ordinal ) ) {
2889- // We can't reliably construct the expected property name from the backing field name for all compilers
2890- // because csc shortens the name of the backing field in some cases
2891- // For example:
2892- // Field Name = <IFoo<int>.Bar>k__BackingField
2893- // Property Name = IFoo<System.Int32>.Bar
2894- //
2895- // instead we will search the properties and find the one that makes use of the current backing field
2896- var propertyDefinition = SearchPropertiesForMatchingFieldDefinition ( field ) ;
2897- if ( propertyDefinition != null && ! Annotations . IsMarked ( propertyDefinition ) )
2898- continue ;
2899- }
29002907 MarkField ( field , reason , origin ) ;
29012908 }
29022909
0 commit comments