diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
index 78a107ea1..c5c935db3 100644
--- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
+++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
@@ -112,6 +112,7 @@
+
diff --git a/ICSharpCode.Decompiler/IL/Transforms/LocalFunctionDecompiler.cs b/ICSharpCode.Decompiler/IL/Transforms/LocalFunctionDecompiler.cs
index d1ca322e1..191ee8b0f 100644
--- a/ICSharpCode.Decompiler/IL/Transforms/LocalFunctionDecompiler.cs
+++ b/ICSharpCode.Decompiler/IL/Transforms/LocalFunctionDecompiler.cs
@@ -827,7 +827,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (!IsLocalFunctionMethod(module, method, context))
continue;
var md = metadata.GetMethodDefinition(method);
- if (md.DecodeSignature(new FindTypeDecoder(typeHandle), default).ParameterTypes.Any())
+ if (md.DecodeSignature(new FindTypeDecoder(typeHandle, module, 0), default).ParameterTypes.Any())
return true;
}
@@ -852,43 +852,6 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return match.Success;
}
- struct FindTypeDecoder : ISignatureTypeProvider
- {
- readonly TypeDefinitionHandle handle;
-
- public FindTypeDecoder(TypeDefinitionHandle handle)
- {
- this.handle = handle;
- }
-
- public bool GetArrayType(bool elementType, ArrayShape shape) => elementType;
- public bool GetByReferenceType(bool elementType) => elementType;
- public bool GetFunctionPointerType(MethodSignature signature) => false;
- public bool GetGenericInstantiation(bool genericType, ImmutableArray typeArguments) => genericType;
- public bool GetGenericMethodParameter(Unit genericContext, int index) => false;
- public bool GetGenericTypeParameter(Unit genericContext, int index) => false;
- public bool GetModifiedType(bool modifier, bool unmodifiedType, bool isRequired) => unmodifiedType;
- public bool GetPinnedType(bool elementType) => elementType;
- public bool GetPointerType(bool elementType) => elementType;
- public bool GetPrimitiveType(PrimitiveTypeCode typeCode) => false;
- public bool GetSZArrayType(bool elementType) => false;
-
- public bool GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind)
- {
- return this.handle == handle;
- }
-
- public bool GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)
- {
- return false;
- }
-
- public bool GetTypeFromSpecification(MetadataReader reader, Unit genericContext, TypeSpecificationHandle handle, byte rawTypeKind)
- {
- return reader.GetTypeSpecification(handle).DecodeSignature(this, genericContext);
- }
- }
-
class FindRefStructParameters : ISignatureTypeProvider
{
public readonly List RefStructTypes = new List();
diff --git a/ICSharpCode.Decompiler/Metadata/FindTypeDecoder.cs b/ICSharpCode.Decompiler/Metadata/FindTypeDecoder.cs
new file mode 100644
index 000000000..7b5847fad
--- /dev/null
+++ b/ICSharpCode.Decompiler/Metadata/FindTypeDecoder.cs
@@ -0,0 +1,126 @@
+// Copyright (c) 2022 Siegfried Pammer
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this
+// software and associated documentation files (the "Software"), to deal in the Software
+// without restriction, including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
+// to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or
+// substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#nullable enable
+
+using System;
+using System.Collections.Immutable;
+using System.Reflection.Metadata;
+
+using ICSharpCode.Decompiler.TypeSystem;
+using ICSharpCode.Decompiler.Util;
+
+namespace ICSharpCode.Decompiler.Metadata
+{
+ public class FindTypeDecoder : ISignatureTypeProvider
+ {
+ readonly PEFile declaringModule;
+ readonly MetadataModule? currentModule;
+ readonly TypeDefinitionHandle handle;
+ readonly string? typeName;
+ readonly string? namespaceName;
+ readonly PrimitiveTypeCode primitiveType;
+
+ public FindTypeDecoder(TypeDefinitionHandle handle, PEFile declaringModule, PrimitiveTypeCode primitiveType)
+ {
+ this.handle = handle;
+ this.declaringModule = declaringModule;
+ this.primitiveType = primitiveType;
+ this.currentModule = null;
+ }
+
+ public FindTypeDecoder(MetadataModule currentModule, ITypeDefinition type)
+ {
+ this.currentModule = currentModule;
+ this.declaringModule = type.ParentModule.PEFile ?? throw new InvalidOperationException("Cannot use MetadataModule without PEFile as context.");
+ this.handle = (TypeDefinitionHandle)type.MetadataToken;
+ this.primitiveType = type.KnownTypeCode == KnownTypeCode.None ? 0 : type.KnownTypeCode.ToPrimitiveTypeCode();
+ this.typeName = type.MetadataName;
+ this.namespaceName = type.Namespace;
+ }
+
+ public bool GetArrayType(bool elementType, ArrayShape shape) => elementType;
+ public bool GetByReferenceType(bool elementType) => elementType;
+ public bool GetFunctionPointerType(MethodSignature signature)
+ {
+ if (signature.ReturnType)
+ return true;
+ foreach (bool type in signature.ParameterTypes)
+ {
+ if (type)
+ return true;
+ }
+ return false;
+ }
+
+ public bool GetGenericInstantiation(bool genericType, ImmutableArray typeArguments)
+ {
+ if (genericType)
+ return true;
+ foreach (bool ta in typeArguments)
+ {
+ if (ta)
+ return true;
+ }
+ return false;
+ }
+
+ public bool GetGenericMethodParameter(Unit genericContext, int index) => false;
+ public bool GetGenericTypeParameter(Unit genericContext, int index) => false;
+ public bool GetModifiedType(bool modifier, bool unmodifiedType, bool isRequired) => unmodifiedType || modifier;
+ public bool GetPinnedType(bool elementType) => elementType;
+ public bool GetPointerType(bool elementType) => elementType;
+
+ public bool GetPrimitiveType(PrimitiveTypeCode typeCode)
+ {
+ return typeCode == primitiveType;
+ }
+
+ public bool GetSZArrayType(bool elementType) => elementType;
+
+ public bool GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind)
+ {
+ return this.handle == handle && reader == declaringModule.Metadata;
+ }
+
+ public bool GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)
+ {
+ if (currentModule == null || typeName == null || namespaceName == null)
+ return false;
+
+ var tr = reader.GetTypeReference(handle);
+ if (!reader.StringComparer.Equals(tr.Name, typeName))
+ return false;
+ if (!((tr.Namespace.IsNil && namespaceName.Length == 0) || reader.StringComparer.Equals(tr.Namespace, namespaceName)))
+ return false;
+
+ var t = currentModule.ResolveType(handle, default);
+ var td = t.GetDefinition();
+ if (td == null)
+ return false;
+
+ return td.MetadataToken == this.handle && td.ParentModule.PEFile == declaringModule;
+ }
+
+ public bool GetTypeFromSpecification(MetadataReader reader, Unit genericContext, TypeSpecificationHandle handle, byte rawTypeKind)
+ {
+ return reader.GetTypeSpecification(handle).DecodeSignature(this, genericContext);
+ }
+ }
+
+}