Browse Source

Fix #1147: Use C# 7.3 syntax for ref reassignment.

pull/1213/head
Daniel Grunwald 7 years ago
parent
commit
796612209d
  1. 12
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  2. 12
      ICSharpCode.Decompiler/CSharp/StatementBuilder.cs
  3. 16
      ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs

12
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -500,7 +500,17 @@ namespace ICSharpCode.Decompiler.CSharp @@ -500,7 +500,17 @@ namespace ICSharpCode.Decompiler.CSharp
inst.Variable.Type = type;
}
}
return Assignment(ConvertVariable(inst.Variable).WithoutILInstruction(), translatedValue).WithILInstruction(inst);
var lhs = ConvertVariable(inst.Variable).WithoutILInstruction();
if (lhs.Expression is DirectionExpression dirExpr && lhs.ResolveResult is ByReferenceResolveResult lhsRefRR) {
// ref (re-)assignment, emit "ref (a = ref b)".
lhs = lhs.UnwrapChild(dirExpr.Expression);
var assign = new AssignmentExpression(lhs.Expression, translatedValue.Expression)
.WithRR(new OperatorResolveResult(lhs.Type, ExpressionType.Assign, lhsRefRR, translatedValue.ResolveResult));
return new DirectionExpression(FieldDirection.Ref, assign)
.WithoutILInstruction().WithRR(lhsRefRR);
} else {
return Assignment(lhs, translatedValue).WithILInstruction(inst);
}
bool IsOtherValueType(IType type)
{

12
ICSharpCode.Decompiler/CSharp/StatementBuilder.cs

@ -65,7 +65,17 @@ namespace ICSharpCode.Decompiler.CSharp @@ -65,7 +65,17 @@ namespace ICSharpCode.Decompiler.CSharp
{
return new ExpressionStatement(exprBuilder.Translate(inst));
}
protected internal override Statement VisitStLoc(StLoc inst)
{
var expr = exprBuilder.Translate(inst);
// strip top-level ref on ref re-assignment
if (expr.Expression is DirectionExpression dirExpr) {
expr = expr.UnwrapChild(dirExpr.Expression);
}
return new ExpressionStatement(expr);
}
protected internal override Statement VisitNop(Nop inst)
{
var stmt = new EmptyStatement();

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

@ -386,14 +386,16 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -386,14 +386,16 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
bool IsMatchingAssignment(VariableToDeclare v, out AssignmentExpression assignment)
{
assignment = v.InsertionPoint.nextNode as AssignmentExpression ?? (v.InsertionPoint.nextNode as ExpressionStatement)?.Expression as AssignmentExpression;
Expression expectedExpr = new IdentifierExpression(v.Name);
if (v.Type.Kind == TypeKind.ByReference) {
expectedExpr = new DirectionExpression(FieldDirection.Ref, expectedExpr);
assignment = v.InsertionPoint.nextNode as AssignmentExpression;
if (assignment == null) {
assignment = (v.InsertionPoint.nextNode as ExpressionStatement)?.Expression as AssignmentExpression;
if (assignment == null)
return false;
}
if (assignment != null && assignment.Operator == AssignmentOperatorType.Assign && assignment.Left.IsMatch(expectedExpr))
return true;
return false;
return assignment.Operator == AssignmentOperatorType.Assign
&& assignment.Left is IdentifierExpression identExpr
&& identExpr.Identifier == v.Name
&& identExpr.TypeArguments.Count == 0;
}
void InsertVariableDeclarations(TransformContext context)

Loading…
Cancel
Save