Method signature formatting loses indentation

I am creating a Code Fix that turns the access modifier of the discovered public methods. The implementation is simple: remove all existing access modifiers and add public in front. Subsequently, I replace node and return the solution.

This leads to a list of modifiers that looks like this: publicvirtual void Method() . In addition to modifiers inserted against eachother, this line of code is incorrectly indented. It looks like this:

  [TestClass] public class MyClass { [TestMethod] publicvirtual void Method() { } } 

So, as a solution, I format the code instead. Using

 var formattedMethod = Formatter.Format(newMethod, newMethod.Modifiers.Span, document.Project.Solution.Workspace, document.Project.Solution.Workspace.Options); 

I can format modifiers, but they still backtrack by mistake:

  [TestClass] public class MyClass { [TestMethod] public virtual void Method() { } } 

I guess this is due to trivialities, but adding a formatted method with the original trivial method doesn't matter. I want to avoid formatting the entire document, because, well, this is not an action to format the entire document.

All relevant implementation of this code fix:

 private Task<Solution> MakePublicAsync(Document document, SyntaxNode root, MethodDeclarationSyntax method) { var removableModifiers = new[] { SyntaxFactory.Token(SyntaxKind.InternalKeyword), SyntaxFactory.Token(SyntaxKind.ProtectedKeyword), SyntaxFactory.Token(SyntaxKind.PrivateKeyword) }; var modifierList = new SyntaxTokenList() .Add(SyntaxFactory.Token(SyntaxKind.PublicKeyword)) .AddRange(method.Modifiers.Where(x => !removableModifiers.Select(y => y.RawKind).Contains(x.RawKind))); var newMethod = method.WithModifiers(modifierList); var formattedMethod = Formatter.Format(newMethod, newMethod.Modifiers.Span, document.Project.Solution.Workspace, document.Project.Solution.Workspace.Options); var newRoot = root.ReplaceNode(method, formattedMethod.WithLeadingTrivia(method.GetLeadingTrivia())); var newDocument = document.WithSyntaxRoot(newRoot); return Task.FromResult(newDocument.Project.Solution); } 
+5
source share
2 answers

Instead of manually calling Formatter.Format simply place Formatter.Annotation on your fixed nodes, and the CodeFix engine will select it automatically for you.

The problem is that you need to call Format in the root of the tree, but specify the interval of the tree you want to format, otherwise formatting will be performed only on the tree in which you pass, without context from its ancestor.

+2
source

The problem was that my tests were indented in the string representation itself, for example:

  var original = @" using System; using System.Text; namespace ConsoleApplication1 { class MyClass { void Method(Nullable<int> myVar = 5) { } } }"; 

As you can see, there is a tab between the left margin and the actual code. Apparently, the Roslyn formatter cannot handle this scenario (which admittedly is not a common situation).

In a situation, by contrast, you are probably interested in formatting, so I will accept Kevin's answer.

0
source

All Articles