Skip to content

Commit

Permalink
Merge pull request #452 from wwh1004/fix-importer
Browse files Browse the repository at this point in the history
Fix 'Importer.Import(FieldInfo)' and 'Importer.ImportDeclaringType(Type)' closes #445
  • Loading branch information
wtfsck authored Jan 31, 2022
2 parents f4e084f + 18d6c48 commit 9ea8189
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 23 deletions.
26 changes: 5 additions & 21 deletions src/DotNet/Importer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ public Importer(ModuleDef module, ImporterOptions options, GenericParamContext g
/// </summary>
/// <param name="type">The type</param>
/// <returns></returns>
public ITypeDefOrRef ImportDeclaringType(Type type) => module.UpdateRowId(ImportAsTypeSig(type, type.IsGenericTypeDefinition).ToTypeDefOrRef());
public ITypeDefOrRef ImportDeclaringType(Type type) => module.UpdateRowId(ImportAsTypeSig(type, type.IsGenericButNotGenericTypeDefinition()).ToTypeDefOrRef());

/// <summary>
/// Imports a <see cref="Type"/> as a <see cref="ITypeDefOrRef"/>
Expand Down Expand Up @@ -641,26 +641,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:
Expand Down
12 changes: 10 additions & 2 deletions src/DotNet/ReflectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ public static ElementType GetElementType2(this Type a) {
return a.IsValueType ? ElementType.ValueType : ElementType.Class;
}

/// <summary>
/// Returns <c>true</c> if <paramref name="type"/> is a generic type, but
/// not a generic type definition, i.e., a TypeSpec.
/// </summary>
/// <param name="type">The type</param>
public static bool IsGenericButNotGenericTypeDefinition(this Type type) =>
type is not null && !type.IsGenericTypeDefinition && type.IsGenericType;

/// <summary>
/// Returns <c>true</c> if <paramref name="mb"/> is a generic method, but
/// not a generic method definition, i.e., a MethodSpec.
Expand All @@ -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: <c>MyType&lt;!0&gt; MyType::SomeMethod()</c>.
/// </summary>
/// <param name="declaringType">Declaring type of method/event/property</param>
/// <param name="t">Parameter/property/event type</param>
/// <param name="declaringType">Declaring type of field/method/event/property</param>
/// <param name="t">Field/parameter/property/event type</param>
internal static bool MustTreatTypeAsGenericInstType(this Type declaringType, Type t) =>
declaringType is not null && declaringType.IsGenericTypeDefinition && t == declaringType;

Expand Down

0 comments on commit 9ea8189

Please sign in to comment.