Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Let TypeNameParser not return fully imported types #497

Merged
merged 3 commits into from
Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/AsmResolver.DotNet/DefaultMetadataResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,13 @@ public TypeResolution(IAssemblyResolver resolver)
switch (scope.MetadataToken.Table)
{
case TableIndex.AssemblyRef:
if (reference.Module?.Assembly is { } assembly)
{
// Are we referencing the current assembly the reference was declared in?
if (SignatureComparer.Default.Equals(scope.GetAssembly(), assembly))
return FindTypeInModule(reference.Module, reference.Namespace, reference.Name);
}

var assemblyDefScope = _assemblyResolver.Resolve((AssemblyReference) scope);
return assemblyDefScope is not null
? FindTypeInAssembly(assemblyDefScope, reference.Namespace, reference.Name)
Expand Down
4 changes: 3 additions & 1 deletion src/AsmResolver.DotNet/Signatures/CustomAttributeArgument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ public class CustomAttributeArgument
/// <param name="argumentType">The type of the argument to read.</param>
/// <param name="reader">The input stream.</param>
/// <returns>The argument.</returns>
public static CustomAttributeArgument FromReader(in BlobReaderContext context, TypeSignature argumentType,
public static CustomAttributeArgument FromReader(
in BlobReaderContext context,
TypeSignature argumentType,
ref BinaryStreamReader reader)
{
var elementReader = CustomAttributeArgumentReader.Create();
Expand Down
3 changes: 2 additions & 1 deletion src/AsmResolver.DotNet/TypeReference.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ public TypeSignature ToTypeSignature(bool isValueType)
}

/// <inheritdoc />
public bool IsImportedInModule(ModuleDefinition module) => Module == module;
public bool IsImportedInModule(ModuleDefinition module) =>
Module == module && (Scope?.IsImportedInModule(module) ?? false);

/// <summary>
/// Imports the type reference using the provided reference importer object.
Expand Down
23 changes: 13 additions & 10 deletions test/AsmResolver.DotNet.Tests/CustomAttributeTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ private static CustomAttribute GetCustomAttributeTestCase(
attributeName += "`1";

var attribute = method.CustomAttributes
.First(c => c.Constructor!.DeclaringType!.Name.Value.StartsWith(attributeName));
.First(c => c.Constructor!.DeclaringType!.Name!.Value.StartsWith(attributeName));

if (access)
{
Expand Down Expand Up @@ -197,10 +197,13 @@ public void FixedComplexTypeArgument(bool rebuild, bool access)
var argument = attribute.Signature.FixedArguments[0];
var factory = attribute.Constructor!.Module!.CorLibTypeFactory;

var listRef = new TypeReference(factory.CorLibScope, "System.Collections.Generic", "KeyValuePair`2");
var instance = new GenericInstanceTypeSignature(listRef, false,
new SzArrayTypeSignature(factory.String),
new SzArrayTypeSignature(factory.Int32));
var instance = factory.CorLibScope
.CreateTypeReference("System.Collections.Generic", "KeyValuePair`2")
.MakeGenericInstanceType(
false,
factory.String.MakeSzArrayType(),
factory.Int32.MakeSzArrayType()
);

Assert.Equal(instance, argument.Element as TypeSignature, _comparer);
}
Expand Down Expand Up @@ -293,7 +296,7 @@ public void GenericTypeArgument(bool rebuild, bool access)

var module = attribute.Constructor!.Module!;
var nestedClass = (TypeDefinition) module.LookupMember(typeof(TestGenericType<>).MetadataToken);
var expected = new GenericInstanceTypeSignature(nestedClass, false, module.CorLibTypeFactory.Object);
var expected = nestedClass.MakeGenericInstanceType(false, module.CorLibTypeFactory.Object);

var element = Assert.IsAssignableFrom<TypeSignature>(argument.Element);
Assert.Equal(expected, element, _comparer);
Expand All @@ -312,9 +315,9 @@ public void ArrayGenericTypeArgument(bool rebuild, bool access)

var module = attribute.Constructor!.Module!;
var nestedClass = (TypeDefinition) module.LookupMember(typeof(TestGenericType<>).MetadataToken);
var expected = new SzArrayTypeSignature(
new GenericInstanceTypeSignature(nestedClass, false, module.CorLibTypeFactory.Object)
);
var expected = nestedClass
.MakeGenericInstanceType(false, module.CorLibTypeFactory.Object)
.MakeSzArrayType();

var element = Assert.IsAssignableFrom<TypeSignature>(argument.Element);
Assert.Equal(expected, element, _comparer);
Expand Down Expand Up @@ -413,7 +416,7 @@ public void FixedInt32EmptyArrayAsObject(bool rebuild, bool access)
var attribute = GetCustomAttributeTestCase(nameof(CustomAttributesTestClass.FixedInt32ArrayAsObjectEmptyArgument),rebuild, access);
var argument = attribute.Signature!.FixedArguments[0];

var boxedArgument =Assert.IsAssignableFrom<BoxedArgument>(argument.Element);
var boxedArgument = Assert.IsAssignableFrom<BoxedArgument>(argument.Element);
Assert.Equal(Array.Empty<object>(), boxedArgument.Value);
}

Expand Down
8 changes: 5 additions & 3 deletions test/AsmResolver.DotNet.Tests/ReferenceImporterTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -421,9 +421,10 @@ public void ImportCustomModifierTypeWithNonImportedModifierTypeShouldResultInNew
[Fact]
public void ImportFullyImportedCustomModifierTypeShouldResultInSameInstance()
{
var signature = new TypeReference(_module, _dummyAssembly, "SomeNamespace", "SomeType")
var assembly = _importer.ImportScope(_dummyAssembly);
var signature = new TypeReference(_module, assembly, "SomeNamespace", "SomeType")
.ToTypeSignature()
.MakeModifierType(new TypeReference(_module, _dummyAssembly, "SomeNamespace", "SomeModifierType"), true);
.MakeModifierType(new TypeReference(_module, assembly, "SomeNamespace", "SomeModifierType"), true);

var imported = _importer.ImportTypeSignature(signature);

Expand Down Expand Up @@ -470,10 +471,11 @@ public void ImportFunctionPointerTypeWithNonImportedReturnTypeShouldResultInNewI
[Fact]
public void ImportFullyImportedFunctionPointerTypeShouldResultInSameInstance()
{
var assembly = _importer.ImportScope(_dummyAssembly);
var signature = MethodSignature
.CreateStatic(
_module.CorLibTypeFactory.Void,
new TypeReference(_module, _dummyAssembly, "SomeNamespace", "SomeType").ToTypeSignature())
new TypeReference(_module, assembly, "SomeNamespace", "SomeType").ToTypeSignature())
.MakeFunctionPointerType();

var imported = _importer.ImportTypeSignature(signature);
Expand Down
18 changes: 14 additions & 4 deletions test/AsmResolver.DotNet.Tests/Signatures/TypeNameParserTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,7 @@ public void TypeWithAssemblyName()
var assemblyRef = new AssemblyReference("MyAssembly", new Version(1, 2, 3, 4));
var expected = new TypeReference(assemblyRef, ns, name).ToTypeSignature();


var actual = TypeNameParser.Parse(_module,
$"{ns}.{name}, {assemblyRef.FullName}");
var actual = TypeNameParser.Parse(_module, $"{ns}.{name}, {assemblyRef.FullName}");
Assert.Equal(expected, actual, _comparer);
}

Expand Down Expand Up @@ -141,7 +139,7 @@ public void GenericTypeSingleBrackets()
var elementType = new TypeReference(_module, ns, name);
var argumentType = _module.CorLibTypeFactory.Object;

var expected = new GenericInstanceTypeSignature(elementType, false, argumentType);
var expected = elementType.MakeGenericInstanceType(false, argumentType);

var actual = TypeNameParser.Parse(_module, $"{ns}.{name}[{argumentType.Namespace}.{argumentType.Name}]");
Assert.Equal(expected, actual, _comparer);
Expand Down Expand Up @@ -299,5 +297,17 @@ public void ReadTypeShouldUseNewScopeInstanceIfNotImportedYet()
"SomeNamespace.SomeType, SomeAssembly, Version=1.2.3.4, Culture=neutral, PublicKeyToken=0123456789abcdef");
Assert.DoesNotContain(type.Scope!.GetAssembly(), _module.AssemblyReferences);
}

[Fact]
public void ReadTypeNameFromLocalModuleShouldResultInResolvableType()
{
var module = ModuleDefinition.FromFile(typeof(TypeNameParserTest).Assembly.Location);
var type = TypeNameParser
.Parse(module, typeof(TypeNameParserTest).AssemblyQualifiedName!)
.GetUnderlyingTypeDefOrRef()!;

Assert.NotNull(type.Resolve());
Assert.NotNull(type.ImportWith(module.DefaultImporter).Resolve());
}
}
}