gpt4 book ai didi

c# - 如何使用新语法树部分更新编译?

转载 作者:IT王子 更新时间:2023-10-29 04:19:45 25 4
gpt4 key购买 nike

我有以下编译:

Solution solutionToAnalyze = workspace.OpenSolutionAsync(pathToSolution).Result;
var projects = solutionToAnalyze.Projects;
Compilation compilation = projects.First().GetCompilationAsync().Result;
var syntaxTrees = compilation.SyntaxTrees.First();
var semanticModel = compilation.GetSemanticModel(syntaxTree, true);
SyntaxNode newSource = semanticModel.SyntaxTree.GetRoot();
var methodRefactoringVisitor = new MethodRefactoringVisitor();

我修改了一个方法体

public override SyntaxNode VisitMethodDeclaration(MethodDeclarationSyntax method)
{
var newBody = method.Body;
//modify newBody
var updatedMethod = method.ReplaceNode(method.Body, newBody);
return updatedMethod;
}

newSource = methodRefactoringVisitor.Visit(newSource);

在我对方法进行更改后,我想更新编译以便例如我可以查询节点的类型:

var typeInfo = semanticModel.GetTypeInfo(node).Type;

目前我在做:

var oldSyntaxTree = semanticModel.SyntaxTree;
var newSyntaxTree = newSource.SyntaxTree;
var newCompilation = compilation.ReplaceSyntaxTree(oldSyntaxTree, newSyntaxTree);
var newSemanticModel = newCompilation.GetSemanticModel(newSyntaxTree);

我想在修改主体后立即更新编译,以便在从修改后的方法的父类调用访问者时可以看到更改。

是否可以在不编译整个项目/类的情况下更新部分编译?

更新

如果我没理解错的话,我觉得是不可能的。在 Roslyn github 上的常见问题页面上,它说:

我可以在编译器管道中重写源代码吗?

Roslyn 不提供整个编译器管道的插件架构,因此在每个阶段您都可以影响语法分析、语义分析、优化算法、代码发布等。[...]您可以使用 Roslyn 解析代码并对其进行语义分析,然后重写树、更改引用等。然后将结果编译为新的编译。

最佳答案

Is it possible to partially update the compilation without compiling the entire project/class?

不,SyntaxTree 是作为 ImmutableArray 实现的。因此,您实际上是在创建一个新的 SyntaxTree,而不是修改旧的 SyntaxTree,同样,需要将新的 SyntaxTree 编译成一个新的编译。
如果这样可以使代码更易于推理,您可以用新对象覆盖 Compilation 或 SemanticModel 对象,但在幕后,每次替换节点或您拥有的东西时,您都在创建语法树的新实例,所以您的目前的做法似乎是合适的。
没什么大不了的,我不会让它太打扰你。您只是关心性能或最佳方法还是...?

关于c# - 如何使用新语法树部分更新编译?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30670881/

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