FIR IDE: separate index helper in LL API and completion
This commit is contained in:
+3
-3
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.idea.caches.project.getModuleInfo
|
||||
import org.jetbrains.kotlin.idea.completion.KotlinFirCompletionParameters
|
||||
import org.jetbrains.kotlin.idea.completion.LookupElementSink
|
||||
import org.jetbrains.kotlin.idea.completion.lookups.factories.KotlinFirLookupElementFactory
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.IndexHelper
|
||||
import org.jetbrains.kotlin.idea.fir.HLIndexHelper
|
||||
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
||||
import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
@@ -28,7 +28,7 @@ internal class FirBasicCompletionContext(
|
||||
val fakeKtFile: KtFile,
|
||||
val project: Project,
|
||||
val targetPlatform: TargetPlatform,
|
||||
val indexHelper: IndexHelper,
|
||||
val indexHelper: HLIndexHelper,
|
||||
val lookupElementFactory: KotlinFirLookupElementFactory = KotlinFirLookupElementFactory(),
|
||||
) {
|
||||
val visibleScope = KotlinSourceFilterScope.projectSourceAndClassFiles(originalKtFile.resolveScope, project)
|
||||
@@ -55,7 +55,7 @@ internal class FirBasicCompletionContext(
|
||||
)
|
||||
}
|
||||
|
||||
private fun createIndexHelper(parameters: CompletionParameters) = IndexHelper(
|
||||
private fun createIndexHelper(parameters: CompletionParameters) = HLIndexHelper(
|
||||
parameters.position.project,
|
||||
parameters.position.getModuleInfo().contentScope()
|
||||
)
|
||||
|
||||
+2
-2
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.idea.completion.checkers.CompletionVisibilityChecker
|
||||
import org.jetbrains.kotlin.idea.completion.checkers.ExtensionApplicabilityChecker
|
||||
import org.jetbrains.kotlin.idea.completion.context.FirBasicCompletionContext
|
||||
import org.jetbrains.kotlin.idea.completion.context.FirNameReferencePositionContext
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.IndexHelper
|
||||
import org.jetbrains.kotlin.idea.fir.HLIndexHelper
|
||||
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.idea.frontend.api.components.KtScopeContext
|
||||
import org.jetbrains.kotlin.idea.frontend.api.scopes.KtCompositeScope
|
||||
@@ -168,7 +168,7 @@ internal class FirCallableCompletionContributor(
|
||||
implicitReceiversTypes.flatMapTo(hashSetOf()) { with(typeNamesProvider) { findAllNames(it) } }
|
||||
}
|
||||
|
||||
private class TypeNamesProvider(private val indexHelper: IndexHelper) {
|
||||
private class TypeNamesProvider(private val indexHelper: HLIndexHelper) {
|
||||
fun KtAnalysisSession.findAllNames(type: KtType): Set<String> {
|
||||
if (type !is KtNonErrorClassType) return emptySet()
|
||||
|
||||
|
||||
+2
-2
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.idea.completion.lookups.CallableImportStrategy
|
||||
import org.jetbrains.kotlin.idea.completion.lookups.CallableInsertionStrategy
|
||||
import org.jetbrains.kotlin.idea.completion.lookups.factories.KotlinFirLookupElementFactory
|
||||
import org.jetbrains.kotlin.idea.completion.weighers.Weighers
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.IndexHelper
|
||||
import org.jetbrains.kotlin.idea.fir.HLIndexHelper
|
||||
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.idea.frontend.api.scopes.KtScopeNameFilter
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
|
||||
@@ -37,7 +37,7 @@ internal abstract class FirCompletionContributorBase<C : FirRawPositionCompletio
|
||||
protected val fakeKtFile: KtFile get() = basicContext.fakeKtFile
|
||||
protected val project: Project get() = basicContext.project
|
||||
protected val targetPlatform: TargetPlatform get() = basicContext.targetPlatform
|
||||
protected val indexHelper: IndexHelper get() = basicContext.indexHelper
|
||||
protected val indexHelper: HLIndexHelper get() = basicContext.indexHelper
|
||||
protected val lookupElementFactory: KotlinFirLookupElementFactory get() = basicContext.lookupElementFactory
|
||||
protected val visibleScope = basicContext.visibleScope
|
||||
|
||||
|
||||
-1
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.idea.completion.contributors
|
||||
import org.jetbrains.kotlin.idea.completion.context.FirBasicCompletionContext
|
||||
import org.jetbrains.kotlin.idea.completion.context.FirNameReferencePositionContext
|
||||
import org.jetbrains.kotlin.idea.completion.context.FirRawPositionCompletionContext
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.IndexHelper
|
||||
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.idea.frontend.api.scopes.KtScopeNameFilter
|
||||
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
package org.jetbrains.kotlin.idea.completion.contributors.helpers
|
||||
|
||||
import org.jetbrains.kotlin.idea.completion.checkers.CompletionVisibilityChecker
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.IndexHelper
|
||||
import org.jetbrains.kotlin.idea.fir.HLIndexHelper
|
||||
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.idea.frontend.api.scopes.KtScopeNameFilter
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassifierSymbol
|
||||
@@ -19,7 +19,7 @@ internal object FirClassifierProvider {
|
||||
originalKtFile: KtFile,
|
||||
position: KtElement,
|
||||
scopeNameFilter: KtScopeNameFilter,
|
||||
indexHelper: IndexHelper,
|
||||
indexHelper: HLIndexHelper,
|
||||
visibilityChecker: CompletionVisibilityChecker
|
||||
): Sequence<KtClassifierSymbol> = sequence {
|
||||
yieldAll(
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.fir
|
||||
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.stubs.StringStubIndexExtension
|
||||
import com.intellij.psi.stubs.StubIndex
|
||||
import com.intellij.psi.stubs.StubIndexKey
|
||||
import org.jetbrains.kotlin.idea.stubindex.*
|
||||
import org.jetbrains.kotlin.name.CallableId
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
|
||||
/*
|
||||
* Move to another module
|
||||
*/
|
||||
class HLIndexHelper(val project: Project, private val scope: GlobalSearchScope) {
|
||||
fun getClassNamesInPackage(packageFqName: FqName): Set<Name> =
|
||||
KotlinTopLevelClassByPackageIndex.getInstance()
|
||||
.get(packageFqName.asStringForIndexes(), project, scope)
|
||||
.mapNotNullTo(hashSetOf()) { it.nameAsName }
|
||||
|
||||
fun getKotlinClasses(
|
||||
nameFilter: (Name) -> Boolean,
|
||||
psiFilter: (element: KtClassOrObject) -> Boolean = { true }
|
||||
): Collection<KtClassOrObject> {
|
||||
val index = KotlinFullClassNameIndex.getInstance()
|
||||
return index.getAllKeys(project).asSequence()
|
||||
.onEach { ProgressManager.checkCanceled() }
|
||||
.filter { fqName -> nameFilter(getShortName(fqName)) }
|
||||
.flatMap { fqName -> index[fqName, project, scope] }
|
||||
.filter(psiFilter)
|
||||
.toList()
|
||||
}
|
||||
|
||||
fun getTopLevelCallables(nameFilter: (Name) -> Boolean): Collection<KtCallableDeclaration> {
|
||||
fun sequenceOfElements(index: StringStubIndexExtension<out KtCallableDeclaration>): Sequence<KtCallableDeclaration> =
|
||||
index.getAllKeys(project).asSequence()
|
||||
.onEach { ProgressManager.checkCanceled() }
|
||||
.filter { fqName -> nameFilter(getShortName(fqName)) }
|
||||
.flatMap { fqName -> index[fqName, project, scope] }
|
||||
.filter { it.receiverTypeReference == null }
|
||||
|
||||
val functions = sequenceOfElements(KotlinTopLevelFunctionFqnNameIndex.getInstance())
|
||||
val properties = sequenceOfElements(KotlinTopLevelPropertyFqnNameIndex.getInstance())
|
||||
|
||||
return (functions + properties).toList()
|
||||
}
|
||||
|
||||
fun getKotlinCallablesByName(name: Name): Collection<KtCallableDeclaration> {
|
||||
val functions: Sequence<KtCallableDeclaration> =
|
||||
KotlinFunctionShortNameIndex.getInstance().get(name.asString(), project, scope).asSequence()
|
||||
|
||||
val properties: Sequence<KtNamedDeclaration> =
|
||||
KotlinPropertyShortNameIndex.getInstance().get(name.asString(), project, scope).asSequence()
|
||||
|
||||
return (functions + properties)
|
||||
.filterIsInstance<KtCallableDeclaration>()
|
||||
.toList()
|
||||
}
|
||||
|
||||
fun getKotlinClassesByName(name: Name): Collection<KtClassOrObject> {
|
||||
return KotlinClassShortNameIndex.getInstance().get(name.asString(), project, scope)
|
||||
}
|
||||
|
||||
fun getTopLevelExtensions(nameFilter: (Name) -> Boolean, receiverTypeNames: Set<String>): Collection<KtCallableDeclaration> {
|
||||
val index = KotlinTopLevelExtensionsByReceiverTypeIndex.INSTANCE
|
||||
|
||||
return index.getAllKeys(project).asSequence()
|
||||
.onEach { ProgressManager.checkCanceled() }
|
||||
.filter { KotlinTopLevelExtensionsByReceiverTypeIndex.receiverTypeNameFromKey(it) in receiverTypeNames }
|
||||
.filter { nameFilter(Name.identifier(KotlinTopLevelExtensionsByReceiverTypeIndex.callableNameFromKey(it))) }
|
||||
.flatMap { key -> index[key, project, scope] }
|
||||
.toList()
|
||||
}
|
||||
|
||||
fun getPossibleTypeAliasExpansionNames(originalTypeName: String): Set<String> {
|
||||
val index = KotlinTypeAliasByExpansionShortNameIndex.INSTANCE
|
||||
val out = mutableSetOf<String>()
|
||||
|
||||
fun searchRecursively(typeName: String) {
|
||||
ProgressManager.checkCanceled()
|
||||
index[typeName, project, scope].asSequence()
|
||||
.mapNotNull { it.name }
|
||||
.filter { out.add(it) }
|
||||
.forEach(::searchRecursively)
|
||||
}
|
||||
|
||||
searchRecursively(originalTypeName)
|
||||
return out
|
||||
}
|
||||
|
||||
companion object {
|
||||
private fun CallableId.asStringForIndexes(): String =
|
||||
(if (packageName.isRoot) callableName.asString() else toString()).replace('/', '.')
|
||||
|
||||
private fun FqName.asStringForIndexes(): String =
|
||||
asString().replace('/', '.')
|
||||
|
||||
private fun ClassId.asStringForIndexes(): String =
|
||||
asSingleFqName().asStringForIndexes()
|
||||
|
||||
private fun getShortName(fqName: String) = Name.identifier(fqName.substringAfterLast('.'))
|
||||
}
|
||||
}
|
||||
@@ -19,8 +19,8 @@ import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.util.PsiModificationTracker
|
||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.caches.project.getModuleInfo
|
||||
import org.jetbrains.kotlin.idea.fir.HLIndexHelper
|
||||
import org.jetbrains.kotlin.idea.fir.api.fixes.diagnosticFixFactory
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.IndexHelper
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.util.createScopeForModuleLibraries
|
||||
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.diagnostics.KtFirDiagnostic
|
||||
@@ -137,7 +137,7 @@ internal class ImportQuickFix(
|
||||
val FACTORY = diagnosticFixFactory(KtFirDiagnostic.UnresolvedReference::class) { diagnostic ->
|
||||
val element = diagnostic.psi
|
||||
|
||||
val indexHelper = IndexHelper(element.project, createSearchScope(element))
|
||||
val indexHelper = HLIndexHelper(element.project, createSearchScope(element))
|
||||
|
||||
val quickFix = when (element) {
|
||||
is KtTypeReference -> createImportTypeFix(indexHelper, element)
|
||||
@@ -157,7 +157,7 @@ internal class ImportQuickFix(
|
||||
}
|
||||
|
||||
private fun KtAnalysisSession.createImportNameFix(
|
||||
indexHelper: IndexHelper,
|
||||
indexHelper: HLIndexHelper,
|
||||
element: KtNameReferenceExpression
|
||||
): ImportQuickFix? {
|
||||
if (isSelectorInQualified(element)) return null
|
||||
@@ -177,7 +177,7 @@ internal class ImportQuickFix(
|
||||
return ImportQuickFix(element, importCandidates)
|
||||
}
|
||||
|
||||
private fun KtAnalysisSession.createImportTypeFix(indexHelper: IndexHelper, element: KtTypeReference): ImportQuickFix? {
|
||||
private fun KtAnalysisSession.createImportTypeFix(indexHelper: HLIndexHelper, element: KtTypeReference): ImportQuickFix? {
|
||||
val firFile = element.containingKtFile.getFileSymbol()
|
||||
val unresolvedName = element.typeName ?: return null
|
||||
|
||||
@@ -191,7 +191,7 @@ internal class ImportQuickFix(
|
||||
}
|
||||
|
||||
private fun KtAnalysisSession.collectCallableCandidates(
|
||||
indexHelper: IndexHelper,
|
||||
indexHelper: HLIndexHelper,
|
||||
unresolvedName: Name,
|
||||
isVisible: (KtCallableSymbol) -> Boolean
|
||||
): List<FqName> {
|
||||
@@ -206,7 +206,7 @@ internal class ImportQuickFix(
|
||||
}
|
||||
|
||||
private fun KtAnalysisSession.collectTypesCandidates(
|
||||
indexHelper: IndexHelper,
|
||||
indexHelper: HLIndexHelper,
|
||||
unresolvedName: Name,
|
||||
isVisible: (KtNamedClassOrObjectSymbol) -> Boolean
|
||||
): List<FqName> {
|
||||
|
||||
+1
-75
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.psi.*
|
||||
/*
|
||||
* Move to another module
|
||||
*/
|
||||
public class IndexHelper(val project: Project, private val scope: GlobalSearchScope) {
|
||||
internal class IndexHelper(val project: Project, private val scope: GlobalSearchScope) {
|
||||
private val stubIndex: StubIndex = StubIndex.getInstance()
|
||||
|
||||
private inline fun <INDEX_KEY : Any, reified PSI : PsiElement> firstMatchingOrNull(
|
||||
@@ -64,86 +64,12 @@ public class IndexHelper(val project: Project, private val scope: GlobalSearchSc
|
||||
fun getTopLevelFunctions(callableId: CallableId): Collection<KtNamedFunction> =
|
||||
KotlinTopLevelFunctionFqnNameIndex.getInstance()[callableId.asStringForIndexes(), project, scope]
|
||||
|
||||
fun getTopLevelPropertiesInPackage(packageFqName: FqName): Collection<KtProperty> =
|
||||
KotlinTopLevelPropertyByPackageIndex.getInstance().get(packageFqName.asStringForIndexes(), project, scope)
|
||||
|
||||
fun getTopLevelFunctionsInPackage(packageFqName: FqName): Collection<KtFunction> =
|
||||
KotlinTopLevelFunctionByPackageIndex.getInstance().get(packageFqName.asStringForIndexes(), project, scope)
|
||||
|
||||
fun getClassNamesInPackage(packageFqName: FqName): Set<Name> =
|
||||
KotlinTopLevelClassByPackageIndex.getInstance()
|
||||
.get(packageFqName.asStringForIndexes(), project, scope)
|
||||
.mapNotNullTo(hashSetOf()) { it.nameAsName }
|
||||
|
||||
fun getKotlinClasses(
|
||||
nameFilter: (Name) -> Boolean,
|
||||
psiFilter: (element: KtClassOrObject) -> Boolean = { true }
|
||||
): Collection<KtClassOrObject> {
|
||||
val index = KotlinFullClassNameIndex.getInstance()
|
||||
return index.getAllKeys(project).asSequence()
|
||||
.onEach { ProgressManager.checkCanceled() }
|
||||
.filter { fqName -> nameFilter(getShortName(fqName)) }
|
||||
.flatMap { fqName -> index[fqName, project, scope] }
|
||||
.filter(psiFilter)
|
||||
.toList()
|
||||
}
|
||||
|
||||
fun getTopLevelCallables(nameFilter: (Name) -> Boolean): Collection<KtCallableDeclaration> {
|
||||
fun sequenceOfElements(index: StringStubIndexExtension<out KtCallableDeclaration>): Sequence<KtCallableDeclaration> =
|
||||
index.getAllKeys(project).asSequence()
|
||||
.onEach { ProgressManager.checkCanceled() }
|
||||
.filter { fqName -> nameFilter(getShortName(fqName)) }
|
||||
.flatMap { fqName -> index[fqName, project, scope] }
|
||||
.filter { it.receiverTypeReference == null }
|
||||
|
||||
val functions = sequenceOfElements(KotlinTopLevelFunctionFqnNameIndex.getInstance())
|
||||
val properties = sequenceOfElements(KotlinTopLevelPropertyFqnNameIndex.getInstance())
|
||||
|
||||
return (functions + properties).toList()
|
||||
}
|
||||
|
||||
fun getKotlinCallablesByName(name: Name): Collection<KtCallableDeclaration> {
|
||||
val functions: Sequence<KtCallableDeclaration> =
|
||||
KotlinFunctionShortNameIndex.getInstance().get(name.asString(), project, scope).asSequence()
|
||||
|
||||
val properties: Sequence<KtNamedDeclaration> =
|
||||
KotlinPropertyShortNameIndex.getInstance().get(name.asString(), project, scope).asSequence()
|
||||
|
||||
return (functions + properties)
|
||||
.filterIsInstance<KtCallableDeclaration>()
|
||||
.toList()
|
||||
}
|
||||
|
||||
fun getKotlinClassesByName(name: Name): Collection<KtClassOrObject> {
|
||||
return KotlinClassShortNameIndex.getInstance().get(name.asString(), project, scope)
|
||||
}
|
||||
|
||||
fun getTopLevelExtensions(nameFilter: (Name) -> Boolean, receiverTypeNames: Set<String>): Collection<KtCallableDeclaration> {
|
||||
val index = KotlinTopLevelExtensionsByReceiverTypeIndex.INSTANCE
|
||||
|
||||
return index.getAllKeys(project).asSequence()
|
||||
.onEach { ProgressManager.checkCanceled() }
|
||||
.filter { KotlinTopLevelExtensionsByReceiverTypeIndex.receiverTypeNameFromKey(it) in receiverTypeNames }
|
||||
.filter { nameFilter(Name.identifier(KotlinTopLevelExtensionsByReceiverTypeIndex.callableNameFromKey(it))) }
|
||||
.flatMap { key -> index[key, project, scope] }
|
||||
.toList()
|
||||
}
|
||||
|
||||
fun getPossibleTypeAliasExpansionNames(originalTypeName: String): Set<String> {
|
||||
val index = KotlinTypeAliasByExpansionShortNameIndex.INSTANCE
|
||||
val out = mutableSetOf<String>()
|
||||
|
||||
fun searchRecursively(typeName: String) {
|
||||
ProgressManager.checkCanceled()
|
||||
index[typeName, project, scope].asSequence()
|
||||
.mapNotNull { it.name }
|
||||
.filter { out.add(it) }
|
||||
.forEach(::searchRecursively)
|
||||
}
|
||||
|
||||
searchRecursively(originalTypeName)
|
||||
return out
|
||||
}
|
||||
|
||||
companion object {
|
||||
private fun CallableId.asStringForIndexes(): String =
|
||||
|
||||
Reference in New Issue
Block a user