AA: populate index in factory, not provider
diff --git a/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticDeclarationProvider.kt b/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticDeclarationProvider.kt
index 84e89b3..fe428ec 100644
--- a/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticDeclarationProvider.kt
+++ b/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticDeclarationProvider.kt
@@ -16,22 +16,104 @@
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
-public class KotlinStaticDeclarationProvider(
- scope: GlobalSearchScope,
- ktFiles: Collection<KtFile>
+public class KotlinStaticDeclarationIndex {
+ internal val facadeFileMap: MutableMap<FqName, MutableSet<KtFile>> = mutableMapOf()
+ internal val classMap: MutableMap<FqName, MutableSet<KtClassOrObject>> = mutableMapOf()
+ internal val typeAliasMap: MutableMap<FqName, MutableSet<KtTypeAlias>> = mutableMapOf()
+ internal val topLevelFunctionMap: MutableMap<FqName, MutableSet<KtNamedFunction>> = mutableMapOf()
+ internal val topLevelPropertyMap: MutableMap<FqName, MutableSet<KtProperty>> = mutableMapOf()
+}
+
+public class KotlinStaticDeclarationProvider internal constructor(
+ private val index: KotlinStaticDeclarationIndex,
+ private val scope: GlobalSearchScope,
) : KotlinDeclarationProvider() {
- private val index = Index()
+ private val KtElement.inScope: Boolean
+ get() = containingKtFile.virtualFile in scope
- private class Index {
- val facadeFileMap: MutableMap<FqName, MutableSet<KtFile>> = mutableMapOf()
- val classMap: MutableMap<FqName, MutableSet<KtClassOrObject>> = mutableMapOf()
- val typeAliasMap: MutableMap<FqName, MutableSet<KtTypeAlias>> = mutableMapOf()
- val topLevelFunctionMap: MutableMap<FqName, MutableSet<KtNamedFunction>> = mutableMapOf()
- val topLevelPropertyMap: MutableMap<FqName, MutableSet<KtProperty>> = mutableMapOf()
+ override fun getClassesByClassId(classId: ClassId): Collection<KtClassOrObject> =
+ index.classMap[classId.packageFqName]
+ ?.filter { ktClassOrObject ->
+ ktClassOrObject.getClassId() == classId && ktClassOrObject.inScope
+ }
+ ?: emptyList()
+
+ override fun getTypeAliasesByClassId(classId: ClassId): Collection<KtTypeAlias> =
+ index.typeAliasMap[classId.packageFqName]
+ ?.filter { ktTypeAlias ->
+ ktTypeAlias.getClassId() == classId && ktTypeAlias.inScope
+ }
+ ?: emptyList()
+
+ override fun getClassNamesInPackage(packageFqName: FqName): Set<Name> =
+ index.classMap[packageFqName]
+ ?.filter { ktClassOrObject ->
+ ktClassOrObject.inScope
+ }
+ ?.mapNotNullTo(mutableSetOf()) { it.nameAsName }
+ ?: emptySet()
+
+ override fun getTypeAliasNamesInPackage(packageFqName: FqName): Set<Name> =
+ index.typeAliasMap[packageFqName]
+ ?.filter { ktTypeAlias ->
+ ktTypeAlias.inScope
+ }
+ ?.mapNotNullTo(mutableSetOf()) { it.nameAsName }
+ ?: emptySet()
+
+ override fun getPropertyNamesInPackage(packageFqName: FqName): Set<Name> =
+ index.topLevelPropertyMap[packageFqName]
+ ?.filter { ktProperty ->
+ ktProperty.inScope
+ }
+ ?.mapNotNullTo(mutableSetOf()) { it.nameAsName }
+ ?: emptySet()
+
+ override fun getFunctionsNamesInPackage(packageFqName: FqName): Set<Name> =
+ index.topLevelFunctionMap[packageFqName]
+ ?.filter { ktNamedFunction ->
+ ktNamedFunction.inScope
+ }
+ ?.mapNotNullTo(mutableSetOf()) { it.nameAsName }
+ ?: emptySet()
+
+ override fun getFacadeFilesInPackage(packageFqName: FqName): Collection<KtFile> =
+ index.facadeFileMap[packageFqName]
+ ?.filter { ktFile ->
+ ktFile.virtualFile in scope
+ }
+ ?: emptyList()
+
+ override fun findFilesForFacade(facadeFqName: FqName): Collection<KtFile> {
+ if (facadeFqName.shortNameOrSpecial().isSpecial) return emptyList()
+ return getFacadeFilesInPackage(facadeFqName.parent()) //TODO Not work correctly for classes with JvmPackageName
+ .filter { it.javaFileFacadeFqName == facadeFqName }
}
- private class KtDeclarationRecorder(private val index: Index) : KtVisitorVoid() {
+ override fun getTopLevelProperties(callableId: CallableId): Collection<KtProperty> =
+ index.topLevelPropertyMap[callableId.packageName]
+ ?.filter { ktProperty ->
+ ktProperty.nameAsName == callableId.callableName && ktProperty.inScope
+ }
+ ?: emptyList()
+
+ override fun getTopLevelFunctions(callableId: CallableId): Collection<KtNamedFunction> =
+ index.topLevelFunctionMap[callableId.packageName]
+ ?.filter { ktNamedFunction ->
+ ktNamedFunction.nameAsName == callableId.callableName && ktNamedFunction.inScope
+ }
+ ?: emptyList()
+
+}
+
+public class KotlinStaticDeclarationProviderFactory(
+ files: Collection<KtFile>
+) : KotlinDeclarationProviderFactory() {
+
+ private val index = KotlinStaticDeclarationIndex()
+
+ private class KtDeclarationRecorder(private val index: KotlinStaticDeclarationIndex) : KtVisitorVoid() {
override fun visitElement(element: PsiElement) {
element.acceptChildren(this)
@@ -87,69 +169,12 @@
init {
val recorder = KtDeclarationRecorder(index)
- ktFiles
- .filter {
- scope.contains(it.virtualFile)
- }
- .forEach {
- it.accept(recorder)
- }
+ files.forEach {
+ it.accept(recorder)
+ }
}
- override fun getClassesByClassId(classId: ClassId): Collection<KtClassOrObject> =
- index.classMap[classId.packageFqName]
- ?.filter { it.getClassId() == classId }
- ?: emptyList()
-
- override fun getTypeAliasesByClassId(classId: ClassId): Collection<KtTypeAlias> =
- index.typeAliasMap[classId.packageFqName]
- ?.filter { it.getClassId() == classId }
- ?: emptyList()
-
- override fun getClassNamesInPackage(packageFqName: FqName): Set<Name> =
- index.classMap[packageFqName]
- ?.mapNotNullTo(mutableSetOf()) { it.nameAsName }
- ?: emptySet()
-
- override fun getTypeAliasNamesInPackage(packageFqName: FqName): Set<Name> =
- index.typeAliasMap[packageFqName]
- ?.mapNotNullTo(mutableSetOf()) { it.nameAsName }
- ?: emptySet()
-
- override fun getPropertyNamesInPackage(packageFqName: FqName): Set<Name> =
- index.topLevelPropertyMap[packageFqName]
- ?.mapNotNullTo(mutableSetOf()) { it.nameAsName }
- ?: emptySet()
-
- override fun getFunctionsNamesInPackage(packageFqName: FqName): Set<Name> =
- index.topLevelFunctionMap[packageFqName]
- ?.mapNotNullTo(mutableSetOf()) { it.nameAsName }
- ?: emptySet()
-
- override fun getFacadeFilesInPackage(packageFqName: FqName): Collection<KtFile> =
- index.facadeFileMap[packageFqName]
- ?: emptyList()
-
- override fun findFilesForFacade(facadeFqName: FqName): Collection<KtFile> {
- if (facadeFqName.shortNameOrSpecial().isSpecial) return emptyList()
- return getFacadeFilesInPackage(facadeFqName.parent()) //TODO Not work correctly for classes with JvmPackageName
- .filter { it.javaFileFacadeFqName == facadeFqName }
- }
-
- override fun getTopLevelProperties(callableId: CallableId): Collection<KtProperty> =
- index.topLevelPropertyMap[callableId.packageName]
- ?.filter { it.nameAsName == callableId.callableName }
- ?: emptyList()
-
- override fun getTopLevelFunctions(callableId: CallableId): Collection<KtNamedFunction> =
- index.topLevelFunctionMap[callableId.packageName]
- ?.filter { it.nameAsName == callableId.callableName }
- ?: emptyList()
-
-}
-
-public class KotlinStaticDeclarationProviderFactory(private val files: Collection<KtFile>) : KotlinDeclarationProviderFactory() {
override fun createDeclarationProvider(searchScope: GlobalSearchScope): KotlinDeclarationProvider {
- return KotlinStaticDeclarationProvider(searchScope, files)
+ return KotlinStaticDeclarationProvider(index, searchScope)
}
}