Performance optimization for completion after "ge", "se", etc

This commit is contained in:
Valentin Kipyatkov
2016-10-27 11:24:36 +03:00
parent 2b2ef5a349
commit 6c17fa7736
2 changed files with 36 additions and 23 deletions
@@ -120,16 +120,7 @@ abstract class CompletionSession(
protected val prefixMatcher = CamelHumpMatcher(prefix) protected val prefixMatcher = CamelHumpMatcher(prefix)
private val descriptorStringNameFilter: (String) -> Boolean = run { protected val descriptorNameFilter: (String) -> Boolean = prefixMatcher.asStringNameFilter()
val nameFilter = prefixMatcher.asStringNameFilter()
val getOrSetPrefix = listOf("get", "set", "ge", "se", "g", "s").firstOrNull { prefix.startsWith(it) }
if (getOrSetPrefix != null)
prefixMatcher.cloneWithPrefix(prefix.removePrefix(getOrSetPrefix).decapitalizeSmart()).asStringNameFilter() or nameFilter
else
nameFilter
}
protected val descriptorNameFilter: (Name) -> Boolean = descriptorStringNameFilter.toNameFilter()
protected val isVisibleFilter: (DeclarationDescriptor) -> Boolean = { isVisibleDescriptor(it, completeNonAccessible = configuration.nonAccessibleDeclarations) } protected val isVisibleFilter: (DeclarationDescriptor) -> Boolean = { isVisibleDescriptor(it, completeNonAccessible = configuration.nonAccessibleDeclarations) }
protected val isVisibleFilterCheckAlways: (DeclarationDescriptor) -> Boolean = { isVisibleDescriptor(it, completeNonAccessible = false) } protected val isVisibleFilterCheckAlways: (DeclarationDescriptor) -> Boolean = { isVisibleDescriptor(it, completeNonAccessible = false) }
@@ -307,23 +298,45 @@ abstract class CompletionSession(
referenceVariants?.let { ReferenceVariants(referenceVariantsHelper.excludeNonInitializedVariable(it.imported, position), it.notImportedExtensions) } referenceVariants?.let { ReferenceVariants(referenceVariantsHelper.excludeNonInitializedVariable(it.imported, position), it.notImportedExtensions) }
} }
private fun collectReferenceVariants(descriptorKindFilter: DescriptorKindFilter, nameExpression: KtSimpleNameExpression, runtimeReceiver: ExpressionReceiver? = null): ReferenceVariants { private fun collectReferenceVariants(
var variants = referenceVariantsHelper.getReferenceVariants( descriptorKindFilter: DescriptorKindFilter,
nameExpression, nameExpression: KtSimpleNameExpression,
descriptorKindFilter, runtimeReceiver: ExpressionReceiver? = null
descriptorNameFilter, ): ReferenceVariants {
filterOutJavaGettersAndSetters = false, fun getReferenceVariants(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection<DeclarationDescriptor> {
filterOutShadowed = false, return referenceVariantsHelper.getReferenceVariants(
excludeNonInitializedVariable = false, nameExpression,
useReceiverType = runtimeReceiver?.type) kindFilter,
nameFilter,
filterOutJavaGettersAndSetters = false,
filterOutShadowed = false,
excludeNonInitializedVariable = false,
useReceiverType = runtimeReceiver?.type)
}
var variants = getReferenceVariants(descriptorKindFilter, descriptorNameFilter.toNameFilter())
val getOrSetPrefix = listOf("get", "set", "ge", "se", "g", "s").firstOrNull { prefix.startsWith(it) }
val additionalPropertyNameFilter: ((String) -> Boolean)? = run {
getOrSetPrefix?.let { prefixMatcher.cloneWithPrefix(prefix.removePrefix(getOrSetPrefix).decapitalizeSmart()).asStringNameFilter() }
}
if (additionalPropertyNameFilter != null) {
variants += getReferenceVariants(descriptorKindFilter.intersect(DescriptorKindFilter.VARIABLES),
additionalPropertyNameFilter.toNameFilter())
variants = variants.distinct()
}
var notImportedExtensions: Collection<CallableDescriptor> = emptyList() var notImportedExtensions: Collection<CallableDescriptor> = emptyList()
if (callTypeAndReceiver.shouldCompleteCallableExtensions()) { if (callTypeAndReceiver.shouldCompleteCallableExtensions()) {
val indicesHelper = indicesHelper(true) val indicesHelper = indicesHelper(true)
val extensions = if (runtimeReceiver != null) val nameFilter = if (additionalPropertyNameFilter != null)
indicesHelper.getCallableTopLevelExtensions(callTypeAndReceiver, listOf(runtimeReceiver.type), descriptorStringNameFilter) descriptorNameFilter or additionalPropertyNameFilter
else else
indicesHelper.getCallableTopLevelExtensions(callTypeAndReceiver, expression!!, bindingContext, descriptorStringNameFilter) descriptorNameFilter
val extensions = if (runtimeReceiver != null)
indicesHelper.getCallableTopLevelExtensions(callTypeAndReceiver, listOf(runtimeReceiver.type), nameFilter)
else
indicesHelper.getCallableTopLevelExtensions(callTypeAndReceiver, expression!!, bindingContext, nameFilter)
val pair = extensions.partition { isImportableDescriptorImported(it) } val pair = extensions.partition { isImportableDescriptorImported(it) }
variants += pair.first variants += pair.first
@@ -116,7 +116,7 @@ class KDocNameCompletionSession(
return true return true
} }
scope.collectDescriptorsFiltered(nameFilter = descriptorNameFilter).filter(::isApplicable).forEach { scope.collectDescriptorsFiltered(nameFilter = descriptorNameFilter.toNameFilter()).filter(::isApplicable).forEach {
val element = basicLookupElementFactory.createLookupElement(it, parametersAndTypeGrayed = true) val element = basicLookupElementFactory.createLookupElement(it, parametersAndTypeGrayed = true)
collector.addElement(object: LookupElementDecorator<LookupElement>(element) { collector.addElement(object: LookupElementDecorator<LookupElement>(element) {
override fun handleInsert(context: InsertionContext?) { override fun handleInsert(context: InsertionContext?) {