Local delegated properties.
This commit is contained in:
committed by
Dmitry Petrov
parent
e42116bb6a
commit
42988383e0
@@ -129,8 +129,7 @@ class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context:
|
||||
irBlockBody.addStatement(irDelegatingConstructorCall)
|
||||
}
|
||||
|
||||
private fun createStatementGenerator() =
|
||||
StatementGenerator(context, scopeOwner, this, scope)
|
||||
fun createStatementGenerator() = StatementGenerator(this, scope)
|
||||
|
||||
fun putLoop(expression: KtLoopExpression, irLoop: IrLoop) {
|
||||
loopTable[expression] = irLoop
|
||||
@@ -261,34 +260,5 @@ class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context:
|
||||
|
||||
private fun createPropertyInitializationExpression(ktElement: KtElement, propertyDescriptor: PropertyDescriptor, value: IrExpression) =
|
||||
IrSetBackingFieldImpl(ktElement.startOffset, ktElement.endOffset, propertyDescriptor, value)
|
||||
|
||||
fun generateDelegatedPropertyGetter(
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
delegateDescriptor: IrPropertyDelegateDescriptor,
|
||||
getterDescriptor: PropertyGetterDescriptor
|
||||
): IrBody =
|
||||
irBlockBody(ktDelegate) {
|
||||
val statementGenerator = createStatementGenerator()
|
||||
val conventionMethodResolvedCall = getOrFail(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, getterDescriptor)
|
||||
val conventionMethodCall = statementGenerator.pregenerateCall(conventionMethodResolvedCall)
|
||||
conventionMethodCall.setExplicitReceiverValue(VariableLValue(ktDelegate.startOffset, ktDelegate.endOffset, delegateDescriptor))
|
||||
conventionMethodCall.irValueArgumentsByIndex[1] = irCallableReference(delegateDescriptor.kPropertyType, delegateDescriptor.correspondingProperty)
|
||||
+irReturn(CallGenerator(statementGenerator).generateCall(ktDelegate.startOffset, ktDelegate.endOffset, conventionMethodCall))
|
||||
}
|
||||
|
||||
fun generateDelegatedPropertySetter(
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
delegateDescriptor: IrPropertyDelegateDescriptor,
|
||||
setterDescriptor: PropertySetterDescriptor
|
||||
): IrBody =
|
||||
irBlockBody(ktDelegate) {
|
||||
val statementGenerator = createStatementGenerator()
|
||||
val conventionMethodResolvedCall = getOrFail(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, setterDescriptor)
|
||||
val conventionMethodCall = statementGenerator.pregenerateCall(conventionMethodResolvedCall)
|
||||
conventionMethodCall.setExplicitReceiverValue(VariableLValue(ktDelegate.startOffset, ktDelegate.endOffset, delegateDescriptor))
|
||||
conventionMethodCall.irValueArgumentsByIndex[1] = irCallableReference(delegateDescriptor.kPropertyType, delegateDescriptor.correspondingProperty)
|
||||
conventionMethodCall.irValueArgumentsByIndex[2] = irGet(setterDescriptor.valueParameters[0])
|
||||
+irReturn(CallGenerator(statementGenerator).generateCall(ktDelegate.startOffset, ktDelegate.endOffset, conventionMethodCall))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -81,8 +81,8 @@ class ClassGenerator(val declarationGenerator: DeclarationGenerator) : Generator
|
||||
val superClass = superTypeConstructorDescriptor as? ClassDescriptor ?:
|
||||
throw AssertionError("Unexpected supertype constructor for delegation: $superTypeConstructorDescriptor")
|
||||
val delegateDescriptor = IrImplementingDelegateDescriptorImpl(irClass.descriptor, delegateType, superType)
|
||||
val irDelegate = IrDelegateImpl(ktDelegateExpression.startOffset, ktDelegateExpression.endOffset, IrDeclarationOrigin.DELEGATE,
|
||||
delegateDescriptor)
|
||||
val irDelegate = IrSimplePropertyImpl(ktDelegateExpression.startOffset, ktDelegateExpression.endOffset, IrDeclarationOrigin.DELEGATE,
|
||||
delegateDescriptor)
|
||||
val bodyGenerator = BodyGenerator(irClass.descriptor, context)
|
||||
irDelegate.initializer = bodyGenerator.generatePropertyInitializerBody(ktDelegateExpression)
|
||||
irClass.addMember(irDelegate)
|
||||
@@ -95,7 +95,7 @@ class ClassGenerator(val declarationGenerator: DeclarationGenerator) : Generator
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateDelegatedMember(irClass: IrClassImpl, irDelegate: IrDelegateImpl, delegatedMember: CallableMemberDescriptor, overriddenMember: CallableMemberDescriptor) {
|
||||
private fun generateDelegatedMember(irClass: IrClassImpl, irDelegate: IrSimplePropertyImpl, delegatedMember: CallableMemberDescriptor, overriddenMember: CallableMemberDescriptor) {
|
||||
when (delegatedMember) {
|
||||
is FunctionDescriptor ->
|
||||
generateDelegatedFunction(irClass, irDelegate, delegatedMember, overriddenMember as FunctionDescriptor)
|
||||
@@ -105,7 +105,7 @@ class ClassGenerator(val declarationGenerator: DeclarationGenerator) : Generator
|
||||
|
||||
}
|
||||
|
||||
private fun generateDelegatedProperty(irClass: IrClassImpl, irDelegate: IrDelegateImpl, delegated: PropertyDescriptor, overridden: PropertyDescriptor) {
|
||||
private fun generateDelegatedProperty(irClass: IrClassImpl, irDelegate: IrSimplePropertyImpl, delegated: PropertyDescriptor, overridden: PropertyDescriptor) {
|
||||
val irProperty = IrSimplePropertyImpl(irDelegate.startOffset, irDelegate.endOffset, IrDeclarationOrigin.DELEGATED_MEMBER, delegated)
|
||||
|
||||
val irGetter = IrPropertyGetterImpl(irDelegate.startOffset, irDelegate.endOffset, IrDeclarationOrigin.DELEGATED_MEMBER, delegated.getter!!)
|
||||
@@ -121,13 +121,13 @@ class ClassGenerator(val declarationGenerator: DeclarationGenerator) : Generator
|
||||
irClass.addMember(irProperty)
|
||||
}
|
||||
|
||||
private fun generateDelegatedFunction(irClass: IrClassImpl, irDelegate: IrDelegateImpl, delegated: FunctionDescriptor, overridden: FunctionDescriptor) {
|
||||
private fun generateDelegatedFunction(irClass: IrClassImpl, irDelegate: IrSimplePropertyImpl, delegated: FunctionDescriptor, overridden: FunctionDescriptor) {
|
||||
val irFunction = IrFunctionImpl(irDelegate.startOffset, irDelegate.endOffset, IrDeclarationOrigin.DELEGATED_MEMBER, delegated)
|
||||
irFunction.body = generateDelegateFunctionBody(irDelegate, delegated, overridden)
|
||||
irClass.addMember(irFunction)
|
||||
}
|
||||
|
||||
private fun generateDelegateFunctionBody(irDelegate: IrDelegateImpl, delegated: FunctionDescriptor, overridden: FunctionDescriptor): IrBlockBodyImpl {
|
||||
private fun generateDelegateFunctionBody(irDelegate: IrSimplePropertyImpl, delegated: FunctionDescriptor, overridden: FunctionDescriptor): IrBlockBodyImpl {
|
||||
val irBlockBody = IrBlockBodyImpl(irDelegate.startOffset, irDelegate.endOffset)
|
||||
val returnType = overridden.returnType!!
|
||||
val irCall = IrCallImpl(irDelegate.startOffset, irDelegate.endOffset, returnType, overridden)
|
||||
@@ -197,7 +197,7 @@ class ClassGenerator(val declarationGenerator: DeclarationGenerator) : Generator
|
||||
val irProperty = IrSimplePropertyImpl(ktParameter.startOffset, ktParameter.endOffset, IrDeclarationOrigin.DEFINED, propertyDescriptor)
|
||||
val irGetParameter = IrGetVariableImpl(ktParameter.startOffset, ktParameter.endOffset,
|
||||
valueParameterDescriptor, IrOperator.INITIALIZE_PROPERTY_FROM_PARAMETER)
|
||||
irProperty.valueInitializer = IrExpressionBodyImpl(ktParameter.startOffset, ktParameter.endOffset, irGetParameter)
|
||||
irProperty.initializer = IrExpressionBodyImpl(ktParameter.startOffset, ktParameter.endOffset, irGetParameter)
|
||||
return irProperty
|
||||
}
|
||||
|
||||
|
||||
+4
-29
@@ -17,10 +17,9 @@
|
||||
package org.jetbrains.kotlin.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrPropertyDelegateDescriptorImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
@@ -116,32 +115,8 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
|
||||
|
||||
private fun generateDelegatedProperty(ktProperty: KtProperty, ktDelegate: KtPropertyDelegate, propertyDescriptor: PropertyDescriptor): IrProperty {
|
||||
val ktDelegateExpression = ktDelegate.expression!!
|
||||
val delegateType = getInferredTypeWithImplicitCasts(ktDelegateExpression)!!
|
||||
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)
|
||||
val irDelegateInitializer = generateInitializerBody(delegateDescriptor, ktDelegateExpression)
|
||||
val irDelegate = IrDelegateImpl(ktDelegate.startOffset, ktDelegate.endOffset, IrDeclarationOrigin.DELEGATE,
|
||||
delegateDescriptor, irDelegateInitializer)
|
||||
|
||||
val irProperty = IrDelegatedPropertyImpl(ktProperty.startOffset, ktProperty.endOffset, IrDeclarationOrigin.DEFINED,
|
||||
propertyDescriptor, irDelegate)
|
||||
|
||||
val getterDescriptor = propertyDescriptor.getter ?: throw AssertionError("Delegated property should have getter: $propertyDescriptor")
|
||||
val getterBody = createBodyGenerator(getterDescriptor).generateDelegatedPropertyGetter(ktDelegate, delegateDescriptor, getterDescriptor)
|
||||
irProperty.getter = IrPropertyGetterImpl(ktDelegate.startOffset, ktDelegate.endOffset, IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR,
|
||||
getterDescriptor, getterBody)
|
||||
|
||||
if (propertyDescriptor.isVar) {
|
||||
val setterDescriptor = propertyDescriptor.setter ?: throw AssertionError("Delegated var should have setter: $propertyDescriptor")
|
||||
val setterBody = createBodyGenerator(setterDescriptor).generateDelegatedPropertySetter(ktDelegate, delegateDescriptor, setterDescriptor)
|
||||
irProperty.setter = IrPropertySetterImpl(ktDelegate.startOffset, ktDelegate.endOffset, IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR,
|
||||
setterDescriptor, setterBody)
|
||||
}
|
||||
|
||||
return irProperty
|
||||
val irDelegateInitializer = generateInitializerBody(propertyDescriptor, ktDelegateExpression)
|
||||
return DelegatedPropertyGenerator(context).generateDelegatedProperty(ktProperty, ktDelegate, propertyDescriptor, irDelegateInitializer)
|
||||
}
|
||||
|
||||
private fun generateSimpleProperty(ktProperty: KtProperty, propertyDescriptor: PropertyDescriptor): IrSimplePropertyImpl {
|
||||
|
||||
+190
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.VariableAccessorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptorWithAccessors
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
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.expressions.*
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.psi.KtPropertyDelegate
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.psi2ir.builders.irBlockBody
|
||||
import org.jetbrains.kotlin.psi2ir.builders.irGet
|
||||
import org.jetbrains.kotlin.psi2ir.builders.irReturn
|
||||
import org.jetbrains.kotlin.psi2ir.intermediate.BackingFieldLValue
|
||||
import org.jetbrains.kotlin.psi2ir.intermediate.IntermediateValue
|
||||
import org.jetbrains.kotlin.psi2ir.intermediate.VariableLValue
|
||||
import org.jetbrains.kotlin.psi2ir.intermediate.setExplicitReceiverValue
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
|
||||
class DelegatedPropertyGenerator(override val context: GeneratorContext) : Generator {
|
||||
fun generateDelegatedProperty(
|
||||
ktProperty: KtProperty,
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
propertyDescriptor: PropertyDescriptor,
|
||||
irDelegateInitializer: IrExpressionBody
|
||||
): IrDelegatedProperty {
|
||||
val delegateDescriptor = createPropertyDelegateDescriptor(ktDelegate, propertyDescriptor)
|
||||
|
||||
val irDelegate = IrSimplePropertyImpl(
|
||||
ktDelegate.startOffset, ktDelegate.endOffset, IrDeclarationOrigin.DELEGATE,
|
||||
delegateDescriptor, irDelegateInitializer)
|
||||
|
||||
val irProperty = IrDelegatedPropertyImpl(
|
||||
ktProperty.startOffset, ktProperty.endOffset, IrDeclarationOrigin.DEFINED,
|
||||
propertyDescriptor, irDelegate)
|
||||
|
||||
val delegateReceiverValue = createBackingFieldValueForDelegate(delegateDescriptor, ktDelegate)
|
||||
val getterDescriptor = propertyDescriptor.getter!!
|
||||
irProperty.getter = IrPropertyGetterImpl(
|
||||
ktDelegate.startOffset, ktDelegate.endOffset, IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR,
|
||||
getterDescriptor,
|
||||
generateDelegatedPropertyGetterBody(
|
||||
ktDelegate, getterDescriptor, delegateReceiverValue,
|
||||
createCallableReference(ktDelegate, delegateDescriptor.kPropertyType, propertyDescriptor)))
|
||||
|
||||
if (propertyDescriptor.isVar) {
|
||||
val setterDescriptor = propertyDescriptor.setter!!
|
||||
irProperty.setter = IrPropertySetterImpl(
|
||||
ktDelegate.startOffset, ktDelegate.endOffset, IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR,
|
||||
setterDescriptor,
|
||||
generateDelegatedPropertySetterBody(
|
||||
ktDelegate, setterDescriptor, delegateReceiverValue,
|
||||
createCallableReference(ktDelegate, delegateDescriptor.kPropertyType, propertyDescriptor)))
|
||||
}
|
||||
|
||||
return irProperty
|
||||
}
|
||||
|
||||
private fun createBackingFieldValueForDelegate(delegateDescriptor: IrPropertyDelegateDescriptor, ktDelegate: KtPropertyDelegate) =
|
||||
BackingFieldLValue(ktDelegate.startOffset, ktDelegate.endOffset, delegateDescriptor, null)
|
||||
|
||||
private fun createCallableReference(ktElement: KtElement, type: KotlinType, referencedDescriptor: CallableDescriptor): IrCallableReference =
|
||||
IrCallableReferenceImpl(ktElement.startOffset, ktElement.endOffset, type, referencedDescriptor)
|
||||
|
||||
fun generateLocalDelegatedProperty(
|
||||
ktProperty: KtProperty,
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
variableDescriptor: VariableDescriptorWithAccessors,
|
||||
irDelegateInitializer: IrExpression
|
||||
) : IrLocalDelegatedProperty {
|
||||
val delegateDescriptor = createLocalPropertyDelegatedDescriptor(ktDelegate, variableDescriptor)
|
||||
|
||||
val irDelegate = IrVariableImpl(
|
||||
ktDelegate.startOffset, ktDelegate.endOffset, IrDeclarationOrigin.DELEGATE,
|
||||
delegateDescriptor, irDelegateInitializer)
|
||||
|
||||
val irLocalDelegatedProperty = IrLocalDelegatedPropertyImpl(
|
||||
ktProperty.startOffset, ktProperty.endOffset, IrDeclarationOrigin.DEFINED,
|
||||
variableDescriptor, irDelegate)
|
||||
|
||||
val getterDescriptor = variableDescriptor.getter!!
|
||||
val delegateReceiverValue = createVariableValueForDelegate(delegateDescriptor, ktDelegate)
|
||||
irLocalDelegatedProperty.getter = createLocalPropertyAccessor(
|
||||
getterDescriptor, ktDelegate,
|
||||
generateDelegatedPropertyGetterBody(
|
||||
ktDelegate, getterDescriptor, delegateReceiverValue,
|
||||
createCallableReference(ktDelegate, delegateDescriptor.kPropertyType, delegateDescriptor.correspondingLocalProperty)))
|
||||
|
||||
if (variableDescriptor.isVar) {
|
||||
val setterDescriptor = variableDescriptor.setter!!
|
||||
irLocalDelegatedProperty.setter = createLocalPropertyAccessor(
|
||||
setterDescriptor, ktDelegate,
|
||||
generateDelegatedPropertySetterBody(
|
||||
ktDelegate, setterDescriptor, delegateReceiverValue,
|
||||
createCallableReference(ktDelegate, delegateDescriptor.kPropertyType, delegateDescriptor.correspondingLocalProperty)))
|
||||
|
||||
}
|
||||
|
||||
return irLocalDelegatedProperty
|
||||
}
|
||||
|
||||
private fun createVariableValueForDelegate(delegateDescriptor: IrLocalDelegatedPropertyDelegateDescriptor, ktDelegate: KtPropertyDelegate) =
|
||||
VariableLValue(ktDelegate.startOffset, ktDelegate.endOffset, delegateDescriptor)
|
||||
|
||||
private fun createLocalPropertyAccessor(getterDescriptor: VariableAccessorDescriptor, ktDelegate: KtPropertyDelegate, body: IrBody) =
|
||||
IrLocalPropertyAccessorImpl(ktDelegate.startOffset, ktDelegate.endOffset, IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR,
|
||||
getterDescriptor, body)
|
||||
|
||||
private fun createLocalPropertyDelegatedDescriptor(
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
variableDescriptor: VariableDescriptorWithAccessors
|
||||
): 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 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
|
||||
}
|
||||
|
||||
fun generateDelegatedPropertyGetterBody(
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
getterDescriptor: VariableAccessorDescriptor,
|
||||
delegateReceiverValue: IntermediateValue,
|
||||
irPropertyReference: IrCallableReference
|
||||
): IrBody = with(BodyGenerator(getterDescriptor, context)) {
|
||||
irBlockBody(ktDelegate) {
|
||||
val statementGenerator = createStatementGenerator()
|
||||
val conventionMethodResolvedCall = getOrFail(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, getterDescriptor)
|
||||
val conventionMethodCall = statementGenerator.pregenerateCall(conventionMethodResolvedCall)
|
||||
conventionMethodCall.setExplicitReceiverValue(delegateReceiverValue)
|
||||
conventionMethodCall.irValueArgumentsByIndex[1] = irPropertyReference
|
||||
+irReturn(CallGenerator(statementGenerator).generateCall(ktDelegate.startOffset, ktDelegate.endOffset, conventionMethodCall))
|
||||
}
|
||||
}
|
||||
|
||||
fun generateDelegatedPropertySetterBody(
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
setterDescriptor: VariableAccessorDescriptor,
|
||||
delegateReceiverValue: IntermediateValue,
|
||||
irPropertyReference: IrCallableReference
|
||||
): IrBody = with(BodyGenerator(setterDescriptor, context)) {
|
||||
irBlockBody(ktDelegate) {
|
||||
val statementGenerator = createStatementGenerator()
|
||||
val conventionMethodResolvedCall = getOrFail(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, setterDescriptor)
|
||||
val conventionMethodCall = statementGenerator.pregenerateCall(conventionMethodResolvedCall)
|
||||
conventionMethodCall.setExplicitReceiverValue(delegateReceiverValue)
|
||||
conventionMethodCall.irValueArgumentsByIndex[1] = irPropertyReference
|
||||
conventionMethodCall.irValueArgumentsByIndex[2] = irGet(setterDescriptor.valueParameters[0])
|
||||
+irReturn(CallGenerator(statementGenerator).generateCall(ktDelegate.startOffset, ktDelegate.endOffset, conventionMethodCall))
|
||||
}
|
||||
}
|
||||
}
|
||||
+17
-4
@@ -43,11 +43,12 @@ import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
|
||||
import java.lang.AssertionError
|
||||
|
||||
class StatementGenerator(
|
||||
override val context: GeneratorContext,
|
||||
val scopeOwner: DeclarationDescriptor,
|
||||
val bodyGenerator: BodyGenerator,
|
||||
override val scope: Scope
|
||||
) : KtVisitor<IrStatement, Nothing?>(), GeneratorWithScope {
|
||||
override val context: GeneratorContext get() = bodyGenerator.context
|
||||
val scopeOwner: DeclarationDescriptor get() = bodyGenerator.scopeOwner
|
||||
|
||||
fun generateStatement(ktElement: KtElement): IrStatement =
|
||||
ktElement.genStmt()
|
||||
|
||||
@@ -64,15 +65,27 @@ class StatementGenerator(
|
||||
createDummyExpression(expression, expression.javaClass.simpleName)
|
||||
|
||||
override fun visitProperty(property: KtProperty, data: Nothing?): IrStatement {
|
||||
if (property.delegateExpression != null) TODO("Local delegated property")
|
||||
|
||||
val variableDescriptor = getOrFail(BindingContext.VARIABLE, property)
|
||||
|
||||
property.delegate?.let { ktDelegate ->
|
||||
return generateLocalDelegatedProperty(property, ktDelegate, variableDescriptor as VariableDescriptorWithAccessors)
|
||||
}
|
||||
|
||||
val irLocalVariable = IrVariableImpl(property.startOffset, property.endOffset, IrDeclarationOrigin.DEFINED, variableDescriptor)
|
||||
irLocalVariable.initializer = property.initializer?.genExpr()
|
||||
return irLocalVariable
|
||||
}
|
||||
|
||||
private fun generateLocalDelegatedProperty(
|
||||
ktProperty: KtProperty,
|
||||
ktDelegate: KtPropertyDelegate,
|
||||
variableDescriptor: VariableDescriptorWithAccessors
|
||||
): IrStatement =
|
||||
DelegatedPropertyGenerator(context).generateLocalDelegatedProperty(
|
||||
ktProperty, ktDelegate, variableDescriptor,
|
||||
ktDelegate.expression!!.genExpr()
|
||||
)
|
||||
|
||||
override fun visitDestructuringDeclaration(multiDeclaration: KtDestructuringDeclaration, data: Nothing?): IrStatement {
|
||||
// TODO use some special form that introduces multiple declarations into surrounding scope?
|
||||
|
||||
|
||||
@@ -34,12 +34,10 @@ interface IrClass : IrDeclaration {
|
||||
fun IrClass.getInstanceInitializerMembers() =
|
||||
members.filter {
|
||||
when (it) {
|
||||
is IrDelegate ->
|
||||
true
|
||||
is IrAnonymousInitializer ->
|
||||
true
|
||||
is IrSimpleProperty ->
|
||||
it.valueInitializer != null
|
||||
it.initializer != null
|
||||
is IrDelegatedProperty ->
|
||||
true
|
||||
else -> false
|
||||
|
||||
@@ -29,16 +29,16 @@ interface IrDeclaration : IrStatement {
|
||||
enum class IrDeclarationKind {
|
||||
MODULE,
|
||||
FILE,
|
||||
CLASS,
|
||||
ENUM_ENTRY,
|
||||
FUNCTION,
|
||||
PROPERTY_GETTER,
|
||||
PROPERTY_SETTER,
|
||||
CONSTRUCTOR,
|
||||
PROPERTY,
|
||||
PROPERTY_ACCESSOR,
|
||||
VARIABLE,
|
||||
DELEGATE,
|
||||
CLASS,
|
||||
LOCAL_PROPERTY,
|
||||
LOCAL_PROPERTY_ACCESSOR,
|
||||
TYPEALIAS,
|
||||
ENUM_ENTRY,
|
||||
ANONYMOUS_INITIALIZER,
|
||||
DUMMY;
|
||||
}
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.declarations
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.ir.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
|
||||
interface IrDelegate : IrDeclaration {
|
||||
override val descriptor: VariableDescriptor
|
||||
|
||||
var initializer: IrExpressionBody
|
||||
|
||||
override val declarationKind: IrDeclarationKind
|
||||
get() = IrDeclarationKind.DELEGATE
|
||||
}
|
||||
|
||||
class IrDelegateImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
override val descriptor: VariableDescriptor
|
||||
) : IrDeclarationBase(startOffset, endOffset, origin), IrDelegate {
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
descriptor: VariableDescriptor,
|
||||
initializer: IrExpressionBody
|
||||
) : this(startOffset, endOffset, origin, descriptor) {
|
||||
this.initializer = initializer
|
||||
}
|
||||
|
||||
private var initializerImpl: IrExpressionBody? = null
|
||||
override var initializer: IrExpressionBody
|
||||
get() = initializerImpl!!
|
||||
set(value) {
|
||||
value.assertDetached()
|
||||
initializerImpl?.detach()
|
||||
initializerImpl = value
|
||||
value.setTreeLocation(this, INITIALIZER_SLOT)
|
||||
}
|
||||
|
||||
override fun getChild(slot: Int): IrElement? =
|
||||
when (slot) {
|
||||
INITIALIZER_SLOT -> initializer
|
||||
else -> null
|
||||
}
|
||||
|
||||
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||
when (slot) {
|
||||
INITIALIZER_SLOT -> initializer = newChild.assertCast()
|
||||
else -> throwNoSuchSlot(slot)
|
||||
}
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||
return visitor.visitDelegate(this, data)
|
||||
}
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
initializer.accept(visitor, data)
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ import java.util.*
|
||||
|
||||
interface IrGeneralFunction : IrDeclaration {
|
||||
override val descriptor: FunctionDescriptor
|
||||
val body: IrBody?
|
||||
var body: IrBody?
|
||||
|
||||
override val declarationKind: IrDeclarationKind
|
||||
get() = IrDeclarationKind.FUNCTION
|
||||
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.declarations
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.VariableAccessorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptorWithAccessors
|
||||
import org.jetbrains.kotlin.ir.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
|
||||
interface IrLocalDelegatedProperty : IrDeclaration {
|
||||
override val descriptor: VariableDescriptorWithAccessors
|
||||
var delegate: IrVariable
|
||||
var getter: IrLocalPropertyAccessor
|
||||
var setter: IrLocalPropertyAccessor?
|
||||
|
||||
override val declarationKind: IrDeclarationKind
|
||||
get() = IrDeclarationKind.LOCAL_PROPERTY
|
||||
}
|
||||
|
||||
interface IrLocalPropertyAccessor : IrGeneralFunction {
|
||||
override val descriptor: VariableAccessorDescriptor
|
||||
|
||||
override val declarationKind: IrDeclarationKind
|
||||
get() = IrDeclarationKind.LOCAL_PROPERTY_ACCESSOR
|
||||
}
|
||||
|
||||
class IrLocalDelegatedPropertyImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
override val descriptor: VariableDescriptorWithAccessors
|
||||
) : IrDeclarationBase(startOffset, endOffset, origin), IrLocalDelegatedProperty {
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
descriptor: VariableDescriptorWithAccessors,
|
||||
delegate: IrVariable
|
||||
) : this(startOffset, endOffset, origin, descriptor) {
|
||||
this.delegate = delegate
|
||||
}
|
||||
|
||||
private var delegateImpl: IrVariable? = null
|
||||
override var delegate: IrVariable
|
||||
get() = delegateImpl!!
|
||||
set(value) {
|
||||
value.assertDetached()
|
||||
delegateImpl?.detach()
|
||||
delegateImpl = value
|
||||
value.setTreeLocation(this, DELEGATE_SLOT)
|
||||
}
|
||||
|
||||
private var getterImpl: IrLocalPropertyAccessor? = null
|
||||
override var getter: IrLocalPropertyAccessor
|
||||
get() = getterImpl!!
|
||||
set(value) {
|
||||
value.assertDetached()
|
||||
getterImpl?.detach()
|
||||
getterImpl = value
|
||||
value.setTreeLocation(this, PROPERTY_GETTER_SLOT)
|
||||
}
|
||||
|
||||
override var setter: IrLocalPropertyAccessor? = null
|
||||
set(value) {
|
||||
value?.assertDetached()
|
||||
field?.detach()
|
||||
field = value
|
||||
value?.setTreeLocation(this, PROPERTY_SETTER_SLOT)
|
||||
}
|
||||
|
||||
override fun getChild(slot: Int): IrElement? =
|
||||
when (slot) {
|
||||
DELEGATE_SLOT -> delegate
|
||||
PROPERTY_GETTER_SLOT -> getter
|
||||
PROPERTY_SETTER_SLOT -> setter
|
||||
else -> null
|
||||
}
|
||||
|
||||
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||
when (slot) {
|
||||
DELEGATE_SLOT -> delegate = newChild.assertCast()
|
||||
PROPERTY_GETTER_SLOT -> getter = newChild.assertCast()
|
||||
PROPERTY_SETTER_SLOT -> setter = newChild.assertCast()
|
||||
}
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitLocalDelegatedProperty(this, data)
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
delegate.accept(visitor, data)
|
||||
getter.accept(visitor, data)
|
||||
setter?.accept(visitor, data)
|
||||
}
|
||||
}
|
||||
|
||||
class IrLocalPropertyAccessorImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
override val descriptor: VariableAccessorDescriptor
|
||||
) : IrGeneralFunctionBase(startOffset, endOffset, origin), IrLocalPropertyAccessor {
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
descriptor: VariableAccessorDescriptor,
|
||||
body: IrBody
|
||||
) : this(startOffset, endOffset, origin, descriptor) {
|
||||
this.body = body
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||
return visitor.visitLocalPropertyAccessor(this, data)
|
||||
}
|
||||
}
|
||||
@@ -31,11 +31,11 @@ interface IrProperty : IrDeclaration {
|
||||
}
|
||||
|
||||
interface IrSimpleProperty : IrProperty {
|
||||
var valueInitializer: IrBody?
|
||||
var initializer: IrBody?
|
||||
}
|
||||
|
||||
interface IrDelegatedProperty : IrProperty {
|
||||
var delegate: IrDelegate
|
||||
var delegate: IrSimpleProperty
|
||||
}
|
||||
|
||||
abstract class IrPropertyBase(
|
||||
@@ -83,7 +83,7 @@ class IrSimplePropertyImpl(
|
||||
descriptor: PropertyDescriptor,
|
||||
valueInitializer: IrBody? = null
|
||||
) : IrPropertyBase(startOffset, endOffset, origin, descriptor), IrSimpleProperty {
|
||||
override var valueInitializer: IrBody? = valueInitializer
|
||||
override var initializer: IrBody? = valueInitializer
|
||||
set(value) {
|
||||
value?.assertDetached()
|
||||
field?.detach()
|
||||
@@ -93,13 +93,13 @@ class IrSimplePropertyImpl(
|
||||
|
||||
override fun getChild(slot: Int): IrElement? =
|
||||
when (slot) {
|
||||
INITIALIZER_SLOT -> valueInitializer
|
||||
INITIALIZER_SLOT -> initializer
|
||||
else -> super.getChild(slot)
|
||||
}
|
||||
|
||||
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||
when (slot) {
|
||||
INITIALIZER_SLOT -> valueInitializer = newChild.assertCast()
|
||||
INITIALIZER_SLOT -> initializer = newChild.assertCast()
|
||||
else -> super.replaceChild(slot, newChild)
|
||||
}
|
||||
}
|
||||
@@ -108,7 +108,7 @@ class IrSimplePropertyImpl(
|
||||
visitor.visitSimpleProperty(this, data)
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
valueInitializer?.accept(visitor, data)
|
||||
initializer?.accept(visitor, data)
|
||||
getter?.accept(visitor, data)
|
||||
setter?.accept(visitor, data)
|
||||
}
|
||||
@@ -125,13 +125,13 @@ class IrDelegatedPropertyImpl(
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
descriptor: PropertyDescriptor,
|
||||
delegate: IrDelegate
|
||||
delegate: IrSimpleProperty
|
||||
) : this(startOffset, endOffset, origin, descriptor) {
|
||||
this.delegate = delegate
|
||||
}
|
||||
|
||||
private var delegateImpl: IrDelegate? = null
|
||||
override var delegate: IrDelegate
|
||||
private var delegateImpl: IrSimpleProperty? = null
|
||||
override var delegate: IrSimpleProperty
|
||||
get() = delegateImpl!!
|
||||
set(value) {
|
||||
value.assertDetached()
|
||||
|
||||
@@ -24,20 +24,19 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
|
||||
interface IrPropertyAccessor : IrGeneralFunction {
|
||||
override val descriptor: PropertyAccessorDescriptor
|
||||
|
||||
override val declarationKind: IrDeclarationKind
|
||||
get() = IrDeclarationKind.PROPERTY_ACCESSOR
|
||||
}
|
||||
|
||||
interface IrPropertyGetter : IrPropertyAccessor {
|
||||
override val descriptor: PropertyGetterDescriptor
|
||||
|
||||
override val declarationKind: IrDeclarationKind
|
||||
get() = IrDeclarationKind.PROPERTY_GETTER
|
||||
|
||||
}
|
||||
|
||||
interface IrPropertySetter : IrPropertyAccessor {
|
||||
override val descriptor: PropertySetterDescriptor
|
||||
|
||||
override val declarationKind: IrDeclarationKind
|
||||
get() = IrDeclarationKind.PROPERTY_SETTER
|
||||
}
|
||||
|
||||
abstract class IrPropertyAccessorBase(
|
||||
|
||||
+65
-8
@@ -18,19 +18,28 @@ package org.jetbrains.kotlin.ir.descriptors
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.VariableDescriptorImpl
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import java.lang.UnsupportedOperationException
|
||||
|
||||
interface IrDelegateDescriptor : VariableDescriptor
|
||||
interface IrDelegateDescriptor : PropertyDescriptor
|
||||
|
||||
interface IrPropertyDelegateDescriptor : IrDelegateDescriptor {
|
||||
val correspondingProperty: PropertyDescriptor
|
||||
val kPropertyType: KotlinType
|
||||
}
|
||||
|
||||
interface IrLocalDelegateDescriptor : VariableDescriptor
|
||||
|
||||
interface IrLocalDelegatedPropertyDelegateDescriptor : IrLocalDelegateDescriptor {
|
||||
val correspondingLocalProperty: VariableDescriptorWithAccessors
|
||||
val kPropertyType: KotlinType
|
||||
}
|
||||
|
||||
interface IrImplementingDelegateDescriptor : IrDelegateDescriptor {
|
||||
val correspondingSuperType: KotlinType
|
||||
}
|
||||
@@ -39,12 +48,32 @@ abstract class IrDelegateDescriptorBase(
|
||||
containingDeclaration: DeclarationDescriptor,
|
||||
name: Name,
|
||||
delegateType: KotlinType
|
||||
) : VariableDescriptorImpl(containingDeclaration, Annotations.EMPTY, name, delegateType, SourceElement.NO_SOURCE) {
|
||||
) : PropertyDescriptorImpl(
|
||||
containingDeclaration,
|
||||
null, // original
|
||||
Annotations.EMPTY,
|
||||
Modality.FINAL,
|
||||
Visibilities.PRIVATE,
|
||||
false, // isVar
|
||||
name,
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
SourceElement.NO_SOURCE,
|
||||
false, // lateInit
|
||||
false // isConst
|
||||
) {
|
||||
init {
|
||||
setOutType(delegateType)
|
||||
}
|
||||
|
||||
override final fun setOutType(outType: KotlinType?) {
|
||||
super.setOutType(outType)
|
||||
}
|
||||
|
||||
override fun getCompileTimeInitializer(): ConstantValue<*>? = null
|
||||
|
||||
override fun getVisibility(): Visibility = Visibilities.PRIVATE
|
||||
|
||||
override fun substitute(substitutor: TypeSubstitutor): VariableDescriptor {
|
||||
override fun substitute(substitutor: TypeSubstitutor): PropertyDescriptor {
|
||||
throw UnsupportedOperationException("Property delegate descriptor shouldn't be substituted: $this")
|
||||
}
|
||||
|
||||
@@ -58,15 +87,21 @@ class IrPropertyDelegateDescriptorImpl(
|
||||
override val correspondingProperty: PropertyDescriptor,
|
||||
delegateType: KotlinType,
|
||||
override val kPropertyType: KotlinType
|
||||
) : IrPropertyDelegateDescriptor,
|
||||
IrDelegateDescriptorBase(correspondingProperty.containingDeclaration, getDelegateName(correspondingProperty.name), delegateType)
|
||||
) : IrDelegateDescriptorBase(
|
||||
correspondingProperty.containingDeclaration,
|
||||
getDelegateName(correspondingProperty.name),
|
||||
delegateType
|
||||
), IrPropertyDelegateDescriptor
|
||||
|
||||
class IrImplementingDelegateDescriptorImpl(
|
||||
containingDeclaration: ClassDescriptor,
|
||||
delegateType: KotlinType,
|
||||
override val correspondingSuperType: KotlinType
|
||||
) : IrImplementingDelegateDescriptor,
|
||||
IrDelegateDescriptorBase(containingDeclaration, getDelegateName(containingDeclaration, correspondingSuperType), delegateType)
|
||||
) : IrDelegateDescriptorBase(
|
||||
containingDeclaration,
|
||||
getDelegateName(containingDeclaration, correspondingSuperType),
|
||||
delegateType
|
||||
), IrImplementingDelegateDescriptor
|
||||
|
||||
internal fun getDelegateName(name: Name): Name =
|
||||
Name.identifier(name.asString() + "\$delegate")
|
||||
@@ -74,4 +109,26 @@ internal fun getDelegateName(name: Name): Name =
|
||||
internal fun getDelegateName(classDescriptor: ClassDescriptor, superType: KotlinType): Name =
|
||||
Name.identifier(classDescriptor.name.asString() + "\$" +
|
||||
(superType.constructor.declarationDescriptor?.name ?: "\$") +
|
||||
"\$delegate")
|
||||
"\$delegate")
|
||||
|
||||
class IrLocalDelegatedPropertyDelegateDescriptorImpl(
|
||||
override val correspondingLocalProperty: VariableDescriptorWithAccessors,
|
||||
delegateType: KotlinType,
|
||||
override val kPropertyType: KotlinType
|
||||
) : IrLocalDelegatedPropertyDelegateDescriptor,
|
||||
VariableDescriptorImpl(
|
||||
correspondingLocalProperty.containingDeclaration,
|
||||
Annotations.EMPTY,
|
||||
getDelegateName(correspondingLocalProperty.name),
|
||||
delegateType,
|
||||
org.jetbrains.kotlin.descriptors.SourceElement.NO_SOURCE
|
||||
) {
|
||||
|
||||
override fun getCompileTimeInitializer(): ConstantValue<*>? = null
|
||||
override fun isVar(): Boolean = false
|
||||
override fun substitute(substitutor: TypeSubstitutor): VariableDescriptor? = throw UnsupportedOperationException()
|
||||
override fun getVisibility(): Visibility = Visibilities.LOCAL
|
||||
|
||||
override fun <R : Any?, D : Any?> accept(visitor: DeclarationDescriptorVisitor<R, D>, data: D): R =
|
||||
visitor.visitVariableDescriptor(this, data)
|
||||
}
|
||||
@@ -51,6 +51,14 @@ class DumpIrTreeVisitor(out: Appendable): IrElementVisitor<Unit, String> {
|
||||
visitFunctionWithParameters(declaration, data)
|
||||
}
|
||||
|
||||
override fun visitDelegatedProperty(declaration: IrDelegatedProperty, data: String) {
|
||||
declaration.dumpLabeledElementWith(data) {
|
||||
declaration.delegate.accept(this, "delegate")
|
||||
declaration.getter?.accept(this, "")
|
||||
declaration.setter?.accept(this, "")
|
||||
}
|
||||
}
|
||||
|
||||
private fun visitFunctionWithParameters(declaration: IrFunction, data: String) {
|
||||
declaration.dumpLabeledElementWith(data) {
|
||||
declaration.descriptor.valueParameters.forEach { valueParameter ->
|
||||
|
||||
@@ -63,9 +63,6 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
|
||||
override fun visitVariable(declaration: IrVariable, data: Nothing?): String =
|
||||
"VAR ${declaration.descriptor.render()}"
|
||||
|
||||
override fun visitDelegate(declaration: IrDelegate, data: Nothing?): String =
|
||||
"DELEGATE ${declaration.descriptor.render()}"
|
||||
|
||||
override fun visitEnumEntry(declaration: IrEnumEntry, data: Nothing?): String =
|
||||
"ENUM_ENTRY ${declaration.descriptor.render()}"
|
||||
|
||||
|
||||
@@ -36,8 +36,9 @@ interface IrElementVisitor<out R, in D> {
|
||||
fun visitProperty(declaration: IrProperty, data: D) = visitDeclaration(declaration, data)
|
||||
fun visitSimpleProperty(declaration: IrSimpleProperty, data: D) = visitProperty(declaration, data)
|
||||
fun visitDelegatedProperty(declaration: IrDelegatedProperty, data: D) = visitProperty(declaration, data)
|
||||
fun visitLocalDelegatedProperty(declaration: IrLocalDelegatedProperty, data: D) = visitDeclaration(declaration, data)
|
||||
fun visitLocalPropertyAccessor(declaration: IrLocalPropertyAccessor, data: D) = visitGeneralFunction(declaration, data)
|
||||
fun visitVariable(declaration: IrVariable, data: D) = visitDeclaration(declaration, data)
|
||||
fun visitDelegate(declaration: IrDelegate, data: D) = visitDeclaration(declaration, data)
|
||||
fun visitEnumEntry(declaration: IrEnumEntry, data: D) = visitDeclaration(declaration, data)
|
||||
fun visitAnonymousInitializer(declaration: IrAnonymousInitializer, data: D) = visitDeclaration(declaration, data)
|
||||
|
||||
@@ -92,6 +93,4 @@ interface IrElementVisitor<out R, in D> {
|
||||
// NB Use it only for testing purposes; will be removed as soon as all Kotlin expression types are covered
|
||||
fun visitDummyDeclaration(declaration: IrDummyDeclaration, data: D) = visitDeclaration(declaration, data)
|
||||
fun visitDummyExpression(expression: IrDummyExpression, data: D) = visitExpression(expression, data)
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ FILE /delegatedImplementation.kt
|
||||
CONSTRUCTOR public constructor Test1()
|
||||
BLOCK_BODY
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor=Test1
|
||||
DELEGATE val `Test1$IBase$delegate`: BaseImpl
|
||||
PROPERTY val `Test1$IBase$delegate`: BaseImpl
|
||||
EXPRESSION_BODY
|
||||
GET_OBJECT BaseImpl type=BaseImpl
|
||||
FUN public open override /*1*/ /*delegation*/ fun foo(/*0*/ x: kotlin.Int, /*1*/ s: kotlin.String): kotlin.Unit
|
||||
@@ -74,7 +74,7 @@ FILE /delegatedImplementation.kt
|
||||
CONSTRUCTOR public constructor Test2()
|
||||
BLOCK_BODY
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor=Test2
|
||||
DELEGATE val `Test2$IBase$delegate`: BaseImpl
|
||||
PROPERTY val `Test2$IBase$delegate`: BaseImpl
|
||||
EXPRESSION_BODY
|
||||
GET_OBJECT BaseImpl type=BaseImpl
|
||||
FUN public open override /*1*/ /*delegation*/ fun foo(/*0*/ x: kotlin.Int, /*1*/ s: kotlin.String): kotlin.Unit
|
||||
@@ -93,7 +93,7 @@ FILE /delegatedImplementation.kt
|
||||
CALL .qux type=kotlin.Unit operator=null
|
||||
$this: GET_VAR Test2$IBase$delegate type=BaseImpl operator=null
|
||||
$receiver: $RECEIVER of: qux type=kotlin.String
|
||||
DELEGATE val `Test2$IOther$delegate`: IOther
|
||||
PROPERTY val `Test2$IOther$delegate`: IOther
|
||||
EXPRESSION_BODY
|
||||
CALL .otherImpl type=IOther operator=null
|
||||
x0: CONST String type=kotlin.String value=''
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ FILE /delegatedImplementationWithExplicitOverride.kt
|
||||
CONSTRUCTOR public constructor C()
|
||||
BLOCK_BODY
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor=C
|
||||
DELEGATE val `C$IFooBar$delegate`: FooBarImpl
|
||||
PROPERTY val `C$IFooBar$delegate`: FooBarImpl
|
||||
EXPRESSION_BODY
|
||||
GET_OBJECT FooBarImpl type=FooBarImpl
|
||||
FUN public open override /*1*/ /*delegation*/ fun foo(): kotlin.Unit
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
FILE /delegatedProperties.kt
|
||||
PROPERTY public val test1: kotlin.Int
|
||||
DELEGATE val `test1$delegate`: kotlin.Lazy<kotlin.Int>
|
||||
delegate: PROPERTY val `test1$delegate`: kotlin.Lazy<kotlin.Int>
|
||||
EXPRESSION_BODY
|
||||
CALL .lazy type=kotlin.Lazy<kotlin.Int> operator=null
|
||||
initializer: BLOCK type=() -> kotlin.Int operator=LAMBDA
|
||||
@@ -13,7 +13,7 @@ FILE /delegatedProperties.kt
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from=<get-test1>
|
||||
CALL .getValue type=kotlin.Int operator=null
|
||||
$receiver: GET_VAR test1$delegate type=kotlin.Lazy<kotlin.Int> operator=null
|
||||
$receiver: GET_BACKING_FIELD test1$delegate type=kotlin.Lazy<kotlin.Int> operator=null
|
||||
thisRef: CONST Null type=kotlin.Nothing? value='null'
|
||||
property: CALLABLE_REFERENCE public val test1: kotlin.Int type=kotlin.reflect.KProperty0<kotlin.Int>
|
||||
CLASS CLASS C
|
||||
@@ -26,7 +26,7 @@ FILE /delegatedProperties.kt
|
||||
EXPRESSION_BODY
|
||||
GET_VAR map type=kotlin.collections.MutableMap<kotlin.String, kotlin.Any> operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
PROPERTY public final val test2: kotlin.Int
|
||||
DELEGATE val `test2$delegate`: kotlin.Lazy<kotlin.Int>
|
||||
delegate: PROPERTY val `test2$delegate`: kotlin.Lazy<kotlin.Int>
|
||||
EXPRESSION_BODY
|
||||
CALL .lazy type=kotlin.Lazy<kotlin.Int> operator=null
|
||||
initializer: BLOCK type=() -> kotlin.Int operator=LAMBDA
|
||||
@@ -39,11 +39,11 @@ FILE /delegatedProperties.kt
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from=<get-test2>
|
||||
CALL .getValue type=kotlin.Int operator=null
|
||||
$receiver: GET_VAR test2$delegate type=kotlin.Lazy<kotlin.Int> operator=null
|
||||
$receiver: GET_BACKING_FIELD test2$delegate type=kotlin.Lazy<kotlin.Int> operator=null
|
||||
thisRef: THIS public final class C type=C
|
||||
property: CALLABLE_REFERENCE public final val test2: kotlin.Int type=kotlin.reflect.KProperty1<C, kotlin.Int>
|
||||
PROPERTY public final var test3: kotlin.Any
|
||||
DELEGATE val `test3$delegate`: kotlin.collections.MutableMap<kotlin.String, kotlin.Any>
|
||||
delegate: PROPERTY val `test3$delegate`: kotlin.collections.MutableMap<kotlin.String, kotlin.Any>
|
||||
EXPRESSION_BODY
|
||||
CALL .<get-map> type=kotlin.collections.MutableMap<kotlin.String, kotlin.Any> operator=GET_PROPERTY
|
||||
$this: THIS public final class C type=C
|
||||
@@ -51,33 +51,33 @@ FILE /delegatedProperties.kt
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from=<get-test3>
|
||||
CALL .getValue type=kotlin.Any operator=null
|
||||
$receiver: GET_VAR test3$delegate type=kotlin.collections.MutableMap<kotlin.String, kotlin.Any> operator=null
|
||||
$receiver: GET_BACKING_FIELD test3$delegate type=kotlin.collections.MutableMap<kotlin.String, kotlin.Any> operator=null
|
||||
thisRef: THIS public final class C type=C
|
||||
property: CALLABLE_REFERENCE public final var test3: kotlin.Any type=kotlin.reflect.KMutableProperty1<C, kotlin.Any>
|
||||
PROPERTY_SETTER public final fun <set-test3>(/*0*/ <set-?>: kotlin.Any): kotlin.Unit
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from=<set-test3>
|
||||
CALL .setValue type=kotlin.Unit operator=null
|
||||
$receiver: GET_VAR test3$delegate type=kotlin.collections.MutableMap<kotlin.String, kotlin.Any> operator=null
|
||||
$receiver: GET_BACKING_FIELD test3$delegate type=kotlin.collections.MutableMap<kotlin.String, kotlin.Any> operator=null
|
||||
thisRef: THIS public final class C type=C
|
||||
property: CALLABLE_REFERENCE public final var test3: kotlin.Any type=kotlin.reflect.KMutableProperty1<C, kotlin.Any>
|
||||
value: GET_VAR <set-?> type=kotlin.Any operator=null
|
||||
PROPERTY public var test4: kotlin.Any
|
||||
DELEGATE val `test4$delegate`: java.util.HashMap<kotlin.String, kotlin.Any>
|
||||
delegate: PROPERTY val `test4$delegate`: java.util.HashMap<kotlin.String, kotlin.Any>
|
||||
EXPRESSION_BODY
|
||||
CALL .hashMapOf type=java.util.HashMap<kotlin.String, kotlin.Any> operator=null
|
||||
PROPERTY_GETTER public fun <get-test4>(): kotlin.Any
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from=<get-test4>
|
||||
CALL .getValue type=kotlin.Any operator=null
|
||||
$receiver: GET_VAR test4$delegate type=java.util.HashMap<kotlin.String, kotlin.Any> operator=null
|
||||
$receiver: GET_BACKING_FIELD test4$delegate type=java.util.HashMap<kotlin.String, kotlin.Any> operator=null
|
||||
thisRef: CONST Null type=kotlin.Nothing? value='null'
|
||||
property: CALLABLE_REFERENCE public var test4: kotlin.Any type=kotlin.reflect.KMutableProperty0<kotlin.Any>
|
||||
PROPERTY_SETTER public fun <set-test4>(/*0*/ <set-?>: kotlin.Any): kotlin.Unit
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from=<set-test4>
|
||||
CALL .setValue type=kotlin.Unit operator=null
|
||||
$receiver: GET_VAR test4$delegate type=java.util.HashMap<kotlin.String, kotlin.Any> operator=null
|
||||
$receiver: GET_BACKING_FIELD test4$delegate type=java.util.HashMap<kotlin.String, kotlin.Any> operator=null
|
||||
thisRef: CONST Null type=kotlin.Nothing? value='null'
|
||||
property: CALLABLE_REFERENCE public var test4: kotlin.Any type=kotlin.reflect.KMutableProperty0<kotlin.Any>
|
||||
value: GET_VAR <set-?> type=kotlin.Any operator=null
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
fun test1() {
|
||||
val x by lazy { 42 }
|
||||
println(x)
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
FILE /localDelegatedProperties.kt
|
||||
FUN public fun test1(): kotlin.Unit
|
||||
BLOCK_BODY
|
||||
? IrLocalDelegatedPropertyImpl x
|
||||
VAR val `x$delegate`: kotlin.Lazy<kotlin.Int>
|
||||
CALL .lazy type=kotlin.Lazy<kotlin.Int> operator=null
|
||||
initializer: BLOCK type=() -> kotlin.Int operator=LAMBDA
|
||||
FUN local final fun <anonymous>(): kotlin.Int
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from=<anonymous>
|
||||
CONST Int type=kotlin.Int value='42'
|
||||
CALLABLE_REFERENCE local final fun <anonymous>(): kotlin.Int type=() -> kotlin.Int
|
||||
? IrLocalPropertyAccessorImpl <get-x>
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from=<get-x>
|
||||
CALL .getValue type=kotlin.Int operator=null
|
||||
$receiver: GET_VAR x$delegate type=kotlin.Lazy<kotlin.Int> operator=null
|
||||
thisRef: CONST Null type=kotlin.Nothing? value='null'
|
||||
property: CALLABLE_REFERENCE val x: kotlin.Int type=kotlin.reflect.KProperty0<kotlin.Int>
|
||||
CALL .println type=kotlin.Unit operator=null
|
||||
message: GET_VAR x type=kotlin.Int operator=null
|
||||
@@ -184,6 +184,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("localDelegatedProperties.kt")
|
||||
public void testLocalDelegatedProperties() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/declarations/localDelegatedProperties.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("typeAlias.kt")
|
||||
public void testTypeAlias() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/declarations/typeAlias.kt");
|
||||
|
||||
Reference in New Issue
Block a user