From a6bee7a22b84d4bfd2183da96ca5e16f8a305ac0 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Tue, 30 Aug 2016 11:02:54 +0300 Subject: [PATCH] Generate delegating constructor calls as IrDelegatingConstructorCall expressions (they have different platform-level representation in JVM and JS). --- .../kotlin/psi2ir/generators/BodyGenerator.kt | 5 +- .../kotlin/psi2ir/generators/CallGenerator.kt | 52 +++++++----- .../FoldStringConcatenation.kt | 6 +- .../transformations/InsertImplicitCasts.kt | 2 +- .../jetbrains/kotlin/ir/expressions/IrCall.kt | 64 +++------------ .../IrDelegatingConstructorCall.kt | 4 +- .../kotlin/ir/expressions/IrFunCall.kt | 38 --------- .../kotlin/ir/expressions/IrGeneralCall.kt | 82 +++++++++++++++++++ .../kotlin/ir/expressions/IrPrimitiveCall.kt | 4 +- .../ir/expressions/IrPropertyAccessorCall.kt | 8 +- .../jetbrains/kotlin/ir/util/DumpIrTree.kt | 2 +- .../kotlin/ir/util/RenderIrElement.kt | 7 +- .../kotlin/ir/visitors/IrElementVisitor.kt | 6 +- ...ntReorderingInDelegatingConstructorCall.kt | 8 ++ ...tReorderingInDelegatingConstructorCall.txt | 50 +++++++++++ .../ir/irText/classes/classMembers.txt | 2 +- ...onstructorCallsInSecondaryConstructors.txt | 6 +- .../testData/ir/irText/classes/initVar.txt | 4 +- ...aryConstructorWithSuperConstructorCall.txt | 2 +- ...nstructorWithInitializersFromClassBody.txt | 4 +- .../irText/classes/secondaryConstructors.txt | 4 +- .../kotlin/ir/IrTextTestCaseGenerated.java | 6 ++ 22 files changed, 224 insertions(+), 142 deletions(-) delete mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrFunCall.kt create mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrGeneralCall.kt create mode 100644 compiler/testData/ir/irText/classes/argumentReorderingInDelegatingConstructorCall.kt create mode 100644 compiler/testData/ir/irText/classes/argumentReorderingInDelegatingConstructorCall.txt 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 192a6d7d423..5a59bdc5d58 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 @@ -104,8 +104,9 @@ class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context: val statementGenerator = createStatementGenerator() val ktDelegatingConstructorCall = ktConstructor.getDelegationCall() val delegatingConstructorCall = statementGenerator.pregenerateCall(getResolvedCall(ktDelegatingConstructorCall)!!) - val irDelegatingConstructorCall = CallGenerator(statementGenerator).generateCall( - ktDelegatingConstructorCall, delegatingConstructorCall, IrOperator.DELEGATING_CONSTRUCTOR_CALL) + val irDelegatingConstructorCall = CallGenerator(statementGenerator).generateDelegatingConstructorCall( + ktDelegatingConstructorCall.startOffset, ktDelegatingConstructorCall.endOffset, + delegatingConstructorCall) irBlockBody.addStatement(irDelegatingConstructorCall) } 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 712c97a3121..1b927ff8acf 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 @@ -16,10 +16,7 @@ package org.jetbrains.kotlin.psi2ir.generators -import org.jetbrains.kotlin.descriptors.FunctionDescriptor -import org.jetbrains.kotlin.descriptors.PropertyDescriptor -import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor -import org.jetbrains.kotlin.descriptors.VariableDescriptor +import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.psiUtil.endOffset @@ -52,6 +49,23 @@ class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorE } } + fun generateDelegatingConstructorCall( + startOffset: Int, + endOffset: Int, + call: CallBuilder + ) : IrExpression { + val descriptor = call.descriptor + if (descriptor !is ConstructorDescriptor) throw AssertionError("Constructor expected: $descriptor") + + return call.callReceiver.call { dispatchReceiver, extensionReceiver -> + if (dispatchReceiver != null) throw AssertionError("Dispatch receiver should be null: $dispatchReceiver") + if (extensionReceiver != null) throw AssertionError("Extension receiver should be null: $extensionReceiver") + val irCall = IrDelegatingConstructorCallImpl(startOffset, endOffset, descriptor) + + addParametersToCall(startOffset, endOffset, call, irCall, descriptor.returnType) + } + } + private fun generatePropertyGetterCall( descriptor: PropertyDescriptor, startOffset: Int, @@ -79,28 +93,28 @@ class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorE val returnType = descriptor.returnType!! return call.callReceiver.call { dispatchReceiverValue, extensionReceiverValue -> - val irCall = IrFunCallImpl(startOffset, endOffset, returnType, descriptor, operator, call.superQualifier) + val irCall = IrCallImpl(startOffset, endOffset, returnType, descriptor, operator, call.superQualifier) irCall.dispatchReceiver = dispatchReceiverValue?.load() irCall.extensionReceiver = extensionReceiverValue?.load() - val irCallWithReordering = - if (call.isValueArgumentReorderingRequired()) { - generateCallWithArgumentReordering(irCall, startOffset, endOffset, call, returnType) - } - else { - val valueArguments = call.getValueArgumentsInParameterOrder() - for ((index, valueArgument) in valueArguments.withIndex()) { - irCall.putArgument(index, valueArgument) - } - irCall - } - - irCallWithReordering + addParametersToCall(startOffset, endOffset, call, irCall, returnType) } } + private fun addParametersToCall(startOffset: Int, endOffset: Int, call: CallBuilder, irCall: IrGeneralCallBase, returnType: KotlinType): IrExpression = + if (call.isValueArgumentReorderingRequired()) { + generateCallWithArgumentReordering(irCall, startOffset, endOffset, call, returnType) + } + else { + val valueArguments = call.getValueArgumentsInParameterOrder() + for ((index, valueArgument) in valueArguments.withIndex()) { + irCall.putArgument(index, valueArgument) + } + irCall + } + private fun generateCallWithArgumentReordering( - irCall: IrCall, + irCall: IrGeneralCall, startOffset: Int, endOffset: Int, call: CallBuilder, diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/FoldStringConcatenation.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/FoldStringConcatenation.kt index 725e72d4787..7dd8c1739c6 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/FoldStringConcatenation.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/FoldStringConcatenation.kt @@ -20,7 +20,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.detach -import org.jetbrains.kotlin.ir.expressions.IrCall +import org.jetbrains.kotlin.ir.expressions.IrGeneralCall import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrStringConcatenation import org.jetbrains.kotlin.ir.expressions.IrStringConcatenationImpl @@ -38,7 +38,7 @@ class FoldStringConcatenation : IrElementVisitor { element.acceptChildren(this, data) } - override fun visitCall(expression: IrCall, data: Nothing?) { + override fun visitGeneralCall(expression: IrGeneralCall, data: Nothing?) { if (!isStringPlus(expression.descriptor)) { visitElement(expression, data) return @@ -54,7 +54,7 @@ class FoldStringConcatenation : IrElementVisitor { private fun collectStringConcatenationArguments(expression: IrExpression, arguments: ArrayList) { when { - expression is IrCall && isStringPlus(expression.descriptor)-> { + expression is IrGeneralCall && isStringPlus(expression.descriptor)-> { collectStringConcatenationArguments(expression.dispatchReceiver!!, arguments) collectStringConcatenationArguments(expression.getArgument(0)!!, arguments) } 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 8c0fc62c9e0..7e29ddbc60f 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 @@ -39,7 +39,7 @@ class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementVisitor(numArguments) - - override fun getArgument(index: Int): IrExpression? = - argumentsByParameterIndex[index] - - override fun putArgument(index: Int, valueArgument: IrExpression?) { - if (index >= argumentsByParameterIndex.size) { - throw AssertionError("$this: No such argument slot: $index") - } - valueArgument?.assertDetached() - argumentsByParameterIndex[index]?.detach() - argumentsByParameterIndex[index] = valueArgument - valueArgument?.setTreeLocation(this, index) - } - - override fun removeArgument(index: Int) { - argumentsByParameterIndex[index]?.detach() - argumentsByParameterIndex[index] = null - } - - override fun getChild(slot: Int): IrElement? = - if (0 <= slot) - argumentsByParameterIndex.getOrNull(slot) - else - super.getChild(slot) - - override fun replaceChild(slot: Int, newChild: IrElement) { - if (0 <= slot) - putArgument(slot, newChild.assertCast()) - else - super.replaceChild(slot, newChild) - } - - override fun acceptChildren(visitor: IrElementVisitor, data: D) { - super.acceptChildren(visitor, data) - argumentsByParameterIndex.forEach { it?.accept(visitor, data) } - } + override val descriptor: CallableDescriptor, + override val operator: IrOperator? = null, + override val superQualifier: ClassDescriptor? = null +) : IrGeneralCallBase(startOffset, endOffset, type, descriptor.valueParameters.size), IrCall { + override fun accept(visitor: IrElementVisitor, data: D): R = + visitor.visitCall(this, 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 index 26769125e9b..4f71a036daf 100644 --- 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 @@ -20,7 +20,7 @@ import org.jetbrains.kotlin.descriptors.ConstructorDescriptor import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns -interface IrDelegatingConstructorCall : IrCall { +interface IrDelegatingConstructorCall : IrGeneralCall { override val descriptor: ConstructorDescriptor } @@ -28,7 +28,7 @@ class IrDelegatingConstructorCallImpl( startOffset: Int, endOffset: Int, override val descriptor: ConstructorDescriptor -) : IrCallBase(startOffset, endOffset, descriptor.builtIns.unitType, descriptor.valueParameters.size), IrDelegatingConstructorCall { +) : IrGeneralCallBase(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 deleted file mode 100644 index a16ef27da70..00000000000 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrFunCall.kt +++ /dev/null @@ -1,38 +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.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/IrGeneralCall.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrGeneralCall.kt new file mode 100644 index 00000000000..c50f0d7cf04 --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrGeneralCall.kt @@ -0,0 +1,82 @@ +/* + * 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.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 + +interface IrGeneralCall : IrMemberAccessExpression { + val operator: IrOperator? + override val descriptor: CallableDescriptor + + fun getArgument(index: Int): IrExpression? + fun putArgument(index: Int, valueArgument: IrExpression?) + fun removeArgument(index: Int) +} + +abstract class IrGeneralCallBase( + startOffset: Int, + endOffset: Int, + type: KotlinType, + numArguments: Int, + override val operator: IrOperator? = null +) : IrMemberAccessExpressionBase(startOffset, endOffset, type), IrGeneralCall { + protected val argumentsByParameterIndex = + arrayOfNulls(numArguments) + + override fun getArgument(index: Int): IrExpression? = + argumentsByParameterIndex[index] + + override fun putArgument(index: Int, valueArgument: IrExpression?) { + if (index >= argumentsByParameterIndex.size) { + throw AssertionError("$this: No such argument slot: $index") + } + valueArgument?.assertDetached() + argumentsByParameterIndex[index]?.detach() + argumentsByParameterIndex[index] = valueArgument + valueArgument?.setTreeLocation(this, index) + } + + override fun removeArgument(index: Int) { + argumentsByParameterIndex[index]?.detach() + argumentsByParameterIndex[index] = null + } + + override fun getChild(slot: Int): IrElement? = + if (0 <= slot) + argumentsByParameterIndex.getOrNull(slot) + else + super.getChild(slot) + + override fun replaceChild(slot: Int, newChild: IrElement) { + if (0 <= slot) + putArgument(slot, newChild.assertCast()) + else + super.replaceChild(slot, newChild) + } + + 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/IrPrimitiveCall.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrPrimitiveCall.kt index 310f13507ea..7a2ec8ddaf3 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 @@ -28,7 +28,7 @@ abstract class IrPrimitiveCallBase( endOffset: Int, override val operator: IrOperator, override val descriptor: CallableDescriptor -) : IrExpressionBase(startOffset, endOffset, descriptor.returnType!!), IrFunCall { +) : IrExpressionBase(startOffset, endOffset, descriptor.returnType!!), IrCall { override val superQualifier: ClassDescriptor? get() = null override var dispatchReceiver: IrExpression? get() = null @@ -49,7 +49,7 @@ abstract class IrPrimitiveCallBase( } override fun accept(visitor: IrElementVisitor, data: D): R { - return visitor.visitFunCall(this, data) + return visitor.visitCall(this, 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 df24e5d9fe5..146c454d6fe 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!!), IrFunCall { +) : IrMemberAccessExpressionBase(startOffset, endOffset, descriptor.returnType!!), IrCall { override fun accept(visitor: IrElementVisitor, data: D): R { - return visitor.visitFunCall(this, data) + return visitor.visitCall(this, data) } } @@ -41,7 +41,7 @@ class IrGetterCallImpl( descriptor: CallableDescriptor, operator: IrOperator? = null, superQualifier: ClassDescriptor? = null -) : IrPropertyAccessorCallBase(startOffset, endOffset, descriptor, operator, superQualifier), IrFunCall { +) : IrPropertyAccessorCallBase(startOffset, endOffset, descriptor, operator, superQualifier), IrCall { 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), IrFunCall { +) : IrPropertyAccessorCallBase(startOffset, endOffset, descriptor, operator, superQualifier), IrCall { constructor( startOffset: Int, endOffset: Int, 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 e94f0dc9c62..d3f1c039b98 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 @@ -53,7 +53,7 @@ class DumpIrTreeVisitor(out: Appendable): IrElementVisitor { } } - override fun visitCall(expression: IrCall, data: String) { + override fun visitGeneralCall(expression: IrGeneralCall, data: String) { expression.dumpLabeledElementWith(data) { expression.dispatchReceiver?.accept(this, "\$this") expression.extensionReceiver?.accept(this, "\$receiver") 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 5e8a771ce78..fe0f5625caf 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 visitFunCall(expression: IrFunCall, data: Nothing?): String = + override fun visitCall(expression: IrCall, data: Nothing?): String = "CALL .${expression.descriptor.name} ${expression.renderSuperQualifier()}" + "type=${expression.type.render()} operator=${expression.operator}" - private fun IrFunCall.renderSuperQualifier(): String = + private fun IrCall.renderSuperQualifier(): String = superQualifier?.let { "superQualifier=${it.name} " } ?: "" + override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall, data: Nothing?): String = + "DELEGATING_CONSTRUCTOR_CALL ${expression.descriptor.containingDeclaration.name}" + override fun visitNestedInitializersCall(expression: IrNestedInitializersCall, data: Nothing?): String = "NESTED_INITIALIZERS_CALL classDescriptor=${expression.classDescriptor.name}" 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 8086c7d799f..5dc46f473bb 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,9 +59,9 @@ 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 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 visitGeneralCall(expression: IrGeneralCall, data: D) = visitDeclarationReference(expression, data) + fun visitCall(expression: IrCall, data: D) = visitGeneralCall(expression, data) + fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall, data: D) = visitGeneralCall(expression, data) fun visitCallableReference(expression: IrCallableReference, data: D) = visitDeclarationReference(expression, data) fun visitNestedInitializersCall(expression: IrNestedInitializersCall, data: D) = visitExpression(expression, data) diff --git a/compiler/testData/ir/irText/classes/argumentReorderingInDelegatingConstructorCall.kt b/compiler/testData/ir/irText/classes/argumentReorderingInDelegatingConstructorCall.kt new file mode 100644 index 00000000000..f019a7db5cb --- /dev/null +++ b/compiler/testData/ir/irText/classes/argumentReorderingInDelegatingConstructorCall.kt @@ -0,0 +1,8 @@ +open class Base(val x: Int, val y: Int) + +class Test1(xx: Int, yy: Int) : Base(y = yy, x = xx) + +class Test2 : Base { + constructor(xx: Int, yy: Int) : super(y = yy, x = xx) + constructor(xxx: Int, yyy: Int, a: Any) : this(yy = yyy, xx = xxx) +} \ No newline at end of file diff --git a/compiler/testData/ir/irText/classes/argumentReorderingInDelegatingConstructorCall.txt b/compiler/testData/ir/irText/classes/argumentReorderingInDelegatingConstructorCall.txt new file mode 100644 index 00000000000..666b32a862b --- /dev/null +++ b/compiler/testData/ir/irText/classes/argumentReorderingInDelegatingConstructorCall.txt @@ -0,0 +1,50 @@ +FILE /argumentReorderingInDelegatingConstructorCall.kt + CLASS CLASS Base + FUN public constructor Base(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int) + BLOCK_BODY + SET_BACKING_FIELD x type=kotlin.Unit operator=null + 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 + PROPERTY public final val x: kotlin.Int getter=null setter=null + EXPRESSION_BODY + GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER + PROPERTY public final val y: kotlin.Int getter=null setter=null + EXPRESSION_BODY + GET_VAR y type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER + CLASS CLASS Test1 + FUN public constructor Test1(/*0*/ xx: kotlin.Int, /*1*/ yy: kotlin.Int) + BLOCK_BODY + BLOCK type=Base operator=ARGUMENTS_REORDERING_FOR_CALL + VAR val tmp0_y: kotlin.Int + GET_VAR yy type=kotlin.Int operator=null + VAR val tmp1_x: kotlin.Int + GET_VAR xx type=kotlin.Int operator=null + CALL . type=Base operator=SUPER_CONSTRUCTOR_CALL + x: GET_VAR tmp1_x type=kotlin.Int operator=null + y: GET_VAR tmp0_y type=kotlin.Int operator=null + CLASS CLASS Test2 + nestedInitializers: BLOCK_BODY + FUN public constructor Test2(/*0*/ xx: kotlin.Int, /*1*/ yy: kotlin.Int) + BLOCK_BODY + BLOCK type=Base operator=ARGUMENTS_REORDERING_FOR_CALL + VAR val tmp0_y: kotlin.Int + GET_VAR yy type=kotlin.Int operator=null + VAR val tmp1_x: kotlin.Int + GET_VAR xx type=kotlin.Int operator=null + TYPE_OP operator=IMPLICIT_CAST typeOperand=Base + DELEGATING_CONSTRUCTOR_CALL Base + x: GET_VAR tmp1_x type=kotlin.Int operator=null + y: GET_VAR tmp0_y type=kotlin.Int operator=null + NESTED_INITIALIZERS_CALL classDescriptor=Test2 + FUN public constructor Test2(/*0*/ xxx: kotlin.Int, /*1*/ yyy: kotlin.Int, /*2*/ a: kotlin.Any) + BLOCK_BODY + BLOCK type=Test2 operator=ARGUMENTS_REORDERING_FOR_CALL + VAR val tmp0_yy: kotlin.Int + GET_VAR yyy type=kotlin.Int operator=null + VAR val tmp1_xx: kotlin.Int + GET_VAR xxx type=kotlin.Int operator=null + TYPE_OP operator=IMPLICIT_CAST typeOperand=Test2 + DELEGATING_CONSTRUCTOR_CALL Test2 + xx: GET_VAR tmp1_xx type=kotlin.Int operator=null + yy: GET_VAR tmp0_yy type=kotlin.Int operator=null diff --git a/compiler/testData/ir/irText/classes/classMembers.txt b/compiler/testData/ir/irText/classes/classMembers.txt index 6a876635468..9c97e2849b5 100644 --- a/compiler/testData/ir/irText/classes/classMembers.txt +++ b/compiler/testData/ir/irText/classes/classMembers.txt @@ -16,7 +16,7 @@ FILE /classMembers.kt GET_VAR z type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER FUN public constructor C() BLOCK_BODY - CALL . type=C operator=DELEGATING_CONSTRUCTOR_CALL + DELEGATING_CONSTRUCTOR_CALL C x: CONST Int type=kotlin.Int value='0' y: CONST Int type=kotlin.Int value='0' z: CONST Int type=kotlin.Int value='0' diff --git a/compiler/testData/ir/irText/classes/delegatingConstructorCallsInSecondaryConstructors.txt b/compiler/testData/ir/irText/classes/delegatingConstructorCallsInSecondaryConstructors.txt index 32b06a7ec8f..6d42b5e7112 100644 --- a/compiler/testData/ir/irText/classes/delegatingConstructorCallsInSecondaryConstructors.txt +++ b/compiler/testData/ir/irText/classes/delegatingConstructorCallsInSecondaryConstructors.txt @@ -6,12 +6,12 @@ FILE /delegatingConstructorCallsInSecondaryConstructors.kt nestedInitializers: BLOCK_BODY FUN public constructor Test() BLOCK_BODY - CALL . type=Base operator=DELEGATING_CONSTRUCTOR_CALL + DELEGATING_CONSTRUCTOR_CALL Base NESTED_INITIALIZERS_CALL classDescriptor=Test FUN public constructor Test(/*0*/ xx: kotlin.Int) BLOCK_BODY - CALL . type=Base operator=DELEGATING_CONSTRUCTOR_CALL + DELEGATING_CONSTRUCTOR_CALL Base NESTED_INITIALIZERS_CALL classDescriptor=Test FUN public constructor Test(/*0*/ xx: kotlin.Short) BLOCK_BODY - CALL . type=Test operator=DELEGATING_CONSTRUCTOR_CALL + DELEGATING_CONSTRUCTOR_CALL Test diff --git a/compiler/testData/ir/irText/classes/initVar.txt b/compiler/testData/ir/irText/classes/initVar.txt index 0472b089ef0..b2f88328398 100644 --- a/compiler/testData/ir/irText/classes/initVar.txt +++ b/compiler/testData/ir/irText/classes/initVar.txt @@ -48,7 +48,7 @@ FILE /initVar.kt GET_VAR value type=kotlin.Int operator=null FUN public constructor TestInitVarWithCustomSetterWithExplicitCtor() BLOCK_BODY - CALL . type=kotlin.Any operator=DELEGATING_CONSTRUCTOR_CALL + DELEGATING_CONSTRUCTOR_CALL Any NESTED_INITIALIZERS_CALL classDescriptor=TestInitVarWithCustomSetterWithExplicitCtor CLASS CLASS TestInitVarWithCustomSetterInCtor nestedInitializers: BLOCK_BODY @@ -59,7 +59,7 @@ FILE /initVar.kt GET_VAR value type=kotlin.Int operator=null FUN public constructor TestInitVarWithCustomSetterInCtor() BLOCK_BODY - CALL . type=kotlin.Any operator=DELEGATING_CONSTRUCTOR_CALL + DELEGATING_CONSTRUCTOR_CALL Any NESTED_INITIALIZERS_CALL classDescriptor=TestInitVarWithCustomSetterInCtor CALL . type=kotlin.Unit operator=EQ $this: THIS public final class TestInitVarWithCustomSetterInCtor type=TestInitVarWithCustomSetterInCtor diff --git a/compiler/testData/ir/irText/classes/primaryConstructorWithSuperConstructorCall.txt b/compiler/testData/ir/irText/classes/primaryConstructorWithSuperConstructorCall.txt index ef28791e964..e91caa0b33c 100644 --- a/compiler/testData/ir/irText/classes/primaryConstructorWithSuperConstructorCall.txt +++ b/compiler/testData/ir/irText/classes/primaryConstructorWithSuperConstructorCall.txt @@ -26,6 +26,6 @@ FILE /primaryConstructorWithSuperConstructorCall.kt GET_VAR y type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER FUN public constructor TestWithDelegatingConstructor(/*0*/ x: kotlin.Int) BLOCK_BODY - CALL . type=TestWithDelegatingConstructor operator=DELEGATING_CONSTRUCTOR_CALL + DELEGATING_CONSTRUCTOR_CALL TestWithDelegatingConstructor x: GET_VAR x type=kotlin.Int operator=null y: CONST Int type=kotlin.Int value='0' diff --git a/compiler/testData/ir/irText/classes/secondaryConstructorWithInitializersFromClassBody.txt b/compiler/testData/ir/irText/classes/secondaryConstructorWithInitializersFromClassBody.txt index 4f1dee4e717..fc22951db26 100644 --- a/compiler/testData/ir/irText/classes/secondaryConstructorWithInitializersFromClassBody.txt +++ b/compiler/testData/ir/irText/classes/secondaryConstructorWithInitializersFromClassBody.txt @@ -11,7 +11,7 @@ FILE /secondaryConstructorWithInitializersFromClassBody.kt CONST Int type=kotlin.Int value='0' FUN public constructor TestProperty() BLOCK_BODY - CALL . type=Base operator=DELEGATING_CONSTRUCTOR_CALL + DELEGATING_CONSTRUCTOR_CALL Base NESTED_INITIALIZERS_CALL classDescriptor=TestProperty CLASS CLASS TestInitBlock nestedInitializers: BLOCK_BODY @@ -21,5 +21,5 @@ FILE /secondaryConstructorWithInitializersFromClassBody.kt PROPERTY public final val x: kotlin.Int getter=null setter=null FUN public constructor TestInitBlock() BLOCK_BODY - CALL . type=Base operator=DELEGATING_CONSTRUCTOR_CALL + DELEGATING_CONSTRUCTOR_CALL Base NESTED_INITIALIZERS_CALL classDescriptor=TestInitBlock diff --git a/compiler/testData/ir/irText/classes/secondaryConstructors.txt b/compiler/testData/ir/irText/classes/secondaryConstructors.txt index f0b61910765..deb367a4c54 100644 --- a/compiler/testData/ir/irText/classes/secondaryConstructors.txt +++ b/compiler/testData/ir/irText/classes/secondaryConstructors.txt @@ -3,9 +3,9 @@ FILE /secondaryConstructors.kt nestedInitializers: BLOCK_BODY FUN public constructor C() BLOCK_BODY - CALL . type=C operator=DELEGATING_CONSTRUCTOR_CALL + DELEGATING_CONSTRUCTOR_CALL C x: CONST Int type=kotlin.Int value='0' FUN public constructor C(/*0*/ x: kotlin.Int) BLOCK_BODY - CALL . type=kotlin.Any operator=DELEGATING_CONSTRUCTOR_CALL + DELEGATING_CONSTRUCTOR_CALL Any NESTED_INITIALIZERS_CALL classDescriptor=C diff --git a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java index 5c7820e9516..e19b35fca29 100644 --- a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java @@ -43,6 +43,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/ir/irText/classes"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("argumentReorderingInDelegatingConstructorCall.kt") + public void testArgumentReorderingInDelegatingConstructorCall() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/classes/argumentReorderingInDelegatingConstructorCall.kt"); + doTest(fileName); + } + @TestMetadata("classMembers.kt") public void testClassMembers() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/classes/classMembers.kt");