Browse Source

Clean up PEFile, move Pdb related types to DebugInfo namespace

pull/1198/head
Siegfried Pammer 7 years ago
parent
commit
bcfb3742eb
  1. 4
      ICSharpCode.Decompiler.PdbProvider.Cecil/MonoCecilDebugInfoProvider.cs
  2. 13
      ICSharpCode.Decompiler.Tests/Helpers/Tester.cs
  3. 5
      ICSharpCode.Decompiler.Tests/RoundtripAssembly.cs
  4. 45
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  5. 16
      ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs
  6. 9
      ICSharpCode.Decompiler/CSharp/WholeProjectDecompiler.cs
  7. 19
      ICSharpCode.Decompiler/DebugInfo/IDebugInfoProvider.cs
  8. 6
      ICSharpCode.Decompiler/DebugInfo/PortablePdbWriter.cs
  9. 2
      ICSharpCode.Decompiler/DebugInfo/SequencePoint.cs
  10. 15
      ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs
  11. 125
      ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs
  12. 18
      ICSharpCode.Decompiler/Documentation/XmlDocumentationProvider.cs
  13. 5
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  14. 6
      ICSharpCode.Decompiler/IL/ControlFlow/YieldReturnDecompiler.cs
  15. 8
      ICSharpCode.Decompiler/IL/ILReader.cs
  16. 5
      ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs
  17. 16
      ICSharpCode.Decompiler/IL/Transforms/IILTransform.cs
  18. 18
      ICSharpCode.Decompiler/IL/Transforms/ProxyCallReplacer.cs
  19. 17
      ICSharpCode.Decompiler/Metadata/Dom.cs
  20. 14
      ICSharpCode.Decompiler/Metadata/MetadataResolver.cs
  21. 19
      ICSharpCode.Decompiler/Metadata/PEFile.cs
  22. 2
      ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs
  23. 12
      ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs
  24. 6
      ICSharpCode.Decompiler/TypeSystem/IAssembly.cs
  25. 2
      ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultUnresolvedAssembly.cs
  26. 3
      ICSharpCode.Decompiler/TypeSystem/MetadataAssembly.cs
  27. 4
      ILSpy.BamlDecompiler.Tests/BamlTestRunner.cs
  28. 14
      ILSpy.BamlDecompiler/BamlResourceEntryNode.cs
  29. 2
      ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs
  30. 7
      ILSpy.BamlDecompiler/CecilTypeResolver.cs
  31. 8
      ILSpy.BamlDecompiler/ConnectMethodDecompiler.cs
  32. 9
      ILSpy/DebugInfo/DiaSymNativeDebugInfoProvider.cs
  33. 7
      ILSpy/DebugInfo/PortableDebugInfoProvider.cs
  34. 2
      ILSpy/ILSpy.csproj
  35. 215
      ILSpy/Languages/CSharpLanguage.cs
  36. 39
      ILSpy/LoadedAssembly.cs
  37. 25
      ILSpy/LoadedAssemblyExtensions.cs
  38. 2
      ILSpy/SearchPane.cs
  39. 6
      ILSpy/TreeNodes/Analyzer/ScopedWhereUsedAnalyzer.cs
  40. 2
      ILSpy/TreeNodes/AssemblyTreeNode.cs
  41. 8
      ILSpy/TreeNodes/BaseTypesEntryNode.cs
  42. 4
      ILSpy/TreeNodes/GeneratePdbContextMenuEntry.cs

4
ICSharpCode.Decompiler.PdbProvider.Cecil/MonoCecilDebugInfoProvider.cs

