From 7f84d2416739c039ae6a46c59982731e6f5fc04d Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Tue, 9 Sep 2025 21:42:29 +0200 Subject: [PATCH] Add support for new extension everything encoding. --- .../TypeSystem/ExtensionInfo.cs | 61 ++++++++++++++++++- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/ICSharpCode.Decompiler/TypeSystem/ExtensionInfo.cs b/ICSharpCode.Decompiler/TypeSystem/ExtensionInfo.cs index 2339f150c..dfe82d774 100644 --- a/ICSharpCode.Decompiler/TypeSystem/ExtensionInfo.cs +++ b/ICSharpCode.Decompiler/TypeSystem/ExtensionInfo.cs @@ -18,6 +18,7 @@ #nullable enable +using System; using System.Collections.Generic; using System.Linq; using System.Reflection.Metadata; @@ -37,11 +38,21 @@ namespace ICSharpCode.Decompiler.TypeSystem var metadata = module.MetadataFile.Metadata; foreach (var extGroup in extensionContainer.NestedTypes) + { + if (TryEncodingV1(extGroup)) + { + continue; + } + + TryEncodingV2(extGroup); + } + + bool TryEncodingV1(ITypeDefinition extGroup) { if (!(extGroup is { Kind: TypeKind.Class, IsSealed: true } && extGroup.Name.StartsWith("<>E__", System.StringComparison.Ordinal))) { - continue; + return false; } TypeDefinition td = metadata.GetTypeDefinition((TypeDefinitionHandle)extGroup.MetadataToken); @@ -69,8 +80,53 @@ namespace ICSharpCode.Decompiler.TypeSystem } if (marker == null || hasMultipleMarkers) - continue; + return false; + + CollectImplementationMethods(extGroup, marker, extensionMethods); + return true; + } + + bool TryEncodingV2(ITypeDefinition extGroup) + { + if (!(extGroup is { Kind: TypeKind.Class, IsSealed: true } + && extGroup.Name.StartsWith("$", StringComparison.Ordinal))) + { + return false; + } + + var markerType = extGroup.NestedTypes.SingleOrDefault(t => t.Name.StartsWith("$", StringComparison.Ordinal) && t.IsStatic); + var marker = markerType?.Methods.SingleOrDefault(m => m.Name == "$" && m.IsStatic && m.Parameters.Count == 1); + + if (markerType == null || marker == null) + return false; + + TypeDefinition td = metadata.GetTypeDefinition((TypeDefinitionHandle)extGroup.MetadataToken); + List extensionMethods = []; + + // For easier access to accessors we use SRM + foreach (var h in td.GetMethods()) + { + var method = module.GetDefinition(h); + + if (method.SymbolKind is SymbolKind.Constructor) + continue; + + var attribute = method.GetAttribute(KnownAttribute.ExtensionMarker); + if (attribute == null) + continue; + + if (attribute.FixedArguments[0].Value?.ToString() != markerType.Name) + continue; + + extensionMethods.Add(method); + } + + CollectImplementationMethods(extGroup, marker, extensionMethods); + return true; + } + void CollectImplementationMethods(ITypeDefinition extGroup, IMethod marker, List extensionMethods) + { foreach (var extension in extensionMethods) { int expectedTypeParameterCount = extension.TypeParameters.Count + extGroup.TypeParameterCount; @@ -119,7 +175,6 @@ namespace ICSharpCode.Decompiler.TypeSystem } } } - } public ExtensionMemberInfo? InfoOfExtensionMember(IMethod method)