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))
|
||||
|
||||
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)
|
||||
|
||||
return sorter
|
||||
|
||||
@@ -23,10 +23,7 @@ import com.intellij.codeInsight.lookup.LookupElementWeigher
|
||||
import com.intellij.codeInsight.lookup.WeighingContext
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.psi.util.proximity.PsiProximityComparator
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.idea.completion.smart.*
|
||||
import org.jetbrains.kotlin.idea.core.ImportableFqNameClassifier
|
||||
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.util.CallType
|
||||
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") {
|
||||
override fun weigh(element: LookupElement, context: WeighingContext)
|
||||
@@ -246,4 +245,32 @@ class SmartCompletionInBasicWeigher(
|
||||
else
|
||||
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);
|
||||
}
|
||||
|
||||
@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")
|
||||
public void testDeprecatedFun() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/DeprecatedFun.kt");
|
||||
@@ -143,6 +149,12 @@ public class BasicCompletionWeigherTestGenerated extends AbstractBasicCompletion
|
||||
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")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@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");
|
||||
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