【问题标题】:Is it possible to modify a SyntaxTree in Roslyn and run the edited code?是否可以在 Roslyn 中修改 SyntaxTree 并运行编辑后的代码?
【发布时间】:2018-09-23 06:20:29
【问题描述】:

我正在使用 Roslyn 更改代码,但是,更改后会生成一个新的 SyntaxNode,但我无法找到执行此新代码的方法。我发现的唯一一个是从新的Root 中获取ToString 并使用新字符串调用EvaluateAsync。应该有一种方法可以超越它,因为我已经编译了一个新代码。

static void Main(string[] args)
{
    var expression = "System.Console.WriteLine(\"Test\")";
    var compile = CSharpScript.Create<EntityRepresentation>(expression).GetCompilation();
    var root = compile.SyntaxTrees.Single().GetRoot();

    var descentands = root.DescendantNodes().Where(n =>
    {
        if (n is ArgumentSyntax)
            return true;
        return false;
    }).ToList();

    var otherRoot = root.ReplaceNodes(descentands, (n1, n2) =>
    {
        var argumentName = Argument(LiteralExpression(SyntaxKind.StringLiteralExpression, Literal("NewValue")));
        return argumentName;
    });

    var newCode = otherRoot.ToString();

    // Faz o que estou querendo, contudo não me parece a melhor maneira
    var result = CSharpScript.EvaluateAsync(newCode).Result;
}

【问题讨论】:

    标签: c# roslyn


    【解决方案1】:

    不幸的是,从语法树创建 Script 对象的方法是 Microsoft 程序集的内部方法。

    但是,你不必编译两次——你可以只解析第一次,然后编译第二次。

    var expression = "System.Console.WriteLine(\"Test\")";
    var origTree = CSharpSyntaxTree.ParseText(expression, 
                      CSharpParseOptions.Default.WithKind(SourceCodeKind.Script));
    var root = origTree.GetRoot();
    
    // -Snip- tree manipulation
    
    var script = CSharpScript.Create(otherRoot.ToString());
    var errors = script.Compile();
    if(errors.Any(x => x.Severity == DiagnosticSeverity.Error)) {
        throw new Exception($"Compilation errors:\n{string.Join("\n", errors.Select(x => x.GetMessage()))}");
    }
    await script.RunAsync();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-17
      • 2014-01-03
      • 1970-01-01
      • 2021-09-30
      • 1970-01-01
      相关资源
      最近更新 更多