KT-12299 Completion: incorrect priority of property foo over method getFoo in Kotlin-only code
#KT-12299 Fixed
This commit is contained in:
@@ -22,8 +22,10 @@ import com.intellij.codeInsight.completion.CompletionSorter
|
|||||||
import com.intellij.codeInsight.completion.CompletionUtil
|
import com.intellij.codeInsight.completion.CompletionUtil
|
||||||
import com.intellij.codeInsight.completion.impl.CamelHumpMatcher
|
import com.intellij.codeInsight.completion.impl.CamelHumpMatcher
|
||||||
import com.intellij.codeInsight.lookup.LookupElement
|
import com.intellij.codeInsight.lookup.LookupElement
|
||||||
|
import com.intellij.patterns.PatternCondition
|
||||||
import com.intellij.patterns.StandardPatterns
|
import com.intellij.patterns.StandardPatterns
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import com.intellij.util.ProcessingContext
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.*
|
import org.jetbrains.kotlin.idea.caches.resolve.*
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.ReferenceVariantsHelper
|
import org.jetbrains.kotlin.idea.codeInsight.ReferenceVariantsHelper
|
||||||
@@ -221,6 +223,12 @@ abstract class CompletionSession(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun complete(): Boolean {
|
fun complete(): Boolean {
|
||||||
|
// we restart completion when prefix becomes "get" or "set" to ensure that properties get lower priority comparing to get/set functions (see KT-12299)
|
||||||
|
val prefixPattern = StandardPatterns.string().with(object : PatternCondition<String>("get or set prefix") {
|
||||||
|
override fun accepts(prefix: String, context: ProcessingContext?) = prefix == "get" || prefix == "set"
|
||||||
|
})
|
||||||
|
collector.restartCompletionOnPrefixChange(prefixPattern)
|
||||||
|
|
||||||
val statisticsContext = calcContextForStatisticsInfo()
|
val statisticsContext = calcContextForStatisticsInfo()
|
||||||
if (statisticsContext != null) {
|
if (statisticsContext != null) {
|
||||||
collector.addLookupElementPostProcessor { lookupElement ->
|
collector.addLookupElementPostProcessor { lookupElement ->
|
||||||
@@ -250,7 +258,7 @@ abstract class CompletionSession(
|
|||||||
protected open fun createSorter(): CompletionSorter {
|
protected open fun createSorter(): CompletionSorter {
|
||||||
var sorter = CompletionSorter.defaultSorter(parameters, prefixMatcher)!!
|
var sorter = CompletionSorter.defaultSorter(parameters, prefixMatcher)!!
|
||||||
|
|
||||||
sorter = sorter.weighBefore("stats", DeprecatedWeigher, PriorityWeigher,
|
sorter = sorter.weighBefore("stats", DeprecatedWeigher, PriorityWeigher, PreferGetSetMethodsToPropertyWeigher,
|
||||||
NotImportedWeigher(importableFqNameClassifier),
|
NotImportedWeigher(importableFqNameClassifier),
|
||||||
NotImportedStaticMemberWeigher(importableFqNameClassifier),
|
NotImportedStaticMemberWeigher(importableFqNameClassifier),
|
||||||
KindWeigher, CallableWeigher)
|
KindWeigher, CallableWeigher)
|
||||||
|
|||||||
@@ -155,6 +155,19 @@ object VariableOrFunctionWeigher : LookupElementWeigher("kotlin.variableOrFuncti
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decreases priority of properties when prefix starts with "get" or "set" (and the property name does not)
|
||||||
|
*/
|
||||||
|
object PreferGetSetMethodsToPropertyWeigher : LookupElementWeigher("kotlin.preferGetSetMethodsToProperty", false, true){
|
||||||
|
override fun weigh(element: LookupElement, context: WeighingContext): Int {
|
||||||
|
val property = (element.`object` as? DeclarationLookupObject)?.descriptor as? PropertyDescriptor ?: return 0
|
||||||
|
val prefixMatcher = context.itemMatcher(element)
|
||||||
|
if (prefixMatcher.prefixMatches(property.name.asString())) return 0
|
||||||
|
val matchedLookupStrings = element.allLookupStrings.filter { prefixMatcher.prefixMatches(it) }
|
||||||
|
if (matchedLookupStrings.all { it.startsWith("get") || it.startsWith("set") }) return 1 else return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
object DeprecatedWeigher : LookupElementWeigher("kotlin.deprecated") {
|
object DeprecatedWeigher : LookupElementWeigher("kotlin.deprecated") {
|
||||||
override fun weigh(element: LookupElement): Int {
|
override fun weigh(element: LookupElement): Int {
|
||||||
val o = element.`object` as? DeclarationLookupObject ?: return 0
|
val o = element.`object` as? DeclarationLookupObject ?: return 0
|
||||||
|
|||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package dependency
|
||||||
|
|
||||||
|
import test.A
|
||||||
|
|
||||||
|
fun A.getFaa() = 1
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
class A {
|
||||||
|
val foo = 42
|
||||||
|
|
||||||
|
fun getFoo() = ""
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
getF<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// ORDER: getFoo
|
||||||
|
// ORDER: getFaa
|
||||||
|
// ORDER: foo
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
interface Z {
|
||||||
|
companion object {
|
||||||
|
val instance: Z? = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo(): Z? = Z<caret>
|
||||||
|
|
||||||
|
// ORDER: instance
|
||||||
|
// ORDER: object
|
||||||
+6
@@ -161,6 +161,12 @@ public class BasicCompletionWeigherTestGenerated extends AbstractBasicCompletion
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("PreferGetMethodToProperty.kt")
|
||||||
|
public void testPreferGetMethodToProperty() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/PreferGetMethodToProperty.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("PropertiesBeforeKeywords.kt")
|
@TestMetadata("PropertiesBeforeKeywords.kt")
|
||||||
public void testPropertiesBeforeKeywords() throws Exception {
|
public void testPropertiesBeforeKeywords() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/PropertiesBeforeKeywords.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/PropertiesBeforeKeywords.kt");
|
||||||
|
|||||||
+6
@@ -245,6 +245,12 @@ public class SmartCompletionWeigherTestGenerated extends AbstractSmartCompletion
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("StaticMemberAndPrefix.kt")
|
||||||
|
public void testStaticMemberAndPrefix() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/smart/StaticMemberAndPrefix.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("SuperMembers.kt")
|
@TestMetadata("SuperMembers.kt")
|
||||||
public void testSuperMembers() throws Exception {
|
public void testSuperMembers() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/smart/SuperMembers.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/smart/SuperMembers.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user