2

Roslyn を使用して 2 つの C# ファイルの内容をマージしようとしています。古いバージョンの特定のメソッド (更新用にマークされている) を新しいものに置き換える必要があります。両方のドキュメントのすべてのメンバーを調べ、変更が必要なメソッドをリストにマークしました。

class Token
{
    public string Name;  // unique identifier
    public SyntaxNode Node;  // actual node in the document
}

これで、OldTokens と NewTokens という 2 つのトークン リストができました。古いメソッドを対応する新しいメソッドで上書きする必要があります。

foreach (Token oldt in OldTokens)
{
    Token newt = NewTokens.Find(m => m.Name == oldt.Name);
    if (newt != null)
    {
        DocumentRoot = DocumentRoot.ReplaceNode(oldt.Node, newt.Node);
    }
}

うまくいきませんでした。名前空間->クラス->メンバーの階層の奥深くに表示されるため、DocumentRootが直接のメンバーリストに古いノードを保持していないためだと思いました。だから私は次のようなものを試しました:

var nd = existing.Node.Parent.ReplaceNode(existing.Node, miss.Node);
var d2 = existing.Node.Parent.Parent.ReplaceNode(existing.Node.Parent, nd);
DocumentRoot = existing.Node.Parent.Parent.Parent.ReplaceNode(existing.Node.Parent.Parent, d2) as CompilationUnitSyntax;

これは機能していますが、処理が難しすぎます。ネストされたクラスが存在すると、混乱します。より良い方法はありますか?

第二に、結果として、コード コメントがありません。ReplaceNode メソッドのオーバーロードを試してみましたが、新しいメソッド ノードを使用しないため、かなり混乱します。

ありがとう

4

1 に答える 1

1

RoslynSyntaxNodeオブジェクトは不変であるため、"ReplaceNode" を呼び出すたびに、まったく新しいツリーが返されます。この問題を解決する通常の方法は、SyntaxAnnotation置き換えたい各ノードに a を追加することです。これは、ノード自体が置き換えられない限り、ツリー変換によって保持される安定したマーカーです。

SyntaxRewriterまたは、このようにファイルに多くの変更を加える場合は、何度も呼び出すのではなく、を実装することを検討できますReplaceNodeSyntaxRewriterはツリーをボトムアップで訪問するため、メソッドに渡されるノードは常に元のSyntaxTree. ただし、base.Visit()オーバーライドするメソッドを最初に呼び出して結果を使用し、現在のノードの子孫であるすべてのノードの更新されたバージョンを取得するようにしてください。

最後に、コメントに関しては、保持するために、置き換えるノードからトリビア ( GetLeadingTrivia()/ ) をコピーする必要があります。GetTrailingTrivia()

于 2013-08-19T15:21:44.290 に答える