Skip to content

Commit 10ea288

Browse files
committed
Supported KProperty2 and KMutableProperty2 for delegated properties
Consider this code: object Delegate { operator fun getValue(t: Any?, p: KProperty<*>): String { return "" } } class A { val String.ext by Delegate } then the type of <p> is KProperty2 (it has 2 receivers). Test fix + review fixes
1 parent d58d75c commit 10ea288

File tree

4 files changed

+19
-18
lines changed

4 files changed

+19
-18
lines changed

compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DoubleColonExpressionResolver.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,7 @@ class DoubleColonExpressionResolver(
772772
val setter = descriptor.setter
773773
setter == null || Visibilities.isVisible(receiverType?.let(::TransientReceiver), setter, scopeOwnerDescriptor)
774774
}
775-
reflectionTypes.getKPropertyType(Annotations.EMPTY, receiverType, descriptor.type, mutable)
775+
reflectionTypes.getKPropertyType(Annotations.EMPTY, listOfNotNull(receiverType), descriptor.type, mutable)
776776
}
777777
is VariableDescriptor -> null
778778
else -> throw UnsupportedOperationException("Callable reference resolved to an unsupported descriptor: $descriptor")

compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DelegatedPropertyGenerator.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,8 @@ class DelegatedPropertyGenerator(override val context: GeneratorContext) : Gener
8080
}
8181

8282
private fun getKPropertyTypeForDelegatedProperty(propertyDescriptor: PropertyDescriptor): KotlinType {
83-
val propertyReceiverType = propertyDescriptor.extensionReceiverParameter?.type ?:
84-
propertyDescriptor.dispatchReceiverParameter?.type
85-
return context.reflectionTypes.getKPropertyType(Annotations.EMPTY, propertyReceiverType, propertyDescriptor.type, propertyDescriptor.isVar)
83+
val receivers = listOfNotNull(propertyDescriptor.extensionReceiverParameter, propertyDescriptor.dispatchReceiverParameter)
84+
return context.reflectionTypes.getKPropertyType(Annotations.EMPTY, receivers.map{ it.type }, propertyDescriptor.type, propertyDescriptor.isVar)
8685
}
8786

8887
private fun generateDelegateFieldForProperty(
@@ -195,7 +194,7 @@ class DelegatedPropertyGenerator(override val context: GeneratorContext) : Gener
195194
}
196195

197196
private fun getKPropertyTypeForLocalDelegatedProperty(variableDescriptor: VariableDescriptorWithAccessors) =
198-
context.reflectionTypes.getKPropertyType(Annotations.EMPTY, null, variableDescriptor.type, variableDescriptor.isVar)
197+
context.reflectionTypes.getKPropertyType(Annotations.EMPTY, emptyList(), variableDescriptor.type, variableDescriptor.isVar)
199198

200199
private fun createPropertyDelegateDescriptor(
201200
propertyDescriptor: PropertyDescriptor,

compiler/testData/ir/irText/declarations/provideDelegate/memberExtension.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,15 @@ FILE /memberExtension.kt
3737
$this: GET_VAR '<receiver: Host>' type=Host origin=null
3838
$receiver: CONST String type=kotlin.String value='K'
3939
host: GET_VAR '<receiver: Host>' type=Host origin=null
40-
p: CALLABLE_REFERENCE 'plusK: String on String' type=kotlin.reflect.KProperty1<kotlin.String, kotlin.String> origin=PROPERTY_REFERENCE_FOR_DELEGATE
40+
p: CALLABLE_REFERENCE 'plusK: String on String' type=kotlin.reflect.KProperty2<kotlin.String, Host, kotlin.String> origin=PROPERTY_REFERENCE_FOR_DELEGATE
4141
FUN DELEGATED_PROPERTY_ACCESSOR public final fun kotlin.String.<get-plusK>(): kotlin.String
4242
BLOCK_BODY
4343
RETURN type=kotlin.Nothing from='<get-plusK>() on String: String'
4444
CALL 'getValue(String, Any): String' type=kotlin.String origin=null
4545
$this: GET_FIELD '`plusK$delegate`: Host.StringDelegate' type=Host.StringDelegate origin=null
4646
receiver: GET_VAR '<receiver: Host>' type=Host origin=null
4747
receiver: GET_VAR '<receiver: plusK: String on String>' type=kotlin.String origin=null
48-
p: CALLABLE_REFERENCE 'plusK: String on String' type=kotlin.reflect.KProperty1<kotlin.String, kotlin.String> origin=PROPERTY_REFERENCE_FOR_DELEGATE
48+
p: CALLABLE_REFERENCE 'plusK: String on String' type=kotlin.reflect.KProperty2<kotlin.String, Host, kotlin.String> origin=PROPERTY_REFERENCE_FOR_DELEGATE
4949
PROPERTY public final val ok: kotlin.String
5050
FIELD PROPERTY_BACKING_FIELD public final val ok: kotlin.String
5151
EXPRESSION_BODY

core/descriptors/src/org/jetbrains/kotlin/builtins/ReflectionTypes.kt

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class ReflectionTypes(module: ModuleDescriptor, private val notFoundClasses: Not
6060
val kProperty2: ClassDescriptor by ClassLookup(3)
6161
val kMutableProperty0: ClassDescriptor by ClassLookup(1)
6262
val kMutableProperty1: ClassDescriptor by ClassLookup(2)
63+
val kMutableProperty2: ClassDescriptor by ClassLookup(3)
6364

6465
fun getKClassType(annotations: Annotations, type: KotlinType, variance: Variance): KotlinType =
6566
KotlinTypeFactory.simpleNotNullType(annotations, kClass, listOf(TypeProjectionImpl(variance, type)))
@@ -77,23 +78,24 @@ class ReflectionTypes(module: ModuleDescriptor, private val notFoundClasses: Not
7778
return KotlinTypeFactory.simpleNotNullType(annotations, classDescriptor, arguments)
7879
}
7980

80-
fun getKPropertyType(annotations: Annotations, receiverType: KotlinType?, returnType: KotlinType, mutable: Boolean): KotlinType {
81-
val classDescriptor = when {
82-
receiverType != null -> when {
81+
fun getKPropertyType(annotations: Annotations, receiverTypes: List<KotlinType>, returnType: KotlinType, mutable: Boolean): KotlinType {
82+
val classDescriptor = when (receiverTypes.size) {
83+
0 -> when {
84+
mutable -> kMutableProperty0
85+
else -> kProperty0
86+
}
87+
1 -> when {
8388
mutable -> kMutableProperty1
8489
else -> kProperty1
8590
}
86-
else -> when {
87-
mutable -> kMutableProperty0
88-
else -> kProperty0
91+
2 -> when {
92+
mutable -> kMutableProperty2
93+
else -> kProperty2
8994
}
95+
else -> throw AssertionError("More than 2 receivers is not allowed")
9096
}
9197

92-
val arguments = ArrayList<TypeProjection>(2)
93-
if (receiverType != null) {
94-
arguments.add(TypeProjectionImpl(receiverType))
95-
}
96-
arguments.add(TypeProjectionImpl(returnType))
98+
val arguments = (receiverTypes + returnType).map(::TypeProjectionImpl)
9799
return KotlinTypeFactory.simpleNotNullType(annotations, classDescriptor, arguments)
98100
}
99101

0 commit comments

Comments
 (0)