在使用 Roslyn 时,我经常会有一个节点位于 CompilationUnitSyntax 中,但不在 SemanticModel 中,反之亦然。(或者我只能通过一个或另一个操作拉出节点——例如,如果您需要来自语义模型的类型信息,则查询的节点必须存在于 SemanticModel 的树中)
我可以看到他们为什么这样做是为了不变性以及所有这些,但是你到底是如何始终返回并从一棵树到另一棵树找到相同的标记?如果修改任一树,则必须以某种方式检索正在使用的节点。最好的方法是什么????
如果要在更改树时跟踪单个语法节点,可以使用SyntaxAnnotation
.
要使用它,请创建一个新的SyntaxAnnotation
(或自定义派生类型,如果您需要使用该注释保留一些附加信息),然后通过调用annotation.AddAnnotationTo(node)
或将其添加到节点node.WithAdditionalAnnotations(annotation)
。请记住,该节点仍然是不可变的,因此您需要将原始节点替换为树中带注释的节点。
然后,在对树进行一些修改后,您可以使用类似parentNode.GetAnnotatedNodesAndTokens(annotation).Single().AsNode()
. (您还可以通过 获取由特定派生类型注释注释的所有节点parentNode.GetAnnotatedNodesAndTokens(typeof(CustomAnnotationType))
。)