Browse Source

Fix #1618: Unwrap in-arguments, when converting method calls to operators.

pull/1633/head
Siegfried Pammer 6 years ago
parent
commit
6ecd99f893
  1. 7
      ICSharpCode.Decompiler/CSharp/Syntax/SyntaxExtensions.cs
  2. 16
      ICSharpCode.Decompiler/CSharp/Transforms/ReplaceMethodCallsWithOperators.cs

7
ICSharpCode.Decompiler/CSharp/Syntax/SyntaxExtensions.cs

@ -75,5 +75,12 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
node.Remove(); node.Remove();
return node; return node;
} }
public static Expression UnwrapInDirectionExpression(this Expression expr)
{
if (!(expr is DirectionExpression dir && dir.FieldDirection == FieldDirection.In))
return expr;
return dir.Expression.Detach();
}
} }
} }

16
ICSharpCode.Decompiler/CSharp/Transforms/ReplaceMethodCallsWithOperators.cs

@ -60,7 +60,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
invocationExpression.Arguments.Clear(); // detach arguments from invocationExpression invocationExpression.Arguments.Clear(); // detach arguments from invocationExpression
Expression expr = arguments[0]; Expression expr = arguments[0];
for (int i = 1; i < arguments.Length; i++) { for (int i = 1; i < arguments.Length; i++) {
expr = new BinaryOperatorExpression(expr, BinaryOperatorType.Add, arguments[i]); expr = new BinaryOperatorExpression(expr, BinaryOperatorType.Add, arguments[i].UnwrapInDirectionExpression());
} }
expr.CopyAnnotationsFrom(invocationExpression); expr.CopyAnnotationsFrom(invocationExpression);
invocationExpression.ReplaceWith(expr); invocationExpression.ReplaceWith(expr);
@ -116,7 +116,11 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
if (bop != null && arguments.Length == 2) { if (bop != null && arguments.Length == 2) {
invocationExpression.Arguments.Clear(); // detach arguments from invocationExpression invocationExpression.Arguments.Clear(); // detach arguments from invocationExpression
invocationExpression.ReplaceWith( invocationExpression.ReplaceWith(
new BinaryOperatorExpression(arguments[0], bop.Value, arguments[1]).CopyAnnotationsFrom(invocationExpression) new BinaryOperatorExpression(
arguments[0].UnwrapInDirectionExpression(),
bop.Value,
arguments[1].UnwrapInDirectionExpression()
).CopyAnnotationsFrom(invocationExpression)
); );
return; return;
} }
@ -130,7 +134,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
// so reverse that optimization here: // so reverse that optimization here:
invocationExpression.ReplaceWith( invocationExpression.ReplaceWith(
new BinaryOperatorExpression( new BinaryOperatorExpression(
arguments[0].Detach(), arguments[0].UnwrapInDirectionExpression().Detach(),
(uop == UnaryOperatorType.Increment ? BinaryOperatorType.Add : BinaryOperatorType.Subtract), (uop == UnaryOperatorType.Increment ? BinaryOperatorType.Add : BinaryOperatorType.Subtract),
new PrimitiveExpression(1m) new PrimitiveExpression(1m)
).CopyAnnotationsFrom(invocationExpression) ).CopyAnnotationsFrom(invocationExpression)
@ -140,20 +144,20 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
} }
arguments[0].Remove(); // detach argument arguments[0].Remove(); // detach argument
invocationExpression.ReplaceWith( invocationExpression.ReplaceWith(
new UnaryOperatorExpression(uop.Value, arguments[0]).CopyAnnotationsFrom(invocationExpression) new UnaryOperatorExpression(uop.Value, arguments[0].UnwrapInDirectionExpression()).CopyAnnotationsFrom(invocationExpression)
); );
return; return;
} }
if (method.Name == "op_Explicit" && arguments.Length == 1) { if (method.Name == "op_Explicit" && arguments.Length == 1) {
arguments[0].Remove(); // detach argument arguments[0].Remove(); // detach argument
invocationExpression.ReplaceWith( invocationExpression.ReplaceWith(
new CastExpression(context.TypeSystemAstBuilder.ConvertType(method.ReturnType), arguments[0]) new CastExpression(context.TypeSystemAstBuilder.ConvertType(method.ReturnType), arguments[0].UnwrapInDirectionExpression())
.CopyAnnotationsFrom(invocationExpression) .CopyAnnotationsFrom(invocationExpression)
); );
return; return;
} }
if (method.Name == "op_True" && arguments.Length == 1 && invocationExpression.Role == Roles.Condition) { if (method.Name == "op_True" && arguments.Length == 1 && invocationExpression.Role == Roles.Condition) {
invocationExpression.ReplaceWith(arguments[0]); invocationExpression.ReplaceWith(arguments[0].UnwrapInDirectionExpression());
return; return;
} }

Loading…
Cancel
Save