gpt4 book ai didi

c# - 使用 Roslyn 更改语法标记

转载 作者:行者123 更新时间:2023-11-30 14:30:04 26 4
gpt4 key购买 nike

我正在尝试使用 Roslyn 重写代码。我想将 GreaterThanToken 更改为 EqualsEqualsToken。到目前为止,这是我的代码:

ToParse.cs:

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

程序.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 .当您将 GreaterThanToken 换成 EqualsEqualsToken 时在此 BinaryExpressionSyntax 中,它不会自动将包含 SyntaxNodekind 调整为 EqualsExpression

因此,您最终得到一个带有 EqualsEqualsTokenGreaterThanExpression。由于这不是编译器本身可以合法生成的语法树,您可能会看到这样的意外行为。

为了在这种情况下生成正确的树,我建议通过覆盖 CSharpSyntaxRewriter.VisitBinaryExpression 来重写节点本身而不是 token 。并做这样的事情:

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

return node;
}

关于c# - 使用 Roslyn 更改语法标记,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24433355/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com