我想编写一个检查,以跟踪对驻留在字段内的对象的方法调用。该算法对我来说是这样的:
field.method()
),则说明已完成variable = field
),请以相同的方式跟踪左手变量/字段method(field)
),请跟踪方法参数的用法第一个很简单:我想支持Java和Kotlin,所以我扩展了AbstractBaseUastLocalInspectionTool
,重写了checkField
方法,并添加了一些检查来帮助我了解自己是否对此感兴趣字段。
然后,看起来我需要references search。好的,ReferencesSearch.search(field.sourceElement).forEach { ... }
将为我的字段的每次使用调用我的lambda,但现在我陷入了困境:
给定PsiReference
的分类方式是哪种?我可以得到PsiElement
,它可能显示为PsiExpression
或KtExpression
。但也可能不会。是否有所有可能案例的详尽清单以及处理(访问)它们的方法?
PsiReference.element
不再是UAST。我是否应该通过UastVisitorAdapter
传递任何PSI元素?
使用情况搜索似乎是检查开发中的常见模式。也许有一些更高层次的抽象可以做到这一点?
当我试图从调用中提取方法名称时,我已经写了这段代码,并且我确定许多极端情况没有得到处理:
private val PsiReference.outerMethodName: String? get() {
val el = element
if (el is PsiExpression) {
((el.parent as? PsiReferenceExpression)?.parent as? PsiMethodCallExpression)?.methodExpression?.let {
if (this === it.qualifierExpression) {
return it.referenceName
}
}
}
if (el is KtExpression) {
el.context?.children?.let {
if (it.size == 2 && (it[0] as? KtNameReferenceExpression)?.references?.firstOrNull() === this) {
return (it[1] as? KtCallExpression)?.firstChild?.text
}
}
}
return null
}