Skip to content

Commit

Permalink
Fix Importer and SigComparer‘s handling of generic when must treat ge…
Browse files Browse the repository at this point in the history
…neric type definition as generic instantiation type.

Mark Importer.ImportDeclaringType(Type) as obsolete.
  • Loading branch information
wwh1004 committed May 28, 2022
1 parent aa403ba commit 4f485e2
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 67 deletions.
50 changes: 26 additions & 24 deletions src/DotNet/Importer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,20 +167,19 @@ public Importer(ModuleDef module, ImporterOptions options, GenericParamContext g
}

/// <summary>
/// Imports a <see cref="Type"/> as a <see cref="ITypeDefOrRef"/>. If it's a type that should be
/// the declaring type of a field/method reference, call <see cref="ImportDeclaringType(Type)"/> instead.
/// Imports a <see cref="Type"/> as a <see cref="ITypeDefOrRef"/>.
/// </summary>
/// <param name="type">The type</param>
/// <returns>The imported type or <c>null</c> if <paramref name="type"/> is invalid</returns>
public ITypeDefOrRef Import(Type type) => module.UpdateRowId(ImportAsTypeSig(type).ToTypeDefOrRef());

/// <summary>
/// Imports a <see cref="Type"/> as a <see cref="ITypeDefOrRef"/>. Should be called if it's the
/// declaring type of a method/field reference. See also <see cref="Import(Type)"/>
/// Imports a <see cref="Type"/> as a <see cref="ITypeDefOrRef"/>. See also <see cref="Import(Type)"/>
/// </summary>
/// <param name="type">The type</param>
/// <returns></returns>
public ITypeDefOrRef ImportDeclaringType(Type type) => module.UpdateRowId(ImportAsTypeSig(type, type.IsGenericButNotGenericTypeDefinition()).ToTypeDefOrRef());
[Obsolete("Use 'Import(Type)' instead.")]
public ITypeDefOrRef ImportDeclaringType(Type type) => Import(type);

