问题
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