Items filtered out from smart completion take lower priority in ordinary one + lower priority for Enum.valueOf

This commit is contained in:
Valentin Kipyatkov
2015-08-06 16:05:46 +03:00
parent 2a8dcabbce
commit be0a0e4401
7 changed files with 61 additions and 20 deletions
@@ -100,10 +100,9 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
else
null
private val smartCastCalculator = if (expression != null)
SmartCastCalculator(bindingContext, moduleDescriptor, expression)
else
null
private val smartCompletion = expression?.let {
SmartCompletion(it, resolutionFacade, moduleDescriptor, bindingContext, isVisibleFilter, inDescriptor, prefixMatcher, GlobalSearchScope.EMPTY_SCOPE, toFromOriginalFileMapper, lookupElementFactory)
}
private fun calcCompletionKind(): CompletionKind {
if (NamedArgumentCompletion.isOnlyNamedArgumentExpected(position)) {
@@ -252,12 +251,9 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
}
if (completionKind != CompletionKind.KEYWORDS_ONLY) {
if (expectedInfos != null && expectedInfos.isNotEmpty()) {
if (smartCompletion != null && expectedInfos != null && expectedInfos.isNotEmpty()) {
@suppress("UNUSED_VARIABLE") // we don't use InheritanceSearcher
val (additionalItems, inheritanceSearcher) = SmartCompletion(
expression!!, resolutionFacade, moduleDescriptor, bindingContext, isVisibleFilter, inDescriptor,
prefixMatcher, GlobalSearchScope.EMPTY_SCOPE, toFromOriginalFileMapper, lookupElementFactory)
.additionalItems(expectedInfos, smartCastCalculator!!, forOrdinaryCompletion = true)
val (additionalItems, inheritanceSearcher) = smartCompletion.additionalItems(expectedInfos, forOrdinaryCompletion = true)
collector.addElements(additionalItems)
}
@@ -304,8 +300,8 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
sorter = sorter.weighBefore(DeprecatedWeigher.toString(), ParameterNameAndTypeCompletion.Weigher)
}
if (expectedInfos != null && expectedInfos.isNotEmpty()) {
sorter = sorter.weighBefore(KindWeigher.toString(), ExpectedInfoMatchWeigher(expectedInfos, smartCastCalculator!!), SmartCompletionPriorityWeigher)
if (smartCompletion != null && expectedInfos != null && expectedInfos.isNotEmpty()) {
sorter = sorter.weighBefore(KindWeigher.toString(), ExpectedInfoMatchWeigher(expectedInfos, smartCompletion), SmartCompletionPriorityWeigher)
}
return sorter
@@ -19,6 +19,8 @@ package org.jetbrains.kotlin.idea.completion
import com.intellij.codeInsight.lookup.LookupElement
import com.intellij.codeInsight.lookup.LookupElementWeigher
import com.intellij.codeInsight.lookup.WeighingContext
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.idea.completion.smart.*
@@ -70,6 +72,7 @@ object KindWeigher : LookupElementWeigher("kotlin.kind") {
when (descriptor) {
is VariableDescriptor -> CompoundWeight(Weight.variable, element.getUserData(CALLABLE_WEIGHT_KEY))
is FunctionDescriptor -> CompoundWeight(Weight.function, element.getUserData(CALLABLE_WEIGHT_KEY))
is ClassDescriptor -> if (descriptor.kind == ClassKind.ENUM_ENTRY) CompoundWeight(Weight.variable) else CompoundWeight(Weight.default)
else -> CompoundWeight(Weight.default)
}
}
@@ -185,9 +188,12 @@ class DeclarationRemotenessWeigher(private val file: JetFile) : LookupElementWei
class ExpectedInfoMatchWeigher(
private val expectedInfos: Collection<ExpectedInfo>,
private val smartCastCalculator: SmartCastCalculator
private val smartCompletion: SmartCompletion
) : LookupElementWeigher("kotlin.expectedInfoMatch") {
private val smartCastCalculator = smartCompletion.smartCastCalculator
private val descriptorsToSkip = smartCompletion.descriptorsToSkip
private fun fullMatchWeight(nameSimilarity: Int): Long {
return -((3L shl 32) + nameSimilarity)
}
@@ -202,6 +208,8 @@ class ExpectedInfoMatchWeigher(
private val NO_MATCH_WEIGHT = 0L
private val DESCRIPTOR_TO_SKIP_WEIGHT = 1L // if descriptor is skipped from smart completion then it's probably irrelevant
override fun weigh(element: LookupElement): Long {
val smartCompletionPriority = element.getUserData(SMART_COMPLETION_ITEM_PRIORITY_KEY)
if (smartCompletionPriority != null) { // it's an "additional item" came from smart completion, don't match it against expected type
@@ -213,6 +221,7 @@ class ExpectedInfoMatchWeigher(
val (fuzzyTypes, name) = when (o) {
is DeclarationLookupObject -> {
val descriptor = o.descriptor ?: return NO_MATCH_WEIGHT
if (descriptor in descriptorsToSkip) return DESCRIPTOR_TO_SKIP_WEIGHT
descriptor.fuzzyTypesForSmartCompletion(smartCastCalculator) to descriptor.name
}
@@ -61,6 +61,8 @@ class SmartCompletion(
) {
private val receiver = if (expression is JetSimpleNameExpression) expression.getReceiverExpression() else null
public val smartCastCalculator: SmartCastCalculator = SmartCastCalculator(bindingContext, moduleDescriptor, expression)
public class Result(
val declarationFilter: ((DeclarationDescriptor) -> Collection<LookupElement>)?,
val additionalItems: Collection<LookupElement>,
@@ -108,11 +110,8 @@ class SmartCompletion(
val asTypePositionResult = buildForAsTypePosition()
if (asTypePositionResult != null) return asTypePositionResult
val expressionWithType = expression.toExpressionWithType()
val expectedInfos = calcExpectedInfos(expressionWithType) ?: return null
val smartCastCalculator = SmartCastCalculator(bindingContext, moduleDescriptor, expression)
val expectedInfos = calcExpectedInfos(expression.toExpressionWithType())
if (expectedInfos == null || expectedInfos.isEmpty()) return null
fun filterDeclaration(descriptor: DeclarationDescriptor): Collection<LookupElement> {
if (descriptor in descriptorsToSkip) return emptyList()
@@ -138,14 +137,13 @@ class SmartCompletion(
return result
}
val (additionalItems, inheritanceSearcher) = additionalItems(expectedInfos, smartCastCalculator)
val (additionalItems, inheritanceSearcher) = additionalItems(expectedInfos)
return Result(::filterDeclaration, additionalItems, inheritanceSearcher)
}
public fun additionalItems(
expectedInfos: Collection<ExpectedInfo>,
smartCastCalculator: SmartCastCalculator,
forOrdinaryCompletion: Boolean = false
): Pair<Collection<LookupElement>, InheritanceItemsSearcher?> {
val items = ArrayList<LookupElement>()
@@ -7,7 +7,7 @@ fun foo(): EE {
return E<caret>
}
// ORDER: valueOf
// ORDER: A
// ORDER: B
// ORDER: valueOf
// ORDER: EE
@@ -0,0 +1,7 @@
class X
fun foo(aaa: X, bbb: X) {
if (aaa == <caret>)
}
// ORDER: bbb
@@ -0,0 +1,19 @@
enum class E {
A,
B,
C
}
fun foo(e: E) {
when (e) {
E.A -> {}
E.<caret>
}
}
// ORDER: B
// ORDER: C
// ORDER: valueOf
// ORDER: values
// ORDER: A
@@ -199,11 +199,23 @@ public class BasicCompletionWeigherTestGenerated extends AbstractBasicCompletion
doTest(fileName);
}
@TestMetadata("NoStupidComparison.kt")
public void testNoStupidComparison() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/expectedInfo/NoStupidComparison.kt");
doTest(fileName);
}
@TestMetadata("PreferMatchingThis.kt")
public void testPreferMatchingThis() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/expectedInfo/PreferMatchingThis.kt");
doTest(fileName);
}
@TestMetadata("WhenByEnum.kt")
public void testWhenByEnum() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/expectedInfo/WhenByEnum.kt");
doTest(fileName);
}
}
@TestMetadata("idea/idea-completion/testData/weighers/basic/parameterNameAndType")