问题
As we all know Roslyn Syntax Trees are Immutable, so after making changes you need to get a new node.
I'm trying to update a document using the document editor, but I keep getting an error that the node is not found in the syntax tree.
public static T FindEquivalentNode<T>(this Document newDocument, T node)
where T : CSharpSyntaxNode
{
var root = newDocument.GetSyntaxRootAsync().Result;
return root.DescendantNodes().OfType<T>()
.FirstOrDefault(newNode => SyntaxFactory.AreEquivalent(newNode, node));
}
When I try to Call this again the document editor:
var newFieldDeclaration = documentEditor.GetChangedDocument().FindEquivalentNode(syntaxNode);
documentEditor.ReplaceNode(newFieldDeclaration, propertyDeclaration);
I get an error:
The node is not part of the tree
The newField Declaration is not null it find an equivalent field yet I still get this error, How Can I Replace this node?
回答1:
You get the node because in your FindEquivalentNode
method, you are doing that:
SyntaxFactory.AreEquivalent(newNode, node)
SyntaxFactory.AreEquivalent
is not return true for "real" same nodes, but for nodes\tokens that are seems equal in their structure (with consideration of topLevel
parameter).
Back to your question, if you want to call ReplaceNode
you must have the "real" old node, so you wouldn't get an
The node is not part of the tree
To achive that, you have a few options, one of them is what @Tamas wrote in comments, use SyntaxAnnotations
.
Example:
//Add annotation to node
var annotation = new SyntaxAnnotation("your_annotation", "some_data");
node = node .WithAdditionalAnnotations(annotation);
// Now you can change the tree as much you want
// And when you want to get the node from the changed tree
var annotatedNode = someNode.DescendantNodesAndSelf().
FirstOrDefault(n => n.GetAnnotations("your_annotation").Any())
来源:https://stackoverflow.com/questions/44208171/roslyn-find-same-node-in-changed-document