Browse Source

Move CodeMappingInfo to Decompiler.

pull/1030/head
Siegfried Pammer 7 years ago
parent
commit
27cf62d710
  1. 55
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  2. 28
      ICSharpCode.Decompiler/CSharp/RequiredNamespaceCollector.cs
  3. 1
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  4. 14
      ICSharpCode.Decompiler/Metadata/CodeMappingInfo.cs
  5. 1
      ILSpy/Analyzers/IAnalyzer.cs
  6. 1
      ILSpy/ILSpy.csproj
  7. 50
      ILSpy/Languages/CSharpLanguage.cs
  8. 2
      ILSpy/Languages/Language.cs

55
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -41,6 +41,8 @@ using ICSharpCode.Decompiler.Metadata; @@ -41,6 +41,8 @@ using ICSharpCode.Decompiler.Metadata;
using System.Reflection.PortableExecutable;
using ICSharpCode.Decompiler.Documentation;
using ICSharpCode.Decompiler.DebugInfo;
using ICSharpCode.Decompiler.Disassembler;
using System.Reflection.Metadata.Ecma335;
namespace ICSharpCode.Decompiler.CSharp
{
@ -464,6 +466,59 @@ namespace ICSharpCode.Decompiler.CSharp @@ -464,6 +466,59 @@ namespace ICSharpCode.Decompiler.CSharp
};
}
public static CodeMappingInfo GetCodeMappingInfo(PEFile module, EntityHandle member)
{
var declaringType = member.GetDeclaringType(module.Metadata);
if (declaringType.IsNil && member.Kind == HandleKind.TypeDefinition) {
declaringType = (TypeDefinitionHandle)member;
}
var info = new CodeMappingInfo(module, declaringType);
var td = module.Metadata.GetTypeDefinition(declaringType);
foreach (var method in td.GetMethods()) {
var parent = method;
var part = method;
var connectedMethods = new Queue<MethodDefinitionHandle>();
connectedMethods.Enqueue(part);
while (connectedMethods.Count > 0) {
part = connectedMethods.Dequeue();
var md = module.Metadata.GetMethodDefinition(part);
if (!md.HasBody()) {
info.AddMapping(parent, part);
} else {
// TODO : async and yield fsms
// deal with ldftn instructions, i.e., lambdas
var blob = module.Reader.GetMethodBody(md.RelativeVirtualAddress).GetILReader();
while (blob.RemainingBytes > 0) {
var code = blob.DecodeOpCode();
if (code == ILOpCode.Ldftn) {
var token = MetadataTokens.EntityHandle(blob.ReadInt32());
if (token.Kind == HandleKind.MethodDefinition) {
if (((MethodDefinitionHandle)token).IsCompilerGenerated(module.Metadata))
connectedMethods.Enqueue((MethodDefinitionHandle)token);
}
} else {
blob.SkipOperand(code);
}
}
info.AddMapping(parent, part);
}
}
}
return info;
}
/// <summary>
/// Decompiles the whole module into a single string.
/// </summary>

28
ICSharpCode.Decompiler/CSharp/RequiredNamespaceCollector.cs

