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.types.typeUtil.isSubtypeOf
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
interface AbstractLookupElementFactory {
|
interface AbstractLookupElementFactory {
|
||||||
fun createStandardLookupElementsForDescriptor(descriptor: DeclarationDescriptor, useReceiverTypes: Boolean): Collection<LookupElement>
|
fun createStandardLookupElementsForDescriptor(descriptor: DeclarationDescriptor, useReceiverTypes: Boolean): Collection<LookupElement>
|
||||||
@@ -342,30 +343,34 @@ class LookupElementFactory(
|
|||||||
?: dispatchReceiverParameter
|
?: dispatchReceiverParameter
|
||||||
?: return null
|
?: return null
|
||||||
|
|
||||||
|
val matchingReceiverIndices = HashSet<Int>()
|
||||||
|
var bestReceiverType: ReceiverType? = null
|
||||||
|
var bestWeight: CallableWeightEnum? = null
|
||||||
for (receiverType in receiverTypes) {
|
for (receiverType in receiverTypes) {
|
||||||
val weight = callableWeightForReceiverType(receiverType.type, receiverParameter.type)
|
val weight = callableWeightForReceiverType(receiverType.type, receiverParameter.type)
|
||||||
if (weight != null) {
|
if (weight != null) {
|
||||||
val receiverIndex = receiverType.receiverIndex
|
if (bestWeight == null || weight < bestWeight) {
|
||||||
|
bestWeight = weight
|
||||||
var receiverIndexToUse: Int? = receiverIndex
|
bestReceiverType = receiverType
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
matchingReceiverIndices.add(receiverType.receiverIndex)
|
||||||
return CallableWeight(weight, receiverIndexToUse)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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? {
|
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");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/boldOrGrayed/SafeCallAfterNullable.kt");
|
||||||
doTest(fileName);
|
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")
|
@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");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/boldOrGrayed/SafeCallAfterNullable.kt");
|
||||||
doTest(fileName);
|
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")
|
@TestMetadata("idea/idea-completion/testData/basic/common/callableReference")
|
||||||
|
|||||||
Reference in New Issue
Block a user