[AA Standalone] Implement KotlinDirectInheritorsProvider

- We are relying on static indexing to find candidates for sealed
  inheritors, hence the extension to the index.
- The direct usage of `KotlinStaticDeclarationProviderFactory` in
  `KotlinStandaloneDirectInheritorsProvider` is not pretty, but a proper
  design requires making the static index available as a service and
  moving "static" services to the Standalone API (from AA providers).

^KT-66013
This commit is contained in:
Marco Pennekamp
2024-02-28 21:18:08 +01:00
committed by Space Team
parent 9bed2e974b
commit b2639a469b
7 changed files with 163 additions and 24 deletions
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.analysis.providers.impl
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
internal class KotlinStaticDeclarationIndex {
@@ -16,4 +17,9 @@ internal class KotlinStaticDeclarationIndex {
internal val typeAliasMap: MutableMap<FqName, MutableSet<KtTypeAlias>> = mutableMapOf()
internal val topLevelFunctionMap: MutableMap<FqName, MutableSet<KtNamedFunction>> = mutableMapOf()
internal val topLevelPropertyMap: MutableMap<FqName, MutableSet<KtProperty>> = mutableMapOf()
/**
* Allows quickly finding [KtClassOrObject]s which have a given simple name as a supertype. The map may contain local classes as well.
*/
internal val classesBySupertypeName: MutableMap<Name, MutableSet<KtClassOrObject>> = mutableMapOf()
}
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.name.*
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getSuperNames
import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
import org.jetbrains.kotlin.psi.stubs.impl.*
@@ -203,7 +204,7 @@ public class KotlinStaticDeclarationProviderFactory(
}
override fun visitClassOrObject(classOrObject: KtClassOrObject) {
addToClassMap(classOrObject)
indexClassOrObject(classOrObject)
super.visitClassOrObject(classOrObject)
}
@@ -236,6 +237,11 @@ public class KotlinStaticDeclarationProviderFactory(
}.add(script)
}
private fun indexClassOrObject(classOrObject: KtClassOrObject) {
addToClassMap(classOrObject)
indexSupertypeNames(classOrObject)
}
private fun addToClassMap(classOrObject: KtClassOrObject) {
classOrObject.getClassId()?.let { classId ->
index.classMap.computeIfAbsent(classId.packageFqName) {
@@ -244,6 +250,14 @@ public class KotlinStaticDeclarationProviderFactory(
}
}
private fun indexSupertypeNames(classOrObject: KtClassOrObject) {
classOrObject.getSuperNames().forEach { superName ->
index.classesBySupertypeName
.computeIfAbsent(Name.identifier(superName)) { mutableSetOf() }
.add(classOrObject)
}
}
private fun addToTypeAliasMap(typeAlias: KtTypeAlias) {
typeAlias.getClassId()?.let { classId ->
index.typeAliasMap.computeIfAbsent(classId.packageFqName) {
@@ -307,12 +321,12 @@ public class KotlinStaticDeclarationProviderFactory(
private fun indexStub(stub: StubElement<*>) {
when (stub) {
is KotlinClassStubImpl -> {
addToClassMap(stub.psi)
indexClassOrObject(stub.psi)
// member functions and properties
stub.childrenStubs.forEach(::indexStub)
}
is KotlinObjectStubImpl -> {
addToClassMap(stub.psi)
indexClassOrObject(stub.psi)
// member functions and properties
stub.childrenStubs.forEach(::indexStub)
}
@@ -399,6 +413,9 @@ public class KotlinStaticDeclarationProviderFactory(
}
public fun getAllKtClasses(): List<KtClassOrObject> = index.classMap.values.flattenTo(mutableListOf())
public fun getDirectInheritorCandidates(baseClassName: Name): Set<KtClassOrObject> =
index.classesBySupertypeName[baseClassName].orEmpty()
}
/**