RoSlyn Code Fix Provider APIを使用して文書からSyntaxNodeのリストを削除する方法 -- c# フィールド と visual-studio-2013 フィールド と roslyn フィールド と vsix フィールド 関連 問題

How to remove a list of SyntaxNode from the Document using Roslyn code fix provider APIs?












2
vote

問題

日本語

SyntaxFactory.VariableDeclaration を使用してカスタム生成された変数宣言と、いくつかの条件に従って収集された<コード> SyntaxNode のリストを使用しています。

私は次のようにしました:

  1. ノードを変更する

    <事前> <コード> var newRoot = root.ReplaceNode(expression, newVariableDeclaration)

    これは newVariableDeclaration を持つノードを正常に変更しました。

  2. ループ内のリストに存在するものに対応するノードを削除する

    <事前> <コード> foreach (var listObject in listObjects) { newRoot = newRoot.RemoveNode(listObject, SyntaxRemoveOptions.KeepNoTrivia); }

    これは newRoot を変更していません、変更されるべきすべての listObject は同じままです。

  3. <コード> root.RemoveNode(listObject, SyntaxRemoveOptions.KeepNoTrivia) を使用した場合は、明らかに、前の変更を置き換え続けます。

    だからここで newVariableDeclaration は、文書全体のに変更されたのみノードです。 newRoot <コード> SyntaxNode0 SyntaxNode2 から取得した SyntaxNode1 の変更点数。

    私が間違っているなら私を修正してください。

    編集: 私は SyntaxNode3 に見えましたが、ノードを訪問するたびに単一のノードを分析しており、一度に単一のノードを変更できます。私のシナリオでは、特定のノードを訪問し、それを変更し、訪問されたノードに加えられた変更に関して他のノードを削除する必要があります。

英語

I'm having a custom generated variable declaration using SyntaxFactory.VariableDeclaration and a list of SyntaxNode's collected according to some conditions.

I did the following:

  1. Modify the node

    var newRoot = root.ReplaceNode(expression, newVariableDeclaration) 

    This successfully modified the node with the newVariableDeclaration.

  2. In a loop remove the nodes corresponding to the ones present in the list

    foreach (var listObject in listObjects) {     newRoot = newRoot.RemoveNode(listObject, SyntaxRemoveOptions.KeepNoTrivia); } 

    This doesn't change the newRoot and all the listObject required to be changed remains the same.

If we use root.RemoveNode(listObject, SyntaxRemoveOptions.KeepNoTrivia) instead it will, obviously, keep on replacing the previous changes.

So here the newVariableDeclaration is the only node that is changed in the whole document, is this because newRoot SyntaxNodes have changes from that of the SyntaxNode that I obtained from root.

Please correct me if I'm doing it wrong.

EDIT: I looked into CSharpSyntaxRewriter but it appears that it is analyzing a single node everytime it's visiting a node and can only modify a single node at a time. In my scenario, I'll have to visit a particular node, make changes to it, and remove other nodes with respect to the changes made to visited node.

</div
           

回答リスト

2
 
vote

あなたのアプローチの問題は、ツリーを変更するたびに(<コード> ReplaceNode() または<コード> RemoveNode() を使用して)、それはすべてのノードも変わることを意味します。これが、 RemoveNode() へのコール<コード> ReplaceNode()

を行っていない理由です。

これを修正する1つの方法は、 TrackNodes() を使用することです。そのため、修正ツリー内のどのノードが元のツリーのノードに対応するかを確認できるようにすることができます。

uisngこれは、単一のノードと一連のノードを置き換えるメソッドがこのようになる可能性があります。

<事前> <コード> public static T ReplaceNodes<T>( this T root, IReadOnlyList<SyntaxNode> oldNodes, SyntaxNode newNode) where T : SyntaxNode { if (oldNodes.Count == 0) throw new ArgumentException(); var newRoot = root.TrackNodes(oldNodes); var first = newRoot.GetCurrentNode(oldNodes[0]); newRoot = newRoot.ReplaceNode(first, newNode); var toRemove = oldNodes.Skip(1).Select(newRoot.GetCurrentNode); newRoot = newRoot.RemoveNodes(toRemove, SyntaxRemoveOptions.KeepNoTrivia); return newRoot; }
 

The problem with your approach is that whenever you change the tree (using ReplaceNode() or RemoveNode()), it means all the nodes change as well. This is why your calls to RemoveNode() after ReplaceNode() don't do anything.

One way to fix this is to use TrackNodes(), so that you can find which nodes in the modified tree correspond to nodes in the original tree.

