2012-08-28 28 views
7

Tôi đang cố gắng sửa đổi cây cú pháp và sau đó nhận mô hình ngữ nghĩa được cập nhật. Dưới đây là những gì tôi có cho đến nay:sửa đổi cây cú pháp, sau đó nhận mô hình ngữ nghĩa cập nhật

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" 

Nếu tôi cố gắng gọi semanticModel = compilation.GetSemanticModel(tree); hoặc thậm chí tạo bộ sưu tập mới với tree trước khi gọi GetTypeInfo() - cùng là ngoại lệ.

Vậy làm cách nào để tôi được cập nhật SemanticModel? (Tất nhiên tôi có thể nhận được nguồn sửa đổi và làm mọi thứ từ đầu với nó, nhưng tôi đoán có cách hiệu quả hơn).

Tôi thiếu điều gì đó hiển nhiên ở đây tôi chắc chắn, có lẽ có một cây cú pháp mới được tạo ở đâu đó?

Trả lời

14

loại Roslyn là không thay đổi, vì vậy bạn cần phải xây dựng một mới SyntaxTree cho newRootNode của bạn, và sau đó gọi compilation.UpdateSyntaxTree để có được một mới Compilation, và sau đó bạn có thể gọi newCompilation.GetSemanticModel(newTree) để có được một mới SemanticModel.

Cân nhắc chuyển lên cấp Dịch vụ và sử dụng ISolution thay thế. Một cái gì đó như:

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(); 
Các vấn đề liên quan