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. 10
      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
inst.Variable.Type = type; 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) bool IsOtherValueType(IType type)
{ {

10
ICSharpCode.Decompiler/CSharp/StatementBuilder.cs

@ -66,6 +66,16 @@ namespace ICSharpCode.Decompiler.CSharp
return new ExpressionStatement(exprBuilder.Translate(inst)); 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) protected internal override Statement VisitNop(Nop inst)
{ {
var stmt = new EmptyStatement(); var stmt = new EmptyStatement();

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

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

Loading…
Cancel
Save