Preference of right member after "super." and not only

This commit is contained in:
Valentin Kipyatkov
2015-11-03 20:54:05 +03:00
parent 731f19ee36
commit 99b35257c6
7 changed files with 112 additions and 4 deletions
@@ -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
@@ -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)
@@ -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);
}
}