@ -20,7 +20,7 @@ using System.Collections.Generic; @@ -20,7 +20,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.DebugInfo;
using ICSharpCode.Decompiler.Util;
using Mono.Cecil;
@ -43,7 +43,7 @@ namespace ICSharpCode.Decompiler.PdbProvider.Cecil @@ -43,7 +43,7 @@ namespace ICSharpCode.Decompiler.PdbProvider.Cecil
var method = this.module.LookupToken(MetadataTokens.GetToken(handle)) as Mono.Cecil.MethodDefinition;
if (method?.DebugInformation == null || !method.DebugInformation.HasSequencePoints)
return EmptyList<SequencePoint>.Instance;
return method.DebugInformation.SequencePoints.Select(point => new Metadata.SequencePoint {
return method.DebugInformation.SequencePoints.Select(point => new SequencePoint {
Offset = point.Offset,
StartLine = point.StartLine,
StartColumn = point.StartColumn,

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

@ -348,8 +348,9 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -348,8 +348,9 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
var emitResult = compilation.Emit(peStream);
peStream.Position = 0;
var moduleDefinition = new PEFile("TestAssembly.dll", peStream, false, PEStreamOptions.PrefetchEntireImage);
var decompiler = new CSharpDecompiler(moduleDefinition, new DecompilerSettings());
var moduleDefinition = new PEFile("TestAssembly.dll", peStream, PEStreamOptions.PrefetchEntireImage);
var resolver = new UniversalAssemblyResolver("TestAssembly.dll", false, moduleDefinition.Reader.DetectTargetFrameworkId(), PEStreamOptions.PrefetchEntireImage);
var decompiler = new CSharpDecompiler(moduleDefinition, resolver, new DecompilerSettings());
return decompiler;
}
@ -394,9 +395,11 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -394,9 +395,11 @@ 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, false, PEStreamOptions.PrefetchEntireImage);
var typeSystem = new DecompilerTypeSystem(module);
CSharpDecompiler decompiler = new CSharpDecompiler(typeSystem, settings ?? new DecompilerSettings());
var module = new PEFile(assemblyFileName, file, PEStreamOptions.PrefetchEntireImage);
var resolver = new UniversalAssemblyResolver(assemblyFileName, false,
module.Reader.DetectTargetFrameworkId(), PEStreamOptions.PrefetchMetadata);
var typeSystem = new DecompilerTypeSystem(module, resolver);
CSharpDecompiler decompiler = new CSharpDecompiler(typeSystem, resolver, settings ?? new DecompilerSettings());
decompiler.AstTransforms.Insert(0, new RemoveEmbeddedAtttributes());
decompiler.AstTransforms.Insert(0, new RemoveCompilerAttribute());
decompiler.AstTransforms.Add(new EscapeInvalidIdentifiers());

5
ICSharpCode.Decompiler.Tests/RoundtripAssembly.cs

@ -144,11 +144,12 @@ namespace ICSharpCode.Decompiler.Tests @@ -144,11 +144,12 @@ 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, false, PEStreamOptions.PrefetchEntireImage);
UniversalAssemblyResolver resolver = (UniversalAssemblyResolver)module.AssemblyResolver;
PEFile module = new PEFile(file, fileStream, PEStreamOptions.PrefetchEntireImage);
UniversalAssemblyResolver resolver = new UniversalAssemblyResolver(file, false, module.Reader.DetectTargetFrameworkId(), PEStreamOptions.PrefetchMetadata);
resolver.AddSearchDirectory(inputDir);
resolver.RemoveSearchDirectory(".");
var decompiler = new TestProjectDecompiler(inputDir);
decompiler.AssemblyResolver = resolver;
// 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}");
decompiler.DecompileProject(module, decompiledDir);

45
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -39,6 +39,8 @@ using System.Reflection.Metadata; @@ -39,6 +39,8 @@ using System.Reflection.Metadata;
using SRM = System.Reflection.Metadata;
using ICSharpCode.Decompiler.Metadata;
using System.Reflection.PortableExecutable;
using ICSharpCode.Decompiler.Documentation;
using ICSharpCode.Decompiler.DebugInfo;
namespace ICSharpCode.Decompiler.CSharp
{
@ -179,6 +181,18 @@ namespace ICSharpCode.Decompiler.CSharp @@ -179,6 +181,18 @@ namespace ICSharpCode.Decompiler.CSharp
public IDecompilerTypeSystem TypeSystem => typeSystem;
public IAssemblyResolver AssemblyResolver { get; }
/// <summary>
/// Gets or sets the optional provider for debug info.
/// </summary>
public IDebugInfoProvider DebugInfoProvider { get; set; }
/// <summary>
/// Gets or sets the optional provider for XML documentation strings.
/// </summary>
public IDocumentationProvider DocumentationProvider { get; set; }
/// <summary>
/// IL transforms.
/// </summary>
@ -193,21 +207,20 @@ namespace ICSharpCode.Decompiler.CSharp @@ -193,21 +207,20 @@ namespace ICSharpCode.Decompiler.CSharp
get { return astTransforms; }
}
public CSharpDecompiler(string fileName, DecompilerSettings settings)
: this(LoadPEFile(fileName, settings), settings)
public CSharpDecompiler(string fileName, IAssemblyResolver assemblyResolver, DecompilerSettings settings)
: this(LoadPEFile(fileName, settings), assemblyResolver, settings)
{
}
public CSharpDecompiler(Metadata.PEFile module, DecompilerSettings settings)
: this(new DecompilerTypeSystem(module, settings), settings)
public CSharpDecompiler(PEFile module, IAssemblyResolver assemblyResolver, DecompilerSettings settings)
: this(new DecompilerTypeSystem(module, assemblyResolver, settings), assemblyResolver, settings)
{
}
public CSharpDecompiler(DecompilerTypeSystem typeSystem, DecompilerSettings settings)
public CSharpDecompiler(DecompilerTypeSystem typeSystem, IAssemblyResolver assemblyResolver, DecompilerSettings settings)
{
if (typeSystem == null)
throw new ArgumentNullException(nameof(typeSystem));
this.typeSystem = typeSystem;
this.typeSystem = typeSystem ?? throw new ArgumentNullException(nameof(typeSystem));
this.AssemblyResolver = assemblyResolver ?? throw new ArgumentNullException(nameof(assemblyResolver));
this.settings = settings;
}
@ -318,7 +331,6 @@ namespace ICSharpCode.Decompiler.CSharp @@ -318,7 +331,6 @@ namespace ICSharpCode.Decompiler.CSharp
return new PEFile(
fileName,
new FileStream(fileName, FileMode.Open, FileAccess.Read),
settings.ThrowOnAssemblyResolveErrors,
options: settings.LoadInMemory ? PEStreamOptions.PrefetchEntireImage : PEStreamOptions.Default
);
}
@ -436,7 +448,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -436,7 +448,7 @@ namespace ICSharpCode.Decompiler.CSharp
{
var decompileRun = new DecompileRun(settings) { CancellationToken = CancellationToken };
RequiredNamespaceCollector.CollectNamespaces(function.Method, typeSystem, decompileRun.Namespaces);
return new ILTransformContext(function, typeSystem, settings) {
return new ILTransformContext(function, typeSystem, DebugInfoProvider, settings) {
CancellationToken = CancellationToken,
DecompileRun = decompileRun
};
@ -887,10 +899,13 @@ namespace ICSharpCode.Decompiler.CSharp @@ -887,10 +899,13 @@ namespace ICSharpCode.Decompiler.CSharp
{
try {
var specializingTypeSystem = typeSystem.GetSpecializingTypeSystem(decompilationContext);
var ilReader = new ILReader(specializingTypeSystem);
ilReader.UseDebugSymbols = settings.UseDebugSymbols;
var ilReader = new ILReader(specializingTypeSystem) {
UseDebugSymbols = settings.UseDebugSymbols,
DebugInfo = DebugInfoProvider
};
var methodDef = typeSystem.ModuleDefinition.Metadata.GetMethodDefinition((MethodDefinitionHandle)method.MetadataToken);
var function = ilReader.ReadIL(typeSystem.ModuleDefinition, (MethodDefinitionHandle)method.MetadataToken, typeSystem.ModuleDefinition.Reader.GetMethodBody(methodDef.RelativeVirtualAddress), CancellationToken);
var methodBody = typeSystem.ModuleDefinition.Reader.GetMethodBody(methodDef.RelativeVirtualAddress);
var function = ilReader.ReadIL(typeSystem.ModuleDefinition, (MethodDefinitionHandle)method.MetadataToken, methodBody, CancellationToken);
function.CheckInvariant(ILPhase.Normal);
if (entityDecl != null) {
@ -911,7 +926,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -911,7 +926,7 @@ namespace ICSharpCode.Decompiler.CSharp
localSettings.AlwaysCastTargetsOfExplicitInterfaceImplementationCalls = true;
}
var context = new ILTransformContext(function, specializingTypeSystem, localSettings) {
var context = new ILTransformContext(function, specializingTypeSystem, DebugInfoProvider, localSettings) {
CancellationToken = CancellationToken,
DecompileRun = decompileRun
};
@ -1126,7 +1141,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1126,7 +1141,7 @@ namespace ICSharpCode.Decompiler.CSharp
///
/// This only works correctly when the nodes in the syntax tree have line/column information.
/// </summary>
public Dictionary<ILFunction, List<Metadata.SequencePoint>> CreateSequencePoints(SyntaxTree syntaxTree)
public Dictionary<ILFunction, List<DebugInfo.SequencePoint>> CreateSequencePoints(SyntaxTree syntaxTree)
{
SequencePointBuilder spb = new SequencePointBuilder();
syntaxTree.AcceptVisitor(spb);

16
ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs

@ -56,7 +56,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -56,7 +56,7 @@ namespace ICSharpCode.Decompiler.CSharp
}
}
readonly List<(ILFunction, Metadata.SequencePoint)> sequencePoints = new List<(ILFunction, Metadata.SequencePoint)>();
readonly List<(ILFunction, DebugInfo.SequencePoint)> sequencePoints = new List<(ILFunction, DebugInfo.SequencePoint)>();
readonly HashSet<ILInstruction> mappedInstructions = new HashSet<ILInstruction>();
// Stack holding information for outer statements.
@ -219,7 +219,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -219,7 +219,7 @@ namespace ICSharpCode.Decompiler.CSharp
// use LongSet to deduplicate and merge the intervals
var longSet = new LongSet(current.Intervals.Select(i => new LongInterval(i.Start, i.End)));
Debug.Assert(!longSet.IsEmpty);
sequencePoints.Add((current.Function, new Metadata.SequencePoint {
sequencePoints.Add((current.Function, new DebugInfo.SequencePoint {
Offset = (int)longSet.Intervals[0].Start,
EndOffset = (int)longSet.Intervals[0].End,
StartLine = startLocation.Line,
@ -277,18 +277,18 @@ namespace ICSharpCode.Decompiler.CSharp @@ -277,18 +277,18 @@ namespace ICSharpCode.Decompiler.CSharp
/// <summary>
/// Called after the visitor is done to return the results.
/// </summary>
internal Dictionary<ILFunction, List<Metadata.SequencePoint>> GetSequencePoints()
internal Dictionary<ILFunction, List<DebugInfo.SequencePoint>> GetSequencePoints()
{
var dict = new Dictionary<ILFunction, List<Metadata.SequencePoint>>();
var dict = new Dictionary<ILFunction, List<DebugInfo.SequencePoint>>();
foreach (var (function, sequencePoint) in this.sequencePoints) {
if (!dict.TryGetValue(function, out var list)) {
dict.Add(function, list = new List<Metadata.SequencePoint>());
dict.Add(function, list = new List<DebugInfo.SequencePoint>());
}
list.Add(sequencePoint);
}
foreach (var (function, list) in dict.ToList()) {
// For each function, sort sequence points and fix overlaps+gaps
var newList = new List<Metadata.SequencePoint>();
var newList = new List<DebugInfo.SequencePoint>();
int pos = 0;
foreach (var sequencePoint in list.OrderBy(sp => sp.Offset).ThenBy(sp => sp.EndOffset)) {
if (sequencePoint.Offset < pos) {
@ -305,7 +305,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -305,7 +305,7 @@ namespace ICSharpCode.Decompiler.CSharp
}
} else if (sequencePoint.Offset > pos) {
// insert hidden sequence point in the gap.
var hidden = new Metadata.SequencePoint();
var hidden = new DebugInfo.SequencePoint();
hidden.Offset = pos;
hidden.EndOffset = sequencePoint.Offset;
hidden.SetHidden();
@ -315,7 +315,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -315,7 +315,7 @@ namespace ICSharpCode.Decompiler.CSharp
pos = sequencePoint.EndOffset;
}
if (pos < function.CodeSize) {
var hidden = new Metadata.SequencePoint();
var hidden = new DebugInfo.SequencePoint();
hidden.Offset = pos;
hidden.EndOffset = function.CodeSize;
hidden.SetHidden();

9
ICSharpCode.Decompiler/CSharp/WholeProjectDecompiler.cs

@ -34,6 +34,7 @@ using System.Reflection.PortableExecutable; @@ -34,6 +34,7 @@ using System.Reflection.PortableExecutable;
using System.Reflection.Metadata;
using static ICSharpCode.Decompiler.Metadata.DotNetCorePathFinderExtensions;
using static ICSharpCode.Decompiler.Metadata.MetadataExtensions;
using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.Decompiler.CSharp
{
@ -56,6 +57,8 @@ namespace ICSharpCode.Decompiler.CSharp @@ -56,6 +57,8 @@ namespace ICSharpCode.Decompiler.CSharp
}
}
public IAssemblyResolver AssemblyResolver { get; set; }
/// <summary>
/// The MSBuild ProjectGuid to use for the new project.
/// <c>null</c> to automatically generate a new GUID.
@ -218,7 +221,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -218,7 +221,7 @@ namespace ICSharpCode.Decompiler.CSharp
if (r.Name != "mscorlib") {
w.WriteStartElement("Reference");
w.WriteAttributeString("Include", r.Name);
var asm = module.AssemblyResolver.Resolve(r);
var asm = AssemblyResolver.Resolve(r);
if (!IsGacAssembly(r, asm)) {
if (asm != null) {
w.WriteElementString("HintPath", asm.FileName);
@ -275,7 +278,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -275,7 +278,7 @@ namespace ICSharpCode.Decompiler.CSharp
CSharpDecompiler CreateDecompiler(DecompilerTypeSystem ts)
{
var decompiler = new CSharpDecompiler(ts, settings);
var decompiler = new CSharpDecompiler(ts, AssemblyResolver, settings);
decompiler.AstTransforms.Add(new EscapeInvalidIdentifiers());
decompiler.AstTransforms.Add(new RemoveCLSCompliantAttribute());
return decompiler;
@ -314,7 +317,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -314,7 +317,7 @@ namespace ICSharpCode.Decompiler.CSharp
return Path.Combine(dir, file);
}
}, StringComparer.OrdinalIgnoreCase).ToList();
DecompilerTypeSystem ts = new DecompilerTypeSystem(module);
DecompilerTypeSystem ts = new DecompilerTypeSystem(module, AssemblyResolver);
Parallel.ForEach(
files,
new ParallelOptions {

19
ICSharpCode.Decompiler/DebugInfo/IDebugInfoProvider.cs

@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Reflection.Metadata;
using System.Text;
namespace ICSharpCode.Decompiler.DebugInfo
{
public struct Variable
{
public string Name { get; set; }
}
public interface IDebugInfoProvider
{
IList<SequencePoint> GetSequencePoints(MethodDefinitionHandle method);
IList<Variable> GetVariables(MethodDefinitionHandle method);
bool TryGetName(MethodDefinitionHandle method, int index, out string name);
}
}

6
ICSharpCode.Decompiler/Pdb/PortablePdbWriter.cs → ICSharpCode.Decompiler/DebugInfo/PortablePdbWriter.cs

@ -17,7 +17,7 @@ using ICSharpCode.Decompiler.Metadata; @@ -17,7 +17,7 @@ using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.Pdb
namespace ICSharpCode.Decompiler.DebugInfo
{
public class PortablePdbWriter
{
@ -39,7 +39,7 @@ namespace ICSharpCode.Decompiler.Pdb @@ -39,7 +39,7 @@ namespace ICSharpCode.Decompiler.Pdb
var hasher = SHA256.Create();
var sequencePointBlobs = new Dictionary<MethodDefinitionHandle, (DocumentHandle Document, BlobHandle SequencePoints)>();
var importScopeBlobs = new Dictionary<MethodDefinitionHandle, (DocumentHandle Document, BlobHandle ImportScope)>();
var emptyList = new List<Metadata.SequencePoint>();
var emptyList = new List<SequencePoint>();
foreach (var handle in reader.GetTopLevelTypeDefinitions()) {
var type = reader.GetTypeDefinition(handle);
@ -156,7 +156,7 @@ namespace ICSharpCode.Decompiler.Pdb @@ -156,7 +156,7 @@ namespace ICSharpCode.Decompiler.Pdb
return metadata.GetOrAddBlob(writer);
}
static BlobHandle EncodeSequencePoints(MetadataBuilder metadata, int localSignatureRowId, List<Metadata.SequencePoint> sequencePoints)
static BlobHandle EncodeSequencePoints(MetadataBuilder metadata, int localSignatureRowId, List<SequencePoint> sequencePoints)
{
if (sequencePoints.Count == 0)
return default;

2
ICSharpCode.Decompiler/Metadata/SequencePoint.cs → ICSharpCode.Decompiler/DebugInfo/SequencePoint.cs

@ -18,7 +18,7 @@ @@ -18,7 +18,7 @@
using System;
namespace ICSharpCode.Decompiler.Metadata
namespace ICSharpCode.Decompiler.DebugInfo
{
/// <summary>
/// A sequence point read from a PDB file or produced by the decompiler.

15
ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs

@ -21,7 +21,7 @@ using System.Collections.Generic; @@ -21,7 +21,7 @@ using System.Collections.Generic;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Threading;
using ICSharpCode.Decompiler.DebugInfo;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.Util;
@ -51,7 +51,12 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -51,7 +51,12 @@ namespace ICSharpCode.Decompiler.Disassembler
/// </summary>
public bool ShowMetadataTokens { get; set; }
IList<Metadata.SequencePoint> sequencePoints;
/// <summary>
/// Optional provider for sequence points.
/// </summary>
public IDebugInfoProvider DebugInfo { get; set; }
IList<DebugInfo.SequencePoint> sequencePoints;
int nextSequencePointIndex;
// cache info
@ -68,7 +73,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -68,7 +73,7 @@ namespace ICSharpCode.Decompiler.Disassembler
public virtual void Disassemble(PEFile module, MethodDefinitionHandle handle)
{
this.module = module;
this.module = module ?? throw new ArgumentNullException(nameof(module));
metadata = module.Metadata;
genericContext = new GenericContext(handle, module);
signatureDecoder = new DisassemblerSignatureProvider(module, output);
@ -94,7 +99,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -94,7 +99,7 @@ namespace ICSharpCode.Decompiler.Disassembler
DisassembleLocalsBlock(body);
output.WriteLine();
sequencePoints = module.DebugInfo?.GetSequencePoints(handle) ?? EmptyList<Metadata.SequencePoint>.Instance;
sequencePoints = DebugInfo?.GetSequencePoints(handle) ?? EmptyList<DebugInfo.SequencePoint>.Instance;
nextSequencePointIndex = 0;
if (DetectControlStructure && blob.Length > 0) {
blob.Reset();
@ -278,7 +283,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -278,7 +283,7 @@ namespace ICSharpCode.Decompiler.Disassembler
{
int offset = blob.Offset;
if (ShowSequencePoints && nextSequencePointIndex < sequencePoints?.Count) {
Metadata.SequencePoint sp = sequencePoints[nextSequencePointIndex];
var sp = sequencePoints[nextSequencePointIndex];
if (sp.Offset <= offset) {
output.Write("// sequence point: ");
if (sp.Offset != offset) {

125
ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs

@ -27,6 +27,7 @@ using System.Threading; @@ -27,6 +27,7 @@ using System.Threading;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.DebugInfo;
namespace ICSharpCode.Decompiler.Disassembler
{
@ -55,8 +56,15 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -55,8 +56,15 @@ namespace ICSharpCode.Decompiler.Disassembler
set => methodBodyDisassembler.ShowMetadataTokens = value;
}
public IDebugInfoProvider DebugInfo {
get => methodBodyDisassembler.DebugInfo;
set => methodBodyDisassembler.DebugInfo = value;
}
public bool ExpandMemberDefinitions { get; set; } = false;
public IAssemblyResolver AssemblyResolver { get; set; }
public ReflectionDisassembler(ITextOutput output, CancellationToken cancellationToken)
: this(output, new MethodBodyDisassembler(output, cancellationToken), cancellationToken)
{
@ -362,59 +370,61 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -362,59 +370,61 @@ namespace ICSharpCode.Decompiler.Disassembler
output.Write(secdecl.Action.ToString());
break;
}
output.WriteLine(" = {");
output.Indent();
var blob = metadata.GetBlobReader(secdecl.PermissionSet);
if ((char)blob.ReadByte() != '.') {
blob.Reset();
WriteXmlSecurityDeclaration(blob.ReadUTF8(blob.RemainingBytes));
if (AssemblyResolver == null) {
output.Write(" = ");
WriteBlob(secdecl.PermissionSet, metadata);
} else {
string currentAssemblyName = null;
string currentFullAssemblyName = null;
if (metadata.IsAssembly) {
currentAssemblyName = metadata.GetString(metadata.GetAssemblyDefinition().Name);
currentFullAssemblyName = metadata.GetFullAssemblyName();
}
int count = blob.ReadCompressedInteger();
for (int i = 0; i < count; i++) {
var typeName = blob.ReadSerializedString();
string[] nameParts = typeName.Split(new[] { ", " }, StringSplitOptions.None);
if (nameParts.Length < 2 || nameParts[1] == currentAssemblyName) {
output.Write("class ");
output.Write(DisassemblerHelpers.Escape(typeName + ", " + currentFullAssemblyName));
} else {
string[] typeNameParts = typeName.Split(new[] { ", " }, StringSplitOptions.None);
if (typeNameParts.Length < 2)
throw new NotImplementedException();
output.Write('[');
output.Write(typeNameParts[1]);
output.Write(']');
output.WriteReference(typeNameParts[0], null); // TODO : hyperlink!
output.WriteLine(" = {");
output.Indent();
var blob = metadata.GetBlobReader(secdecl.PermissionSet);
if ((char)blob.ReadByte() != '.') {
blob.Reset();
WriteXmlSecurityDeclaration(blob.ReadUTF8(blob.RemainingBytes));
} else {
string currentAssemblyName = null;
string currentFullAssemblyName = null;
if (metadata.IsAssembly) {
currentAssemblyName = metadata.GetString(metadata.GetAssemblyDefinition().Name);
currentFullAssemblyName = metadata.GetFullAssemblyName();
}
output.Write(" = {");
blob.ReadCompressedInteger(); // ?
// The specification seems to be incorrect here, so I'm using the logic from Cecil instead.
int argCount = blob.ReadCompressedInteger();
if (argCount > 0) {
output.WriteLine();
output.Indent();
for (int j = 0; j < argCount; j++) {
WriteSecurityDeclarationArgument(module, ref blob);
int count = blob.ReadCompressedInteger();
for (int i = 0; i < count; i++) {
var typeName = blob.ReadSerializedString();
string[] nameParts = typeName.Split(new[] { ", " }, StringSplitOptions.None);
if (nameParts.Length < 2 || nameParts[1] == currentAssemblyName) {
output.Write("class ");
output.Write(DisassemblerHelpers.Escape(typeName + ", " + currentFullAssemblyName));
} else {
output.Write('[');
output.Write(nameParts[1]);
output.Write(']');
output.WriteReference(nameParts[0], null); // TODO : hyperlink!
}
output.Write(" = {");
blob.ReadCompressedInteger(); // ?
// The specification seems to be incorrect here, so I'm using the logic from Cecil instead.
int argCount = blob.ReadCompressedInteger();
if (argCount > 0) {
output.WriteLine();
output.Indent();
for (int j = 0; j < argCount; j++) {
WriteSecurityDeclarationArgument(module, ref blob);
output.WriteLine();
}
output.Unindent();
}
output.Write('}');
output.Unindent();
if (i + 1 < count)
output.Write(',');
output.WriteLine();
}
output.Write('}');
if (i + 1 < count)
output.Write(',');
output.WriteLine();
}
output.Unindent();
output.WriteLine("}");
}
output.Unindent();
output.WriteLine("}");
}
}
@ -525,7 +535,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -525,7 +535,7 @@ namespace ICSharpCode.Decompiler.Disassembler
PEFile containingModule = null;
// if we deal with an assembly-qualified name, resolve the assembly
if (nameParts.Length == 2)
containingModule = module.AssemblyResolver.Resolve(AssemblyNameReference.Parse(nameParts[1]));
containingModule = AssemblyResolver.Resolve(AssemblyNameReference.Parse(nameParts[1]));
if (containingModule != null) {
// try to find the type in the assembly
var handle = FindType(containingModule, typeNameParts);
@ -539,7 +549,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -539,7 +549,7 @@ namespace ICSharpCode.Decompiler.Disassembler
var handle = FindType(module, typeNameParts);
if (handle.IsNil) {
// otherwise try mscorlib
var mscorlib = module.AssemblyResolver.Resolve(AssemblyNameReference.Parse("mscorlib"));
var mscorlib = AssemblyResolver.Resolve(AssemblyNameReference.Parse("mscorlib"));
handle = FindType(mscorlib, typeNameParts);
if (handle.IsNil)
throw new NotImplementedException();
@ -1352,27 +1362,27 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1352,27 +1362,27 @@ namespace ICSharpCode.Decompiler.Disassembler
output.Write(".custom ");
var attr = metadata.GetCustomAttribute(a);
attr.Constructor.WriteTo(module, output, GenericContext.Empty);
byte[] blob = metadata.GetBlobBytes(attr.Value);
if (blob.Length > 0) {
if (!attr.Value.IsNil) {
output.Write(" = ");
WriteBlob(blob);
WriteBlob(attr.Value, metadata);
}
output.WriteLine();
}
}
void WriteBlob(byte[] blob)
void WriteBlob(BlobHandle blob, MetadataReader metadata)
{
var reader = metadata.GetBlobReader(blob);
output.Write("(");
output.Indent();
for (int i = 0; i < blob.Length; i++) {
if (i % 16 == 0 && i < blob.Length - 1) {
for (int i = 0; i < reader.Length; i++) {
if (i % 16 == 0 && i < reader.Length - 1) {
output.WriteLine();
} else {
output.Write(' ');
}
output.Write(blob[i].ToString("x2"));
output.Write(reader.ReadByte().ToString("x2"));
}
output.WriteLine();
@ -1484,10 +1494,9 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1484,10 +1494,9 @@ namespace ICSharpCode.Decompiler.Disassembler
OpenBlock(false);
WriteAttributes(module, asm.GetCustomAttributes());
WriteSecurityDeclarations(module, asm.GetDeclarativeSecurityAttributes());
var publicKey = metadata.GetBlobBytes(asm.PublicKey);
if (publicKey.Length > 0) {
if (!asm.PublicKey.IsNil) {
output.Write(".publickey = ");
WriteBlob(publicKey);
WriteBlob(asm.PublicKey, metadata);
output.WriteLine();
}
if (asm.HashAlgorithm != AssemblyHashAlgorithm.None) {
@ -1518,7 +1527,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1518,7 +1527,7 @@ namespace ICSharpCode.Decompiler.Disassembler
OpenBlock(false);
if (!aref.PublicKeyOrToken.IsNil) {
output.Write(".publickeytoken = ");
WriteBlob(metadata.GetBlobBytes(aref.PublicKeyOrToken));
WriteBlob(aref.PublicKeyOrToken, metadata);
output.WriteLine();
}
if (aref.Version != null) {

18
ICSharpCode.Decompiler/Documentation/XmlDocumentationProvider.cs

@ -23,9 +23,15 @@ using System.IO; @@ -23,9 +23,15 @@ using System.IO;
using System.Runtime.Serialization;
using System.Text;
using System.Xml;
using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.Decompiler.Documentation
{
public interface IDocumentationProvider
{
string GetDocumentation(IEntity entity);
}
/// <summary>
/// Provides documentation from an .xml file (as generated by the Microsoft C# compiler).
/// </summary>
@ -36,7 +42,7 @@ namespace ICSharpCode.Decompiler.Documentation @@ -36,7 +42,7 @@ namespace ICSharpCode.Decompiler.Documentation
/// If the .xml file is changed, the index will automatically be recreated.
/// </remarks>
[Serializable]
public class XmlDocumentationProvider : IDeserializationCallback
public class XmlDocumentationProvider : IDeserializationCallback, IDocumentationProvider
{
#region Cache
sealed class XmlDocumentationCache
@ -317,6 +323,16 @@ namespace ICSharpCode.Decompiler.Documentation @@ -317,6 +323,16 @@ namespace ICSharpCode.Decompiler.Documentation
return GetDocumentation(key, true);
}
/// <summary>
/// Get the documentation for the specified member.
/// </summary>
public string GetDocumentation(IEntity entity)
{
if (entity == null)
throw new ArgumentNullException(nameof(entity));
return GetDocumentation(XmlDocKeyProvider.GetKey(entity));
}
string GetDocumentation(string key, bool allowReload)
{
int hashcode = GetHashCode(key);

5
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -306,7 +306,7 @@ @@ -306,7 +306,7 @@
<Compile Include="IL\Instructions\LdFlda.cs" />
<Compile Include="IL\Instructions\NullableInstructions.cs" />
<Compile Include="IL\Instructions\StLoc.cs" />
<Compile Include="Metadata\SequencePoint.cs" />
<Compile Include="DebugInfo\SequencePoint.cs" />
<Compile Include="IL\Instructions\CallIndirect.cs" />
<Compile Include="IL\Instructions\DefaultValue.cs" />
<Compile Include="IL\Transforms\DynamicCallSiteTransform.cs" />
@ -342,7 +342,8 @@ @@ -342,7 +342,8 @@
<Compile Include="IL\Transforms\StatementTransform.cs" />
<Compile Include="IL\Transforms\TransformCollectionAndObjectInitializers.cs" />
<Compile Include="Output\TextTokenWriter.cs" />
<Compile Include="Pdb\PortablePdbWriter.cs" />
<Compile Include="DebugInfo\IDebugInfoProvider.cs" />
<Compile Include="DebugInfo\PortablePdbWriter.cs" />
<Compile Include="SRMExtensions.cs" />
<Compile Include="SRMHacks.cs" />
<Compile Include="TypeSystem\ApplyAttributeTypeVisitor.cs" />

6
ICSharpCode.Decompiler/IL/ControlFlow/YieldReturnDecompiler.cs

@ -384,9 +384,11 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -384,9 +384,11 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
)
);
}
var il = new ILReader(typeSystem).ReadIL(typeSystem.ModuleDefinition, method, typeSystem.ModuleDefinition.Reader.GetMethodBody(methodDef.RelativeVirtualAddress), context.CancellationToken);
var body = typeSystem.ModuleDefinition.Reader.GetMethodBody(methodDef.RelativeVirtualAddress);
var il = context.CreateILReader(typeSystem)
.ReadIL(typeSystem.ModuleDefinition, method, body, context.CancellationToken);
il.RunTransforms(CSharpDecompiler.EarlyILTransforms(true),
new ILTransformContext(il, typeSystem, context.Settings) {
new ILTransformContext(il, typeSystem, context.DebugInfo, context.Settings) {
CancellationToken = context.CancellationToken,
DecompileRun = context.DecompileRun
});

8
ICSharpCode.Decompiler/IL/ILReader.cs

@ -40,6 +40,7 @@ namespace ICSharpCode.Decompiler.IL @@ -40,6 +40,7 @@ namespace ICSharpCode.Decompiler.IL
readonly IDecompilerTypeSystem typeSystem;
public bool UseDebugSymbols { get; set; }
public DebugInfo.IDebugInfoProvider DebugInfo { get; set; }
public List<string> Warnings { get; } = new List<string>();
public ILReader(IDecompilerTypeSystem typeSystem)
@ -53,7 +54,6 @@ namespace ICSharpCode.Decompiler.IL @@ -53,7 +54,6 @@ namespace ICSharpCode.Decompiler.IL
MetadataReader metadata;
IMethod method;
MethodBodyBlock body;
Metadata.IDebugInfoProvider debugInfo;
StackType methodReturnStackType;
BlobReader reader;
ImmutableStack<ILVariable> currentStack;
@ -79,7 +79,6 @@ namespace ICSharpCode.Decompiler.IL @@ -79,7 +79,6 @@ namespace ICSharpCode.Decompiler.IL
var methodDefinition = metadata.GetMethodDefinition(methodDefinitionHandle);
this.body = body;
this.reader = body.GetILReader();
this.debugInfo = module.DebugInfo;
this.currentStack = ImmutableStack<ILVariable>.Empty;
this.unionFind = new UnionFind<ILVariable>();
this.stackMismatchPairs = new List<(ILVariable, ILVariable)>();
@ -177,7 +176,7 @@ namespace ICSharpCode.Decompiler.IL @@ -177,7 +176,7 @@ namespace ICSharpCode.Decompiler.IL
kind = VariableKind.Local;
}
ILVariable ilVar = new ILVariable(kind, type, index);
if (!UseDebugSymbols || debugInfo == null || !debugInfo.TryGetName((MethodDefinitionHandle)method.MetadataToken, index, out string name)) {
if (!UseDebugSymbols || DebugInfo == null || !DebugInfo.TryGetName((MethodDefinitionHandle)method.MetadataToken, index, out string name)) {
ilVar.Name = "V_" + index;
ilVar.HasGeneratedName = true;
} else if (string.IsNullOrWhiteSpace(name)) {
@ -410,7 +409,8 @@ namespace ICSharpCode.Decompiler.IL @@ -410,7 +409,8 @@ namespace ICSharpCode.Decompiler.IL
/// <summary>
/// Debugging helper: writes the decoded instruction stream interleaved with the inferred evaluation stack layout.
/// </summary>
public void WriteTypedIL(Metadata.PEFile module, MethodDefinitionHandle method, MethodBodyBlock body, ITextOutput output, CancellationToken cancellationToken = default(CancellationToken))
public void WriteTypedIL(Metadata.PEFile module,
MethodDefinitionHandle method, MethodBodyBlock body, ITextOutput output, CancellationToken cancellationToken = default)
{
Init(module, method, body);
ReadInstructions(cancellationToken);

5
ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs

@ -145,8 +145,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -145,8 +145,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (!methodDefinition.HasBody())
return null;
var localTypeSystem = context.TypeSystem.GetSpecializingTypeSystem(targetMethod.Substitution);
var ilReader = new ILReader(localTypeSystem);
ilReader.UseDebugSymbols = context.Settings.UseDebugSymbols;
var ilReader = context.CreateILReader(localTypeSystem);
var function = ilReader.ReadIL(context.TypeSystem.ModuleDefinition, (MethodDefinitionHandle)targetMethod.MetadataToken, context.TypeSystem.ModuleDefinition.Reader.GetMethodBody(methodDefinition.RelativeVirtualAddress), context.CancellationToken);
function.DelegateType = value.Method.DeclaringType;
function.CheckInvariant(ILPhase.Normal);
@ -156,7 +155,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -156,7 +155,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
v.Name = contextPrefix + v.Name;
}
var nestedContext = new ILTransformContext(function, localTypeSystem, context.Settings) {
var nestedContext = new ILTransformContext(function, localTypeSystem, context.DebugInfo, context.Settings) {
CancellationToken = context.CancellationToken,
DecompileRun = context.DecompileRun
};

16
ICSharpCode.Decompiler/IL/Transforms/IILTransform.cs

@ -22,6 +22,7 @@ using System.Collections.Immutable; @@ -22,6 +22,7 @@ using System.Collections.Immutable;
using System.Diagnostics;
using System.Threading;
using ICSharpCode.Decompiler.CSharp.TypeSystem;
using ICSharpCode.Decompiler.DebugInfo;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
@ -42,6 +43,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -42,6 +43,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{
public ILFunction Function { get; }
public IDecompilerTypeSystem TypeSystem { get; }
public IDebugInfoProvider DebugInfo { get; }
public DecompilerSettings Settings { get; }
public CancellationToken CancellationToken { get; set; }
public Stepper Stepper { get; set; }
@ -49,11 +51,12 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -49,11 +51,12 @@ namespace ICSharpCode.Decompiler.IL.Transforms
internal DecompileRun DecompileRun { get; set; }
internal ResolvedUsingScope UsingScope => DecompileRun.UsingScope.Resolve(TypeSystem.Compilation);
public ILTransformContext(ILFunction function, IDecompilerTypeSystem typeSystem, DecompilerSettings settings = null)
public ILTransformContext(ILFunction function, IDecompilerTypeSystem typeSystem, IDebugInfoProvider debugInfo, DecompilerSettings settings = null)
{
this.Function = function ?? throw new ArgumentNullException(nameof(function));
this.TypeSystem = typeSystem ?? throw new ArgumentNullException(nameof(typeSystem));
this.Settings = settings ?? new DecompilerSettings();
this.DebugInfo = debugInfo;
Stepper = new Stepper();
}
@ -61,12 +64,23 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -61,12 +64,23 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{
this.Function = context.Function;
this.TypeSystem = context.TypeSystem;
this.DebugInfo = context.DebugInfo;
this.Settings = context.Settings;
this.DecompileRun = context.DecompileRun;
this.CancellationToken = context.CancellationToken;
this.Stepper = context.Stepper;
}
public ILReader CreateILReader(IDecompilerTypeSystem typeSystem = null)
{
if (typeSystem == null)
typeSystem = this.TypeSystem;
return new ILReader(typeSystem) {
UseDebugSymbols = Settings.UseDebugSymbols,
DebugInfo = DebugInfo
};
}
/// <summary>
/// Call this method immediately before performing a transform step.
/// Unlike <c>context.Stepper.Step()</c>, calls to this method are only compiled in debug builds.

18
ICSharpCode.Decompiler/IL/Transforms/ProxyCallReplacer.cs

@ -31,20 +31,14 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -31,20 +31,14 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return;
// partially copied from CSharpDecompiler
var specializingTypeSystem = context.TypeSystem.GetSpecializingTypeSystem(inst.Method.Substitution);
var ilReader = new ILReader(specializingTypeSystem);
System.Threading.CancellationToken cancellationToken = new System.Threading.CancellationToken();
var proxyFunction = ilReader.ReadIL(module, handle, module.Reader.GetMethodBody(methodDef.RelativeVirtualAddress), cancellationToken);
var transformContext = new ILTransformContext(proxyFunction, specializingTypeSystem, context.Settings) {
CancellationToken = cancellationToken,
var ilReader = context.CreateILReader(specializingTypeSystem);
var body = module.Reader.GetMethodBody(methodDef.RelativeVirtualAddress);
var proxyFunction = ilReader.ReadIL(module, handle, body, context.CancellationToken);
var transformContext = new ILTransformContext(proxyFunction, specializingTypeSystem, context.DebugInfo, context.Settings) {
CancellationToken = context.CancellationToken,
DecompileRun = context.DecompileRun
};
foreach (var transform in CSharp.CSharpDecompiler.GetILTransforms()) {
if (transform.GetType() != typeof(ProxyCallReplacer)) { // don't call itself on itself
cancellationToken.ThrowIfCancellationRequested();
transform.Run(proxyFunction, transformContext);
}
}
proxyFunction.RunTransforms(CSharp.CSharpDecompiler.EarlyILTransforms(), transformContext);
if (!(proxyFunction.Body is BlockContainer blockContainer))
return;
if (blockContainer.Blocks.Count != 1)

17
ICSharpCode.Decompiler/Metadata/Dom.cs

@ -15,23 +15,6 @@ using ICSharpCode.Decompiler.Util; @@ -15,23 +15,6 @@ using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.Metadata
{
public interface IAssemblyDocumentationResolver
{
XmlDocumentationProvider GetProvider();
}
public struct Variable
{
public string Name { get; set; }
}
public interface IDebugInfoProvider
{
IList<SequencePoint> GetSequencePoints(MethodDefinitionHandle method);
IList<Variable> GetVariables(MethodDefinitionHandle method);
bool TryGetName(MethodDefinitionHandle method, int index, out string name);
}
public enum TargetRuntime
{
Unknown,

14
ICSharpCode.Decompiler/Metadata/MetadataResolver.cs

@ -40,18 +40,18 @@ namespace ICSharpCode.Decompiler.Metadata @@ -40,18 +40,18 @@ namespace ICSharpCode.Decompiler.Metadata
readonly IAssemblyResolver assemblyResolver;
readonly Dictionary<IAssemblyReference, PEFile> loadedModules;
public SimpleMetadataResolveContext(PEFile mainModule)
public SimpleMetadataResolveContext(PEFile mainModule, IAssemblyResolver assemblyResolver)
{
this.mainModule = mainModule;
this.assemblyResolver = mainModule.AssemblyResolver;
this.mainModule = mainModule ?? throw new ArgumentNullException(nameof(mainModule));
this.assemblyResolver = assemblyResolver ?? throw new ArgumentNullException(nameof(assemblyResolver));
this.loadedModules = new Dictionary<IAssemblyReference, PEFile>();
}
public SimpleMetadataResolveContext(PEFile mainModule, IMetadataResolveContext parentContext)
public SimpleMetadataResolveContext(PEFile mainModule, SimpleMetadataResolveContext parentContext)
{
this.mainModule = mainModule;
this.assemblyResolver = mainModule.AssemblyResolver;
this.loadedModules = parentContext is SimpleMetadataResolveContext simple ? simple.loadedModules : new Dictionary<IAssemblyReference, PEFile>();
this.mainModule = mainModule ?? throw new ArgumentNullException(nameof(mainModule));
this.assemblyResolver = parentContext.assemblyResolver;
this.loadedModules = parentContext.loadedModules;
}
public PEFile CurrentModule => mainModule;

19
ICSharpCode.Decompiler/Metadata/PEFile.cs

@ -33,24 +33,17 @@ namespace ICSharpCode.Decompiler.Metadata @@ -33,24 +33,17 @@ namespace ICSharpCode.Decompiler.Metadata
public string FileName { get; }
public PEReader Reader { get; }
public MetadataReader Metadata { get; }
public IAssemblyResolver AssemblyResolver { get; }
public IAssemblyDocumentationResolver DocumentationResolver { get; set; }
public IDebugInfoProvider DebugInfo { get; set; }
public PEFile(string fileName, Stream stream, bool throwOnResolveError = false, PEStreamOptions options = PEStreamOptions.Default)
public PEFile(string fileName, Stream stream, PEStreamOptions options = PEStreamOptions.Default)
: this(fileName, new PEReader(stream, options))
{
this.FileName = fileName;
this.Reader = new PEReader(stream, options);
this.Metadata = Reader.GetMetadataReader();
this.AssemblyResolver = new UniversalAssemblyResolver(fileName, throwOnResolveError, Reader.DetectTargetFrameworkId(), options);
}
public PEFile(string fileName, Stream stream, IAssemblyResolver assemblyResolver, PEStreamOptions options = PEStreamOptions.Default)
public PEFile(string fileName, PEReader reader)
{
this.FileName = fileName;
this.Reader = new PEReader(stream, options);
this.Metadata = Reader.GetMetadataReader();
this.AssemblyResolver = assemblyResolver;
this.FileName = fileName ?? throw new ArgumentNullException(nameof(fileName));
this.Reader = reader ?? throw new ArgumentNullException(nameof(reader));
this.Metadata = reader.GetMetadataReader();
}
public bool IsAssembly => Metadata.IsAssembly;

2
ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs

@ -90,7 +90,7 @@ namespace ICSharpCode.Decompiler.Metadata @@ -90,7 +90,7 @@ namespace ICSharpCode.Decompiler.Metadata
throw new AssemblyResolutionException(name);
return null;
}
return new PEFile(file, new FileStream(file, FileMode.Open, FileAccess.Read), this, options);
return new PEFile(file, new FileStream(file, FileMode.Open, FileAccess.Read), options);
}
public string FindAssemblyFile(IAssemblyReference name)

12
ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs

@ -26,6 +26,7 @@ using ICSharpCode.Decompiler.Util; @@ -26,6 +26,7 @@ using ICSharpCode.Decompiler.Util;
using static ICSharpCode.Decompiler.Metadata.MetadataExtensions;
using System.Diagnostics;
using System.Collections.Immutable;
using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.Decompiler.TypeSystem
{
@ -77,18 +78,21 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -77,18 +78,21 @@ namespace ICSharpCode.Decompiler.TypeSystem
{
readonly Metadata.PEFile moduleDefinition;
readonly ICompilation compilation;
readonly IAssemblyResolver assemblyResolver;
readonly TypeSystemOptions typeSystemOptions;
readonly MetadataAssembly mainAssembly;
public DecompilerTypeSystem(Metadata.PEFile moduleDefinition) : this(moduleDefinition, new DecompilerSettings())
public DecompilerTypeSystem(Metadata.PEFile moduleDefinition, IAssemblyResolver assemblyResolver)
: this(moduleDefinition, assemblyResolver, new DecompilerSettings())
{
}
public DecompilerTypeSystem(Metadata.PEFile moduleDefinition, DecompilerSettings settings)
public DecompilerTypeSystem(PEFile moduleDefinition, IAssemblyResolver assemblyResolver, DecompilerSettings settings)
{
if (settings == null)
throw new ArgumentNullException(nameof(settings));
this.moduleDefinition = moduleDefinition;
this.moduleDefinition = moduleDefinition ?? throw new ArgumentNullException(nameof(moduleDefinition));
this.assemblyResolver = assemblyResolver ?? throw new ArgumentNullException(nameof(assemblyResolver));
typeSystemOptions = TypeSystemOptions.None;
if (settings.Dynamic)
typeSystemOptions |= TypeSystemOptions.Dynamic;
@ -106,7 +110,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -106,7 +110,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
var asmRef = assemblyReferenceQueue.Dequeue();
if (!processedAssemblyReferences.Add(asmRef))
continue;
var asm = moduleDefinition.AssemblyResolver.Resolve(asmRef);
var asm = assemblyResolver.Resolve(asmRef);
if (asm != null) {
referencedAssemblies.Add(asm.WithOptions(typeSystemOptions));
var metadata = asm.Metadata;

6
ICSharpCode.Decompiler/TypeSystem/IAssembly.cs

@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
using System.Collections.Generic;
using System.Reflection.Metadata;
using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.Decompiler.TypeSystem
{
@ -65,6 +66,11 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -65,6 +66,11 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// </summary>
public interface IAssembly : ICompilationProvider
{
/// <summary>
/// Gets the underlying metadata file. May return null, if the IAssembly was not created from a PE file.
/// </summary>
PEFile PEFile { get; }
/// <summary>
/// Gets whether this assembly is the main assembly of the compilation.
/// </summary>

2
ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultUnresolvedAssembly.cs

@ -330,6 +330,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -330,6 +330,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
this.ModuleAttributes = unresolved.ModuleAttributes.CreateResolvedAttributes(context);
}
public Metadata.PEFile PEFile => null;
public IUnresolvedAssembly UnresolvedAssembly {
get { return unresolvedAssembly; }
}

3
ICSharpCode.Decompiler/TypeSystem/MetadataAssembly.cs

@ -38,7 +38,6 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -38,7 +38,6 @@ namespace ICSharpCode.Decompiler.TypeSystem
public class MetadataAssembly : IAssembly
{
public ICompilation Compilation { get; }
public readonly Metadata.PEFile PEFile;
internal readonly MetadataReader metadata;
readonly TypeSystemOptions options;
internal readonly TypeProvider TypeProvider;
@ -86,6 +85,8 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -86,6 +85,8 @@ namespace ICSharpCode.Decompiler.TypeSystem
public TypeSystemOptions TypeSystemOptions => options;
#region IAssembly interface
public PEFile PEFile { get; }
public bool IsMainAssembly => this == Compilation.MainAssembly;
public string AssemblyName { get; }

4
ILSpy.BamlDecompiler.Tests/BamlTestRunner.cs

@ -114,13 +114,13 @@ namespace ILSpy.BamlDecompiler.Tests @@ -114,13 +114,13 @@ namespace ILSpy.BamlDecompiler.Tests
{
using (var fileStream = new FileStream(asmPath, FileMode.Open, FileAccess.Read)) {
var module = new PEFile(asmPath, fileStream);
var resolver = (UniversalAssemblyResolver)module.AssemblyResolver;
var resolver = new UniversalAssemblyResolver(asmPath, false, module.Reader.DetectTargetFrameworkId());
resolver.RemoveSearchDirectory(".");
resolver.AddSearchDirectory(Path.GetDirectoryName(asmPath));
var res = module.Resources.First();
Stream bamlStream = LoadBaml(res, name + ".baml");
Assert.IsNotNull(bamlStream);
XDocument document = BamlResourceEntryNode.LoadIntoDocument(module, bamlStream, CancellationToken.None);
XDocument document = BamlResourceEntryNode.LoadIntoDocument(module, resolver, bamlStream, CancellationToken.None);
XamlIsEqual(File.ReadAllText(sourcePath), document.ToString());
}

14
ILSpy.BamlDecompiler/BamlResourceEntryNode.cs

@ -50,30 +50,32 @@ namespace ILSpy.BamlDecompiler @@ -50,30 +50,32 @@ namespace ILSpy.BamlDecompiler
{
var asm = this.Ancestors().OfType<AssemblyTreeNode>().FirstOrDefault().LoadedAssembly;
Data.Position = 0;
XDocument xamlDocument = LoadIntoDocument(asm.GetPEFileOrNull(), Data, cancellationToken);
XDocument xamlDocument = LoadIntoDocument(asm.GetPEFileOrNull(), asm.GetAssemblyResolver(), Data, cancellationToken);
output.Write(xamlDocument.ToString());
return true;
}
internal static XDocument LoadIntoDocument(PEFile module, Stream stream, CancellationToken cancellationToken)
internal static XDocument LoadIntoDocument(PEFile module, IAssemblyResolver assemblyResolver,
Stream stream, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
XDocument xamlDocument;
using (XmlBamlReader reader = new XmlBamlReader(stream, new NRTypeResolver(module))) {
using (XmlBamlReader reader = new XmlBamlReader(stream, new NRTypeResolver(module, assemblyResolver))) {
xamlDocument = XDocument.Load(reader);
ConvertConnectionIds(xamlDocument, module, cancellationToken);
ConvertConnectionIds(xamlDocument, module, assemblyResolver, cancellationToken);
ConvertToEmptyElements(xamlDocument.Root);
MoveNamespacesToRoot(xamlDocument, reader.XmlnsDefinitions);
return xamlDocument;
}
}
static void ConvertConnectionIds(XDocument xamlDocument, PEFile asm, CancellationToken cancellationToken)
static void ConvertConnectionIds(XDocument xamlDocument, PEFile asm, IAssemblyResolver assemblyResolver,
CancellationToken cancellationToken)
{
var attr = xamlDocument.Root.Attribute(XName.Get("Class", XmlBamlReader.XWPFNamespace));
if (attr != null) {
string fullTypeName = attr.Value;
var mappings = new ConnectMethodDecompiler().DecompileEventMappings(asm, fullTypeName, cancellationToken);
var mappings = new ConnectMethodDecompiler().DecompileEventMappings(asm, assemblyResolver, fullTypeName, cancellationToken);
RemoveConnectionIds(xamlDocument.Root, mappings);
}
}

2
ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs

@ -36,7 +36,7 @@ namespace ILSpy.BamlDecompiler @@ -36,7 +36,7 @@ namespace ILSpy.BamlDecompiler
public string WriteResourceToFile(LoadedAssembly assembly, string fileName, Stream stream, DecompilationOptions options)
{
var document = BamlResourceEntryNode.LoadIntoDocument(assembly.GetPEFileOrNull(), stream, options.CancellationToken);
var document = BamlResourceEntryNode.LoadIntoDocument(assembly.GetPEFileOrNull(), assembly.GetAssemblyResolver(), stream, options.CancellationToken);
fileName = Path.ChangeExtension(fileName, ".xaml");
document.Save(Path.Combine(options.SaveAsProjectDirectory, fileName));
return fileName;

7
ILSpy.BamlDecompiler/CecilTypeResolver.cs

@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
using System;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy;
using Ricciolo.StylesExplorer.MarkupReflection;
namespace ILSpy.BamlDecompiler
@ -17,10 +18,10 @@ namespace ILSpy.BamlDecompiler @@ -17,10 +18,10 @@ namespace ILSpy.BamlDecompiler
readonly DecompilerTypeSystem typeSystem;
readonly ICompilation compilation;
public NRTypeResolver(PEFile module)
public NRTypeResolver(PEFile module, IAssemblyResolver resolver)
{
this.module = module;
this.typeSystem = new DecompilerTypeSystem(module);
this.module = module ?? throw new ArgumentNullException(nameof(module));
this.typeSystem = new DecompilerTypeSystem(module, resolver);
this.compilation = typeSystem.Compilation;
}

8
ILSpy.BamlDecompiler/ConnectMethodDecompiler.cs

@ -9,9 +9,11 @@ using System.Threading; @@ -9,9 +9,11 @@ using System.Threading;
using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.IL.Transforms;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
using ICSharpCode.Decompiler.Util;
using ICSharpCode.ILSpy;
using Metadata = ICSharpCode.Decompiler.Metadata;
namespace ILSpy.BamlDecompiler
@ -29,11 +31,11 @@ namespace ILSpy.BamlDecompiler @@ -29,11 +31,11 @@ namespace ILSpy.BamlDecompiler
/// </summary>
sealed class ConnectMethodDecompiler
{
public List<(LongSet, EventRegistration[])> DecompileEventMappings(Metadata.PEFile module,
public List<(LongSet, EventRegistration[])> DecompileEventMappings(Metadata.PEFile module, IAssemblyResolver assemblyResolver,
string fullTypeName, CancellationToken cancellationToken)
{
var result = new List<(LongSet, EventRegistration[])>();
var typeSystem = new DecompilerTypeSystem(module);
var typeSystem = new DecompilerTypeSystem(module, assemblyResolver);
var typeDefinition = typeSystem.Compilation.FindType(new FullTypeName(fullTypeName)).GetDefinition();
if (typeDefinition == null)
@ -58,7 +60,7 @@ namespace ILSpy.BamlDecompiler @@ -58,7 +60,7 @@ namespace ILSpy.BamlDecompiler
var function = ilReader.ReadIL(module, (MethodDefinitionHandle)method.MetadataToken,
module.Reader.GetMethodBody(metadataEntry.RelativeVirtualAddress), cancellationToken);
var context = new ILTransformContext(function, typeSystem) {
var context = new ILTransformContext(function, typeSystem, null) {
CancellationToken = cancellationToken
};
function.RunTransforms(CSharpDecompiler.GetILTransforms(), context);

9
ILSpy/DebugInfo/DiaSymNativeDebugInfoProvider.cs

@ -25,6 +25,7 @@ using System.Reflection.Metadata; @@ -25,6 +25,7 @@ using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Text;
using System.Threading.Tasks;
using ICSharpCode.Decompiler.DebugInfo;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.Util;
using Microsoft.DiaSymReader;
@ -48,12 +49,12 @@ namespace ICSharpCode.ILSpy.DebugInfo @@ -48,12 +49,12 @@ namespace ICSharpCode.ILSpy.DebugInfo
this.reader = SymUnmanagedReaderFactory.CreateReader<ISymUnmanagedReader5>(stream, this);
}
public IList<Decompiler.Metadata.SequencePoint> GetSequencePoints(MethodDefinitionHandle handle)
public IList<Decompiler.DebugInfo.SequencePoint> GetSequencePoints(MethodDefinitionHandle handle)
{
var method = reader.GetMethod(MetadataTokens.GetToken(handle));
if (method == null || method.GetSequencePointCount(out int count) != 0)
return Empty<Decompiler.Metadata.SequencePoint>.Array;
var sequencePoints = new Decompiler.Metadata.SequencePoint[count];
return Empty<Decompiler.DebugInfo.SequencePoint>.Array;
var sequencePoints = new Decompiler.DebugInfo.SequencePoint[count];
var points = method.GetSequencePoints();
int i = 0;
var buffer = new char[1024];
@ -64,7 +65,7 @@ namespace ICSharpCode.ILSpy.DebugInfo @@ -64,7 +65,7 @@ namespace ICSharpCode.ILSpy.DebugInfo
} else {
url = "";
}
sequencePoints[i] = new Decompiler.Metadata.SequencePoint() {
sequencePoints[i] = new Decompiler.DebugInfo.SequencePoint() {
Offset = point.Offset,
StartLine = point.StartLine,
StartColumn = point.StartColumn,

7
ILSpy/DebugInfo/PortableDebugInfoProvider.cs

@ -19,6 +19,7 @@ @@ -19,6 +19,7 @@
using System;
using System.Collections.Generic;
using System.Reflection.Metadata;
using ICSharpCode.Decompiler.DebugInfo;
using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.DebugInfo
@ -34,11 +35,11 @@ namespace ICSharpCode.ILSpy.DebugInfo @@ -34,11 +35,11 @@ namespace ICSharpCode.ILSpy.DebugInfo
this.provider = provider;
}
public IList<Decompiler.Metadata.SequencePoint> GetSequencePoints(MethodDefinitionHandle method)
public IList<Decompiler.DebugInfo.SequencePoint> GetSequencePoints(MethodDefinitionHandle method)
{
var metadata = provider.GetMetadataReader();
var debugInfo = metadata.GetMethodDebugInformation(method);
var sequencePoints = new List<Decompiler.Metadata.SequencePoint>();
var sequencePoints = new List<Decompiler.DebugInfo.SequencePoint>();
foreach (var point in debugInfo.GetSequencePoints()) {
string documentFileName;
@ -50,7 +51,7 @@ namespace ICSharpCode.ILSpy.DebugInfo @@ -50,7 +51,7 @@ namespace ICSharpCode.ILSpy.DebugInfo
documentFileName = "";
}
sequencePoints.Add(new Decompiler.Metadata.SequencePoint() {
sequencePoints.Add(new Decompiler.DebugInfo.SequencePoint() {
Offset = point.Offset,
StartLine = point.StartLine,
StartColumn = point.StartColumn,

2
ILSpy/ILSpy.csproj

@ -120,6 +120,7 @@ @@ -120,6 +120,7 @@
<Compile Include="GacInterop.cs" />
<Compile Include="GuessFileType.cs" />
<Compile Include="ContextMenuEntry.cs" />
<Compile Include="Languages\CSharpLanguage.cs" />
<Compile Include="Languages\CSharpLexer.cs" />
<Compile Include="Languages\CSharpHighlightingTokenWriter.cs" />
<Compile Include="ILSpySettings.cs" />
@ -135,6 +136,7 @@ @@ -135,6 +136,7 @@
<Compile Include="Languages\Language.cs" />
<Compile Include="Languages\Languages.cs" />
<Compile Include="LoadedAssembly.cs" />
<Compile Include="LoadedAssemblyExtensions.cs" />
<Compile Include="LoadedNugetPackage.cs" />
<Compile Include="NativeMethods.cs" />
<Compile Include="NavigationHistory.cs" />

215
ILSpy/Languages/CSharpLanguage.cs

@ -110,9 +110,9 @@ namespace ICSharpCode.ILSpy @@ -110,9 +110,9 @@ namespace ICSharpCode.ILSpy
}
}
CSharpDecompiler CreateDecompiler(Decompiler.Metadata.PEFile module, DecompilationOptions options)
CSharpDecompiler CreateDecompiler(PEFile module, DecompilationOptions options)
{
CSharpDecompiler decompiler = new CSharpDecompiler(module, options.DecompilerSettings);
CSharpDecompiler decompiler = new CSharpDecompiler(module, module.GetAssemblyResolver(), options.DecompilerSettings);
decompiler.CancellationToken = options.CancellationToken;
while (decompiler.AstTransforms.Count > transformCount)
decompiler.AstTransforms.RemoveAt(decompiler.AstTransforms.Count - 1);
@ -129,19 +129,19 @@ namespace ICSharpCode.ILSpy @@ -129,19 +129,19 @@ namespace ICSharpCode.ILSpy
syntaxTree.AcceptVisitor(new CSharpOutputVisitor(tokenWriter, settings.CSharpFormattingOptions));
}
public override void DecompileMethod(Decompiler.Metadata.MethodDefinition method, ITextOutput output, DecompilationOptions options)
public override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options)
{
AddReferenceWarningMessage(method.Module, output);
var md = method.Module.Metadata.GetMethodDefinition(method.Handle);
WriteCommentLine(output, TypeToString(new Entity(method.Module, md.GetDeclaringType()), includeNamespace: true));
CSharpDecompiler decompiler = CreateDecompiler(method.Module, options);
var methodDefinition = decompiler.TypeSystem.ResolveAsMethod(method.Handle);
PEFile assembly = method.ParentAssembly.PEFile;
AddReferenceWarningMessage(assembly, output);
WriteCommentLine(output, TypeToString(method.DeclaringType, includeNamespace: true));
CSharpDecompiler decompiler = CreateDecompiler(assembly, options);
var methodDefinition = decompiler.TypeSystem.ResolveAsMethod(method.MetadataToken);
if (methodDefinition.IsConstructor && methodDefinition.DeclaringType.IsReferenceType != false) {
var members = CollectFieldsAndCtors(methodDefinition.DeclaringTypeDefinition, methodDefinition.IsStatic);
decompiler.AstTransforms.Add(new SelectCtorTransform(methodDefinition));
WriteCode(output, options.DecompilerSettings, decompiler.Decompile(members), decompiler.TypeSystem);
} else {
WriteCode(output, options.DecompilerSettings, decompiler.Decompile(method.Handle), decompiler.TypeSystem);
WriteCode(output, options.DecompilerSettings, decompiler.Decompile(method.MetadataToken), decompiler.TypeSystem);
}
}
@ -196,28 +196,26 @@ namespace ICSharpCode.ILSpy @@ -196,28 +196,26 @@ namespace ICSharpCode.ILSpy
}
}
public override void DecompileProperty(Decompiler.Metadata.PropertyDefinition property, ITextOutput output, DecompilationOptions options)
public override void DecompileProperty(IProperty property, ITextOutput output, DecompilationOptions options)
{
AddReferenceWarningMessage(property.Module, output);
CSharpDecompiler decompiler = CreateDecompiler(property.Module, options);
var metadata = property.Module.Metadata;
var accessorHandle = metadata.GetPropertyDefinition(property.Handle).GetAccessors().GetAny();
WriteCommentLine(output, TypeToString(new Decompiler.Metadata.TypeDefinition(property.Module, metadata.GetMethodDefinition(accessorHandle).GetDeclaringType()), includeNamespace: true));
WriteCode(output, options.DecompilerSettings, decompiler.Decompile(property.Handle), decompiler.TypeSystem);
PEFile assembly = property.ParentAssembly.PEFile;
AddReferenceWarningMessage(assembly, output);
CSharpDecompiler decompiler = CreateDecompiler(assembly, options);
WriteCommentLine(output, TypeToString(property.DeclaringType, includeNamespace: true));
WriteCode(output, options.DecompilerSettings, decompiler.Decompile(property.MetadataToken), decompiler.TypeSystem);
}
public override void DecompileField(Decompiler.Metadata.FieldDefinition field, ITextOutput output, DecompilationOptions options)
public override void DecompileField(IField field, ITextOutput output, DecompilationOptions options)
{
AddReferenceWarningMessage(field.Module, output);
var fd = field.Module.Metadata.GetFieldDefinition(field.Handle);
WriteCommentLine(output, TypeToString(new Decompiler.Metadata.TypeDefinition(field.Module, fd.GetDeclaringType()), includeNamespace: true));
CSharpDecompiler decompiler = CreateDecompiler(field.Module, options);
var fieldDefinition = decompiler.TypeSystem.ResolveAsField(field.Handle);
if (fd.HasFlag(FieldAttributes.Literal)) {
WriteCode(output, options.DecompilerSettings, decompiler.Decompile(field.Handle), decompiler.TypeSystem);
PEFile assembly = field.ParentAssembly.PEFile;
AddReferenceWarningMessage(assembly, output);
WriteCommentLine(output, TypeToString(field.DeclaringType, includeNamespace: true));
CSharpDecompiler decompiler = CreateDecompiler(assembly, options);
if (field.IsConst) {
WriteCode(output, options.DecompilerSettings, decompiler.Decompile(field.MetadataToken), decompiler.TypeSystem);
} else {
var members = CollectFieldsAndCtors(fieldDefinition.DeclaringTypeDefinition, fieldDefinition.IsStatic);
decompiler.AstTransforms.Add(new SelectFieldTransform(fieldDefinition));
var members = CollectFieldsAndCtors(field.DeclaringTypeDefinition, field.IsStatic);
decompiler.AstTransforms.Add(new SelectFieldTransform(field));
WriteCode(output, options.DecompilerSettings, decompiler.Decompile(members), decompiler.TypeSystem);
}
}
@ -266,25 +264,25 @@ namespace ICSharpCode.ILSpy @@ -266,25 +264,25 @@ namespace ICSharpCode.ILSpy
}
}
public override void DecompileEvent(Decompiler.Metadata.EventDefinition ev, ITextOutput output, DecompilationOptions options)
public override void DecompileEvent(IEvent @event, ITextOutput output, DecompilationOptions options)
{
AddReferenceWarningMessage(ev.Module, output);
var metadata = ev.Module.Metadata;
var accessorHandle = metadata.GetEventDefinition(ev.Handle).GetAccessors().GetAny();
base.WriteCommentLine(output, TypeToString(new Decompiler.Metadata.TypeDefinition(ev.Module, metadata.GetMethodDefinition(accessorHandle).GetDeclaringType()), includeNamespace: true));
CSharpDecompiler decompiler = CreateDecompiler(ev.Module, options);
WriteCode(output, options.DecompilerSettings, decompiler.Decompile(ev.Handle), decompiler.TypeSystem);
PEFile assembly = @event.ParentAssembly.PEFile;
AddReferenceWarningMessage(assembly, output);
base.WriteCommentLine(output, TypeToString(@event.DeclaringType, includeNamespace: true));
CSharpDecompiler decompiler = CreateDecompiler(assembly, options);
WriteCode(output, options.DecompilerSettings, decompiler.Decompile(@event.MetadataToken), decompiler.TypeSystem);
}
public override void DecompileType(Decompiler.Metadata.TypeDefinition type, ITextOutput output, DecompilationOptions options)
public override void DecompileType(ITypeDefinition type, ITextOutput output, DecompilationOptions options)
{
AddReferenceWarningMessage(type.Module, output);
PEFile assembly = type.ParentAssembly.PEFile;
AddReferenceWarningMessage(assembly, output);
WriteCommentLine(output, TypeToString(type, includeNamespace: true));
CSharpDecompiler decompiler = CreateDecompiler(type.Module, options);
WriteCode(output, options.DecompilerSettings, decompiler.Decompile(type.Handle), decompiler.TypeSystem);
CSharpDecompiler decompiler = CreateDecompiler(assembly, options);
WriteCode(output, options.DecompilerSettings, decompiler.Decompile(type.MetadataToken), decompiler.TypeSystem);
}
void AddReferenceWarningMessage(Decompiler.Metadata.PEFile assembly, ITextOutput output)
void AddReferenceWarningMessage(PEFile assembly, ITextOutput output)
{
var loadedAssembly = MainWindow.Instance.CurrentAssemblyList.GetAssemblies().FirstOrDefault(la => la.GetPEFileOrNull() == assembly);
if (loadedAssembly == null || !loadedAssembly.LoadedAssemblyReferencesInfo.HasErrors)
@ -320,7 +318,7 @@ namespace ICSharpCode.ILSpy @@ -320,7 +318,7 @@ namespace ICSharpCode.ILSpy
public override void DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options)
{
var module = assembly.GetPEFileAsync().Result;
var module = assembly.GetPEFileOrNull();
if (options.FullDecompilation && options.SaveAsProjectDirectory != null) {
var decompiler = new ILSpyWholeProjectDecompiler(assembly, options);
decompiler.DecompileProject(module, options.SaveAsProjectDirectory, new TextOutputWriter(output), options.CancellationToken);
@ -328,23 +326,24 @@ namespace ICSharpCode.ILSpy @@ -328,23 +326,24 @@ namespace ICSharpCode.ILSpy
AddReferenceWarningMessage(module, output);
output.WriteLine();
base.DecompileAssembly(assembly, output, options);
var metadata = module.Metadata;
if (metadata.TypeDefinitions.Count > 0) {
IAssemblyResolver assemblyResolver = assembly.GetAssemblyResolver();
var typeSystem = new DecompilerTypeSystem(module, assemblyResolver, options.DecompilerSettings);
var globalType = typeSystem.MainAssembly.TypeDefinitions.FirstOrDefault();
if (globalType != null) {
output.Write("// Global type: ");
var globalType = metadata.TypeDefinitions.First();
output.WriteReference(globalType.GetFullTypeName(metadata).ToString(), new Decompiler.Metadata.TypeDefinition(module, globalType));
output.WriteReference(globalType.FullName, globalType);
output.WriteLine();
}
var metadata = module.Metadata;
var corHeader = module.Reader.PEHeaders.CorHeader;
var entrypointHandle = MetadataTokenHelpers.EntityHandleOrNil(corHeader.EntryPointTokenOrRelativeVirtualAddress);
if (!entrypointHandle.IsNil && entrypointHandle.Kind == HandleKind.MethodDefinition) {
var entrypoint = metadata.GetMethodDefinition((MethodDefinitionHandle)entrypointHandle);
output.Write("// Entry point: ");
string name = entrypoint.GetDeclaringType().GetFullTypeName(metadata) + "." + metadata.GetString(entrypoint.Name);
var entrypointEntity = new Decompiler.Metadata.MethodDefinition(module, (MethodDefinitionHandle)entrypointHandle);
output.WriteReference(name, entrypointEntity);
output.WriteLine();
var entrypoint = typeSystem.ResolveAsMethod(entrypointHandle);
if (entrypoint != null) {
output.Write("// Entry point: ");
output.WriteReference(entrypoint.DeclaringType.FullName + "." + entrypoint.Name, entrypoint);
output.WriteLine();
}
}
output.WriteLine("// Architecture: " + GetPlatformDisplayName(module));
if ((corHeader.Flags & System.Reflection.PortableExecutable.CorFlags.ILOnly) == 0) {
@ -358,7 +357,7 @@ namespace ICSharpCode.ILSpy @@ -358,7 +357,7 @@ namespace ICSharpCode.ILSpy
// don't automatically load additional assemblies when an assembly node is selected in the tree view
using (options.FullDecompilation ? null : LoadedAssembly.DisableAssemblyLoad()) {
CSharpDecompiler decompiler = new CSharpDecompiler(module, options.DecompilerSettings);
CSharpDecompiler decompiler = new CSharpDecompiler(typeSystem, assemblyResolver, options.DecompilerSettings);
decompiler.CancellationToken = options.CancellationToken;
SyntaxTree st;
if (options.FullDecompilation) {
@ -405,82 +404,35 @@ namespace ICSharpCode.ILSpy @@ -405,82 +404,35 @@ namespace ICSharpCode.ILSpy
}
}
public override string TypeToString(Entity type, Decompiler.Metadata.GenericContext genericContext = null, bool includeNamespace = true)
public override string TypeToString(IType type, bool includeNamespace)
{
if (type.Handle.IsNil)
if (type == null)
throw new ArgumentNullException(nameof(type));
var metadata = type.Module.Metadata;
ConvertTypeOptions convertTypeOptions = ConvertTypeOptions.IncludeTypeParameterDefinitions;
if (includeNamespace)
convertTypeOptions |= ConvertTypeOptions.IncludeNamespace;
//if (includeTypeName)
// convertTypeOptions |= ConvertTypeOptions.IncludeOuterTypeName;
var builder = new AstTypeBuilder(convertTypeOptions);
AstType astType;
switch (type.Handle.Kind) {
case HandleKind.TypeReference:
astType = builder.GetTypeFromReference(metadata, (TypeReferenceHandle)type.Handle, 0);
return TypeToString(astType, metadata, null);
case HandleKind.TypeDefinition:
var td = metadata.GetTypeDefinition((TypeDefinitionHandle)type.Handle);
var genericParams = td.GetGenericParameters();
var buffer = new System.Text.StringBuilder();
var name = td.GetFullTypeName(metadata);
if (includeNamespace)
buffer.Append(name.ToString());
else
buffer.Append(name.Name);
if (genericParams.Count > 0) {
buffer.Append('<');
int i = 0;
foreach (var h in genericParams) {
var gp = metadata.GetGenericParameter(h);
if (i > 0)
buffer.Append(", ");
buffer.Append(metadata.GetString(gp.Name));
i++;
}
buffer.Append('>');
}
TypeSystemAstBuilder builder = new TypeSystemAstBuilder();
AstType astType = builder.ConvertType(type);
StringWriter w = new StringWriter();
return buffer.ToString();
case HandleKind.TypeSpecification:
var ts = metadata.GetTypeSpecification((TypeSpecificationHandle)type.Handle);
astType = builder.GetTypeFromSpecification(metadata, genericContext ?? GenericContext.Empty, (TypeSpecificationHandle)type.Handle, 0);
return TypeToString(astType, metadata, ts.GetCustomAttributes());
default:
throw new NotSupportedException();
}
astType.AcceptVisitor(new CSharpOutputVisitor(w, FormattingOptionsFactory.CreateAllman()));
return w.ToString();
}
public override string FieldToString(Decompiler.Metadata.FieldDefinition field, bool includeTypeName, bool includeNamespace)
public override string FieldToString(IField field, bool includeTypeName, bool includeNamespace)
{
if (field.Handle.IsNil)
if (field == null)
throw new ArgumentNullException(nameof(field));
ConvertTypeOptions convertTypeOptions = ConvertTypeOptions.IncludeTypeParameterDefinitions;
if (includeNamespace)
convertTypeOptions |= ConvertTypeOptions.IncludeNamespace;
if (includeTypeName)
convertTypeOptions |= ConvertTypeOptions.IncludeOuterTypeName;
var metadata = field.Module.Metadata;
var fd = metadata.GetFieldDefinition(field.Handle);
AstType fieldType = fd.DecodeSignature(new AstTypeBuilder(convertTypeOptions), new GenericContext(fd.GetDeclaringType(), field.Module));
string simple = metadata.GetString(fd.Name) + " : " + TypeToString(fieldType, metadata, fd.GetCustomAttributes());
string simple = field.Name + " : " + TypeToString(field.Type, includeNamespace);
if (!includeTypeName)
return simple;
var typeName = fd.GetDeclaringType().GetFullTypeName(metadata);
var typeName = field.DeclaringTypeDefinition.FullTypeName;
if (!includeNamespace)
return typeName.Name + "." + simple;
return typeName + "." + simple;
}
public override string PropertyToString(Decompiler.Metadata.PropertyDefinition property, bool includeTypeName, bool includeNamespace, bool? isIndexer = null)
/*
public override string PropertyToString(IProperty property, bool includeTypeName, bool includeNamespace, bool? isIndexer = null)
{
if (property.IsNil)
if (property == null)
throw new ArgumentNullException(nameof(property));
ConvertTypeOptions convertTypeOptions = ConvertTypeOptions.IncludeTypeParameterDefinitions;
if (includeNamespace)
@ -699,43 +651,18 @@ namespace ICSharpCode.ILSpy @@ -699,43 +651,18 @@ namespace ICSharpCode.ILSpy
buffer.Append(" : ");
buffer.Append(TypeToString(signature, metadata, returnTypeAttributes));
return buffer.ToString();
}
}*/
public override bool ShowMember(IMetadataEntity member)
public override bool ShowMember(IEntity member)
{
return showAllMembers || !CSharpDecompiler.MemberIsHidden(member.Module, member.Handle, new DecompilationOptions().DecompilerSettings);
PEFile assembly = member.ParentAssembly.PEFile;
return showAllMembers || !CSharpDecompiler.MemberIsHidden(assembly, member.MetadataToken, new DecompilationOptions().DecompilerSettings);
}
public override string GetTooltip(Entity entity)
public override string GetTooltip(IEntity entity)
{
var decompilerTypeSystem = new DecompilerTypeSystem(entity.Module);
ISymbol symbol;
switch (entity.Handle.Kind) {
case HandleKind.MethodDefinition:
symbol = decompilerTypeSystem.ResolveAsMethod(entity.Handle);
if (symbol == null) return base.GetTooltip(entity);
break;
case HandleKind.PropertyDefinition:
symbol = decompilerTypeSystem.ResolveAsProperty(entity.Handle);
if (symbol == null) return base.GetTooltip(entity);
break;
case HandleKind.EventDefinition:
symbol = decompilerTypeSystem.ResolveAsEvent(entity.Handle);
if (symbol == null) return base.GetTooltip(entity);
break;
case HandleKind.FieldDefinition:
symbol = decompilerTypeSystem.ResolveAsField(entity.Handle);
if (symbol == null) return base.GetTooltip(entity);
break;
case HandleKind.TypeDefinition:
symbol = decompilerTypeSystem.ResolveAsType(entity.Handle).GetDefinition();
if (symbol == null) return base.GetTooltip(entity);
break;
default:
return base.GetTooltip(entity);
}
var flags = ConversionFlags.All & ~ConversionFlags.ShowBody;
return new CSharpAmbience() { ConversionFlags = flags }.ConvertSymbol(symbol);
return new CSharpAmbience() { ConversionFlags = flags }.ConvertSymbol(entity);
}
public override CodeMappingInfo GetCodeMappingInfo(PEFile module, EntityHandle member)

39
ILSpy/LoadedAssembly.cs

@ -21,9 +21,11 @@ using System.Collections.Generic; @@ -21,9 +21,11 @@ using System.Collections.Generic;
using System.IO;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.DebugInfo;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
@ -39,6 +41,8 @@ namespace ICSharpCode.ILSpy @@ -39,6 +41,8 @@ namespace ICSharpCode.ILSpy
/// </summary>
public sealed class LoadedAssembly
{
internal static readonly ConditionalWeakTable<PEFile, LoadedAssembly> loadedAssemblies = new ConditionalWeakTable<PEFile, LoadedAssembly>();
readonly Task<PEFile> assemblyTask;
readonly AssemblyList assemblyList;
readonly string fileName;
@ -65,6 +69,8 @@ namespace ICSharpCode.ILSpy @@ -65,6 +69,8 @@ namespace ICSharpCode.ILSpy
public ReferenceLoadInfo LoadedAssemblyReferencesInfo { get; } = new ReferenceLoadInfo();
IDebugInfoProvider debugInfoProvider;
/// <summary>
/// Gets the Cecil ModuleDefinition.
/// </summary>
@ -87,12 +93,20 @@ namespace ICSharpCode.ILSpy @@ -87,12 +93,20 @@ namespace ICSharpCode.ILSpy
}
}
public ICompilation GetTypeSystem()
ICompilation typeSystem;
/// <summary>
/// Gets a type system containing all types from this assembly + primitve types from mscorlib.
/// Returns null in case of load errors.
/// </summary>
public ICompilation GetTypeSystemOrNull()
{
if (typeSystem != null)
return typeSystem;
var module = GetPEFileOrNull();
if (module == null)
return null;
return new SimpleCompilation(module, MinimalCorlib.Instance);
return typeSystem = new SimpleCompilation(module, MinimalCorlib.Instance);
}
public AssemblyList AssemblyList => assemblyList;
@ -129,12 +143,12 @@ namespace ICSharpCode.ILSpy @@ -129,12 +143,12 @@ namespace ICSharpCode.ILSpy
if (stream != null)
{
// Read the module from a precrafted stream
module = new PEFile(fileName, stream, new MyAssemblyResolver(this), PEStreamOptions.Default);
module = new PEFile(fileName, stream);
}
else
{
// Read the module from disk (by default)
module = new PEFile(fileName, new FileStream(fileName, FileMode.Open, FileAccess.Read), new MyAssemblyResolver(this), PEStreamOptions.PrefetchEntireImage);
module = new PEFile(fileName, new FileStream(fileName, FileMode.Open, FileAccess.Read), PEStreamOptions.PrefetchEntireImage);
}
if (DecompilerSettingsPanel.CurrentDecompilerSettings.UseDebugSymbols) {
@ -146,6 +160,9 @@ namespace ICSharpCode.ILSpy @@ -146,6 +160,9 @@ namespace ICSharpCode.ILSpy
// ignore any errors during symbol loading
}
}
lock (loadedAssemblies) {
loadedAssemblies.Add(module, this);
}
return module;
}
@ -154,13 +171,13 @@ namespace ICSharpCode.ILSpy @@ -154,13 +171,13 @@ namespace ICSharpCode.ILSpy
var reader = module.Reader;
// try to open portable pdb file/embedded pdb info:
if (reader.TryOpenAssociatedPortablePdb(fileName, OpenStream, out var provider, out var pdbFileName)) {
module.DebugInfo = new PortableDebugInfoProvider(pdbFileName, provider);
debugInfoProvider = new PortableDebugInfoProvider(pdbFileName, provider);
} else {
// search for pdb in same directory as dll
string pdbDirectory = Path.GetDirectoryName(fileName);
pdbFileName = Path.Combine(pdbDirectory, Path.GetFileNameWithoutExtension(fileName) + ".pdb");
if (File.Exists(pdbFileName)) {
module.DebugInfo = new DiaSymNativeDebugInfoProvider(module, pdbFileName, OpenStream(pdbFileName));
debugInfoProvider = new DiaSymNativeDebugInfoProvider(module, pdbFileName, OpenStream(pdbFileName));
return;
}
@ -223,6 +240,16 @@ namespace ICSharpCode.ILSpy @@ -223,6 +240,16 @@ namespace ICSharpCode.ILSpy
return new MyAssemblyResolver(this);
}
/// <summary>
/// Returns the debug info for this assembly. Returns null in case of load errors or no debug info is available.
/// </summary>
public IDebugInfoProvider GetDebugInfoOrNull()
{
if (GetPEFileOrNull() == null)
return null;
return debugInfoProvider;
}
public LoadedAssembly LookupReferencedAssembly(Decompiler.Metadata.IAssemblyReference reference)
{
if (reference == null)

25
ILSpy/LoadedAssemblyExtensions.cs

@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy
{
public static class LoadedAssemblyExtensions
{
public static IAssemblyResolver GetAssemblyResolver(this PEFile file)
{
if (file == null)
throw new ArgumentNullException(nameof(file));
LoadedAssembly loadedAssembly;
lock (LoadedAssembly.loadedAssemblies) {
if (!LoadedAssembly.loadedAssemblies.TryGetValue(file, out loadedAssembly))
throw new ArgumentException("The specified file is not associated with a LoadedAssembly!");
}
return loadedAssembly.GetAssemblyResolver();
}
}
}

2
ILSpy/SearchPane.cs

@ -217,7 +217,7 @@ namespace ICSharpCode.ILSpy @@ -217,7 +217,7 @@ namespace ICSharpCode.ILSpy
try {
var searcher = GetSearchStrategy(searchMode, searchTerm);
foreach (var loadedAssembly in assemblies) {
var typeSystem = loadedAssembly.GetTypeSystem();
var typeSystem = loadedAssembly.GetTypeSystemOrNull();
if (typeSystem == null)
continue;
CancellationToken cancellationToken = cts.Token;

6
ILSpy/TreeNodes/Analyzer/ScopedWhereUsedAnalyzer.cs

@ -233,7 +233,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -233,7 +233,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
IEnumerable<T> FindReferencesInAssembly(Decompiler.Metadata.PEFile module, CancellationToken ct)
{
IDecompilerTypeSystem ts = provideTypeSystem ? new DecompilerTypeSystem(module) : null;
IDecompilerTypeSystem ts = provideTypeSystem ? new DecompilerTypeSystem(module, module.GetAssemblyResolver()) : null;
var metadata = module.Metadata;
foreach (var type in TreeTraversal.PreOrder(metadata.TypeDefinitions, t => metadata.GetTypeDefinition(t).GetNestedTypes())) {
ct.ThrowIfCancellationRequested();
@ -247,7 +247,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -247,7 +247,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
IEnumerable<T> FindReferencesInTypeScope(CancellationToken ct)
{
IDecompilerTypeSystem ts = provideTypeSystem ? new DecompilerTypeSystem(assemblyScope) : null;
IDecompilerTypeSystem ts = provideTypeSystem ? new DecompilerTypeSystem(assemblyScope, assemblyScope.GetAssemblyResolver()) : null;
foreach (var type in TreeTraversal.PreOrder(typeScopeHandle, t => assemblyScope.Metadata.GetTypeDefinition(t).GetNestedTypes())) {
ct.ThrowIfCancellationRequested();
var codeMappingInfo = language.GetCodeMappingInfo(assemblyScope, type);
@ -260,7 +260,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -260,7 +260,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
IEnumerable<T> FindReferencesInEnclosingTypeScope(CancellationToken ct)
{
IDecompilerTypeSystem ts = provideTypeSystem ? new DecompilerTypeSystem(assemblyScope) : null;
IDecompilerTypeSystem ts = provideTypeSystem ? new DecompilerTypeSystem(assemblyScope, assemblyScope.GetAssemblyResolver()) : null;
var codeMappingInfo = language.GetCodeMappingInfo(assemblyScope, typeScope.GetDeclaringType());
foreach (var type in TreeTraversal.PreOrder(typeScope.GetDeclaringType(), t => assemblyScope.Metadata.GetTypeDefinition(t).GetNestedTypes())) {
ct.ThrowIfCancellationRequested();

2
ILSpy/TreeNodes/AssemblyTreeNode.cs

@ -135,7 +135,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -135,7 +135,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
// if we crashed on loading, then we don't have any children
return;
}
typeSystem = new SimpleCompilation(module, MinimalCorlib.Instance);
typeSystem = LoadedAssembly.GetTypeSystemOrNull();
var assembly = (MetadataAssembly)typeSystem.MainAssembly;
var metadata = module.Metadata;

8
ILSpy/TreeNodes/BaseTypesEntryNode.cs

@ -65,16 +65,16 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -65,16 +65,16 @@ namespace ICSharpCode.ILSpy.TreeNodes
protected override void LoadChildren()
{
DecompilerTypeSystem typeSystem = new DecompilerTypeSystem(module);
DecompilerTypeSystem typeSystem = new DecompilerTypeSystem(module, module.GetAssemblyResolver());
var t = typeSystem.ResolveAsType(handle).GetDefinition();
if (t != null) {
BaseTypesTreeNode.AddBaseTypes(this.Children, ((MetadataAssembly)t.ParentAssembly).PEFile, t);
BaseTypesTreeNode.AddBaseTypes(this.Children, t.ParentAssembly.PEFile, t);
}
}
public override void ActivateItem(System.Windows.RoutedEventArgs e)
{
DecompilerTypeSystem typeSystem = new DecompilerTypeSystem(module);
DecompilerTypeSystem typeSystem = new DecompilerTypeSystem(module, module.GetAssemblyResolver());
var t = typeSystem.ResolveAsType(handle).GetDefinition();
e.Handled = ActivateItem(this, t);
}
@ -98,7 +98,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -98,7 +98,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
IEntity IMemberTreeNode.Member {
get {
DecompilerTypeSystem typeSystem = new DecompilerTypeSystem(module);
DecompilerTypeSystem typeSystem = new DecompilerTypeSystem(module, module.GetAssemblyResolver());
var t = typeSystem.ResolveAsType(handle).GetDefinition();
return t;
}

4
ILSpy/TreeNodes/GeneratePdbContextMenuEntry.cs

@ -7,7 +7,7 @@ using System.Text; @@ -7,7 +7,7 @@ using System.Text;
using System.Threading.Tasks;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.Pdb;
using ICSharpCode.Decompiler.DebugInfo;
using ICSharpCode.ILSpy.TextView;
using Microsoft.Win32;
@ -33,7 +33,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -33,7 +33,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
using (FileStream stream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write)) {
try {
var file = assembly.GetPEFileOrNull();
var decompiler = new CSharpDecompiler(file, options.DecompilerSettings);
var decompiler = new CSharpDecompiler(file, assembly.GetAssemblyResolver(), options.DecompilerSettings);
PortablePdbWriter.WritePdb(file, decompiler, options.DecompilerSettings, stream);
} catch (OperationCanceledException) {
output.WriteLine();

Loading…
Cancel
Save