正如您可能已经猜到的,我正在学习有关roslyn的所有知识,尤其是作为一名代码分析器。
语法高亮显示非常有效。然而,以下是我的代码操作,在删除节点时会无声地失败:
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);
}
主题:
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
FruitMix fm = new FruitMix(); //This is the matched node
}
}
}
我觉得我错过了如何与Roslyn合作的"大局",所以尽管这里的帮助会很神奇,但我也很喜欢一些能帮助我的链接/资源。
我在这里上传了这个项目,虽然不是一个"最小"的例子,但它很容易重现这个问题。上面的代码在CodeFixProvider.cs
中。
感谢
当我在启用break-on-all exceptions thrown的情况下运行代码时,我可以看到它将ArgumentNullException
深入到RemoveNode()
内部的调用堆栈中,特别是在SyntaxFactory.LocalDeclarationStatement()
中。
该异常令人困惑(GitHub上已经报道过),但实际上是您的错误:您正试图从其父级LocalDeclarationStatementSyntax
中删除VariableDeclarationSyntax
(其语法类似于LocalDeclarationStatement:const
?VariableDeclaration;
)。由于没有VariableDeclarationSyntax
的LocalDeclarationStatementSyntax
是无效的,因此会得到异常。
最简单的修复方法是只删除父LocalDeclarationStatementSyntax
:
SyntaxNode newRoot = oldRoot.RemoveNode(oldNode.Single().Parent, SyntaxRemoveOptions.KeepNoTrivia);