Tengo la siguiente compilación:
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();He modificado el cuerpo de un método.
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);Después de realizar los cambios en el método, me gustaría actualizar la compilación para que, por ejemplo, pueda consultar el tipo de un nodo:
var typeInfo = semanticModel.GetTypeInfo(node).Type;En este momento estoy haciendo:
var oldSyntaxTree = semanticModel.SyntaxTree; var newSyntaxTree = newSource.SyntaxTree; var newCompilation = compilation.ReplaceSyntaxTree(oldSyntaxTree, newSyntaxTree); var newSemanticModel = newCompilation.GetSemanticModel(newSyntaxTree);Me gustaría actualizar la compilación justo después de modificar el cuerpo, para poder ver los cambios si llamo al visitante desde la clase principal del método modificado.
¿Es posible actualizar parcialmente la compilación sin compilar todo el proyecto/clase?
Actualizar
Si entendí bien, no creo que sea posible. En la página de preguntas frecuentes en Roslyn github dice:
¿Puedo reescribir el código fuente dentro de la canalización del compilador?
Roslyn no proporciona una arquitectura de complemento a lo largo de la tubería del compilador para que en cada etapa pueda afectar la sintaxis analizada, el análisis semántico, los algoritmos de optimización, la emisión de código, etc. [...] Puede usar Roslyn para analizar el código y analizar semánticamente y luego reescribir los árboles, cambiar las referencias, etc. Luego compilar el resultado como una nueva compilación.
¿Es posible actualizar parcialmente la compilación sin compilar todo el proyecto/clase?
No, SyntaxTree se implementa como ImmutableArray. Por lo tanto, en realidad está creando un nuevo SyntaxTree, no modificando el anterior y, de manera similar, deberá compilar el nuevo SyntaxTree en una nueva compilación.
Puede sobrescribir el objeto Compilation o SemanticModel con el nuevo si eso hace que el código sea más fácil de razonar, pero bajo el capó, está creando una nueva instancia del árbol de sintaxis cada vez que reemplaza un nodo o lo que sea, por lo que su enfoque actual parece apropiado.
No es gran cosa, no dejaría que te molestara demasiado. ¿Estaba simplemente preocupado por el rendimiento o el mejor enfoque o...?