我正在尝试在Roslyn中执行语法转换。AST重排工作正常,但是,由于我正在更改内容,我需要获得更新的SemanticModel
,以反映我的SyntaxTree
的新结构。
转化树
这部分工作,我可以告诉,因为我做了大量的调试。
CSharpSyntaxTree tree = RetrieveTree(); // Just successfully gets the original tree
CSharpCompilation compilation = CSharpCompilation.Create(...); // Retrieves the compilation object
CompilationUnitSyntax node = tree.GetRoot();
// Doing stuff to change the tree
node = node.RemoveNodes(...);
node = node.AddMembers(...);
字符串
我可以得到新的树:
CSharpSyntaxTree newTree = node.SyntaxTree as CSharpSyntaxTree;
型
通过调试,我可以看到newTree
具有新的结构,而tree
具有旧的结构。我也可以成功地遍历newTree
并在AST上操作。所以改造是成功的。
更新树和语义
我认为问题从这里开始当我试图更新CSharpCompilation
和当我得到SemanticModel
了。
CSharpCompilation newCompilation = compilation.ReplaceSyntaxTree(tree, newTree);
SemanticModel newSemanticModel = newCompilation.GetSemanticModel(newTree);
型
因为当我尝试:
TypeSyntax myClassTypeNode = GetSourceCodeClassTypeNode(); // Just successfully gets a node
var symbol = newSemanticModel.getSymbolInfo(myClassTypeNode).Symbol;
型symbol
为null。当然,如果我尝试使用原始的SemanticModel
,它也会保持为null
。
不转换也可以如果我不执行转换,使用旧的SemanticModel
,符号被成功检索!
我做错了什么?
1条答案
按热度按时间xjreopfe1#
这是一个迟来的答案,但我希望它对某人有用。根据我的经验,如果在用
SyntaxNode.ReplaceNode
替换节点并用CompilationReplaceSyntaxTree
更新编译后,无法从语义模型中获取符号,这是因为在替换节点时引入了错误。当插入使用SyntaxFactory
API创建的节点时,很容易引入细微的错误,这些节点只是看起来正确(但实际上并不正确),因为一些类似的节点发出相同的代码,并且替换函数将非常宽松,只是为了在稍后的语义分析中发现错误。我发现的一个技巧是使用以下扩展方法测试编译错误:字符串
假设树操作在语义上是正确的,如果用上述函数没有检测到错误,则语义模型应该产生预期的结果。