Implement equivalence of light members by origin when possible

Previous implementation worked through equality that used equality
of method stubs (see LightMemberOriginForCompiledMethod). But method
stubs for compiled element can be recreated when caches are outdated,
including weak reference cleaning (see ClsJavaStubByVirtualFileCache).

This could cause misbehave of find usages when java reference has an
outdated version of light element in resolution cache.
This commit is contained in:
Nikolay Krasko
2017-07-14 19:58:26 +03:00
parent fda097fc3b
commit 44ed903303
5 changed files with 24 additions and 15 deletions
@@ -50,10 +50,16 @@ interface LightMemberOrigin : LightElementOrigin {
override val originalElement: KtDeclaration?
override val originKind: JvmDeclarationOriginKind
fun isEquivalentTo(other: LightMemberOrigin?): Boolean
fun copy(): LightMemberOrigin
}
data class LightMemberOriginForDeclaration(override val originalElement: KtDeclaration, override val originKind: JvmDeclarationOriginKind) : LightMemberOrigin {
override fun isEquivalentTo(other: LightMemberOrigin?): Boolean {
if (other !is LightMemberOriginForDeclaration) return false
return originalElement.isEquivalentTo(other.originalElement)
}
override fun copy(): LightMemberOrigin {
return LightMemberOriginForDeclaration(originalElement.copy() as KtDeclaration, originKind)
}
@@ -70,13 +70,6 @@ sealed class KtLightFieldImpl<D : PsiField>(
return (clsDelegate as PsiVariableEx).computeConstantValue(visitedVars)
}
override fun isEquivalentTo(another: PsiElement?): Boolean {
if (another is KtLightField && this == another) {
return true
}
return super.isEquivalentTo(another)
}
override fun copy() = Factory.create(lightMemberOrigin?.copy(), clsDelegate, containingClass)
@@ -64,6 +64,14 @@ abstract class KtLightMemberImpl<out D : PsiMember>(
override fun getDocComment() = (clsDelegate as PsiDocCommentOwner).docComment
override fun isDeprecated() = (clsDelegate as PsiDocCommentOwner).isDeprecated
override fun isEquivalentTo(another: PsiElement?): Boolean {
val isEquivalentByOrigin =
another is KtLightMember<*> &&
lightMemberOrigin?.isEquivalentTo(another.lightMemberOrigin) == true
return isEquivalentByOrigin || this == another
}
}
internal fun getMemberOrigin(member: PsiMember): LightMemberOriginForDeclaration? {
@@ -139,14 +139,6 @@ class KtLightMethodImpl private constructor(
return typeParameters.all { processor.execute(it, state) }
}
override fun isEquivalentTo(another: PsiElement?): Boolean {
if (another is KtLightMethod && this == another) {
return true
}
return super.isEquivalentTo(another)
}
private val _memberIndex: MemberIndex?
get() = (dummyDelegate ?: clsDelegate).memberIndex
@@ -52,6 +52,11 @@ data class LightMemberOriginForCompiledField(val psiField: PsiField, val file: K
return LightMemberOriginForCompiledField(psiField.copy() as PsiField, file)
}
override fun isEquivalentTo(other: LightMemberOrigin?): Boolean {
if (other !is LightMemberOriginForCompiledField) return false
return psiField.isEquivalentTo(other.psiField)
}
override val originalElement: KtDeclaration? by lazyPub {
val desc = MapPsiToAsmDesc.typeDesc(psiField.type)
val signature = MemberSignature.fromFieldNameAndDesc(psiField.name!!, desc)
@@ -60,6 +65,11 @@ data class LightMemberOriginForCompiledField(val psiField: PsiField, val file: K
}
data class LightMemberOriginForCompiledMethod(val psiMethod: PsiMethod, val file: KtClsFile) : LightMemberOriginForCompiledElement {
override fun isEquivalentTo(other: LightMemberOrigin?): Boolean {
if (other !is LightMemberOriginForCompiledMethod) return false
return psiMethod.isEquivalentTo(other.psiMethod)
}
override fun copy(): LightMemberOrigin {
return LightMemberOriginForCompiledMethod(psiMethod.copy() as PsiMethod, file)
}