[AA Standalone] Consider type aliases in direct inheritors search

A type alias may still be inherited from. For example:

```
sealed class MyClass

typealias T = MyClass

class Inheritor : T() // `Inheritor` is a direct inheritor of `MyClass`.
```

The index is a simplified version of the IDE's
`KotlinTypeAliasByExpansionShortNameIndex`, but it should be sufficient
for virtually all cases.

^KT-66013
This commit is contained in:
Marco Pennekamp
2024-02-29 20:18:45 +01:00
committed by Space Team
parent 54f2655b4d
commit a9d7b0c595
8 changed files with 130 additions and 14 deletions
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.contains
@@ -42,7 +43,11 @@ class KotlinStandaloneDirectInheritorsProvider(private val project: Project) : K
includeLocalInheritors: Boolean,
): Iterable<KtClassOrObject> {
val classId = ktClass.getClassId() ?: return emptyList()
val possibleInheritors = staticDeclarationProviderFactory.getDirectInheritorCandidates(classId.shortClassName)
val aliases = mutableSetOf(classId.shortClassName)
calculateAliases(classId.shortClassName, aliases)
val possibleInheritors = aliases.flatMap { staticDeclarationProviderFactory.getDirectInheritorCandidates(it) }
if (possibleInheritors.isEmpty()) {
return emptyList()
@@ -65,6 +70,16 @@ class KotlinStandaloneDirectInheritorsProvider(private val project: Project) : K
return possibleInheritors.filter { isValidInheritor(it, baseFirClass, scope, includeLocalInheritors) }
}
private fun calculateAliases(aliasedName: Name, aliases: MutableSet<Name>) {
staticDeclarationProviderFactory.getInheritableTypeAliases(aliasedName).forEach { alias ->
val aliasName = alias.nameAsSafeName
val isNewAliasName = aliases.add(aliasName)
if (isNewAliasName) {
calculateAliases(aliasName, aliases)
}
}
}
private fun isValidInheritor(
candidate: KtClassOrObject,
baseFirClass: FirClass,