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);
}
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 );
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.
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 .
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With