2012-08-28 11 views
7

構文ツリーを変更して意味モデルを更新しようとしています。 - 同じ例外を構文ツリーを変更してセマンティックモデルを更新する

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" 

私はsemanticModel = compilation.GetSemanticModel(tree);を呼び出すかさえGetTypeInfo()を呼び出す前treeと新しいコンパイルを作るしようとした場合:ここでは私がこれまで持っているものです。

どのようにして更新されますかSemanticModel? (もちろん、修正されたソースを取得して、最初からすべてを行うこともできますが、より効率的な方法があると思います)。

私は確かに何かが分からないのですが、どこかに新しい構文ツリーが作成されているのでしょうか?

答えて

14

ロザリンタイプは不変ですので、あなたのnewRootNodeのための新しいSyntaxTreeを構築し、新しいCompilationを取得するためにcompilation.UpdateSyntaxTreeを呼び出し、その後、あなたは新しいSemanticModelを取得するためにnewCompilation.GetSemanticModel(newTree)を呼び出すことができますする必要があります。

サービスレベルに移動し、代わりにISolutionを使用することを検討してください。次のようなもの:

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(); 
関連する問題