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 @@
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Reflection.Metadata;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
using Mono.Cecil;
namespace ICSharpCode.Decompiler.IL.Transforms namespace ICSharpCode.Decompiler.IL.Transforms
{ {
@ -12,15 +12,22 @@ namespace ICSharpCode.Decompiler.IL.Transforms
public void Run(ILFunction function, ILTransformContext context) public void Run(ILFunction function, ILTransformContext context)
{ {
this.context = context; this.context = context;
var module = context.TypeSystem.ModuleDefinition;
var metadata = context.TypeSystem.GetMetadata();
foreach (var inst in function.Descendants.OfType<CallInstruction>()) { foreach (var inst in function.Descendants.OfType<CallInstruction>()) {
MethodDefinition methodDef = context.TypeSystem.GetCecil(inst.Method) as MethodDefinition; var handle = (MethodDefinitionHandle)inst.Method.MetadataToken;
if (methodDef != null && methodDef.Body != null) { if (handle.IsNil
if (inst.Method.IsCompilerGeneratedOrIsInCompilerGeneratedClass()) { || !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 // partially copied from CSharpDecompiler
var specializingTypeSystem = this.context.TypeSystem.GetSpecializingTypeSystem(inst.Method.Substitution); var specializingTypeSystem = this.context.TypeSystem.GetSpecializingTypeSystem(inst.Method.Substitution);
var ilReader = new ILReader(specializingTypeSystem); var ilReader = new ILReader(specializingTypeSystem);
System.Threading.CancellationToken cancellationToken = new System.Threading.CancellationToken(); 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) { var transformContext = new ILTransformContext(proxyFunction, specializingTypeSystem, this.context.Settings) {
CancellationToken = cancellationToken, CancellationToken = cancellationToken,
DecompileRun = context.DecompileRun DecompileRun = context.DecompileRun
@ -74,7 +81,15 @@ namespace ICSharpCode.Decompiler.IL.Transforms
inst.ReplaceWith(newInst); 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;
using ICSharpCode.Decompiler.CSharp.OutputVisitor; using ICSharpCode.Decompiler.CSharp.OutputVisitor;
using ICSharpCode.Decompiler.CSharp.Syntax; using ICSharpCode.Decompiler.CSharp.Syntax;
using ICSharpCode.Decompiler.IL; using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
using Mono.Cecil;
namespace ICSharpCode.Decompiler namespace ICSharpCode.Decompiler
{ {
@ -63,18 +63,18 @@ namespace ICSharpCode.Decompiler
var definition = GetCurrentDefinition(); var definition = GetCurrentDefinition();
if (definition != null) { if (definition != null) {
MemberReference cecil = SymbolToCecil(definition); IMetadataEntity entity = SymbolToMetadata(definition);
if (cecil != null) { if (entity != null) {
output.WriteDefinition(identifier.Name, cecil, false); output.WriteDefinition(identifier.Name, entity, false);
return; return;
} }
} }
var member = GetCurrentMemberReference(); var member = GetCurrentMemberReference();
if (member != null) { if (member != null) {
MemberReference cecil = SymbolToCecil(member); IMetadataEntity entity = SymbolToMetadata(member);
if (cecil != null) { if (entity != null) {
output.WriteReference(identifier.Name, cecil); output.WriteReference(identifier.Name, entity);
return; return;
} }
} }
@ -99,13 +99,23 @@ namespace ICSharpCode.Decompiler
output.Write(identifier.Name); output.Write(identifier.Name);
} }
MemberReference SymbolToCecil(ISymbol symbol) IMetadataEntity SymbolToMetadata(ISymbol symbol)
{ {
if (symbol is IType type) { switch (symbol) {
return typeSystem.GetCecil(type.GetDefinition()); case IType type:
} else if (symbol is IMember member) { var definition = type.GetDefinition();
return typeSystem.GetCecil(member); if (definition == null)
} else { 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; return null;
} }
} }
@ -200,9 +210,9 @@ namespace ICSharpCode.Decompiler
//To make reference for 'this' and 'base' keywords in the ClassName():this() expression //To make reference for 'this' and 'base' keywords in the ClassName():this() expression
if (role == ConstructorInitializer.ThisKeywordRole || role == ConstructorInitializer.BaseKeywordRole) { if (role == ConstructorInitializer.ThisKeywordRole || role == ConstructorInitializer.BaseKeywordRole) {
if (nodeStack.Peek() is ConstructorInitializer initializer && initializer.GetSymbol() is IMember member) { if (nodeStack.Peek() is ConstructorInitializer initializer && initializer.GetSymbol() is IMember member) {
var cecil = typeSystem.GetCecil(member); var entity = SymbolToMetadata(member);
if (cecil != null) { if (entity != null) {
output.WriteReference(keyword, cecil); output.WriteReference(keyword, entity);
return; return;
} }
} }
@ -235,7 +245,7 @@ namespace ICSharpCode.Decompiler
break; break;
default: default:
// Attach member reference to token only if there's no identifier in the current node. // 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(); var node = nodeStack.Peek();
if (member != null && node.GetChildByRole(Roles.Identifier).IsNull) if (member != null && node.GetChildByRole(Roles.Identifier).IsNull)
output.WriteReference(token, member); output.WriteReference(token, member);
@ -349,7 +359,7 @@ namespace ICSharpCode.Decompiler
symbol = nodeStack.Peek().GetSymbol(); symbol = nodeStack.Peek().GetSymbol();
} }
if (symbol == null) goto default; if (symbol == null) goto default;
output.WriteReference(type, SymbolToCecil(symbol)); output.WriteReference(type, SymbolToMetadata(symbol));
break; break;
default: default:
output.Write(type); output.Write(type);

Loading…
Cancel
Save