2014-10-27 54 views
3

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

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

翻译成

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

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

+2

为什么你想这样做?你有什么尝试? – svick 2014-10-27 11:22:43

+0

原因:用C#子集编写的程序以不同的语法翻译成任意语言。我知道如何修改树,我不知道如何控制令牌表示输出。 – tomash 2014-10-27 11:45:17

回答

6

我不知道这会如何工作,但您可以用另一个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遍历整个树并将其复制到您的输出文件,除了是关键字标记的元素。

1

只为记录 - 下面的代码也工作,但接受的答案更优雅。

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); 
    } 

}