From 8d86c0a2dd2a5b7217d7f68bdd8fd976f35e2cb2 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Mon, 29 Aug 2016 17:35:38 +0300 Subject: [PATCH] Representation for nested initializers in a class & nested initializers call. --- .../kotlin/psi2ir/generators/CallGenerator.kt | 2 +- .../src/org/jetbrains/kotlin/ir/IrSlots.kt | 3 +- .../kotlin/ir/declarations/IrClass.kt | 33 ++++++++-- .../jetbrains/kotlin/ir/expressions/IrCall.kt | 22 +++---- .../IrDelegatingConstructorCall.kt | 35 +++++++++++ .../kotlin/ir/expressions/IrFunCall.kt | 38 +++++++++++ .../ir/expressions/IrInitializeProperty.kt | 63 ------------------- .../expressions/IrNestedInitializersCall.kt | 32 ++++++++++ .../kotlin/ir/expressions/IrPrimitiveCall.kt | 10 ++- .../ir/expressions/IrPropertyAccessorCall.kt | 8 +-- .../kotlin/ir/util/RenderIrElement.kt | 10 +-- .../kotlin/ir/visitors/IrElementVisitor.kt | 5 +- 12 files changed, 162 insertions(+), 99 deletions(-) create mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrDelegatingConstructorCall.kt create mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrFunCall.kt delete mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrInitializeProperty.kt create mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrNestedInitializersCall.kt 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 179816bbfd5..92c3d72d358 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 @@ -87,7 +87,7 @@ class CallGenerator( val returnType = descriptor.returnType!! return call.callReceiver.call { dispatchReceiverValue, extensionReceiverValue -> - val irCall = IrCallImpl(startOffset, endOffset, returnType, descriptor, operator, call.superQualifier) + val irCall = IrFunCallImpl(startOffset, endOffset, returnType, descriptor, operator, call.superQualifier) irCall.dispatchReceiver = dispatchReceiverValue?.load() irCall.extensionReceiver = extensionReceiverValue?.load() 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 8282c671ccf..bcc2246b579 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 @@ -32,4 +32,5 @@ const val LOOP_BODY_SLOT = -1 const val LOOP_CONDITION_SLOT = -2 const val SETTER_ARGUMENT_INDEX = 0 const val TRY_RESULT_SLOT = -1 -const val FINALLY_EXPRESSION_SLOT = -2 \ No newline at end of file +const val FINALLY_EXPRESSION_SLOT = -2 +const val NESTED_INITIALIZERS_SLOT = -1 \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrClass.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrClass.kt index a7e84c3ca3c..1a4d1634a7e 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrClass.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrClass.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.ir.declarations import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.ir.* +import org.jetbrains.kotlin.ir.expressions.IrBody import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import java.util.* @@ -28,6 +29,8 @@ interface IrClass : IrDeclaration { override val descriptor: ClassDescriptor val members: List + + var nestedInitializers: IrBody? } class IrClassImpl( @@ -44,20 +47,40 @@ class IrClassImpl( members.add(member) } + override var nestedInitializers: IrBody? = null + set(value) { + value?.assertDetached() + field?.detach() + field = value + value?.setTreeLocation(this, NESTED_INITIALIZERS_SLOT) + } + override fun getChild(slot: Int): IrElement? = - members.getOrNull(slot) + when (slot) { + NESTED_INITIALIZERS_SLOT -> nestedInitializers + else -> members.getOrNull(slot) + } + override fun replaceChild(slot: Int, newChild: IrElement) { - newChild.assertDetached() - members.getOrNull(slot)?.detach() ?: throwNoSuchSlot(slot) - members[slot] = newChild.assertCast() - newChild.setTreeLocation(this, slot) + when (slot) { + NESTED_INITIALIZERS_SLOT -> + nestedInitializers = newChild.assertCast() + else -> { + newChild.assertDetached() + members.getOrNull(slot)?.detach() ?: throwNoSuchSlot(slot) + members[slot] = newChild.assertCast() + newChild.setTreeLocation(this, slot) + } + } + } override fun accept(visitor: IrElementVisitor, data: D): R = visitor.visitClass(this, data) override fun acceptChildren(visitor: IrElementVisitor, data: D) { + nestedInitializers?.accept(visitor, data) members.forEach { it.accept(visitor, data) } } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrCall.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrCall.kt index 7ba1989d4e9..f2a05895b6b 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrCall.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrCall.kt @@ -17,15 +17,15 @@ package org.jetbrains.kotlin.ir.expressions import org.jetbrains.kotlin.descriptors.CallableDescriptor -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.ir.* +import org.jetbrains.kotlin.ir.IrElement +import org.jetbrains.kotlin.ir.assertCast +import org.jetbrains.kotlin.ir.assertDetached +import org.jetbrains.kotlin.ir.detach import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.types.KotlinType import java.lang.AssertionError -import java.lang.UnsupportedOperationException interface IrCall : IrMemberAccessExpression { - val superQualifier: ClassDescriptor? val operator: IrOperator? override val descriptor: CallableDescriptor @@ -34,16 +34,15 @@ interface IrCall : IrMemberAccessExpression { fun removeArgument(index: Int) } -class IrCallImpl( +abstract class IrCallBase( startOffset: Int, endOffset: Int, type: KotlinType, - override val descriptor: CallableDescriptor, - override val operator: IrOperator? = null, - override val superQualifier: ClassDescriptor? = null + numArguments: Int, + override val operator: IrOperator? = null ) : IrMemberAccessExpressionBase(startOffset, endOffset, type), IrCall { - private val argumentsByParameterIndex = - arrayOfNulls(descriptor.valueParameters.size) + protected val argumentsByParameterIndex = + arrayOfNulls(numArguments) override fun getArgument(index: Int): IrExpression? = argumentsByParameterIndex[index] @@ -76,9 +75,6 @@ class IrCallImpl( super.replaceChild(slot, newChild) } - override fun accept(visitor: IrElementVisitor, data: D): R = - visitor.visitCall(this, data) - override fun acceptChildren(visitor: IrElementVisitor, data: D) { super.acceptChildren(visitor, data) argumentsByParameterIndex.forEach { it?.accept(visitor, data) } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrDelegatingConstructorCall.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrDelegatingConstructorCall.kt new file mode 100644 index 00000000000..26769125e9b --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrDelegatingConstructorCall.kt @@ -0,0 +1,35 @@ +/* + * 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.ConstructorDescriptor +import org.jetbrains.kotlin.ir.visitors.IrElementVisitor +import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns + +interface IrDelegatingConstructorCall : IrCall { + override val descriptor: ConstructorDescriptor +} + +class IrDelegatingConstructorCallImpl( + startOffset: Int, + endOffset: Int, + override val descriptor: ConstructorDescriptor +) : IrCallBase(startOffset, endOffset, descriptor.builtIns.unitType, descriptor.valueParameters.size), IrDelegatingConstructorCall { + override fun accept(visitor: IrElementVisitor, data: D): R { + return visitor.visitDelegatingConstructorCall(this, data) + } +} diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrFunCall.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrFunCall.kt new file mode 100644 index 00000000000..a16ef27da70 --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrFunCall.kt @@ -0,0 +1,38 @@ +/* + * 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.ClassDescriptor +import org.jetbrains.kotlin.ir.visitors.IrElementVisitor +import org.jetbrains.kotlin.types.KotlinType + +interface IrFunCall : IrCall { + val superQualifier: ClassDescriptor? +} + +class IrFunCallImpl( + startOffset: Int, + endOffset: Int, + type: KotlinType, + override val descriptor: CallableDescriptor, + override val operator: IrOperator? = null, + override val superQualifier: ClassDescriptor? = null +) : IrCallBase(startOffset, endOffset, type, descriptor.valueParameters.size), IrFunCall { + override fun accept(visitor: IrElementVisitor, data: D): R = + visitor.visitFunCall(this, data) +} diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrInitializeProperty.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrInitializeProperty.kt deleted file mode 100644 index ee4640ffaac..00000000000 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrInitializeProperty.kt +++ /dev/null @@ -1,63 +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 - -import org.jetbrains.kotlin.descriptors.PropertyDescriptor -import org.jetbrains.kotlin.ir.* -import org.jetbrains.kotlin.ir.visitors.IrElementVisitor -import org.jetbrains.kotlin.types.KotlinType - -interface IrInitializeProperty : IrDeclarationReference { - override val descriptor: PropertyDescriptor - - var initBlockExpression: IrExpression? -} - -class IrInitializePropertyImpl( - startOffset: Int, - endOffset: Int, - type: KotlinType, - descriptor: PropertyDescriptor -) : IrDeclarationReferenceBase(startOffset, endOffset, type, descriptor), IrInitializeProperty { - override var initBlockExpression: IrExpression? = null - set(value) { - value?.assertDetached() - field?.detach() - field = value - value?.setTreeLocation(this, CHILD_EXPRESSION_SLOT) - } - - override fun getChild(slot: Int): IrElement? = - when (slot) { - CHILD_EXPRESSION_SLOT -> initBlockExpression - else -> null - } - - override fun replaceChild(slot: Int, newChild: IrElement) { - when (slot) { - CHILD_EXPRESSION_SLOT -> initBlockExpression = newChild.assertCast() - } - } - - override fun accept(visitor: IrElementVisitor, data: D): R { - return visitor.visitInitializeProperty(this, data) - } - - override fun acceptChildren(visitor: IrElementVisitor, data: D) { - initBlockExpression?.accept(visitor, data) - } -} \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrNestedInitializersCall.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrNestedInitializersCall.kt new file mode 100644 index 00000000000..9b701380f65 --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrNestedInitializersCall.kt @@ -0,0 +1,32 @@ +/* + * 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.ir.visitors.IrElementVisitor +import org.jetbrains.kotlin.types.KotlinType + +interface IrNestedInitializersCall : IrExpression + +class IrNestedInitializersCallImpl( + startOffset: Int, + endOffset: Int, + type: KotlinType +) : IrTerminalExpressionBase(startOffset, endOffset, type), IrNestedInitializersCall { + override fun accept(visitor: IrElementVisitor, data: D): R { + return visitor.visitNestedInitializersCall(this, data) + } +} \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrPrimitiveCall.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrPrimitiveCall.kt index ab0d342117f..310f13507ea 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrPrimitiveCall.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrPrimitiveCall.kt @@ -20,14 +20,15 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.ir.* import org.jetbrains.kotlin.ir.visitors.IrElementVisitor -import org.jetbrains.kotlin.types.KotlinType +import java.lang.AssertionError +import java.lang.UnsupportedOperationException abstract class IrPrimitiveCallBase( startOffset: Int, endOffset: Int, override val operator: IrOperator, override val descriptor: CallableDescriptor -) : IrExpressionBase(startOffset, endOffset, descriptor.returnType!!), IrCall { +) : IrExpressionBase(startOffset, endOffset, descriptor.returnType!!), IrFunCall { override val superQualifier: ClassDescriptor? get() = null override var dispatchReceiver: IrExpression? get() = null @@ -48,7 +49,7 @@ abstract class IrPrimitiveCallBase( } override fun accept(visitor: IrElementVisitor, data: D): R { - return visitor.visitCall(this, data) + return visitor.visitFunCall(this, data) } } @@ -166,9 +167,6 @@ class IrBinaryPrimitiveImpl( } } - override fun accept(visitor: IrElementVisitor, data: D): R = - visitor.visitCall(this, data) - override fun acceptChildren(visitor: IrElementVisitor, data: D) { argument0.accept(visitor, data) argument1.accept(visitor, data) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrPropertyAccessorCall.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrPropertyAccessorCall.kt index 146c454d6fe..df24e5d9fe5 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrPropertyAccessorCall.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrPropertyAccessorCall.kt @@ -29,9 +29,9 @@ abstract class IrPropertyAccessorCallBase( override val descriptor: CallableDescriptor, override val operator: IrOperator? = null, override val superQualifier: ClassDescriptor? = null -) : IrMemberAccessExpressionBase(startOffset, endOffset, descriptor.returnType!!), IrCall { +) : IrMemberAccessExpressionBase(startOffset, endOffset, descriptor.returnType!!), IrFunCall { override fun accept(visitor: IrElementVisitor, data: D): R { - return visitor.visitCall(this, data) + return visitor.visitFunCall(this, data) } } @@ -41,7 +41,7 @@ class IrGetterCallImpl( descriptor: CallableDescriptor, operator: IrOperator? = null, superQualifier: ClassDescriptor? = null -) : IrPropertyAccessorCallBase(startOffset, endOffset, descriptor, operator, superQualifier), IrCall { +) : IrPropertyAccessorCallBase(startOffset, endOffset, descriptor, operator, superQualifier), IrFunCall { constructor( startOffset: Int, endOffset: Int, @@ -72,7 +72,7 @@ class IrSetterCallImpl( descriptor: CallableDescriptor, operator: IrOperator? = null, superQualifier: ClassDescriptor? = null -) : IrPropertyAccessorCallBase(startOffset, endOffset, descriptor, operator, superQualifier), IrCall { +) : IrPropertyAccessorCallBase(startOffset, endOffset, descriptor, operator, superQualifier), IrFunCall { constructor( startOffset: Int, endOffset: Int, 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 958b87b07a1..4acb6e99d0d 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 @@ -90,13 +90,16 @@ class RenderIrElementVisitor : IrElementVisitor { override fun visitThisReference(expression: IrThisReference, data: Nothing?): String = "THIS ${expression.classDescriptor.render()} type=${expression.type.render()}" - override fun visitCall(expression: IrCall, data: Nothing?): String = + override fun visitFunCall(expression: IrFunCall, data: Nothing?): String = "CALL .${expression.descriptor.name} ${expression.renderSuperQualifier()}" + "type=${expression.type.render()} operator=${expression.operator}" - private fun IrCall.renderSuperQualifier(): String = + private fun IrFunCall.renderSuperQualifier(): String = superQualifier?.let { "superQualifier=${it.name} " } ?: "" + override fun visitNestedInitializersCall(expression: IrNestedInitializersCall, data: Nothing?): String = + "NESTED_INITIALIZERS_CALL" + override fun visitGetVariable(expression: IrGetVariable, data: Nothing?): String = "GET_VAR ${expression.descriptor.name} type=${expression.type.render()} operator=${expression.operator}" @@ -115,9 +118,6 @@ class RenderIrElementVisitor : IrElementVisitor { override fun visitGetEnumValue(expression: IrGetEnumValue, data: Nothing?): String = "GET_ENUM_VALUE ${expression.descriptor.name} type=${expression.type.render()}" - override fun visitInitializeProperty(expression: IrInitializeProperty, data: Nothing?): String = - "INITIALIZE_PROPERTY ${expression.descriptor.name}" - override fun visitStringConcatenation(expression: IrStringConcatenation, data: Nothing?): String = "STRING_CONCATENATION type=${expression.type.render()}" 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 e622309c4ac..8086c7d799f 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 @@ -59,10 +59,13 @@ interface IrElementVisitor { fun visitGetBackingField(expression: IrGetBackingField, data: D) = visitDeclarationReference(expression, data) fun visitSetBackingField(expression: IrSetBackingField, data: D) = visitDeclarationReference(expression, data) fun visitGetExtensionReceiver(expression: IrGetExtensionReceiver, data: D) = visitDeclarationReference(expression, data) - fun visitInitializeProperty(expression: IrInitializeProperty, data: D): R = visitDeclarationReference(expression, data) fun visitCall(expression: IrCall, data: D) = visitDeclarationReference(expression, data) + fun visitFunCall(expression: IrFunCall, data: D) = visitCall(expression, data) + fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall, data: D) = visitCall(expression, data) fun visitCallableReference(expression: IrCallableReference, data: D) = visitDeclarationReference(expression, data) + fun visitNestedInitializersCall(expression: IrNestedInitializersCall, data: D) = visitExpression(expression, data) + fun visitTypeOperator(expression: IrTypeOperatorCall, data: D) = visitExpression(expression, data) fun visitWhen(expression: IrWhen, data: D) = visitExpression(expression, data)