Skip to content

Commit e34db06

Browse files
Fix #3543: Missing parentheses around field assignment expression in list initializers
1 parent 6aa9bd8 commit e34db06

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

ICSharpCode.Decompiler.Tests/Output/InsertParenthesesVisitorTests.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,5 +484,32 @@ public void ArrayCreationWithInitializerInIndexer()
484484
Assert.That(InsertRequired(expr), Is.EqualTo("new int[1] { 42 } [0]"));
485485
Assert.That(InsertReadable(expr), Is.EqualTo("(new int[1] { 42 }) [0]"));
486486
}
487+
488+
[Test]
489+
public void AssignmentInObjectOrCollectionInitializer()
490+
{
491+
Expression expr = new ObjectCreateExpression {
492+
Type = AstType.Create("List<int>"),
493+
Initializer = new ArrayInitializerExpression {
494+
Elements = { new AssignmentExpression(new IdentifierExpression("x"), new PrimitiveExpression(42)) }
495+
}
496+
};
497+
Expression expr2 = new ObjectCreateExpression {
498+
Type = AstType.Create("Data"),
499+
Initializer = new ArrayInitializerExpression {
500+
Elements = { new NamedExpression("X", new PrimitiveExpression(42)) }
501+
}
502+
};
503+
Expression expr3 = new ObjectCreateExpression {
504+
Type = AstType.Create("Dictionary<int, string>"),
505+
Initializer = new ArrayInitializerExpression {
506+
Elements = { new AssignmentExpression(new IndexerExpression(null, new PrimitiveExpression(0)), new PrimitiveExpression("42")) }
507+
}
508+
};
509+
510+
Assert.That(InsertRequired(expr), Is.EqualTo("new List<int> { (x = 42) }"));
511+
Assert.That(InsertRequired(expr2), Is.EqualTo("new Data { X = 42 }"));
512+
Assert.That(InsertRequired(expr3), Is.EqualTo("new Dictionary<int, string> { [0] = \"42\" }"));
513+
}
487514
}
488515
}

ICSharpCode.Decompiler/CSharp/OutputVisitor/InsertParenthesesVisitor.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,15 @@ private bool IsConditionalRefExpression(ConditionalExpression conditionalExpress
458458

459459
public override void VisitAssignmentExpression(AssignmentExpression assignmentExpression)
460460
{
461+
// Assignments in initializers need additional parentheses to disambiguate assignments
462+
// to variables and assignments to members of the initialized object.
463+
// This works without access to semantic information, because the ExpressionBuilder
464+
// uses NamedExpression for `Member = value` instead of AssignmentExpression.
465+
if (assignmentExpression.Parent is ArrayInitializerExpression
466+
&& assignmentExpression.Left is not IndexerExpression)
467+
{
468+
Parenthesize(assignmentExpression);
469+
}
461470
// assignment is right-associative
462471
ParenthesizeIfRequired(assignmentExpression.Left, PrecedenceLevel.Assignment + 1);
463472
HandleAssignmentRHS(assignmentExpression.Right);

0 commit comments

Comments
 (0)