【问题标题】:Creating BlockSyntax from string (Roslyn)从字符串创建 BlockSyntax (Roslyn)
【发布时间】:2017-12-29 06:53:42
【问题描述】:

我有一些带有源代码的字符串,例如

var newSource = @"
int a = 5;
int b = 10;
Console.WriteLine(a + b);";

我尝试使用已解析的代码创建 BlockSyntax 对象

var newTokens = SyntaxFactory.ParseTokens(newSource);
var newBody = SyntaxFactory.Block();
newBody = newBody.InsertTokensAfter(
  newBody.OpenBraceToken, // or newBody.ChildTokens().First()
  newTokens
);

但是方法 InsertTokenAfter 会抛出 System.InvalidOperationException '指定的项目不是列表的元素。'

据我了解,该方法在 ChildTokens() 中找不到令牌,但是为什么会发生呢?

.NET Core 1.0.4

【问题讨论】:

    标签: c# .net-core roslyn


    【解决方案1】:

    InsertTokensAfter 方法不适用于添加语句。它只允许您在现有的标记列表中插入标记(这是在 C# 语法树中仅出现在声明的修饰符列表中的特定构造)。

    语句是节点。您可以使用 InsertNodesAfter 在语句列表中插入一个或多个节点,但您必须在列表中已有一个现有的语句节点才能执行此操作,并且在您的示例中,您有一个尚未包含任何语句的空块。

    如果你有一个语句列表,你可以使用 block.WithStatements() 方法,直接向它传递一个语句列表。不幸的是,没有 SyntaxFactory.ParseStatementList 方法。

    但是,有一个 SyntaxFactory.ParseStatement 方法,但它只解析一个语句。幸运的是,块是一个语句。因此,您只需在语句的源代码周围添加一对大括号,并将其解析为一个块。

    var block = (BlockSyntax)SyntaxFactory.ParseStatement("{" + newSource + "}");
    

    【讨论】:

      【解决方案2】:

      在调试过程中你可以找到一个类

      public abstract partial class CodeFixVerifier : DiagnosticVerifier
      

      在 TestHelper 命名空间中。您的代码在 ApplyFix(Document document, CodeAction codeAction) 方法中失败。我假设线索在文档参数中:应该对文档应用更改,但您的 newBody 尚未附加。

      如果您对修复代码感兴趣 - 您可以应用类似的代码

      StatementSyntax newTokens = SyntaxFactory.ParseStatement(newSource);           
      BlockSyntax block = SyntaxFactory.Block(newTokens);
      

      【讨论】:

        猜你喜欢
        • 2012-07-11
        • 2012-11-27
        • 1970-01-01
        • 2021-12-01
        • 2012-11-07
        • 2012-04-03
        • 2011-05-13
        • 2012-09-25
        相关资源
        最近更新 更多