From 1e3cdf300a434794ac60bbe9d34bd6652e61a42e Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Mon, 5 Sep 2016 10:03:56 +0300 Subject: [PATCH] Generate default super constructor calls for secondary constructors. --- .../kotlin/psi2ir/generators/BodyGenerator.kt | 34 +++++++++++++++---- 1 file changed, 27 insertions(+), 7 deletions(-) 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 87d9340213b..e1b141e7187 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 @@ -120,9 +120,23 @@ class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context: } private fun generateDelegatingConstructorCall(irBlockBody: IrBlockBodyImpl, ktConstructor: KtSecondaryConstructor) { + val constructorDescriptor = scopeOwner as ConstructorDescriptor + val statementGenerator = createStatementGenerator() val ktDelegatingConstructorCall = ktConstructor.getDelegationCall() - val delegatingConstructorCall = statementGenerator.pregenerateCall(getResolvedCall(ktDelegatingConstructorCall)!!) + val delegatingConstructorResolvedCall = getResolvedCall(ktDelegatingConstructorCall) + + if (delegatingConstructorResolvedCall == null) { + if (constructorDescriptor.containingDeclaration.kind == ClassKind.ENUM_CLASS) { + generateEnumSuperConstructorCall(irBlockBody, ktConstructor) + } + else { + generateAnySuperConstructorCAll(irBlockBody, ktConstructor) + } + return + } + + val delegatingConstructorCall = statementGenerator.pregenerateCall(delegatingConstructorResolvedCall) val irDelegatingConstructorCall = CallGenerator(statementGenerator).generateDelegatingConstructorCall( ktDelegatingConstructorCall.startOffset, ktDelegatingConstructorCall.endOffset, delegatingConstructorCall) @@ -170,9 +184,7 @@ class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context: when (classDescriptor.kind) { ClassKind.ENUM_CLASS -> { - val kotlinEnumConstructor = context.builtIns.enum.unsubstitutedPrimaryConstructor!! - irBlockBody.addStatement(IrEnumConstructorCallImpl(ktClassOrObject.startOffset, ktClassOrObject.endOffset, - kotlinEnumConstructor, null)) + generateEnumSuperConstructorCall(irBlockBody, ktClassOrObject) } ClassKind.ENUM_ENTRY -> { irBlockBody.addStatement(generateEnumEntrySuperConstructorCall(ktClassOrObject as KtEnumEntry, classDescriptor)) @@ -196,13 +208,21 @@ class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context: // Thus, super class should be Any. val superClass = classDescriptor.getSuperClassOrAny() assert(KotlinBuiltIns.isAny(superClass)) { "$classDescriptor: Super class should be any: $superClass" } - val superConstructor = superClass.constructors.single() - irBlockBody.addStatement(IrDelegatingConstructorCallImpl(ktClassOrObject.startOffset, ktClassOrObject.endOffset, - superConstructor)) + generateAnySuperConstructorCAll(irBlockBody, ktClassOrObject) } } } + private fun generateAnySuperConstructorCAll(irBlockBody: IrBlockBodyImpl, ktElement: KtElement) { + val anyConstructor = context.builtIns.any.constructors.single() + irBlockBody.addStatement(IrDelegatingConstructorCallImpl(ktElement.startOffset, ktElement.endOffset, anyConstructor)) + } + + private fun generateEnumSuperConstructorCall(irBlockBody: IrBlockBodyImpl, ktElement: KtElement) { + val enumConstructor = context.builtIns.enum.constructors.single() + irBlockBody.addStatement(IrEnumConstructorCallImpl(ktElement.startOffset, ktElement.endOffset, enumConstructor, null)) + } + private fun generateEnumEntrySuperConstructorCall(ktEnumEntry: KtEnumEntry, enumEntryDescriptor: ClassDescriptor): IrExpression { return generateEnumConstructorCallOrSuperCall(ktEnumEntry, enumEntryDescriptor.containingDeclaration as ClassDescriptor, null) }