Browse Source

DecompilerTypeSystem: Add support for implicit references

pull/2642/head
Siegfried Pammer 3 years ago
parent
commit
50cfcc214c
  1. 2
      ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs
  2. 32
      ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs

2
ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs

@ -147,6 +147,8 @@ namespace ICSharpCode.Decompiler.Metadata @@ -147,6 +147,8 @@ namespace ICSharpCode.Decompiler.Metadata
internal static (TargetFrameworkIdentifier, Version) ParseTargetFramework(string targetFramework)
{
if (string.IsNullOrEmpty(targetFramework))
return (TargetFrameworkIdentifier.NETFramework, ZeroVersion);
string[] tokens = targetFramework.Split(',');
TargetFrameworkIdentifier identifier;

32
ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs

@ -210,6 +210,11 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -210,6 +210,11 @@ namespace ICSharpCode.Decompiler.TypeSystem
InitializeAsync(mainModule, assemblyResolver, typeSystemOptions).GetAwaiter().GetResult();
}
static readonly string[] implicitReferences = new[] {
"System.Runtime.InteropServices",
"System.Runtime.CompilerServices.Unsafe"
};
private async Task InitializeAsync(PEFile mainModule, IAssemblyResolver assemblyResolver, TypeSystemOptions typeSystemOptions)
{
// Load referenced assemblies and type-forwarder references.
@ -217,10 +222,12 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -217,10 +222,12 @@ namespace ICSharpCode.Decompiler.TypeSystem
var referencedAssemblies = new List<PEFile>();
var assemblyReferenceQueue = new Queue<(bool IsAssembly, PEFile MainModule, object Reference, Task<PEFile> ResolveTask)>();
var comparer = KeyComparer.Create(((bool IsAssembly, PEFile MainModule, object Reference) reference) =>
reference.IsAssembly ? "A:" + ((AssemblyReference)reference.Reference).FullName :
reference.IsAssembly ? "A:" + ((IAssemblyReference)reference.Reference).FullName :
"M:" + reference.Reference);
var assemblyReferencesInQueue = new HashSet<(bool IsAssembly, PEFile Parent, object Reference)>(comparer);
var mainMetadata = mainModule.Metadata;
var tfm = mainModule.DetectTargetFrameworkId();
var (identifier, version) = UniversalAssemblyResolver.ParseTargetFramework(tfm);
foreach (var h in mainMetadata.GetModuleReferences())
{
try
@ -268,6 +275,27 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -268,6 +275,27 @@ namespace ICSharpCode.Decompiler.TypeSystem
}
}
}
if (assemblyReferenceQueue.Count == 0)
{
// For .NET Core and .NET 5 and newer, we need to pull in implicit references which are not included in the metadata,
// as they contain compile-time-only types, such as System.Runtime.InteropServices.dll (for DllImport, MarshalAs, etc.)
switch (identifier)
{
case TargetFrameworkIdentifier.NETCoreApp:
case TargetFrameworkIdentifier.NETStandard:
case TargetFrameworkIdentifier.NET:
foreach (var item in implicitReferences)
{
var existing = referencedAssemblies.FirstOrDefault(asm => asm.Name == item);
if (existing == null)
{
AddToQueue(true, mainModule, AssemblyNameReference.Parse(item + ", Version=" + version.ToString(3) + ".0, Culture=neutral"));
}
}
break;
}
}
}
var mainModuleWithOptions = mainModule.WithOptions(typeSystemOptions);
var referencedAssembliesWithOptions = referencedAssemblies.Select(file => file.WithOptions(typeSystemOptions));
@ -294,7 +322,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -294,7 +322,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
Task<PEFile> asm;
if (isAssembly)
{
asm = assemblyResolver.ResolveAsync((AssemblyReference)reference);
asm = assemblyResolver.ResolveAsync((IAssemblyReference)reference);
}
else
{

Loading…
Cancel
Save