Browse Source

Fix assertion fail in DeclareVariables: Make sure that we do not try to declare variables in non-assignment contexts.

pull/870/merge
Siegfried Pammer 8 years ago
parent
commit
d45e3bfb3c
  1. 12
      ICSharpCode.Decompiler.Tests/TestCases/Correctness/Patterns.cs
  2. 21
      ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs

12
ICSharpCode.Decompiler.Tests/TestCases/Correctness/Patterns.cs

@ -14,6 +14,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
static void Main() static void Main()
{ {
SimpleUsingNullStatement(); SimpleUsingNullStatement();
ForWithMultipleVariables();
} }
/// <summary> /// <summary>
@ -27,5 +28,16 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
} }
Console.WriteLine("after using"); Console.WriteLine("after using");
} }
public static void ForWithMultipleVariables()
{
int x, y;
Console.WriteLine("before for");
for (x = y = 0; x < 10; x++) {
y++;
Console.WriteLine("x = " + x + ", y = " + y);
}
Console.WriteLine("after for");
}
} }
} }

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

@ -312,7 +312,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
// guarantee that it finds only blocks. // guarantee that it finds only blocks.
// Fix that up now. // Fix that up now.
while (!(v.InsertionPoint.nextNode.Parent is BlockStatement)) { while (!(v.InsertionPoint.nextNode.Parent is BlockStatement)) {
if (v.InsertionPoint.nextNode.Parent is ForStatement f && v.InsertionPoint.nextNode == f.Initializers.FirstOrDefault()) if (v.InsertionPoint.nextNode.Parent is ForStatement f && v.InsertionPoint.nextNode == f.Initializers.FirstOrDefault() && IsMatchingAssignment(v, out _))
break; break;
v.InsertionPoint = v.InsertionPoint.Up(); v.InsertionPoint = v.InsertionPoint.Up();
} }
@ -348,6 +348,18 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
} }
} }
bool IsMatchingAssignment(VariableToDeclare v, out AssignmentExpression assignment)
{
assignment = (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);
}
if (assignment != null && assignment.Operator == AssignmentOperatorType.Assign && assignment.Left.IsMatch(expectedExpr))
return true;
return false;
}
void InsertVariableDeclarations(TransformContext context) void InsertVariableDeclarations(TransformContext context)
{ {
var replacements = new List<KeyValuePair<AstNode, AstNode>>(); var replacements = new List<KeyValuePair<AstNode, AstNode>>();
@ -356,12 +368,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
if (v.RemovedDueToCollision) if (v.RemovedDueToCollision)
continue; continue;
var assignment = (v.InsertionPoint.nextNode as ExpressionStatement)?.Expression as AssignmentExpression; if (IsMatchingAssignment(v, out AssignmentExpression assignment)) {
Expression expectedExpr = new IdentifierExpression(v.Name);
if (v.Type.Kind == TypeKind.ByReference) {
expectedExpr = new DirectionExpression(FieldDirection.Ref, expectedExpr);
}
if (assignment != null && assignment.Operator == AssignmentOperatorType.Assign && assignment.Left.IsMatch(expectedExpr)) {
AstType type; AstType type;
if (context.Settings.AnonymousTypes && v.Type.ContainsAnonymousType()) { if (context.Settings.AnonymousTypes && v.Type.ContainsAnonymousType()) {
type = new SimpleType("var"); type = new SimpleType("var");

Loading…
Cancel
Save