Browse Source

Simplify PEFile API

pull/1198/head
Siegfried Pammer 7 years ago
parent
commit
d5f7cd46fc
  1. 3
      ICSharpCode.Decompiler.Tests/DecompilerTestBase.cs
  2. 9
      ICSharpCode.Decompiler.Tests/Helpers/Tester.cs
  3. 6
      ICSharpCode.Decompiler.Tests/RoundtripAssembly.cs
  4. 20
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  5. 13
      ICSharpCode.Decompiler/Metadata/Dom.cs
  6. 26
      ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs
  7. 4
      ICSharpCode.Decompiler/TypeSystem/MetadataLoader.cs
  8. 5
      ILSpy.BamlDecompiler.Tests/BamlTestRunner.cs
  9. 11
      ILSpy/LoadedAssembly.cs

3
ICSharpCode.Decompiler.Tests/DecompilerTestBase.cs

@ -52,8 +52,7 @@ namespace ICSharpCode.Decompiler.Tests @@ -52,8 +52,7 @@ namespace ICSharpCode.Decompiler.Tests
{
var code = RemoveIgnorableLines(File.ReadLines(fileName));
using (var assembly = CompileLegacy(code, optimize, useDebug, compilerVersion)) {
var module = new Metadata.PEFile("temp.exe", assembly, PEStreamOptions.Default);
module.AssemblyResolver = new Metadata.UniversalAssemblyResolver(fileName, false, true, module.Reader.DetectTargetFrameworkId(), PEStreamOptions.Default);
var module = new PEFile("temp.exe", assembly, throwOnResolveError: false, options: PEStreamOptions.PrefetchEntireImage);
CSharpDecompiler decompiler = new CSharpDecompiler(module, new DecompilerSettings());
decompiler.AstTransforms.Insert(0, new RemoveEmbeddedAtttributes());

9
ICSharpCode.Decompiler.Tests/Helpers/Tester.cs

@ -112,7 +112,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -112,7 +112,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
{
if (asmOptions.HasFlag(AssemblerOptions.UseOwnDisassembler)) {
using (var peFileStream = new FileStream(sourceFileName, FileMode.Open, FileAccess.Read))
using (var peFile = new PEFile(sourceFileName, peFileStream, PEStreamOptions.Default))
using (var peFile = new PEFile(sourceFileName, peFileStream))
using (var writer = new StringWriter()) {
var metadata = peFile.GetMetadataReader();
var output = new PlainTextOutput(writer);
@ -341,8 +341,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -341,8 +341,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
var emitResult = compilation.Emit(peStream);
peStream.Position = 0;
var moduleDefinition = new PEFile("TestAssembly.dll", peStream, PEStreamOptions.Default);
moduleDefinition.AssemblyResolver = new UniversalAssemblyResolver(typeof(Tester).Assembly.Location, false, true, moduleDefinition.Reader.DetectTargetFrameworkId(), PEStreamOptions.Default);
var moduleDefinition = new PEFile("TestAssembly.dll", peStream, false, PEStreamOptions.PrefetchEntireImage);
var decompiler = new CSharpDecompiler(moduleDefinition, new DecompilerSettings());
return decompiler;
@ -388,9 +387,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -388,9 +387,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
public static string DecompileCSharp(string assemblyFileName, DecompilerSettings settings = null)
{
using (var file = new FileStream(assemblyFileName, FileMode.Open, FileAccess.Read)) {
var module = new PEFile(assemblyFileName, file, PEStreamOptions.Default);
var resolver = new UniversalAssemblyResolver(assemblyFileName, false, true, module.Reader.DetectTargetFrameworkId(), PEStreamOptions.Default);
module.AssemblyResolver = resolver;
var module = new PEFile(assemblyFileName, file, false, PEStreamOptions.PrefetchEntireImage);
var typeSystem = new DecompilerTypeSystem(module);
CSharpDecompiler decompiler = new CSharpDecompiler(typeSystem, settings ?? new DecompilerSettings());
decompiler.AstTransforms.Insert(0, new RemoveEmbeddedAtttributes());

6
ICSharpCode.Decompiler.Tests/RoundtripAssembly.cs

@ -20,6 +20,7 @@ using System; @@ -20,6 +20,7 @@ using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection.PortableExecutable;
using System.Text.RegularExpressions;
using System.Threading;
using ICSharpCode.Decompiler.CSharp;
@ -143,11 +144,10 @@ namespace ICSharpCode.Decompiler.Tests @@ -143,11 +144,10 @@ namespace ICSharpCode.Decompiler.Tests
Console.WriteLine($"Decompiling {fileToRoundtrip}...");
Stopwatch w = Stopwatch.StartNew();
using (var fileStream = new FileStream(file, FileMode.Open, FileAccess.Read)) {
PEFile module = new PEFile(file, fileStream, System.Reflection.PortableExecutable.PEStreamOptions.Default);
var resolver = new UniversalAssemblyResolver(file, false, true, module.Reader.DetectTargetFrameworkId(), System.Reflection.PortableExecutable.PEStreamOptions.Default);
PEFile module = new PEFile(file, fileStream, false, PEStreamOptions.PrefetchEntireImage);
UniversalAssemblyResolver resolver = (UniversalAssemblyResolver)module.AssemblyResolver;
resolver.AddSearchDirectory(inputDir);
resolver.RemoveSearchDirectory(".");
module.AssemblyResolver = resolver;
var decompiler = new TestProjectDecompiler(inputDir);
// use a fixed GUID so that we can diff the output between different ILSpy runs without spurious changes
decompiler.ProjectGuid = Guid.Parse("{127C83E4-4587-4CF9-ADCA-799875F3DFE6}");

20
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -38,6 +38,7 @@ using System.Runtime.InteropServices; @@ -38,6 +38,7 @@ using System.Runtime.InteropServices;
using System.Reflection.Metadata;
using SRM = System.Reflection.Metadata;
using ICSharpCode.Decompiler.Metadata;
using System.Reflection.PortableExecutable;
namespace ICSharpCode.Decompiler.CSharp
{
@ -301,19 +302,14 @@ namespace ICSharpCode.Decompiler.CSharp @@ -301,19 +302,14 @@ namespace ICSharpCode.Decompiler.CSharp
}
#endregion
static Metadata.PEFile LoadPEFile(string fileName, DecompilerSettings settings)
static PEFile LoadPEFile(string fileName, DecompilerSettings settings)
{
Stream stream;
if (settings.LoadInMemory) {
using (var fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read)) {
stream = new MemoryStream();
fileStream.CopyTo(stream);
stream.Position = 0;
}
} else {
stream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
}
return new Metadata.PEFile(fileName, stream, System.Reflection.PortableExecutable.PEStreamOptions.Default);
return new PEFile(
fileName,
new FileStream(fileName, FileMode.Open, FileAccess.Read),
settings.ThrowOnAssemblyResolveErrors,
options: settings.LoadInMemory ? PEStreamOptions.PrefetchEntireImage : PEStreamOptions.Default
);
}
TypeSystemAstBuilder CreateAstBuilder(ITypeResolveContext decompilationContext)

13
ICSharpCode.Decompiler/Metadata/Dom.cs

@ -94,14 +94,22 @@ namespace ICSharpCode.Decompiler.Metadata @@ -94,14 +94,22 @@ namespace ICSharpCode.Decompiler.Metadata
{
public string FileName { get; }
public PEReader Reader { get; }
public IAssemblyResolver AssemblyResolver { get; set; }
public IAssemblyResolver AssemblyResolver { get; }
public IAssemblyDocumentationResolver DocumentationResolver { get; set; }
public IDebugInfoProvider DebugInfo { get; set; }
public PEFile(string fileName, Stream stream, PEStreamOptions options)
public PEFile(string fileName, Stream stream, bool throwOnResolveError = false, PEStreamOptions options = PEStreamOptions.Default)
{
this.FileName = fileName;
this.Reader = new PEReader(stream, options);
this.AssemblyResolver = new UniversalAssemblyResolver(fileName, throwOnResolveError, Reader.DetectTargetFrameworkId(), options);
}
public PEFile(string fileName, Stream stream, IAssemblyResolver assemblyResolver, PEStreamOptions options = PEStreamOptions.Default)
{
this.FileName = fileName;
this.Reader = new PEReader(stream, options);
this.AssemblyResolver = assemblyResolver;
}
public bool IsAssembly => GetMetadataReader().IsAssembly;
@ -140,7 +148,6 @@ namespace ICSharpCode.Decompiler.Metadata @@ -140,7 +148,6 @@ namespace ICSharpCode.Decompiler.Metadata
public ImmutableArray<AssemblyReference> AssemblyReferences => GetMetadataReader().AssemblyReferences.Select(r => new AssemblyReference(this, r)).ToImmutableArray();
public ImmutableArray<ModuleReferenceHandle> ModuleReferences => GetMetadataReader().GetModuleReferences().ToImmutableArray();
public ImmutableArray<TypeDefinition> TypeDefinitions => Reader.GetMetadataReader().GetTopLevelTypeDefinitions().Select(t => new TypeDefinition(this, t)).ToImmutableArray();
public ImmutableArray<TypeReference> TypeReferences => Reader.GetMetadataReader().TypeReferences.Select(t => new TypeReference(this, t)).ToImmutableArray();
public ImmutableArray<Resource> Resources => GetResources().ToImmutableArray();
IEnumerable<Resource> GetResources()

26
ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs

@ -10,7 +10,6 @@ namespace ICSharpCode.Decompiler.Metadata @@ -10,7 +10,6 @@ namespace ICSharpCode.Decompiler.Metadata
{
DotNetCorePathFinder dotNetCorePathFinder;
readonly bool throwOnError;
readonly bool inMemory;
readonly PEStreamOptions options;
readonly string mainAssemblyFileName;
readonly string baseDirectory;
@ -49,9 +48,8 @@ namespace ICSharpCode.Decompiler.Metadata @@ -49,9 +48,8 @@ namespace ICSharpCode.Decompiler.Metadata
public string TargetFramework { get; }
public UniversalAssemblyResolver(string mainAssemblyFileName, bool throwOnError, bool inMemory, string targetFramework, PEStreamOptions options)
public UniversalAssemblyResolver(string mainAssemblyFileName, bool throwOnError, string targetFramework, PEStreamOptions options)
{
this.inMemory = inMemory;
this.options = options;
this.TargetFramework = targetFramework;
this.mainAssemblyFileName = mainAssemblyFileName;
@ -70,17 +68,7 @@ namespace ICSharpCode.Decompiler.Metadata @@ -70,17 +68,7 @@ namespace ICSharpCode.Decompiler.Metadata
throw new AssemblyResolutionException(name);
return null;
}
Stream stream;
if (inMemory) {
using (var fileStream = new FileStream(file, FileMode.Open, FileAccess.Read)) {
stream = new MemoryStream();
fileStream.CopyTo(stream);
}
} else {
stream = new FileStream(file, FileMode.Open, FileAccess.Read);
}
stream.Position = 0;
return new PEFile(file, stream, options);
return new PEFile(file, new FileStream(file, FileMode.Open, FileAccess.Read), this, options);
}
public string FindAssemblyFile(IAssemblyReference name)
@ -334,15 +322,5 @@ namespace ICSharpCode.Decompiler.Metadata @@ -334,15 +322,5 @@ namespace ICSharpCode.Decompiler.Metadata
}
#endregion
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
}
}
}

4
ICSharpCode.Decompiler/TypeSystem/MetadataLoader.cs

@ -272,12 +272,12 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -272,12 +272,12 @@ namespace ICSharpCode.Decompiler.TypeSystem
#endregion
#region Load Assembly From Disk
public IUnresolvedAssembly LoadAssemblyFile(string fileName)
public IUnresolvedAssembly LoadAssemblyFile(string fileName, bool throwOnResolveError = true, PEStreamOptions options = PEStreamOptions.Default)
{
if (fileName == null)
throw new ArgumentNullException(nameof(fileName));
var fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
return LoadModule(new Metadata.PEFile(fileName, fileStream, PEStreamOptions.Default));
return LoadModule(new Metadata.PEFile(fileName, fileStream, throwOnResolveError, options));
}
#endregion

5
ILSpy.BamlDecompiler.Tests/BamlTestRunner.cs

@ -113,11 +113,10 @@ namespace ILSpy.BamlDecompiler.Tests @@ -113,11 +113,10 @@ namespace ILSpy.BamlDecompiler.Tests
void RunTest(string name, string asmPath, string sourcePath)
{
using (var fileStream = new FileStream(asmPath, FileMode.Open, FileAccess.Read)) {
var module = new PEFile(asmPath, fileStream, System.Reflection.PortableExecutable.PEStreamOptions.Default);
var resolver = new UniversalAssemblyResolver(asmPath, false, true, module.Reader.DetectTargetFrameworkId(), System.Reflection.PortableExecutable.PEStreamOptions.Default);
var module = new PEFile(asmPath, fileStream);
var resolver = (UniversalAssemblyResolver)module.AssemblyResolver;
resolver.RemoveSearchDirectory(".");
resolver.AddSearchDirectory(Path.GetDirectoryName(asmPath));
module.AssemblyResolver = resolver;
var res = module.Resources.First();
Stream bamlStream = LoadBaml(res, name + ".baml");
Assert.IsNotNull(bamlStream);

11
ILSpy/LoadedAssembly.cs

@ -119,17 +119,12 @@ namespace ICSharpCode.ILSpy @@ -119,17 +119,12 @@ namespace ICSharpCode.ILSpy
if (stream != null)
{
// Read the module from a precrafted stream
module = new PEFile(fileName, stream, PEStreamOptions.Default) { AssemblyResolver = new MyAssemblyResolver(this) };
module = new PEFile(fileName, stream, new MyAssemblyResolver(this), PEStreamOptions.Default);
}
else
{
// Read the module from disk (by default)
using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read)) {
var ms = new MemoryStream();
fs.CopyTo(ms);
ms.Position = 0;
module = new PEFile(fileName, ms, PEStreamOptions.Default) { AssemblyResolver = new MyAssemblyResolver(this) };
}
module = new PEFile(fileName, new FileStream(fileName, FileMode.Open, FileAccess.Read), new MyAssemblyResolver(this), PEStreamOptions.PrefetchEntireImage);
}
if (DecompilerSettingsPanel.CurrentDecompilerSettings.UseDebugSymbols) {
@ -232,7 +227,7 @@ namespace ICSharpCode.ILSpy @@ -232,7 +227,7 @@ namespace ICSharpCode.ILSpy
class MyUniversalResolver : UniversalAssemblyResolver
{
public MyUniversalResolver(LoadedAssembly assembly)
: base(assembly.FileName, false, true, assembly.GetTargetFrameworkIdAsync().Result, PEStreamOptions.Default)
: base(assembly.FileName, false, assembly.GetTargetFrameworkIdAsync().Result, PEStreamOptions.PrefetchEntireImage)
{
}
}

Loading…
Cancel
Save