gpt4 book ai didi

c# - 通过 roslyn 在语句后插入新表达式

转载 作者:太空狗 更新时间:2023-10-29 23:44:54 27 4
gpt4 key购买 nike

我在使用 Roslyn 向 SyntaxTree 添加表达式时遇到了一些问题。我需要实现以下目标:每当我发现一个特殊的语句时,我都想在这个语句之后插入一个或多个表达式。

假设我想在每个写入变量“testVar”的语句之后插入语句“myVar = myVar + 1”。

所以下面的片段:

 a = 10;
testVar = 50;
a = testVar / a;
testVar = a;

应该变成这段代码:

 a = 10;
testVar = 50;
myVar = myVar + 1;
a = testVar / a;
testVar = a;
myVar = myVar + 1;

我当前的方法使用带有方法“SyntaxNode VisitExpressionStatement(ExpressionStatement node)”的 SyntaxVisitor。此方法访问 SyntaxTree 中的所有表达式,并允许用它返回的 SyntaxNode 替换访问的表达式。但是,我不想替换 语句,而是在它们之后添加新的表达式,这基本上需要返回两个表达式。我发现的唯一解决方案是使用“BlockSyntax”作为两个表达式的容器(参见代码片段 [0])。不幸的是,“BlockSyntax”在其自身周围引入了大括号,这导致了以下结果:

 a = 10;
{
testVar = 50;
myVar = myVar + 1;
}
a = testVar / a;
{
testVar = a;
myVar = myVar + 1;
}

这种方法对我来说是 Not Acceptable ,因为我不想操纵范围。有什么方法可以使用 Roslyn 在我选择的位置插入任意表达式吗?

[0]

public SyntaxNode VisitExpressionStatement(ExpressionStatement node){
if(node has special characteristics){
var newExpression = ...

var newStatmentList = new Roslyn.Compilers.CSharp.SyntaxList<StatementSyntax>();
newStatmentList = newStatmentList.Insert(newStatmentList.Count, node);
newStatmentList = newStatmentList.Insert(newStatmentList.Count, newExpression);

BlockSyntax newBlock = Syntax.Block(newStatmentList);
return newBlock;

}
else {
return node;
}
}

最佳答案

我的策略是使用 BlockSyntax 作弊。看我的similar question .

所以我像您一样添加了 BlockSyntax,但随后我通过将 {} 标记标记为缺失来“删除”它们.我还没有遇到这种方法的任何问题,但它似乎更像是一种变通方法,而不是解决方案。

var statements = new SyntaxList<StatementSyntax>();
//Tried bundling newNode and invocation together
statements.Add(SyntaxFactory.ExpressionStatement(newNode));
statements.Add(SyntaxFactory.ExpressionStatement(invocation));
var wrapper = SyntaxFactory.Block(statements);

//Now we can remove the { and } braces
wrapper = wrapper.WithOpenBraceToken(SyntaxFactory.MissingToken(SyntaxKind.OpenBraceToken))
.WithCloseBraceToken(SyntaxFactory.MissingToken(SyntaxKind.CloseBraceToken));

请注意,我说的是“删除”它们。这里的问题是,您将生成的 SyntaxTree 仍然会出现在 C# 编译器中,就好像它在您放置它的位置有一个 BlockSyntax 一样。这可能重要也可能不重要。

例如:

  • 如果您将这棵树作为字符串输出到文件中,就没问题。

  • 如果您立即编译这棵树,我相信编译器会将 BlockSyntax 解释为您重写它的地方存在,并且所有范围语义仍将被强制执行,就好像它是那里。

有关生成“怪异”树的更多信息,请查看我的博客文章:Don't Trust SyntaxNode.ToFullString()

关于c# - 通过 roslyn 在语句后插入新表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30126323/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com