Fixed type of callable reference to property with private setter
The actual type of callable reference is presented in IR, take it from there.
This commit is contained in:
+1
@@ -167,6 +167,7 @@ class ReflectionTypes(module: ModuleDescriptor) {
|
|||||||
val kProperty2: ClassDescriptor by ClassLookup(kotlinReflectScope)
|
val kProperty2: ClassDescriptor by ClassLookup(kotlinReflectScope)
|
||||||
val kMutableProperty0: ClassDescriptor by ClassLookup(kotlinReflectScope)
|
val kMutableProperty0: ClassDescriptor by ClassLookup(kotlinReflectScope)
|
||||||
val kMutableProperty1: ClassDescriptor by ClassLookup(kotlinReflectScope)
|
val kMutableProperty1: ClassDescriptor by ClassLookup(kotlinReflectScope)
|
||||||
|
val kMutableProperty2: ClassDescriptor by ClassLookup(kotlinReflectScope)
|
||||||
val kProperty0Impl: ClassDescriptor by ClassLookup(konanInternalScope)
|
val kProperty0Impl: ClassDescriptor by ClassLookup(konanInternalScope)
|
||||||
val kProperty1Impl: ClassDescriptor by ClassLookup(konanInternalScope)
|
val kProperty1Impl: ClassDescriptor by ClassLookup(konanInternalScope)
|
||||||
val kProperty2Impl: ClassDescriptor by ClassLookup(konanInternalScope)
|
val kProperty2Impl: ClassDescriptor by ClassLookup(konanInternalScope)
|
||||||
|
|||||||
+23
-19
@@ -28,15 +28,7 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
|
|
||||||
internal class PropertyDelegationLowering(val context: Context) : FileLoweringPass {
|
internal class PropertyDelegationLowering(val context: Context) : FileLoweringPass {
|
||||||
private val genericKProperty0ImplType = context.reflectionTypes.kProperty0Impl
|
val reflectionTypes = context.reflectionTypes
|
||||||
private val genericKLocalDelegatedPropertyImplType = context.reflectionTypes.kLocalDelegatedPropertyImpl
|
|
||||||
private val genericKProperty1ImplType = context.reflectionTypes.kProperty1Impl
|
|
||||||
private val genericKProperty2ImplType = context.reflectionTypes.kProperty2Impl
|
|
||||||
private val genericKMutableProperty0ImplType = context.reflectionTypes.kMutableProperty0Impl
|
|
||||||
private val genericKMutableProperty1ImplType = context.reflectionTypes.kMutableProperty1Impl
|
|
||||||
private val genericKMutableProperty2ImplType = context.reflectionTypes.kMutableProperty2Impl
|
|
||||||
private val genericKLocalDelegatedMutablePropertyImplType = context.reflectionTypes.kLocalDelegatedMutablePropertyImpl
|
|
||||||
|
|
||||||
private val kotlinPackage = context.irModule!!.descriptor.getPackage(FqName("kotlin"))
|
private val kotlinPackage = context.irModule!!.descriptor.getPackage(FqName("kotlin"))
|
||||||
private val genericArrayType = kotlinPackage.memberScope.getContributedClassifier(Name.identifier("Array"), NoLookupLocation.FROM_BACKEND) as ClassDescriptor
|
private val genericArrayType = kotlinPackage.memberScope.getContributedClassifier(Name.identifier("Array"), NoLookupLocation.FROM_BACKEND) as ClassDescriptor
|
||||||
|
|
||||||
@@ -48,22 +40,22 @@ internal class PropertyDelegationLowering(val context: Context) : FileLoweringPa
|
|||||||
if (isLocal) {
|
if (isLocal) {
|
||||||
assert(receiverTypes.isEmpty(), { "Local delegated property cannot have explicit receiver" })
|
assert(receiverTypes.isEmpty(), { "Local delegated property cannot have explicit receiver" })
|
||||||
when {
|
when {
|
||||||
isMutable -> genericKLocalDelegatedMutablePropertyImplType
|
isMutable -> reflectionTypes.kLocalDelegatedMutablePropertyImpl
|
||||||
else -> genericKLocalDelegatedPropertyImplType
|
else -> reflectionTypes.kLocalDelegatedPropertyImpl
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
when (receiverTypes.size) {
|
when (receiverTypes.size) {
|
||||||
0 -> when {
|
0 -> when {
|
||||||
isMutable -> genericKMutableProperty0ImplType
|
isMutable -> reflectionTypes.kMutableProperty0Impl
|
||||||
else -> genericKProperty0ImplType
|
else -> reflectionTypes.kProperty0Impl
|
||||||
}
|
}
|
||||||
1 -> when {
|
1 -> when {
|
||||||
isMutable -> genericKMutableProperty1ImplType
|
isMutable -> reflectionTypes.kMutableProperty1Impl
|
||||||
else -> genericKProperty1ImplType
|
else -> reflectionTypes.kProperty1Impl
|
||||||
}
|
}
|
||||||
2 -> when {
|
2 -> when {
|
||||||
isMutable -> genericKMutableProperty2ImplType
|
isMutable -> reflectionTypes.kMutableProperty2Impl
|
||||||
else -> genericKProperty2ImplType
|
else -> reflectionTypes.kProperty2Impl
|
||||||
}
|
}
|
||||||
else -> throw AssertionError("More than 2 receivers is not allowed")
|
else -> throw AssertionError("More than 2 receivers is not allowed")
|
||||||
}
|
}
|
||||||
@@ -85,7 +77,7 @@ internal class PropertyDelegationLowering(val context: Context) : FileLoweringPa
|
|||||||
val arrayItemGetter = genericArrayType.unsubstitutedMemberScope.getContributedFunctions(Name.identifier("get"),
|
val arrayItemGetter = genericArrayType.unsubstitutedMemberScope.getContributedFunctions(Name.identifier("get"),
|
||||||
NoLookupLocation.FROM_BACKEND).single()
|
NoLookupLocation.FROM_BACKEND).single()
|
||||||
val typeParameterT = genericArrayType.declaredTypeParameters[0]
|
val typeParameterT = genericArrayType.declaredTypeParameters[0]
|
||||||
val kPropertyImplType = genericKProperty1ImplType.replace(context.builtIns.anyType, context.builtIns.anyType)
|
val kPropertyImplType = reflectionTypes.kProperty1Impl.replace(context.builtIns.anyType, context.builtIns.anyType)
|
||||||
val typeSubstitutor = TypeSubstitutor.create(mapOf(typeParameterT.typeConstructor to TypeProjectionImpl(kPropertyImplType)))
|
val typeSubstitutor = TypeSubstitutor.create(mapOf(typeParameterT.typeConstructor to TypeProjectionImpl(kPropertyImplType)))
|
||||||
val substitutedArrayItemGetter = arrayItemGetter.substitute(typeSubstitutor)!!
|
val substitutedArrayItemGetter = arrayItemGetter.substitute(typeSubstitutor)!!
|
||||||
|
|
||||||
@@ -178,7 +170,7 @@ internal class PropertyDelegationLowering(val context: Context) : FileLoweringPa
|
|||||||
}
|
}
|
||||||
|
|
||||||
val setterCallableReference = propertyDescriptor.setter.let {
|
val setterCallableReference = propertyDescriptor.setter.let {
|
||||||
if (it == null || isLocal) null
|
if (it == null || isLocal || !isKMutablePropertyType(expression.type)) null
|
||||||
else {
|
else {
|
||||||
val setterKFunctionType = context.reflectionTypes.getKFunctionType(
|
val setterKFunctionType = context.reflectionTypes.getKFunctionType(
|
||||||
annotations = Annotations.EMPTY,
|
annotations = Annotations.EMPTY,
|
||||||
@@ -208,6 +200,18 @@ internal class PropertyDelegationLowering(val context: Context) : FileLoweringPa
|
|||||||
return initializer
|
return initializer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun isKMutablePropertyType(type: KotlinType): Boolean {
|
||||||
|
val arguments = type.arguments
|
||||||
|
val expectedClassDescriptor = when (arguments.size) {
|
||||||
|
0 -> return false
|
||||||
|
1 -> reflectionTypes.kMutableProperty0
|
||||||
|
2 -> reflectionTypes.kMutableProperty1
|
||||||
|
3 -> reflectionTypes.kMutableProperty2
|
||||||
|
else -> throw AssertionError("More than 2 receivers is not allowed")
|
||||||
|
}
|
||||||
|
return type == expectedClassDescriptor.defaultType.replace(arguments)
|
||||||
|
}
|
||||||
|
|
||||||
private object DECLARATION_ORIGIN_KPROPERTIES_FOR_DELEGATION :
|
private object DECLARATION_ORIGIN_KPROPERTIES_FOR_DELEGATION :
|
||||||
IrDeclarationOriginImpl("KPROPERTIES_FOR_DELEGATION")
|
IrDeclarationOriginImpl("KPROPERTIES_FOR_DELEGATION")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user