@ -34,12 +34,15 @@ namespace ICSharpCode.Decompiler.CSharp @@ -34,12 +34,15 @@ namespace ICSharpCode.Decompiler.CSharp
HandleAttributes(typeSystem.MainAssembly.GetModuleAttributes(), namespaces);
}
public static void CollectNamespaces(IEntity entity, DecompilerTypeSystem typeSystem, HashSet<string> namespaces, bool scanningFullType = false)
public static void CollectNamespaces(IEntity entity, DecompilerTypeSystem typeSystem,
HashSet<string> namespaces, CodeMappingInfo mappingInfo = null, bool scanningFullType = false)
{
if (entity == null)
if (entity == null || entity.MetadataToken.IsNil)
return;
switch (entity) {
case ITypeDefinition td:
if (mappingInfo == null)
mappingInfo = CSharpDecompiler.GetCodeMappingInfo(entity.ParentAssembly.PEFile, entity.MetadataToken);
namespaces.Add(td.Namespace);
HandleAttributes(td.GetAttributes(), namespaces);
@ -52,23 +55,23 @@ namespace ICSharpCode.Decompiler.CSharp @@ -52,23 +55,23 @@ namespace ICSharpCode.Decompiler.CSharp
}
foreach (var nestedType in td.NestedTypes) {
CollectNamespaces(nestedType, typeSystem, namespaces, scanningFullType: true);
CollectNamespaces(nestedType, typeSystem, namespaces, mappingInfo, scanningFullType: true);
}
foreach (var field in td.Fields) {
CollectNamespaces(field, typeSystem, namespaces, scanningFullType: true);
CollectNamespaces(field, typeSystem, namespaces, mappingInfo, scanningFullType: true);
}
foreach (var property in td.Properties) {
CollectNamespaces(property, typeSystem, namespaces, scanningFullType: true);
CollectNamespaces(property, typeSystem, namespaces, mappingInfo, scanningFullType: true);
}
foreach (var @event in td.Events) {
CollectNamespaces(@event, typeSystem, namespaces, scanningFullType: true);
CollectNamespaces(@event, typeSystem, namespaces, mappingInfo, scanningFullType: true);
}
foreach (var method in td.Methods) {
CollectNamespaces(method, typeSystem, namespaces, scanningFullType: true);
CollectNamespaces(method, typeSystem, namespaces, mappingInfo, scanningFullType: true);
}
break;
case IField field:
@ -87,10 +90,15 @@ namespace ICSharpCode.Decompiler.CSharp @@ -87,10 +90,15 @@ namespace ICSharpCode.Decompiler.CSharp
HandleAttributes(typeParam.GetAttributes(), namespaces);
}
if (!method.MetadataToken.IsNil && method.HasBody) {
if (mappingInfo == null)
mappingInfo = CSharpDecompiler.GetCodeMappingInfo(entity.ParentAssembly.PEFile, entity.MetadataToken);
var reader = typeSystem.ModuleDefinition.Reader;
var methodDef = typeSystem.ModuleDefinition.Metadata.GetMethodDefinition((MethodDefinitionHandle)method.MetadataToken);
var body = reader.GetMethodBody(methodDef.RelativeVirtualAddress);
CollectNamespacesFromMethodBody(body, reader, typeSystem, namespaces, scanningFullType: scanningFullType);
var parts = mappingInfo.GetMethodParts((MethodDefinitionHandle)method.MetadataToken).ToList();
foreach (var part in parts) {
var methodDef = typeSystem.ModuleDefinition.Metadata.GetMethodDefinition(part);
var body = reader.GetMethodBody(methodDef.RelativeVirtualAddress);
CollectNamespacesFromMethodBody(body, reader, typeSystem, namespaces, scanningFullType: scanningFullType);
}
}
break;
case IProperty property:

1
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -267,6 +267,7 @@ @@ -267,6 +267,7 @@
<Compile Include="CSharp\Transforms\AddXmlDocumentationTransform.cs" />
<Compile Include="DecompileRun.cs" />
<Compile Include="Metadata\AssemblyReferences.cs" />
<Compile Include="Metadata\CodeMappingInfo.cs" />
<Compile Include="Metadata\EnumUnderlyingTypeResolveException.cs" />
<Compile Include="Metadata\MetadataTokenHelpers.cs" />
<Compile Include="Disassembler\OpCodeInfo.cs" />

14
ILSpy/Languages/CodeMappingInfo.cs → ICSharpCode.Decompiler/Metadata/CodeMappingInfo.cs

