Browse Source

Refactoring of ILFunction: allow Method and CecilMethod to be null for expression trees.

pull/988/head
Siegfried Pammer 8 years ago
parent
commit
29a2d3ec34
  1. 14
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  2. 12
      ICSharpCode.Decompiler/CSharp/StatementBuilder.cs
  3. 16
      ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs
  4. 2
      ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs

14
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -1350,15 +1350,15 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1350,15 +1350,15 @@ namespace ICSharpCode.Decompiler.CSharp
internal ExpressionWithResolveResult TranslateFunction(IType delegateType, ILFunction function)
{
var method = function.Method.MemberDefinition as IMethod;
Debug.Assert(method != null);
var method = function.Method?.MemberDefinition as IMethod;
// Create AnonymousMethodExpression and prepare parameters
AnonymousMethodExpression ame = new AnonymousMethodExpression();
ame.IsAsync = function.IsAsync;
ame.Parameters.AddRange(MakeParameters(method, function));
ame.Parameters.AddRange(MakeParameters(function.Parameters, function));
ame.HasParameterList = ame.Parameters.Count > 0;
StatementBuilder builder = new StatementBuilder(typeSystem.GetSpecializingTypeSystem(new SimpleTypeResolveContext(method)), this.decompilationContext, method, function, settings, cancellationToken);
var context = method == null ? decompilationContext : new SimpleTypeResolveContext(method);
StatementBuilder builder = new StatementBuilder(typeSystem.GetSpecializingTypeSystem(context), this.decompilationContext, function, settings, cancellationToken);
var body = builder.ConvertAsBlock(function.Body);
Comment prev = null;
@ -1459,17 +1459,17 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1459,17 +1459,17 @@ namespace ICSharpCode.Decompiler.CSharp
return SpecialType.UnknownType;
}
IEnumerable<ParameterDeclaration> MakeParameters(IMethod method, ILFunction function)
IEnumerable<ParameterDeclaration> MakeParameters(IList<IParameter> parameters, ILFunction function)
{
var variables = function.Variables.Where(v => v.Kind == VariableKind.Parameter).ToDictionary(v => v.Index);
int i = 0;
foreach (var parameter in method.Parameters) {
foreach (var parameter in parameters) {
var pd = astBuilder.ConvertParameter(parameter);
if (settings.AnonymousTypes && parameter.Type.ContainsAnonymousType())
pd.Type = null;
ILVariable v;
if (variables.TryGetValue(i, out v))
pd.AddAnnotation(new ILVariableResolveResult(v, method.Parameters[i].Type));
pd.AddAnnotation(new ILVariableResolveResult(v, parameters[i].Type));
yield return pd;
i++;
}

12
ICSharpCode.Decompiler/CSharp/StatementBuilder.cs

@ -35,16 +35,16 @@ namespace ICSharpCode.Decompiler.CSharp @@ -35,16 +35,16 @@ namespace ICSharpCode.Decompiler.CSharp
{
internal readonly ExpressionBuilder exprBuilder;
readonly ILFunction currentFunction;
readonly IMethod currentMethod;
readonly IDecompilerTypeSystem typeSystem;
readonly DecompilerSettings settings;
readonly CancellationToken cancellationToken;
public StatementBuilder(IDecompilerTypeSystem typeSystem, ITypeResolveContext decompilationContext, IMethod currentMethod, ILFunction currentFunction, DecompilerSettings settings, CancellationToken cancellationToken)
public StatementBuilder(IDecompilerTypeSystem typeSystem, ITypeResolveContext decompilationContext, ILFunction currentFunction, DecompilerSettings settings, CancellationToken cancellationToken)
{
Debug.Assert(typeSystem != null && decompilationContext != null && currentMethod != null);
Debug.Assert(typeSystem != null && decompilationContext != null);
this.exprBuilder = new ExpressionBuilder(typeSystem, decompilationContext, settings, cancellationToken);
this.currentFunction = currentFunction;
this.currentMethod = currentMethod;
this.typeSystem = typeSystem;
this.settings = settings;
this.cancellationToken = cancellationToken;
}
@ -263,7 +263,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -263,7 +263,7 @@ namespace ICSharpCode.Decompiler.CSharp
if (currentFunction.IsIterator)
return new YieldBreakStatement();
else if (!inst.Value.MatchNop()) {
IType targetType = currentFunction.IsAsync ? currentFunction.AsyncReturnType : currentMethod.ReturnType;
IType targetType = currentFunction.IsAsync ? currentFunction.AsyncReturnType : currentFunction.ReturnType;
return new ReturnStatement(exprBuilder.Translate(inst.Value).ConvertTo(targetType, exprBuilder, allowImplicitConversion: true));
} else
return new ReturnStatement();
@ -288,7 +288,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -288,7 +288,7 @@ namespace ICSharpCode.Decompiler.CSharp
protected internal override Statement VisitYieldReturn(YieldReturn inst)
{
var elementType = currentMethod.ReturnType.GetElementTypeFromIEnumerable(currentMethod.Compilation, true, out var isGeneric);
var elementType = currentFunction.ReturnType.GetElementTypeFromIEnumerable(typeSystem.Compilation, true, out var isGeneric);
return new YieldReturnStatement {
Expression = exprBuilder.Translate(inst.Value).ConvertTo(elementType, exprBuilder)
};

16
ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs

@ -61,11 +61,27 @@ namespace ICSharpCode.Decompiler.IL @@ -61,11 +61,27 @@ namespace ICSharpCode.Decompiler.IL
/// </summary>
public IType AsyncReturnType;
public bool IsExpressionTree;
public readonly IType ReturnType;
public readonly IList<IParameter> Parameters;
public ILFunction(IMethod method, MethodDefinition cecilMethod, ILInstruction body) : base(OpCode.ILFunction)
{
this.Body = body;
this.Method = method;
this.CecilMethod = cecilMethod;
this.ReturnType = Method.ReturnType;
this.Parameters = Method.Parameters;
this.Variables = new ILVariableCollection(this);
}
public ILFunction(IType returnType, IList<IParameter> parameters, ILInstruction body) : base(OpCode.ILFunction)
{
this.Body = body;
this.ReturnType = returnType;
this.Parameters = parameters;
this.Variables = new ILVariableCollection(this);
}

2
ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs

@ -61,7 +61,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -61,7 +61,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
currentFieldNames = function.CecilMethod.DeclaringType.Fields.Select(f => f.Name).ToArray();
reservedVariableNames = new Dictionary<string, int>();
loopCounters = CollectLoopCounters(function);
foreach (var p in function.Descendants.OfType<ILFunction>().Select(f => f.Method).SelectMany(m => m.Parameters))
foreach (var p in function.Descendants.OfType<ILFunction>().SelectMany(f => f.Variables).Where(v => v.Kind == VariableKind.Parameter))
AddExistingName(reservedVariableNames, p.Name);
foreach (ILFunction f in function.Descendants.OfType<ILFunction>().Reverse()) {
PerformAssignment(f);

Loading…
Cancel
Save