[英]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.