我写了我的类 MonitorSyntaxRewriter,它继承自 CSharpSyntaxRewriter。通过这个类(class),我改变了我的 SyntaxTree。但是,我怎样才能将这个修改过的语法树“注入(inject)”到某个地方呢?我的意思是,我在 Visual Studio 中有一些随机项目,在构建时,我希望所有语法树都经过此 MonitorSyntaxRewriter。有什么选择吗?
或者还有其他可能的解决方法吗? (创建新的解决方案...)。我只是不想在项目中更改我的 *.cs 文件。
最佳答案
据我所知,在语法树被编译并发送到磁盘之前,您无法插入构建过程并重写语法树。
这意味着实现您的愿望并非易事。但是,您的项目并非不可能,您可以想象创建自己的 Visual Studio 扩展,将菜单选项添加到 Visual Studio 并启动您自己的构建和发出过程。
为了重写语法树并将它们应用到解决方案中,您需要将它们应用到它们的父文档中。编写 Visual Studio 扩展时,您需要访问 VisualStudioWorkspace
.这包含当前打开的解决方案中的解决方案、项目和文档。我写了一些 background info在您可能感兴趣的工作区上。
您可以通过以下方式在 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
或运行直接取决于您要做什么。
关于c# - Roslyn SyntaxTree 更改注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33329966/