使用Roslyn codefix

时间:2016-08-31 15:45:16

标签: c# roslyn

我正在使用Roslyn创建一个分析器,将postsharp [NotNull]属性添加到方法参数中。

private async Task<Document> MakeNotNullAsync(Document document, MethodDeclarationSyntax method, CancellationToken cancellationToken, string paramName)
    {

        var parameters = method.ChildNodes().OfType<ParameterListSyntax>().First();
        var param = parameters.ChildNodes().OfType<ParameterSyntax>().First() as SyntaxNode;



        NameSyntax name = SyntaxFactory.ParseName("NotNull");
        AttributeSyntax attribute = SyntaxFactory.Attribute(name, null);
        Collection<AttributeSyntax> list = new Collection<AttributeSyntax>();
        list.Add(attribute);
        var separatedlist = SyntaxFactory.SeparatedList(list);
        var newLiteral = SyntaxFactory.AttributeList(separatedlist);
        Collection<SyntaxNode> synlist = new Collection<SyntaxNode>();
        synlist.Add(newLiteral);

        var root = await document.GetSyntaxRootAsync();
        var newRoot = root.InsertNodesBefore(param, synlist);
        var newDocument = document.WithSyntaxRoot(newRoot);
        return newDocument;

这是我到目前为止所做的(并且肯定有一种更简单的方法)但是当我尝试执行root.InsertNodesBefore()时,我得到一个'System.InvalidCastException'。有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

我通常发现使用ReplaceNode更容易。在您的情况下,您只需将param替换为具有新属性的(WithAttributeLists):

var attribute = SyntaxFactory.AttributeList(
    SyntaxFactory.SingletonSeparatedList<AttributeSyntax>(
        SyntaxFactory.Attribute(SyntaxFactory.IdentifierName("NotNull"), null)));
var newParam = param.WithAttributeLists(param.AttributeLists.Add(attribute));

var root = await document.GetSyntaxRootAsync();
var newRoot = root.ReplaceNode(param, newParam);    
var newDocument = document.WithSyntaxRoot(newRoot);
return newDocument;

请注意,这也会处理param具有现有属性的情况。