Visit and modify all documents in a solution using Roslyn

萝らか妹 提交于 2020-01-03 08:37:34

问题


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

This is the code I have now:

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);
        }                    
    }
}

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.

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?


回答1:


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);

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)



来源:https://stackoverflow.com/questions/32176651/visit-and-modify-all-documents-in-a-solution-using-roslyn

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!