简体   繁体   中英

Roslyn CodeFixProvider add attribute to the method

I'm building CodeFixProvider for the analyzer that is detecting if custom attribute is missing from the method declaration. Basically custom attribute that should be added to the method looks like

    [CustomAttribute(param1: false, param2: new int[]{1,2,3})]

this is what I've got so far:

    public sealed override async Task RegisterCodeFixesAsync( CodeFixContext context ) {
        var root = await context.Document.GetSyntaxRootAsync( context.CancellationToken ).ConfigureAwait( false );

        var diagnostic = context.Diagnostics.First();
        var diagnosticSpan = diagnostic.Location.SourceSpan;
        var declaration = root.FindToken( diagnosticSpan.Start ).Parent.AncestorsAndSelf( ).OfType<MethodDeclarationSyntax>( ).First( );

        context.RegisterCodeFix(
            CodeAction.Create(
                title: title,
                createChangedSolution: c => this.AddCustomAttribute(context.Document, declaration, c),
                equivalenceKey: title),
            diagnostic);
    }

    private async Task<Solution> AddCustomAttribute( Document document, MethodDeclarationSyntax methodDeclaration, CancellationToken cancellationToken ) {
        // I suspect I need to do something like methodDeclaration.AddAttributeLists(new AttributeListSyntax[] {
        // but not sure how to use it exactly

        throw new NotImplementedException( );
    }

Remember, roslyn syntax trees are immutable. You'll need something like:

private async Task<Solution> AddCustomAttribute(Document document, MethodDeclarationSyntax methodDeclaration, CancellationToken cancellationToken)
{
    var root = await document.GetSyntaxRootAsync(cancellationToken);
    var attributes = methodDeclaration.AttributeLists.Add(
        SyntaxFactory.AttributeList(SyntaxFactory.SingletonSeparatedList<AttributeSyntax>(
            SyntaxFactory.Attribute(SyntaxFactory.IdentifierName("CustomAttribute"))
            //  .WithArgumentList(...)
        )).NormalizeWhitespace());

    return document.WithSyntaxRoot(
        root.ReplaceNode(
            methodDeclaration,
            methodDeclaration.WithAttributeLists(attributes)
        )).Project.Solution;
}

To get the full SyntaxFactory code for the attribute constructor .WithArgumentList() throw it into the Roslyn Quoter .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM