From 65c30902e7341a86455c96729925dd4d321a8515 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Mon, 20 Oct 2014 17:18:00 +0400 Subject: [PATCH] KT-6028 Smart completion items priority #KT-6028 Fixed --- .../plugin/completion/CompletionSorting.kt | 13 +++++++-- .../plugin/completion/smart/StaticMembers.kt | 2 +- .../jet/plugin/completion/smart/ThisItems.kt | 4 ++- .../smart/TypeInstantiationItems.kt | 2 ++ .../jet/plugin/completion/smart/Utils.kt | 21 ++++++++++++++ .../weighers/smart/SmartPriority.kt | 22 +++++++++++++++ .../weighers/smart/SmartPriority2.kt | 28 +++++++++++++++++++ .../SmartCompletionWeigherTestGenerated.java | 12 ++++++++ 8 files changed, 99 insertions(+), 5 deletions(-) create mode 100644 idea/testData/completion/weighers/smart/SmartPriority.kt create mode 100644 idea/testData/completion/weighers/smart/SmartPriority2.kt diff --git a/idea/src/org/jetbrains/jet/plugin/completion/CompletionSorting.kt b/idea/src/org/jetbrains/jet/plugin/completion/CompletionSorting.kt index c5bc1a6fb6e..09a11d69b29 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/CompletionSorting.kt +++ b/idea/src/org/jetbrains/jet/plugin/completion/CompletionSorting.kt @@ -35,6 +35,8 @@ import org.jetbrains.jet.lang.resolve.ImportPath import org.jetbrains.jet.plugin.quickfix.ImportInsertHelper import com.intellij.codeInsight.completion.CompletionType import org.jetbrains.jet.plugin.completion.smart.NameSimilarityWeigher +import org.jetbrains.jet.plugin.completion.smart.SMART_COMPLETION_ITEM_PRIORITY_KEY +import org.jetbrains.jet.plugin.completion.smart.SmartCompletionItemPriority public fun CompletionResultSet.addKotlinSorting(parameters: CompletionParameters): CompletionResultSet { var sorter = CompletionSorter.defaultSorter(parameters, getPrefixMatcher())!! @@ -42,7 +44,7 @@ public fun CompletionResultSet.addKotlinSorting(parameters: CompletionParameters sorter = sorter.weighBefore("stats", PriorityWeigher, KindWeigher) if (parameters.getCompletionType() == CompletionType.SMART) { - sorter = sorter.weighBefore("kotlin.kind", NameSimilarityWeigher) + sorter = sorter.weighBefore("kotlin.kind", NameSimilarityWeigher, SmartCompletionPriorityWeigher) } sorter = sorter.weighAfter( @@ -60,6 +62,11 @@ private object PriorityWeigher : LookupElementWeigher("kotlin.priority") { = (element.getUserData(ITEM_PRIORITY_KEY) ?: ItemPriority.DEFAULT).ordinal() } +private object SmartCompletionPriorityWeigher : LookupElementWeigher("kotlin.smartCompletionPriority") { + override fun weigh(element: LookupElement, context: WeighingContext) + = (element.getUserData(SMART_COMPLETION_ITEM_PRIORITY_KEY) ?: SmartCompletionItemPriority.DEFAULT).ordinal() +} + private object KindWeigher : LookupElementWeigher("kotlin.kind") { private enum class Weight { localOrParameter @@ -69,7 +76,7 @@ private object KindWeigher : LookupElementWeigher("kotlin.kind") { packages } - override fun weigh(element: LookupElement): Weight { + override fun weigh(element: LookupElement): Comparable { val o = element.getObject() return when (o) { is DeclarationDescriptorLookupObject -> when (o.descriptor) { @@ -109,7 +116,7 @@ private class JetDeclarationRemotenessWeigher(private val file: JetFile) : Looku notImported } - override fun weigh(element: LookupElement): Weight { + override fun weigh(element: LookupElement): Comparable { val o = element.getObject() if (o is DeclarationDescriptorLookupObject) { val elementFile = o.psiElement?.getContainingFile() diff --git a/idea/src/org/jetbrains/jet/plugin/completion/smart/StaticMembers.kt b/idea/src/org/jetbrains/jet/plugin/completion/smart/StaticMembers.kt index 4767e6b9f35..98a8cf9f89c 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/smart/StaticMembers.kt +++ b/idea/src/org/jetbrains/jet/plugin/completion/smart/StaticMembers.kt @@ -145,6 +145,6 @@ class StaticMembers(val bindingContext: BindingContext, val resolveSession: Reso shortenReferences(context, context.getStartOffset(), context.getTailOffset()) } - } + }.assignSmartCompletionPriority(SmartCompletionItemPriority.STATIC_MEMBER) } } diff --git a/idea/src/org/jetbrains/jet/plugin/completion/smart/ThisItems.kt b/idea/src/org/jetbrains/jet/plugin/completion/smart/ThisItems.kt index a179207fd42..61171e21730 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/smart/ThisItems.kt +++ b/idea/src/org/jetbrains/jet/plugin/completion/smart/ThisItems.kt @@ -53,7 +53,9 @@ class ThisItems(val bindingContext: BindingContext) { //val expressionText = if (i == 0) "this" else "this@" + (thisQualifierName(receiver, bindingContext) ?: return null) val qualifier = if (i == 0) null else (thisQualifierName(receiver) ?: return null) val expressionText = if (qualifier == null) "this" else "this@" + qualifier - return LookupElementBuilder.create(expressionText).withTypeText(DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(thisType)) + return LookupElementBuilder.create(expressionText) + .withTypeText(DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(thisType)) + .assignSmartCompletionPriority(SmartCompletionItemPriority.THIS) } collection.addLookupElements(expectedInfos, classifier, ::lookupElementFactory) } diff --git a/idea/src/org/jetbrains/jet/plugin/completion/smart/TypeInstantiationItems.kt b/idea/src/org/jetbrains/jet/plugin/completion/smart/TypeInstantiationItems.kt index 477eec4bac2..3206fb13227 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/smart/TypeInstantiationItems.kt +++ b/idea/src/org/jetbrains/jet/plugin/completion/smart/TypeInstantiationItems.kt @@ -88,6 +88,7 @@ class TypeInstantiationItems(val resolveSession: ResolveSessionForBodies, val vi ImplementMethodsHandler().invoke(context.getProject(), editor, context.getFile(), true) } lookupElement = lookupElement.suppressAutoInsertion() + lookupElement = lookupElement.assignSmartCompletionPriority(SmartCompletionItemPriority.ANONYMOUS_OBJECT) } else { //TODO: when constructor has one parameter of lambda type with more than one parameter, generate special additional item @@ -115,6 +116,7 @@ class TypeInstantiationItems(val resolveSession: ResolveSessionForBodies, val vi if (baseInsertHandler.lambdaInfo != null) { lookupElement.putUserData(KotlinCompletionCharFilter.ACCEPT_OPENING_BRACE, true) } + lookupElement = lookupElement.assignSmartCompletionPriority(SmartCompletionItemPriority.INSTANTIATION) } lookupElement = object: LookupElementDecorator(lookupElement) { diff --git a/idea/src/org/jetbrains/jet/plugin/completion/smart/Utils.kt b/idea/src/org/jetbrains/jet/plugin/completion/smart/Utils.kt index f57f51af4fe..09ba6ff5f84 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/smart/Utils.kt +++ b/idea/src/org/jetbrains/jet/plugin/completion/smart/Utils.kt @@ -36,6 +36,7 @@ import org.jetbrains.jet.plugin.project.ResolveSessionForBodies import org.jetbrains.jet.plugin.completion.handlers.WithTailInsertHandler import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor +import com.intellij.openapi.util.Key class ArtificialElementInsertHandler( val textBeforeCaret: String, val textAfterCaret: String, val shortenRefs: Boolean) : InsertHandler{ @@ -137,6 +138,7 @@ fun MutableCollection.addLookupElementsForNullable(factory: () -> } } lookupElement = lookupElement!!.suppressAutoInsertion() + lookupElement = lookupElement!!.assignSmartCompletionPriority(SmartCompletionItemPriority.NULLABLE) add(lookupElement!!.addTailAndNameSimilarity(matchedInfos)) } @@ -152,6 +154,7 @@ fun MutableCollection.addLookupElementsForNullable(factory: () -> } } lookupElement = lookupElement!!.suppressAutoInsertion() + lookupElement = lookupElement!!.assignSmartCompletionPriority(SmartCompletionItemPriority.NULLABLE) add(lookupElement!!.addTailAndNameSimilarity(matchedInfos)) } } @@ -192,3 +195,21 @@ fun T?.toList(): List = if (this != null) listOf(this) else listOf( fun T?.toSet(): Set = if (this != null) setOf(this) else setOf() fun String?.isNullOrEmpty() = this == null || this.isEmpty() + +enum class SmartCompletionItemPriority { + /*IT*/ //TODO + THIS + DEFAULT + NULLABLE + STATIC_MEMBER + INSTANTIATION + ANONYMOUS_OBJECT +} + +val SMART_COMPLETION_ITEM_PRIORITY_KEY = Key("SMART_COMPLETION_ITEM_PRIORITY_KEY") + +fun LookupElement.assignSmartCompletionPriority(priority: SmartCompletionItemPriority): LookupElement { + putUserData(SMART_COMPLETION_ITEM_PRIORITY_KEY, priority) + return this +} + diff --git a/idea/testData/completion/weighers/smart/SmartPriority.kt b/idea/testData/completion/weighers/smart/SmartPriority.kt new file mode 100644 index 00000000000..6db78fb1537 --- /dev/null +++ b/idea/testData/completion/weighers/smart/SmartPriority.kt @@ -0,0 +1,22 @@ +var nonNullable: C = C() + +class C { + var nullableX: C? = null + var nullableFoo: C? = null + + fun foo(pFoo: C, s: String) { + val local = C() + foo() + } +} + +// ORDER: "pFoo, s" +// ORDER: pFoo +// ORDER: nullableFoo +// ORDER: nullableFoo +// ORDER: this +// ORDER: local +// ORDER: nonNullable +// ORDER: nullableX +// ORDER: nullableX +// ORDER: C diff --git a/idea/testData/completion/weighers/smart/SmartPriority2.kt b/idea/testData/completion/weighers/smart/SmartPriority2.kt new file mode 100644 index 00000000000..6377e81d09a --- /dev/null +++ b/idea/testData/completion/weighers/smart/SmartPriority2.kt @@ -0,0 +1,28 @@ +var nonNullable: C = C() +var nullableX: C? = null +var nullableFoo: C? = null + +abstract class C { + class object { + val INSTANCE_X = C() + val INSTANCE_FOO = C() + } +} + +fun foo(pFoo: C, s: String) { + val local = C() + foo() +} + + +// ORDER: "pFoo, s" +// ORDER: pFoo +// ORDER: nullableFoo +// ORDER: nullableFoo +// ORDER: C.INSTANCE_FOO +// ORDER: local +// ORDER: nonNullable +// ORDER: nullableX +// ORDER: nullableX +// ORDER: C.INSTANCE_X +// ORDER: object diff --git a/idea/tests/org/jetbrains/jet/completion/weighers/SmartCompletionWeigherTestGenerated.java b/idea/tests/org/jetbrains/jet/completion/weighers/SmartCompletionWeigherTestGenerated.java index 9f02abe0a91..0b233d08986 100644 --- a/idea/tests/org/jetbrains/jet/completion/weighers/SmartCompletionWeigherTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/completion/weighers/SmartCompletionWeigherTestGenerated.java @@ -161,4 +161,16 @@ public class SmartCompletionWeigherTestGenerated extends AbstractSmartCompletion String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/weighers/smart/NameSimilaritySorterPlacement.kt"); doTest(fileName); } + + @TestMetadata("SmartPriority.kt") + public void testSmartPriority() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/weighers/smart/SmartPriority.kt"); + doTest(fileName); + } + + @TestMetadata("SmartPriority2.kt") + public void testSmartPriority2() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/weighers/smart/SmartPriority2.kt"); + doTest(fileName); + } }