Parameter names from current file get higher priority + number of occurrences matters
This commit is contained in:
@@ -44,7 +44,7 @@ import java.util.HashSet
|
|||||||
public fun CompletionResultSet.addKotlinSorting(parameters: CompletionParameters): CompletionResultSet {
|
public fun CompletionResultSet.addKotlinSorting(parameters: CompletionParameters): CompletionResultSet {
|
||||||
var sorter = CompletionSorter.defaultSorter(parameters, getPrefixMatcher())!!
|
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) {
|
if (parameters.getCompletionType() == CompletionType.SMART) {
|
||||||
sorter = sorter.weighBefore("kotlin.kind", NameSimilarityWeigher, SmartCompletionPriorityWeigher)
|
sorter = sorter.weighBefore("kotlin.kind", NameSimilarityWeigher, SmartCompletionPriorityWeigher)
|
||||||
|
|||||||
+27
-16
@@ -20,9 +20,8 @@ import com.intellij.codeInsight.completion.CompletionInitializationContext
|
|||||||
import com.intellij.codeInsight.completion.CompletionParameters
|
import com.intellij.codeInsight.completion.CompletionParameters
|
||||||
import com.intellij.codeInsight.completion.InsertionContext
|
import com.intellij.codeInsight.completion.InsertionContext
|
||||||
import com.intellij.codeInsight.completion.PrefixMatcher
|
import com.intellij.codeInsight.completion.PrefixMatcher
|
||||||
import com.intellij.codeInsight.lookup.LookupElement
|
import com.intellij.codeInsight.lookup.*
|
||||||
import com.intellij.codeInsight.lookup.LookupElementDecorator
|
import com.intellij.openapi.util.Key
|
||||||
import com.intellij.codeInsight.lookup.LookupElementPresentation
|
|
||||||
import com.intellij.psi.PsiClass
|
import com.intellij.psi.PsiClass
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager
|
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.formatter.JetCodeStyleSettings
|
||||||
import org.jetbrains.kotlin.idea.core.refactoring.EmptyValidator
|
import org.jetbrains.kotlin.idea.core.refactoring.EmptyValidator
|
||||||
import org.jetbrains.kotlin.idea.core.refactoring.JetNameSuggester
|
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.idea.util.IdeDescriptorRenderers
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType
|
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.renderer.render
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
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.DescriptorKindFilter
|
||||||
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
||||||
import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
|
import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
|
||||||
import org.jetbrains.kotlin.types.JetType
|
import org.jetbrains.kotlin.types.JetType
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
class ParameterNameAndTypeCompletion(
|
class ParameterNameAndTypeCompletion(
|
||||||
private val collector: LookupElementsCollector,
|
private val collector: LookupElementsCollector,
|
||||||
@@ -98,6 +96,7 @@ class ParameterNameAndTypeCompletion(
|
|||||||
}
|
}
|
||||||
|
|
||||||
public fun addFromParametersInFile(position: PsiElement, resolutionFacade: ResolutionFacade, visibilityFilter: (DeclarationDescriptor) -> Boolean) {
|
public fun addFromParametersInFile(position: PsiElement, resolutionFacade: ResolutionFacade, visibilityFilter: (DeclarationDescriptor) -> Boolean) {
|
||||||
|
val lookupElementToCount = LinkedHashMap<LookupElement, Int>()
|
||||||
position.getContainingFile().forEachDescendantOfType<JetParameter>(
|
position.getContainingFile().forEachDescendantOfType<JetParameter>(
|
||||||
canGoInside = { it !is JetExpression || it is JetDeclaration } // we analyze parameters inside bodies to not resolve too much
|
canGoInside = { it !is JetExpression || it is JetDeclaration } // we analyze parameters inside bodies to not resolve too much
|
||||||
) { declaration ->
|
) { declaration ->
|
||||||
@@ -107,11 +106,18 @@ class ParameterNameAndTypeCompletion(
|
|||||||
if (parameter != null) {
|
if (parameter != null) {
|
||||||
val parameterType = parameter.getType()
|
val parameterType = parameter.getType()
|
||||||
if (parameterType.isVisible(visibilityFilter)) {
|
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) {
|
private fun addSuggestionsForClassifier(classifier: DeclarationDescriptor) {
|
||||||
@@ -126,18 +132,14 @@ class ParameterNameAndTypeCompletion(
|
|||||||
val parameterNames = JetNameSuggester.getCamelNames(className, EmptyValidator)
|
val parameterNames = JetNameSuggester.getCamelNames(className, EmptyValidator)
|
||||||
for (parameterName in parameterNames) {
|
for (parameterName in parameterNames) {
|
||||||
if (prefixMatcher.prefixMatches(parameterName)) {
|
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 {
|
private fun JetType.isVisible(visibilityFilter: (DeclarationDescriptor) -> Boolean): Boolean {
|
||||||
if (isError()) return false
|
if (isError()) return false
|
||||||
val classifier = getConstructor().getDeclarationDescriptor() ?: return false
|
val classifier = getConstructor().getDeclarationDescriptor() ?: return false
|
||||||
@@ -181,8 +183,9 @@ class ParameterNameAndTypeCompletion(
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun create(nameAndType: NameAndType, factory: LookupElementFactory): LookupElement? {
|
fun create(nameAndType: NameAndType, factory: LookupElementFactory): LookupElement? {
|
||||||
val lookupElement = nameAndType.createTypeLookupElement(factory) ?: return null
|
val typeLookupElement = nameAndType.createTypeLookupElement(factory) ?: return null
|
||||||
return MyLookupElement(nameAndType.parameterName, nameAndType.typeIdString, lookupElement).suppressAutoInsertion()
|
val lookupElement = MyLookupElement(nameAndType.parameterName, nameAndType.typeIdString, typeLookupElement)
|
||||||
|
return lookupElement.suppressAutoInsertion()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,4 +215,12 @@ class ParameterNameAndTypeCompletion(
|
|||||||
super.handleInsert(context)
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Vendored
+16
@@ -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
|
||||||
+6
@@ -145,6 +145,12 @@ public class BasicCompletionWeigherTestGenerated extends AbstractBasicCompletion
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("ImportedFirst.kt")
|
||||||
public void testImportedFirst() throws Exception {
|
public void testImportedFirst() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/parameterNameAndType/ImportedFirst.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/parameterNameAndType/ImportedFirst.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user