More efficient getting of top-level callables
This commit is contained in:
@@ -158,7 +158,7 @@ abstract class CompletionSession(
|
|||||||
|
|
||||||
protected fun indicesHelper(mayIncludeInaccessible: Boolean): KotlinIndicesHelper {
|
protected fun indicesHelper(mayIncludeInaccessible: Boolean): KotlinIndicesHelper {
|
||||||
val filter = if (mayIncludeInaccessible) isVisibleFilter else isVisibleFilterCheckAlways
|
val filter = if (mayIncludeInaccessible) isVisibleFilter else isVisibleFilterCheckAlways
|
||||||
return KotlinIndicesHelper(resolutionFacade, searchScope, filter, visibilityFilterMayIncludeAccessible = mayIncludeInaccessible)
|
return KotlinIndicesHelper(resolutionFacade, searchScope, filter, filterOutPrivate = !mayIncludeInaccessible)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected val toFromOriginalFileMapper: ToFromOriginalFileMapper
|
protected val toFromOriginalFileMapper: ToFromOriginalFileMapper
|
||||||
@@ -394,9 +394,10 @@ abstract class CompletionSession(
|
|||||||
return callTypeAndReceiver.receiver == null
|
return callTypeAndReceiver.receiver == null
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun getTopLevelCallables(): Collection<DeclarationDescriptor> {
|
protected fun getTopLevelCallables(): Collection<CallableDescriptor> {
|
||||||
return indicesHelper(true).getTopLevelCallables({ prefixMatcher.prefixMatches(it) })
|
val result = LinkedHashSet<CallableDescriptor>()
|
||||||
.filterShadowedNonImported()
|
indicesHelper(true).processTopLevelCallables({ prefixMatcher.prefixMatches(it) }) { result.add(it) }
|
||||||
|
return result.filterShadowedNonImported()
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun CallTypeAndReceiver<*, *>.shouldCompleteCallableExtensions(): Boolean {
|
protected fun CallTypeAndReceiver<*, *>.shouldCompleteCallableExtensions(): Boolean {
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ public class KotlinIndicesHelper(
|
|||||||
private val scope: GlobalSearchScope,
|
private val scope: GlobalSearchScope,
|
||||||
visibilityFilter: (DeclarationDescriptor) -> Boolean,
|
visibilityFilter: (DeclarationDescriptor) -> Boolean,
|
||||||
applyExcludeSettings: Boolean = true,
|
applyExcludeSettings: Boolean = true,
|
||||||
private val visibilityFilterMayIncludeAccessible: Boolean = false
|
private val filterOutPrivate: Boolean = true
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private val moduleDescriptor = resolutionFacade.moduleDescriptor
|
private val moduleDescriptor = resolutionFacade.moduleDescriptor
|
||||||
@@ -91,16 +91,26 @@ public class KotlinIndicesHelper(
|
|||||||
index.get(name, project, scope).filterTo(this) { it.getParent() is KtFile && it.getReceiverTypeReference() == null }
|
index.get(name, project, scope).filterTo(this) { it.getParent() is KtFile && it.getReceiverTypeReference() == null }
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun getTopLevelCallables(nameFilter: (String) -> Boolean): Collection<CallableDescriptor> {
|
public fun processTopLevelCallables(nameFilter: (String) -> Boolean, processor: (CallableDescriptor) -> Unit) {
|
||||||
return (KotlinTopLevelFunctionFqnNameIndex.getInstance().getAllKeys(project).asSequence() +
|
fun processIndex(index: StringStubIndexExtension<out KtCallableDeclaration>) {
|
||||||
KotlinTopLevelPropertyFqnNameIndex.getInstance().getAllKeys(project).asSequence())
|
for (key in index.getAllKeys(project)) {
|
||||||
.map { FqName(it) }
|
ProgressManager.checkCanceled()
|
||||||
.filter {
|
if (!nameFilter(key.substringAfterLast('.', key))) continue
|
||||||
ProgressManager.checkCanceled()
|
|
||||||
nameFilter(it.shortName().asString())
|
for (declaration in index.get(key, project, scope)) {
|
||||||
|
if (declaration.receiverTypeReference != null) continue
|
||||||
|
if (filterOutPrivate && declaration.hasModifier(KtTokens.PRIVATE_KEYWORD)) continue
|
||||||
|
|
||||||
|
for (descriptor in declaration.resolveToDescriptorsWithHack()) {
|
||||||
|
if (descriptorFilter(descriptor)) {
|
||||||
|
processor(descriptor)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.toSet()
|
}
|
||||||
.flatMap { findTopLevelCallables(it).filter(descriptorFilter) }
|
}
|
||||||
|
processIndex(KotlinTopLevelFunctionFqnNameIndex.getInstance())
|
||||||
|
processIndex(KotlinTopLevelPropertyFqnNameIndex.getInstance())
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun getCallableTopLevelExtensions(
|
public fun getCallableTopLevelExtensions(
|
||||||
@@ -211,7 +221,7 @@ public class KotlinIndicesHelper(
|
|||||||
for (declaration in index.get(name, project, scope)) {
|
for (declaration in index.get(name, project, scope)) {
|
||||||
val objectDeclaration = declaration.parent.parent as? KtObjectDeclaration ?: continue
|
val objectDeclaration = declaration.parent.parent as? KtObjectDeclaration ?: continue
|
||||||
if (objectDeclaration.isObjectLiteral()) continue
|
if (objectDeclaration.isObjectLiteral()) continue
|
||||||
if (!visibilityFilterMayIncludeAccessible && declaration.hasModifier(KtTokens.PRIVATE_KEYWORD)) continue
|
if (filterOutPrivate && declaration.hasModifier(KtTokens.PRIVATE_KEYWORD)) continue
|
||||||
if (!filter(declaration, objectDeclaration)) continue
|
if (!filter(declaration, objectDeclaration)) continue
|
||||||
for (descriptor in declaration.resolveToDescriptorsWithHack()) {
|
for (descriptor in declaration.resolveToDescriptorsWithHack()) {
|
||||||
if (descriptorKindFilter.accepts(descriptor) && descriptorFilter(descriptor)) {
|
if (descriptorKindFilter.accepts(descriptor) && descriptorFilter(descriptor)) {
|
||||||
@@ -244,7 +254,7 @@ public class KotlinIndicesHelper(
|
|||||||
|
|
||||||
for (method in shortNamesCache.getMethodsByName(name, scope)) {
|
for (method in shortNamesCache.getMethodsByName(name, scope)) {
|
||||||
if (!method.hasModifierProperty(PsiModifier.STATIC)) continue
|
if (!method.hasModifierProperty(PsiModifier.STATIC)) continue
|
||||||
if (!visibilityFilterMayIncludeAccessible && method.hasModifierProperty(PsiModifier.PRIVATE)) continue
|
if (filterOutPrivate && method.hasModifierProperty(PsiModifier.PRIVATE)) continue
|
||||||
if (method.containingClass?.parent !is PsiFile) continue // only top-level classes
|
if (method.containingClass?.parent !is PsiFile) continue // only top-level classes
|
||||||
val descriptor = method.getJavaMethodDescriptor(resolutionFacade) ?: continue
|
val descriptor = method.getJavaMethodDescriptor(resolutionFacade) ?: continue
|
||||||
val container = descriptor.containingDeclaration as? ClassDescriptor ?: continue
|
val container = descriptor.containingDeclaration as? ClassDescriptor ?: continue
|
||||||
@@ -268,7 +278,7 @@ public class KotlinIndicesHelper(
|
|||||||
|
|
||||||
for (field in shortNamesCache.getFieldsByName(name, scope)) {
|
for (field in shortNamesCache.getFieldsByName(name, scope)) {
|
||||||
if (!field.hasModifierProperty(PsiModifier.STATIC)) continue
|
if (!field.hasModifierProperty(PsiModifier.STATIC)) continue
|
||||||
if (!visibilityFilterMayIncludeAccessible && field.hasModifierProperty(PsiModifier.PRIVATE)) continue
|
if (filterOutPrivate && field.hasModifierProperty(PsiModifier.PRIVATE)) continue
|
||||||
val descriptor = field.getJavaFieldDescriptor() ?: continue
|
val descriptor = field.getJavaFieldDescriptor() ?: continue
|
||||||
if (descriptorKindFilter.accepts(descriptor) && descriptorFilter(descriptor)) {
|
if (descriptorKindFilter.accepts(descriptor) && descriptorFilter(descriptor)) {
|
||||||
processor(descriptor)
|
processor(descriptor)
|
||||||
@@ -279,12 +289,6 @@ public class KotlinIndicesHelper(
|
|||||||
shortNamesCache.processAllFieldNames(fieldNamesProcessor, scope, idFilter)
|
shortNamesCache.processAllFieldNames(fieldNamesProcessor, scope, idFilter)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findTopLevelCallables(fqName: FqName): Collection<CallableDescriptor> {
|
|
||||||
return resolutionFacade.resolveImportReference(moduleDescriptor, fqName)
|
|
||||||
.filterIsInstance<CallableDescriptor>()
|
|
||||||
.filter { it.getExtensionReceiverParameter() == null }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun isExcludedFromAutoImport(descriptor: DeclarationDescriptor): Boolean {
|
private fun isExcludedFromAutoImport(descriptor: DeclarationDescriptor): Boolean {
|
||||||
val fqName = descriptor.importableFqName?.asString() ?: return false
|
val fqName = descriptor.importableFqName?.asString() ?: return false
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user