2012-08-28 13 views
7

Sözdizimi ağacını değiştirmeye çalışıyorum ve sonra semantik modelini güncelleştirmeye çalışıyorum. - Aynı istisnasözdizimi ağacını değiştirin ve sonra güncelleştirilmiş semantik modelini edinin

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" 

ben semanticModel = compilation.GetSemanticModel(tree); arayın veya hatta GetTypeInfo() çağırmadan önce tree ile yeni derleme yapmaya çalışırsanız: İşte ben bugüne kadar ne var.

Peki nasıl güncelleştirilir SemanticModel? (Tabii ki değiştirilmiş bir kaynak alıp baştan beri her şeyi yapabilirim, ama sanırım daha verimli bir yol var).

Burada bariz bir şey eksik. Eminim, belki de bir yerlerde yaratılmış yeni bir sözdizimi ağacı var mı?

cevap

14

Roslyn tipleri değişmez, bu nedenle yeni bir Compilation almak compilation.UpdateSyntaxTree çağrı sonra senin newRootNode için yeni SyntaxTree inşa ve gerek ve sonra yeni bir SemanticModel almak newCompilation.GetSemanticModel(newTree) çağırabilir.

Hizmet düzeyine ilerlemeyi ve bunun yerine bir IS kullanarak kullanmayı düşünün. Bir şey gibi:

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(); 
İlgili konular