Browse Source

Fix #3543: Missing parentheses around field assignment expression in list initializers

pull/3551/head
Siegfried Pammer 4 months ago
parent
commit
e34db06a67
  1. 27
      ICSharpCode.Decompiler.Tests/Output/InsertParenthesesVisitorTests.cs
  2. 9
      ICSharpCode.Decompiler/CSharp/OutputVisitor/InsertParenthesesVisitor.cs

27
ICSharpCode.Decompiler.Tests/Output/InsertParenthesesVisitorTests.cs

@ -484,5 +484,32 @@ namespace ICSharpCode.Decompiler.Tests.Output @@ -484,5 +484,32 @@ namespace ICSharpCode.Decompiler.Tests.Output
Assert.That(InsertRequired(expr), Is.EqualTo("new int[1] { 42 } [0]"));
Assert.That(InsertReadable(expr), Is.EqualTo("(new int[1] { 42 }) [0]"));
}
[Test]
public void AssignmentInObjectOrCollectionInitializer()
{
Expression expr = new ObjectCreateExpression {
Type = AstType.Create("List<int>"),
Initializer = new ArrayInitializerExpression {
Elements = { new AssignmentExpression(new IdentifierExpression("x"), new PrimitiveExpression(42)) }
}
};
Expression expr2 = new ObjectCreateExpression {
Type = AstType.Create("Data"),
Initializer = new ArrayInitializerExpression {
Elements = { new NamedExpression("X", new PrimitiveExpression(42)) }
}
};
Expression expr3 = new ObjectCreateExpression {
Type = AstType.Create("Dictionary<int, string>"),
Initializer = new ArrayInitializerExpression {
Elements = { new AssignmentExpression(new IndexerExpression(null, new PrimitiveExpression(0)), new PrimitiveExpression("42")) }
}
};
Assert.That(InsertRequired(expr), Is.EqualTo("new List<int> { (x = 42) }"));
Assert.That(InsertRequired(expr2), Is.EqualTo("new Data { X = 42 }"));
Assert.That(InsertRequired(expr3), Is.EqualTo("new Dictionary<int, string> { [0] = \"42\" }"));
}
}
}

9
ICSharpCode.Decompiler/CSharp/OutputVisitor/InsertParenthesesVisitor.cs

@ -458,6 +458,15 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor @@ -458,6 +458,15 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
public override void VisitAssignmentExpression(AssignmentExpression assignmentExpression)
{
// Assignments in initializers need additional parentheses to disambiguate assignments
// to variables and assignments to members of the initialized object.
// This works without access to semantic information, because the ExpressionBuilder
// uses NamedExpression for `Member = value` instead of AssignmentExpression.
if (assignmentExpression.Parent is ArrayInitializerExpression
&& assignmentExpression.Left is not IndexerExpression)
{
Parenthesize(assignmentExpression);
}
// assignment is right-associative
ParenthesizeIfRequired(assignmentExpression.Left, PrecedenceLevel.Assignment + 1);
HandleAssignmentRHS(assignmentExpression.Right);

Loading…
Cancel
Save