Посетите и измените все документы в решении с помощью Roslyn

Я хочу просмотреть все документы в каждом проекте в данном решении с помощью 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);
        }                    
    }
}

проблема здесь в том, что как Рослин в значительной степени неизменна. После первого " msWorkspace.TryApplyChanges", решение и документ теперь заменены новыми версиями.

таким образом, следующая итерация по-прежнему будет проходить по старым версиям. Есть ли способ сделать это идиоматическим способом Рослин? Или я должен? прибегнуть к некоторым for(int projectIndex = 0;projectIndex < solution.Projects.count) { вид шаманства?

1 ответов


это решение, опубликованное в чате Roslyn gitter, делает трюк и решает проблему.

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, а не из перечислителя, который проходит по исходной структуре)