简体   繁体   中英

Code Analyzer - removing a node fails without exception

As you may have guessed I'm learning all about roslyn, particularly as a code analyzer.

Syntax highlighting is working perfectly. However the following - which is my code action - fails silently when removing the node:

    private async Task<Document> RemoveNode(Document document, LocalDeclarationStatementSyntax typeDecl, CancellationToken cancellationToken)
    {
        IEnumerable<SyntaxNode> oldNode = typeDecl.DescendantNodes().OfType<VariableDeclarationSyntax>();

        SyntaxNode oldRoot = await document.GetSyntaxRootAsync(cancellationToken);

        SyntaxNode newRoot = oldRoot.RemoveNode(oldNode.Single(), SyntaxRemoveOptions.KeepNoTrivia); //Analyzer fails here

        return document.WithSyntaxRoot(newRoot);
    }

Subject:

namespace ConsoleApplication3
{
    class Program
    {
        static void Main(string[] args)
        {
            FruitMix fm = new FruitMix(); //This is the matched node
        }
    }
}

I feel like I'm missing the 'bigger' picture with how to work with Roslyn, so although help here would be amazing I'd also love some links / resources that'll help me.

I've uploaded this project here although not a 'minimial' example it will readily reproduce the problem. The code above is in CodeFixProvider.cs .

Thanks

When I run your code with break on all exceptions thrown enabled, I can see that it throws ArgumentNullException deep in the call stack inside RemoveNode() , specifically in SyntaxFactory.LocalDeclarationStatement() .

The exception is confusing (which is already reported on GitHub ), but it is actually your error: you're trying to remove VariableDeclarationSyntax from its parent, which is LocalDeclarationStatementSyntax (the syntax for that would be something like LocalDeclarationStatement : const ? VariableDeclaration ; ). And since LocalDeclarationStatementSyntax without VariableDeclarationSyntax is not valid, you get the exception.

The simplest fix is to just remove the parent LocalDeclarationStatementSyntax :

SyntaxNode newRoot = oldRoot.RemoveNode(oldNode.Single().Parent, SyntaxRemoveOptions.KeepNoTrivia);

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