Skip to content

Commit

Permalink
Merge branch 'development' into dependabot/nuget/development/xunit.ru…
Browse files Browse the repository at this point in the history
…nner.visualstudio-3.0.2
  • Loading branch information
Washi1337 authored Mar 2, 2025
2 parents f2b3b69 + a67c659 commit 0084987
Show file tree
Hide file tree
Showing 26 changed files with 305 additions and 150 deletions.
6 changes: 6 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ updates:
directory: "/" # Location of package manifests
schedule:
interval: "daily"
groups:
ms-dependencies:
patterns:
- "System*"
- "Microsoft*"
- "xunit*"

- package-ecosystem: "github-actions"
target-branch: "development"
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test-and-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ jobs:
architecture: ${{matrix.runner.arch}}
dotnet_target_frameworks: ${{needs.variables.outputs.DOTNET_TARGET_FRAMEWORKS}}
build_configuration: ${{matrix.build_configuration}}
# Ignore MacOS test results since support is yet lacking
is_experimental: ${{matrix.runner.image != 'windows-2022' && matrix.runner.image != 'ubuntu-22.04'}}
# TODO: Fully support tests on non-x64 and MacOS.
is_experimental: ${{matrix.runner.arch != 'x64' || (matrix.runner.image != 'windows-2022' && matrix.runner.image != 'ubuntu-22.04')}}
skip_experimental: ${{ needs.variables.outputs.EXPERIMENTAL != 'true' }}

publish:
Expand Down
3 changes: 3 additions & 0 deletions AsmResolver.sln
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TestBinaries", "TestBinaries", "{7919C544-023E-4617-A41C-27A69DB397DE}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DotNet", "DotNet", "{B3AF102B-ABE1-41B2-AE48-C40702F45AB0}"
ProjectSection(SolutionItems) = preProject
test\TestBinaries\DotNet\Directory.Build.props = test\TestBinaries\DotNet\Directory.Build.props
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HelloWorld", "test\TestBinaries\DotNet\HelloWorld\HelloWorld.csproj", "{856EEF27-8430-4360-9E4C-F923AF142D23}"
EndProject
Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
<LangVersion>10</LangVersion>
<LangVersion>12</LangVersion>
<VersionPrefix>6.0.0</VersionPrefix>
<VersionSuffix>beta.2</VersionSuffix>
<Deterministic>true</Deterministic>
Expand Down
21 changes: 14 additions & 7 deletions src/AsmResolver.DotNet.Dynamic/DynamicTypeSignatureReader.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
#if !NET8_0_OR_GREATER
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
#endif
using AsmResolver.DotNet.Signatures;

