Change the syntax tree, then get the updated semantic model

I am trying to change the syntax tree and then update the semantic model. Here is what I still have:

var tree = Roslyn.Compilers.CSharp.SyntaxTree.ParseCompilationUnit(code); var compilation = Roslyn.Compilers.CSharp.Compilation.Create( "MyCompilation", syntaxTrees: new[] { tree }, references: new[] { mscorlib }); var semanticModel = compilation.GetSemanticModel(tree); ... var oldStatementNode = (parent as ExpressionStatementSyntax); //some SyntaxNode in the tree var oldExpressionNode = oldStatementNode.Expression; var newExpressionNode = Syntax.ParenthesizedExpression(oldExpressionNode); var newRootNode = tree.GetRoot().ReplaceNode(oldExpressionNode, newExpressionNode); var semanticInfo = semanticModel.GetTypeInfo(newExpressionNode); //throws exception "Syntax node is not within syntax tree" 

If I try to call semanticModel = compilation.GetSemanticModel(tree); or even make a new compilation with tree before calling GetTypeInfo() - the same exception.

So how do I get the SemanticModel update? (Of course, I could get a modified source and do everything from the very beginning, but I think there is a more efficient way).

I'm missing something obvious here, I'm sure maybe a new syntax tree has appeared somewhere?

+7
source share
1 answer

Roslyn types are immutable, so you need to build a new SyntaxTree for your newRootNode , and then call compilation.UpdateSyntaxTree to get a new Compilation , and then you can call newCompilation.GetSemanticModel(newTree) to get a new SemanticModel .

Consider upgrading to a service level and use ISolution instead. Something like:

 var doc = Solution.Create(SolutionId.CreateNewId()).AddCSharpProject("MyCompilation", "MyCompilation").AddMetadataReference(mscorlib).AddDocument("MyFile", code); var semanticModel = (SemanticModel)doc.GetSemanticModel(); var root = (CompilationUnitSyntax)doc.GetSyntaxRoot(); SyntaxNode parent = null; var oldStatementNode = (parent as ExpressionStatementSyntax); //some SyntaxNode in the tree var oldExpressionNode = oldStatementNode.Expression; var newExpressionNode = Syntax.ParenthesizedExpression(oldExpressionNode); var newRootNode = root.ReplaceNode(oldExpressionNode, newExpressionNode); doc = doc.UpdateSyntaxRoot(newRootNode); semanticModel = (SemanticModel)doc.GetSemanticModel(); 
+14
source

All Articles