格式化方法签名会丢失缩进

Jer*_*vel 6 c# roslyn

我正在创建一个代码修复程序,它会转换检测到的方法的访问修饰符public.实现很简单:删除所有现有的访问修饰符并public在前面添加.然后我替换节点并返回解决方案.

但是这会产生一个如下所示的修饰符列表:publicvirtual void Method().在粘贴彼此的修改器之上,该行代码被错误地缩进.它看起来像这样:

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

            }
        }
Run Code Online (Sandbox Code Playgroud)

因此,作为解决方案,我会格式化代码.运用

var formattedMethod = Formatter.Format(newMethod, 
                                       newMethod.Modifiers.Span,
                                       document.Project.Solution.Workspace,
                                       document.Project.Solution.Workspace.Options);
Run Code Online (Sandbox Code Playgroud)

我可以格式化修饰符,但它们仍然错误地缩进:

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

            }
        }
Run Code Online (Sandbox Code Playgroud)

我认为这是因为琐事,但是使用原始方法的主要琐事预先设置格式化的方法并没有什么不同.我想避免格式化整个文档,因为这不是格式化整个文档的操作.

本代码修复的完整相关实现:

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);
}
Run Code Online (Sandbox Code Playgroud)

Kev*_*lch 3

无需Formatter.Format手动调用,只需将其放在Formatter.Annotation您的固定节点上,CodeFix 引擎就会自动为您调用。

问题是您需要调用Format树的根,但指定要格式化的树的跨度,否则格式化程序将在您传入的树上运行,而没有来自其父级的上下文。