From 1cd229d8e550fb3e92a06b05b71529650e58a7b9 Mon Sep 17 00:00:00 2001 From: Igor Chevdar Date: Mon, 13 Mar 2017 11:46:11 -0400 Subject: [PATCH] Default enum class should not have primary constructor. (#335) * Default enum class should not have primary constructor. * Made simple delegating constructor non-primary + some refactoring. * Make singleton object constructor primary. --- .../konan/EnumSpecialDescriptorsFactory.kt | 3 +- .../kotlin/backend/konan/ir/IrUtils.kt | 30 ++++++++++--------- .../backend/konan/lower/DelegationLowering.kt | 2 +- .../backend/konan/lower/EnumClassLowering.kt | 19 ++++++------ 4 files changed, 29 insertions(+), 25 deletions(-) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/EnumSpecialDescriptorsFactory.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/EnumSpecialDescriptorsFactory.kt index 943e623d596..ed4f3ee5cd7 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/EnumSpecialDescriptorsFactory.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/EnumSpecialDescriptorsFactory.kt @@ -38,7 +38,8 @@ internal class EnumSpecialDescriptorsFactory(val context: Context) { val memberScope = MemberScope.Empty val constructorOfAny = context.builtIns.any.constructors.first() - val constructorDescriptor = implObjectDescriptor.createSimpleDelegatingConstructorDescriptor(constructorOfAny) + // TODO: why primary? + val constructorDescriptor = implObjectDescriptor.createSimpleDelegatingConstructorDescriptor(constructorOfAny, true) implObjectDescriptor.initialize(memberScope, setOf(constructorDescriptor), constructorDescriptor) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/IrUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/IrUtils.kt index 580146f7975..ee7f8e17000 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/IrUtils.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/IrUtils.kt @@ -28,13 +28,13 @@ fun ir2stringWhole(ir: IrElement?): String { return strWriter.toString() } -internal fun ClassDescriptor.createSimpleDelegatingConstructorDescriptor(superConstructorDescriptor: ClassConstructorDescriptor) +internal fun ClassDescriptor.createSimpleDelegatingConstructorDescriptor(superConstructorDescriptor: ClassConstructorDescriptor, isPrimary: Boolean = false) : ClassConstructorDescriptor { val constructorDescriptor = ClassConstructorDescriptorImpl.createSynthesized( - this, - Annotations.EMPTY, - superConstructorDescriptor.isPrimary, - SourceElement.NO_SOURCE) + /* containingDeclaration = */ this, + /* annotations = */ Annotations.EMPTY, + /* isPrimary = */ isPrimary, + /* source = */ SourceElement.NO_SOURCE) val valueParameters = superConstructorDescriptor.valueParameters.map { it.copy(constructorDescriptor, it.name, it.index) } @@ -44,23 +44,25 @@ internal fun ClassDescriptor.createSimpleDelegatingConstructorDescriptor(superCo } internal fun ClassDescriptor.createSimpleDelegatingConstructor(superConstructorDescriptor: ClassConstructorDescriptor, - constructorDescriptor: ClassConstructorDescriptor) + constructorDescriptor: ClassConstructorDescriptor, + startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin) : IrConstructor { - val body = IrBlockBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, + val body = IrBlockBodyImpl(startOffset, endOffset, listOf( - IrDelegatingConstructorCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, superConstructorDescriptor).apply { + IrDelegatingConstructorCallImpl(startOffset, endOffset, superConstructorDescriptor).apply { constructorDescriptor.valueParameters.forEachIndexed { idx, parameter -> - putValueArgument(idx, IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, parameter)) + putValueArgument(idx, IrGetValueImpl(startOffset, endOffset, parameter)) } }, - IrInstanceInitializerCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, this) + IrInstanceInitializerCallImpl(startOffset, endOffset, this) ) ) - return IrConstructorImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.DEFINED, constructorDescriptor, body) + return IrConstructorImpl(startOffset, endOffset, origin, constructorDescriptor, body) } internal fun Context.createArrayOfExpression(arrayElementType: KotlinType, - arrayElements: List): IrExpression { + arrayElements: List, + startOffset: Int, endOffset: Int): IrExpression { val kotlinPackage = irModule!!.descriptor.getPackage(FqName("kotlin")) val genericArrayOfFun = kotlinPackage.memberScope.getContributedFunctions(Name.identifier("arrayOf"), NoLookupLocation.FROM_BACKEND).first() val typeParameter0 = genericArrayOfFun.typeParameters[0] @@ -72,9 +74,9 @@ internal fun Context.createArrayOfExpression(arrayElementType: KotlinType, val valueParameter0 = substitutedArrayOfFun.valueParameters[0] val arg0VarargType = valueParameter0.type val arg0VarargElementType = valueParameter0.varargElementType!! - val arg0 = IrVarargImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, arg0VarargType, arg0VarargElementType, arrayElements) + val arg0 = IrVarargImpl(startOffset, endOffset, arg0VarargType, arg0VarargElementType, arrayElements) - return IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, substitutedArrayOfFun, typeArguments).apply { + return IrCallImpl(startOffset, endOffset, substitutedArrayOfFun, typeArguments).apply { putValueArgument(0, arg0) } } \ No newline at end of file diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/DelegationLowering.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/DelegationLowering.kt index 7e73a1968fe..8c97b6fca92 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/DelegationLowering.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/DelegationLowering.kt @@ -132,7 +132,7 @@ internal class PropertyDelegationLowering(val context: Context) : FileLoweringPa DECLARATION_ORIGIN_KPROPERTIES_FOR_DELEGATION, kPropertiesField, IrExpressionBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, - context.createArrayOfExpression(kPropertyImplType, initializers)))) + context.createArrayOfExpression(kPropertyImplType, initializers, UNDEFINED_OFFSET, UNDEFINED_OFFSET)))) } } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/EnumClassLowering.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/EnumClassLowering.kt index 52498818546..d57d317bfe7 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/EnumClassLowering.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/EnumClassLowering.kt @@ -175,17 +175,16 @@ internal class EnumClassLowering(val context: Context) : ClassLoweringPass { val defaultClass = IrClassImpl(startOffset, endOffset, IrDeclarationOrigin.DEFINED, defaultClassDescriptor) val constructors = mutableSetOf() - var primaryConstructor: ClassConstructorDescriptor? = null descriptor.constructors.forEach { val loweredEnumConstructor = loweredEnumConstructors[it]!! val constructorDescriptor = defaultClassDescriptor.createSimpleDelegatingConstructorDescriptor(loweredEnumConstructor) - val constructor = defaultClassDescriptor.createSimpleDelegatingConstructor(loweredEnumConstructor, constructorDescriptor) + val constructor = defaultClassDescriptor.createSimpleDelegatingConstructor( + loweredEnumConstructor, constructorDescriptor, + startOffset, endOffset, DECLARATION_ORIGIN_ENUM) constructors.add(constructorDescriptor) defaultClass.declarations.add(constructor) defaultEnumEntryConstructors.put(loweredEnumConstructor, constructorDescriptor) - if (loweredEnumConstructor.isPrimary) - primaryConstructor = constructorDescriptor val irConstructor = descriptorToIrConstructorWithDefaultArguments[loweredEnumConstructor] if (irConstructor != null) { @@ -199,7 +198,7 @@ internal class EnumClassLowering(val context: Context) : ClassLoweringPass { } val memberScope = SimpleMemberScope(irClass.descriptor.unsubstitutedMemberScope.getContributedDescriptors().toList()) - defaultClassDescriptor.initialize(memberScope, constructors, primaryConstructor) + defaultClassDescriptor.initialize(memberScope, constructors, null) return defaultClass } @@ -232,7 +231,9 @@ internal class EnumClassLowering(val context: Context) : ClassLoweringPass { } val constructorOfAny = irClass.descriptor.module.builtIns.any.constructors.first() - val constructor = implObjectDescriptor.createSimpleDelegatingConstructor(constructorOfAny, implObjectDescriptor.constructors.single()) + val constructor = implObjectDescriptor.createSimpleDelegatingConstructor( + constructorOfAny, implObjectDescriptor.constructors.single(), + startOffset, endOffset, DECLARATION_ORIGIN_ENUM) implObject.declarations.add(constructor) implObject.declarations.add(createSyntheticValuesPropertyDeclaration(enumEntries)) @@ -243,11 +244,11 @@ internal class EnumClassLowering(val context: Context) : ClassLoweringPass { } private fun createSyntheticValuesPropertyDeclaration(enumEntries: List): IrPropertyImpl { - val irValuesInitializer = context.createArrayOfExpression(irClass.descriptor.defaultType, - enumEntries.sortedBy { it.descriptor.name }.map { it.initializerExpression }) - val startOffset = irClass.startOffset val endOffset = irClass.endOffset + val irValuesInitializer = context.createArrayOfExpression(irClass.descriptor.defaultType, + enumEntries.sortedBy { it.descriptor.name }.map { it.initializerExpression }, startOffset, endOffset) + val irField = IrFieldImpl(startOffset, endOffset, DECLARATION_ORIGIN_ENUM, loweredEnum.valuesProperty, IrExpressionBodyImpl(startOffset, endOffset, irValuesInitializer))