重写 if 语句:其中一个语句以一对太多的大括号结束

Re-writing if-statements: One of these statements ended up with one too many pair of braces

我想编写一种方法来确保我的树中的所有 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,要么使用 "manually"。现在你正在做这两件事:首先你调用重写器,然后循环遍历它的所有节点并在每个 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());