[英]Replacing multiple nodes in Roslyn syntax tree
我正在嘗試使用roslyn替換語法樹中的幾個節點。 但它的不變性質似乎妨礙了我。
public static string Rewrite(string content)
{
var tree = CSharpSyntaxTree.ParseText(content);
var root = tree.GetRoot();
var methods =root
.DescendantNodes(node=>true)
.OfType<MethodDeclarationSyntax>()
.ToList();
foreach(var method in methods)
{
var returnActions = method
.DescendantNodes(node => true)
.OfType<BinaryExpressionSyntax>()
//Ok this is cheating
.Where(node => node.OperatorToken.ValueText == "==")
.Where(node => node.Right.ToString() == "\"#exit#\"" || node.Right.ToString() == "\"#break#\"")
.Select(node => node.Parent as IfStatementSyntax)
.ToList();
var lookup = new Dictionary<StatementSyntax,StatementSyntax>();
if (returnActions.Count > 0)
{
foreach(var ifStatement in returnActions)
{
var mainCall = ifStatement.GetPrevious() as ExpressionStatementSyntax;
var newIfStatement = ifStatement.WithCondition(mainCall.Expression.WithoutTrivia());
lookup[mainCall] = null;
lookup[ifStatement] = newIfStatement;
}
//this only replace some of the nodes
root = root.ReplaceNodes(lookup.Keys, (s, d) => lookup[s]);
}
}
return root.ToFullString();
}
問題是,當我調用root.ReplaceNodes
只有部分節點被替換。
我想替換會更改樹,以便其他節點不再與原始樹匹配,因此無法替換。
但是解決這個問題的最佳方法是什么?
一遍又一遍地循環過程直到不再發生變化感覺跛腳:)
這些更改可以嵌套發生,我認為這就是導致問題的原因。 我可以以某種方式對變更集進行排序以解決這個問題,還是有一種慣用的方式來處理這里的事情?
我想替換會更改樹,以便其他節點不再與原始樹匹配,因此無法替換。
你是對的。 替換節點會創建全新的語法樹。 來自先前語法樹的節點無法與這些新語法樹進行比較。
將多個更改應用於語法樹有四種方法:
DocumentEditor
- 請參閱: https : //stackoverflow.com/a/30563669/300908 Annotations
(第236和240行) .TrackNodes()
CSharpSyntaxRewriter
,以自下而上的方式替換節點。 我在博客上寫過這篇文章 。 在這些選項中,我相信DocumentEditor
具有最容易使用的聲譽。 它很可能是未來應用多項更改的慣用方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.