Browse Source

Remove redundant lambda casts.

pull/892/merge
Daniel Grunwald 8 years ago
parent
commit
236c7c28b4
  1. 2
      ICSharpCode.Decompiler.Tests/DataFlowTest.cs
  2. 6
      ICSharpCode.Decompiler.Tests/TestCases/Correctness/Async.cs
  3. 5
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/CheckedUnchecked.cs
  4. 26
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/DelegateConstruction.cs
  5. 8
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/FixProxyCalls.cs
  6. 2
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.cs
  7. 2
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/PropertiesAndEvents.cs
  8. 2
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.cs
  9. 15
      ICSharpCode.Decompiler/CSharp/CallBuilder.cs
  10. 95
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  11. 77
      ICSharpCode.Decompiler/CSharp/Resolver/LambdaResolveResult.cs
  12. 8
      ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs
  13. 2
      ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs
  14. 2
      ICSharpCode.Decompiler/IL/ControlFlow/YieldReturnDecompiler.cs
  15. 3
      ICSharpCode.Decompiler/IL/ILReader.cs
  16. 8
      ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs
  17. 6
      ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs
  18. 4
      ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs

2
ICSharpCode.Decompiler.Tests/DataFlowTest.cs

@ -55,7 +55,7 @@ namespace ICSharpCode.Decompiler.Tests @@ -55,7 +55,7 @@ namespace ICSharpCode.Decompiler.Tests
public void TryFinallyWithAssignmentInFinally()
{
ILVariable v = new ILVariable(VariableKind.Local, SpecialType.UnknownType, 0);
ILFunction f = new ILFunction(null, new TryFinally(
ILFunction f = new ILFunction(null, null, new TryFinally(
new Nop(),
new StLoc(v, new LdcI4(0))
));

6
ICSharpCode.Decompiler.Tests/TestCases/Correctness/Async.cs

@ -30,15 +30,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness @@ -30,15 +30,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
{
public static void Main()
{
new Async().Run();
new Async().Run().Wait();
}
public async void Run()
public async Task Run()
{
await SimpleBoolTaskMethod();
StreamCopyTo(new MemoryStream(new byte[1024]), 16);
StreamCopyToWithConfigureAwait(new MemoryStream(new byte[1024]), 16);
await AwaitInForEach(Enumerable.Range(0, 100).Select(i => Task<int>.FromResult(i)));
await AwaitInForEach(Enumerable.Range(0, 100).Select(i => Task.FromResult(i)));
await TaskMethodWithoutAwaitButWithExceptionHandling();
#if !LEGACY_CSC
await AwaitCatch(Task.FromResult(1));

5
ICSharpCode.Decompiler.Tests/TestCases/Pretty/CheckedUnchecked.cs

@ -83,16 +83,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -83,16 +83,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
});
}
public void ArrayInitializerChecked()
{
this.TestHelp(new int[2] {
1,
2
}, (Func<int[], int[]>)((int[] n) => checked(new int[2] {
}, (int[] n) => checked(new int[2] {
n[0] + 1,
n[1] + 1
})));
}));
}
public T TestHelp<T>(T t, Func<T, T> f)

26
ICSharpCode.Decompiler.Tests/TestCases/Pretty/DelegateConstruction.cs

