重写 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());
我想编写一种方法来确保我的树中的所有 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());