diff --git a/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpSyntaxGenerator.cs b/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpSyntaxGenerator.cs index cf03d43c8ed4e..7ad89b49d2666 100644 --- a/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpSyntaxGenerator.cs +++ b/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpSyntaxGenerator.cs @@ -236,9 +236,7 @@ private protected override SyntaxNode MethodDeclaration( return SyntaxFactory.MethodDeclaration( attributeLists: default, - // Pass `withLeadingElasticMarker: true` to ensure method will space itself properly within the members it - // is added to. - modifiers: AsModifierList(accessibility, modifiers, SyntaxKind.MethodDeclaration, withLeadingElasticMarker: true), + modifiers: AsModifierList(accessibility, modifiers, SyntaxKind.MethodDeclaration), returnType: returnType != null ? (TypeSyntax)returnType : SyntaxFactory.PredefinedType(VoidKeyword), explicitInterfaceSpecifier: null, identifier: name.ToIdentifierToken(), @@ -430,12 +428,13 @@ public override SyntaxNode GetAccessorDeclaration(Accessibility accessibility, I private protected override SyntaxNode SetAccessorDeclaration(Accessibility accessibility, bool isInitOnly, IEnumerable? statements) => AccessorDeclaration(isInitOnly ? SyntaxKind.InitAccessorDeclaration : SyntaxKind.SetAccessorDeclaration, accessibility, statements); - private static SyntaxNode AccessorDeclaration( + private static AccessorDeclarationSyntax AccessorDeclaration( SyntaxKind kind, Accessibility accessibility, IEnumerable? statements) { - var accessor = SyntaxFactory.AccessorDeclaration(kind); - accessor = accessor.WithModifiers( - AsModifierList(accessibility, DeclarationModifiers.None, SyntaxKind.PropertyDeclaration)); + var accessor = SyntaxFactory + .AccessorDeclaration(kind) + .WithModifiers( + AsModifierList(accessibility, DeclarationModifiers.None, SyntaxKind.PropertyDeclaration)); accessor = statements == null ? accessor.WithSemicolonToken(SemicolonToken) @@ -1437,7 +1436,10 @@ public override SyntaxNode WithAccessibility(SyntaxNode declaration, Accessibili modifiers = modifiers.WithIsStatic(false); } - var newTokens = Merge(tokens, AsModifierList(accessibility, modifiers)); + // We're updating the modifiers for something. We don't want to add elastic trivia in that case as + // we don't want the act of adding/removing/modifying modifiers to change the formatting of the parent + // construct. + var newTokens = Merge(tokens, AsModifierList(accessibility, modifiers, withLeadingElasticMarker: false)); return SetModifierTokens(d, newTokens); }); } @@ -1647,7 +1649,10 @@ private SyntaxNode WithModifiersInternal(SyntaxNode declaration, DeclarationModi } } - var newTokens = Merge(tokens, AsModifierList(accessibility, modifiers)); + // We're updating the modifiers for something. We don't want to add elastic trivia in that case as + // we don't want the act of adding/removing/modifying modifiers to change the formatting of the parent + // construct. + var newTokens = Merge(tokens, AsModifierList(accessibility, modifiers, withLeadingElasticMarker: false)); return SetModifierTokens(d, newTokens); }); } @@ -1674,13 +1679,13 @@ private static SyntaxTokenList AsModifierList( Accessibility accessibility, DeclarationModifiers modifiers, SyntaxKind kind, - bool withLeadingElasticMarker = false) + bool withLeadingElasticMarker = true) => AsModifierList(accessibility, GetAllowedModifiers(kind) & modifiers, withLeadingElasticMarker); private static SyntaxTokenList AsModifierList( Accessibility accessibility, DeclarationModifiers modifiers, - bool withLeadingElasticMarker = false) + bool withLeadingElasticMarker = true) { using var _ = ArrayBuilder.GetInstance(out var list); diff --git a/src/Workspaces/CSharpTest/CodeGeneration/SyntaxGeneratorTests.cs b/src/Workspaces/CSharpTest/CodeGeneration/SyntaxGeneratorTests.cs index 0e054d2e13945..353a97993edc2 100644 --- a/src/Workspaces/CSharpTest/CodeGeneration/SyntaxGeneratorTests.cs +++ b/src/Workspaces/CSharpTest/CodeGeneration/SyntaxGeneratorTests.cs @@ -2916,6 +2916,30 @@ interface i """); } + [Fact] + public void TestMultipleMembersIntoClass() + { + using var workspace = new AdhocWorkspace(); + var node = Generator.AddMembers(Generator.ClassDeclaration("C"), + [ + Generator.MethodDeclaration("M1", returnType: Generator.TypeExpression(SpecialType.System_Void), accessibility: Accessibility.Public), + Generator.PropertyDeclaration("P1", Generator.TypeExpression(SpecialType.System_Int32), accessibility: Accessibility.Public) + ]); + + AssertEx.EqualOrDiff( + """ + class C + { + public void M1() + { + } + + public int P1 { get; set; } + } + """, + Formatter.Format(node, workspace).ToFullString()); + } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65932")] public void TestAddExpressionBodyMembersToInterface() {