KT-6028 Smart completion items priority

#KT-6028 Fixed
This commit is contained in:
Valentin Kipyatkov
2014-10-20 17:18:00 +04:00
parent e6dbfac232
commit 65c30902e7
8 changed files with 99 additions and 5 deletions
@@ -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<Weight> {
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<Weight> {
val o = element.getObject()
if (o is DeclarationDescriptorLookupObject) {
val elementFile = o.psiElement?.getContainingFile()
@@ -145,6 +145,6 @@ class StaticMembers(val bindingContext: BindingContext, val resolveSession: Reso
shortenReferences(context, context.getStartOffset(), context.getTailOffset())
}
}
}.assignSmartCompletionPriority(SmartCompletionItemPriority.STATIC_MEMBER)
}
}
@@ -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)
}
@@ -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>(lookupElement) {
@@ -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<LookupElement>{
@@ -137,6 +138,7 @@ fun MutableCollection<LookupElement>.addLookupElementsForNullable(factory: () ->
}
}
lookupElement = lookupElement!!.suppressAutoInsertion()
lookupElement = lookupElement!!.assignSmartCompletionPriority(SmartCompletionItemPriority.NULLABLE)
add(lookupElement!!.addTailAndNameSimilarity(matchedInfos))
}
@@ -152,6 +154,7 @@ fun MutableCollection<LookupElement>.addLookupElementsForNullable(factory: () ->
}
}
lookupElement = lookupElement!!.suppressAutoInsertion()
lookupElement = lookupElement!!.assignSmartCompletionPriority(SmartCompletionItemPriority.NULLABLE)
add(lookupElement!!.addTailAndNameSimilarity(matchedInfos))
}
}
@@ -192,3 +195,21 @@ fun <T : Any> T?.toList(): List<T> = if (this != null) listOf(this) else listOf(
fun <T : Any> T?.toSet(): Set<T> = 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<SmartCompletionItemPriority>("SMART_COMPLETION_ITEM_PRIORITY_KEY")
fun LookupElement.assignSmartCompletionPriority(priority: SmartCompletionItemPriority): LookupElement {
putUserData(SMART_COMPLETION_ITEM_PRIORITY_KEY, priority)
return this
}
@@ -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(<caret>)
}
}
// ORDER: "pFoo, s"
// ORDER: pFoo
// ORDER: nullableFoo
// ORDER: nullableFoo
// ORDER: this
// ORDER: local
// ORDER: nonNullable
// ORDER: nullableX
// ORDER: nullableX
// ORDER: C
@@ -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(<caret>)
}
// 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
@@ -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);
}
}