26

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.

6
  • SyntaxTree.GetRoot().SyntaxTree is the same as SyntaxTree Commented Jun 5, 2015 at 17:20
  • 1
    It's unclear to me what you're trying to do. Can you expand on your question? Commented Jun 7, 2015 at 19:30
  • @JeroenVannevel I have expanded the question. I hope now it is clearer. Thanks for the suggestion. Commented Jun 8, 2015 at 20:05
  • This is not possible without compiling the whole project. Consider a case where you rename a method: this would make all code that calls this method invalid. Keep in mind that Roslyn is an incremental compiler, though. It won't re-compile every piece of code in the project. Commented Jun 16, 2015 at 3:14
  • You should explain what you want to achieve functionally. So not on a technical level but explain what your end goal is. Commented Jun 29, 2015 at 9:55

1 Answer 1

1

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...?

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.