2017-05-26 3 views
0

Roslyn Syntax Treesは変更不可能なので、変更後は新しいノードを取得する必要があります。Roslyn変更された文書内で同じノードを見つける

ドキュメントエディタを使用してドキュメントを更新しようとしていますが、ノードが構文ツリーに見つからないというエラーが発生し続けます。

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)); 
} 

私は文書エディタ再びこれを呼び出そう:

var newFieldDeclaration = documentEditor.GetChangedDocument().FindEquivalentNode(syntaxNode); 
documentEditor.ReplaceNode(newFieldDeclaration, propertyDeclaration); 

私はエラーを取得する:

The node is not part of the tree

ニューフィールド宣言はまだそれが同等のフィールドを見つけるnullでない私はこのエラーは、このノードを置き換えることはできますか?

+0

あなたはツリーを変更し、元の木にあなたが置か何か(た)を見つけようとしていますか?そうであれば、新しいSyntaxAnnotation()をノードに追加して、変更されたツリー内の注釈の同じインスタンスを見つけることができます。以下の例を参照してください:https://github.com/SonarSource/sonar-csharp/blob/63c661bde321a96ffcf9daca1aabac79e0f37929/sonaranalyzer-dotnet/src/SonarAnalyzer.CSharp/Rules/GenericReadonlyFieldPropertyAssignmentCodeFixProvider.cs#L130 – Tamas

+0

@Tamas特定のノードを見つける方法はありますか? –

+0

検索する構文ノードはどのように取得しましたか?あなたが変更したいツリーの一部ではありませんか?はいの場合は、上記の動作します。そうでない場合は、['SyntaxFactory.AreEquivalent'](http://source.roslyn.codeplex.com/#Microsoft.CodeAnalysis.CSharp/Syntax/SyntaxFactory.cs,84069a73c6b638c2)を使用することができます。しかし、私はあなたが変更したいsytaxツリーを持つドキュメントを持っている必要があるので、後者の解決法はめったに必要ではないと言います。 – Tamas

答えて

1

あなたFindEquivalentNode方法では、あなたがそれをやっているので、あなたはノードを取得します:

SyntaxFactory.AreEquivalent(newNode, node) 

SyntaxFactory.AreEquivalentは「本物」同じノードのための、しかしノードに対してtrueを返すではありません\その構造に等しい思われるトークン(topLevelパラメータを考慮して)。戻るあなたの質問に

、あなたがReplaceNodeを呼び出したい場合は、

The node is not part of the tree

あなたはいくつかのオプションを持っている、ということachiveするには、Getないようにあなたは、一つの「本当の」古いノードを持っている必要がありますそれらのうち@Tamasがコメントに書いたものはSyntaxAnnotationsです。

例:

//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()) 
関連する問題