@ -5,32 +5,24 @@ using System.Linq; @@ -5,32 +5,24 @@ using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
namespace ICSharpCode.ILSpy
namespace ICSharpCode.Decompiler.Metadata
{
public class CodeMappingInfo
{
public Decompiler.Metadata.PEFile Module { get; }
public Language Language { get; }
public PEFile Module { get; }
public TypeDefinitionHandle TypeDefinition { get; }
Dictionary<MethodDefinitionHandle, List<MethodDefinitionHandle>> parts;
Dictionary<MethodDefinitionHandle, MethodDefinitionHandle> parents;
public CodeMappingInfo(Language language, Decompiler.Metadata.PEFile module, TypeDefinitionHandle type)
public CodeMappingInfo(PEFile module, TypeDefinitionHandle type)
{
this.Language = language;
this.Module = module;
this.TypeDefinition = type;
this.parts = new Dictionary<MethodDefinitionHandle, List<MethodDefinitionHandle>>();
this.parents = new Dictionary<MethodDefinitionHandle, MethodDefinitionHandle>();
}
public bool ShowMember(EntityHandle entity)
{
throw null;
//return Language.ShowMember(new Decompiler.Metadata.Entity(Module, entity));
}
public IEnumerable<MethodDefinitionHandle> GetMethodParts(MethodDefinitionHandle method)
{
if (parts.TryGetValue(method, out var p))

1
ILSpy/Analyzers/IAnalyzer.cs

@ -21,6 +21,7 @@ using System.Collections.Generic; @@ -21,6 +21,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection.Metadata;
using System.Threading;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.ILSpy.Analyzers

1
ILSpy/ILSpy.csproj

@ -130,7 +130,6 @@ @@ -130,7 +130,6 @@
<DependentUpon>DebugSteps.xaml</DependentUpon>
</Compile>
<Compile Include="ILSpyTraceListener.cs" />
<Compile Include="Languages\CodeMappingInfo.cs" />
<Compile Include="DecompilationOptions.cs" />
<Compile Include="ExtensionMethods.cs" />
<Compile Include="FilterSettings.cs" />

50
ILSpy/Languages/CSharpLanguage.cs

@ -564,55 +564,7 @@ namespace ICSharpCode.ILSpy @@ -564,55 +564,7 @@ namespace ICSharpCode.ILSpy
public override CodeMappingInfo GetCodeMappingInfo(PEFile module, EntityHandle member)
{
var declaringType = member.GetDeclaringType(module.Metadata);
if (declaringType.IsNil && member.Kind == HandleKind.TypeDefinition) {
declaringType = (TypeDefinitionHandle)member;
}
var info = new CodeMappingInfo(this, module, declaringType);
var td = module.Metadata.GetTypeDefinition(declaringType);
foreach (var method in td.GetMethods()) {
var parent = method;
var part = method;
var connectedMethods = new Queue<MethodDefinitionHandle>();
connectedMethods.Enqueue(part);
while (connectedMethods.Count > 0) {
part = connectedMethods.Dequeue();
var md = module.Metadata.GetMethodDefinition(part);
if (!md.HasBody()) {
info.AddMapping(parent, part);
} else {
// TODO : async and yield fsms
// deal with ldftn instructions, i.e., lambdas
var blob = module.Reader.GetMethodBody(md.RelativeVirtualAddress).GetILReader();
while (blob.RemainingBytes > 0) {
var code = blob.DecodeOpCode();
if (code == ILOpCode.Ldftn) {
var token = MetadataTokens.EntityHandle(blob.ReadInt32());
if (token.Kind == HandleKind.MethodDefinition) {
if (((MethodDefinitionHandle)token).IsCompilerGenerated(module.Metadata))
connectedMethods.Enqueue((MethodDefinitionHandle)token);
}
} else {
blob.SkipOperand(code);
}
}
info.AddMapping(parent, part);
}
}
}
return info;
return CSharpDecompiler.GetCodeMappingInfo(module, member);
}
}
}

2
ILSpy/Languages/Language.cs

@ -274,7 +274,7 @@ namespace ICSharpCode.ILSpy @@ -274,7 +274,7 @@ namespace ICSharpCode.ILSpy
declaringType = (SRM.TypeDefinitionHandle)member;
}
return new CodeMappingInfo(this, module, declaringType);
return new CodeMappingInfo(module, declaringType);
}
public static string GetPlatformDisplayName(PEFile module)

Loading…
Cancel
Save