@ -26,14 +26,14 @@ public static class DelegateConstruction @@ -26,14 +26,14 @@ public static class DelegateConstruction
{
public Action CaptureOfThis()
{
return (Action)delegate {
return delegate {
this.CaptureOfThis();
};
}
public Action CaptureOfThisAndParameter(int a)
{
return (Action)delegate {
return delegate {
this.CaptureOfThisAndParameter(a);
};
}
@ -42,7 +42,7 @@ public static class DelegateConstruction @@ -42,7 +42,7 @@ public static class DelegateConstruction
{
foreach (int item in Enumerable.Empty<int>()) {
if (item > 0) {
return (Action)delegate {
return delegate {
this.CaptureOfThisAndParameter(item + a);
};
}
@ -55,7 +55,7 @@ public static class DelegateConstruction @@ -55,7 +55,7 @@ public static class DelegateConstruction
foreach (int item in Enumerable.Empty<int>()) {
int copyOfItem = item;
if (item > 0) {
return (Action)delegate {
return delegate {
this.CaptureOfThisAndParameter(item + a + copyOfItem);
};
}
@ -66,7 +66,7 @@ public static class DelegateConstruction @@ -66,7 +66,7 @@ public static class DelegateConstruction
public void LambdaInForLoop()
{
for (int i = 0; i < 100000; i++) {
this.Bar((Func<int>)(() => this.Foo()));
this.Bar(() => this.Foo());
}
}
@ -119,7 +119,7 @@ public static class DelegateConstruction @@ -119,7 +119,7 @@ public static class DelegateConstruction
List<Action<int>> list = new List<Action<int>>();
for (int i = 0; i < 10; i++) {
int counter;
list.Add((Action<int>)delegate(int x) {
list.Add(delegate(int x) {
counter = x;
});
}
@ -131,7 +131,7 @@ public static class DelegateConstruction @@ -131,7 +131,7 @@ public static class DelegateConstruction
List<Action<int>> list = new List<Action<int>>();
int counter;
for (int i = 0; i < 10; i++) {
list.Add((Action<int>)delegate(int x) {
list.Add(delegate(int x) {
counter = x;
});
}
@ -140,7 +140,7 @@ public static class DelegateConstruction @@ -140,7 +140,7 @@ public static class DelegateConstruction
public static Action StaticAnonymousMethodNoClosure()
{
return (Action)delegate {
return delegate {
Console.WriteLine();
};
}
@ -156,7 +156,7 @@ public static class DelegateConstruction @@ -156,7 +156,7 @@ public static class DelegateConstruction
for (int k = 0; k < 10; k++) {
int i;
for (i = 0; i < 10; i++) {
list.Add((Action<int>)delegate(int j) {
list.Add(delegate(int j) {
for (int l = 0; l < i; l += j) {
Console.WriteLine();
}
@ -169,7 +169,7 @@ public static class DelegateConstruction @@ -169,7 +169,7 @@ public static class DelegateConstruction
{
List<Action<int>> list = new List<Action<int>>();
for (int k = 0; k < 10; k++) {
list.Add((Action<int>)delegate(int i) {
list.Add(delegate(int i) {
Console.WriteLine(i);
});
}
@ -177,7 +177,7 @@ public static class DelegateConstruction @@ -177,7 +177,7 @@ public static class DelegateConstruction
public static Action<int> NameConflict3(int i)
{
return (Action<int>)delegate(int j) {
return delegate(int j) {
for (int k = 0; k < j; k++) {
Console.WriteLine(k);
}
@ -186,11 +186,11 @@ public static class DelegateConstruction @@ -186,11 +186,11 @@ public static class DelegateConstruction
public static Func<int, Func<int, int>> CurriedAddition(int a)
{
return (Func<int, Func<int, int>>)((int b) => (Func<int, int>)((int c) => a + b + c));
return (int b) => (int c) => a + b + c;
}
public static Func<int, Func<int, Func<int, int>>> CurriedAddition2(int a)
{
return (Func<int, Func<int, Func<int, int>>>)((int b) => (Func<int, Func<int, int>>)((int c) => (Func<int, int>)((int d) => a + b + c + d)));
return (int b) => (int c) => (int d) => a + b + c + d;
}
}

8
ICSharpCode.Decompiler.Tests/TestCases/Pretty/FixProxyCalls.cs

@ -8,7 +8,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty @@ -8,7 +8,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty
{
protected internal virtual Task<string> Test(string test)
{
return Task.Run((Func<string>)(() => test.ToUpper()));
return Task.Run(() => test.ToUpper());
}
}
@ -48,7 +48,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty @@ -48,7 +48,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty
{
protected internal override string Test(string test)
{
Func<string, string> func = (Func<string, string>)((string a) => base.Test(a));
Func<string, string> func = (string a) => base.Test(a);
test = string.Join(test, "aa");
return func(test);
}
@ -66,7 +66,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty @@ -66,7 +66,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty
{
protected internal override void Test(string test)
{
Action<string> action = (Action<string>)delegate(string a) {
Action<string> action = delegate(string a) {
base.Test(a);
};
if (test.Equals(1)) {
@ -88,7 +88,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty @@ -88,7 +88,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty
{
protected internal override void Test(int a)
{
Action action = (Action)delegate {
Action action = delegate {
base.Test(a);
};
if (a.Equals(1)) {

2
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.cs

@ -388,7 +388,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -388,7 +388,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
foreach (int item in items) {
int c = item;
Loops.Operation((Func<bool>)(() => c == 5));
Loops.Operation(() => c == 5);
}
}

2
ICSharpCode.Decompiler.Tests/TestCases/Pretty/PropertiesAndEvents.cs

@ -40,7 +40,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -40,7 +40,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
public event EventHandler AutomaticEvent;
[field: NonSerialized]
public event EventHandler AutomaticEventWithInitializer = (EventHandler)delegate(object sender, EventArgs e) {
public event EventHandler AutomaticEventWithInitializer = delegate(object sender, EventArgs e) {
};
public event EventHandler CustomEvent {

2
ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.cs

@ -111,7 +111,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -111,7 +111,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
public object FromLetWhereSelect()
{
return from o in this.orders
let t = o.Details.Sum((Func<OrderDetail, decimal>)((OrderDetail d) => d.UnitPrice * d.Quantity))
let t = o.Details.Sum((OrderDetail d) => d.UnitPrice * d.Quantity)
where t >= 1000m
select new {
OrderID = o.OrderID,

15
ICSharpCode.Decompiler/CSharp/CallBuilder.cs

@ -140,7 +140,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -140,7 +140,7 @@ namespace ICSharpCode.Decompiler.CSharp
atce.Initializers.Add(
new NamedExpression {
Name = expectedParameters[i].Name,
Expression = argumentExpressions[i]
Expression = arguments[i].ConvertTo(expectedParameters[i].Type, expressionBuilder)
});
}
}
@ -321,9 +321,11 @@ namespace ICSharpCode.Decompiler.CSharp @@ -321,9 +321,11 @@ namespace ICSharpCode.Decompiler.CSharp
case OpCode.LdVirtFtn:
method = ((LdVirtFtn)func).Method;
break;
case OpCode.ILFunction:
method = ((ILFunction)func).Method;
return expressionBuilder.TranslateFunction(inst.Method.DeclaringType, (ILFunction)func);
default:
method = typeSystem.Resolve(((ILFunction)func).Method);
break;
throw new ArgumentException($"Unknown instruction type: {func.OpCode}");
}
var invokeMethod = inst.Method.DeclaringType.GetDelegateInvokeMethod();
TranslatedExpression target;
@ -355,12 +357,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -355,12 +357,7 @@ namespace ICSharpCode.Decompiler.CSharp
inst.Method.DeclaringType,
new MemberResolveResult(target.ResolveResult, method),
Conversion.MethodGroupConversion(method, func.OpCode == OpCode.LdVirtFtn, false)));
if (func is ILFunction) {
return expressionBuilder.TranslateFunction(oce, target, (ILFunction)func);
} else {
return oce;
}
return oce;
}
}
}

95
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -310,12 +310,12 @@ namespace ICSharpCode.Decompiler.CSharp @@ -310,12 +310,12 @@ namespace ICSharpCode.Decompiler.CSharp
.WithILInstruction(inst)
.WithRR(new ConstantResolveResult(compilation.FindType(KnownTypeCode.String), inst.Value));
}
protected internal override TranslatedExpression VisitLdNull(LdNull inst, TranslationContext context)
{
return GetDefaultValueExpression(SpecialType.NullType).WithILInstruction(inst);
}
protected internal override TranslatedExpression VisitDefaultValue(DefaultValue inst, TranslationContext context)
{
return GetDefaultValueExpression(inst.Type).WithILInstruction(inst);
@ -1024,9 +1024,9 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1024,9 +1024,9 @@ namespace ICSharpCode.Decompiler.CSharp
return new CallBuilder(this, typeSystem, settings).Build(inst);
}
internal TranslatedExpression TranslateFunction(TranslatedExpression objectCreateExpression, TranslatedExpression target, ILFunction function)
internal TranslatedExpression TranslateFunction(IType delegateType, ILFunction function)
{
var method = typeSystem.Resolve(function.Method)?.MemberDefinition as IMethod;
var method = function.Method.MemberDefinition as IMethod;
Debug.Assert(method != null);
// Create AnonymousMethodExpression and prepare parameters
@ -1036,19 +1036,18 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1036,19 +1036,18 @@ namespace ICSharpCode.Decompiler.CSharp
ame.HasParameterList = ame.Parameters.Count > 0;
StatementBuilder builder = new StatementBuilder(typeSystem.GetSpecializingTypeSystem(new SimpleTypeResolveContext(method)), this.decompilationContext, method, function, settings, cancellationToken);
var body = builder.ConvertAsBlock(function.Body);
bool isLambda = false;
bool isMultiLineLambda = false;
Comment prev = null;
foreach (string warning in function.Warnings) {
body.InsertChildAfter(prev, prev = new Comment(warning), Roles.Comment);
}
// if there is an anonymous type involved, we are forced to use a lambda expression.
bool isLambda = false;
if (ame.Parameters.Any(p => p.Type.IsNull)) {
// if there is an anonymous type involved, we are forced to use a lambda expression.
isLambda = true;
isMultiLineLambda = body.Statements.Count > 1;
} else if (ame.Parameters.All(p => p.ParameterModifier == ParameterModifier.None)) {
// otherwise use lambda only if an expression lambda is possible
isLambda = (body.Statements.Count == 1 && body.Statements.Single() is ReturnStatement);
}
// Remove the parameter list from an AnonymousMethodExpression if the original method had no names,
@ -1064,39 +1063,81 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1064,39 +1063,81 @@ namespace ICSharpCode.Decompiler.CSharp
ame.HasParameterList = false;
}
}
Expression replacement;
IType inferredReturnType;
if (isLambda) {
LambdaExpression lambda = new LambdaExpression();
lambda.IsAsync = ame.IsAsync;
lambda.CopyAnnotationsFrom(ame);
ame.Parameters.MoveTo(lambda.Parameters);
if (isMultiLineLambda) {
lambda.Body = body;
if (body.Statements.Count == 1 && body.Statements.Single() is ReturnStatement returnStmt) {
lambda.Body = returnStmt.Expression.Detach();
inferredReturnType = lambda.Body.GetResolveResult().Type;
} else {
Expression returnExpr = ((ReturnStatement)body.Statements.Single()).Expression;
returnExpr.Remove();
lambda.Body = returnExpr;
lambda.Body = body;
inferredReturnType = InferReturnType(body);
}
replacement = lambda;
} else {
ame.Body = body;
inferredReturnType = InferReturnType(body);
replacement = ame;
}
var expectedType = objectCreateExpression.ResolveResult.Type;
var expectedTypeDefinition = expectedType.GetDefinition();
if (expectedTypeDefinition != null && expectedTypeDefinition.Kind != TypeKind.Delegate) {
var simplifiedDelegateCreation = (ObjectCreateExpression)objectCreateExpression.Expression.Clone();
simplifiedDelegateCreation.Arguments.Clear();
simplifiedDelegateCreation.Arguments.Add(replacement);
replacement = simplifiedDelegateCreation;
} else if (!settings.AnonymousTypes || !expectedType.ContainsAnonymousType()) {
replacement = new CastExpression(ConvertType(expectedType), replacement);
if (ame.IsAsync) {
inferredReturnType = GetTaskType(inferredReturnType);
}
return replacement
.WithILInstruction(function)
.WithRR(objectCreateExpression.ResolveResult);
var rr = new DecompiledLambdaResolveResult(
function, delegateType, inferredReturnType,
hasParameterList: ame.HasParameterList,
isAnonymousMethod: !isLambda,
isImplicitlyTyped: ame.Parameters.Any(p => p.Type.IsNull));
TranslatedExpression translatedLambda = replacement.WithILInstruction(function).WithRR(rr);
return new CastExpression(ConvertType(delegateType), translatedLambda)
.WithoutILInstruction().WithRR(new ConversionResolveResult(delegateType, rr, LambdaConversion.Instance));
}
IType InferReturnType(BlockStatement body)
{
var returnExpressions = new List<ResolveResult>();
CollectReturnExpressions(body);
var ti = new TypeInference(compilation, resolver.conversions);
return ti.GetBestCommonType(returnExpressions, out _);
// Failure to infer a return type does not make the lambda invalid,
// so we can ignore the 'success' value
void CollectReturnExpressions(AstNode node)
{
if (node is ReturnStatement ret) {
if (!ret.Expression.IsNull) {
returnExpressions.Add(ret.Expression.GetResolveResult());
}
} else if (node is LambdaExpression || node is AnonymousMethodExpression) {
// do not recurse into nested lambdas
return;
}
foreach (var child in node.Children) {
CollectReturnExpressions(child);
}
}
}
IType GetTaskType(IType resultType)
{
if (resultType.Kind == TypeKind.Unknown)
return SpecialType.UnknownType;
if (resultType.Kind == TypeKind.Void)
return compilation.FindType(KnownTypeCode.Task);
ITypeDefinition def = compilation.FindType(KnownTypeCode.TaskOfT).GetDefinition();
if (def != null)
return new ParameterizedType(def, new[] { resultType });
else
return SpecialType.UnknownType;
}
IEnumerable<ParameterDeclaration> MakeParameters(IMethod method, ILFunction function)
{
var variables = function.Variables.Where(v => v.Kind == VariableKind.Parameter).ToDictionary(v => v.Index);

77
ICSharpCode.Decompiler/CSharp/Resolver/LambdaResolveResult.cs

@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using ICSharpCode.Decompiler.Semantics;
using ICSharpCode.Decompiler.TypeSystem;
@ -97,4 +98,80 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver @@ -97,4 +98,80 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
return new [] { this.Body };
}
}
sealed class DecompiledLambdaResolveResult : LambdaResolveResult
{
readonly IL.ILFunction function;
public readonly IType DelegateType;
/// <summary>
/// The inferred return type.
/// Can differ from <c>ReturnType</c> if a return statement
/// performs an implicit conversion.
/// </summary>
public readonly IType InferredReturnType;
public DecompiledLambdaResolveResult(IL.ILFunction function,
IType delegateType,
IType inferredReturnType,
bool hasParameterList,
bool isAnonymousMethod,
bool isImplicitlyTyped)
{
this.function = function ?? throw new ArgumentNullException(nameof(function));
this.DelegateType = delegateType ?? throw new ArgumentNullException(nameof(delegateType));
this.InferredReturnType = inferredReturnType ?? throw new ArgumentNullException(nameof(inferredReturnType));
this.HasParameterList = hasParameterList;
this.IsAnonymousMethod = isAnonymousMethod;
this.IsImplicitlyTyped = isImplicitlyTyped;
this.Body = new ResolveResult(SpecialType.UnknownType);
}
public override bool HasParameterList { get; }
public override bool IsAnonymousMethod { get; }
public override bool IsImplicitlyTyped { get; }
public override bool IsAsync => function.IsAsync;
public override IList<IParameter> Parameters => function.Method.Parameters;
public override IType ReturnType => function.Method.ReturnType;
public override ResolveResult Body { get; }
public override IType GetInferredReturnType(IType[] parameterTypes)
{
// We don't know how to compute which type would be inferred if
// given other parameter types.
// Let's hope this is good enough:
return InferredReturnType;
}
public override Conversion IsValid(IType[] parameterTypes, IType returnType, CSharpConversions conversions)
{
if (this.Parameters.Count != parameterTypes.Length)
return Conversion.None;
for (int i = 0; i < parameterTypes.Length; ++i) {
if (!parameterTypes[i].Equals(this.Parameters[i].Type)) {
if (IsImplicitlyTyped) {
// it's possible that different parameter types also lead to a valid conversion
return LambdaConversion.Instance;
} else {
return Conversion.None;
}
}
}
if (returnType.Equals(this.ReturnType)) {
return LambdaConversion.Instance;
} else {
return Conversion.None;
}
}
}
class LambdaConversion : Conversion
{
public static readonly LambdaConversion Instance = new LambdaConversion();
public override bool IsAnonymousFunctionConversion => true;
public override bool IsImplicit => true;
}
}

8
ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs

@ -172,9 +172,11 @@ namespace ICSharpCode.Decompiler.CSharp @@ -172,9 +172,11 @@ namespace ICSharpCode.Decompiler.CSharp
{
var type = this.Type;
if (type.Equals(targetType)) {
// Remove boxing conversion if possible
if (allowImplicitConversion && type.IsKnownType(KnownTypeCode.Object)) {
if (Expression is CastExpression cast && ResolveResult is ConversionResolveResult conversion && conversion.Conversion.IsBoxingConversion) {
// Make explicit conversion implicit, if possible
if (allowImplicitConversion && Expression is CastExpression cast && ResolveResult is ConversionResolveResult conversion) {
if (type.IsKnownType(KnownTypeCode.Object) && conversion.Conversion.IsBoxingConversion
|| type.Kind == TypeKind.Delegate && conversion.Conversion.IsAnonymousFunctionConversion)
{
return this.UnwrapChild(cast.Expression);
}
}

2
ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs

@ -169,7 +169,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -169,7 +169,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
return false;
if (startCall.Method.Name != "Start")
return false;
taskType = context.TypeSystem.Resolve(function.Method.ReturnType);
taskType = function.Method.ReturnType;
builderType = startCall.Method.DeclaringTypeDefinition;
const string ns = "System.Runtime.CompilerServices";
if (taskType.IsKnownType(KnownTypeCode.Void)) {

2
ICSharpCode.Decompiler/IL/ControlFlow/YieldReturnDecompiler.cs

@ -105,7 +105,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -105,7 +105,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
if (!context.Settings.YieldReturn)
return; // abort if enumerator decompilation is disabled
this.context = context;
this.currentType = function.Method.DeclaringType;
this.currentType = function.CecilMethod.DeclaringType;
this.enumeratorType = null;
this.enumeratorCtor = null;
this.stateField = null;

3
ICSharpCode.Decompiler/IL/ILReader.cs

@ -317,7 +317,8 @@ namespace ICSharpCode.Decompiler.IL @@ -317,7 +317,8 @@ namespace ICSharpCode.Decompiler.IL
ReadInstructions(cancellationToken);
var blockBuilder = new BlockBuilder(body, typeSystem, variableByExceptionHandler);
blockBuilder.CreateBlocks(mainContainer, instructionBuilder, isBranchTarget, cancellationToken);
var function = new ILFunction(body.Method, mainContainer);
var method = typeSystem.Resolve(body.Method);
var function = new ILFunction(method, body.Method, mainContainer);
CollectionExtensions.AddRange(function.Variables, parameterVariables);
CollectionExtensions.AddRange(function.Variables, localVariables);
CollectionExtensions.AddRange(function.Variables, stackVariables);

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

@ -18,10 +18,8 @@ @@ -18,10 +18,8 @@
using System;
using System.Collections.Generic;
using System.Threading;
using ICSharpCode.Decompiler.IL.Transforms;
using Mono.Cecil;
using ICSharpCode.Decompiler.Disassembler;
using System.Linq;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
@ -31,7 +29,8 @@ namespace ICSharpCode.Decompiler.IL @@ -31,7 +29,8 @@ namespace ICSharpCode.Decompiler.IL
{
partial class ILFunction
{
public readonly MethodDefinition Method;
public readonly IMethod Method;
public readonly MethodDefinition CecilMethod;
public readonly ILVariableCollection Variables;
/// <summary>
@ -62,10 +61,11 @@ namespace ICSharpCode.Decompiler.IL @@ -62,10 +61,11 @@ namespace ICSharpCode.Decompiler.IL
/// </summary>
public IType AsyncReturnType;
public ILFunction(MethodDefinition method, ILInstruction body) : base(OpCode.ILFunction)
public ILFunction(IMethod method, MethodDefinition cecilMethod, ILInstruction body) : base(OpCode.ILFunction)
{
this.Body = body;
this.Method = method;
this.CecilMethod = cecilMethod;
this.Variables = new ILVariableCollection(this);
}

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

@ -58,7 +58,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -58,7 +58,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
public void Run(ILFunction function, ILTransformContext context)
{
this.context = context;
currentFieldNames = function.Method.DeclaringType.Fields.Select(f => f.Name).ToArray();
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))
@ -358,7 +358,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -358,7 +358,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (v != existingVariable)
AddExistingName(reservedVariableNames, v.Name);
}
foreach (var f in function.Method.DeclaringType.Fields.Select(f => f.Name))
foreach (var f in function.CecilMethod.DeclaringType.Fields.Select(f => f.Name))
AddExistingName(reservedVariableNames, f);
string baseName = GetNameFromInstruction(valueContext);
@ -399,7 +399,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -399,7 +399,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (v != existingVariable)
AddExistingName(reservedVariableNames, v.Name);
}
foreach (var f in function.Method.DeclaringType.Fields.Select(f => f.Name))
foreach (var f in function.CecilMethod.DeclaringType.Fields.Select(f => f.Name))
AddExistingName(reservedVariableNames, f);
string baseName = GetNameByType(type);

4
ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs

@ -34,7 +34,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -34,7 +34,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (!context.Settings.AnonymousMethods)
return;
this.context = context;
this.decompilationContext = new SimpleTypeResolveContext(context.TypeSystem.Resolve(function.Method));
this.decompilationContext = new SimpleTypeResolveContext(function.Method);
var orphanedVariableInits = new List<ILInstruction>();
var targetsToReplace = new List<IInstructionWithVariableOperand>();
foreach (var block in function.Descendants.OfType<Block>()) {
@ -102,7 +102,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -102,7 +102,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
internal static bool IsPotentialClosure(ILTransformContext context, NewObj inst)
{
var decompilationContext = new SimpleTypeResolveContext(context.TypeSystem.Resolve(context.Function.Method));
var decompilationContext = new SimpleTypeResolveContext(context.Function.Method);
return IsPotentialClosure(decompilationContext.CurrentTypeDefinition, inst.Method.DeclaringTypeDefinition);
}

Loading…
Cancel
Save