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

时间:2014-11-02 18:50:32

标签: c# roslyn

几天前我在TechEd,我看到this talk by Kevin Pilch-Bisson (relevent part starts at about 18 minutes) ......我觉得很酷,所以我决定自己和Roslyn一起玩。

我试图制定规则"必须声明访问修饰符" (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时,我也无法确定创建SyntaxToken SyntaxKind.PublicKeyword

所需的方法

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

3 个答案:

答案 0 :(得分:6)

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

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

获取新方法声明。

这种扩展形式类似于:

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

希望这有帮助

答案 1 :(得分:3)

我真正需要的是:

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

它几乎是克里斯·艾尔玛(Chris Eelmaa)所建议的,但有了这个建议,我最终得到了static public void Main,这是有效的,但很难看。

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

答案 2 :(得分:1)

好吧,要创建一个表示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);

无效。