1818
1919#nullable enable
2020
21+ using System ;
2122using System . Collections . Generic ;
2223using System . Linq ;
2324using System . Reflection . Metadata ;
@@ -37,11 +38,24 @@ 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+ if ( TryEncodingV2 ( extGroup ) )
48+ {
49+
50+ }
51+ }
52+
53+ bool TryEncodingV1 ( ITypeDefinition extGroup )
4054 {
4155 if ( ! ( extGroup is { Kind : TypeKind . Class , IsSealed : true }
4256 && extGroup . Name . StartsWith ( "<>E__" , System . StringComparison . Ordinal ) ) )
4357 {
44- continue ;
58+ return false ;
4559 }
4660
4761 TypeDefinition td = metadata . GetTypeDefinition ( ( TypeDefinitionHandle ) extGroup . MetadataToken ) ;
@@ -69,8 +83,53 @@ public ExtensionInfo(MetadataModule module, ITypeDefinition extensionContainer)
6983 }
7084
7185 if ( marker == null || hasMultipleMarkers )
72- continue ;
86+ return false ;
87+
88+ CollectImplementationMethods ( extGroup , marker , extensionMethods ) ;
89+ return true ;
90+ }
91+
92+ bool TryEncodingV2 ( ITypeDefinition extGroup )
93+ {
94+ if ( ! ( extGroup is { Kind : TypeKind . Class , IsSealed : true }
95+ && extGroup . Name . StartsWith ( "<G>$" , StringComparison . Ordinal ) ) )
96+ {
97+ return false ;
98+ }
99+
100+ var markerType = extGroup . NestedTypes . SingleOrDefault ( t => t . Name . StartsWith ( "<M>$" , StringComparison . Ordinal ) && t . IsStatic ) ;
101+ var marker = markerType ? . Methods . SingleOrDefault ( m => m . Name == "<Extension>$" && m . IsStatic && m . Parameters . Count == 1 ) ;
102+
103+ if ( markerType == null || marker == null )
104+ return false ;
105+
106+ TypeDefinition td = metadata . GetTypeDefinition ( ( TypeDefinitionHandle ) extGroup . MetadataToken ) ;
107+ List < IMethod > extensionMethods = [ ] ;
108+
109+ // For easier access to accessors we use SRM
110+ foreach ( var h in td . GetMethods ( ) )
111+ {
112+ var method = module . GetDefinition ( h ) ;
113+
114+ if ( method . SymbolKind is SymbolKind . Constructor )
115+ continue ;
116+
117+ var attribute = method . GetAttribute ( KnownAttribute . ExtensionMarker ) ;
118+ if ( attribute == null )
119+ continue ;
120+
121+ if ( attribute . FixedArguments [ 0 ] . Value ? . ToString ( ) != markerType . Name )
122+ continue ;
123+
124+ extensionMethods . Add ( method ) ;
125+ }
73126
127+ CollectImplementationMethods ( extGroup , marker , extensionMethods ) ;
128+ return true ;
129+ }
130+
131+ void CollectImplementationMethods ( ITypeDefinition extGroup , IMethod marker , List < IMethod > extensionMethods )
132+ {
74133 foreach ( var extension in extensionMethods )
75134 {
76135 int expectedTypeParameterCount = extension . TypeParameters . Count + extGroup . TypeParameterCount ;
@@ -119,9 +178,9 @@ bool IsMatchingImplementation(IMethod impl)
119178 }
120179 }
121180 }
122-
123181 }
124182
183+
125184 public ExtensionMemberInfo ? InfoOfExtensionMember ( IMethod method )
126185 {
127186 return this . extensionMemberMap . TryGetValue ( method , out var value ) ? value : null ;
0 commit comments