使用 Roslyn 访问和修改解决方案中的所有文档 [英] Visit and modify all documents in a solution using Roslyn

查看:39
本文介绍了使用 Roslyn 访问和修改解决方案中的所有文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 Roslyn 遍历给定解决方案中每个项目中的所有文档.

I want to walk over all the documents in every project in a given solution using Roslyn.

这是我现在的代码:

var msWorkspace = MSBuildWorkspace.Create();
var solution = await msWorkspace.OpenSolutionAsync(solutionPath);
foreach (var project in solution.Projects)
{
    foreach (var document in project.Documents)
    {
        if (document.SourceCodeKind != SourceCodeKind.Regular)
            continue;

        var doc = document;
        foreach (var rewriter in rewriters)
        {
            doc = await rewriter.Rewrite(doc);
        }

        if (doc != document)
        {
            Console.WriteLine("changed {0}",doc.Name);
            //save result

            //the solution is now changed and the next document to be processed will belong to the old solution
            msWorkspace.TryApplyChanges(doc.Project.Solution);
        }                    
    }
}

这里的问题是 Roslyn 在很大程度上是不可变的.在第一个msWorkspace.TryApplyChanges"之后,解决方案和文档现在替换为新版本.

The problem here is that as Roslyn is largely immutable. After the first "msWorkspace.TryApplyChanges", the solution and the document are now replaced with new versions.

所以下一次迭代仍然会遍历旧版本.有没有办法以 Roslyn 惯用的方式做到这一点?或者我必须求助于一些 for(int projectIndex = 0;projectIndex < solution.Projects.count) { 那种黑客?

So the next iteration will still walk over the old versions. Is there any way to do this in a Roslyn idiomatic way? Or do I have to resort to some for(int projectIndex = 0;projectIndex < solution.Projects.count) { kind of hackery?

推荐答案

发布在 Roslyn gitter chat 中的这个解决方案可以解决问题并解决问题.

This solution posted in the Roslyn gitter chat does the trick and solves the problem.

var solution = await msWorkspace.OpenSolutionAsync(solutionPath);

foreach (var projectId in solution.ProjectIds)
{
    var project = solution.GetProject(projectId);
    foreach (var documentId in project.DocumentIds)
    {
        Document document = project.GetDocument(documentId);

        if (document.SourceCodeKind != SourceCodeKind.Regular)
            continue;

        var doc = document;
        foreach (var rewriter in rewriters)
        {
            doc = await rewriter.Rewrite(doc);

        }

        project = doc.Project;
    }
    solution = project.Solution;
}
msWorkspace.TryApplyChanges(solution);

在这种情况下,在迭代之间不再丢弃更改,因为一切都建立在上次迭代的结果上.(也就是说,文档和项目是通过 ID 获取的,而不是从遍历原始结构的枚举器中获取的)

in this case, changes are no longer discarded between iterations as everything builds on the result of the last iteration. (that is, documents and projects are fetched by ID rather than from an enumerator that walks over the original structure)

这篇关于使用 Roslyn 访问和修改解决方案中的所有文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