From ceeccfa1b77f78341560dcc9fe38a20f71ea6b44 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Mon, 5 Sep 2016 15:06:38 +0300 Subject: [PATCH] Properties without accessors are generated as IrGetBackingField / IrSetBackingField expressions. --- .../psi2ir/generators/AssignmentGenerator.kt | 25 ++++++- .../kotlin/psi2ir/generators/BodyGenerator.kt | 14 +++- .../kotlin/psi2ir/generators/CallGenerator.kt | 16 +++-- .../generators/DelegatedPropertyGenerator.kt | 19 +++--- .../psi2ir/intermediate/BackingFieldLValue.kt | 5 +- .../intermediate/SimplePropertyLValue.kt | 30 +++++---- .../transformations/InsertImplicitCasts.kt | 23 ++++--- .../kotlin/ir/AbstractIrTextTestCase.kt | 8 +-- .../src/org/jetbrains/kotlin/ir/IrSlots.kt | 1 + .../expressions/IrBackingFieldExpression.kt | 67 +++++++++++++++---- .../jetbrains/kotlin/ir/util/DumpIrTree.kt | 13 ++++ .../kotlin/ir/visitors/IrElementVisitor.kt | 5 +- .../ir/visitors/IrElementVisitorVoid.kt | 7 +- ...tReorderingInDelegatingConstructorCall.txt | 6 +- .../ir/irText/classes/classMembers.txt | 6 +- .../ir/irText/classes/dataClasses.txt | 9 ++- compiler/testData/ir/irText/classes/enum.txt | 9 ++- .../testData/ir/irText/classes/initBlock.txt | 3 +- .../testData/ir/irText/classes/initVal.txt | 6 +- .../testData/ir/irText/classes/initVar.txt | 9 +-- .../irText/classes/objectWithInitializers.txt | 3 +- .../ir/irText/classes/primaryConstructor.txt | 15 +++-- ...aryConstructorWithSuperConstructorCall.txt | 6 +- .../ir/irText/classes/sealedClasses.txt | 9 ++- ...nstructorWithInitializersFromClassBody.txt | 3 +- .../declarations/delegatedProperties.txt | 6 +- .../expressions/arrayAugmentedAssignment1.txt | 3 +- .../ir/irText/expressions/assignments.txt | 3 +- .../complexAugmentedAssignment.txt | 3 +- .../ir/irText/expressions/destructuring1.kt | 2 +- .../ir/irText/expressions/destructuring1.txt | 45 +++++++++---- .../testData/ir/irText/expressions/field.txt | 4 +- .../expressions/forWithImplicitReceivers.txt | 3 +- .../expressions/jvmInstanceFieldReference.kt | 19 ++++++ .../expressions/jvmInstanceFieldReference.txt | 21 ++++++ .../expressions/jvmStaticFieldReference.txt | 10 +-- .../ir/irText/expressions/safeCalls.txt | 3 +- .../expressions/setFieldWithImplicitCast.kt | 14 ++++ .../expressions/setFieldWithImplicitCast.txt | 16 +++++ .../kotlin/ir/IrTextTestCaseGenerated.java | 12 ++++ 40 files changed, 359 insertions(+), 122 deletions(-) create mode 100644 compiler/testData/ir/irText/expressions/jvmInstanceFieldReference.kt create mode 100644 compiler/testData/ir/irText/expressions/jvmInstanceFieldReference.txt create mode 100644 compiler/testData/ir/irText/expressions/setFieldWithImplicitCast.kt create mode 100644 compiler/testData/ir/irText/expressions/setFieldWithImplicitCast.txt diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/AssignmentGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/AssignmentGenerator.kt index 3a1c641db45..f43bf955bb3 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/AssignmentGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/AssignmentGenerator.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrOperator +import org.jetbrains.kotlin.ir.expressions.IrThisReferenceImpl import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset @@ -108,8 +109,14 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen val descriptor = resolvedCall.candidateDescriptor return when (descriptor) { - is SyntheticFieldDescriptor -> - BackingFieldLValue(ktLeft.startOffset, ktLeft.endOffset, descriptor.propertyDescriptor, operator) + is SyntheticFieldDescriptor -> { + val receiverValue = resolvedCall.dispatchReceiver?.let { + statementGenerator.generateReceiver(ktLeft, it) + } + BackingFieldLValue(ktLeft.startOffset, ktLeft.endOffset, descriptor.propertyDescriptor, + receiverValue, operator) + + } is LocalVariableDescriptor -> if (descriptor.isDelegated) DelegatedLocalPropertyLValue(ktLeft.startOffset, ktLeft.endOffset, descriptor, operator) @@ -131,7 +138,10 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen resolvedCall: ResolvedCall<*> ): AssignmentReceiver { if (isValInitializationInConstructor(descriptor, resolvedCall)) { - return BackingFieldLValue(ktLeft.startOffset, ktLeft.endOffset, descriptor, null) + val thisClass = getThisClass() + val irThis = IrThisReferenceImpl(ktLeft.startOffset, ktLeft.endOffset, thisClass.defaultType, thisClass) + return BackingFieldLValue(ktLeft.startOffset, ktLeft.endOffset, descriptor, + RematerializableValue(irThis), null) } val propertyReceiver = statementGenerator.generateCallReceiver( @@ -148,6 +158,15 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen statementGenerator.scopeOwner.let { it is ConstructorDescriptor || it is ClassDescriptor } && resolvedCall.dispatchReceiver is ThisClassReceiver + private fun getThisClass(): ClassDescriptor { + val scopeOwner = statementGenerator.scopeOwner + return when (scopeOwner) { + is ConstructorDescriptor -> scopeOwner.containingDeclaration + is ClassDescriptor -> scopeOwner + else -> scopeOwner.containingDeclaration as ClassDescriptor + } + } + private fun generateArrayAccessAssignmentReceiver(ktLeft: KtArrayAccessExpression, irOperator: IrOperator): ArrayAccessAssignmentReceiver { val irArray = statementGenerator.generateExpression(ktLeft.arrayExpression!!) val irIndexExpressions = ktLeft.indexExpressions.map { statementGenerator.generateExpression(it) } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/BodyGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/BodyGenerator.kt index 8c976c488ac..05c0ba68718 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/BodyGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/BodyGenerator.kt @@ -288,7 +288,7 @@ class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context: val valueParameterDescriptor = getOrFail(BindingContext.VALUE_PARAMETER, ktParameter) irBlockBody.addStatement( - createPropertyInitializationExpression( + initializePropertyInPrimaryConstructor( ktParameter, propertyDescriptor, IrGetVariableImpl(ktParameter.startOffset, ktParameter.endOffset, valueParameterDescriptor, IrOperator.INITIALIZE_PROPERTY_FROM_PARAMETER) @@ -298,7 +298,15 @@ class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context: } } - private fun createPropertyInitializationExpression(ktElement: KtElement, propertyDescriptor: PropertyDescriptor, value: IrExpression) = - IrSetBackingFieldImpl(ktElement.startOffset, ktElement.endOffset, propertyDescriptor, value) + private fun initializePropertyInPrimaryConstructor( + ktElement: KtElement, + propertyDescriptor: PropertyDescriptor, + value: IrExpression + ): IrExpression { + val thisClass = propertyDescriptor.containingDeclaration as ClassDescriptor + return IrSetBackingFieldImpl(ktElement.startOffset, ktElement.endOffset, propertyDescriptor, + IrThisReferenceImpl(ktElement.startOffset, ktElement.endOffset, thisClass.defaultType, thisClass), + value) + } } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt index 5df2b40d48b..00a3f4d8e49 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt @@ -85,13 +85,15 @@ class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorE call: CallBuilder ): IrExpression { return call.callReceiver.call { dispatchReceiverValue, extensionReceiverValue -> - val getter = descriptor.getter ?: - context.syntheticDescriptorsFactory.getOrCreatePropertyGetter(descriptor) - IrGetterCallImpl(startOffset, endOffset, getter, - dispatchReceiverValue?.load(), - extensionReceiverValue?.load(), - IrOperator.GET_PROPERTY, - call.superQualifier) + descriptor.getter?.let { getter -> + IrGetterCallImpl(startOffset, endOffset, getter, + dispatchReceiverValue?.load(), + extensionReceiverValue?.load(), + IrOperator.GET_PROPERTY, + call.superQualifier) + } ?: IrGetBackingFieldImpl(startOffset, endOffset, descriptor, + dispatchReceiverValue?.load(), + IrOperator.GET_PROPERTY, call.superQualifier) } } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DelegatedPropertyGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DelegatedPropertyGenerator.kt index 917aa77f159..a1ed6b2d47d 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DelegatedPropertyGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DelegatedPropertyGenerator.kt @@ -16,10 +16,7 @@ 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.* import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.descriptors.IrLocalDelegatedPropertyDelegateDescriptor @@ -35,10 +32,7 @@ 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.psi2ir.intermediate.* import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.types.KotlinType @@ -82,8 +76,13 @@ class DelegatedPropertyGenerator(override val context: GeneratorContext) : Gener return irProperty } - private fun createBackingFieldValueForDelegate(delegateDescriptor: IrPropertyDelegateDescriptor, ktDelegate: KtPropertyDelegate) = - BackingFieldLValue(ktDelegate.startOffset, ktDelegate.endOffset, delegateDescriptor, null) + private fun createBackingFieldValueForDelegate(delegateDescriptor: IrPropertyDelegateDescriptor, ktDelegate: KtPropertyDelegate): IntermediateValue { + val thisClass = delegateDescriptor.correspondingProperty.containingDeclaration as? ClassDescriptor + val thisValue = thisClass?.let { + RematerializableValue(IrThisReferenceImpl(ktDelegate.startOffset, ktDelegate.endOffset, thisClass.defaultType, thisClass)) + } + return BackingFieldLValue(ktDelegate.startOffset, ktDelegate.endOffset, delegateDescriptor, thisValue, null) + } private fun createCallableReference(ktElement: KtElement, type: KotlinType, referencedDescriptor: CallableDescriptor): IrCallableReference = IrCallableReferenceImpl(ktElement.startOffset, ktElement.endOffset, type, diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/BackingFieldLValue.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/BackingFieldLValue.kt index e5e092a0e91..f9223309a4c 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/BackingFieldLValue.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/BackingFieldLValue.kt @@ -24,15 +24,16 @@ class BackingFieldLValue( val startOffset: Int, val endOffset: Int, val descriptor: PropertyDescriptor, + val receiver: IntermediateValue?, val operator: IrOperator? ) : LValue, AssignmentReceiver { override val type: KotlinType get() = descriptor.type override fun store(irExpression: IrExpression): IrExpression = - IrSetBackingFieldImpl(startOffset, endOffset, descriptor, irExpression, operator) + IrSetBackingFieldImpl(startOffset, endOffset, descriptor, receiver?.load(), irExpression, operator) override fun load(): IrExpression = - IrGetBackingFieldImpl(startOffset, endOffset, descriptor, operator) + IrGetBackingFieldImpl(startOffset, endOffset, descriptor, receiver?.load(), operator) override fun assign(withLValue: (LValue) -> IrExpression): IrExpression = withLValue(this) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/SimplePropertyLValue.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/SimplePropertyLValue.kt index f89b814b888..beead0f7173 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/SimplePropertyLValue.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/SimplePropertyLValue.kt @@ -37,23 +37,27 @@ class SimplePropertyLValue( override fun load(): IrExpression = callReceiver.call { dispatchReceiverValue, extensionReceiverValue -> - val getter = descriptor.getter ?: context.syntheticDescriptorsFactory.getOrCreatePropertyGetter(descriptor) - IrGetterCallImpl(startOffset, endOffset, getter, - dispatchReceiverValue?.load(), - extensionReceiverValue?.load(), - irOperator, - superQualifier) + descriptor.getter?.let { getter -> + IrGetterCallImpl(startOffset, endOffset, getter, + dispatchReceiverValue?.load(), + extensionReceiverValue?.load(), + irOperator, + superQualifier) + } ?: IrGetBackingFieldImpl(startOffset, endOffset, descriptor, + dispatchReceiverValue?.load(), irOperator, superQualifier) } override fun store(irExpression: IrExpression) = callReceiver.call { dispatchReceiverValue, extensionReceiverValue -> - val setter = descriptor.setter ?: context.syntheticDescriptorsFactory.getOrCreatePropertySetter(descriptor) - IrSetterCallImpl(startOffset, endOffset, setter, - dispatchReceiverValue?.load(), - extensionReceiverValue?.load(), - irExpression, - irOperator, - superQualifier) + descriptor.setter?.let { setter -> + IrSetterCallImpl(startOffset, endOffset, setter, + dispatchReceiverValue?.load(), + extensionReceiverValue?.load(), + irExpression, + irOperator, + superQualifier) + } ?: IrSetBackingFieldImpl(startOffset, endOffset, descriptor, + dispatchReceiverValue?.load(), irExpression, irOperator, superQualifier) } override fun assign(withLValue: (LValue) -> IrExpression) = diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt index 56430d8d902..20ee0ed0338 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt @@ -55,7 +55,7 @@ class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementVisitorVoid { } override fun visitBlock(expression: IrBlock) { - expression.acceptChildren(this, null) + expression.acceptChildrenVoid(this) val type = expression.type if (KotlinBuiltIns.isUnit(type)) return if (expression.statements.isEmpty()) return @@ -67,25 +67,31 @@ class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementVisitorVoid { } override fun visitReturn(expression: IrReturn) { - expression.acceptChildren(this, null) + expression.acceptChildrenVoid(this) expression.value?.replaceWithCast(expression.returnTarget.returnType) } override fun visitSetVariable(expression: IrSetVariable) { - expression.acceptChildren(this, null) + expression.acceptChildrenVoid(this) + + expression.value.replaceWithCast(expression.descriptor.type) + } + + override fun visitSetBackingField(expression: IrSetBackingField) { + expression.acceptChildrenVoid(this) expression.value.replaceWithCast(expression.descriptor.type) } override fun visitVariable(declaration: IrVariable) { - declaration.acceptChildren(this, null) + declaration.acceptChildrenVoid(this) declaration.initializer?.replaceWithCast(declaration.descriptor.type) } override fun visitWhen(expression: IrWhen) { - expression.acceptChildren(this, null) + expression.acceptChildrenVoid(this) for (branchIndex in expression.branchIndices) { expression.getNthCondition(branchIndex)!!.replaceWithCast(builtIns.booleanType) @@ -95,19 +101,19 @@ class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementVisitorVoid { } override fun visitLoop(loop: IrLoop) { - loop.acceptChildren(this, null) + loop.acceptChildrenVoid(this) loop.condition.replaceWithCast(builtIns.booleanType) } override fun visitThrow(expression: IrThrow) { - expression.acceptChildren(this, null) + expression.acceptChildrenVoid(this) expression.value.replaceWithCast(builtIns.throwable.defaultType) } override fun visitTryCatch(tryCatch: IrTryCatch) { - tryCatch.acceptChildren(this, null) + tryCatch.acceptChildrenVoid(this) val resultType = tryCatch.type @@ -119,6 +125,7 @@ class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementVisitorVoid { override fun visitVararg(expression: IrVararg) { expression.acceptChildrenVoid(this) + for (element in expression.elements) { when (element) { is IrSpreadElement -> element.expression.replaceWithCast(expression.type) diff --git a/compiler/ir/ir.tests/tests/org/jetbrains/kotlin/ir/AbstractIrTextTestCase.kt b/compiler/ir/ir.tests/tests/org/jetbrains/kotlin/ir/AbstractIrTextTestCase.kt index 33972e1708f..3468f5dda26 100644 --- a/compiler/ir/ir.tests/tests/org/jetbrains/kotlin/ir/AbstractIrTextTestCase.kt +++ b/compiler/ir/ir.tests/tests/org/jetbrains/kotlin/ir/AbstractIrTextTestCase.kt @@ -74,7 +74,7 @@ abstract class AbstractIrTextTestCase : AbstractIrGeneratorTestCase() { companion object { private val EXPECTED_OCCURRENCES_PATTERN = Regex("""^\s*//\s*(\d+)\s*(.*)$""") - private val IR_TREES_TXT_PATTERN = Regex("""// \s*<<<\s+(.*)$""") + private val IR_FILE_TXT_PATTERN = Regex("""// IR_FILE: (.*)$""") private val IGNORE_ERRORS_PATTERN = Regex("""// !IGNORE_ERRORS""") internal fun shouldIgnoreErrors(wholeFile: File): Boolean = @@ -84,14 +84,14 @@ abstract class AbstractIrTextTestCase : AbstractIrGeneratorTestCase() { val regexps = ArrayList() val treeFiles = ArrayList() - for ((lineNumber, line) in testFile.content.split("\n").withIndex()) { + for (line in testFile.content.split("\n")) { EXPECTED_OCCURRENCES_PATTERN.matchEntire(line)?.let { matchResult -> regexps.add(RegexpInText(matchResult.groupValues[1], matchResult.groupValues[2].trim())) } - ?: IR_TREES_TXT_PATTERN.find(line)?.let { matchResult -> + ?: IR_FILE_TXT_PATTERN.find(line)?.let { matchResult -> val fileName = matchResult.groupValues[1].trim() val file = createExpectedTextFile(testFile, dir, fileName) - treeFiles.add(IrTreeFileLabel(file, lineNumber)) + treeFiles.add(IrTreeFileLabel(file, 0)) } } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrSlots.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrSlots.kt index 736468c6c3e..eedfe9aa81d 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrSlots.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrSlots.kt @@ -22,6 +22,7 @@ const val ARGUMENT0_SLOT = 0 const val ARGUMENT1_SLOT = 1 const val DISPATCH_RECEIVER_SLOT = -1 const val EXTENSION_RECEIVER_SLOT = -2 +const val BACKING_FIELD_RECEIVER_SLOT = -1 const val FUNCTION_BODY_SLOT = -1 const val ANONYMOUS_INITIALIZER_BODY_SLOT = -1 const val MODULE_SLOT = 0 diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrBackingFieldExpression.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrBackingFieldExpression.kt index e0d56029e3f..844330a0936 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrBackingFieldExpression.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrBackingFieldExpression.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.ir.expressions +import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.ir.* import org.jetbrains.kotlin.ir.visitors.IrElementVisitor @@ -24,6 +25,8 @@ import org.jetbrains.kotlin.types.typeUtil.builtIns interface IrBackingFieldExpression : IrDeclarationReference { override val descriptor: PropertyDescriptor + val superQualifier: ClassDescriptor? + var receiver: IrExpression? val operator: IrOperator? } @@ -38,20 +41,54 @@ abstract class IrBackingFieldExpressionBase( endOffset: Int, descriptor: PropertyDescriptor, type: KotlinType, - override val operator: IrOperator? = null -) : IrDeclarationReferenceBase(startOffset, endOffset, type, descriptor), IrBackingFieldExpression + override val operator: IrOperator? = null, + override val superQualifier: ClassDescriptor? = null +) : IrDeclarationReferenceBase(startOffset, endOffset, type, descriptor), IrBackingFieldExpression { + override final var receiver: IrExpression? = null + set(value) { + value?.assertDetached() + field?.detach() + field = value + value?.setTreeLocation(this, BACKING_FIELD_RECEIVER_SLOT) + } + + override fun getChild(slot: Int): IrElement? = + when (slot) { + BACKING_FIELD_RECEIVER_SLOT -> receiver + else -> null + } + + override fun replaceChild(slot: Int, newChild: IrElement) { + when (slot) { + BACKING_FIELD_RECEIVER_SLOT -> receiver = newChild.assertCast() + else -> throwNoSuchSlot(slot) + } + } +} class IrGetBackingFieldImpl( startOffset: Int, endOffset: Int, descriptor: PropertyDescriptor, - operator: IrOperator? = null -) : IrBackingFieldExpressionBase(startOffset, endOffset, descriptor, descriptor.type, operator), IrGetBackingField { + operator: IrOperator? = null, + superQualifier: ClassDescriptor? = null +) : IrBackingFieldExpressionBase(startOffset, endOffset, descriptor, descriptor.type, operator, superQualifier), IrGetBackingField { + constructor( + startOffset: Int, + endOffset: Int, + descriptor: PropertyDescriptor, + receiver: IrExpression?, + operator: IrOperator? = null, + superQualifier: ClassDescriptor? = null + ) : this(startOffset, endOffset, descriptor, operator, superQualifier) { + this.receiver = receiver + } + override fun getChild(slot: Int): IrElement? = - null + super.getChild(slot) override fun replaceChild(slot: Int, newChild: IrElement) { - throwNoSuchSlot(slot) + super.replaceChild(slot, newChild) } override fun accept(visitor: IrElementVisitor, data: D): R { @@ -59,7 +96,7 @@ class IrGetBackingFieldImpl( } override fun acceptChildren(visitor: IrElementVisitor, data: D) { - // no children + receiver?.accept(visitor, data) } } @@ -67,15 +104,19 @@ class IrSetBackingFieldImpl( startOffset: Int, endOffset: Int, descriptor: PropertyDescriptor, - operator: IrOperator? = null -) : IrBackingFieldExpressionBase(startOffset, endOffset, descriptor, descriptor.type.builtIns.unitType, operator), IrSetBackingField { + operator: IrOperator? = null, + superQualifier: ClassDescriptor? = null +) : IrBackingFieldExpressionBase(startOffset, endOffset, descriptor, descriptor.type.builtIns.unitType, operator, superQualifier), IrSetBackingField { constructor( startOffset: Int, endOffset: Int, descriptor: PropertyDescriptor, + receiver: IrExpression?, value: IrExpression, - operator: IrOperator? = null - ) : this(startOffset, endOffset, descriptor, operator) { + operator: IrOperator? = null, + superQualifier: ClassDescriptor? = null + ) : this(startOffset, endOffset, descriptor, operator, superQualifier) { + this.receiver = receiver this.value = value } @@ -92,12 +133,13 @@ class IrSetBackingFieldImpl( override fun getChild(slot: Int): IrElement? = when (slot) { CHILD_EXPRESSION_SLOT -> value - else -> null + else -> super.getChild(slot) } override fun replaceChild(slot: Int, newChild: IrElement) { when (slot) { CHILD_EXPRESSION_SLOT -> value = newChild.assertCast() + else -> super.replaceChild(slot, newChild) } } @@ -106,6 +148,7 @@ class IrSetBackingFieldImpl( } override fun acceptChildren(visitor: IrElementVisitor, data: D) { + receiver?.accept(visitor, data) value.accept(visitor, data) } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DumpIrTree.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DumpIrTree.kt index a8434a5c4d2..74df6ff56be 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DumpIrTree.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DumpIrTree.kt @@ -94,6 +94,19 @@ class DumpIrTreeVisitor(out: Appendable): IrElementVisitor { } } + override fun visitGetBackingField(expression: IrGetBackingField, data: String) { + expression.dumpLabeledElementWith(data) { + expression.receiver?.accept(this, "receiver") + } + } + + override fun visitSetBackingField(expression: IrSetBackingField, data: String) { + expression.dumpLabeledElementWith(data) { + expression.receiver?.accept(this, "receiver") + expression.value.accept(this, "value") + } + } + override fun visitWhen(expression: IrWhen, data: String) { expression.dumpLabeledElementWith(data) { for (i in 0 .. expression.branchesCount - 1) { diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitor.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitor.kt index c35076db57b..5350ffa6d10 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitor.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitor.kt @@ -62,8 +62,9 @@ interface IrElementVisitor { fun visitGetEnumValue(expression: IrGetEnumValue, data: D) = visitSingletonReference(expression, data) fun visitGetVariable(expression: IrGetVariable, data: D) = visitDeclarationReference(expression, data) fun visitSetVariable(expression: IrSetVariable, data: D) = visitDeclarationReference(expression, data) - fun visitGetBackingField(expression: IrGetBackingField, data: D) = visitDeclarationReference(expression, data) - fun visitSetBackingField(expression: IrSetBackingField, data: D) = visitDeclarationReference(expression, data) + fun visitBackingFieldReference(expression: IrBackingFieldExpression, data: D) = visitDeclarationReference(expression, data) + fun visitGetBackingField(expression: IrGetBackingField, data: D) = visitBackingFieldReference(expression, data) + fun visitSetBackingField(expression: IrSetBackingField, data: D) = visitBackingFieldReference(expression, data) fun visitGetExtensionReceiver(expression: IrGetExtensionReceiver, data: D) = visitDeclarationReference(expression, data) fun visitGeneralCall(expression: IrGeneralCall, data: D) = visitDeclarationReference(expression, data) fun visitCall(expression: IrCall, data: D) = visitGeneralCall(expression, data) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitorVoid.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitorVoid.kt index 420b8c80011..b3c0fef7e75 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitorVoid.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitorVoid.kt @@ -129,10 +129,13 @@ interface IrElementVisitorVoid : IrElementVisitor { fun visitSetVariable(expression: IrSetVariable) = visitDeclarationReference(expression) override fun visitSetVariable(expression: IrSetVariable, data: Nothing?) = visitSetVariable(expression) - fun visitGetBackingField(expression: IrGetBackingField) = visitDeclarationReference(expression) + fun visitBackingFieldReference(expression: IrBackingFieldExpression) = visitDeclarationReference(expression) + override fun visitBackingFieldReference(expression: IrBackingFieldExpression, data: Nothing?) = visitBackingFieldReference(expression) + + fun visitGetBackingField(expression: IrGetBackingField) = visitBackingFieldReference(expression) override fun visitGetBackingField(expression: IrGetBackingField, data: Nothing?) = visitGetBackingField(expression) - fun visitSetBackingField(expression: IrSetBackingField) = visitDeclarationReference(expression) + fun visitSetBackingField(expression: IrSetBackingField) = visitBackingFieldReference(expression) override fun visitSetBackingField(expression: IrSetBackingField, data: Nothing?) = visitSetBackingField(expression) fun visitGetExtensionReceiver(expression: IrGetExtensionReceiver) = visitDeclarationReference(expression) diff --git a/compiler/testData/ir/irText/classes/argumentReorderingInDelegatingConstructorCall.txt b/compiler/testData/ir/irText/classes/argumentReorderingInDelegatingConstructorCall.txt index 2b1927edcd6..b63be31379f 100644 --- a/compiler/testData/ir/irText/classes/argumentReorderingInDelegatingConstructorCall.txt +++ b/compiler/testData/ir/irText/classes/argumentReorderingInDelegatingConstructorCall.txt @@ -4,9 +4,11 @@ FILE /argumentReorderingInDelegatingConstructorCall.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL Any SET_BACKING_FIELD x type=kotlin.Unit operator=null - GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER + receiver: THIS public open class Base type=Base + value: GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER SET_BACKING_FIELD y type=kotlin.Unit operator=null - GET_VAR y type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER + receiver: THIS public open class Base type=Base + value: GET_VAR y type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER INSTANCE_INITIALIZER_CALL classDescriptor=Base PROPERTY public final val x: kotlin.Int EXPRESSION_BODY diff --git a/compiler/testData/ir/irText/classes/classMembers.txt b/compiler/testData/ir/irText/classes/classMembers.txt index e6d757a3e68..130346ceb31 100644 --- a/compiler/testData/ir/irText/classes/classMembers.txt +++ b/compiler/testData/ir/irText/classes/classMembers.txt @@ -6,9 +6,11 @@ FILE /classMembers.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL Any SET_BACKING_FIELD y type=kotlin.Unit operator=null - GET_VAR y type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER + receiver: THIS public final class C type=C + value: GET_VAR y type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER SET_BACKING_FIELD z type=kotlin.Unit operator=null - GET_VAR z type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER + receiver: THIS public final class C type=C + value: GET_VAR z type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER INSTANCE_INITIALIZER_CALL classDescriptor=C PROPERTY public final val y: kotlin.Int EXPRESSION_BODY diff --git a/compiler/testData/ir/irText/classes/dataClasses.txt b/compiler/testData/ir/irText/classes/dataClasses.txt index 07fb57d4a57..d29d025aea8 100644 --- a/compiler/testData/ir/irText/classes/dataClasses.txt +++ b/compiler/testData/ir/irText/classes/dataClasses.txt @@ -4,11 +4,14 @@ FILE /dataClasses.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL Any SET_BACKING_FIELD x type=kotlin.Unit operator=null - GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER + receiver: THIS public final data class Test1 type=Test1 + value: GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER SET_BACKING_FIELD y type=kotlin.Unit operator=null - GET_VAR y type=kotlin.String operator=INITIALIZE_PROPERTY_FROM_PARAMETER + receiver: THIS public final data class Test1 type=Test1 + value: GET_VAR y type=kotlin.String operator=INITIALIZE_PROPERTY_FROM_PARAMETER SET_BACKING_FIELD z type=kotlin.Unit operator=null - GET_VAR z type=kotlin.Any operator=INITIALIZE_PROPERTY_FROM_PARAMETER + receiver: THIS public final data class Test1 type=Test1 + value: GET_VAR z type=kotlin.Any operator=INITIALIZE_PROPERTY_FROM_PARAMETER INSTANCE_INITIALIZER_CALL classDescriptor=Test1 PROPERTY public final val x: kotlin.Int EXPRESSION_BODY diff --git a/compiler/testData/ir/irText/classes/enum.txt b/compiler/testData/ir/irText/classes/enum.txt index c34dca3175b..cc95dee6d4b 100644 --- a/compiler/testData/ir/irText/classes/enum.txt +++ b/compiler/testData/ir/irText/classes/enum.txt @@ -17,7 +17,8 @@ FILE /enum.kt BLOCK_BODY ENUM_CONSTRUCTOR_CALL Enum super SET_BACKING_FIELD x type=kotlin.Unit operator=null - GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER + receiver: THIS public final enum class TestEnum2 : kotlin.Enum type=TestEnum2 + value: GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER INSTANCE_INITIALIZER_CALL classDescriptor=TestEnum2 PROPERTY public final val x: kotlin.Int EXPRESSION_BODY @@ -61,7 +62,8 @@ FILE /enum.kt BLOCK_BODY ENUM_CONSTRUCTOR_CALL Enum super SET_BACKING_FIELD x type=kotlin.Unit operator=null - GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER + receiver: THIS public final enum class TestEnum4 : kotlin.Enum type=TestEnum4 + value: GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER INSTANCE_INITIALIZER_CALL classDescriptor=TestEnum4 PROPERTY public final val x: kotlin.Int EXPRESSION_BODY @@ -90,7 +92,8 @@ FILE /enum.kt ANONYMOUS_INITIALIZER TEST2 BLOCK_BODY SET_BACKING_FIELD z type=kotlin.Unit operator=null - CALL . type=kotlin.Int operator=GET_PROPERTY + receiver: THIS enum entry TEST2 type=TestEnum4.TEST2 + value: CALL . type=kotlin.Int operator=GET_PROPERTY $this: THIS enum entry TEST2 type=TestEnum4.TEST2 FUN public open override /*1*/ fun foo(): kotlin.Unit BLOCK_BODY diff --git a/compiler/testData/ir/irText/classes/initBlock.txt b/compiler/testData/ir/irText/classes/initBlock.txt index 303381dcf91..3160f8bd7bf 100644 --- a/compiler/testData/ir/irText/classes/initBlock.txt +++ b/compiler/testData/ir/irText/classes/initBlock.txt @@ -12,7 +12,8 @@ FILE /initBlock.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL Any SET_BACKING_FIELD x type=kotlin.Unit operator=null - GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER + receiver: THIS public final class Test2 type=Test2 + value: GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER INSTANCE_INITIALIZER_CALL classDescriptor=Test2 PROPERTY public final val x: kotlin.Int EXPRESSION_BODY diff --git a/compiler/testData/ir/irText/classes/initVal.txt b/compiler/testData/ir/irText/classes/initVal.txt index fa24906b30f..04bd89eda99 100644 --- a/compiler/testData/ir/irText/classes/initVal.txt +++ b/compiler/testData/ir/irText/classes/initVal.txt @@ -4,7 +4,8 @@ FILE /initVal.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL Any SET_BACKING_FIELD x type=kotlin.Unit operator=null - GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER + receiver: THIS public final class TestInitValFromParameter type=TestInitValFromParameter + value: GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER INSTANCE_INITIALIZER_CALL classDescriptor=TestInitValFromParameter PROPERTY public final val x: kotlin.Int EXPRESSION_BODY @@ -26,4 +27,5 @@ FILE /initVal.kt ANONYMOUS_INITIALIZER TestInitValInInitBlock BLOCK_BODY SET_BACKING_FIELD x type=kotlin.Unit operator=null - CONST Int type=kotlin.Int value='0' + receiver: THIS public final class TestInitValInInitBlock type=TestInitValInInitBlock + value: CONST Int type=kotlin.Int value='0' diff --git a/compiler/testData/ir/irText/classes/initVar.txt b/compiler/testData/ir/irText/classes/initVar.txt index 512e855c741..6742c692852 100644 --- a/compiler/testData/ir/irText/classes/initVar.txt +++ b/compiler/testData/ir/irText/classes/initVar.txt @@ -4,7 +4,8 @@ FILE /initVar.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL Any SET_BACKING_FIELD x type=kotlin.Unit operator=null - GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER + receiver: THIS public final class TestInitVarFromParameter type=TestInitVarFromParameter + value: GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER INSTANCE_INITIALIZER_CALL classDescriptor=TestInitVarFromParameter PROPERTY public final var x: kotlin.Int EXPRESSION_BODY @@ -39,13 +40,13 @@ FILE /initVar.kt PROPERTY_SETTER public final fun (/*0*/ value: kotlin.Int): kotlin.Unit BLOCK_BODY SET_BACKING_FIELD x type=kotlin.Unit operator=EQ - GET_VAR value type=kotlin.Int operator=null + value: GET_VAR value type=kotlin.Int operator=null CLASS CLASS TestInitVarWithCustomSetterWithExplicitCtor PROPERTY public final var x: kotlin.Int PROPERTY_SETTER public final fun (/*0*/ value: kotlin.Int): kotlin.Unit BLOCK_BODY SET_BACKING_FIELD x type=kotlin.Unit operator=EQ - GET_VAR value type=kotlin.Int operator=null + value: GET_VAR value type=kotlin.Int operator=null ANONYMOUS_INITIALIZER TestInitVarWithCustomSetterWithExplicitCtor BLOCK_BODY CALL . type=kotlin.Unit operator=EQ @@ -60,7 +61,7 @@ FILE /initVar.kt PROPERTY_SETTER public final fun (/*0*/ value: kotlin.Int): kotlin.Unit BLOCK_BODY SET_BACKING_FIELD x type=kotlin.Unit operator=EQ - GET_VAR value type=kotlin.Int operator=null + value: GET_VAR value type=kotlin.Int operator=null CONSTRUCTOR public constructor TestInitVarWithCustomSetterInCtor() BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL Any diff --git a/compiler/testData/ir/irText/classes/objectWithInitializers.txt b/compiler/testData/ir/irText/classes/objectWithInitializers.txt index d6893f2964f..bdb687fb8f6 100644 --- a/compiler/testData/ir/irText/classes/objectWithInitializers.txt +++ b/compiler/testData/ir/irText/classes/objectWithInitializers.txt @@ -16,5 +16,6 @@ FILE /objectWithInitializers.kt ANONYMOUS_INITIALIZER Test BLOCK_BODY SET_BACKING_FIELD y type=kotlin.Unit operator=null - CALL . type=kotlin.Int operator=GET_PROPERTY + receiver: THIS public object Test : Base type=Test + value: CALL . type=kotlin.Int operator=GET_PROPERTY $this: THIS public object Test : Base type=Test diff --git a/compiler/testData/ir/irText/classes/primaryConstructor.txt b/compiler/testData/ir/irText/classes/primaryConstructor.txt index 33b8b16042d..04580cf0013 100644 --- a/compiler/testData/ir/irText/classes/primaryConstructor.txt +++ b/compiler/testData/ir/irText/classes/primaryConstructor.txt @@ -4,9 +4,11 @@ FILE /primaryConstructor.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL Any SET_BACKING_FIELD x type=kotlin.Unit operator=null - GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER + receiver: THIS public final class Test1 type=Test1 + value: GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER SET_BACKING_FIELD y type=kotlin.Unit operator=null - GET_VAR y type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER + receiver: THIS public final class Test1 type=Test1 + value: GET_VAR y type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER INSTANCE_INITIALIZER_CALL classDescriptor=Test1 PROPERTY public final val x: kotlin.Int EXPRESSION_BODY @@ -19,7 +21,8 @@ FILE /primaryConstructor.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL Any SET_BACKING_FIELD y type=kotlin.Unit operator=null - GET_VAR y type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER + receiver: THIS public final class Test2 type=Test2 + value: GET_VAR y type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER INSTANCE_INITIALIZER_CALL classDescriptor=Test2 PROPERTY public final val y: kotlin.Int EXPRESSION_BODY @@ -32,7 +35,8 @@ FILE /primaryConstructor.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL Any SET_BACKING_FIELD y type=kotlin.Unit operator=null - GET_VAR y type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER + receiver: THIS public final class Test3 type=Test3 + value: GET_VAR y type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER INSTANCE_INITIALIZER_CALL classDescriptor=Test3 PROPERTY public final val y: kotlin.Int EXPRESSION_BODY @@ -41,4 +45,5 @@ FILE /primaryConstructor.kt ANONYMOUS_INITIALIZER Test3 BLOCK_BODY SET_BACKING_FIELD x type=kotlin.Unit operator=null - GET_VAR x type=kotlin.Int operator=null + receiver: THIS public final class Test3 type=Test3 + value: GET_VAR x type=kotlin.Int operator=null diff --git a/compiler/testData/ir/irText/classes/primaryConstructorWithSuperConstructorCall.txt b/compiler/testData/ir/irText/classes/primaryConstructorWithSuperConstructorCall.txt index b06bdee5d87..926a58cd624 100644 --- a/compiler/testData/ir/irText/classes/primaryConstructorWithSuperConstructorCall.txt +++ b/compiler/testData/ir/irText/classes/primaryConstructorWithSuperConstructorCall.txt @@ -19,9 +19,11 @@ FILE /primaryConstructorWithSuperConstructorCall.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL Base SET_BACKING_FIELD x type=kotlin.Unit operator=null - GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER + receiver: THIS public final class TestWithDelegatingConstructor : Base type=TestWithDelegatingConstructor + value: GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER SET_BACKING_FIELD y type=kotlin.Unit operator=null - GET_VAR y type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER + receiver: THIS public final class TestWithDelegatingConstructor : Base type=TestWithDelegatingConstructor + value: GET_VAR y type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER INSTANCE_INITIALIZER_CALL classDescriptor=TestWithDelegatingConstructor PROPERTY public final val x: kotlin.Int EXPRESSION_BODY diff --git a/compiler/testData/ir/irText/classes/sealedClasses.txt b/compiler/testData/ir/irText/classes/sealedClasses.txt index d5668a96f5f..1b4285596d4 100644 --- a/compiler/testData/ir/irText/classes/sealedClasses.txt +++ b/compiler/testData/ir/irText/classes/sealedClasses.txt @@ -9,7 +9,8 @@ FILE /sealedClasses.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL Expr SET_BACKING_FIELD number type=kotlin.Unit operator=null - GET_VAR number type=kotlin.Double operator=INITIALIZE_PROPERTY_FROM_PARAMETER + receiver: THIS public final class Const : Expr type=Expr.Const + value: GET_VAR number type=kotlin.Double operator=INITIALIZE_PROPERTY_FROM_PARAMETER INSTANCE_INITIALIZER_CALL classDescriptor=Const PROPERTY public final val number: kotlin.Double EXPRESSION_BODY @@ -19,9 +20,11 @@ FILE /sealedClasses.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL Expr SET_BACKING_FIELD e1 type=kotlin.Unit operator=null - GET_VAR e1 type=Expr operator=INITIALIZE_PROPERTY_FROM_PARAMETER + receiver: THIS public final class Sum : Expr type=Expr.Sum + value: GET_VAR e1 type=Expr operator=INITIALIZE_PROPERTY_FROM_PARAMETER SET_BACKING_FIELD e2 type=kotlin.Unit operator=null - GET_VAR e2 type=Expr operator=INITIALIZE_PROPERTY_FROM_PARAMETER + receiver: THIS public final class Sum : Expr type=Expr.Sum + value: GET_VAR e2 type=Expr operator=INITIALIZE_PROPERTY_FROM_PARAMETER INSTANCE_INITIALIZER_CALL classDescriptor=Sum PROPERTY public final val e1: Expr EXPRESSION_BODY diff --git a/compiler/testData/ir/irText/classes/secondaryConstructorWithInitializersFromClassBody.txt b/compiler/testData/ir/irText/classes/secondaryConstructorWithInitializersFromClassBody.txt index c85754859aa..94e36f3b8d6 100644 --- a/compiler/testData/ir/irText/classes/secondaryConstructorWithInitializersFromClassBody.txt +++ b/compiler/testData/ir/irText/classes/secondaryConstructorWithInitializersFromClassBody.txt @@ -17,7 +17,8 @@ FILE /secondaryConstructorWithInitializersFromClassBody.kt ANONYMOUS_INITIALIZER TestInitBlock BLOCK_BODY SET_BACKING_FIELD x type=kotlin.Unit operator=null - CONST Int type=kotlin.Int value='0' + receiver: THIS public final class TestInitBlock : Base type=TestInitBlock + value: CONST Int type=kotlin.Int value='0' CONSTRUCTOR public constructor TestInitBlock() BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL Base diff --git a/compiler/testData/ir/irText/declarations/delegatedProperties.txt b/compiler/testData/ir/irText/declarations/delegatedProperties.txt index ea402a4efae..8c8ddf1d0b1 100644 --- a/compiler/testData/ir/irText/declarations/delegatedProperties.txt +++ b/compiler/testData/ir/irText/declarations/delegatedProperties.txt @@ -21,7 +21,8 @@ FILE /delegatedProperties.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL Any SET_BACKING_FIELD map type=kotlin.Unit operator=null - GET_VAR map type=kotlin.collections.MutableMap operator=INITIALIZE_PROPERTY_FROM_PARAMETER + receiver: THIS public final class C type=C + value: GET_VAR map type=kotlin.collections.MutableMap operator=INITIALIZE_PROPERTY_FROM_PARAMETER INSTANCE_INITIALIZER_CALL classDescriptor=C PROPERTY public final val map: kotlin.collections.MutableMap EXPRESSION_BODY @@ -41,6 +42,7 @@ FILE /delegatedProperties.kt RETURN type=kotlin.Nothing from= CALL .getValue type=kotlin.Int operator=null $receiver: GET_BACKING_FIELD test2$delegate type=kotlin.Lazy operator=null + receiver: THIS public final class C type=C thisRef: THIS public final class C type=C property: CALLABLE_REFERENCE test2 type=kotlin.reflect.KProperty1 operator=PROPERTY_REFERENCE_FOR_DELEGATE PROPERTY public final var test3: kotlin.Any @@ -53,6 +55,7 @@ FILE /delegatedProperties.kt RETURN type=kotlin.Nothing from= CALL .getValue type=kotlin.Any operator=null $receiver: GET_BACKING_FIELD test3$delegate type=kotlin.collections.MutableMap operator=null + receiver: THIS public final class C type=C thisRef: THIS public final class C type=C property: CALLABLE_REFERENCE test3 type=kotlin.reflect.KMutableProperty1 operator=PROPERTY_REFERENCE_FOR_DELEGATE PROPERTY_SETTER public final fun (/*0*/ : kotlin.Any): kotlin.Unit @@ -60,6 +63,7 @@ FILE /delegatedProperties.kt RETURN type=kotlin.Nothing from= CALL .setValue type=kotlin.Unit operator=null $receiver: GET_BACKING_FIELD test3$delegate type=kotlin.collections.MutableMap operator=null + receiver: THIS public final class C type=C thisRef: THIS public final class C type=C property: CALLABLE_REFERENCE test3 type=kotlin.reflect.KMutableProperty1 operator=PROPERTY_REFERENCE_FOR_DELEGATE value: GET_VAR type=kotlin.Any operator=null diff --git a/compiler/testData/ir/irText/expressions/arrayAugmentedAssignment1.txt b/compiler/testData/ir/irText/expressions/arrayAugmentedAssignment1.txt index e9b8d019515..6c5d4974b72 100644 --- a/compiler/testData/ir/irText/expressions/arrayAugmentedAssignment1.txt +++ b/compiler/testData/ir/irText/expressions/arrayAugmentedAssignment1.txt @@ -16,7 +16,8 @@ FILE /arrayAugmentedAssignment1.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL Any SET_BACKING_FIELD x type=kotlin.Unit operator=null - GET_VAR x type=kotlin.IntArray operator=INITIALIZE_PROPERTY_FROM_PARAMETER + receiver: THIS public final class C type=C + value: GET_VAR x type=kotlin.IntArray operator=INITIALIZE_PROPERTY_FROM_PARAMETER INSTANCE_INITIALIZER_CALL classDescriptor=C PROPERTY public final val x: kotlin.IntArray EXPRESSION_BODY diff --git a/compiler/testData/ir/irText/expressions/assignments.txt b/compiler/testData/ir/irText/expressions/assignments.txt index 6099b8f5194..c9007196bad 100644 --- a/compiler/testData/ir/irText/expressions/assignments.txt +++ b/compiler/testData/ir/irText/expressions/assignments.txt @@ -4,7 +4,8 @@ FILE /assignments.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL Any SET_BACKING_FIELD x type=kotlin.Unit operator=null - GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER + receiver: THIS public final class Ref type=Ref + value: GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER INSTANCE_INITIALIZER_CALL classDescriptor=Ref PROPERTY public final var x: kotlin.Int EXPRESSION_BODY diff --git a/compiler/testData/ir/irText/expressions/complexAugmentedAssignment.txt b/compiler/testData/ir/irText/expressions/complexAugmentedAssignment.txt index 9d1567f75a6..4120e972f2f 100644 --- a/compiler/testData/ir/irText/expressions/complexAugmentedAssignment.txt +++ b/compiler/testData/ir/irText/expressions/complexAugmentedAssignment.txt @@ -93,7 +93,8 @@ FILE /complexAugmentedAssignment.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL Any SET_BACKING_FIELD s type=kotlin.Unit operator=null - GET_VAR s type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER + receiver: THIS public final class B type=B + value: GET_VAR s type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER INSTANCE_INITIALIZER_CALL classDescriptor=B PROPERTY public final var s: kotlin.Int EXPRESSION_BODY diff --git a/compiler/testData/ir/irText/expressions/destructuring1.kt b/compiler/testData/ir/irText/expressions/destructuring1.kt index e726afb8027..6b3f5aabcfd 100644 --- a/compiler/testData/ir/irText/expressions/destructuring1.kt +++ b/compiler/testData/ir/irText/expressions/destructuring1.kt @@ -5,6 +5,6 @@ object B { operator fun A.component2() = 2 } -fun B.test() { // <<< destructuring1.txt +fun B.test() { val (x, y) = A } \ No newline at end of file diff --git a/compiler/testData/ir/irText/expressions/destructuring1.txt b/compiler/testData/ir/irText/expressions/destructuring1.txt index 00321f3b307..7f1feedeb75 100644 --- a/compiler/testData/ir/irText/expressions/destructuring1.txt +++ b/compiler/testData/ir/irText/expressions/destructuring1.txt @@ -1,13 +1,32 @@ -FUN public fun B.test(): kotlin.Unit - BLOCK_BODY - BLOCK type=kotlin.Unit operator=DESTRUCTURING_DECLARATION - VAR val tmp0_container: A - GET_OBJECT A type=A - VAR val x: kotlin.Int - CALL .component1 type=kotlin.Int operator=COMPONENT_N(index=1) - $this: $RECEIVER of: test type=B - $receiver: GET_VAR tmp0_container type=A operator=null - VAR val y: kotlin.Int - CALL .component2 type=kotlin.Int operator=COMPONENT_N(index=2) - $this: $RECEIVER of: test type=B - $receiver: GET_VAR tmp0_container type=A operator=null +FILE /destructuring1.kt + CLASS OBJECT A + CONSTRUCTOR private constructor A() + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL Any + INSTANCE_INITIALIZER_CALL classDescriptor=A + CLASS OBJECT B + CONSTRUCTOR private constructor B() + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL Any + INSTANCE_INITIALIZER_CALL classDescriptor=B + FUN public final operator fun A.component1(): kotlin.Int + BLOCK_BODY + RETURN type=kotlin.Nothing from=component1 + CONST Int type=kotlin.Int value='1' + FUN public final operator fun A.component2(): kotlin.Int + BLOCK_BODY + RETURN type=kotlin.Nothing from=component2 + CONST Int type=kotlin.Int value='2' + FUN public fun B.test(): kotlin.Unit + BLOCK_BODY + BLOCK type=kotlin.Unit operator=DESTRUCTURING_DECLARATION + VAR val tmp0_container: A + GET_OBJECT A type=A + VAR val x: kotlin.Int + CALL .component1 type=kotlin.Int operator=COMPONENT_N(index=1) + $this: $RECEIVER of: test type=B + $receiver: GET_VAR tmp0_container type=A operator=null + VAR val y: kotlin.Int + CALL .component2 type=kotlin.Int operator=COMPONENT_N(index=2) + $this: $RECEIVER of: test type=B + $receiver: GET_VAR tmp0_container type=A operator=null diff --git a/compiler/testData/ir/irText/expressions/field.txt b/compiler/testData/ir/irText/expressions/field.txt index e5095f2bf8e..9372b6e9886 100644 --- a/compiler/testData/ir/irText/expressions/field.txt +++ b/compiler/testData/ir/irText/expressions/field.txt @@ -5,13 +5,13 @@ FILE /field.kt PROPERTY_SETTER public fun (/*0*/ value: kotlin.Int): kotlin.Unit BLOCK_BODY SET_BACKING_FIELD testSimple type=kotlin.Unit operator=EQ - GET_VAR value type=kotlin.Int operator=null + value: GET_VAR value type=kotlin.Int operator=null PROPERTY public var testAugmented: kotlin.Int EXPRESSION_BODY CONST Int type=kotlin.Int value='0' PROPERTY_SETTER public fun (/*0*/ value: kotlin.Int): kotlin.Unit BLOCK_BODY SET_BACKING_FIELD testAugmented type=kotlin.Unit operator=PLUSEQ - CALL .plus type=kotlin.Int operator=PLUSEQ + value: CALL .plus type=kotlin.Int operator=PLUSEQ $this: GET_BACKING_FIELD testAugmented type=kotlin.Int operator=PLUSEQ other: GET_VAR value type=kotlin.Int operator=null diff --git a/compiler/testData/ir/irText/expressions/forWithImplicitReceivers.txt b/compiler/testData/ir/irText/expressions/forWithImplicitReceivers.txt index 754cb36f880..161c714b35f 100644 --- a/compiler/testData/ir/irText/expressions/forWithImplicitReceivers.txt +++ b/compiler/testData/ir/irText/expressions/forWithImplicitReceivers.txt @@ -9,7 +9,8 @@ FILE /forWithImplicitReceivers.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL Any SET_BACKING_FIELD value type=kotlin.Unit operator=null - GET_VAR value type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER + receiver: THIS public final class IntCell type=IntCell + value: GET_VAR value type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER INSTANCE_INITIALIZER_CALL classDescriptor=IntCell PROPERTY public final var value: kotlin.Int EXPRESSION_BODY diff --git a/compiler/testData/ir/irText/expressions/jvmInstanceFieldReference.kt b/compiler/testData/ir/irText/expressions/jvmInstanceFieldReference.kt new file mode 100644 index 00000000000..6ddcd1bf0f3 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/jvmInstanceFieldReference.kt @@ -0,0 +1,19 @@ +// FILE: Derived.kt +// IR_FILE: jvmInstanceFieldReference.txt +class Derived: Base() { + init { + value = 0 + } + + fun getValue() = value + + fun setValue(value: Int) { + this.value = value + } +} + +// FILE: Base.java +public class Base { + public int value; +} + diff --git a/compiler/testData/ir/irText/expressions/jvmInstanceFieldReference.txt b/compiler/testData/ir/irText/expressions/jvmInstanceFieldReference.txt new file mode 100644 index 00000000000..e683f9d5a39 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/jvmInstanceFieldReference.txt @@ -0,0 +1,21 @@ +FILE /Derived.kt + CLASS CLASS Derived + CONSTRUCTOR public constructor Derived() + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL Base + INSTANCE_INITIALIZER_CALL classDescriptor=Derived + ANONYMOUS_INITIALIZER Derived + BLOCK_BODY + SET_BACKING_FIELD value type=kotlin.Unit operator=EQ + receiver: THIS public final class Derived : Base type=Derived + value: CONST Int type=kotlin.Int value='0' + FUN public final fun getValue(): kotlin.Int + BLOCK_BODY + RETURN type=kotlin.Nothing from=getValue + GET_BACKING_FIELD value type=kotlin.Int operator=GET_PROPERTY + receiver: THIS public final class Derived : Base type=Derived + FUN public final fun setValue(/*0*/ value: kotlin.Int): kotlin.Unit + BLOCK_BODY + SET_BACKING_FIELD value type=kotlin.Unit operator=EQ + receiver: THIS public final class Derived : Base type=Derived + value: GET_VAR value type=kotlin.Int operator=null diff --git a/compiler/testData/ir/irText/expressions/jvmStaticFieldReference.txt b/compiler/testData/ir/irText/expressions/jvmStaticFieldReference.txt index 34cef009b21..98f845dfe30 100644 --- a/compiler/testData/ir/irText/expressions/jvmStaticFieldReference.txt +++ b/compiler/testData/ir/irText/expressions/jvmStaticFieldReference.txt @@ -3,14 +3,14 @@ FILE /jvmStaticFieldReference.kt BLOCK_BODY CALL .println type=kotlin.Unit operator=null $this: TYPE_OP operator=IMPLICIT_NOTNULL typeOperand=java.io.PrintStream - CALL . type=java.io.PrintStream! operator=GET_PROPERTY + GET_BACKING_FIELD out type=java.io.PrintStream! operator=GET_PROPERTY p0: CONST String type=kotlin.String value='testFun' PROPERTY public var testProp: kotlin.Any PROPERTY_GETTER public fun (): kotlin.Any BLOCK_BODY CALL .println type=kotlin.Unit operator=null $this: TYPE_OP operator=IMPLICIT_NOTNULL typeOperand=java.io.PrintStream - CALL . type=java.io.PrintStream! operator=GET_PROPERTY + GET_BACKING_FIELD out type=java.io.PrintStream! operator=GET_PROPERTY p0: CONST String type=kotlin.String value='testProp/get' RETURN type=kotlin.Nothing from= CONST Int type=kotlin.Int value='42' @@ -18,7 +18,7 @@ FILE /jvmStaticFieldReference.kt BLOCK_BODY CALL .println type=kotlin.Unit operator=null $this: TYPE_OP operator=IMPLICIT_NOTNULL typeOperand=java.io.PrintStream - CALL . type=java.io.PrintStream! operator=GET_PROPERTY + GET_BACKING_FIELD out type=java.io.PrintStream! operator=GET_PROPERTY p0: CONST String type=kotlin.String value='testProp/set' CLASS CLASS TestClass CONSTRUCTOR public constructor TestClass() @@ -31,12 +31,12 @@ FILE /jvmStaticFieldReference.kt else: BLOCK type=kotlin.Int operator=null CALL .println type=kotlin.Unit operator=null $this: TYPE_OP operator=IMPLICIT_NOTNULL typeOperand=java.io.PrintStream - CALL . type=java.io.PrintStream! operator=GET_PROPERTY + GET_BACKING_FIELD out type=java.io.PrintStream! operator=GET_PROPERTY p0: CONST String type=kotlin.String value='TestClass/test' CONST Int type=kotlin.Int value='42' ANONYMOUS_INITIALIZER TestClass BLOCK_BODY CALL .println type=kotlin.Unit operator=null $this: TYPE_OP operator=IMPLICIT_NOTNULL typeOperand=java.io.PrintStream - CALL . type=java.io.PrintStream! operator=GET_PROPERTY + GET_BACKING_FIELD out type=java.io.PrintStream! operator=GET_PROPERTY p0: CONST String type=kotlin.String value='TestClass/init' diff --git a/compiler/testData/ir/irText/expressions/safeCalls.txt b/compiler/testData/ir/irText/expressions/safeCalls.txt index 141ff55f2e1..41debf39ad7 100644 --- a/compiler/testData/ir/irText/expressions/safeCalls.txt +++ b/compiler/testData/ir/irText/expressions/safeCalls.txt @@ -4,7 +4,8 @@ FILE /safeCalls.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL Any SET_BACKING_FIELD value type=kotlin.Unit operator=null - GET_VAR value type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER + receiver: THIS public final class Ref type=Ref + value: GET_VAR value type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER INSTANCE_INITIALIZER_CALL classDescriptor=Ref PROPERTY public final var value: kotlin.Int EXPRESSION_BODY diff --git a/compiler/testData/ir/irText/expressions/setFieldWithImplicitCast.kt b/compiler/testData/ir/irText/expressions/setFieldWithImplicitCast.kt new file mode 100644 index 00000000000..d33f11e38a1 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/setFieldWithImplicitCast.kt @@ -0,0 +1,14 @@ +// FILE: Derived.kt +// IR_FILE: setFieldWithImplicitCast.txt +class Derived : Base() { + fun setValue(v: Any) { + if (v is String) { + value = v + } + } +} + +// FILE: Base.java +public class Base { + public String value; +} diff --git a/compiler/testData/ir/irText/expressions/setFieldWithImplicitCast.txt b/compiler/testData/ir/irText/expressions/setFieldWithImplicitCast.txt new file mode 100644 index 00000000000..2e05ee0eb34 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/setFieldWithImplicitCast.txt @@ -0,0 +1,16 @@ +FILE /Derived.kt + CLASS CLASS Derived + CONSTRUCTOR public constructor Derived() + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL Base + INSTANCE_INITIALIZER_CALL classDescriptor=Derived + FUN public final fun setValue(/*0*/ v: kotlin.Any): kotlin.Unit + BLOCK_BODY + WHEN type=kotlin.Unit operator=IF + if: TYPE_OP operator=INSTANCEOF typeOperand=kotlin.String + GET_VAR v type=kotlin.Any operator=null + then: BLOCK type=kotlin.Unit operator=null + SET_BACKING_FIELD value type=kotlin.Unit operator=EQ + receiver: THIS public final class Derived : Base type=Derived + value: TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.String! + GET_VAR v type=kotlin.Any operator=null diff --git a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java index ba0bca5e01b..0ca3ac8ffa3 100644 --- a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java @@ -424,6 +424,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase { doTest(fileName); } + @TestMetadata("jvmInstanceFieldReference.kt") + public void testJvmInstanceFieldReference() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/jvmInstanceFieldReference.kt"); + doTest(fileName); + } + @TestMetadata("jvmStaticFieldReference.kt") public void testJvmStaticFieldReference() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/jvmStaticFieldReference.kt"); @@ -466,6 +472,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase { doTest(fileName); } + @TestMetadata("setFieldWithImplicitCast.kt") + public void testSetFieldWithImplicitCast() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/setFieldWithImplicitCast.kt"); + doTest(fileName); + } + @TestMetadata("simpleOperators.kt") public void testSimpleOperators() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/simpleOperators.kt");