Local delegated properties.

This commit is contained in:
Dmitry Petrov
2016-09-02 10:18:06 +03:00
committed by Dmitry Petrov
parent e42116bb6a
commit 42988383e0
22 changed files with 490 additions and 201 deletions
@@ -129,8 +129,7 @@ class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context:
irBlockBody.addStatement(irDelegatingConstructorCall) irBlockBody.addStatement(irDelegatingConstructorCall)
} }
private fun createStatementGenerator() = fun createStatementGenerator() = StatementGenerator(this, scope)
StatementGenerator(context, scopeOwner, this, scope)
fun putLoop(expression: KtLoopExpression, irLoop: IrLoop) { fun putLoop(expression: KtLoopExpression, irLoop: IrLoop) {
loopTable[expression] = 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) = private fun createPropertyInitializationExpression(ktElement: KtElement, propertyDescriptor: PropertyDescriptor, value: IrExpression) =
IrSetBackingFieldImpl(ktElement.startOffset, ktElement.endOffset, propertyDescriptor, value) 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 ?: val superClass = superTypeConstructorDescriptor as? ClassDescriptor ?:
throw AssertionError("Unexpected supertype constructor for delegation: $superTypeConstructorDescriptor") throw AssertionError("Unexpected supertype constructor for delegation: $superTypeConstructorDescriptor")
val delegateDescriptor = IrImplementingDelegateDescriptorImpl(irClass.descriptor, delegateType, superType) val delegateDescriptor = IrImplementingDelegateDescriptorImpl(irClass.descriptor, delegateType, superType)
val irDelegate = IrDelegateImpl(ktDelegateExpression.startOffset, ktDelegateExpression.endOffset, IrDeclarationOrigin.DELEGATE, val irDelegate = IrSimplePropertyImpl(ktDelegateExpression.startOffset, ktDelegateExpression.endOffset, IrDeclarationOrigin.DELEGATE,
delegateDescriptor) delegateDescriptor)
val bodyGenerator = BodyGenerator(irClass.descriptor, context) val bodyGenerator = BodyGenerator(irClass.descriptor, context)
irDelegate.initializer = bodyGenerator.generatePropertyInitializerBody(ktDelegateExpression) irDelegate.initializer = bodyGenerator.generatePropertyInitializerBody(ktDelegateExpression)
irClass.addMember(irDelegate) 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) { when (delegatedMember) {
is FunctionDescriptor -> is FunctionDescriptor ->
generateDelegatedFunction(irClass, irDelegate, delegatedMember, overriddenMember as 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 irProperty = IrSimplePropertyImpl(irDelegate.startOffset, irDelegate.endOffset, IrDeclarationOrigin.DELEGATED_MEMBER, delegated)
val irGetter = IrPropertyGetterImpl(irDelegate.startOffset, irDelegate.endOffset, IrDeclarationOrigin.DELEGATED_MEMBER, delegated.getter!!) 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) 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) val irFunction = IrFunctionImpl(irDelegate.startOffset, irDelegate.endOffset, IrDeclarationOrigin.DELEGATED_MEMBER, delegated)
irFunction.body = generateDelegateFunctionBody(irDelegate, delegated, overridden) irFunction.body = generateDelegateFunctionBody(irDelegate, delegated, overridden)
irClass.addMember(irFunction) 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 irBlockBody = IrBlockBodyImpl(irDelegate.startOffset, irDelegate.endOffset)
val returnType = overridden.returnType!! val returnType = overridden.returnType!!
val irCall = IrCallImpl(irDelegate.startOffset, irDelegate.endOffset, returnType, overridden) 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 irProperty = IrSimplePropertyImpl(ktParameter.startOffset, ktParameter.endOffset, IrDeclarationOrigin.DEFINED, propertyDescriptor)
val irGetParameter = IrGetVariableImpl(ktParameter.startOffset, ktParameter.endOffset, val irGetParameter = IrGetVariableImpl(ktParameter.startOffset, ktParameter.endOffset,
valueParameterDescriptor, IrOperator.INITIALIZE_PROPERTY_FROM_PARAMETER) valueParameterDescriptor, IrOperator.INITIALIZE_PROPERTY_FROM_PARAMETER)
irProperty.valueInitializer = IrExpressionBodyImpl(ktParameter.startOffset, ktParameter.endOffset, irGetParameter) irProperty.initializer = IrExpressionBodyImpl(ktParameter.startOffset, ktParameter.endOffset, irGetParameter)
return irProperty return irProperty
} }
@@ -17,10 +17,9 @@
package org.jetbrains.kotlin.psi2ir.generators package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.IrPropertyDelegateDescriptorImpl import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset 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 { private fun generateDelegatedProperty(ktProperty: KtProperty, ktDelegate: KtPropertyDelegate, propertyDescriptor: PropertyDescriptor): IrProperty {
val ktDelegateExpression = ktDelegate.expression!! val ktDelegateExpression = ktDelegate.expression!!
val delegateType = getInferredTypeWithImplicitCasts(ktDelegateExpression)!! val irDelegateInitializer = generateInitializerBody(propertyDescriptor, ktDelegateExpression)
val propertyReceiverType = propertyDescriptor.extensionReceiverParameter?.type ?: return DelegatedPropertyGenerator(context).generateDelegatedProperty(ktProperty, ktDelegate, propertyDescriptor, irDelegateInitializer)
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
} }
private fun generateSimpleProperty(ktProperty: KtProperty, propertyDescriptor: PropertyDescriptor): IrSimplePropertyImpl { private fun generateSimpleProperty(ktProperty: KtProperty, propertyDescriptor: PropertyDescriptor): IrSimplePropertyImpl {
@@ -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))
}
}
}
@@ -43,11 +43,12 @@ import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
import java.lang.AssertionError import java.lang.AssertionError
class StatementGenerator( class StatementGenerator(
override val context: GeneratorContext,
val scopeOwner: DeclarationDescriptor,
val bodyGenerator: BodyGenerator, val bodyGenerator: BodyGenerator,
override val scope: Scope override val scope: Scope
) : KtVisitor<IrStatement, Nothing?>(), GeneratorWithScope { ) : KtVisitor<IrStatement, Nothing?>(), GeneratorWithScope {
override val context: GeneratorContext get() = bodyGenerator.context
val scopeOwner: DeclarationDescriptor get() = bodyGenerator.scopeOwner
fun generateStatement(ktElement: KtElement): IrStatement = fun generateStatement(ktElement: KtElement): IrStatement =
ktElement.genStmt() ktElement.genStmt()
@@ -64,15 +65,27 @@ class StatementGenerator(
createDummyExpression(expression, expression.javaClass.simpleName) createDummyExpression(expression, expression.javaClass.simpleName)
override fun visitProperty(property: KtProperty, data: Nothing?): IrStatement { override fun visitProperty(property: KtProperty, data: Nothing?): IrStatement {
if (property.delegateExpression != null) TODO("Local delegated property")
val variableDescriptor = getOrFail(BindingContext.VARIABLE, 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) val irLocalVariable = IrVariableImpl(property.startOffset, property.endOffset, IrDeclarationOrigin.DEFINED, variableDescriptor)
irLocalVariable.initializer = property.initializer?.genExpr() irLocalVariable.initializer = property.initializer?.genExpr()
return irLocalVariable 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 { override fun visitDestructuringDeclaration(multiDeclaration: KtDestructuringDeclaration, data: Nothing?): IrStatement {
// TODO use some special form that introduces multiple declarations into surrounding scope? // TODO use some special form that introduces multiple declarations into surrounding scope?
@@ -34,12 +34,10 @@ interface IrClass : IrDeclaration {
fun IrClass.getInstanceInitializerMembers() = fun IrClass.getInstanceInitializerMembers() =
members.filter { members.filter {
when (it) { when (it) {
is IrDelegate ->
true
is IrAnonymousInitializer -> is IrAnonymousInitializer ->
true true
is IrSimpleProperty -> is IrSimpleProperty ->
it.valueInitializer != null it.initializer != null
is IrDelegatedProperty -> is IrDelegatedProperty ->
true true
else -> false else -> false
@@ -29,16 +29,16 @@ interface IrDeclaration : IrStatement {
enum class IrDeclarationKind { enum class IrDeclarationKind {
MODULE, MODULE,
FILE, FILE,
CLASS,
ENUM_ENTRY,
FUNCTION, FUNCTION,
PROPERTY_GETTER,
PROPERTY_SETTER,
CONSTRUCTOR, CONSTRUCTOR,
PROPERTY, PROPERTY,
PROPERTY_ACCESSOR,
VARIABLE, VARIABLE,
DELEGATE, LOCAL_PROPERTY,
CLASS, LOCAL_PROPERTY_ACCESSOR,
TYPEALIAS, TYPEALIAS,
ENUM_ENTRY,
ANONYMOUS_INITIALIZER, ANONYMOUS_INITIALIZER,
DUMMY; 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 { interface IrGeneralFunction : IrDeclaration {
override val descriptor: FunctionDescriptor override val descriptor: FunctionDescriptor
val body: IrBody? var body: IrBody?
override val declarationKind: IrDeclarationKind override val declarationKind: IrDeclarationKind
get() = IrDeclarationKind.FUNCTION get() = IrDeclarationKind.FUNCTION
@@ -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 { interface IrSimpleProperty : IrProperty {
var valueInitializer: IrBody? var initializer: IrBody?
} }
interface IrDelegatedProperty : IrProperty { interface IrDelegatedProperty : IrProperty {
var delegate: IrDelegate var delegate: IrSimpleProperty
} }
abstract class IrPropertyBase( abstract class IrPropertyBase(
@@ -83,7 +83,7 @@ class IrSimplePropertyImpl(
descriptor: PropertyDescriptor, descriptor: PropertyDescriptor,
valueInitializer: IrBody? = null valueInitializer: IrBody? = null
) : IrPropertyBase(startOffset, endOffset, origin, descriptor), IrSimpleProperty { ) : IrPropertyBase(startOffset, endOffset, origin, descriptor), IrSimpleProperty {
override var valueInitializer: IrBody? = valueInitializer override var initializer: IrBody? = valueInitializer
set(value) { set(value) {
value?.assertDetached() value?.assertDetached()
field?.detach() field?.detach()
@@ -93,13 +93,13 @@ class IrSimplePropertyImpl(
override fun getChild(slot: Int): IrElement? = override fun getChild(slot: Int): IrElement? =
when (slot) { when (slot) {
INITIALIZER_SLOT -> valueInitializer INITIALIZER_SLOT -> initializer
else -> super.getChild(slot) else -> super.getChild(slot)
} }
override fun replaceChild(slot: Int, newChild: IrElement) { override fun replaceChild(slot: Int, newChild: IrElement) {
when (slot) { when (slot) {
INITIALIZER_SLOT -> valueInitializer = newChild.assertCast() INITIALIZER_SLOT -> initializer = newChild.assertCast()
else -> super.replaceChild(slot, newChild) else -> super.replaceChild(slot, newChild)
} }
} }
@@ -108,7 +108,7 @@ class IrSimplePropertyImpl(
visitor.visitSimpleProperty(this, data) visitor.visitSimpleProperty(this, data)
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) { override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
valueInitializer?.accept(visitor, data) initializer?.accept(visitor, data)
getter?.accept(visitor, data) getter?.accept(visitor, data)
setter?.accept(visitor, data) setter?.accept(visitor, data)
} }
@@ -125,13 +125,13 @@ class IrDelegatedPropertyImpl(
endOffset: Int, endOffset: Int,
origin: IrDeclarationOrigin, origin: IrDeclarationOrigin,
descriptor: PropertyDescriptor, descriptor: PropertyDescriptor,
delegate: IrDelegate delegate: IrSimpleProperty
) : this(startOffset, endOffset, origin, descriptor) { ) : this(startOffset, endOffset, origin, descriptor) {
this.delegate = delegate this.delegate = delegate
} }
private var delegateImpl: IrDelegate? = null private var delegateImpl: IrSimpleProperty? = null
override var delegate: IrDelegate override var delegate: IrSimpleProperty
get() = delegateImpl!! get() = delegateImpl!!
set(value) { set(value) {
value.assertDetached() value.assertDetached()
@@ -24,20 +24,19 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
interface IrPropertyAccessor : IrGeneralFunction { interface IrPropertyAccessor : IrGeneralFunction {
override val descriptor: PropertyAccessorDescriptor override val descriptor: PropertyAccessorDescriptor
override val declarationKind: IrDeclarationKind
get() = IrDeclarationKind.PROPERTY_ACCESSOR
} }
interface IrPropertyGetter : IrPropertyAccessor { interface IrPropertyGetter : IrPropertyAccessor {
override val descriptor: PropertyGetterDescriptor override val descriptor: PropertyGetterDescriptor
override val declarationKind: IrDeclarationKind
get() = IrDeclarationKind.PROPERTY_GETTER
} }
interface IrPropertySetter : IrPropertyAccessor { interface IrPropertySetter : IrPropertyAccessor {
override val descriptor: PropertySetterDescriptor override val descriptor: PropertySetterDescriptor
override val declarationKind: IrDeclarationKind
get() = IrDeclarationKind.PROPERTY_SETTER
} }
abstract class IrPropertyAccessorBase( abstract class IrPropertyAccessorBase(
@@ -18,19 +18,28 @@ package org.jetbrains.kotlin.ir.descriptors
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations 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.descriptors.impl.VariableDescriptorImpl
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeSubstitutor import org.jetbrains.kotlin.types.TypeSubstitutor
import java.lang.UnsupportedOperationException
interface IrDelegateDescriptor : VariableDescriptor interface IrDelegateDescriptor : PropertyDescriptor
interface IrPropertyDelegateDescriptor : IrDelegateDescriptor { interface IrPropertyDelegateDescriptor : IrDelegateDescriptor {
val correspondingProperty: PropertyDescriptor val correspondingProperty: PropertyDescriptor
val kPropertyType: KotlinType val kPropertyType: KotlinType
} }
interface IrLocalDelegateDescriptor : VariableDescriptor
interface IrLocalDelegatedPropertyDelegateDescriptor : IrLocalDelegateDescriptor {
val correspondingLocalProperty: VariableDescriptorWithAccessors
val kPropertyType: KotlinType
}
interface IrImplementingDelegateDescriptor : IrDelegateDescriptor { interface IrImplementingDelegateDescriptor : IrDelegateDescriptor {
val correspondingSuperType: KotlinType val correspondingSuperType: KotlinType
} }
@@ -39,12 +48,32 @@ abstract class IrDelegateDescriptorBase(
containingDeclaration: DeclarationDescriptor, containingDeclaration: DeclarationDescriptor,
name: Name, name: Name,
delegateType: KotlinType 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 getCompileTimeInitializer(): ConstantValue<*>? = null
override fun getVisibility(): Visibility = Visibilities.PRIVATE 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") throw UnsupportedOperationException("Property delegate descriptor shouldn't be substituted: $this")
} }
@@ -58,15 +87,21 @@ class IrPropertyDelegateDescriptorImpl(
override val correspondingProperty: PropertyDescriptor, override val correspondingProperty: PropertyDescriptor,
delegateType: KotlinType, delegateType: KotlinType,
override val kPropertyType: KotlinType override val kPropertyType: KotlinType
) : IrPropertyDelegateDescriptor, ) : IrDelegateDescriptorBase(
IrDelegateDescriptorBase(correspondingProperty.containingDeclaration, getDelegateName(correspondingProperty.name), delegateType) correspondingProperty.containingDeclaration,
getDelegateName(correspondingProperty.name),
delegateType
), IrPropertyDelegateDescriptor
class IrImplementingDelegateDescriptorImpl( class IrImplementingDelegateDescriptorImpl(
containingDeclaration: ClassDescriptor, containingDeclaration: ClassDescriptor,
delegateType: KotlinType, delegateType: KotlinType,
override val correspondingSuperType: KotlinType override val correspondingSuperType: KotlinType
) : IrImplementingDelegateDescriptor, ) : IrDelegateDescriptorBase(
IrDelegateDescriptorBase(containingDeclaration, getDelegateName(containingDeclaration, correspondingSuperType), delegateType) containingDeclaration,
getDelegateName(containingDeclaration, correspondingSuperType),
delegateType
), IrImplementingDelegateDescriptor
internal fun getDelegateName(name: Name): Name = internal fun getDelegateName(name: Name): Name =
Name.identifier(name.asString() + "\$delegate") Name.identifier(name.asString() + "\$delegate")
@@ -74,4 +109,26 @@ internal fun getDelegateName(name: Name): Name =
internal fun getDelegateName(classDescriptor: ClassDescriptor, superType: KotlinType): Name = internal fun getDelegateName(classDescriptor: ClassDescriptor, superType: KotlinType): Name =
Name.identifier(classDescriptor.name.asString() + "\$" + Name.identifier(classDescriptor.name.asString() + "\$" +
(superType.constructor.declarationDescriptor?.name ?: "\$") + (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) 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) { private fun visitFunctionWithParameters(declaration: IrFunction, data: String) {
declaration.dumpLabeledElementWith(data) { declaration.dumpLabeledElementWith(data) {
declaration.descriptor.valueParameters.forEach { valueParameter -> declaration.descriptor.valueParameters.forEach { valueParameter ->
@@ -63,9 +63,6 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
override fun visitVariable(declaration: IrVariable, data: Nothing?): String = override fun visitVariable(declaration: IrVariable, data: Nothing?): String =
"VAR ${declaration.descriptor.render()}" "VAR ${declaration.descriptor.render()}"
override fun visitDelegate(declaration: IrDelegate, data: Nothing?): String =
"DELEGATE ${declaration.descriptor.render()}"
override fun visitEnumEntry(declaration: IrEnumEntry, data: Nothing?): String = override fun visitEnumEntry(declaration: IrEnumEntry, data: Nothing?): String =
"ENUM_ENTRY ${declaration.descriptor.render()}" "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 visitProperty(declaration: IrProperty, data: D) = visitDeclaration(declaration, data)
fun visitSimpleProperty(declaration: IrSimpleProperty, data: D) = visitProperty(declaration, data) fun visitSimpleProperty(declaration: IrSimpleProperty, data: D) = visitProperty(declaration, data)
fun visitDelegatedProperty(declaration: IrDelegatedProperty, 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 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 visitEnumEntry(declaration: IrEnumEntry, data: D) = visitDeclaration(declaration, data)
fun visitAnonymousInitializer(declaration: IrAnonymousInitializer, 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 // 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 visitDummyDeclaration(declaration: IrDummyDeclaration, data: D) = visitDeclaration(declaration, data)
fun visitDummyExpression(expression: IrDummyExpression, data: D) = visitExpression(expression, data) fun visitDummyExpression(expression: IrDummyExpression, data: D) = visitExpression(expression, data)
} }
@@ -51,7 +51,7 @@ FILE /delegatedImplementation.kt
CONSTRUCTOR public constructor Test1() CONSTRUCTOR public constructor Test1()
BLOCK_BODY BLOCK_BODY
INSTANCE_INITIALIZER_CALL classDescriptor=Test1 INSTANCE_INITIALIZER_CALL classDescriptor=Test1
DELEGATE val `Test1$IBase$delegate`: BaseImpl PROPERTY val `Test1$IBase$delegate`: BaseImpl
EXPRESSION_BODY EXPRESSION_BODY
GET_OBJECT BaseImpl type=BaseImpl GET_OBJECT BaseImpl type=BaseImpl
FUN public open override /*1*/ /*delegation*/ fun foo(/*0*/ x: kotlin.Int, /*1*/ s: kotlin.String): kotlin.Unit 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() CONSTRUCTOR public constructor Test2()
BLOCK_BODY BLOCK_BODY
INSTANCE_INITIALIZER_CALL classDescriptor=Test2 INSTANCE_INITIALIZER_CALL classDescriptor=Test2
DELEGATE val `Test2$IBase$delegate`: BaseImpl PROPERTY val `Test2$IBase$delegate`: BaseImpl
EXPRESSION_BODY EXPRESSION_BODY
GET_OBJECT BaseImpl type=BaseImpl GET_OBJECT BaseImpl type=BaseImpl
FUN public open override /*1*/ /*delegation*/ fun foo(/*0*/ x: kotlin.Int, /*1*/ s: kotlin.String): kotlin.Unit 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 CALL .qux type=kotlin.Unit operator=null
$this: GET_VAR Test2$IBase$delegate type=BaseImpl operator=null $this: GET_VAR Test2$IBase$delegate type=BaseImpl operator=null
$receiver: $RECEIVER of: qux type=kotlin.String $receiver: $RECEIVER of: qux type=kotlin.String
DELEGATE val `Test2$IOther$delegate`: IOther PROPERTY val `Test2$IOther$delegate`: IOther
EXPRESSION_BODY EXPRESSION_BODY
CALL .otherImpl type=IOther operator=null CALL .otherImpl type=IOther operator=null
x0: CONST String type=kotlin.String value='' x0: CONST String type=kotlin.String value=''
@@ -14,7 +14,7 @@ FILE /delegatedImplementationWithExplicitOverride.kt
CONSTRUCTOR public constructor C() CONSTRUCTOR public constructor C()
BLOCK_BODY BLOCK_BODY
INSTANCE_INITIALIZER_CALL classDescriptor=C INSTANCE_INITIALIZER_CALL classDescriptor=C
DELEGATE val `C$IFooBar$delegate`: FooBarImpl PROPERTY val `C$IFooBar$delegate`: FooBarImpl
EXPRESSION_BODY EXPRESSION_BODY
GET_OBJECT FooBarImpl type=FooBarImpl GET_OBJECT FooBarImpl type=FooBarImpl
FUN public open override /*1*/ /*delegation*/ fun foo(): kotlin.Unit FUN public open override /*1*/ /*delegation*/ fun foo(): kotlin.Unit
@@ -1,6 +1,6 @@
FILE /delegatedProperties.kt FILE /delegatedProperties.kt
PROPERTY public val test1: kotlin.Int 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 EXPRESSION_BODY
CALL .lazy type=kotlin.Lazy<kotlin.Int> operator=null CALL .lazy type=kotlin.Lazy<kotlin.Int> operator=null
initializer: BLOCK type=() -> kotlin.Int operator=LAMBDA initializer: BLOCK type=() -> kotlin.Int operator=LAMBDA
@@ -13,7 +13,7 @@ FILE /delegatedProperties.kt
BLOCK_BODY BLOCK_BODY
RETURN type=kotlin.Nothing from=<get-test1> RETURN type=kotlin.Nothing from=<get-test1>
CALL .getValue type=kotlin.Int operator=null 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' thisRef: CONST Null type=kotlin.Nothing? value='null'
property: CALLABLE_REFERENCE public val test1: kotlin.Int type=kotlin.reflect.KProperty0<kotlin.Int> property: CALLABLE_REFERENCE public val test1: kotlin.Int type=kotlin.reflect.KProperty0<kotlin.Int>
CLASS CLASS C CLASS CLASS C
@@ -26,7 +26,7 @@ FILE /delegatedProperties.kt
EXPRESSION_BODY EXPRESSION_BODY
GET_VAR map type=kotlin.collections.MutableMap<kotlin.String, kotlin.Any> operator=INITIALIZE_PROPERTY_FROM_PARAMETER GET_VAR map type=kotlin.collections.MutableMap<kotlin.String, kotlin.Any> operator=INITIALIZE_PROPERTY_FROM_PARAMETER
PROPERTY public final val test2: kotlin.Int 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 EXPRESSION_BODY
CALL .lazy type=kotlin.Lazy<kotlin.Int> operator=null CALL .lazy type=kotlin.Lazy<kotlin.Int> operator=null
initializer: BLOCK type=() -> kotlin.Int operator=LAMBDA initializer: BLOCK type=() -> kotlin.Int operator=LAMBDA
@@ -39,11 +39,11 @@ FILE /delegatedProperties.kt
BLOCK_BODY BLOCK_BODY
RETURN type=kotlin.Nothing from=<get-test2> RETURN type=kotlin.Nothing from=<get-test2>
CALL .getValue type=kotlin.Int operator=null 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 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: CALLABLE_REFERENCE public final val test2: kotlin.Int type=kotlin.reflect.KProperty1<C, kotlin.Int>
PROPERTY public final var test3: kotlin.Any 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 EXPRESSION_BODY
CALL .<get-map> type=kotlin.collections.MutableMap<kotlin.String, kotlin.Any> operator=GET_PROPERTY CALL .<get-map> type=kotlin.collections.MutableMap<kotlin.String, kotlin.Any> operator=GET_PROPERTY
$this: THIS public final class C type=C $this: THIS public final class C type=C
@@ -51,33 +51,33 @@ FILE /delegatedProperties.kt
BLOCK_BODY BLOCK_BODY
RETURN type=kotlin.Nothing from=<get-test3> RETURN type=kotlin.Nothing from=<get-test3>
CALL .getValue type=kotlin.Any operator=null 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 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: 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 PROPERTY_SETTER public final fun <set-test3>(/*0*/ <set-?>: kotlin.Any): kotlin.Unit
BLOCK_BODY BLOCK_BODY
RETURN type=kotlin.Nothing from=<set-test3> RETURN type=kotlin.Nothing from=<set-test3>
CALL .setValue type=kotlin.Unit operator=null 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 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: CALLABLE_REFERENCE public final var test3: kotlin.Any type=kotlin.reflect.KMutableProperty1<C, kotlin.Any>
value: GET_VAR <set-?> type=kotlin.Any operator=null value: GET_VAR <set-?> type=kotlin.Any operator=null
PROPERTY public var test4: kotlin.Any 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 EXPRESSION_BODY
CALL .hashMapOf type=java.util.HashMap<kotlin.String, kotlin.Any> operator=null CALL .hashMapOf type=java.util.HashMap<kotlin.String, kotlin.Any> operator=null
PROPERTY_GETTER public fun <get-test4>(): kotlin.Any PROPERTY_GETTER public fun <get-test4>(): kotlin.Any
BLOCK_BODY BLOCK_BODY
RETURN type=kotlin.Nothing from=<get-test4> RETURN type=kotlin.Nothing from=<get-test4>
CALL .getValue type=kotlin.Any operator=null 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' thisRef: CONST Null type=kotlin.Nothing? value='null'
property: CALLABLE_REFERENCE public var test4: kotlin.Any type=kotlin.reflect.KMutableProperty0<kotlin.Any> 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 PROPERTY_SETTER public fun <set-test4>(/*0*/ <set-?>: kotlin.Any): kotlin.Unit
BLOCK_BODY BLOCK_BODY
RETURN type=kotlin.Nothing from=<set-test4> RETURN type=kotlin.Nothing from=<set-test4>
CALL .setValue type=kotlin.Unit operator=null 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' thisRef: CONST Null type=kotlin.Nothing? value='null'
property: CALLABLE_REFERENCE public var test4: kotlin.Any type=kotlin.reflect.KMutableProperty0<kotlin.Any> property: CALLABLE_REFERENCE public var test4: kotlin.Any type=kotlin.reflect.KMutableProperty0<kotlin.Any>
value: GET_VAR <set-?> type=kotlin.Any operator=null 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); 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") @TestMetadata("typeAlias.kt")
public void testTypeAlias() throws Exception { public void testTypeAlias() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/declarations/typeAlias.kt"); String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/declarations/typeAlias.kt");