Parameter names from current file get higher priority + number of occurrences matters

This commit is contained in:
Valentin Kipyatkov
2015-06-18 22:03:15 +03:00
parent c6fd04dcac
commit 84ba634c3e
4 changed files with 50 additions and 17 deletions
@@ -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)
@@ -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<LookupElement, Int>()
position.getContainingFile().forEachDescendantOfType<JetParameter>(
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<Int>("ParameterNameAndTypeCompletion.PRIORITY_KEY")
}
object Weigher : LookupElementWeigher("kotlin.parameterNameAndTypePriority") {
override fun weigh(element: LookupElement, context: WeighingContext): Int = element.getUserData(PRIORITY_KEY) ?: 0
}
}
@@ -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<caret>)
// ORDER: myFileY
// ORDER: myFileB
// ORDER: myFileX
// ORDER: myFileX
// ORDER: myFileA
// ORDER: myFileC
@@ -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");