From 4ccf3c3590285d9115f2ce4cf805835897a2d9a3 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Thu, 11 Aug 2016 17:17:05 +0300 Subject: [PATCH] Refactor calls and related expressions --- .../kotlin/psi2ir/IrDeclarationGenerator.kt | 2 +- .../kotlin/psi2ir/IrExpressionGenerator.kt | 93 ++++++++------- .../ir/{util/PairList.kt => IrBuiltIns.kt} | 16 +-- .../ir/expressions/IrArgumentIndices.kt | 24 ++++ .../jetbrains/kotlin/ir/expressions/IrBody.kt | 10 +- .../kotlin/ir/expressions/IrCallExpression.kt | 54 ++------- .../ir/expressions/IrCallableOperator.kt | 69 ----------- .../ir/expressions/IrCompoundExpression.kt | 56 ++++++++- .../ir/expressions/IrDeclarationReference.kt | 40 ++----- .../kotlin/ir/expressions/IrExpression.kt | 8 +- .../ir/expressions/IrExpressionOwner.kt | 9 +- .../ir/expressions/IrGetVariableExpression.kt | 50 ++++++++ .../expressions/IrMemberAccessExpression.kt | 46 ++++++++ .../kotlin/ir/expressions/IrOperator.kt | 63 ++++++++++ .../ir/expressions/IrOperatorExpression.kt | 53 +++++++++ .../expressions/IrPropertyAccessExpression.kt | 111 ++++++++++++++++++ .../ir/expressions/IrReturnExpression.kt | 4 +- .../expressions/IrTypeOperatorExpression.kt | 7 +- .../jetbrains/kotlin/ir/util/DumpIrTree.kt | 20 +++- .../kotlin/ir/util/RenderIrElement.kt | 25 ++-- .../kotlin/ir/visitors/IrElementVisitor.kt | 20 +++- compiler/testData/ir/irText/calls.txt | 16 +-- compiler/testData/ir/irText/dotQualified.txt | 8 +- .../ir/irText/extensionPropertyGetterCall.txt | 2 +- compiler/testData/ir/irText/references.txt | 12 +- 25 files changed, 561 insertions(+), 257 deletions(-) rename compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/{util/PairList.kt => IrBuiltIns.kt} (56%) create mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrArgumentIndices.kt delete mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrCallableOperator.kt create mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrGetVariableExpression.kt create mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrMemberAccessExpression.kt create mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrOperator.kt create mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrOperatorExpression.kt create mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrPropertyAccessExpression.kt diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrDeclarationGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrDeclarationGenerator.kt index 787de47fd2d..d1f8c682005 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrDeclarationGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrDeclarationGenerator.kt @@ -106,6 +106,6 @@ abstract class IrDeclarationGeneratorBase( IrReturnExpressionImpl(startOffset, endOffset, irExpression.type) .apply { returnedExpression = irExpression } - return IrExpressionBodyImpl(startOffset, endOffset, containingDeclaration).apply { childExpression = bodyExpression } + return IrExpressionBodyImpl(startOffset, endOffset, containingDeclaration).apply { argument = bodyExpression } } } \ No newline at end of file diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrExpressionGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrExpressionGenerator.kt index db85ee46c22..3239d8e7511 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrExpressionGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrExpressionGenerator.kt @@ -53,7 +53,7 @@ class IrExpressionGenerator( return IrTypeOperatorExpressionImpl( ktElement.startOffset, ktElement.endOffset, smartCastType, IrTypeOperator.SMART_AS, smartCastType - ).apply { childExpression = this@smartCastIfNeeded } + ).apply { argument = this@smartCastIfNeeded } } } return this @@ -70,7 +70,7 @@ class IrExpressionGenerator( override fun visitReturnExpression(expression: KtReturnExpression, data: Nothing?): IrExpression = IrReturnExpressionImpl(expression.startOffset, expression.endOffset, expression.type()) - .apply { this.childExpression = expression.returnedExpression?.generate() } + .apply { this.argument = expression.returnedExpression?.generate() } override fun visitConstantExpression(expression: KtConstantExpression, data: Nothing?): IrExpression { val compileTimeConstant = ConstantExpressionEvaluator.getConstant(expression, context.bindingContext) @@ -112,21 +112,22 @@ class IrExpressionGenerator( return when (descriptor) { is ClassDescriptor -> - IrSingletonReferenceImpl(expression.startOffset, expression.endOffset, expression.type(), - descriptor.singletonDescriptor() ?: TODO("Unsupported class as value: ${descriptor.name}")) + if (DescriptorUtils.isObject(descriptor)) + IrGetObjectValueExpressionImpl(expression.startOffset, expression.endOffset, expression.type(), descriptor) + else if (DescriptorUtils.isEnumEntry(descriptor)) + IrGetEnumValueExpressionImpl(expression.startOffset, expression.endOffset, expression.type(), descriptor) + else + IrGetObjectValueExpressionImpl(expression.startOffset, expression.endOffset, expression.type(), + descriptor.companionObjectDescriptor ?: error("Class value without companion object: $descriptor")) is PropertyDescriptor -> { - generateCall( - expression, - resolvedCall ?: TODO("Property, no resolved call: ${descriptor.name}"), - IrCallableOperator.PROPERTY_GET - ) + generateCall(expression, resolvedCall ?: TODO("Property, no resolved call: ${descriptor.name}"), null) } is VariableDescriptor -> - IrVariableReferenceImpl(expression.startOffset, expression.endOffset, expression.type(), descriptor) + IrGetVariableExpressionImpl(expression.startOffset, expression.endOffset, expression.type(), descriptor) else -> IrDummyExpression(expression.startOffset, expression.endOffset, expression.type(), - expression.getReferencedName() + - ": ${descriptor?.name} ${descriptor?.javaClass?.simpleName}") + expression.getReferencedName() + + ": ${descriptor?.name} ${descriptor?.javaClass?.simpleName}") } } @@ -150,35 +151,47 @@ class IrExpressionGenerator( val referenceTarget = getOrFail(BindingContext.REFERENCE_TARGET, expression.instanceReference) { "No reference target for this" } return when (referenceTarget) { is ClassDescriptor -> - IrThisExpressionImpl(expression.startOffset, expression.endOffset, expression.type(), referenceTarget) + IrThisExpressionImpl(expression.startOffset, expression.endOffset, expression.type(), referenceTarget) is CallableDescriptor -> - IrExtensionReceiverReferenceImpl(expression.startOffset, expression.endOffset, expression.type(), referenceTarget) + IrGetExtensionReceiverExpressionImpl(expression.startOffset, expression.endOffset, expression.type(), + referenceTarget.extensionReceiverParameter!!) else -> - error("Expected this or receiver: $referenceTarget") + error("Expected this or receiver: $referenceTarget") } } private fun generateCall( ktExpression: KtExpression, resolvedCall: ResolvedCall, - operator: IrCallableOperator?, + operator: IrOperator? = null, superQualifier: ClassDescriptor? = null - ): IrExpression = - IrCallExpressionImpl( - ktExpression.startOffset, ktExpression.endOffset, ktExpression.type(), - resolvedCall.resultingDescriptor, resolvedCall.call.isSafeCall(), operator, superQualifier - ).apply { - dispatchReceiver = generateReceiver(ktExpression, resolvedCall.dispatchReceiver) - extensionReceiver = generateReceiver(ktExpression, resolvedCall.extensionReceiver) - - val valueParameters = resolvedCall.resultingDescriptor.valueParameters - val valueArguments = resolvedCall.valueArgumentsByIndex ?: TODO("null for value arguments: ${ktExpression.text}") - for (index in valueArguments.indices) { - val valueArgument = valueArguments[index] - val valueParameter = valueParameters[index] - putValueArgument(valueParameter, generateValueArgument(valueParameter, valueArgument)) + ): IrExpression { + val descriptor = resolvedCall.resultingDescriptor + return when (descriptor) { + is PropertyDescriptor -> + IrGetPropertyExpressionImpl( + ktExpression.startOffset, ktExpression.endOffset, ktExpression.type(), + resolvedCall.call.isSafeCall(), descriptor + ) + else -> + IrCallExpressionImpl( + ktExpression.startOffset, ktExpression.endOffset, ktExpression.type(), + resolvedCall.resultingDescriptor, resolvedCall.call.isSafeCall(), operator, superQualifier + ).apply { + val valueParameters = resolvedCall.resultingDescriptor.valueParameters + val valueArguments = resolvedCall.valueArgumentsByIndex ?: TODO("null for value arguments: ${ktExpression.text}") + for (index in valueArguments.indices) { + val valueArgument = valueArguments[index] + val valueParameter = valueParameters[index] + putValueArgument(valueParameter, generateValueArgument(valueParameter, valueArgument)) + } } - } + + }.apply { + dispatchReceiver = generateReceiver(ktExpression, resolvedCall.dispatchReceiver) + extensionReceiver = generateReceiver(ktExpression, resolvedCall.extensionReceiver) + } + } private fun generateReceiver(ktExpression: KtExpression, receiver: ReceiverValue?): IrExpression? = when (receiver) { @@ -191,11 +204,11 @@ class IrExpressionGenerator( is ExpressionReceiver -> receiver.expression.generate() is ClassValueReceiver -> - IrSingletonReferenceImpl(receiver.expression.startOffset, receiver.expression.endOffset, receiver.type, - receiver.classQualifier.descriptor) + IrGetObjectValueExpressionImpl(receiver.expression.startOffset, receiver.expression.endOffset, receiver.type, + receiver.classQualifier.descriptor) is ExtensionReceiver -> - IrExtensionReceiverReferenceImpl(ktExpression.startOffset, ktExpression.startOffset, receiver.type, - receiver.declarationDescriptor.extensionReceiverParameter!!) + IrGetExtensionReceiverExpressionImpl(ktExpression.startOffset, ktExpression.startOffset, receiver.type, + receiver.declarationDescriptor.extensionReceiverParameter!!) null -> null else -> @@ -211,14 +224,4 @@ class IrExpressionGenerator( TODO("vararg") } } - - companion object { - fun ClassDescriptor.singletonDescriptor(): ClassDescriptor? = - if (DescriptorUtils.isObject(this) || DescriptorUtils.isEnumEntry(this)) - this - else - companionObjectDescriptor - - - } } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/PairList.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrBuiltIns.kt similarity index 56% rename from compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/PairList.kt rename to compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrBuiltIns.kt index 923ff32824e..06cda0a2c92 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/PairList.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrBuiltIns.kt @@ -14,20 +14,10 @@ * limitations under the License. */ -package org.jetbrains.kotlin.ir.util +package org.jetbrains.kotlin.ir -import java.util.* +import org.jetbrains.kotlin.builtins.KotlinBuiltIns -class PairListImpl(val first: T, val second: T) : AbstractList() { - override val size: Int get() = 2 +class IrBuiltIns(val builtIns: KotlinBuiltIns) { - override fun get(index: Int): T = - when (index) { - 0 -> first - 1 -> second - else -> throw IndexOutOfBoundsException(index.toString()) - } } - -fun pairList(first: T, second: T): List = - PairListImpl(first, second) \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrArgumentIndices.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrArgumentIndices.kt new file mode 100644 index 00000000000..e9631ffb93e --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrArgumentIndices.kt @@ -0,0 +1,24 @@ +/* + * 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.expressions + +const val DETACHED_INDEX = Int.MIN_VALUE +const val CHILD_EXPRESSION_INDEX = 0 +const val ARGUMENT0_INDEX = 0 +const val ARGUMENT1_INDEX = 1 +const val DISPATCH_RECEIVER_INDEX = -1 +const val EXTENSION_RECEIVER_INDEX = -2 diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrBody.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrBody.kt index 2c998097fc6..c6ab45ffbe3 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrBody.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrBody.kt @@ -34,19 +34,19 @@ class IrExpressionBodyImpl( endOffset: Int, override val parent: IrDeclaration ) : IrDeclarationOwnerBase(startOffset, endOffset), IrExpressionBody { - override var childExpression: IrExpression? = null + override var argument: IrExpression? = null set(newExpression) { field?.detach() field = newExpression - newExpression?.setTreeLocation(this, IrExpressionOwner1.EXPRESSION_INDEX) + newExpression?.setTreeLocation(this, CHILD_EXPRESSION_INDEX) } override fun getChildExpression(index: Int): IrExpression? = - if (index == IrExpressionOwner1.EXPRESSION_INDEX) childExpression else null + if (index == CHILD_EXPRESSION_INDEX) argument else null override fun replaceChildExpression(oldChild: IrExpression, newChild: IrExpression) { validateChild(oldChild) - childExpression = newChild + argument = newChild } override fun accept(visitor: IrElementVisitor, data: D): R = @@ -57,6 +57,6 @@ class IrExpressionBodyImpl( } override fun acceptChildExpressions(visitor: IrElementVisitor, data: D) { - childExpression?.accept(visitor, data) + argument?.accept(visitor, data) } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrCallExpression.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrCallExpression.kt index 89822a003c4..eb664deef3a 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrCallExpression.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrCallExpression.kt @@ -22,13 +22,10 @@ import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.types.KotlinType -interface IrCallExpression : IrCompoundExpression { +interface IrCallExpression : IrMemberAccessExpression, IrCompoundExpression { val superQualifier: ClassDescriptor? - val operator: IrCallableOperator? - val isSafe: Boolean - val callee: CallableDescriptor - var dispatchReceiver: IrExpression? - var extensionReceiver: IrExpression? + val operator: IrOperator? + override val descriptor: CallableDescriptor fun getValueArgument(valueParameterDescriptor: ValueParameterDescriptor): IrExpression? fun putValueArgument(valueParameterDescriptor: ValueParameterDescriptor, valueArgument: IrExpression?) @@ -38,33 +35,19 @@ interface IrCallExpression : IrCompoundExpression { } fun IrCallExpression.getMappedValueArguments(): List = - callee.valueParameters.mapNotNull { getValueArgument(it) } + descriptor.valueParameters.mapNotNull { getValueArgument(it) } -abstract class IrCallExpressionBase( +class IrCallExpressionImpl( startOffset: Int, endOffset: Int, type: KotlinType, - override final val callee: CallableDescriptor, - override val isSafe: Boolean, - override val operator: IrCallableOperator?, + override val descriptor: CallableDescriptor, + isSafe: Boolean, + override val operator: IrOperator?, override val superQualifier: ClassDescriptor? -) : IrExpressionBase(startOffset, endOffset, type), IrCallExpression { +) : IrMemberAccessExpressionBase(startOffset, endOffset, type, isSafe), IrCallExpression { private val argumentsByParameterIndex = - kotlin.arrayOfNulls(callee.valueParameters.size) - - override var dispatchReceiver: IrExpression? = null - set(newReceiver) { - field?.detach() - field = newReceiver - newReceiver?.setTreeLocation(this, DISPATCH_RECEIVER_INDEX) - } - - override var extensionReceiver: IrExpression? = null - set(newReceiver) { - field?.detach() - field = newReceiver - newReceiver?.setTreeLocation(this, EXTENSION_RECEIVER_INDEX) - } + kotlin.arrayOfNulls(descriptor.valueParameters.size) override fun getValueArgument(valueParameterDescriptor: ValueParameterDescriptor): IrExpression? = argumentsByParameterIndex[valueParameterDescriptor.index] @@ -122,21 +105,6 @@ abstract class IrCallExpressionBase( acceptChildExpressions(visitor, data) } - companion object { - const val DISPATCH_RECEIVER_INDEX = -1 - const val EXTENSION_RECEIVER_INDEX = -2 - } -} - -class IrCallExpressionImpl( - startOffset: Int, - endOffset: Int, - type: KotlinType, - callee: CallableDescriptor, - isSafe: Boolean, - operator: IrCallableOperator? = null, - superQualifier: ClassDescriptor? = null -) : IrCallExpressionBase(startOffset, endOffset, type, callee, isSafe, operator, superQualifier), IrCallExpression { override fun accept(visitor: IrElementVisitor, data: D): R = visitor.visitCallExpression(this, data) -} \ No newline at end of file +} diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrCallableOperator.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrCallableOperator.kt deleted file mode 100644 index db4d3b1767e..00000000000 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrCallableOperator.kt +++ /dev/null @@ -1,69 +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.expressions - -enum class IrCallableOperator { - PROPERTY_GET, - PROPERTY_SET, - INVOKE, - INVOKE_EXTENSION, - PLUSPLUS, - MINUSMINUS, - UMINUS, - EXCL, - LT, - GT, - LTEQ, - GTEQ, - EQEQ, - EQEQEQ, - EXCLEQ, - EXCLEQEQ, - IN, - NOT_IN, - ANDAND, - OROR, - RANGE, - PLUS, - MINUS, - MUL, - DIV, - MOD, - PLUSEQ, - MINUSEQ, - MULEQ, - DIVEQ, - MODEQ; -} - -fun IrCallableOperator.isCompoundAssignment(): Boolean = - this >= IrCallableOperator.PLUSEQ && this <= IrCallableOperator.MODEQ - -fun IrCallableOperator.hasCompoundAssignmentDual(): Boolean = - this >= IrCallableOperator.PLUS && this <= IrCallableOperator.MOD - -fun IrCallableOperator.toDualOperator(): IrCallableOperator = - when { - isCompoundAssignment() -> - IrCallableOperator.values()[this.ordinal - IrCallableOperator.PLUSEQ.ordinal + IrCallableOperator.PLUS.ordinal] - hasCompoundAssignmentDual() -> - IrCallableOperator.values()[this.ordinal - IrCallableOperator.PLUS.ordinal + IrCallableOperator.PLUSEQ.ordinal] - else -> - throw UnsupportedOperationException("Operator $this is not a compound assignment") - } - - diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrCompoundExpression.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrCompoundExpression.kt index 72bac8549a3..e2880e00324 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrCompoundExpression.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrCompoundExpression.kt @@ -24,6 +24,8 @@ interface IrCompoundExpression : IrExpression, IrExpressionOwner interface IrCompoundExpression1 : IrCompoundExpression, IrExpressionOwner1 +interface IrCompoundExpression2 : IrCompoundExpression, IrExpressionOwner2 + interface IrCompoundExpressionN : IrCompoundExpression, IrExpressionOwnerN abstract class IrCompoundExpressionNBase( @@ -72,19 +74,19 @@ abstract class IrCompoundExpression1Base( endOffset: Int, override val type: KotlinType ) : IrExpressionBase(startOffset, endOffset, type), IrCompoundExpression1 { - override var childExpression: IrExpression? = null + override var argument: IrExpression? = null set(newExpression) { field?.detach() field = newExpression - newExpression?.setTreeLocation(this, IrExpressionOwner1.EXPRESSION_INDEX) + newExpression?.setTreeLocation(this, ARGUMENT0_INDEX) } override fun getChildExpression(index: Int): IrExpression? = - if (index == IrExpressionOwner1.EXPRESSION_INDEX) childExpression else null + if (index == ARGUMENT0_INDEX) argument else null override fun replaceChildExpression(oldChild: IrExpression, newChild: IrExpression) { validateChild(oldChild) - childExpression = newChild + argument = newChild } override fun acceptChildren(visitor: IrElementVisitor, data: D) { @@ -92,6 +94,50 @@ abstract class IrCompoundExpression1Base( } override fun acceptChildExpressions(visitor: IrElementVisitor, data: D) { - childExpression?.accept(visitor, data) + argument?.accept(visitor, data) + } +} + +abstract class IrCompoundExpression2Base( + startOffset: Int, + endOffset: Int, + override val type: KotlinType +) : IrExpressionBase(startOffset, endOffset, type), IrCompoundExpression2 { + override var argument0: IrExpression? = null + set(newExpression) { + field?.detach() + field = newExpression + newExpression?.setTreeLocation(this, ARGUMENT0_INDEX) + } + + override var argument1: IrExpression? = null + set(newExpression) { + field?.detach() + field = newExpression + newExpression?.setTreeLocation(this, ARGUMENT1_INDEX) + } + + override fun getChildExpression(index: Int): IrExpression? = + when (index) { + ARGUMENT0_INDEX -> argument0 + ARGUMENT1_INDEX -> argument1 + else -> null + } + + override fun replaceChildExpression(oldChild: IrExpression, newChild: IrExpression) { + validateChild(oldChild) + when (oldChild.index) { + ARGUMENT0_INDEX -> argument0 = newChild + ARGUMENT1_INDEX -> argument1 = newChild + } + } + + override fun acceptChildren(visitor: IrElementVisitor, data: D) { + acceptChildExpressions(visitor, data) + } + + override fun acceptChildExpressions(visitor: IrElementVisitor, data: D) { + argument0?.accept(visitor, data) + argument1?.accept(visitor, data) } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrDeclarationReference.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrDeclarationReference.kt index aaaac125528..bc4c19dd434 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrDeclarationReference.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrDeclarationReference.kt @@ -16,7 +16,8 @@ package org.jetbrains.kotlin.ir.expressions -import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.types.KotlinType @@ -25,17 +26,13 @@ interface IrDeclarationReference : IrExpression { val descriptor: DeclarationDescriptor } -interface IrVariableReference : IrDeclarationReference { - override val descriptor: VariableDescriptor -} - -interface IrSingletonReference : IrDeclarationReference { +interface IrGetSingletonValueExpression : IrDeclarationReference { override val descriptor: ClassDescriptor } -interface IrExtensionReceiverReference : IrDeclarationReference { - override val descriptor: CallableDescriptor -} +interface IrGetObjectValueExpression : IrGetSingletonValueExpression + +interface IrGetEnumValueExpression : IrGetSingletonValueExpression abstract class IrDeclarationReferenceBase( startOffset: Int, @@ -44,34 +41,23 @@ abstract class IrDeclarationReferenceBase( override val descriptor: D ) : IrTerminalExpressionBase(startOffset, endOffset, type), IrDeclarationReference -class IrVariableReferenceImpl( - startOffset: Int, - endOffset: Int, - type: KotlinType, - descriptor: VariableDescriptor -) : IrDeclarationReferenceBase(startOffset, endOffset, type, descriptor), IrVariableReference { - override fun accept(visitor: IrElementVisitor, data: D): R = - visitor.visitVariableReference(this, data) -} - -class IrSingletonReferenceImpl( +class IrGetObjectValueExpressionImpl( startOffset: Int, endOffset: Int, type: KotlinType, descriptor: ClassDescriptor -) : IrDeclarationReferenceBase(startOffset, endOffset, type, descriptor), IrSingletonReference { +) : IrDeclarationReferenceBase(startOffset, endOffset, type, descriptor), IrGetObjectValueExpression { override fun accept(visitor: IrElementVisitor, data: D): R = - visitor.visitSingletonReference(this, data) + visitor.visitGetObjectValue(this, data) } - -class IrExtensionReceiverReferenceImpl( +class IrGetEnumValueExpressionImpl( startOffset: Int, endOffset: Int, type: KotlinType, - override val descriptor: CallableDescriptor -) : IrTerminalExpressionBase(startOffset, endOffset, type), IrExtensionReceiverReference { + descriptor: ClassDescriptor +) : IrDeclarationReferenceBase(startOffset, endOffset, type, descriptor), IrGetEnumValueExpression { override fun accept(visitor: IrElementVisitor, data: D): R { - return visitor.visitExtensionReceiverReference(this, data) + return visitor.visitGetEnumValue(this, data) } } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrExpression.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrExpression.kt index c94cf68f4b9..3bad8880e8a 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrExpression.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrExpression.kt @@ -28,14 +28,10 @@ interface IrExpression : IrElement { val type: KotlinType fun setTreeLocation(parent: IrExpressionOwner?, index: Int) - - companion object { - const val DETACHED_INDEX = Int.MIN_VALUE - } } fun IrExpression.detach() { - setTreeLocation(null, IrExpression.DETACHED_INDEX) + setTreeLocation(null, DETACHED_INDEX) } fun IrExpressionOwner.validateChild(child: IrExpression) { @@ -48,7 +44,7 @@ abstract class IrExpressionBase( override val type: KotlinType ) : IrElementBase(startOffset, endOffset), IrExpression { override var parent: IrExpressionOwner? = null - override var index: Int = IrExpression.DETACHED_INDEX + override var index: Int = DETACHED_INDEX override fun setTreeLocation(parent: IrExpressionOwner?, index: Int) { this.parent = parent diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrExpressionOwner.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrExpressionOwner.kt index bcfe3ea64d9..b45b406f480 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrExpressionOwner.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrExpressionOwner.kt @@ -26,11 +26,12 @@ interface IrExpressionOwner : IrElement { } interface IrExpressionOwner1 : IrExpressionOwner { - var childExpression: IrExpression? + var argument: IrExpression? +} - companion object { - const val EXPRESSION_INDEX = 0 - } +interface IrExpressionOwner2 : IrExpressionOwner { + var argument0: IrExpression? + var argument1: IrExpression? } interface IrExpressionOwnerN : IrExpressionOwner { diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrGetVariableExpression.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrGetVariableExpression.kt new file mode 100644 index 00000000000..f98b766a09e --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrGetVariableExpression.kt @@ -0,0 +1,50 @@ +/* + * 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.expressions + +import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.descriptors.VariableDescriptor +import org.jetbrains.kotlin.ir.visitors.IrElementVisitor +import org.jetbrains.kotlin.types.KotlinType + +interface IrGetVariableExpression : IrDeclarationReference { + override val descriptor: VariableDescriptor +} + +interface IrGetExtensionReceiverExpression : IrDeclarationReference { + override val descriptor: CallableDescriptor +} + +class IrGetVariableExpressionImpl( + startOffset: Int, + endOffset: Int, + type: KotlinType, + descriptor: VariableDescriptor +) : IrDeclarationReferenceBase(startOffset, endOffset, type, descriptor), IrGetVariableExpression { + override fun accept(visitor: IrElementVisitor, data: D): R = + visitor.visitGetVariable(this, data) +} + +class IrGetExtensionReceiverExpressionImpl( + startOffset: Int, + endOffset: Int, + type: KotlinType, + override val descriptor: CallableDescriptor +) : IrTerminalExpressionBase(startOffset, endOffset, type), IrGetExtensionReceiverExpression { + override fun accept(visitor: IrElementVisitor, data: D): R = + visitor.visitGetExtensionReceiver(this, data) +} \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrMemberAccessExpression.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrMemberAccessExpression.kt new file mode 100644 index 00000000000..dc6e9d34c77 --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrMemberAccessExpression.kt @@ -0,0 +1,46 @@ +/* + * 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.expressions + +import org.jetbrains.kotlin.types.KotlinType + +interface IrMemberAccessExpression : IrDeclarationReference, IrExpressionOwner { + var dispatchReceiver: IrExpression? + var extensionReceiver: IrExpression? + val isSafe: Boolean +} + +abstract class IrMemberAccessExpressionBase( + startOffset: Int, + endOffset: Int, + type: KotlinType, + override val isSafe: Boolean +) : IrExpressionBase(startOffset, endOffset, type), IrMemberAccessExpression { + override var dispatchReceiver: IrExpression? = null + set(newReceiver) { + field?.detach() + field = newReceiver + newReceiver?.setTreeLocation(this, DISPATCH_RECEIVER_INDEX) + } + + override var extensionReceiver: IrExpression? = null + set(newReceiver) { + field?.detach() + field = newReceiver + newReceiver?.setTreeLocation(this, EXTENSION_RECEIVER_INDEX) + } +} diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrOperator.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrOperator.kt new file mode 100644 index 00000000000..fbb125e9940 --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrOperator.kt @@ -0,0 +1,63 @@ +/* + * 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.expressions + +enum class IrOperator { + INVOKE, INVOKE_EXTENSION, + PREFIX_INCR, PREFIX_DECR, POSTFIX_INCR, POSTFIX_DECR, + UMINUS, + EXCL, + EXCLEXCL, + LT, GT, LTEQ, GTEQ, + EQEQ, EQEQEQ, EXCLEQ, EXCLEQEQ, + IN, NOT_IN, + ANDAND, OROR, + RANGE, + PLUS, MINUS, MUL, DIV, MOD, + EQ, + PLUSEQ, MINUSEQ, MULEQ, DIVEQ, MODEQ; +} + +private val CAO_START = IrOperator.PLUSEQ +private val CAO_END = IrOperator.MODEQ +private val DUAL_START = IrOperator.PLUS +private val DUAL_END = IrOperator.MOD +private val INCR_DECR_START = IrOperator.PREFIX_INCR +private val INCR_DECR_END = IrOperator.POSTFIX_DECR + +fun IrOperator.isIncrementOrDecrement(): Boolean = + this in INCR_DECR_START..INCR_DECR_END + +fun IrOperator.isCompoundAssignment(): Boolean = + this in CAO_START .. CAO_END + +fun IrOperator.isAssignmentOrCompoundAssignment(): Boolean = + this == IrOperator.EQ || isCompoundAssignment() + +fun IrOperator.hasCompoundAssignmentDual(): Boolean = + this in DUAL_START .. DUAL_END + +fun IrOperator.toDualOperator(): IrOperator = + when { + isCompoundAssignment() -> + IrOperator.values()[this.ordinal - CAO_START.ordinal + DUAL_START.ordinal] + hasCompoundAssignmentDual() -> + IrOperator.values()[this.ordinal - DUAL_START.ordinal + CAO_START.ordinal] + else -> + throw UnsupportedOperationException("Operator $this is not a compound assignment") + } + diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrOperatorExpression.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrOperatorExpression.kt new file mode 100644 index 00000000000..0442505796f --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrOperatorExpression.kt @@ -0,0 +1,53 @@ +/* + * 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.expressions + +import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.ir.visitors.IrElementVisitor +import org.jetbrains.kotlin.types.KotlinType + +interface IrOperatorExpression : IrExpression { + val operator: IrOperator + val relatedDescriptor: FunctionDescriptor? +} + +interface IrUnaryOperatorExpression : IrOperatorExpression, IrCompoundExpression1 + +interface IrBinaryOperatorExpression : IrOperatorExpression, IrCompoundExpression2 + +class IrUnaryOperatorExpressionImpl( + startOffset: Int, + endOffset: Int, + type: KotlinType, + override val operator: IrOperator, + override val relatedDescriptor: FunctionDescriptor? +) : IrCompoundExpression1Base(startOffset, endOffset, type), IrUnaryOperatorExpression { + override fun accept(visitor: IrElementVisitor, data: D): R { + return visitor.visitUnaryOperator(this, data) + } +} + +class IrBinaryOperatorExpressionImpl( + startOffset: Int, + endOffset: Int, + type: KotlinType, + override val operator: IrOperator, + override val relatedDescriptor: FunctionDescriptor? +) : IrCompoundExpression2Base(startOffset, endOffset, type), IrBinaryOperatorExpression { + override fun accept(visitor: IrElementVisitor, data: D): R = + visitor.visitBinaryOperator(this, data) +} diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrPropertyAccessExpression.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrPropertyAccessExpression.kt new file mode 100644 index 00000000000..ccb5db195d4 --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrPropertyAccessExpression.kt @@ -0,0 +1,111 @@ +/* + * 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.expressions + +import org.jetbrains.kotlin.descriptors.PropertyDescriptor +import org.jetbrains.kotlin.ir.visitors.IrElementVisitor +import org.jetbrains.kotlin.types.KotlinType + +interface IrPropertyAccessExpression : IrMemberAccessExpression { + override val descriptor: PropertyDescriptor +} + +interface IrGetPropertyExpression : IrPropertyAccessExpression + +interface IrSetPropertyExpression : IrPropertyAccessExpression, IrCompoundExpression1 + +class IrGetPropertyExpressionImpl( + startOffset: Int, + endOffset: Int, + type: KotlinType, + isSafe: Boolean, + override val descriptor: PropertyDescriptor +) : IrMemberAccessExpressionBase(startOffset, endOffset, type, isSafe), IrGetPropertyExpression { + override fun accept(visitor: IrElementVisitor, data: D): R { + return visitor.visitGetProperty(this, data) + } + + override fun acceptChildren(visitor: IrElementVisitor, data: D) { + acceptChildExpressions(visitor, data) + } + + override fun acceptChildExpressions(visitor: IrElementVisitor, data: D) { + dispatchReceiver?.accept(visitor, data) + extensionReceiver?.accept(visitor, data) + } + + override fun getChildExpression(index: Int): IrExpression? = + when (index) { + DISPATCH_RECEIVER_INDEX -> dispatchReceiver + EXTENSION_RECEIVER_INDEX -> extensionReceiver + else -> null + } + + override fun replaceChildExpression(oldChild: IrExpression, newChild: IrExpression) { + validateChild(oldChild) + when (oldChild.index) { + DISPATCH_RECEIVER_INDEX -> dispatchReceiver = newChild + EXTENSION_RECEIVER_INDEX -> extensionReceiver = newChild + } + } +} + +class IrSetPropertyExpressionImpl( + startOffset: Int, + endOffset: Int, + type: KotlinType, + isSafe: Boolean, + override val descriptor: PropertyDescriptor +) : IrMemberAccessExpressionBase(startOffset, endOffset, type, isSafe), IrSetPropertyExpression { + override var argument: IrExpression? = null + set(value) { + field?.detach() + field = value + value?.setTreeLocation(this, ARGUMENT0_INDEX) + } + + override fun accept(visitor: IrElementVisitor, data: D): R { + return visitor.visitSetProperty(this, data) + } + + override fun acceptChildren(visitor: IrElementVisitor, data: D) { + acceptChildExpressions(visitor, data) + } + + override fun acceptChildExpressions(visitor: IrElementVisitor, data: D) { + dispatchReceiver?.accept(visitor, data) + extensionReceiver?.accept(visitor, data) + argument?.accept(visitor, data) + } + + override fun getChildExpression(index: Int): IrExpression? = + when (index) { + DISPATCH_RECEIVER_INDEX -> dispatchReceiver + EXTENSION_RECEIVER_INDEX -> extensionReceiver + ARGUMENT0_INDEX -> argument + else -> null + } + + override fun replaceChildExpression(oldChild: IrExpression, newChild: IrExpression) { + validateChild(oldChild) + when (oldChild.index) { + DISPATCH_RECEIVER_INDEX -> dispatchReceiver = newChild + EXTENSION_RECEIVER_INDEX -> extensionReceiver = newChild + ARGUMENT0_INDEX -> argument = newChild + } + } +} diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrReturnExpression.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrReturnExpression.kt index c0d0f9d88b4..9105cc26e57 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrReturnExpression.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrReturnExpression.kt @@ -23,9 +23,9 @@ import org.jetbrains.kotlin.types.KotlinType interface IrReturnExpression : IrCompoundExpression1 var IrReturnExpression.returnedExpression: IrExpression? - get() = childExpression + get() = argument set(newReturnedExpression) { - childExpression = newReturnedExpression + argument = newReturnedExpression } class IrReturnExpressionImpl( diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrTypeOperatorExpression.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrTypeOperatorExpression.kt index 0b399e0b053..cf3547d7882 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrTypeOperatorExpression.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrTypeOperatorExpression.kt @@ -20,10 +20,11 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.types.KotlinType enum class IrTypeOperator { - SMART_AS, AS, - AS_SAFE, - IS; + SMART_AS, + SAFE_AS, + IS, + NOT_IS; } interface IrTypeOperatorExpression : IrExpression, IrCompoundExpression1 { 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 36415bae8c4..4f90d33080e 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 @@ -18,9 +18,10 @@ package org.jetbrains.kotlin.ir.util import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.SourceLocationManager -import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.expressions.IrCallExpression +import org.jetbrains.kotlin.ir.expressions.IrGetPropertyExpression +import org.jetbrains.kotlin.ir.expressions.IrSetPropertyExpression import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.utils.Printer @@ -48,12 +49,27 @@ class DumpIrTreeVisitor(out: Appendable): IrElementVisitor { expression.dumpLabeledElementWith(data) { expression.dispatchReceiver?.accept(this, "\$this") expression.extensionReceiver?.accept(this, "\$receiver") - for (valueParameter in expression.callee.valueParameters) { + for (valueParameter in expression.descriptor.valueParameters) { expression.getValueArgument(valueParameter)?.accept(this, valueParameter.name.asString()) } } } + override fun visitGetProperty(expression: IrGetPropertyExpression, data: String) { + expression.dumpLabeledElementWith(data) { + expression.dispatchReceiver?.accept(this, "\$this") + expression.extensionReceiver?.accept(this, "\$receiver") + } + } + + override fun visitSetProperty(expression: IrSetPropertyExpression, data: String) { + expression.dumpLabeledElementWith(data) { + expression.dispatchReceiver?.accept(this, "\$this") + expression.extensionReceiver?.accept(this, "\$receiver") + expression.argument?.accept(this, "\$value") + } + } + private inline fun IrElement.dumpLabeledElementWith(label: String, body: () -> Unit) { printer.println(accept(elementRenderer, null).withLabel(label)) indented(body) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt index 2e58b8fb6ee..fbe0efcc8d9 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt @@ -63,20 +63,29 @@ class RenderIrElementVisitor : IrElementVisitor { override fun visitReturnExpression(expression: IrReturnExpression, data: Nothing?): String = "RETURN type=${expression.renderType()}" - override fun visitVariableReference(expression: IrVariableReference, data: Nothing?): String = - "VAR ${expression.descriptor.name}" - - override fun visitSingletonReference(expression: IrSingletonReference, data: Nothing?): String = - "SINGLETON ${expression.descriptor.name}" - - override fun visitExtensionReceiverReference(expression: IrExtensionReceiverReference, data: Nothing?): String = + override fun visitGetExtensionReceiver(expression: IrGetExtensionReceiverExpression, data: Nothing?): String = "\$RECEIVER of: ${expression.descriptor.containingDeclaration.name}" override fun visitThisExpression(expression: IrThisExpression, data: Nothing?): String = "THIS ${expression.classDescriptor.render()}" override fun visitCallExpression(expression: IrCallExpression, data: Nothing?): String = - "CALL ${if (expression.isSafe) "?." else "."}${expression.callee.name} ${expression.operator ?: ""}" + "CALL ${if (expression.isSafe) "?." else "."}${expression.descriptor.name} ${expression.operator ?: ""}" + + override fun visitGetProperty(expression: IrGetPropertyExpression, data: Nothing?): String = + "GET_PROPERTY ${if (expression.isSafe) "?." else "."}${expression.descriptor.name}" + + override fun visitGetVariable(expression: IrGetVariableExpression, data: Nothing?): String = + "GET_VAR ${expression.descriptor.name}" + + override fun visitGetObjectValue(expression: IrGetObjectValueExpression, data: Nothing?): String = + "GET_OBJECT ${expression.descriptor.name}" + + override fun visitGetEnumValue(expression: IrGetEnumValueExpression, data: Nothing?): String = + "GET_ENUM_VALUE ${expression.descriptor.name}" + + override fun visitSetProperty(expression: IrSetPropertyExpression, data: Nothing?): String = + "SET_PROPERTY ${if (expression.isSafe) "?." else "."}${expression.descriptor.name}" override fun visitDummyExpression(expression: IrDummyExpression, data: Nothing?): String = "DUMMY ${expression.description}" 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 54c990975d5..33b096b2692 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 @@ -44,17 +44,27 @@ interface IrElementVisitor { fun visitBlockExpression(expression: IrBlockExpression, data: D): R = visitExpression(expression, data) fun visitStringTemplate(expression: IrStringConcatenationExpression, data: D) = visitExpression(expression, data) fun visitThisExpression(expression: IrThisExpression, data: D) = visitExpression(expression, data) + fun visitDeclarationReference(expression: IrDeclarationReference, data: D) = visitExpression(expression, data) - fun visitVariableReference(expression: IrVariableReference, data: D) = visitDeclarationReference(expression, data) - fun visitSingletonReference(expression: IrSingletonReference, data: D) = visitDeclarationReference(expression, data) - fun visitExtensionReceiverReference(expression: IrExtensionReceiverReference, data: D) = visitDeclarationReference(expression, data) + fun visitGetObjectValue(expression: IrGetObjectValueExpression, data: D) = visitDeclarationReference(expression, data) + fun visitGetEnumValue(expression: IrGetEnumValueExpression, data: D) = visitDeclarationReference(expression, data) + fun visitGetVariable(expression: IrGetVariableExpression, data: D) = visitDeclarationReference(expression, data) + fun visitGetExtensionReceiver(expression: IrGetExtensionReceiverExpression, data: D) = visitDeclarationReference(expression, data) + fun visitMemberAccess(expression: IrMemberAccessExpression, data: D) = visitDeclarationReference(expression, data) + fun visitCallExpression(expression: IrCallExpression, data: D) = visitMemberAccess(expression, data) + fun visitPropertyAccess(expression: IrPropertyAccessExpression, data: D) = visitMemberAccess(expression, data) + fun visitGetProperty(expression: IrGetPropertyExpression, data: D) = visitPropertyAccess(expression, data) + fun visitSetProperty(expression: IrSetPropertyExpression, data: D) = visitPropertyAccess(expression, data) - - fun visitCallExpression(expression: IrCallExpression, data: D) = visitExpression(expression, data) + fun visitOperatorExpression(expression: IrOperatorExpression, data: D) = visitExpression(expression, data) + fun visitUnaryOperator(expression: IrUnaryOperatorExpression, data: D) = visitOperatorExpression(expression, data) + fun visitBinaryOperator(expression: IrBinaryOperatorExpression, data: D) = visitOperatorExpression(expression, data) fun visitTypeOperatorExpression(expression: IrTypeOperatorExpression, data: D) = visitExpression(expression, data) // NB Use it only for testing purposes; will be removed as soon as all Kotlin expression types are covered fun visitDummyExpression(expression: IrDummyExpression, data: D) = visitExpression(expression, data) + + } diff --git a/compiler/testData/ir/irText/calls.txt b/compiler/testData/ir/irText/calls.txt index c6034d1f3a5..972d270351b 100644 --- a/compiler/testData/ir/irText/calls.txt +++ b/compiler/testData/ir/irText/calls.txt @@ -2,28 +2,28 @@ IrFile /calls.kt IrFunction public fun foo(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int): kotlin.Int IrExpressionBody RETURN type=kotlin.Int - VAR x + GET_VAR x IrFunction public fun bar(/*0*/ x: kotlin.Int): kotlin.Int IrExpressionBody RETURN type=kotlin.Int CALL .foo - x: VAR x + x: GET_VAR x y: LITERAL Int type=kotlin.Int value='1' IrFunction public fun qux(/*0*/ x: kotlin.Int): kotlin.Int IrExpressionBody RETURN type=kotlin.Int CALL .foo x: CALL .foo - x: VAR x - y: VAR x - y: VAR x + x: GET_VAR x + y: GET_VAR x + y: GET_VAR x IrFunction public fun kotlin.Int.ext1(): kotlin.Int IrExpressionBody RETURN type=kotlin.Int - $RECEIVER of: + $RECEIVER of: ext1 IrFunction public fun kotlin.Int.ext2(/*0*/ x: kotlin.Int): kotlin.Int IrExpressionBody RETURN type=kotlin.Int CALL .foo - x: $RECEIVER of: - y: VAR x + x: $RECEIVER of: ext2 + y: GET_VAR x diff --git a/compiler/testData/ir/irText/dotQualified.txt b/compiler/testData/ir/irText/dotQualified.txt index b6c5769e686..ae2978f6991 100644 --- a/compiler/testData/ir/irText/dotQualified.txt +++ b/compiler/testData/ir/irText/dotQualified.txt @@ -2,10 +2,10 @@ IrFile /dotQualified.kt IrFunction public fun length(/*0*/ s: kotlin.String): kotlin.Int IrExpressionBody RETURN type=kotlin.Int - CALL .length PROPERTY_GET - $this: VAR s + GET_PROPERTY .length + $this: GET_VAR s IrFunction public fun lengthN(/*0*/ s: kotlin.String?): kotlin.Int? IrExpressionBody RETURN type=kotlin.Int? - CALL ?.length PROPERTY_GET - $this: VAR s + GET_PROPERTY ?.length + $this: GET_VAR s diff --git a/compiler/testData/ir/irText/extensionPropertyGetterCall.txt b/compiler/testData/ir/irText/extensionPropertyGetterCall.txt index a7c0d845efe..32b26ee83b6 100644 --- a/compiler/testData/ir/irText/extensionPropertyGetterCall.txt +++ b/compiler/testData/ir/irText/extensionPropertyGetterCall.txt @@ -7,5 +7,5 @@ IrFile /extensionPropertyGetterCall.kt IrFunction public fun kotlin.String.test5(): kotlin.String IrExpressionBody RETURN type=kotlin.String - CALL .okext PROPERTY_GET + GET_PROPERTY .okext $receiver: $RECEIVER of: test5 diff --git a/compiler/testData/ir/irText/references.txt b/compiler/testData/ir/irText/references.txt index dfce09ab2b8..6da12582631 100644 --- a/compiler/testData/ir/irText/references.txt +++ b/compiler/testData/ir/irText/references.txt @@ -6,7 +6,7 @@ IrFile /references.kt IrProperty public val ok2: kotlin.String = "OK" getter=null setter=null IrExpressionBody RETURN type=kotlin.String - CALL .ok PROPERTY_GET + GET_PROPERTY .ok IrProperty public val ok3: kotlin.String getter= setter=null IrPropertyGetter public fun (): kotlin.String property=ok3 IrExpressionBody @@ -15,21 +15,21 @@ IrFile /references.kt IrFunction public fun test1(): kotlin.String IrExpressionBody RETURN type=kotlin.String - CALL .ok PROPERTY_GET + GET_PROPERTY .ok IrFunction public fun test2(/*0*/ x: kotlin.String): kotlin.String IrExpressionBody RETURN type=kotlin.String - VAR x + GET_VAR x IrFunction public fun test3(): kotlin.String IrExpressionBody BLOCK type=kotlin.Nothing DUMMY KtProperty RETURN type=kotlin.Nothing - VAR x + GET_VAR x IrFunction public fun test4(): kotlin.String IrExpressionBody RETURN type=kotlin.String - CALL .ok3 PROPERTY_GET + GET_PROPERTY .ok3 IrProperty public val kotlin.String.okext: kotlin.String getter= setter=null IrPropertyGetter public fun kotlin.String.(): kotlin.String property=okext IrExpressionBody @@ -38,5 +38,5 @@ IrFile /references.kt IrFunction public fun kotlin.String.test5(): kotlin.String IrExpressionBody RETURN type=kotlin.String - CALL .okext PROPERTY_GET + GET_PROPERTY .okext $receiver: $RECEIVER of: test5