Skip to content

Commit 7f84d24

Browse files
Add support for new extension everything encoding.
1 parent 17a5336 commit 7f84d24

File tree

1 file changed

+58
-3
lines changed

1 file changed

+58
-3
lines changed

ICSharpCode.Decompiler/TypeSystem/ExtensionInfo.cs

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#nullable enable
2020

21+
using System;
2122
using System.Collections.Generic;
2223
using System.Linq;
2324
using 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

Comments
 (0)