2012-08-28 22 views
7

Próbuję zmodyfikować drzewo składniowe, a następnie zaktualizować model semantyczny. Oto co mam do tej pory:zmodyfikować drzewo składni, a następnie uzyskać zaktualizowany model semantyczny

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" 

Gdy próbuję zadzwonić semanticModel = compilation.GetSemanticModel(tree); lub nawet zrobić nową kompilację z tree przed wywołaniem GetTypeInfo() - sam wyjątek.

Jak mogę uzyskać zaktualizowaną wersję SemanticModel? (Oczywiście mogłem uzyskać zmodyfikowane źródło i zrobić wszystko od początku, ale wydaje mi się, że jest bardziej efektywny sposób).

Brakuje mi czegoś oczywistego, jestem pewien, że może gdzieś powstało nowe drzewo składni?

Odpowiedz

14

rodzaje Roslyn są niezmienne, więc trzeba zbudować nową SyntaxTree Dla Państwa newRootNode, a następnie zadzwonić compilation.UpdateSyntaxTree dostać nową Compilation, a następnie można nazwać newCompilation.GetSemanticModel(newTree) dostać nową SemanticModel.

Zastanów się nad przejściem do poziomu Usługi i skorzystaj z rozwiązania ISolution. Coś jak:

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(); 
Powiązane problemy