diff --git a/src/CSharp/CodeCracker/Usage/ReadonlyFieldCodeFixProvider.cs b/src/CSharp/CodeCracker/Usage/ReadonlyFieldCodeFixProvider.cs index 1b9e85a58..b54cb0463 100644 --- a/src/CSharp/CodeCracker/Usage/ReadonlyFieldCodeFixProvider.cs +++ b/src/CSharp/CodeCracker/Usage/ReadonlyFieldCodeFixProvider.cs @@ -4,6 +4,7 @@ using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Formatting; +using System; using System.Collections.Immutable; using System.Composition; using System.Linq; @@ -44,10 +45,13 @@ private async static Task MakeFieldReadonlyAsync(Document document, Di private static SyntaxNode MakeSingleFieldReadonly(SyntaxNode root, FieldDeclarationSyntax fieldDeclaration) { - var newFieldDeclaration = fieldDeclaration.AddModifiers(SyntaxFactory.Token(SyntaxKind.ReadOnlyKeyword)) - .WithTrailingTrivia(fieldDeclaration.GetTrailingTrivia()) - .WithLeadingTrivia(fieldDeclaration.GetLeadingTrivia()) - .WithAdditionalAnnotations(Formatter.Annotation); + + var newFieldDeclaration = fieldDeclaration + .WithoutLeadingTrivia() + .AddModifiers(SyntaxFactory.Token(SyntaxKind.ReadOnlyKeyword)) + .WithTrailingTrivia(fieldDeclaration.GetTrailingTrivia()) + .WithLeadingTrivia(fieldDeclaration.GetLeadingTrivia()) + .WithAdditionalAnnotations(Formatter.Annotation); var newRoot = root.ReplaceNode(fieldDeclaration, newFieldDeclaration); return newRoot; } @@ -57,8 +61,8 @@ private static SyntaxNode MakeMultipleFieldsReadonly(SyntaxNode root, FieldDecla var newFieldDeclaration = fieldDeclaration.WithDeclaration(newDeclaration); var newReadonlyFieldDeclaration = fieldDeclaration.WithDeclaration(SyntaxFactory.VariableDeclaration(fieldDeclaration.Declaration.Type, SyntaxFactory.SeparatedList(new[] { variableToMakeReadonly }))) .WithoutLeadingTrivia() - .WithTrailingTrivia(SyntaxFactory.ParseTrailingTrivia("\n")) .AddModifiers(SyntaxFactory.Token(SyntaxKind.ReadOnlyKeyword)) + .WithTrailingTrivia(SyntaxFactory.ParseTrailingTrivia(Environment.NewLine)) .WithAdditionalAnnotations(Formatter.Annotation); var newRoot = root.ReplaceNode(fieldDeclaration, new[] { newFieldDeclaration, newReadonlyFieldDeclaration }); return newRoot; diff --git a/test/CSharp/CodeCracker.Test/Usage/ReadonlyFieldTests.cs b/test/CSharp/CodeCracker.Test/Usage/ReadonlyFieldTests.cs index 8639541c5..ed92be9ee 100644 --- a/test/CSharp/CodeCracker.Test/Usage/ReadonlyFieldTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/ReadonlyFieldTests.cs @@ -433,6 +433,77 @@ class TypeName await VerifyCSharpFixAsync(source, fixtest); } + + [Fact] + public async Task DoesNotDuplicateLeadingDirectivesOnFixSingle() + { + const string source = @" + namespace ConsoleApplication1 + { + public class Foo + { + #region standard + Foo foo1 = new Foo(); + #endregion + + #region withAccessModifier + private Foo foo2 = new Foo(); + #endregion + + #region withStatic + private static Foo foo3 = new Foo(); + #endregion + } + }"; + const string fixtest = @" + namespace ConsoleApplication1 + { + public class Foo + { + #region standard + readonly Foo foo1 = new Foo(); + #endregion + + #region withAccessModifier + private readonly Foo foo2 = new Foo(); + #endregion + + #region withStatic + private static readonly Foo foo3 = new Foo(); + #endregion + } + }"; + await VerifyCSharpFixAsync(source, fixtest); + } + + + [Fact] + public async Task DoesNotDuplicateLeadingDirectivesOnFixAll() + { + const string source = @" + namespace ConsoleApplication1 + { + public class Foo + { + #region standard + Foo foo1, foo2 = new Foo(), foo3; + #endregion + } + }"; + const string fixtest = @" + namespace ConsoleApplication1 + { + public class Foo + { + #region standard + Foo foo1, foo3; + readonly Foo foo2 = new Foo(); + #endregion + } + }"; + await VerifyCSharpFixAsync(source, fixtest); + } + [Fact] public async Task FieldsWithAssignmentOnDeclarationWithSingleDeclarationCreatesDiagnostic() {