Подтвердить что ты не робот

Как частично обновить компиляцию с помощью нового дерева синтаксиса?

У меня есть следующая компиляция:

Solution solutionToAnalyze = workspace.OpenSolutionAsync(pathToSolution).Result;
var projects = solutionToAnalyze.Projects;
Compilation compilation = projects.First().GetCompilationAsync().Result; 
var syntaxTrees = compilation.SyntaxTrees.First();
var semanticModel = compilation.GetSemanticModel(syntaxTree, true);
SyntaxNode newSource = semanticModel.SyntaxTree.GetRoot();
var methodRefactoringVisitor = new MethodRefactoringVisitor();

Я изменил тело метода

public override SyntaxNode VisitMethodDeclaration(MethodDeclarationSyntax method)
{
    var newBody = method.Body;
    //modify newBody
    var updatedMethod = method.ReplaceNode(method.Body, newBody);
    return updatedMethod;
}

newSource = methodRefactoringVisitor.Visit(newSource);

После внесения изменений в метод я хотел бы обновить компиляцию, чтобы, например, я мог запросить тип node:

var typeInfo = semanticModel.GetTypeInfo(node).Type;

В настоящий момент я делаю:

var oldSyntaxTree = semanticModel.SyntaxTree;
var newSyntaxTree = newSource.SyntaxTree;
var newCompilation = compilation.ReplaceSyntaxTree(oldSyntaxTree, newSyntaxTree);
var newSemanticModel = newCompilation.GetSemanticModel(newSyntaxTree);

Я хотел бы обновить компиляцию сразу после того, как я изменил тело, чтобы увидеть изменения, если я вызываю посетителя из родительского класса модифицированного метода.

Возможно ли частично обновить компиляцию без компиляции всего проекта/класса?

Обновление

Если я правильно понял, я не думаю, что это возможно. На странице часто задаваемых вопросов в Roslyn github говорится:

Можно ли переписать исходный код в конвейере компилятора?

Roslyn не обеспечивает плагиновую архитектуру в конвейере компилятора, так что на каждом этапе вы можете влиять на синтаксический анализ, семантический анализ, алгоритмы оптимизации, эмиссию кода и т.д. [...] Вы можете использовать Roslyn для анализа кода и семантически анализировать его, а затем переписывать деревья, изменять ссылки и т.д. Затем скомпилируйте результат как новую компиляцию.

4b9b3361

Ответ 1

Возможно ли частично обновить компиляцию без компиляции всего проекта/класса?

    Нет, SyntaxTree реализуется как ImmutableArray. Таким образом, вы на самом деле создаете новый SyntaxTree, не изменяя старый, и аналогичным образом вам нужно будет скомпилировать новый SyntaxTree в новую компиляцию.
      Вы можете перезаписать объект Compilation или SemanticModel новым, если это делает код более понятным, но под капотом вы создаете новый экземпляр дерева синтаксиса каждый раз, когда вы заменяете node или что у вас есть, поэтому ваш нынешний подход кажется подходящим.
    Нет большой сделки, я бы не позволял этому беспокоить вас слишком много. Вас просто беспокоили производительность или лучший подход или...?