From 6014534eeb75179dca7095235ba5bff47038908f Mon Sep 17 00:00:00 2001 From: CreateAndInject Date: Wed, 12 Jul 2023 05:29:33 +0800 Subject: [PATCH] Improve Importer TryToUseTypeDefs --- src/DotNet/Importer.cs | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/DotNet/Importer.cs b/src/DotNet/Importer.cs index aa0f02b8f..8004f977c 100644 --- a/src/DotNet/Importer.cs +++ b/src/DotNet/Importer.cs @@ -84,9 +84,9 @@ public abstract class ImportMapper { /// Overrides default behavior of /// May be used to use reference assemblies for resolution, for example. /// - /// to create for. is non-generic type or generic type without generic arguments. - /// or null to use default 's type resolution - public virtual TypeRef Map(Type source) => null; + /// to create for. is non-generic type or generic type without generic arguments. + /// or null to use default 's type resolution + public virtual ITypeDefOrRef Map(Type source) => null; } /// @@ -223,8 +223,8 @@ TypeSig ImportAsTypeSig(Type type, Type declaringType, bool? treatAsGenericInst case ElementType.Ptr: return new PtrSig(ImportAsTypeSig(type.GetElementType(), declaringType)); case ElementType.ByRef: return new ByRefSig(ImportAsTypeSig(type.GetElementType(), declaringType)); case ElementType.SZArray: return new SZArraySig(ImportAsTypeSig(type.GetElementType(), declaringType)); - case ElementType.ValueType: return new ValueTypeSig(CreateTypeRef(type)); - case ElementType.Class: return new ClassSig(CreateTypeRef(type)); + case ElementType.ValueType: return new ValueTypeSig(CreateTypeDefOrRef(type)); + case ElementType.Class: return new ClassSig(CreateTypeDefOrRef(type)); case ElementType.Var: return new GenericVar((uint)type.GenericParameterPosition, gpContext.Type); case ElementType.MVar: return new GenericMVar((uint)type.GenericParameterPosition, gpContext.Method); @@ -356,13 +356,26 @@ static bool Equals(IAssembly a, IAssembly b) { UTF8String.CaseInsensitiveEquals(a.Culture, b.Culture); } - ITypeDefOrRef CreateTypeRef(Type type) => TryResolve(mapper?.Map(type) ?? CreateTypeRef2(type)); + ITypeDefOrRef CreateTypeDefOrRef(Type type) { + var tdr = mapper?.Map(type); + if (tdr is TypeSpec) + throw new InvalidOperationException(); + if (tdr is TypeDef td) + return td; + if (tdr is TypeRef tr) + return TryResolve(tr); + + if (TryToUseTypeDefs && IsThisModule(type.Module) && module.ResolveToken(type.MetadataToken) is TypeDef def) + return def; + + return TryResolve(CreateTypeRef(type)); + } - TypeRef CreateTypeRef2(Type type) { + TypeRef CreateTypeRef(Type type) { if (!type.IsNested) return module.UpdateRowId(new TypeRefUser(module, type.Namespace ?? string.Empty, ReflectionExtensions.Unescape(type.Name) ?? string.Empty, CreateScopeReference(type))); type.GetTypeNamespaceAndName_TypeDefOrRef(out var @namespace, out var name); - return module.UpdateRowId(new TypeRefUser(module, @namespace ?? string.Empty, name ?? string.Empty, CreateTypeRef2(type.DeclaringType))); + return module.UpdateRowId(new TypeRefUser(module, @namespace ?? string.Empty, name ?? string.Empty, CreateTypeRef(type.DeclaringType))); } IResolutionScope CreateScopeReference(Type type) {