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
internal ExpressionWithResolveResult TranslateFunction(IType delegateType, ILFunction function) internal ExpressionWithResolveResult TranslateFunction(IType delegateType, ILFunction function)
{ {
var method = function.Method.MemberDefinition as IMethod; var method = function.Method?.MemberDefinition as IMethod;
Debug.Assert(method != null);
// Create AnonymousMethodExpression and prepare parameters // Create AnonymousMethodExpression and prepare parameters
AnonymousMethodExpression ame = new AnonymousMethodExpression(); AnonymousMethodExpression ame = new AnonymousMethodExpression();
ame.IsAsync = function.IsAsync; ame.IsAsync = function.IsAsync;
ame.Parameters.AddRange(MakeParameters(method, function)); ame.Parameters.AddRange(MakeParameters(function.Parameters, function));
ame.HasParameterList = ame.Parameters.Count > 0; 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); var body = builder.ConvertAsBlock(function.Body);
Comment prev = null; Comment prev = null;
@ -1459,17 +1459,17 @@ namespace ICSharpCode.Decompiler.CSharp
return SpecialType.UnknownType; 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); var variables = function.Variables.Where(v => v.Kind == VariableKind.Parameter).ToDictionary(v => v.Index);
int i = 0; int i = 0;
foreach (var parameter in method.Parameters) { foreach (var parameter in parameters) {
var pd = astBuilder.ConvertParameter(parameter); var pd = astBuilder.ConvertParameter(parameter);
if (settings.AnonymousTypes && parameter.Type.ContainsAnonymousType()) if (settings.AnonymousTypes && parameter.Type.ContainsAnonymousType())
pd.Type = null; pd.Type = null;
ILVariable v; ILVariable v;
if (variables.TryGetValue(i, out 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; yield return pd;
i++; i++;
} }

12
ICSharpCode.Decompiler/CSharp/StatementBuilder.cs

@ -35,16 +35,16 @@ namespace ICSharpCode.Decompiler.CSharp
{ {
internal readonly ExpressionBuilder exprBuilder; internal readonly ExpressionBuilder exprBuilder;
readonly ILFunction currentFunction; readonly ILFunction currentFunction;
readonly IMethod currentMethod; readonly IDecompilerTypeSystem typeSystem;
readonly DecompilerSettings settings; readonly DecompilerSettings settings;
readonly CancellationToken cancellationToken; 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.exprBuilder = new ExpressionBuilder(typeSystem, decompilationContext, settings, cancellationToken);
this.currentFunction = currentFunction; this.currentFunction = currentFunction;
this.currentMethod = currentMethod; this.typeSystem = typeSystem;
this.settings = settings; this.settings = settings;
this.cancellationToken = cancellationToken; this.cancellationToken = cancellationToken;
} }
@ -263,7 +263,7 @@ namespace ICSharpCode.Decompiler.CSharp
if (currentFunction.IsIterator) if (currentFunction.IsIterator)
return new YieldBreakStatement(); return new YieldBreakStatement();
else if (!inst.Value.MatchNop()) { 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)); return new ReturnStatement(exprBuilder.Translate(inst.Value).ConvertTo(targetType, exprBuilder, allowImplicitConversion: true));
} else } else
return new ReturnStatement(); return new ReturnStatement();
@ -288,7 +288,7 @@ namespace ICSharpCode.Decompiler.CSharp
protected internal override Statement VisitYieldReturn(YieldReturn inst) 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 { return new YieldReturnStatement {
Expression = exprBuilder.Translate(inst.Value).ConvertTo(elementType, exprBuilder) Expression = exprBuilder.Translate(inst.Value).ConvertTo(elementType, exprBuilder)
}; };

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

@ -61,11 +61,27 @@ namespace ICSharpCode.Decompiler.IL
/// </summary> /// </summary>
public IType AsyncReturnType; 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) public ILFunction(IMethod method, MethodDefinition cecilMethod, ILInstruction body) : base(OpCode.ILFunction)
{ {
this.Body = body; this.Body = body;
this.Method = method; this.Method = method;
this.CecilMethod = cecilMethod; 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); this.Variables = new ILVariableCollection(this);
} }

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

@ -61,7 +61,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
currentFieldNames = function.CecilMethod.DeclaringType.Fields.Select(f => f.Name).ToArray(); currentFieldNames = function.CecilMethod.DeclaringType.Fields.Select(f => f.Name).ToArray();
reservedVariableNames = new Dictionary<string, int>(); reservedVariableNames = new Dictionary<string, int>();
loopCounters = CollectLoopCounters(function); 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); AddExistingName(reservedVariableNames, p.Name);
foreach (ILFunction f in function.Descendants.OfType<ILFunction>().Reverse()) { foreach (ILFunction f in function.Descendants.OfType<ILFunction>().Reverse()) {
PerformAssignment(f); PerformAssignment(f);

Loading…
Cancel
Save