使用Roslyn CodeFixProvider向方法添加访问修饰符

本文关键字:访问 添加 方法 Roslyn CodeFixProvider 使用 | 更新日期: 2023-09-27 18:28:45

几天前我在TechEd,我看到了Kevin Pilch Bisson的演讲(相关部分大约18分钟开始)。。。我觉得这很酷,所以我决定自己和罗斯林一起玩。

我正试图制定一条规则"必须声明访问修饰符"(Stylecop SA1400),意思是

这违反了规则:

    static void Main(string[] args)
    {
    }

这没问题:

    public static void Main(string[] args)
    {
    }

它必须具有显式的内部关键字、公共关键字、私有关键字或受保护关键字。

检测违规行为相当容易,但现在我正在尝试提供一个修复程序。我一直在尝试,到处搜索,但我找不到如何添加访问修饰符。

这就是我目前所拥有的:

public async Task<IEnumerable<CodeAction>> GetFixesAsync(Document document, TextSpan span, IEnumerable<Diagnostic> diagnostics, CancellationToken cancellationToken)
{
    var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
    var token = root.FindToken(span.Start);
    var methodDeclaration = token.Parent as MethodDeclarationSyntax;
    //var newModifiers = methodDeclaration.Modifiers.Add(SyntaxFactory.AccessorDeclaration(SyntaxKind.PublicKeyword));         
    //var newModifiers = new SyntaxTokenList() { new SyntaxToken() };
    MethodDeclarationSyntax newMethodDeclaration = methodDeclaration.WithModifiers(methodDeclaration.Modifiers);
    var newRoot = root.ReplaceNode(methodDeclaration, newMethodDeclaration);
    var newDocument = document.WithSyntaxRoot(newRoot);
    return new[] { CodeAction.Create("Add Public Keyword", newDocument) };
}

WithModifiers需要一个SyntaxTokenList,我可以新建(),但我不知道如何使用SyntaxKind.PublicKeyword。我也不确定我是否应该新建它,或者使用SyntaxFactory。然而,当使用SyntaxFactory时,我也不知道我需要哪种方法来创建SyntaxKind.PublicKeywordSyntaxToken

如果有兴趣的话,我可以发布整个东西,包括DiagnosticAnalyzer。。。

使用Roslyn CodeFixProvider向方法添加访问修饰符

很高兴你喜欢这次演讲!实际上,我们在语法模型中有一些助手,可以更容易地将项目添加到列表中,因此您应该能够执行以下操作:

var newMethodDeclaration = methodDeclaration.AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword));

获取新方法声明。

这种扩展形式类似于:

var newModifiers = SyntaxFactory.TokenList(modifiers.Concat(new[] { SyntaxFactory.Token(SyntaxKind.PublicKeyword)}));
var newMethodDeclaration = methodDeclaration.WithModifiers(newModifiers);

希望这能帮助

我真正需要的是:

var newModifiers = SyntaxFactory.TokenList(SyntaxFactory.Token(accessModifierToken))
    .AddRange(methodDeclaration.Modifiers);

这几乎是Chris Eelma的建议,但有了这个建议,我最终得到了static public void Main,这是有效的,但很难看。

追加public会将其添加到列表的末尾,据我所知,访问修饰符应该始终是第一个。

好吧,要创建指示public static的修饰符,可以使用以下命令:

var modifiers = SyntaxFactory.TokenList(
    new SyntaxToken[] { 
        SyntaxFactory.Token(SyntaxKind.PublicKeyword), 
        SyntaxFactory.Token(SyntaxKind.StaticKeyword) 
    }),

但就你而言,我不明白为什么

var updatedModifiers = methodDeclaration
                .Modifiers
                .Add(SyntaxFactory.Token(SyntaxKind.PublicKeyword));
methodDeclaration.WithModifiers(updatedModifiers);

不起作用。