Fixed correct detection of bold members in case of multiple receivers (broken by previous changes)
This commit is contained in:
+23
-18
@@ -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: "" }
|
||||
+6
@@ -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")
|
||||
|
||||
+6
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user