[NI] Support callable references on qualified types with generics
#KT-32154 Fixed
This commit is contained in:
+13
-14
@@ -19,10 +19,11 @@ import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.EXTENSION_R
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.*
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.DetailedReceiver
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.QualifierReceiver
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.UnwrappedType
|
||||
import org.jetbrains.kotlin.types.checker.captureFromExpression
|
||||
import org.jetbrains.kotlin.types.expressions.CoercionStrategy
|
||||
import org.jetbrains.kotlin.types.typeUtil.immediateSupertypes
|
||||
@@ -32,11 +33,10 @@ import org.jetbrains.kotlin.utils.SmartList
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
|
||||
sealed class CallableReceiver(val receiver: ReceiverValueWithSmartCastInfo) {
|
||||
class UnboundReference(val qualifier: QualifierReceiver, receiver: ReceiverValueWithSmartCastInfo) : CallableReceiver(receiver)
|
||||
class BoundValueReference(val qualifier: QualifierReceiver, receiver: ReceiverValueWithSmartCastInfo) : CallableReceiver(receiver)
|
||||
class UnboundReference(receiver: ReceiverValueWithSmartCastInfo) : CallableReceiver(receiver)
|
||||
class BoundValueReference(receiver: ReceiverValueWithSmartCastInfo) : CallableReceiver(receiver)
|
||||
class ScopeReceiver(receiver: ReceiverValueWithSmartCastInfo) : CallableReceiver(receiver)
|
||||
class ExplicitValueReceiver(val lhsArgument: SimpleKotlinCallArgument, receiver: ReceiverValueWithSmartCastInfo) :
|
||||
CallableReceiver(receiver)
|
||||
class ExplicitValueReceiver(receiver: ReceiverValueWithSmartCastInfo) : CallableReceiver(receiver)
|
||||
}
|
||||
|
||||
// todo investigate similar code in CheckVisibility
|
||||
@@ -89,7 +89,7 @@ fun createCallableReferenceProcessor(factory: CallableReferencesCandidateFactory
|
||||
// note that if we use PrioritizedCompositeScopeTowerProcessor then static will win over unbound members
|
||||
val staticOrUnbound = SamePriorityCompositeScopeTowerProcessor(static, unbound)
|
||||
|
||||
val asValue = lhsResult.qualifier.classValueReceiverWithSmartCastInfo ?: return staticOrUnbound
|
||||
val asValue = lhsResult.qualifier?.classValueReceiverWithSmartCastInfo ?: return staticOrUnbound
|
||||
return PrioritizedCompositeScopeTowerProcessor(staticOrUnbound, factory.createCallableProcessor(asValue))
|
||||
}
|
||||
is LHSResult.Object -> {
|
||||
@@ -329,17 +329,16 @@ class CallableReferencesCandidateFactory(
|
||||
private fun toCallableReceiver(receiver: ReceiverValueWithSmartCastInfo, isExplicit: Boolean): CallableReceiver {
|
||||
if (!isExplicit) return CallableReceiver.ScopeReceiver(receiver)
|
||||
|
||||
val lhsResult = argument.lhsResult
|
||||
return when (lhsResult) {
|
||||
is LHSResult.Expression -> CallableReceiver.ExplicitValueReceiver(lhsResult.lshCallArgument, receiver)
|
||||
return when (val lhsResult = argument.lhsResult) {
|
||||
is LHSResult.Expression -> CallableReceiver.ExplicitValueReceiver(receiver)
|
||||
is LHSResult.Type -> {
|
||||
if (lhsResult.qualifier.classValueReceiver?.type == receiver.receiverValue.type) {
|
||||
CallableReceiver.BoundValueReference(lhsResult.qualifier, receiver)
|
||||
if (lhsResult.qualifier?.classValueReceiver?.type == receiver.receiverValue.type) {
|
||||
CallableReceiver.BoundValueReference(receiver)
|
||||
} else {
|
||||
CallableReceiver.UnboundReference(lhsResult.qualifier, receiver)
|
||||
CallableReceiver.UnboundReference(receiver)
|
||||
}
|
||||
}
|
||||
is LHSResult.Object -> CallableReceiver.BoundValueReference(lhsResult.qualifier, receiver)
|
||||
is LHSResult.Object -> CallableReceiver.BoundValueReference(receiver)
|
||||
else -> throw IllegalStateException("Unsupported kind of lhsResult: $lhsResult")
|
||||
}
|
||||
}
|
||||
|
||||
+5
-1
@@ -167,7 +167,11 @@ private fun preprocessCallableReference(
|
||||
val lhsType = it.unboundDetailedReceiver.stableType
|
||||
if (ReflectionTypes.isNumberedTypeWithOneOrMoreNumber(expectedType)) {
|
||||
val lhsTypeVariable = expectedType.arguments.first().type.unwrap()
|
||||
csBuilder.addSubtypeConstraint(lhsType, lhsTypeVariable, LHSArgumentConstraintPosition(it.qualifier))
|
||||
csBuilder.addSubtypeConstraint(
|
||||
lhsType,
|
||||
lhsTypeVariable,
|
||||
LHSArgumentConstraintPosition(it.qualifier ?: it.unboundDetailedReceiver)
|
||||
)
|
||||
}
|
||||
}
|
||||
if (notCallableTypeConstructor != null) {
|
||||
|
||||
+2
-3
@@ -21,9 +21,8 @@ import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability.INAPPLICABLE
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability.INAPPLICABLE_WRONG_RECEIVER
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.QualifierReceiver
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.DetailedReceiver
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.UnwrappedType
|
||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeVariableMarker
|
||||
|
||||
@@ -58,7 +57,7 @@ class KnownTypeParameterConstraintPosition(val typeArgument: KotlinType) : Const
|
||||
override fun toString() = "TypeArgument $typeArgument"
|
||||
}
|
||||
|
||||
class LHSArgumentConstraintPosition(val receiver: QualifierReceiver) : ConstraintPosition() {
|
||||
class LHSArgumentConstraintPosition(val receiver: DetailedReceiver) : ConstraintPosition() {
|
||||
override fun toString(): String {
|
||||
return "LHS receiver $receiver"
|
||||
}
|
||||
|
||||
+5
-3
@@ -78,12 +78,14 @@ interface FunctionExpression : LambdaKotlinCallArgument {
|
||||
* D.E::foo <-> Expression
|
||||
*/
|
||||
sealed class LHSResult {
|
||||
class Type(val qualifier: QualifierReceiver, resolvedType: UnwrappedType) : LHSResult() {
|
||||
class Type(val qualifier: QualifierReceiver?, resolvedType: UnwrappedType) : LHSResult() {
|
||||
val unboundDetailedReceiver: ReceiverValueWithSmartCastInfo
|
||||
|
||||
init {
|
||||
assert(qualifier.descriptor is ClassDescriptor || qualifier.descriptor is TypeAliasDescriptor) {
|
||||
"Should be ClassDescriptor: ${qualifier.descriptor}"
|
||||
if (qualifier != null) {
|
||||
assert(qualifier.descriptor is ClassDescriptor || qualifier.descriptor is TypeAliasDescriptor) {
|
||||
"Should be ClassDescriptor: ${qualifier.descriptor}"
|
||||
}
|
||||
}
|
||||
|
||||
val unboundReceiver = TransientReceiver(resolvedType)
|
||||
|
||||
Reference in New Issue
Block a user