给定通过不同的 `SemanticModel` 实例获得的匹配 IMethodSymbol 对象,如何获取 IMethodSymbol 对象?
Posted
技术标签:
【中文标题】给定通过不同的 `SemanticModel` 实例获得的匹配 IMethodSymbol 对象,如何获取 IMethodSymbol 对象?【英文标题】:How to get the IMethodSymbol object given the matching IMethodSymbol object obtained through a different `SemanticModel` instance? 【发布时间】:2021-12-19 21:46:17 【问题描述】:我从给定的SemanticModel
获得了一个IMethodSymbol
对象,但随后意识到该符号缺少对其声明语法的引用。
让我们假设我可以轻松地为任何符号创建尊重 SyntaxTree
对象。
如何“刷新”IMethodSymbol
对象?
这是我目前所拥有的:
IMethodSymbol methodSymbol = ...;
if (methodSymbol.DeclaringSyntaxReferences.Length == 0)
var syntaxTree = ...;
var compilation = semanticModel.Compilation.AddSyntaxTrees(syntaxTree);
semanticModel = compilation.GetSemanticModel(semanticModel.SyntaxTree);
methodSymbol = ???;
新的semanticModel
对象链接到新的compilation
对象,该对象使用相关的语法树扩展了旧对象。我不想重复我最初用来获取methodSymbol
对象的整个过程。
当然,我应该能够利用我已经从语义模型的另一个实例中获得它的事实。但是怎么做呢?
【问题讨论】:
【参考方案1】:这似乎是一个 hack,但我们可以通过注释 SynatxNode 来添加一种引用:
MethodDeclarationSyntax method = ...
// create annotation
var methodAnnotation = new SyntaxAnnotation("MethodWithoutReferences");
// nodes are immutable, i.e., we have to create a copy containing our annotated method
var newMethod = method.WithAdditionalAnnotations(methodAnnotation);
var newRoot = root.ReplaceNode(method, newMethod);
// retrieve the annotated node
var annotatedMethod = newRoot.GetAnnotatedNodes(methodSymbolAnnotation).Single();
var methodSymbol = semanticModel.GetDeclaredSymbol(annotatedMethod);
【讨论】:
非常有趣的方法。但它并没有完全回答这个问题。您没有利用链接到语义模型的先前实例的methodSymbol
的存在。相反,您说的是“使用任何算法来查找声明,对其进行注释,然后使用注释第二次找到它”。我理解基本原理 - 找到带注释的节点可能比原始过程更简单。但是你在这里暗示不可能“重用”以前找到的符号。
@mark 据我所知,我们无法在新的语义模型中找到以前存在的引用。缺少诸如全局唯一标识符之类的概念。这就是我提出“注解方式”的原因
问题是注解创建了一个全新的SyntaxTree
实例。这可能是有问题的。因为我猜新树不等于旧树?
它不会创建SyntaxTree
的新实例。我们只替换 same 语法树中的单个节点(可能还有它的子节点)。此外,IsEquivalentTo(...)
方法将返回 true,因为注释被忽略。
哦,那好多了。我将不得不抽出时间来探索它。以上是关于给定通过不同的 `SemanticModel` 实例获得的匹配 IMethodSymbol 对象,如何获取 IMethodSymbol 对象?的主要内容,如果未能解决你的问题,请参考以下文章
#私藏项目实操分享# Angular @HostListener 装饰器的使用笔记