namespace AsmResolver.DotNet.Dynamic
Expand All @@ -12,18 +14,15 @@ namespace AsmResolver.DotNet.Dynamic
/// </summary>
public class DynamicTypeSignatureResolver : PhysicalTypeSignatureResolver
{
private static readonly MethodInfo? GetTypeFromHandleUnsafeMethod;

static DynamicTypeSignatureResolver()
{
// We need to use reflection for this to stay compatible with .netstandard 2.0.
GetTypeFromHandleUnsafeMethod = typeof(Type)
#if !NET8_0_OR_GREATER
// We need to use reflection for this to stay compatible with .netstandard 2.0.
private static readonly MethodInfo? GetTypeFromHandleUnsafeMethod = typeof(Type)
.GetMethod("GetTypeFromHandleUnsafe",
(BindingFlags) (-1),
null,
new[] {typeof(IntPtr)},
null);
}
#endif

/// <summary>
/// Gets the singleton instance of the <see cref="DynamicTypeSignatureResolver"/> class.
Expand All @@ -36,17 +35,25 @@ static DynamicTypeSignatureResolver()
/// <summary>
/// Gets a value indicating whether dynamic resolution of method tables is supported.
/// </summary>
#if NET8_0_OR_GREATER
public static bool IsSupported => true;
#else
[MemberNotNullWhen(true, nameof(GetTypeFromHandleUnsafeMethod))]
public static bool IsSupported => GetTypeFromHandleUnsafeMethod is not null;
#endif

/// <inheritdoc />
public override TypeSignature ResolveRuntimeType(ref BlobReaderContext context, nint address)
{
#if NET8_0_OR_GREATER
var clrType = Type.GetTypeFromHandle(RuntimeTypeHandle.FromIntPtr(address));
#else
if (!IsSupported)
throw new PlatformNotSupportedException("The current platform does not support the translation of raw type handles to System.Type instances.");

// Let the runtime translate the address to a type and import it.
var clrType = (Type?) GetTypeFromHandleUnsafeMethod.Invoke(null, new object[] { address });
#endif

var type = clrType is not null
? new ReferenceImporter(context.ReaderContext.ParentModule).ImportType(clrType)
Expand Down
53 changes: 53 additions & 0 deletions src/AsmResolver.DotNet/Signatures/Parsing/ParsedTypeFullName.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace AsmResolver.DotNet.Signatures.Parsing;

internal sealed class ParsedTypeFullName(TypeName name)
{
public TypeName Name { get; } = name;

public IList<TypeAnnotation> Annotations { get; } = new List<TypeAnnotation>();

public IResolutionScope? Scope { get; set; }

public TypeSignature ToTypeSignature(ModuleDefinition contextModule)
{
var baseTypeDefOrRef = Name.ToTypeDefOrRef(contextModule, Scope);

// The first annotation may be a generic instantiation, of which the root typesig is represented by
// GenericInstanceTypeSignature.
int startIndex = 0;
TypeSignature signature;
if (Annotations.Count > 0 && Annotations[0] is {Kind: TypeAnnotationType.GenericInstance} first)
{
var arguments = new TypeSignature[first.TypeArguments.Count];
for (int i = 0; i < first.TypeArguments.Count; i++)
arguments[i] = first.TypeArguments[i].ToTypeSignature(contextModule);

signature = baseTypeDefOrRef.MakeGenericInstanceType(arguments);
startIndex++;
}
else
{
signature = baseTypeDefOrRef.ToTypeSignature();
}

// Go over all type annotations and annotate the type signature accordingly.
for (int i = startIndex; i < Annotations.Count; i++)
{
signature = Annotations[i].Kind switch
{
TypeAnnotationType.ByReference => signature.MakeByReferenceType(),
TypeAnnotationType.Pointer => signature.MakePointerType(),
TypeAnnotationType.SzArray => signature.MakeSzArrayType(),
TypeAnnotationType.Array => signature.MakeArrayType(Annotations[i].Dimensions.ToArray()),
TypeAnnotationType.GenericInstance => throw new FormatException("Cannot instantiate a non-generic type."),
_ => throw new ArgumentOutOfRangeException()
};
}

return signature;
}
}
32 changes: 32 additions & 0 deletions src/AsmResolver.DotNet/Signatures/Parsing/TypeAnnotation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Collections.Generic;

namespace AsmResolver.DotNet.Signatures.Parsing;

internal readonly struct TypeAnnotation
{
private readonly object? _data;

public TypeAnnotation(TypeAnnotationType kind)
{
Kind = kind;
_data = null;
}

public TypeAnnotation(IList<ArrayDimension> dimensions)
{
Kind = TypeAnnotationType.Array;
_data = dimensions;
}

public TypeAnnotation(IList<ParsedTypeFullName> typeArguments)
{
Kind = TypeAnnotationType.GenericInstance;
_data = typeArguments;
}

public TypeAnnotationType Kind { get; }

public IList<ArrayDimension> Dimensions => (IList<ArrayDimension>) _data!;

public IList<ParsedTypeFullName> TypeArguments => (IList<ParsedTypeFullName>) _data!;
}
10 changes: 10 additions & 0 deletions src/AsmResolver.DotNet/Signatures/Parsing/TypeAnnotationType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace AsmResolver.DotNet.Signatures.Parsing;

internal enum TypeAnnotationType
{
ByReference,
Pointer,
SzArray,
Array,
GenericInstance,
}
44 changes: 44 additions & 0 deletions src/AsmResolver.DotNet/Signatures/Parsing/TypeName.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System.Collections.Generic;

namespace AsmResolver.DotNet.Signatures.Parsing;

internal readonly struct TypeName(string? ns, IList<string> names)
{
public string? Namespace { get; } = ns;

public IList<string> Names { get; } = names;

public ITypeDefOrRef ToTypeDefOrRef(ModuleDefinition contextModule, IResolutionScope? scope)
{
// Short circuit corlib types to avoid allocations.
if (Names.Count == 1 && contextModule.CorLibTypeFactory.FromName(Namespace, Names[0]) is {} corlibType)
return corlibType.Type;

var type = new TypeReference(contextModule, scope, Namespace, Names[0]);

// If the scope is null, it means it was omitted from the fully qualified type name.
// In this case, the CLR first looks into the current assembly, and then into corlib.
if (scope is null)
{
// First look into the current module.
type.Scope = contextModule;
var definition = type.Resolve();
if (definition is null)
{
// If that fails, try corlib.
type.Scope = contextModule.CorLibTypeFactory.CorLibScope;
definition = type.Resolve();

// If both lookups fail, revert to the normal module as scope as a fallback.
if (definition is null)
type.Scope = contextModule;
}
}

// Walk over nested type names.
for (int i = 1; i < Names.Count; i++)
type = new TypeReference(type, null, Names[i]);

return type;
}
}
11 changes: 7 additions & 4 deletions src/AsmResolver.DotNet/Signatures/Parsing/TypeNameBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.IO;
using AsmResolver.Shims;
Expand Down Expand Up @@ -172,19 +172,22 @@ private void WriteSimpleTypeName(ITypeDefOrRef? type)

private void WriteAssemblySpec(AssemblyDescriptor assembly)
{
// Order matters for Mono

WriteIdentifier(assembly.Name, true);
_writer.Write(", Version=");
_writer.Write(assembly.Version.ToString());

_writer.Write(", Culture=");
WriteIdentifier(assembly.Culture ?? "neutral");

_writer.Write(", PublicKeyToken=");

var token = assembly.GetPublicKeyToken();
if (token is null)
_writer.Write("null");
else
WriteHexBlob(token);

_writer.Write(", Culture=");
WriteIdentifier(assembly.Culture ?? "neutral");
}

private void WriteIdentifier(string? identifier, bool escapeDots = false)
Expand Down
Loading

0 comments on commit 0084987

Please sign in to comment.