/// <summary>
/// Imports a <see cref="Type"/> as a <see cref="ITypeDefOrRef"/>
Expand All @@ -197,12 +196,13 @@ public ITypeDefOrRef Import(Type type, IList<Type> requiredModifiers, IList<Type
/// </summary>
/// <param name="type">The type</param>
/// <returns>The imported type or <c>null</c> if <paramref name="type"/> is invalid</returns>
public TypeSig ImportAsTypeSig(Type type) => ImportAsTypeSig(type, false);
public TypeSig ImportAsTypeSig(Type type) => ImportAsTypeSig(type, null, false);

TypeSig ImportAsTypeSig(Type type, bool treatAsGenericInst) {
TypeSig ImportAsTypeSig(Type type, Type declaringType, bool? treatAsGenericInst = null) {
if (type is null)
return null;
switch (treatAsGenericInst ? ElementType.GenericInst : type.GetElementType2()) {
bool treatAsGenericInst2 = treatAsGenericInst ?? declaringType.MustTreatTypeAsGenericInstType(type);
switch (treatAsGenericInst2 ? ElementType.GenericInst : type.GetElementType2()) {
case ElementType.Void: return module.CorLibTypes.Void;
case ElementType.Boolean: return module.CorLibTypes.Boolean;
case ElementType.Char: return module.CorLibTypes.Char;
Expand All @@ -220,9 +220,9 @@ TypeSig ImportAsTypeSig(Type type, bool treatAsGenericInst) {
case ElementType.TypedByRef:return module.CorLibTypes.TypedReference;
case ElementType.U: return module.CorLibTypes.UIntPtr;
case ElementType.Object: return module.CorLibTypes.Object;
case ElementType.Ptr: return new PtrSig(ImportAsTypeSig(type.GetElementType(), treatAsGenericInst));
case ElementType.ByRef: return new ByRefSig(ImportAsTypeSig(type.GetElementType(), treatAsGenericInst));
case ElementType.SZArray: return new SZArraySig(ImportAsTypeSig(type.GetElementType(), 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.Var: return new GenericVar((uint)type.GenericParameterPosition, gpContext.Type);
Expand All @@ -237,13 +237,13 @@ TypeSig ImportAsTypeSig(Type type, bool treatAsGenericInst) {
var lowerBounds = new int[type.GetArrayRank()];
var sizes = Array2.Empty<uint>();
FixSignature = true;
return new ArraySig(ImportAsTypeSig(type.GetElementType(), treatAsGenericInst), (uint)type.GetArrayRank(), sizes, lowerBounds);
return new ArraySig(ImportAsTypeSig(type.GetElementType(), declaringType), (uint)type.GetArrayRank(), sizes, lowerBounds);

case ElementType.GenericInst:
var typeGenArgs = type.GetGenericArguments();
var git = new GenericInstSig(ImportAsTypeSig(type.GetGenericTypeDefinition()) as ClassOrValueTypeSig, (uint)typeGenArgs.Length);
var git = new GenericInstSig(ImportAsTypeSig(type.GetGenericTypeDefinition(), null, false) as ClassOrValueTypeSig, (uint)typeGenArgs.Length);
foreach (var ga in typeGenArgs)
git.GenericArguments.Add(ImportAsTypeSig(ga));
git.GenericArguments.Add(ImportAsTypeSig(ga, declaringType));
return git;

case ElementType.Sentinel:
Expand Down Expand Up @@ -393,16 +393,16 @@ IResolutionScope CreateScopeReference(Type type) {
/// <param name="optionalModifiers">A list of all optional modifiers or <c>null</c></param>
/// <returns>The imported type or <c>null</c> if <paramref name="type"/> is invalid</returns>
public TypeSig ImportAsTypeSig(Type type, IList<Type> requiredModifiers, IList<Type> optionalModifiers) =>
ImportAsTypeSig(type, requiredModifiers, optionalModifiers, false);
ImportAsTypeSig(type, requiredModifiers, optionalModifiers, null);

TypeSig ImportAsTypeSig(Type type, IList<Type> requiredModifiers, IList<Type> optionalModifiers, bool treatAsGenericInst) {
TypeSig ImportAsTypeSig(Type type, IList<Type> requiredModifiers, IList<Type> optionalModifiers, Type declaringType) {
if (type is null)
return null;
if (IsEmpty(requiredModifiers) && IsEmpty(optionalModifiers))
return ImportAsTypeSig(type, treatAsGenericInst);
return ImportAsTypeSig(type, declaringType);

FixSignature = true; // Order of modifiers is unknown
var ts = ImportAsTypeSig(type, treatAsGenericInst);
var ts = ImportAsTypeSig(type, declaringType);

// We don't know the original order of the modifiers.
// Assume all required modifiers are closer to the real type.
Expand Down Expand Up @@ -469,11 +469,13 @@ IMethod ImportInternal(MethodBase methodBase, bool forceFixSignature) {
IMethodDefOrRef method;
var origMethod = methodBase.Module.ResolveMethod(methodBase.MetadataToken);
if (methodBase.DeclaringType.GetElementType2() == ElementType.GenericInst)
method = module.UpdateRowId(new MemberRefUser(module, methodBase.Name, CreateMethodSig(origMethod), ImportDeclaringType(methodBase.DeclaringType)));
method = module.UpdateRowId(new MemberRefUser(module, methodBase.Name, CreateMethodSig(origMethod), Import(methodBase.DeclaringType)));
else
method = ImportInternal(origMethod) as IMethodDefOrRef;

method = TryResolveMethod(method);
if (methodBase.ContainsGenericParameters)
return method; // Declaring type is instantiated but method itself is not

var gim = CreateGenericInstMethodSig(methodBase);
var methodSpec = module.UpdateRowId(new MethodSpecUser(method, gim));
Expand All @@ -489,7 +491,7 @@ IMethod ImportInternal(MethodBase methodBase, bool forceFixSignature) {
parent = GetModuleParent(methodBase.Module);
}
else
parent = ImportDeclaringType(methodBase.DeclaringType);
parent = Import(methodBase.DeclaringType);
if (parent is null)
return null;

Expand Down Expand Up @@ -536,7 +538,7 @@ MethodSig CreateMethodSig(MethodBase mb) {
}

TypeSig ImportAsTypeSig(ParameterInfo p, Type declaringType) =>
ImportAsTypeSig(p.ParameterType, p.GetRequiredCustomModifiers(), p.GetOptionalCustomModifiers(), declaringType.MustTreatTypeAsGenericInstType(p.ParameterType));
ImportAsTypeSig(p.ParameterType, p.GetRequiredCustomModifiers(), p.GetOptionalCustomModifiers(), declaringType);

CallingConvention GetCallingConvention(MethodBase mb) {
CallingConvention cc = 0;
Expand Down Expand Up @@ -627,7 +629,7 @@ public IField Import(FieldInfo fieldInfo, bool forceFixSignature) {
parent = GetModuleParent(fieldInfo.Module);
}
else
parent = ImportDeclaringType(fieldInfo.DeclaringType);
parent = Import(fieldInfo.DeclaringType);
if (parent is null)
return null;

Expand All @@ -641,8 +643,8 @@ public IField Import(FieldInfo fieldInfo, bool forceFixSignature) {
origField = fieldInfo;
}

bool treatAsGenericInst = fieldInfo.DeclaringType.MustTreatTypeAsGenericInstType(origField.FieldType);
var fieldSig = new FieldSig(ImportAsTypeSig(origField.FieldType, origField.GetRequiredCustomModifiers(), origField.GetOptionalCustomModifiers(), treatAsGenericInst));
var fieldSig = new FieldSig(ImportAsTypeSig(origField.FieldType,
origField.GetRequiredCustomModifiers(), origField.GetOptionalCustomModifiers(), origField.DeclaringType));
var fieldRef = module.UpdateRowId(new MemberRefUser(module, fieldInfo.Name, fieldSig, parent));

var field = TryResolveField(fieldRef);
Expand Down
Loading

0 comments on commit 4f485e2

Please sign in to comment.