KT-16535 'provideDelegate' convention is not supported in IR
Implement provideDelegate convention support. NB delegate type now depends on 'provideDelegate' convention resolution.
This commit is contained in:
+75
-28
@@ -22,12 +22,10 @@ import org.jetbrains.kotlin.ir.builders.irGet
|
||||
import org.jetbrains.kotlin.ir.builders.irReturn
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.*
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrLocalDelegatedPropertyDelegateDescriptor
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrLocalDelegatedPropertyDelegateDescriptorImpl
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrPropertyDelegateDescriptor
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrPropertyDelegateDescriptorImpl
|
||||
import org.jetbrains.kotlin.ir.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallableReferenceImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
@@ -46,11 +44,10 @@ class DelegatedPropertyGenerator(override val context: GeneratorContext) : Gener
|
||||
propertyDescriptor: PropertyDescriptor,
|
||||
irDelegateInitializer: IrExpressionBody
|
||||
): IrProperty {
|
||||
val delegateDescriptor = createPropertyDelegateDescriptor(ktDelegate, propertyDescriptor)
|
||||
val kPropertyType = getKPropertyTypeForDelegatedProperty(propertyDescriptor)
|
||||
|
||||
val irDelegate = IrFieldImpl(
|
||||
ktDelegate.startOffset, ktDelegate.endOffset, IrDeclarationOrigin.DELEGATE,
|
||||
delegateDescriptor, irDelegateInitializer)
|
||||
val irDelegate = generateDelegateFieldForProperty(propertyDescriptor, kPropertyType, irDelegateInitializer, ktDelegate)
|
||||
val delegateDescriptor = irDelegate.descriptor as IrPropertyDelegateDescriptor
|
||||
|
||||
val irProperty = IrPropertyImpl(
|
||||
ktProperty.startOffset, ktProperty.endOffset, IrDeclarationOrigin.DEFINED, true,
|
||||
@@ -63,7 +60,9 @@ class DelegatedPropertyGenerator(override val context: GeneratorContext) : Gener
|
||||
getterDescriptor,
|
||||
generateDelegatedPropertyGetterBody(
|
||||
ktDelegate, getterDescriptor, delegateReceiverValue,
|
||||
createCallableReference(ktDelegate, delegateDescriptor.kPropertyType, propertyDescriptor)))
|
||||
createCallableReference(ktDelegate, kPropertyType, propertyDescriptor)
|
||||
)
|
||||
)
|
||||
|
||||
if (propertyDescriptor.isVar) {
|
||||
val setterDescriptor = propertyDescriptor.setter!!
|
||||
@@ -72,12 +71,54 @@ class DelegatedPropertyGenerator(override val context: GeneratorContext) : Gener
|
||||
setterDescriptor,
|
||||
generateDelegatedPropertySetterBody(
|
||||
ktDelegate, setterDescriptor, delegateReceiverValue,
|
||||
createCallableReference(ktDelegate, delegateDescriptor.kPropertyType, propertyDescriptor)))
|
||||
createCallableReference(ktDelegate, kPropertyType, propertyDescriptor)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
return irProperty
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
private fun generateDelegateFieldForProperty(
|
||||
propertyDescriptor: PropertyDescriptor,
|
||||
kPropertyType: KotlinType,
|
||||
irDelegateInitializer: IrExpressionBody,
|
||||
ktDelegate: KtPropertyDelegate
|
||||
): IrFieldImpl {
|
||||
val irActualDelegateInitializer = generateInitializerBodyForPropertyDelegate(propertyDescriptor, kPropertyType, irDelegateInitializer, ktDelegate)
|
||||
|
||||
val delegateType = irActualDelegateInitializer.expression.type
|
||||
val delegateDescriptor = createPropertyDelegateDescriptor(propertyDescriptor, delegateType, kPropertyType)
|
||||
|
||||
return IrFieldImpl(
|
||||
ktDelegate.startOffset, ktDelegate.endOffset, IrDeclarationOrigin.DELEGATE,
|
||||
delegateDescriptor, irActualDelegateInitializer
|
||||
)
|
||||
}
|
||||
|
||||
private fun generateInitializerBodyForPropertyDelegate(
|
||||
property: VariableDescriptorWithAccessors,
|
||||
kPropertyType: KotlinType,
|
||||
irDelegateInitializer: IrExpressionBody,
|
||||
ktDelegate: KtPropertyDelegate
|
||||
): IrExpressionBody {
|
||||
val provideDelegateResolvedCall = get(BindingContext.PROVIDE_DELEGATE_RESOLVED_CALL, property)
|
||||
?: return irDelegateInitializer
|
||||
|
||||
val statementGenerator = BodyGenerator(property, context).createStatementGenerator()
|
||||
val provideDelegateCall = statementGenerator.pregenerateCall(provideDelegateResolvedCall)
|
||||
provideDelegateCall.setExplicitReceiverValue(OnceExpressionValue(irDelegateInitializer.expression))
|
||||
provideDelegateCall.irValueArgumentsByIndex[1] = createCallableReference(ktDelegate, kPropertyType, property)
|
||||
val irProvideDelegate = CallGenerator(statementGenerator).generateCall(ktDelegate.startOffset, ktDelegate.endOffset, provideDelegateCall)
|
||||
return IrExpressionBodyImpl(irProvideDelegate)
|
||||
}
|
||||
|
||||
private fun createBackingFieldValueForDelegate(delegateDescriptor: IrPropertyDelegateDescriptor, ktDelegate: KtPropertyDelegate): IntermediateValue {
|
||||
val thisClass = delegateDescriptor.correspondingProperty.containingDeclaration as? ClassDescriptor
|
||||
val thisValue = thisClass?.let {
|
||||
@@ -96,11 +137,22 @@ class DelegatedPropertyGenerator(override val context: GeneratorContext) : Gener
|
||||
variableDescriptor: VariableDescriptorWithAccessors,
|
||||
irDelegateInitializer: IrExpression
|
||||
): IrLocalDelegatedProperty {
|
||||
val delegateDescriptor = createLocalPropertyDelegatedDescriptor(ktDelegate, variableDescriptor)
|
||||
val kPropertyType = getKPropertyTypeForLocalDelegatedProperty(variableDescriptor)
|
||||
|
||||
val irActualDelegateInitializer =
|
||||
generateInitializerBodyForPropertyDelegate(
|
||||
variableDescriptor, kPropertyType,
|
||||
IrExpressionBodyImpl(irDelegateInitializer), ktDelegate
|
||||
).expression
|
||||
val delegateType = irActualDelegateInitializer.type
|
||||
|
||||
val delegateDescriptor = createLocalPropertyDelegatedDescriptor(variableDescriptor, delegateType, kPropertyType)
|
||||
|
||||
val irDelegate = IrVariableImpl(
|
||||
ktDelegate.startOffset, ktDelegate.endOffset, IrDeclarationOrigin.DELEGATE,
|
||||
delegateDescriptor, irDelegateInitializer)
|
||||
delegateDescriptor,
|
||||
irActualDelegateInitializer
|
||||
)
|
||||
|
||||
val irLocalDelegatedProperty = IrLocalDelegatedPropertyImpl(
|
||||
ktProperty.startOffset, ktProperty.endOffset, IrDeclarationOrigin.DEFINED,
|
||||
@@ -135,27 +187,22 @@ class DelegatedPropertyGenerator(override val context: GeneratorContext) : Gener
|
||||
getterDescriptor, body)
|
||||
|
||||
private fun createLocalPropertyDelegatedDescriptor(
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
variableDescriptor: VariableDescriptorWithAccessors
|
||||
variableDescriptor: VariableDescriptorWithAccessors,
|
||||
delegateType: KotlinType,
|
||||
kPropertyType: KotlinType
|
||||
): IrLocalDelegatedPropertyDelegateDescriptor {
|
||||
val delegateType = getInferredTypeWithImplicitCastsOrFail(ktDelegate.expression!!)
|
||||
val kPropertyType = context.reflectionTypes.getKPropertyType(
|
||||
Annotations.EMPTY, null, variableDescriptor.type, variableDescriptor.isVar)
|
||||
return IrLocalDelegatedPropertyDelegateDescriptorImpl(variableDescriptor, delegateType, kPropertyType)
|
||||
}
|
||||
|
||||
private fun getKPropertyTypeForLocalDelegatedProperty(variableDescriptor: VariableDescriptorWithAccessors) =
|
||||
context.reflectionTypes.getKPropertyType(Annotations.EMPTY, null, variableDescriptor.type, variableDescriptor.isVar)
|
||||
|
||||
private fun createPropertyDelegateDescriptor(
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
propertyDescriptor: PropertyDescriptor
|
||||
): IrPropertyDelegateDescriptor {
|
||||
val delegateType = getInferredTypeWithImplicitCastsOrFail(ktDelegate.expression!!)
|
||||
val propertyReceiverType = propertyDescriptor.extensionReceiverParameter?.type ?:
|
||||
propertyDescriptor.dispatchReceiverParameter?.type
|
||||
val kPropertyType = context.reflectionTypes.getKPropertyType(
|
||||
Annotations.EMPTY, propertyReceiverType, propertyDescriptor.type, propertyDescriptor.isVar)
|
||||
val delegateDescriptor = IrPropertyDelegateDescriptorImpl(propertyDescriptor, delegateType, kPropertyType)
|
||||
return delegateDescriptor
|
||||
}
|
||||
propertyDescriptor: PropertyDescriptor,
|
||||
delegateType: KotlinType,
|
||||
kPropertyType: KotlinType
|
||||
): IrPropertyDelegateDescriptor =
|
||||
IrPropertyDelegateDescriptorImpl(propertyDescriptor, delegateType, kPropertyType)
|
||||
|
||||
fun generateDelegatedPropertyGetterBody(
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
class MyClass(val value: String)
|
||||
|
||||
operator fun MyClass.provideDelegate(host: Any?, p: Any): String =
|
||||
this.value
|
||||
|
||||
operator fun String.getValue(receiver: Any?, p: Any): String =
|
||||
this
|
||||
|
||||
val testO by MyClass("O")
|
||||
val testK by "K"
|
||||
val testOK = testO + testK
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
FILE /differentReceivers.kt
|
||||
CLASS CLASS MyClass
|
||||
CONSTRUCTOR public constructor MyClass(value: kotlin.String)
|
||||
BLOCK_BODY
|
||||
DELEGATING_CONSTRUCTOR_CALL 'constructor Any()'
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='MyClass'
|
||||
PROPERTY public final val value: kotlin.String
|
||||
FIELD PROPERTY_BACKING_FIELD public final val value: kotlin.String
|
||||
EXPRESSION_BODY
|
||||
GET_VAR 'value-parameter value: String' type=kotlin.String origin=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR public final fun <get-value>(): kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='<get-value>(): String'
|
||||
GET_FIELD 'value: String' type=kotlin.String origin=null
|
||||
receiver: GET_VAR '<receiver: MyClass>' type=MyClass origin=null
|
||||
FUN public operator fun MyClass.provideDelegate(host: kotlin.Any?, p: kotlin.Any): kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='provideDelegate(Any?, Any) on MyClass: String'
|
||||
CALL '<get-value>(): String' type=kotlin.String origin=GET_PROPERTY
|
||||
$this: GET_VAR '<receiver: provideDelegate(Any?, Any) on MyClass: String>' type=MyClass origin=null
|
||||
FUN public operator fun kotlin.String.getValue(receiver: kotlin.Any?, p: kotlin.Any): kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='getValue(Any?, Any) on String: String'
|
||||
GET_VAR '<receiver: getValue(Any?, Any) on String: String>' type=kotlin.String origin=null
|
||||
PROPERTY public val testO: kotlin.String
|
||||
FIELD DELEGATE val `testO$delegate`: kotlin.String
|
||||
EXPRESSION_BODY
|
||||
CALL 'provideDelegate(Any?, Any) on MyClass: String' type=kotlin.String origin=null
|
||||
$receiver: CALL 'constructor MyClass(String)' type=MyClass origin=null
|
||||
value: CONST String type=kotlin.String value='O'
|
||||
host: CONST Null type=kotlin.Nothing? value='null'
|
||||
p: CALLABLE_REFERENCE 'testO: String' type=kotlin.reflect.KProperty0<kotlin.String> origin=PROPERTY_REFERENCE_FOR_DELEGATE
|
||||
FUN DELEGATED_PROPERTY_ACCESSOR public fun <get-testO>(): kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='<get-testO>(): String'
|
||||
CALL 'getValue(Any?, Any) on String: String' type=kotlin.String origin=null
|
||||
$receiver: GET_FIELD '`testO$delegate`: String' type=kotlin.String origin=null
|
||||
receiver: CONST Null type=kotlin.Nothing? value='null'
|
||||
p: CALLABLE_REFERENCE 'testO: String' type=kotlin.reflect.KProperty0<kotlin.String> origin=PROPERTY_REFERENCE_FOR_DELEGATE
|
||||
PROPERTY public val testK: kotlin.String
|
||||
FIELD DELEGATE val `testK$delegate`: kotlin.String
|
||||
EXPRESSION_BODY
|
||||
CONST String type=kotlin.String value='K'
|
||||
FUN DELEGATED_PROPERTY_ACCESSOR public fun <get-testK>(): kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='<get-testK>(): String'
|
||||
CALL 'getValue(Any?, Any) on String: String' type=kotlin.String origin=null
|
||||
$receiver: GET_FIELD '`testK$delegate`: String' type=kotlin.String origin=null
|
||||
receiver: CONST Null type=kotlin.Nothing? value='null'
|
||||
p: CALLABLE_REFERENCE 'testK: String' type=kotlin.reflect.KProperty0<kotlin.String> origin=PROPERTY_REFERENCE_FOR_DELEGATE
|
||||
PROPERTY public val testOK: kotlin.String
|
||||
FIELD PROPERTY_BACKING_FIELD public val testOK: kotlin.String
|
||||
EXPRESSION_BODY
|
||||
CALL 'plus(Any?): String' type=kotlin.String origin=PLUS
|
||||
$this: CALL '<get-testO>(): String' type=kotlin.String origin=GET_PROPERTY
|
||||
other: CALL '<get-testK>(): String' type=kotlin.String origin=GET_PROPERTY
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR public fun <get-testOK>(): kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='<get-testOK>(): String'
|
||||
GET_FIELD 'testOK: String' type=kotlin.String origin=null
|
||||
@@ -0,0 +1,12 @@
|
||||
class Delegate(val value: String) {
|
||||
operator fun getValue(thisRef: Any?, property: Any?) = value
|
||||
}
|
||||
|
||||
class DelegateProvider(val value: String) {
|
||||
operator fun provideDelegate(thisRef: Any?, property: Any?) = Delegate(value)
|
||||
}
|
||||
|
||||
fun foo() {
|
||||
val testMember by DelegateProvider("OK")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
FILE /local.kt
|
||||
CLASS CLASS Delegate
|
||||
CONSTRUCTOR public constructor Delegate(value: kotlin.String)
|
||||
BLOCK_BODY
|
||||
DELEGATING_CONSTRUCTOR_CALL 'constructor Any()'
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='Delegate'
|
||||
PROPERTY public final val value: kotlin.String
|
||||
FIELD PROPERTY_BACKING_FIELD public final val value: kotlin.String
|
||||
EXPRESSION_BODY
|
||||
GET_VAR 'value-parameter value: String' type=kotlin.String origin=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR public final fun <get-value>(): kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='<get-value>(): String'
|
||||
GET_FIELD 'value: String' type=kotlin.String origin=null
|
||||
receiver: GET_VAR '<receiver: Delegate>' type=Delegate origin=null
|
||||
FUN public final operator fun getValue(thisRef: kotlin.Any?, property: kotlin.Any?): kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='getValue(Any?, Any?): String'
|
||||
CALL '<get-value>(): String' type=kotlin.String origin=GET_PROPERTY
|
||||
$this: GET_VAR '<receiver: Delegate>' type=Delegate origin=null
|
||||
CLASS CLASS DelegateProvider
|
||||
CONSTRUCTOR public constructor DelegateProvider(value: kotlin.String)
|
||||
BLOCK_BODY
|
||||
DELEGATING_CONSTRUCTOR_CALL 'constructor Any()'
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='DelegateProvider'
|
||||
PROPERTY public final val value: kotlin.String
|
||||
FIELD PROPERTY_BACKING_FIELD public final val value: kotlin.String
|
||||
EXPRESSION_BODY
|
||||
GET_VAR 'value-parameter value: String' type=kotlin.String origin=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR public final fun <get-value>(): kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='<get-value>(): String'
|
||||
GET_FIELD 'value: String' type=kotlin.String origin=null
|
||||
receiver: GET_VAR '<receiver: DelegateProvider>' type=DelegateProvider origin=null
|
||||
FUN public final operator fun provideDelegate(thisRef: kotlin.Any?, property: kotlin.Any?): Delegate
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='provideDelegate(Any?, Any?): Delegate'
|
||||
CALL 'constructor Delegate(String)' type=Delegate origin=null
|
||||
value: CALL '<get-value>(): String' type=kotlin.String origin=GET_PROPERTY
|
||||
$this: GET_VAR '<receiver: DelegateProvider>' type=DelegateProvider origin=null
|
||||
FUN public fun foo(): kotlin.Unit
|
||||
BLOCK_BODY
|
||||
LOCAL_DELEGATED_PROPERTY val testMember: kotlin.String
|
||||
VAR DELEGATE val `testMember$delegate`: Delegate
|
||||
CALL 'provideDelegate(Any?, Any?): Delegate' type=Delegate origin=null
|
||||
$this: CALL 'constructor DelegateProvider(String)' type=DelegateProvider origin=null
|
||||
value: CONST String type=kotlin.String value='OK'
|
||||
thisRef: CONST Null type=kotlin.Nothing? value='null'
|
||||
property: CALLABLE_REFERENCE 'testMember: String' type=kotlin.reflect.KProperty0<kotlin.String> origin=PROPERTY_REFERENCE_FOR_DELEGATE
|
||||
FUN DELEGATED_PROPERTY_ACCESSOR local final fun <get-testMember>(): kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='<get-testMember>(): String'
|
||||
CALL 'getValue(Any?, Any?): String' type=kotlin.String origin=null
|
||||
$this: GET_VAR '`testMember$delegate`: Delegate' type=Delegate origin=null
|
||||
thisRef: CONST Null type=kotlin.Nothing? value='null'
|
||||
property: CALLABLE_REFERENCE 'testMember: String' type=kotlin.reflect.KProperty0<kotlin.String> origin=PROPERTY_REFERENCE_FOR_DELEGATE
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
class MyClass(val value: String)
|
||||
|
||||
operator fun MyClass.provideDelegate(host: Any?, p: Any): String =
|
||||
this.value
|
||||
|
||||
operator fun String.getValue(receiver: Any?, p: Any): String =
|
||||
this
|
||||
|
||||
|
||||
fun box(): String {
|
||||
val testO by MyClass("O")
|
||||
val testK by "K"
|
||||
val testOK = testO + testK
|
||||
|
||||
return testOK
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
FILE /localDifferentReceivers.kt
|
||||
CLASS CLASS MyClass
|
||||
CONSTRUCTOR public constructor MyClass(value: kotlin.String)
|
||||
BLOCK_BODY
|
||||
DELEGATING_CONSTRUCTOR_CALL 'constructor Any()'
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='MyClass'
|
||||
PROPERTY public final val value: kotlin.String
|
||||
FIELD PROPERTY_BACKING_FIELD public final val value: kotlin.String
|
||||
EXPRESSION_BODY
|
||||
GET_VAR 'value-parameter value: String' type=kotlin.String origin=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR public final fun <get-value>(): kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='<get-value>(): String'
|
||||
GET_FIELD 'value: String' type=kotlin.String origin=null
|
||||
receiver: GET_VAR '<receiver: MyClass>' type=MyClass origin=null
|
||||
FUN public operator fun MyClass.provideDelegate(host: kotlin.Any?, p: kotlin.Any): kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='provideDelegate(Any?, Any) on MyClass: String'
|
||||
CALL '<get-value>(): String' type=kotlin.String origin=GET_PROPERTY
|
||||
$this: GET_VAR '<receiver: provideDelegate(Any?, Any) on MyClass: String>' type=MyClass origin=null
|
||||
FUN public operator fun kotlin.String.getValue(receiver: kotlin.Any?, p: kotlin.Any): kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='getValue(Any?, Any) on String: String'
|
||||
GET_VAR '<receiver: getValue(Any?, Any) on String: String>' type=kotlin.String origin=null
|
||||
FUN public fun box(): kotlin.String
|
||||
BLOCK_BODY
|
||||
LOCAL_DELEGATED_PROPERTY val testO: kotlin.String
|
||||
VAR DELEGATE val `testO$delegate`: kotlin.String
|
||||
CALL 'provideDelegate(Any?, Any) on MyClass: String' type=kotlin.String origin=null
|
||||
$receiver: CALL 'constructor MyClass(String)' type=MyClass origin=null
|
||||
value: CONST String type=kotlin.String value='O'
|
||||
host: CONST Null type=kotlin.Nothing? value='null'
|
||||
p: CALLABLE_REFERENCE 'testO: String' type=kotlin.reflect.KProperty0<kotlin.String> origin=PROPERTY_REFERENCE_FOR_DELEGATE
|
||||
FUN DELEGATED_PROPERTY_ACCESSOR local final fun <get-testO>(): kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='<get-testO>(): String'
|
||||
CALL 'getValue(Any?, Any) on String: String' type=kotlin.String origin=null
|
||||
$receiver: GET_VAR '`testO$delegate`: String' type=kotlin.String origin=null
|
||||
receiver: CONST Null type=kotlin.Nothing? value='null'
|
||||
p: CALLABLE_REFERENCE 'testO: String' type=kotlin.reflect.KProperty0<kotlin.String> origin=PROPERTY_REFERENCE_FOR_DELEGATE
|
||||
LOCAL_DELEGATED_PROPERTY val testK: kotlin.String
|
||||
VAR DELEGATE val `testK$delegate`: kotlin.String
|
||||
CONST String type=kotlin.String value='K'
|
||||
FUN DELEGATED_PROPERTY_ACCESSOR local final fun <get-testK>(): kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='<get-testK>(): String'
|
||||
CALL 'getValue(Any?, Any) on String: String' type=kotlin.String origin=null
|
||||
$receiver: GET_VAR '`testK$delegate`: String' type=kotlin.String origin=null
|
||||
receiver: CONST Null type=kotlin.Nothing? value='null'
|
||||
p: CALLABLE_REFERENCE 'testK: String' type=kotlin.reflect.KProperty0<kotlin.String> origin=PROPERTY_REFERENCE_FOR_DELEGATE
|
||||
VAR val testOK: kotlin.String
|
||||
CALL 'plus(Any?): String' type=kotlin.String origin=PLUS
|
||||
$this: CALL '<get-testO>(): String' type=kotlin.String origin=GET_LOCAL_PROPERTY
|
||||
other: CALL '<get-testK>(): String' type=kotlin.String origin=GET_LOCAL_PROPERTY
|
||||
RETURN type=kotlin.Nothing from='box(): String'
|
||||
GET_VAR 'testOK: String' type=kotlin.String origin=null
|
||||
@@ -0,0 +1,12 @@
|
||||
class Delegate(val value: String) {
|
||||
operator fun getValue(thisRef: Any?, property: Any?) = value
|
||||
}
|
||||
|
||||
class DelegateProvider(val value: String) {
|
||||
operator fun provideDelegate(thisRef: Any?, property: Any?) = Delegate(value)
|
||||
}
|
||||
|
||||
class Host {
|
||||
val testMember by DelegateProvider("OK")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
FILE /member.kt
|
||||
CLASS CLASS Delegate
|
||||
CONSTRUCTOR public constructor Delegate(value: kotlin.String)
|
||||
BLOCK_BODY
|
||||
DELEGATING_CONSTRUCTOR_CALL 'constructor Any()'
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='Delegate'
|
||||
PROPERTY public final val value: kotlin.String
|
||||
FIELD PROPERTY_BACKING_FIELD public final val value: kotlin.String
|
||||
EXPRESSION_BODY
|
||||
GET_VAR 'value-parameter value: String' type=kotlin.String origin=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR public final fun <get-value>(): kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='<get-value>(): String'
|
||||
GET_FIELD 'value: String' type=kotlin.String origin=null
|
||||
receiver: GET_VAR '<receiver: Delegate>' type=Delegate origin=null
|
||||
FUN public final operator fun getValue(thisRef: kotlin.Any?, property: kotlin.Any?): kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='getValue(Any?, Any?): String'
|
||||
CALL '<get-value>(): String' type=kotlin.String origin=GET_PROPERTY
|
||||
$this: GET_VAR '<receiver: Delegate>' type=Delegate origin=null
|
||||
CLASS CLASS DelegateProvider
|
||||
CONSTRUCTOR public constructor DelegateProvider(value: kotlin.String)
|
||||
BLOCK_BODY
|
||||
DELEGATING_CONSTRUCTOR_CALL 'constructor Any()'
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='DelegateProvider'
|
||||
PROPERTY public final val value: kotlin.String
|
||||
FIELD PROPERTY_BACKING_FIELD public final val value: kotlin.String
|
||||
EXPRESSION_BODY
|
||||
GET_VAR 'value-parameter value: String' type=kotlin.String origin=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR public final fun <get-value>(): kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='<get-value>(): String'
|
||||
GET_FIELD 'value: String' type=kotlin.String origin=null
|
||||
receiver: GET_VAR '<receiver: DelegateProvider>' type=DelegateProvider origin=null
|
||||
FUN public final operator fun provideDelegate(thisRef: kotlin.Any?, property: kotlin.Any?): Delegate
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='provideDelegate(Any?, Any?): Delegate'
|
||||
CALL 'constructor Delegate(String)' type=Delegate origin=null
|
||||
value: CALL '<get-value>(): String' type=kotlin.String origin=GET_PROPERTY
|
||||
$this: GET_VAR '<receiver: DelegateProvider>' type=DelegateProvider origin=null
|
||||
CLASS CLASS Host
|
||||
CONSTRUCTOR public constructor Host()
|
||||
BLOCK_BODY
|
||||
DELEGATING_CONSTRUCTOR_CALL 'constructor Any()'
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='Host'
|
||||
PROPERTY public final val testMember: kotlin.String
|
||||
FIELD DELEGATE val `testMember$delegate`: Delegate
|
||||
EXPRESSION_BODY
|
||||
CALL 'provideDelegate(Any?, Any?): Delegate' type=Delegate origin=null
|
||||
$this: CALL 'constructor DelegateProvider(String)' type=DelegateProvider origin=null
|
||||
value: CONST String type=kotlin.String value='OK'
|
||||
thisRef: GET_VAR '<receiver: Host>' type=Host origin=null
|
||||
property: CALLABLE_REFERENCE 'testMember: String' type=kotlin.reflect.KProperty1<Host, kotlin.String> origin=PROPERTY_REFERENCE_FOR_DELEGATE
|
||||
FUN DELEGATED_PROPERTY_ACCESSOR public final fun <get-testMember>(): kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='<get-testMember>(): String'
|
||||
CALL 'getValue(Any?, Any?): String' type=kotlin.String origin=null
|
||||
$this: GET_FIELD '`testMember$delegate`: Delegate' type=Delegate origin=null
|
||||
receiver: GET_VAR '<receiver: Host>' type=Host origin=null
|
||||
thisRef: GET_VAR '<receiver: Host>' type=Host origin=null
|
||||
property: CALLABLE_REFERENCE 'testMember: String' type=kotlin.reflect.KProperty1<Host, kotlin.String> origin=PROPERTY_REFERENCE_FOR_DELEGATE
|
||||
@@ -0,0 +1,12 @@
|
||||
object Host {
|
||||
class StringDelegate(val s: String) {
|
||||
operator fun getValue(receiver: String, p: Any) = receiver + s
|
||||
}
|
||||
|
||||
operator fun String.provideDelegate(host: Any?, p: Any) = StringDelegate(this)
|
||||
|
||||
val String.plusK by "K"
|
||||
|
||||
val ok = "O".plusK
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
FILE /memberExtension.kt
|
||||
CLASS OBJECT Host
|
||||
CONSTRUCTOR private constructor Host()
|
||||
BLOCK_BODY
|
||||
DELEGATING_CONSTRUCTOR_CALL 'constructor Any()'
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='Host'
|
||||
CLASS CLASS StringDelegate
|
||||
CONSTRUCTOR public constructor StringDelegate(s: kotlin.String)
|
||||
BLOCK_BODY
|
||||
DELEGATING_CONSTRUCTOR_CALL 'constructor Any()'
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='StringDelegate'
|
||||
PROPERTY public final val s: kotlin.String
|
||||
FIELD PROPERTY_BACKING_FIELD public final val s: kotlin.String
|
||||
EXPRESSION_BODY
|
||||
GET_VAR 'value-parameter s: String' type=kotlin.String origin=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR public final fun <get-s>(): kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='<get-s>(): String'
|
||||
GET_FIELD 's: String' type=kotlin.String origin=null
|
||||
receiver: GET_VAR '<receiver: StringDelegate>' type=Host.StringDelegate origin=null
|
||||
FUN public final operator fun getValue(receiver: kotlin.String, p: kotlin.Any): kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='getValue(String, Any): String'
|
||||
CALL 'plus(Any?): String' type=kotlin.String origin=PLUS
|
||||
$this: GET_VAR 'value-parameter receiver: String' type=kotlin.String origin=null
|
||||
other: CALL '<get-s>(): String' type=kotlin.String origin=GET_PROPERTY
|
||||
$this: GET_VAR '<receiver: StringDelegate>' type=Host.StringDelegate origin=null
|
||||
FUN public final operator fun kotlin.String.provideDelegate(host: kotlin.Any?, p: kotlin.Any): Host.StringDelegate
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='provideDelegate(Any?, Any) on String: Host.StringDelegate'
|
||||
CALL 'constructor StringDelegate(String)' type=Host.StringDelegate origin=null
|
||||
s: GET_VAR '<receiver: provideDelegate(Any?, Any) on String: Host.StringDelegate>' type=kotlin.String origin=null
|
||||
PROPERTY public final val kotlin.String.plusK: kotlin.String
|
||||
FIELD DELEGATE val `plusK$delegate`: Host.StringDelegate
|
||||
EXPRESSION_BODY
|
||||
CALL 'provideDelegate(Any?, Any) on String: Host.StringDelegate' type=Host.StringDelegate origin=null
|
||||
$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
|
||||
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'
|
||||
CALL 'getValue(String, Any): String' type=kotlin.String origin=null
|
||||
$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
|
||||
PROPERTY public final val ok: kotlin.String
|
||||
FIELD PROPERTY_BACKING_FIELD public final val ok: kotlin.String
|
||||
EXPRESSION_BODY
|
||||
CALL '<get-plusK>() on String: String' type=kotlin.String origin=GET_PROPERTY
|
||||
$this: GET_VAR '<receiver: Host>' type=Host origin=null
|
||||
$receiver: CONST String type=kotlin.String value='O'
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR public final fun <get-ok>(): kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='<get-ok>(): String'
|
||||
GET_FIELD 'ok: String' type=kotlin.String origin=null
|
||||
receiver: GET_VAR '<receiver: Host>' type=Host origin=null
|
||||
@@ -0,0 +1,10 @@
|
||||
class Delegate(val value: String) {
|
||||
operator fun getValue(thisRef: Any?, property: Any?) = value
|
||||
}
|
||||
|
||||
class DelegateProvider(val value: String) {
|
||||
operator fun provideDelegate(thisRef: Any?, property: Any?) = Delegate(value)
|
||||
}
|
||||
|
||||
val testTopLevel by DelegateProvider("OK")
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
FILE /topLevel.kt
|
||||
CLASS CLASS Delegate
|
||||
CONSTRUCTOR public constructor Delegate(value: kotlin.String)
|
||||
BLOCK_BODY
|
||||
DELEGATING_CONSTRUCTOR_CALL 'constructor Any()'
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='Delegate'
|
||||
PROPERTY public final val value: kotlin.String
|
||||
FIELD PROPERTY_BACKING_FIELD public final val value: kotlin.String
|
||||
EXPRESSION_BODY
|
||||
GET_VAR 'value-parameter value: String' type=kotlin.String origin=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR public final fun <get-value>(): kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='<get-value>(): String'
|
||||
GET_FIELD 'value: String' type=kotlin.String origin=null
|
||||
receiver: GET_VAR '<receiver: Delegate>' type=Delegate origin=null
|
||||
FUN public final operator fun getValue(thisRef: kotlin.Any?, property: kotlin.Any?): kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='getValue(Any?, Any?): String'
|
||||
CALL '<get-value>(): String' type=kotlin.String origin=GET_PROPERTY
|
||||
$this: GET_VAR '<receiver: Delegate>' type=Delegate origin=null
|
||||
CLASS CLASS DelegateProvider
|
||||
CONSTRUCTOR public constructor DelegateProvider(value: kotlin.String)
|
||||
BLOCK_BODY
|
||||
DELEGATING_CONSTRUCTOR_CALL 'constructor Any()'
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='DelegateProvider'
|
||||
PROPERTY public final val value: kotlin.String
|
||||
FIELD PROPERTY_BACKING_FIELD public final val value: kotlin.String
|
||||
EXPRESSION_BODY
|
||||
GET_VAR 'value-parameter value: String' type=kotlin.String origin=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR public final fun <get-value>(): kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='<get-value>(): String'
|
||||
GET_FIELD 'value: String' type=kotlin.String origin=null
|
||||
receiver: GET_VAR '<receiver: DelegateProvider>' type=DelegateProvider origin=null
|
||||
FUN public final operator fun provideDelegate(thisRef: kotlin.Any?, property: kotlin.Any?): Delegate
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='provideDelegate(Any?, Any?): Delegate'
|
||||
CALL 'constructor Delegate(String)' type=Delegate origin=null
|
||||
value: CALL '<get-value>(): String' type=kotlin.String origin=GET_PROPERTY
|
||||
$this: GET_VAR '<receiver: DelegateProvider>' type=DelegateProvider origin=null
|
||||
PROPERTY public val testTopLevel: kotlin.String
|
||||
FIELD DELEGATE val `testTopLevel$delegate`: Delegate
|
||||
EXPRESSION_BODY
|
||||
CALL 'provideDelegate(Any?, Any?): Delegate' type=Delegate origin=null
|
||||
$this: CALL 'constructor DelegateProvider(String)' type=DelegateProvider origin=null
|
||||
value: CONST String type=kotlin.String value='OK'
|
||||
thisRef: CONST Null type=kotlin.Nothing? value='null'
|
||||
property: CALLABLE_REFERENCE 'testTopLevel: String' type=kotlin.reflect.KProperty0<kotlin.String> origin=PROPERTY_REFERENCE_FOR_DELEGATE
|
||||
FUN DELEGATED_PROPERTY_ACCESSOR public fun <get-testTopLevel>(): kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='<get-testTopLevel>(): String'
|
||||
CALL 'getValue(Any?, Any?): String' type=kotlin.String origin=null
|
||||
$this: GET_FIELD '`testTopLevel$delegate`: Delegate' type=Delegate origin=null
|
||||
thisRef: CONST Null type=kotlin.Nothing? value='null'
|
||||
property: CALLABLE_REFERENCE 'testTopLevel: String' type=kotlin.reflect.KProperty0<kotlin.String> origin=PROPERTY_REFERENCE_FOR_DELEGATE
|
||||
@@ -268,6 +268,51 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/declarations/typeAlias.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/ir/irText/declarations/provideDelegate")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ProvideDelegate extends AbstractIrTextTestCase {
|
||||
public void testAllFilesPresentInProvideDelegate() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/ir/irText/declarations/provideDelegate"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("differentReceivers.kt")
|
||||
public void testDifferentReceivers() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/declarations/provideDelegate/differentReceivers.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("local.kt")
|
||||
public void testLocal() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/declarations/provideDelegate/local.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("localDifferentReceivers.kt")
|
||||
public void testLocalDifferentReceivers() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/declarations/provideDelegate/localDifferentReceivers.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("member.kt")
|
||||
public void testMember() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/declarations/provideDelegate/member.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("memberExtension.kt")
|
||||
public void testMemberExtension() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/declarations/provideDelegate/memberExtension.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("topLevel.kt")
|
||||
public void testTopLevel() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/declarations/provideDelegate/topLevel.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/ir/irText/errors")
|
||||
|
||||
Reference in New Issue
Block a user