Fixed correct detection of bold members in case of multiple receivers (broken by previous changes)

This commit is contained in:
Valentin Kipyatkov
2016-08-31 19:46:03 +03:00
parent d93525d7f8
commit c068bd3158
4 changed files with 58 additions and 18 deletions
@@ -47,6 +47,7 @@ import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.kotlin.utils.addIfNotNull
import java.util.*
interface AbstractLookupElementFactory {
fun createStandardLookupElementsForDescriptor(descriptor: DeclarationDescriptor, useReceiverTypes: Boolean): Collection<LookupElement>
@@ -342,30 +343,34 @@ class LookupElementFactory(
?: dispatchReceiverParameter
?: return null
val matchingReceiverIndices = HashSet<Int>()
var bestReceiverType: ReceiverType? = null
var bestWeight: CallableWeightEnum? = null
for (receiverType in receiverTypes) {
val weight = callableWeightForReceiverType(receiverType.type, receiverParameter.type)
if (weight != null) {
val receiverIndex = receiverType.receiverIndex
var receiverIndexToUse: Int? = receiverIndex
if (receiverIndex == 0) {
val maxReceiverIndex = receiverTypes.map { it.receiverIndex }.max()!!
if (maxReceiverIndex > 0) {
val matchesAllReceivers = receiverTypes
.filter { it.receiverIndex != 0 && callableWeightForReceiverType(it.type, receiverParameter.type) != null }
.map { it.receiverIndex }
.toSet()
.containsAll((1..maxReceiverIndex).toList())
if (matchesAllReceivers) { // if descriptor is matching all receivers then use null as receiverIndex - otherwise e.g. all members of Any would have too high priority
receiverIndexToUse = null
}
}
if (bestWeight == null || weight < bestWeight) {
bestWeight = weight
bestReceiverType = receiverType
}
return CallableWeight(weight, receiverIndexToUse)
matchingReceiverIndices.add(receiverType.receiverIndex)
}
}
return onReceiverTypeMismatch
if (bestWeight == null) return onReceiverTypeMismatch
val receiverIndex = bestReceiverType!!.receiverIndex
var receiverIndexToUse: Int? = receiverIndex
val maxReceiverIndex = receiverTypes.map { it.receiverIndex }.max()!!
if (maxReceiverIndex > 0) {
val matchesAllReceivers = (0..maxReceiverIndex).all { it in matchingReceiverIndices }
if (matchesAllReceivers) { // if descriptor is matching all receivers then use null as receiverIndex - otherwise e.g. all members of Any would have too high priority
receiverIndexToUse = null
}
}
return CallableWeight(bestWeight, receiverIndexToUse)
}
private fun CallableDescriptor.callableWeightForReceiverType(receiverType: KotlinType, receiverParameterType: KotlinType): CallableWeightEnum? {
@@ -0,0 +1,23 @@
interface Base {
fun inBase()
}
interface I1 : Base {
fun inI1()
}
interface I2 : I1 {
fun inI2()
}
fun foo(i1: I1, i2: I2) {
with(i1) {
with(i2) {
<caret>
}
}
}
// EXIST: { lookupString: "inI1", attributes: "bold" }
// EXIST: { lookupString: "inI2", attributes: "bold" }
// EXIST: { lookupString: "inBase", attributes: "" }
// EXIST: { lookupString: "equals", attributes: "" }
@@ -1184,6 +1184,12 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/boldOrGrayed/SafeCallAfterNullable.kt");
doTest(fileName);
}
@TestMetadata("TwoReceivers.kt")
public void testTwoReceivers() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/boldOrGrayed/TwoReceivers.kt");
doTest(fileName);
}
}
@TestMetadata("idea/idea-completion/testData/basic/common/callableReference")
@@ -1184,6 +1184,12 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/boldOrGrayed/SafeCallAfterNullable.kt");
doTest(fileName);
}
@TestMetadata("TwoReceivers.kt")
public void testTwoReceivers() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/boldOrGrayed/TwoReceivers.kt");
doTest(fileName);
}
}
@TestMetadata("idea/idea-completion/testData/basic/common/callableReference")