Roslyn SyntaxTree改变了注入

本文关键字:注入 改变 SyntaxTree Roslyn | 更新日期: 2023-09-27 18:19:13

我写了我的类MonitorSyntaxRewriter,它继承自CSharpSyntaxRewriter。使用这个类,我更改了SyntaxTree。但是,我如何在某处"注入"这个修改过的synaxtree呢?我的意思是,我在Visual Studio中有一些随机项目,在Build上,我希望所有的语法树都经过这个MonitorSyntaxRewriter。有其他选择吗?

或者有其他可能的解决方法吗?(创造新的解决方案…)。我只是不希望我的*.cs文件在项目中被更改。

Roslyn SyntaxTree改变了注入

据我所知,在编译并发送到磁盘之前,您无法插入构建过程并重写语法树。

这意味着实现你想要的并不容易。然而,你的项目不是不可能的,你可以创建你自己的Visual Studio扩展,在Visual Studio中添加一个菜单选项,并启动你自己的构建和发布过程。

为了重写语法树并将它们应用于解决方案,您需要将它们应用于它们的父文档。在编写Visual Studio扩展时,您将希望访问VisualStudioWorkspace。其中包含当前打开的解决方案中的解决方案、项目和文档。我已经写了一些你可能感兴趣的工作空间的背景信息。

你可以在MEF导出类中导入Visual Studio工作区,通过:

[Import(typeof(Microsoft.VisualStudio.LanguageServices.VisualStudioWorkspace))]

一旦您访问了VisualStudioWorkspace,您就可以逐一重写每个文档。下面的示例代码应该可以帮助您开始:

Workspace ws = null; //Normally you'd get access to the VisualStudioWorkspace here.
var currentSolution = ws.CurrentSolution;
foreach (var projectId in currentSolution.ProjectIds)
{
    var project = currentSolution.GetProject(projectId);
    foreach (var documentId in project.DocumentIds)
    {
        Document doc = project.GetDocument(documentId);
        var root = await doc.GetSyntaxRootAsync();
        //Rewrite your root here
        var rewrittenRoot = RewriteSyntaxRoot(root);
        //Save the changes to the current document
        doc = doc.WithSyntaxRoot(root);
        //Persist your changes to the current project
        project = doc.Project;
    }
    //Persist the project changes to the current solution
    currentSolution = project.Solution;
}
//Now you have your rewritten solution. You can emit the projects to disk one by one if you'd like.

这不会修改用户的代码,但将允许您发送您的自定义项目到磁盘或MemoryStream,您可以将其加载到AppDomain或直接运行,这取决于您想要做什么。