I have the following compilation:
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();
I have modified the body of a method
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);
After I made the changes to the method, I would like to update the compilation so that for example I can query for the type of a node:
var typeInfo = semanticModel.GetTypeInfo(node).Type;
At the moment I am doing:
var oldSyntaxTree = semanticModel.SyntaxTree;
var newSyntaxTree = newSource.SyntaxTree;
var newCompilation = compilation.ReplaceSyntaxTree(oldSyntaxTree, newSyntaxTree);
var newSemanticModel = newCompilation.GetSemanticModel(newSyntaxTree);
I would like to update the compilation right after I modified the body, so that I can see the changes if I am calling the visitor from the parent class of the modified method.
Is it possible to partially update the compilation without compiling the entire project/class?
Update
If I understood correctly, I don't think it is possible. On the FAQ page on Roslyn github it says:
Can I rewrite source code within the compiler pipeline?
Roslyn does not provide a plug-in architecture throughout the compiler pipeline so that at each stage you can affect syntax parsed, semantic analysis, optimization algorithms, code emission, etc. [...] You can use Roslyn to parse code and semantically analyze it, and then rewrite the trees, change references, etc. Then compile the result as a new compilation.
Is it possible to partially update the compilation without compiling the entire project/class?
No, the SyntaxTree is implemented as an ImmutableArray. Thus, you are actually creating a new SyntaxTree, not modifying the old one, and similarly, will need to compile the new SyntaxTree into a new compilation.
You can overwrite the Compilation or SemanticModel object with the new one if that makes the code easier to reason about, but under the hood, you are creating a new instance of the syntax tree each time you replace a node or what have you, so your current approach seems appropriate.
No big deal, I wouldn't let it bother you too much. Were you just concerned about performance or the best approach or...?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With