【问题标题】:How to replace C# keywords with string subsitutes using Roslyn?如何使用 Roslyn 用字符串替换替换 C# 关键字?
【发布时间】:2014-12-22 12:45:40
【问题描述】:

我想使用 Roslyn 加载 C# 源代码并将其写入另一个文件,将关键字替换为替代项。示例:

for (int i=0; i<10; i++){}

翻译成

foobar (int i=0; i<10; i++){}

这种操作的语法是什么样的?

【问题讨论】:

  • 你为什么要这样做?你试过什么?
  • 原因:将用 C# 子集编写的程序翻译成具有不同语法的任意语言。我知道如何修改树,我不知道如何控制令牌表示输出。

标签: c# code-generation abstract-syntax-tree roslyn


【解决方案1】:

我不知道这将如何运作,但您可以将每个 ForKeyword 令牌替换为另一个 ForKeyword 令牌,但这次使用您的自定义文本。为此,您可以使用CSharpSyntaxRewriter:

class KeywordRewriter : CSharpSyntaxRewriter
{
    public override SyntaxToken VisitToken(SyntaxToken token)
    {
        if (token.Kind() == SyntaxKind.ForKeyword)
        {
            return SyntaxFactory.Token(
                token.LeadingTrivia, SyntaxKind.ForKeyword, "foobar", "foobar",
                token.TrailingTrivia);
        }

        return token;
    }
}

使用此重写器,您可以编写如下代码:

string code = "for (int i=0; i<10; i++){}";

var statement = SyntaxFactory.ParseStatement(code);

var rewrittenStatement = new KeywordRewriter().Visit(statement);

Console.WriteLine(rewrittenStatement);

打印你想要的:

foobar (int i=0; i<10; i++){}

【讨论】:

    【解决方案2】:

    您需要考虑创建一个SyntaxWalker,它遍历整个树并将其复制到您的输出文件中,关键字标记元素除外。

    【讨论】:

      【解决方案3】:

      仅作记录 - 以下代码也有效,但接受的答案更加优雅。

      foreach (var t in tree.GetCompilationUnitRoot().DescendantTokens())
      {
      
          if (t.HasLeadingTrivia)
          {
              file.Write(t.LeadingTrivia);
          }
      
          file.Write(t.IsKind(SyntaxKind.ForKeyword)? "foobar" : t.ToString());
      
          if (t.HasTrailingTrivia)
          {
              file.Write(t.TrailingTrivia);
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 2014-09-13
        • 1970-01-01
        • 2014-10-07
        • 1970-01-01
        • 2013-08-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-24
        相关资源
        最近更新 更多