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
This commit is contained in:
Igor Chevdar
2017-03-14 13:06:40 +03:00
parent d58d75c6ef
commit 10ea2883f7
4 changed files with 20 additions and 19 deletions
@@ -772,7 +772,7 @@ class DoubleColonExpressionResolver(
val setter = descriptor.setter
setter == null || Visibilities.isVisible(receiverType?.let(::TransientReceiver), setter, scopeOwnerDescriptor)
}
reflectionTypes.getKPropertyType(Annotations.EMPTY, receiverType, descriptor.type, mutable)
reflectionTypes.getKPropertyType(Annotations.EMPTY, listOfNotNull(receiverType), descriptor.type, mutable)
}
is VariableDescriptor -> null
else -> throw UnsupportedOperationException("Callable reference resolved to an unsupported descriptor: $descriptor")
@@ -80,9 +80,8 @@ class DelegatedPropertyGenerator(override val context: GeneratorContext) : Gener
}
private fun getKPropertyTypeForDelegatedProperty(propertyDescriptor: PropertyDescriptor): KotlinType {
val propertyReceiverType = propertyDescriptor.extensionReceiverParameter?.type ?:
propertyDescriptor.dispatchReceiverParameter?.type
return context.reflectionTypes.getKPropertyType(Annotations.EMPTY, propertyReceiverType, propertyDescriptor.type, propertyDescriptor.isVar)
val receivers = listOfNotNull(propertyDescriptor.extensionReceiverParameter, propertyDescriptor.dispatchReceiverParameter)
return context.reflectionTypes.getKPropertyType(Annotations.EMPTY, receivers.map{ it.type }, propertyDescriptor.type, propertyDescriptor.isVar)
}
private fun generateDelegateFieldForProperty(
@@ -195,7 +194,7 @@ class DelegatedPropertyGenerator(override val context: GeneratorContext) : Gener
}
private fun getKPropertyTypeForLocalDelegatedProperty(variableDescriptor: VariableDescriptorWithAccessors) =
context.reflectionTypes.getKPropertyType(Annotations.EMPTY, null, variableDescriptor.type, variableDescriptor.isVar)
context.reflectionTypes.getKPropertyType(Annotations.EMPTY, emptyList(), variableDescriptor.type, variableDescriptor.isVar)
private fun createPropertyDelegateDescriptor(
propertyDescriptor: PropertyDescriptor,
@@ -37,7 +37,7 @@ FILE /memberExtension.kt
$this: GET_VAR '<receiver: Host>' type=Host origin=null
$receiver: CONST String type=kotlin.String value='K'
host: GET_VAR '<receiver: Host>' type=Host origin=null
p: CALLABLE_REFERENCE 'plusK: String on String' type=kotlin.reflect.KProperty1<kotlin.String, kotlin.String> origin=PROPERTY_REFERENCE_FOR_DELEGATE
p: CALLABLE_REFERENCE 'plusK: String on String' type=kotlin.reflect.KProperty2<kotlin.String, Host, kotlin.String> origin=PROPERTY_REFERENCE_FOR_DELEGATE
FUN DELEGATED_PROPERTY_ACCESSOR public final fun kotlin.String.<get-plusK>(): kotlin.String
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-plusK>() on String: String'
@@ -45,7 +45,7 @@ FILE /memberExtension.kt
$this: GET_FIELD '`plusK$delegate`: Host.StringDelegate' type=Host.StringDelegate origin=null
receiver: GET_VAR '<receiver: Host>' type=Host origin=null
receiver: GET_VAR '<receiver: plusK: String on String>' type=kotlin.String origin=null
p: CALLABLE_REFERENCE 'plusK: String on String' type=kotlin.reflect.KProperty1<kotlin.String, kotlin.String> origin=PROPERTY_REFERENCE_FOR_DELEGATE
p: CALLABLE_REFERENCE 'plusK: String on String' type=kotlin.reflect.KProperty2<kotlin.String, Host, kotlin.String> origin=PROPERTY_REFERENCE_FOR_DELEGATE
PROPERTY public final val ok: kotlin.String
FIELD PROPERTY_BACKING_FIELD public final val ok: kotlin.String
EXPRESSION_BODY
@@ -60,6 +60,7 @@ class ReflectionTypes(module: ModuleDescriptor, private val notFoundClasses: Not
val kProperty2: ClassDescriptor by ClassLookup(3)
val kMutableProperty0: ClassDescriptor by ClassLookup(1)
val kMutableProperty1: ClassDescriptor by ClassLookup(2)
val kMutableProperty2: ClassDescriptor by ClassLookup(3)
fun getKClassType(annotations: Annotations, type: KotlinType, variance: Variance): KotlinType =
KotlinTypeFactory.simpleNotNullType(annotations, kClass, listOf(TypeProjectionImpl(variance, type)))
@@ -77,23 +78,24 @@ class ReflectionTypes(module: ModuleDescriptor, private val notFoundClasses: Not
return KotlinTypeFactory.simpleNotNullType(annotations, classDescriptor, arguments)
}
fun getKPropertyType(annotations: Annotations, receiverType: KotlinType?, returnType: KotlinType, mutable: Boolean): KotlinType {
val classDescriptor = when {
receiverType != null -> when {
mutable -> kMutableProperty1
else -> kProperty1
}
else -> when {
fun getKPropertyType(annotations: Annotations, receiverTypes: List<KotlinType>, returnType: KotlinType, mutable: Boolean): KotlinType {
val classDescriptor = when (receiverTypes.size) {
0 -> when {
mutable -> kMutableProperty0
else -> kProperty0
}
1 -> when {
mutable -> kMutableProperty1
else -> kProperty1
}
2 -> when {
mutable -> kMutableProperty2
else -> kProperty2
}
else -> throw AssertionError("More than 2 receivers is not allowed")
}
val arguments = ArrayList<TypeProjection>(2)
if (receiverType != null) {
arguments.add(TypeProjectionImpl(receiverType))
}
arguments.add(TypeProjectionImpl(returnType))
val arguments = (receiverTypes + returnType).map(::TypeProjectionImpl)
return KotlinTypeFactory.simpleNotNullType(annotations, classDescriptor, arguments)
}