Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Formatting a method signature loses indentation

Tags:

c#

roslyn

I'm creating a Code Fix which turns the access modifier of detected methods public. The implementation is straightforward: remove all existing access modifiers and add public at the front. Afterwards I replace the node and return the solution.

This however results in a modifier list that looks like this: publicvirtual void Method(). On top of the modifiers being pasted against eachother, that line of code is wrongly 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 the modifiers but they are still wrongly indented:

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

            }
        }

I assume this is because of trivia but prepending the formatted method with the original method's leading trivia does not make a difference. I want to avoid formatting the entire document because, well, this isn't an action to format the entire document.

The entire 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);
}
like image 490
Jeroen Vannevel Avatar asked May 04 '15 13:05

Jeroen Vannevel


People also ask

How do I fix indentation in Visual Studio?

Menu Tools > Options... > Text Editor > All Languages > Tabs: Click on Smart (for resolving conflicts); Type the Tab Size and Indent Size you want (e.g. 2 );

How do I turn on auto indent in Visual Studio?

Select the text you want to automatically indent.Click menu Edit → Advanced → *Format Selection, or press Ctrl + K , Ctrl + F . Format Selection applies the smart indenting rules for the language in which you are programming to the selected text.

How do I add an indent in Visual Studio?

Visual studio's smart indenting does automatically indenting, but we can select a block or all the code for indentation. Use either of the two ways to indentation the code: Shift + Tab , Ctrl + k + f .


1 Answers

Instead of calling Formatter.Format manually, just put the Formatter.Annotation on your fixed nodes, and the CodeFix engine will call it automatically for you.

The issue is that you need to call Format on the root of the tree, but specify the span of the tree you want formatted, otherwise the formatter will run on just the tree you pass in, with no context from its parent.

like image 77
Kevin Pilch Avatar answered Sep 27 '22 22:09

Kevin Pilch