簡體   English   中英

使用Roslyn更改語法標記

[英]Changing syntax token with Roslyn

我正在嘗試用Roslyn重寫代碼。 我想將GreaterThanToken更改為EqualsEqualsToken。 到目前為止,這是我的代碼:

ToParse.cs:

public class ToParse
{
    public bool MethodToConvert(int param)
    {
        return (1 > param);
    }
}

Program.cs中:

class Rewriter : SyntaxRewriter
{
    private readonly SyntaxKind _replace;
    private readonly SyntaxKind _replacewith;
    public Rewriter(SyntaxKind replace, SyntaxKind replacewith)
    {
        _replace = replace;
        _replacewith = replacewith;
    }

    public override SyntaxToken VisitToken(SyntaxToken token)
    {
        if (token.Kind != _replace)
            return token;

        return Syntax.Token(_replacewith);
    }
}

用法:

var code = new StreamReader("ToParse.cs").ReadToEnd();
var tree = SyntaxTree.ParseText(code);
var root = tree.GetRoot();
var rewriter = new Rewriter(SyntaxKind.GreaterThanToken, SyntaxKind.EqualsEqualsToken);
var newRoot = rewriter.Visit(root);

var newTree = SyntaxTree.Create((CompilationUnitSyntax)newRoot);
var compilation = Compilation.Create("TestAssembly.dll", 
      new CompilationOptions(OutputKind.DynamicallyLinkedLibrary),
      references: new[]{ new MetadataFileReference(typeof(object).Assembly.Location)},
      syntaxTrees: new[] { newTree });
Console.WriteLine(newTree);
EmitResult res;

using (var file = new FileStream("e:\\TestAssembly.dll", FileMode.Create))
   res = compilation.Emit(file);

執行后,Console.WriteLine打印更改的令牌return (1 == param); 但是當我用ilspy打開testassembly.dll時,我仍然看到return 1 > param; 有什么建議?

[注意:你使用的是較舊版本的Roslyn。 這個答案也適用於該版本,但我可以通過更新的名稱引用類和成員,以便它們與CodePlex上可用的源匹配。

您已解析的原始樹包含BinaryExpressionSyntax節點,其SyntaxKindGreaterThanExpression 當你換出GreaterThanTokenEqualsEqualsToken這里面BinaryExpressionSyntax ,它不會自動調整包含SyntaxNode實物 EqualsExpression

因此,您最終會得到一個帶有EqualsEqualsTokenGreaterThanExpression 由於這不是編譯器本身可以合法生成的語法樹,因此您可能會看到類似的意外行為。

要在這種情況下生成正確的樹,我建議通過重寫CSharpSyntaxRewriter.VisitBinaryExpression並執行以下操作來重寫節點本身而不是令牌:

public override SyntaxNode VisitBinaryExpression(BinaryExpressionSyntax node)
{
    if (node.CSharpKind() == SyntaxKind.GreaterThanExpression)
    {
        return SyntaxFactory.BinaryExpression(SyntaxKind.EqualsExpression, node.Left, node.Right);
    }

    return node;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM