From 84ba634c3ed504c15417eb3c5363f0ff2a95f597 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Thu, 18 Jun 2015 22:03:15 +0300 Subject: [PATCH] Parameter names from current file get higher priority + number of occurrences matters --- .../idea/completion/CompletionSorting.kt | 2 +- .../ParameterNameAndTypeCompletion.kt | 43 ++++++++++++------- .../FromCurrentFilePriority.kt | 16 +++++++ .../BasicCompletionWeigherTestGenerated.java | 6 +++ 4 files changed, 50 insertions(+), 17 deletions(-) create mode 100644 idea/idea-completion/testData/weighers/basic/parameterNameAndType/FromCurrentFilePriority.kt diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionSorting.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionSorting.kt index 190e8da09e8..067f38b1e6b 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionSorting.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionSorting.kt @@ -44,7 +44,7 @@ import java.util.HashSet public fun CompletionResultSet.addKotlinSorting(parameters: CompletionParameters): CompletionResultSet { var sorter = CompletionSorter.defaultSorter(parameters, getPrefixMatcher())!! - sorter = sorter.weighBefore("stats", DeprecatedWeigher, PriorityWeigher, KindWeigher) + sorter = sorter.weighBefore("stats", ParameterNameAndTypeCompletion.Weigher, DeprecatedWeigher, PriorityWeigher, KindWeigher) if (parameters.getCompletionType() == CompletionType.SMART) { sorter = sorter.weighBefore("kotlin.kind", NameSimilarityWeigher, SmartCompletionPriorityWeigher) diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ParameterNameAndTypeCompletion.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ParameterNameAndTypeCompletion.kt index fb58239b6ed..842b7c9fa55 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ParameterNameAndTypeCompletion.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ParameterNameAndTypeCompletion.kt @@ -20,9 +20,8 @@ import com.intellij.codeInsight.completion.CompletionInitializationContext import com.intellij.codeInsight.completion.CompletionParameters import com.intellij.codeInsight.completion.InsertionContext import com.intellij.codeInsight.completion.PrefixMatcher -import com.intellij.codeInsight.lookup.LookupElement -import com.intellij.codeInsight.lookup.LookupElementDecorator -import com.intellij.codeInsight.lookup.LookupElementPresentation +import com.intellij.codeInsight.lookup.* +import com.intellij.openapi.util.Key import com.intellij.psi.PsiClass import com.intellij.psi.PsiElement import com.intellij.psi.codeStyle.CodeStyleSettingsManager @@ -34,7 +33,6 @@ import org.jetbrains.kotlin.idea.core.KotlinIndicesHelper import org.jetbrains.kotlin.idea.core.formatter.JetCodeStyleSettings import org.jetbrains.kotlin.idea.core.refactoring.EmptyValidator import org.jetbrains.kotlin.idea.core.refactoring.JetNameSuggester -import org.jetbrains.kotlin.idea.imports.importableFqName import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType @@ -42,11 +40,11 @@ import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf import org.jetbrains.kotlin.renderer.render import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DescriptorUtils -import org.jetbrains.kotlin.resolve.descriptorUtil.getImportableDescriptor import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.JetScope import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered import org.jetbrains.kotlin.types.JetType +import java.util.* class ParameterNameAndTypeCompletion( private val collector: LookupElementsCollector, @@ -98,6 +96,7 @@ class ParameterNameAndTypeCompletion( } public fun addFromParametersInFile(position: PsiElement, resolutionFacade: ResolutionFacade, visibilityFilter: (DeclarationDescriptor) -> Boolean) { + val lookupElementToCount = LinkedHashMap() position.getContainingFile().forEachDescendantOfType( canGoInside = { it !is JetExpression || it is JetDeclaration } // we analyze parameters inside bodies to not resolve too much ) { declaration -> @@ -107,11 +106,18 @@ class ParameterNameAndTypeCompletion( if (parameter != null) { val parameterType = parameter.getType() if (parameterType.isVisible(visibilityFilter)) { - addLookupElement(NameAndArbitraryType(name, parameterType)) + val lookupElement = MyLookupElement.create(NameAndArbitraryType(name, parameterType), lookupElementFactory) + val count = lookupElementToCount[lookupElement] ?: 0 + lookupElementToCount[lookupElement] = count + 1 } } } } + + for ((lookupElement, count) in lookupElementToCount) { + lookupElement.putUserData(PRIORITY_KEY, -count) + collector.addElement(lookupElement) + } } private fun addSuggestionsForClassifier(classifier: DeclarationDescriptor) { @@ -126,18 +132,14 @@ class ParameterNameAndTypeCompletion( val parameterNames = JetNameSuggester.getCamelNames(className, EmptyValidator) for (parameterName in parameterNames) { if (prefixMatcher.prefixMatches(parameterName)) { - addLookupElement(nameAndTypeFactory(parameterName)) + val lookupElement = MyLookupElement.create(nameAndTypeFactory(parameterName), lookupElementFactory) + if (lookupElement != null) { + collector.addElement(lookupElement) + } } } } - private fun addLookupElement(nameAndType: NameAndType) { - val lookupElement = MyLookupElement.create(nameAndType, lookupElementFactory) - if (lookupElement != null) { - collector.addElement(lookupElement) - } - } - private fun JetType.isVisible(visibilityFilter: (DeclarationDescriptor) -> Boolean): Boolean { if (isError()) return false val classifier = getConstructor().getDeclarationDescriptor() ?: return false @@ -181,8 +183,9 @@ class ParameterNameAndTypeCompletion( companion object { fun create(nameAndType: NameAndType, factory: LookupElementFactory): LookupElement? { - val lookupElement = nameAndType.createTypeLookupElement(factory) ?: return null - return MyLookupElement(nameAndType.parameterName, nameAndType.typeIdString, lookupElement).suppressAutoInsertion() + val typeLookupElement = nameAndType.createTypeLookupElement(factory) ?: return null + val lookupElement = MyLookupElement(nameAndType.parameterName, nameAndType.typeIdString, typeLookupElement) + return lookupElement.suppressAutoInsertion() } } @@ -212,4 +215,12 @@ class ParameterNameAndTypeCompletion( super.handleInsert(context) } } + + private companion object { + val PRIORITY_KEY = Key("ParameterNameAndTypeCompletion.PRIORITY_KEY") + } + + object Weigher : LookupElementWeigher("kotlin.parameterNameAndTypePriority") { + override fun weigh(element: LookupElement, context: WeighingContext): Int = element.getUserData(PRIORITY_KEY) ?: 0 + } } \ No newline at end of file diff --git a/idea/idea-completion/testData/weighers/basic/parameterNameAndType/FromCurrentFilePriority.kt b/idea/idea-completion/testData/weighers/basic/parameterNameAndType/FromCurrentFilePriority.kt new file mode 100644 index 00000000000..e567fa16a47 --- /dev/null +++ b/idea/idea-completion/testData/weighers/basic/parameterNameAndType/FromCurrentFilePriority.kt @@ -0,0 +1,16 @@ +class MyFileA +class MyFileB +class MyFileC + +fun f(myFileB: MyFileB, myFileX: Int, myFileY: Int) +fun g(myFileY: Int) +fun h(myFileX: String) + +fun foo(myFi) + +// ORDER: myFileY +// ORDER: myFileB +// ORDER: myFileX +// ORDER: myFileX +// ORDER: myFileA +// ORDER: myFileC diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/weighers/BasicCompletionWeigherTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/weighers/BasicCompletionWeigherTestGenerated.java index 9f990ce282c..f6b8983c654 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/weighers/BasicCompletionWeigherTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/weighers/BasicCompletionWeigherTestGenerated.java @@ -145,6 +145,12 @@ public class BasicCompletionWeigherTestGenerated extends AbstractBasicCompletion doTest(fileName); } + @TestMetadata("FromCurrentFilePriority.kt") + public void testFromCurrentFilePriority() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/parameterNameAndType/FromCurrentFilePriority.kt"); + doTest(fileName); + } + @TestMetadata("ImportedFirst.kt") public void testImportedFirst() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/parameterNameAndType/ImportedFirst.kt");