我想编写一个方法来确保树中的所有 if 语句后面都跟着大括号代码块。这是我的代码:
class Program
{
static void Main(string[] args)
{
var tree = CSharpSyntaxTree.ParseText(@"
class Program
{
static void main()
{
if(true)
Console.WriteLine(""It was true!"");
if(false)
Console.WriteLine(""It was false!"");
}
}");
var root = tree.GetRoot();
var rewriter = new MyRewriter();
var newRoot = rewriter.Visit(root);
var ifStatements = newRoot.DescendantNodes().OfType<IfStatementSyntax>();
foreach (var ifStatement in ifStatements)
{
SyntaxNode newIfStatement = rewriter.VisitIfStatement(ifStatement);
newRoot = newRoot.ReplaceNode(ifStatement, newIfStatement);
}
var result = newRoot;
Console.WriteLine(result.ToString());
Console.ReadKey();
}
}
public class MyRewriter: CSharpSyntaxRewriter
{
public override SyntaxNode VisitIfStatement(IfStatementSyntax node)
{
var body = node.Statement;
var block = SyntaxFactory.Block(body);
var newIfStatement = node.WithStatement(block);
return newIfStatement;
}
}
这是我的输出:
class Program { static void main() { if(true) {{
Console.WriteL ine("It was true!"); }}
if(false) {
Console.WriteLi ne("It was false!"); }
} }
如您所见,第一个 if 语句后面的代码块被括起来两次(不是如预期的那样),而第二个 if 语句后面的代码块仅被括起来一次(如预期的那样) )。
我确信我对 Roslyn 的工作原理有一些错误的假设,所以有人可以告诉我哪里出了问题吗?我应该做出哪些改变?
最佳答案
您正在混合两件事:要么使用SyntaxRewriter
,要么“手动”执行。现在您正在执行这两件事:首先调用重写器,然后循环遍历其所有节点并在每个 IfStatementSyntax
上再次调用重写器。
修复所有
if
语句:var newRoot = rewriter.Visit(root);
手动替换所有
if
语句:
var ifStatements = newRoot.DescendantNodes().OfType<IfStatementSyntax>();
foreach (var ifStatement in ifStatements)
{
SyntaxNode newIfStatement = rewriter.VisitIfStatement(ifStatement);
newRoot = newRoot.ReplaceNode(ifStatement, newIfStatement);
}
您可以完全省略循环:这具体是 SyntaxRewriter
的任务。
Why did only the first statement get two braces?
例如,应通过 DocumentEditor
对树进行多次修改。第一次替换后,ifStatements
集合中的第二个 IfStatementSyntax
与您因第一次替换而收到的新创建的语法树不同步。由于不同步,原始 ifStatementSyntax
的位置现在位于新创建的树中的不同位置(已添加括号 --> 根据应用的格式,这会移动所有字符至少一个位置)。
结果:第一次替换成功,第二次替换失败(静默)。
进一步说明:通过向添加的节点添加 Formatter
注解并随后调用 Formatter.Format
来应用格式化,如下所示:
var newRoot = rewriter.Visit(root).WithAdditionalAnnotations(Formatter.Annotation);
var result = Formatter.Format(newRoot, Formatter.Annotation, new AdhocWorkspace());
关于c# - 重写if语句: One of these statements ended up with one too many pair of braces,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34772602/