Preference of right member after "super." and not only
This commit is contained in:
@@ -250,6 +250,14 @@ abstract class CompletionSession(protected val configuration: CompletionSessionC
|
|||||||
|
|
||||||
sorter = sorter.weighAfter("stats", VariableOrFunctionWeigher, ImportedWeigher(importableFqNameClassifier))
|
sorter = sorter.weighAfter("stats", VariableOrFunctionWeigher, ImportedWeigher(importableFqNameClassifier))
|
||||||
|
|
||||||
|
val preferContextElementsWeigher = PreferContextElementsWeigher(inDescriptor)
|
||||||
|
if (callTypeAndReceiver is CallTypeAndReceiver.SUPER_MEMBERS) { // for completion after "super." strictly prefer the current member
|
||||||
|
sorter = sorter.weighBefore("kotlin.deprecated", preferContextElementsWeigher)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sorter = sorter.weighBefore("kotlin.proximity", preferContextElementsWeigher)
|
||||||
|
}
|
||||||
|
|
||||||
sorter = sorter.weighBefore("middleMatching", PreferMatchingItemWeigher)
|
sorter = sorter.weighBefore("middleMatching", PreferMatchingItemWeigher)
|
||||||
|
|
||||||
return sorter
|
return sorter
|
||||||
|
|||||||
@@ -23,10 +23,7 @@ import com.intellij.codeInsight.lookup.LookupElementWeigher
|
|||||||
import com.intellij.codeInsight.lookup.WeighingContext
|
import com.intellij.codeInsight.lookup.WeighingContext
|
||||||
import com.intellij.openapi.util.Key
|
import com.intellij.openapi.util.Key
|
||||||
import com.intellij.psi.util.proximity.PsiProximityComparator
|
import com.intellij.psi.util.proximity.PsiProximityComparator
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
|
||||||
import org.jetbrains.kotlin.idea.completion.smart.*
|
import org.jetbrains.kotlin.idea.completion.smart.*
|
||||||
import org.jetbrains.kotlin.idea.core.ImportableFqNameClassifier
|
import org.jetbrains.kotlin.idea.core.ImportableFqNameClassifier
|
||||||
import org.jetbrains.kotlin.idea.core.completion.DeclarationLookupObject
|
import org.jetbrains.kotlin.idea.core.completion.DeclarationLookupObject
|
||||||
@@ -34,6 +31,8 @@ import org.jetbrains.kotlin.idea.core.completion.PackageLookupObject
|
|||||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||||
import org.jetbrains.kotlin.idea.util.CallType
|
import org.jetbrains.kotlin.idea.util.CallType
|
||||||
import org.jetbrains.kotlin.idea.util.FuzzyType
|
import org.jetbrains.kotlin.idea.util.FuzzyType
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf
|
||||||
|
import org.jetbrains.kotlin.resolve.getOriginalTopmostOverriddenDescriptors
|
||||||
|
|
||||||
object PriorityWeigher : LookupElementWeigher("kotlin.priority") {
|
object PriorityWeigher : LookupElementWeigher("kotlin.priority") {
|
||||||
override fun weigh(element: LookupElement, context: WeighingContext)
|
override fun weigh(element: LookupElement, context: WeighingContext)
|
||||||
@@ -246,4 +245,32 @@ class SmartCompletionInBasicWeigher(
|
|||||||
else
|
else
|
||||||
ifNotNullMatchWeight(nameSimilarity)
|
ifNotNullMatchWeight(nameSimilarity)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PreferContextElementsWeigher(private val context: DeclarationDescriptor) : LookupElementWeigher("kotlin.preferContextElements", true, false) {
|
||||||
|
private val contextElements = context.parentsWithSelf
|
||||||
|
.takeWhile { it !is PackageFragmentDescriptor }
|
||||||
|
.toList()
|
||||||
|
.flatMap { if (it is CallableDescriptor) it.getOriginalTopmostOverriddenDescriptors() else listOf(it) }
|
||||||
|
.toSet()
|
||||||
|
private val contextElementNames = contextElements.map { it.name }.toSet()
|
||||||
|
|
||||||
|
override fun weigh(element: LookupElement): Boolean {
|
||||||
|
val lookupObject = element.`object` as? DeclarationLookupObject ?: return false
|
||||||
|
val descriptor = lookupObject.descriptor ?: return false
|
||||||
|
return descriptor.isContextElement()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun DeclarationDescriptor.isContextElement(): Boolean {
|
||||||
|
if (name !in contextElementNames) return false // optimization
|
||||||
|
|
||||||
|
if (this is CallableMemberDescriptor) {
|
||||||
|
val overridden = this.overriddenDescriptors
|
||||||
|
if (overridden.isNotEmpty()) {
|
||||||
|
return overridden.any { it.isContextElement() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return original in contextElements
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
interface I {
|
||||||
|
fun foo1()
|
||||||
|
fun foo2()
|
||||||
|
fun foo3()
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class Base1 : I
|
||||||
|
abstract class Base2 : I
|
||||||
|
|
||||||
|
abstract class A : Base1() {
|
||||||
|
override fun foo2() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class B(val a: A) : Base2() {
|
||||||
|
override fun foo2() {
|
||||||
|
a.<caret>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ORDER: foo2
|
||||||
|
// ORDER: foo1
|
||||||
|
// ORDER: foo3
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
class B {
|
||||||
|
open fun foo1(): String = ""
|
||||||
|
open fun foo2(): String = ""
|
||||||
|
open fun foo3(): Int = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
class C : B() {
|
||||||
|
override fun foo2(): String {
|
||||||
|
takeInt(super.fo<caret>)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun takeInt(p: Int){}
|
||||||
|
|
||||||
|
// ORDER: foo2
|
||||||
|
// ORDER: foo3
|
||||||
|
// ORDER: foo1
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
class B {
|
||||||
|
open fun foo1(): String = ""
|
||||||
|
open fun foo2(): String = ""
|
||||||
|
open fun foo3(): String = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
class C : B() {
|
||||||
|
override fun foo2(): String {
|
||||||
|
return super.fo<caret>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ORDER: foo2
|
||||||
|
// ORDER: foo1
|
||||||
|
// ORDER: foo3
|
||||||
+12
@@ -47,6 +47,12 @@ public class BasicCompletionWeigherTestGenerated extends AbstractBasicCompletion
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("DelegateToOtherObject.kt")
|
||||||
|
public void testDelegateToOtherObject() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/DelegateToOtherObject.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("DeprecatedFun.kt")
|
@TestMetadata("DeprecatedFun.kt")
|
||||||
public void testDeprecatedFun() throws Exception {
|
public void testDeprecatedFun() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/DeprecatedFun.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/DeprecatedFun.kt");
|
||||||
@@ -143,6 +149,12 @@ public class BasicCompletionWeigherTestGenerated extends AbstractBasicCompletion
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("SuperMembers.kt")
|
||||||
|
public void testSuperMembers() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/SuperMembers.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/idea-completion/testData/weighers/basic/expectedInfo")
|
@TestMetadata("idea/idea-completion/testData/weighers/basic/expectedInfo")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
+6
@@ -232,4 +232,10 @@ public class SmartCompletionWeigherTestGenerated extends AbstractSmartCompletion
|
|||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/smart/SmartPriority3.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/smart/SmartPriority3.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("SuperMembers.kt")
|
||||||
|
public void testSuperMembers() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/smart/SuperMembers.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user