I'm trying to modify syntax tree and then get semantic model updated. Here is what I have so far:
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 new compilation with tree
before calling GetTypeInfo()
- same exception.
So how do I get updated SemanticModel
?
(Of course I could get modified source and do everything from start with it, but I guess there is more efficient way).
I'm missing something obvious here I'm sure, perhaps there is a new syntax tree created somewhere?
Roslyn types are immutable, so you need to construct 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 moving up to the Services level and using an 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();
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