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

Ron*_*ijm 11 c# roslyn

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

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

这违反了规则:

    static void Main(string[] args)
    {
    }
Run Code Online (Sandbox Code Playgroud)

还行吧:

    public static void Main(string[] args)
    {
    }
Run Code Online (Sandbox Code Playgroud)

它必须具有明确的内部关键字,公共关键字,私有关键字或受保护的关键字.

检测违规是相当容易的,但现在我正在尝试提供修复.我一直在尝试和搜索各处,但我无法找到如何添加访问修饰符.

这是我到目前为止:

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

WithModifiers需求SyntaxTokenList,我可以新建(),但我不知道如何使它的SyntaxKind.PublicKeyword.我也不确定我是否想要新的,或使用SyntaxFactory.然而,在使用的时候SyntaxFactory,我也想不出我需要创建一个该方法SyntaxTokenSyntaxKind.PublicKeyword

我可以发布整个事情,包括DiagnosticAnalyzer如果有兴趣......

Kev*_*lch 6

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

var newMethodDeclaration = methodDeclaration.AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword));
Run Code Online (Sandbox Code Playgroud)

获取新方法声明.

扩展形式的类似于:

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

希望这可以帮助


Ron*_*ijm 4

我真正需要的是这样的:

var newModifiers = SyntaxFactory.TokenList(SyntaxFactory.Token(accessModifierToken))
    .AddRange(methodDeclaration.Modifiers);
Run Code Online (Sandbox Code Playgroud)

这几乎就是 Chris Eelmaa 的建议,但根据这个建议,我最终得到的建议static public void Main是有效的,但很丑陋。

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