Uisng this, a method that replaces a sequence of nodes with a single node could look like this:

public static T ReplaceNodes<T>(     this T root, IReadOnlyList<SyntaxNode> oldNodes, SyntaxNode newNode)     where T : SyntaxNode {     if (oldNodes.Count == 0)         throw new ArgumentException();      var newRoot = root.TrackNodes(oldNodes);      var first = newRoot.GetCurrentNode(oldNodes[0]);      newRoot = newRoot.ReplaceNode(first, newNode);      var toRemove = oldNodes.Skip(1).Select(newRoot.GetCurrentNode);      newRoot = newRoot.RemoveNodes(toRemove, SyntaxRemoveOptions.KeepNoTrivia);      return newRoot; } 
</div
 
 

関連する質問

1  現在のズームレベルに従ってWPFマージンをレンダリングします  ( Render wpf margin according to current zoom level ) 
私は使用してカスタムマージンを持つVisual Studioの拡張を開発しました <コード> IWpfTextViewMargin 。私はライン番号に対してこの余白にいくつかのグリフをレンダリングします。 通常のシナリオ: 100%ズームレベルでVisual...

2  Process Attachの後に機能しないキーボードショートカット(デバッグ中のVisual Studio 2013バグ)  ( Keyboard shortcuts not working after process attach visual studio 2013 bug duri ) 
私はデバッガを特定のプロセスに添付することができる小さなVSIXプラグインを書きました。このプロセスはC#とC ++コードを使用して書かれているので、管理対象エンジンとネイティブエンジンの両方を使用して添付する必要があります。 Visual Studioから、...

0  vsixを使用して、サーバーリストにローカルNUGETサーバーを追加します  ( Add local nuget server to server list with vsix ) 
NUGETサーバのリストにローカルNUGETサーバを追加するVisual Studio Extension(.vsix)を提供します。これは可能ですか? .vsix?でVisual Studioオプションを変更する一般的な方法はありますか? あなたの回答のた...

8  Window8デスクトップのVisual Studio Express 2012の拡張機能を追加する  ( Adding extensions in visual studio express 2012 for window8 desktop ) 
VS2012 Express EditionがNUGETパッケージをサポートするようになることを認識しています。 VS Express Edition 2012のRESHARPERやRFECTERのような生産性ツールの追加の制限が変更されましたか?私は制限事...

1  VSPACKAGEを追加せずにVSIX拡張子にオプションメニューを追加できますか?  ( Can i add an options menu to my vsix extension without adding a vspackage ) 
私は非常に軽量の視覚的スタジオ拡張を持っています。現在、マウスプロセッサとキーボードプロセッサと1つのクラスファイル、vSixManifest、および必要な2つのアイコンです。 ツール&gtで簡単なメニューを追加したいです。オプション。オン/オフを切り替えるた...

5  Visual Studio 2010 Extension - ドキュメント上にInfobarを表示  ( Visual studio 2010 extension show infobar on top of document ) 
Visual Studio 2015から、extensions SDKはドキュメントウィンドウの上にINFOBARを表示することをサポートしています。 https://msdn.microsoft.com/en-us/library/mt300796.asp...

0  VSIXにフォルダ全体を含める  ( Include whole folder in vsix ) 
VSIXパッケージのコンテンツとしてフォルダ全体を含める簡単な方法はありますか?願っていけば、各ファイルの「include」フラグを別々に設定すること以上の方法があります。 これを必要とする理由は、コンパイル済みのHTMLヘルプページ(多くの依存ファイルを持...

0  VSIX:参照を取得/追加/削除します  ( Vsix get add remove references ) 
選択したプロジェクトの参照を一覧表示する方法そしてディスク上のDLLへの新しい参照を追加しますか? ...

5  マルチプロジェクトソリューションテンプレート  ( Multi project solution template ) 
Webアプリケーション、デスクトップ、いくつかのクラスライブラリ、および単体テストプロジェクトを持つマルチプロジェクトソリューションテンプレートを作成するプロセス。 基本コンテナを構築し、それをVSIXコンテナとして梱包しました。 VSIXコンテナをインスト...

0  Visual Studio Editorウィンドウを盗むフォーカス  ( Visual studio editor window stealing focus ) 
私はVisual Studioの拡張機能に取り組んでいます。テキストボックスである単一のアイテムを持つWPFウィンドウを開くコマンドがあります。テキストボックスを入力すると、テキストが表示されますが、Ctrl + Aなどのキーの組み合わせがヒットした場合、私の...




© 2022 cndgn.com All Rights Reserved. Q&Aハウス 全著作権所有