From 18d6c486a827de130f4f453f5c8fd96582461f1d Mon Sep 17 00:00:00 2001 From: wwh1004 Date: Sun, 23 Jan 2022 23:53:37 +0800 Subject: [PATCH] Fix 'Importer.Import(FieldInfo)' and 'Importer.ImportDeclaringType(Type)' --- src/DotNet/Importer.cs | 26 +++++--------------------- src/DotNet/ReflectionExtensions.cs | 12 ++++++++++-- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/src/DotNet/Importer.cs b/src/DotNet/Importer.cs index 06a533607..238e26e00 100644 --- a/src/DotNet/Importer.cs +++ b/src/DotNet/Importer.cs @@ -180,7 +180,7 @@ public Importer(ModuleDef module, ImporterOptions options, GenericParamContext g /// /// The type /// - public ITypeDefOrRef ImportDeclaringType(Type type) => module.UpdateRowId(ImportAsTypeSig(type, type.IsGenericTypeDefinition).ToTypeDefOrRef()); + public ITypeDefOrRef ImportDeclaringType(Type type) => module.UpdateRowId(ImportAsTypeSig(type, type.IsGenericButNotGenericTypeDefinition()).ToTypeDefOrRef()); /// /// Imports a as a @@ -621,26 +621,10 @@ public IField Import(FieldInfo fieldInfo, bool forceFixSignature) { origField = fieldInfo; } - MemberRef fieldRef; - if (origField.FieldType.ContainsGenericParameters) { - var origDeclType = origField.DeclaringType; - var asm = module.Context.AssemblyResolver.Resolve(origDeclType.Module.Assembly.GetName(), module); - if (asm is null || asm.FullName != origDeclType.Assembly.FullName) - throw new Exception("Couldn't resolve the correct assembly"); - var mod = asm.FindModule(origDeclType.Module.ScopeName) as ModuleDefMD; - if (mod is null) - throw new Exception("Couldn't resolve the correct module"); - var fieldDef = mod.ResolveField((uint)(origField.MetadataToken & 0x00FFFFFF)); - if (fieldDef is null) - throw new Exception("Couldn't resolve the correct field"); - - var fieldSig = new FieldSig(Import(fieldDef.FieldSig.GetFieldType())); - fieldRef = module.UpdateRowId(new MemberRefUser(module, fieldInfo.Name, fieldSig, parent)); - } - else { - var fieldSig = new FieldSig(ImportAsTypeSig(fieldInfo.FieldType, fieldInfo.GetRequiredCustomModifiers(), fieldInfo.GetOptionalCustomModifiers())); - fieldRef = module.UpdateRowId(new MemberRefUser(module, fieldInfo.Name, fieldSig, parent)); - } + bool treatAsGenericInst = fieldInfo.DeclaringType.MustTreatTypeAsGenericInstType(origField.FieldType); + var fieldSig = new FieldSig(ImportAsTypeSig(origField.FieldType, origField.GetRequiredCustomModifiers(), origField.GetOptionalCustomModifiers(), treatAsGenericInst)); + var fieldRef = module.UpdateRowId(new MemberRefUser(module, fieldInfo.Name, fieldSig, parent)); + var field = TryResolveField(fieldRef); if (FixSignature && !forceFixSignature) { //TODO: diff --git a/src/DotNet/ReflectionExtensions.cs b/src/DotNet/ReflectionExtensions.cs index 3cf1fad50..5e29bac64 100644 --- a/src/DotNet/ReflectionExtensions.cs +++ b/src/DotNet/ReflectionExtensions.cs @@ -79,6 +79,14 @@ public static ElementType GetElementType2(this Type a) { return a.IsValueType ? ElementType.ValueType : ElementType.Class; } + /// + /// Returns true if is a generic type, but + /// not a generic type definition, i.e., a TypeSpec. + /// + /// The type + public static bool IsGenericButNotGenericTypeDefinition(this Type type) => + type is not null && !type.IsGenericTypeDefinition && type.IsGenericType; + /// /// Returns true if is a generic method, but /// not a generic method definition, i.e., a MethodSpec. @@ -94,8 +102,8 @@ public static bool IsGenericButNotGenericMethodDefinition(this MethodBase mb) => /// a generic type def. This seems to happen only if the parameter type is exactly the same /// type as the declaring type, eg. a method similar to: MyType<!0> MyType::SomeMethod(). /// - /// Declaring type of method/event/property - /// Parameter/property/event type + /// Declaring type of field/method/event/property + /// Field/parameter/property/event type internal static bool MustTreatTypeAsGenericInstType(this Type declaringType, Type t) => declaringType is not null && declaringType.IsGenericTypeDefinition && t == declaringType;