Browse Source

Port ProxyCallReplacer and TextTokenWriter to SRM

pull/1198/head
Siegfried Pammer 7 years ago
parent
commit
a2e27dd7ed
  1. 25
      ICSharpCode.Decompiler/IL/Transforms/ProxyCallReplacer.cs
  2. 46
      ICSharpCode.Decompiler/Output/TextTokenWriter.cs

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

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
using System.Diagnostics;
using System.Linq;
using System.Reflection.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using Mono.Cecil;
namespace ICSharpCode.Decompiler.IL.Transforms
{
@ -12,15 +12,22 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -12,15 +12,22 @@ namespace ICSharpCode.Decompiler.IL.Transforms
public void Run(ILFunction function, ILTransformContext context)
{
this.context = context;
var module = context.TypeSystem.ModuleDefinition;
var metadata = context.TypeSystem.GetMetadata();
foreach (var inst in function.Descendants.OfType<CallInstruction>()) {
MethodDefinition methodDef = context.TypeSystem.GetCecil(inst.Method) as MethodDefinition;
if (methodDef != null && methodDef.Body != null) {
if (inst.Method.IsCompilerGeneratedOrIsInCompilerGeneratedClass()) {
var handle = (MethodDefinitionHandle)inst.Method.MetadataToken;
if (handle.IsNil
|| !IsDefinedInCurrentOrOuterClass(inst.Method, context.Function.Method.DeclaringTypeDefinition)
|| !inst.Method.IsCompilerGeneratedOrIsInCompilerGeneratedClass()) {
continue;
}
MethodDefinition methodDef = metadata.GetMethodDefinition((MethodDefinitionHandle)inst.Method.MetadataToken);
if (!methodDef.HasBody()) continue;
// partially copied from CSharpDecompiler
var specializingTypeSystem = this.context.TypeSystem.GetSpecializingTypeSystem(inst.Method.Substitution);
var ilReader = new ILReader(specializingTypeSystem);
System.Threading.CancellationToken cancellationToken = new System.Threading.CancellationToken();
var proxyFunction = ilReader.ReadIL(methodDef.Body, cancellationToken);
var proxyFunction = ilReader.ReadIL(module, handle, module.Reader.GetMethodBody(methodDef.RelativeVirtualAddress), cancellationToken);
var transformContext = new ILTransformContext(proxyFunction, specializingTypeSystem, this.context.Settings) {
CancellationToken = cancellationToken,
DecompileRun = context.DecompileRun
@ -74,7 +81,15 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -74,7 +81,15 @@ namespace ICSharpCode.Decompiler.IL.Transforms
inst.ReplaceWith(newInst);
}
}
static bool IsDefinedInCurrentOrOuterClass(IMethod method, ITypeDefinition declaringTypeDefinition)
{
while (declaringTypeDefinition != null) {
if (method.DeclaringTypeDefinition == declaringTypeDefinition)
return true;
declaringTypeDefinition = declaringTypeDefinition.DeclaringTypeDefinition;
}
return false;
}
}
}

46
ICSharpCode.Decompiler/Output/TextTokenWriter.cs

@ -23,8 +23,8 @@ using ICSharpCode.Decompiler.CSharp; @@ -23,8 +23,8 @@ using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.CSharp.OutputVisitor;
using ICSharpCode.Decompiler.CSharp.Syntax;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using Mono.Cecil;
namespace ICSharpCode.Decompiler
{
@ -63,18 +63,18 @@ namespace ICSharpCode.Decompiler @@ -63,18 +63,18 @@ namespace ICSharpCode.Decompiler
var definition = GetCurrentDefinition();
if (definition != null) {
MemberReference cecil = SymbolToCecil(definition);
if (cecil != null) {
output.WriteDefinition(identifier.Name, cecil, false);
IMetadataEntity entity = SymbolToMetadata(definition);
if (entity != null) {
output.WriteDefinition(identifier.Name, entity, false);
return;
}
}
var member = GetCurrentMemberReference();
if (member != null) {
MemberReference cecil = SymbolToCecil(member);
if (cecil != null) {
output.WriteReference(identifier.Name, cecil);
IMetadataEntity entity = SymbolToMetadata(member);
if (entity != null) {
output.WriteReference(identifier.Name, entity);
return;
}
}
@ -99,13 +99,23 @@ namespace ICSharpCode.Decompiler @@ -99,13 +99,23 @@ namespace ICSharpCode.Decompiler
output.Write(identifier.Name);
}
MemberReference SymbolToCecil(ISymbol symbol)
IMetadataEntity SymbolToMetadata(ISymbol symbol)
{
if (symbol is IType type) {
return typeSystem.GetCecil(type.GetDefinition());
} else if (symbol is IMember member) {
return typeSystem.GetCecil(member);
} else {
switch (symbol) {
case IType type:
var definition = type.GetDefinition();
if (definition == null)
return null;
return new TypeDefinition(typeSystem.ModuleDefinition, (System.Reflection.Metadata.TypeDefinitionHandle)definition.MetadataToken);
case IMethod method:
return new MethodDefinition(typeSystem.ModuleDefinition, (System.Reflection.Metadata.MethodDefinitionHandle)method.MetadataToken);
case IProperty property:
return new PropertyDefinition(typeSystem.ModuleDefinition, (System.Reflection.Metadata.PropertyDefinitionHandle)property.MetadataToken);
case IEvent @event:
return new EventDefinition(typeSystem.ModuleDefinition, (System.Reflection.Metadata.EventDefinitionHandle)@event.MetadataToken);
case IField field:
return new FieldDefinition(typeSystem.ModuleDefinition, (System.Reflection.Metadata.FieldDefinitionHandle)field.MetadataToken);
default:
return null;
}
}
@ -200,9 +210,9 @@ namespace ICSharpCode.Decompiler @@ -200,9 +210,9 @@ namespace ICSharpCode.Decompiler
//To make reference for 'this' and 'base' keywords in the ClassName():this() expression
if (role == ConstructorInitializer.ThisKeywordRole || role == ConstructorInitializer.BaseKeywordRole) {
if (nodeStack.Peek() is ConstructorInitializer initializer && initializer.GetSymbol() is IMember member) {
var cecil = typeSystem.GetCecil(member);
if (cecil != null) {
output.WriteReference(keyword, cecil);
var entity = SymbolToMetadata(member);
if (entity != null) {
output.WriteReference(keyword, entity);
return;
}
}
@ -235,7 +245,7 @@ namespace ICSharpCode.Decompiler @@ -235,7 +245,7 @@ namespace ICSharpCode.Decompiler
break;
default:
// Attach member reference to token only if there's no identifier in the current node.
var member = SymbolToCecil(GetCurrentMemberReference());
var member = SymbolToMetadata(GetCurrentMemberReference());
var node = nodeStack.Peek();
if (member != null && node.GetChildByRole(Roles.Identifier).IsNull)
output.WriteReference(token, member);
@ -349,7 +359,7 @@ namespace ICSharpCode.Decompiler @@ -349,7 +359,7 @@ namespace ICSharpCode.Decompiler
symbol = nodeStack.Peek().GetSymbol();
}
if (symbol == null) goto default;
output.WriteReference(type, SymbolToCecil(symbol));
output.WriteReference(type, SymbolToMetadata(symbol));
break;
default:
output.Write(type);

Loading…
Cancel
Save