1818
1919#nullable enable
2020
21+ using System ;
2122using System . Collections . Generic ;
2223using System . Linq ;
2324using System . Reflection . Metadata ;
@@ -37,11 +38,21 @@ public ExtensionInfo(MetadataModule module, ITypeDefinition extensionContainer)
3738 var metadata = module . MetadataFile . Metadata ;
3839
3940 foreach ( var extGroup in extensionContainer . NestedTypes )
41+ {
42+ if ( TryEncodingV1 ( extGroup ) )
43+ {
44+ continue ;
45+ }
46+
47+ TryEncodingV2 ( extGroup ) ;
48+ }
49+
50+ bool TryEncodingV1 ( ITypeDefinition extGroup )
4051 {
4152 if ( ! ( extGroup is { Kind : TypeKind . Class , IsSealed : true }
4253 && extGroup . Name . StartsWith ( "<>E__" , System . StringComparison . Ordinal ) ) )
4354 {
44- continue ;
55+ return false ;
4556 }
4657
4758 TypeDefinition td = metadata . GetTypeDefinition ( ( TypeDefinitionHandle ) extGroup . MetadataToken ) ;
@@ -69,8 +80,53 @@ public ExtensionInfo(MetadataModule module, ITypeDefinition extensionContainer)
6980 }
7081
7182 if ( marker == null || hasMultipleMarkers )
72- continue ;
83+ return false ;
84+
85+ CollectImplementationMethods ( extGroup , marker , extensionMethods ) ;
86+ return true ;
87+ }
88+
89+ bool TryEncodingV2 ( ITypeDefinition extGroup )
90+ {
91+ if ( ! ( extGroup is { Kind : TypeKind . Class , IsSealed : true }
92+ && extGroup . Name . StartsWith ( "<G>$" , StringComparison . Ordinal ) ) )
93+ {
94+ return false ;
95+ }
96+
97+ var markerType = extGroup . NestedTypes . SingleOrDefault ( t => t . Name . StartsWith ( "<M>$" , StringComparison . Ordinal ) && t . IsStatic ) ;
98+ var marker = markerType ? . Methods . SingleOrDefault ( m => m . Name == "<Extension>$" && m . IsStatic && m . Parameters . Count == 1 ) ;
99+
100+ if ( markerType == null || marker == null )
101+ return false ;
102+
103+ TypeDefinition td = metadata . GetTypeDefinition ( ( TypeDefinitionHandle ) extGroup . MetadataToken ) ;
104+ List < IMethod > extensionMethods = [ ] ;
105+
106+ // For easier access to accessors we use SRM
107+ foreach ( var h in td . GetMethods ( ) )
108+ {
109+ var method = module . GetDefinition ( h ) ;
110+
111+ if ( method . SymbolKind is SymbolKind . Constructor )
112+ continue ;
113+
114+ var attribute = method . GetAttribute ( KnownAttribute . ExtensionMarker ) ;
115+ if ( attribute == null )
116+ continue ;
117+
118+ if ( attribute . FixedArguments [ 0 ] . Value ? . ToString ( ) != markerType . Name )
119+ continue ;
120+
121+ extensionMethods . Add ( method ) ;
122+ }
123+
124+ CollectImplementationMethods ( extGroup , marker , extensionMethods ) ;
125+ return true ;
126+ }
73127
128+ void CollectImplementationMethods ( ITypeDefinition extGroup , IMethod marker , List < IMethod > extensionMethods )
129+ {
74130 foreach ( var extension in extensionMethods )
75131 {
76132 int expectedTypeParameterCount = extension . TypeParameters . Count + extGroup . TypeParameterCount ;
@@ -119,7 +175,6 @@ bool IsMatchingImplementation(IMethod impl)
119175 }
120176 }
121177 }
122-
123178 }
124179
125180 public ExtensionMemberInfo ? InfoOfExtensionMember ( IMethod method )
0 commit comments