FIR find usage: correctly set extendsList of FirLightInterfaceClassSymbol
The existing code does not set the list of bases that FirLightInterfaceClassSymbol extends for "extendsList". It collects only the set of interfaces for "extendsList" of FirLightInterfaceClassSymbol. However, interfaces can "extend" other classes and/or interfaces, but they cannot "implement" other interfaces. Therefore, we have to includes all interfaces and classes that the child interface extends in the "extendsList". Additionally, this commit adds `private fun PsiClass.hasSuper(..): Boolean` to FirLightClassBase that returns whether one of recursive super classes of the PsiClass is `baseClass` or not. This commit lets `isInheritor()` method use `PsiClass.hasSuper()`.
This commit is contained in:
committed by
Ilya Kirillov
parent
21f65b2fe3
commit
ef482bb126
+15
@@ -22,6 +22,8 @@ import org.jetbrains.kotlin.analysis.api.KtAllowAnalysisOnEdt
|
|||||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||||
import org.jetbrains.kotlin.analysis.api.lifetime.allowAnalysisOnEdt
|
import org.jetbrains.kotlin.analysis.api.lifetime.allowAnalysisOnEdt
|
||||||
import org.jetbrains.kotlin.analysis.providers.createProjectWideOutOfBlockModificationTracker
|
import org.jetbrains.kotlin.analysis.providers.createProjectWideOutOfBlockModificationTracker
|
||||||
|
import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol
|
||||||
|
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||||
import org.jetbrains.kotlin.asJava.classes.*
|
import org.jetbrains.kotlin.asJava.classes.*
|
||||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||||
import org.jetbrains.kotlin.light.classes.symbol.classes.checkIsInheritor
|
import org.jetbrains.kotlin.light.classes.symbol.classes.checkIsInheritor
|
||||||
@@ -104,10 +106,23 @@ abstract class FirLightClassBase protected constructor(
|
|||||||
return if (baseClassOrigin != null && thisClassOrigin != null) {
|
return if (baseClassOrigin != null && thisClassOrigin != null) {
|
||||||
thisClassOrigin.checkIsInheritor(baseClassOrigin, checkDeep)
|
thisClassOrigin.checkIsInheritor(baseClassOrigin, checkDeep)
|
||||||
} else {
|
} else {
|
||||||
|
hasSuper(baseClass, checkDeep) ||
|
||||||
InheritanceImplUtil.isInheritor(this, baseClass, checkDeep)
|
InheritanceImplUtil.isInheritor(this, baseClass, checkDeep)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun PsiClass.hasSuper(
|
||||||
|
baseClass: PsiClass,
|
||||||
|
checkDeep: Boolean,
|
||||||
|
visitedSupers: MutableSet<PsiClass> = mutableSetOf<PsiClass>()
|
||||||
|
): Boolean {
|
||||||
|
visitedSupers.add(this)
|
||||||
|
val notVisitedSupers = supers.filterNot { visitedSupers.contains(it) }
|
||||||
|
if (notVisitedSupers.any { it == baseClass }) return true
|
||||||
|
if (!checkDeep) return false
|
||||||
|
return notVisitedSupers.any { it.hasSuper(baseClass, true, visitedSupers) }
|
||||||
|
}
|
||||||
|
|
||||||
override fun getText(): String = kotlinOrigin?.text ?: ""
|
override fun getText(): String = kotlinOrigin?.text ?: ""
|
||||||
|
|
||||||
override fun getLanguage(): KotlinLanguage = KotlinLanguage.INSTANCE
|
override fun getLanguage(): KotlinLanguage = KotlinLanguage.INSTANCE
|
||||||
|
|||||||
+1
-1
@@ -64,7 +64,7 @@ internal open class FirLightInterfaceClassSymbol(
|
|||||||
FirLightInterfaceClassSymbol(classOrObjectSymbol, manager)
|
FirLightInterfaceClassSymbol(classOrObjectSymbol, manager)
|
||||||
|
|
||||||
private val _extendsList: PsiReferenceList by lazyPub {
|
private val _extendsList: PsiReferenceList by lazyPub {
|
||||||
createInheritanceList(forExtendsList = false, classOrObjectSymbol.superTypes)
|
createInheritanceList(forExtendsList = true, classOrObjectSymbol.superTypes)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getExtendsList(): PsiReferenceList? = _extendsList
|
override fun getExtendsList(): PsiReferenceList? = _extendsList
|
||||||
|
|||||||
+6
-3
@@ -398,10 +398,13 @@ context(KtAnalysisSession)
|
|||||||
// We don't have Enum among enums supertype in sources neither we do for decompiled class-files and light-classes
|
// We don't have Enum among enums supertype in sources neither we do for decompiled class-files and light-classes
|
||||||
if (isEnum && this.classId == StandardClassIds.Enum) return false
|
if (isEnum && this.classId == StandardClassIds.Enum) return false
|
||||||
|
|
||||||
val isInterfaceType =
|
// Interfaces have only extends lists
|
||||||
(this.classSymbol as? KtClassOrObjectSymbol)?.classKind == KtClassKind.INTERFACE
|
if (isInterface) return forExtendsList
|
||||||
|
|
||||||
return forExtendsList == !isInterfaceType
|
val classKind = (classSymbol as? KtClassOrObjectSymbol)?.classKind
|
||||||
|
val isJvmInterface = classKind == KtClassKind.INTERFACE || classKind == KtClassKind.ANNOTATION_CLASS
|
||||||
|
|
||||||
|
return forExtendsList == !isJvmInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO Add support for kotlin.collections.
|
//TODO Add support for kotlin.collections.
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@ public abstract interface C /* p.C*/ extends p.B {
|
|||||||
public abstract java.lang.String c();// c()
|
public abstract java.lang.String c();// c()
|
||||||
|
|
||||||
|
|
||||||
public static final class DefaultImpls /* p.C.DefaultImpls*/ extends p.B {
|
public static final class DefaultImpls /* p.C.DefaultImpls*/ {
|
||||||
@org.jetbrains.annotations.NotNull()
|
@org.jetbrains.annotations.NotNull()
|
||||||
public java.lang.String c();// c()
|
public java.lang.String c();// c()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user