From 7016a087c302bf6b86d095a92b3e951a45128fd5 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Thu, 6 Aug 2015 22:42:40 +0300 Subject: [PATCH] Refactoring --- .../idea/completion/smart/SmartCompletion.kt | 116 ++++++++---------- .../smart/SmartCompletionSession.kt | 39 +++--- 2 files changed, 70 insertions(+), 85 deletions(-) diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletion.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletion.kt index 14d6d01f9ee..14062b4daf5 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletion.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletion.kt @@ -39,6 +39,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.types.JetType import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.typeUtil.makeNotNullable +import org.jetbrains.kotlin.utils.addToStdlib.check import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptySet import java.util.ArrayList import java.util.HashSet @@ -67,84 +68,47 @@ class SmartCompletion( public val smartCastCalculator: SmartCastCalculator = SmartCastCalculator(bindingContext, moduleDescriptor, expression) - public class Result( - val declarationFilter: ((DeclarationDescriptor) -> Collection)?, - val additionalItems: Collection, - val inheritanceSearcher: InheritanceItemsSearcher?) + public val descriptorFilter: ((DeclarationDescriptor) -> Collection)? + = { descriptor: DeclarationDescriptor -> filterDescriptor(descriptor).map { postProcess(it) } }.check { expectedInfos.isNotEmpty() } - public fun execute(): Result? { - fun postProcess(item: LookupElement): LookupElement { - return if (item.getUserData(KEEP_OLD_ARGUMENT_LIST_ON_TAB_KEY) == null) { - object : LookupElementDecorator(item) { - override fun handleInsert(context: InsertionContext) { - if (context.getCompletionChar() == Lookup.REPLACE_SELECT_CHAR) { - val offset = context.getOffsetMap().getOffset(OLD_ARGUMENTS_REPLACEMENT_OFFSET) - if (offset != -1) { - context.getDocument().deleteString(context.getTailOffset(), offset) - } - } + private fun filterDescriptor(descriptor: DeclarationDescriptor): Collection { + if (descriptor in descriptorsToSkip) return emptyList() - super.handleInsert(context) - } - } - } - else { - item + val result = SmartList() + val types = descriptor.fuzzyTypesForSmartCompletion(smartCastCalculator) + val infoClassifier = { expectedInfo: ExpectedInfo -> types.classifyExpectedInfo(expectedInfo) } + + result.addLookupElements(descriptor, expectedInfos, infoClassifier, noNameSimilarityForReturnItself = receiver == null) { descriptor -> + lookupElementFactory.createLookupElement(descriptor, bindingContext, true) + } + + if (descriptor is PropertyDescriptor) { + result.addLookupElements(descriptor, expectedInfos, infoClassifier) { descriptor -> + lookupElementFactory.createBackingFieldLookupElement(descriptor, inDescriptor, resolutionFacade) } } - val result = executeInternal() ?: return null - // TODO: code could be more simple, see KT-5726 - val additionalItems = result.additionalItems.map(::postProcess) - val inheritanceSearcher = result.inheritanceSearcher?.let { + if (receiver == null) { + toFunctionReferenceLookupElement(descriptor, expectedInfos.filterFunctionExpected())?.let { result.add(it) } + } + + return result + } + + public fun additionalItems(): Pair, InheritanceItemsSearcher?> { + val (items, inheritanceSearcher) = additionalItemsNoPostProcess() + val postProcessedItems = items.map { postProcess(it) } + val postProcessedSearcher = inheritanceSearcher?.let { object : InheritanceItemsSearcher { override fun search(nameFilter: (String) -> Boolean, consumer: (LookupElement) -> Unit) { it.search(nameFilter, { consumer(postProcess(it)) }) } } } - val filter = result.declarationFilter - return if (filter != null) - Result({ filter(it).map(::postProcess) }, additionalItems, inheritanceSearcher) - else - Result(null, additionalItems, inheritanceSearcher) + return postProcessedItems to postProcessedSearcher } - private fun executeInternal(): Result? { - val (additionalItems, inheritanceSearcher) = additionalItems() - - if (expectedInfos.isEmpty()) { - return Result(null, additionalItems, inheritanceSearcher) - } - - fun filterDeclaration(descriptor: DeclarationDescriptor): Collection { - if (descriptor in descriptorsToSkip) return emptyList() - - val result = SmartList() - val types = descriptor.fuzzyTypesForSmartCompletion(smartCastCalculator) - val infoClassifier = { expectedInfo: ExpectedInfo -> types.classifyExpectedInfo(expectedInfo) } - - result.addLookupElements(descriptor, expectedInfos, infoClassifier, noNameSimilarityForReturnItself = receiver == null) { descriptor -> - lookupElementFactory.createLookupElement(descriptor, bindingContext, true) - } - - if (descriptor is PropertyDescriptor) { - result.addLookupElements(descriptor, expectedInfos, infoClassifier) { descriptor -> - lookupElementFactory.createBackingFieldLookupElement(descriptor, inDescriptor, resolutionFacade) - } - } - - if (receiver == null) { - toFunctionReferenceLookupElement(descriptor, expectedInfos.filterFunctionExpected())?.let { result.add(it) } - } - - return result - } - - return Result(::filterDeclaration, additionalItems, inheritanceSearcher) - } - - public fun additionalItems(): Pair, InheritanceItemsSearcher?> { + private fun additionalItemsNoPostProcess(): Pair, InheritanceItemsSearcher?> { val asTypePositionItems = buildForAsTypePosition() if (asTypePositionItems != null) { assert(expectedInfos.isEmpty()) @@ -185,6 +149,28 @@ class SmartCompletion( return Pair(items, inheritanceSearcher) } + private fun postProcess(item: LookupElement): LookupElement { + if (forBasicCompletion) return item + + return if (item.getUserData(KEEP_OLD_ARGUMENT_LIST_ON_TAB_KEY) == null) { + object : LookupElementDecorator(item) { + override fun handleInsert(context: InsertionContext) { + if (context.getCompletionChar() == Lookup.REPLACE_SELECT_CHAR) { + val offset = context.getOffsetMap().getOffset(OLD_ARGUMENTS_REPLACEMENT_OFFSET) + if (offset != -1) { + context.getDocument().deleteString(context.getTailOffset(), offset) + } + } + + super.handleInsert(context) + } + } + } + else { + item + } + } + private fun MutableCollection.addThisItems(place: JetExpression, expectedInfos: Collection, smartCastCalculator: SmartCastCalculator) { if (shouldCompleteThisItems(prefixMatcher)) { val items = thisExpressionItems(bindingContext, place, prefixMatcher.getPrefix()) diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletionSession.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletionSession.kt index 739c4770aef..57c3126e6e6 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletionSession.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletionSession.kt @@ -50,33 +50,32 @@ class SmartCompletionSession(configuration: CompletionSessionConfiguration, para val completion = SmartCompletion(expression, resolutionFacade, moduleDescriptor, bindingContext, isVisibleFilter, inDescriptor, prefixMatcher, originalSearchScope, toFromOriginalFileMapper, lookupElementFactory) - val result = completion.execute() - if (result != null) { - collector.addElements(result.additionalItems) - if (nameExpression != null) { - val filter = result.declarationFilter - if (filter != null) { - referenceVariants.forEach { collector.addElements(filter(it)) } - flushToResultSet() + val (additionalItems, inheritanceSearcher) = completion.additionalItems() + collector.addElements(additionalItems) - processNonImported { collector.addElements(filter(it)) } - flushToResultSet() + if (nameExpression != null) { + val filter = completion.descriptorFilter + if (filter != null) { + referenceVariants.forEach { collector.addElements(filter(it)) } + flushToResultSet() - if (position.getContainingFile() is JetCodeFragment) { - getRuntimeReceiverTypeReferenceVariants().forEach { - collector.addElements(filter(it).map { it.withReceiverCast() }) - } - flushToResultSet() + processNonImported { collector.addElements(filter(it)) } + flushToResultSet() + + if (position.getContainingFile() is JetCodeFragment) { + getRuntimeReceiverTypeReferenceVariants().forEach { + collector.addElements(filter(it).map { it.withReceiverCast() }) } - } - - // it makes no sense to search inheritors if there is no reference because it means that we have prefix like "this@" - result.inheritanceSearcher?.search({ prefixMatcher.prefixMatches(it) }) { - collector.addElement(it) flushToResultSet() } } + + // it makes no sense to search inheritors if there is no reference because it means that we have prefix like "this@" + inheritanceSearcher?.search({ prefixMatcher.prefixMatches(it) }) { + collector.addElement(it) + flushToResultSet() + } } } }