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.
This commit is contained in:
Igor Chevdar
2017-03-13 11:46:11 -04:00
committed by GitHub
parent b803e95c0b
commit 1cd229d8e5
4 changed files with 29 additions and 25 deletions
@@ -38,7 +38,8 @@ internal class EnumSpecialDescriptorsFactory(val context: Context) {
val memberScope = MemberScope.Empty val memberScope = MemberScope.Empty
val constructorOfAny = context.builtIns.any.constructors.first() 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) implObjectDescriptor.initialize(memberScope, setOf(constructorDescriptor), constructorDescriptor)
@@ -28,13 +28,13 @@ fun ir2stringWhole(ir: IrElement?): String {
return strWriter.toString() return strWriter.toString()
} }
internal fun ClassDescriptor.createSimpleDelegatingConstructorDescriptor(superConstructorDescriptor: ClassConstructorDescriptor) internal fun ClassDescriptor.createSimpleDelegatingConstructorDescriptor(superConstructorDescriptor: ClassConstructorDescriptor, isPrimary: Boolean = false)
: ClassConstructorDescriptor { : ClassConstructorDescriptor {
val constructorDescriptor = ClassConstructorDescriptorImpl.createSynthesized( val constructorDescriptor = ClassConstructorDescriptorImpl.createSynthesized(
this, /* containingDeclaration = */ this,
Annotations.EMPTY, /* annotations = */ Annotations.EMPTY,
superConstructorDescriptor.isPrimary, /* isPrimary = */ isPrimary,
SourceElement.NO_SOURCE) /* source = */ SourceElement.NO_SOURCE)
val valueParameters = superConstructorDescriptor.valueParameters.map { val valueParameters = superConstructorDescriptor.valueParameters.map {
it.copy(constructorDescriptor, it.name, it.index) it.copy(constructorDescriptor, it.name, it.index)
} }
@@ -44,23 +44,25 @@ internal fun ClassDescriptor.createSimpleDelegatingConstructorDescriptor(superCo
} }
internal fun ClassDescriptor.createSimpleDelegatingConstructor(superConstructorDescriptor: ClassConstructorDescriptor, internal fun ClassDescriptor.createSimpleDelegatingConstructor(superConstructorDescriptor: ClassConstructorDescriptor,
constructorDescriptor: ClassConstructorDescriptor) constructorDescriptor: ClassConstructorDescriptor,
startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin)
: IrConstructor { : IrConstructor {
val body = IrBlockBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, val body = IrBlockBodyImpl(startOffset, endOffset,
listOf( listOf(
IrDelegatingConstructorCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, superConstructorDescriptor).apply { IrDelegatingConstructorCallImpl(startOffset, endOffset, superConstructorDescriptor).apply {
constructorDescriptor.valueParameters.forEachIndexed { idx, parameter -> 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, internal fun Context.createArrayOfExpression(arrayElementType: KotlinType,
arrayElements: List<IrExpression>): IrExpression { arrayElements: List<IrExpression>,
startOffset: Int, endOffset: Int): IrExpression {
val kotlinPackage = irModule!!.descriptor.getPackage(FqName("kotlin")) val kotlinPackage = irModule!!.descriptor.getPackage(FqName("kotlin"))
val genericArrayOfFun = kotlinPackage.memberScope.getContributedFunctions(Name.identifier("arrayOf"), NoLookupLocation.FROM_BACKEND).first() val genericArrayOfFun = kotlinPackage.memberScope.getContributedFunctions(Name.identifier("arrayOf"), NoLookupLocation.FROM_BACKEND).first()
val typeParameter0 = genericArrayOfFun.typeParameters[0] val typeParameter0 = genericArrayOfFun.typeParameters[0]
@@ -72,9 +74,9 @@ internal fun Context.createArrayOfExpression(arrayElementType: KotlinType,
val valueParameter0 = substitutedArrayOfFun.valueParameters[0] val valueParameter0 = substitutedArrayOfFun.valueParameters[0]
val arg0VarargType = valueParameter0.type val arg0VarargType = valueParameter0.type
val arg0VarargElementType = valueParameter0.varargElementType!! 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) putValueArgument(0, arg0)
} }
} }
@@ -132,7 +132,7 @@ internal class PropertyDelegationLowering(val context: Context) : FileLoweringPa
DECLARATION_ORIGIN_KPROPERTIES_FOR_DELEGATION, DECLARATION_ORIGIN_KPROPERTIES_FOR_DELEGATION,
kPropertiesField, kPropertiesField,
IrExpressionBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrExpressionBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET,
context.createArrayOfExpression(kPropertyImplType, initializers)))) context.createArrayOfExpression(kPropertyImplType, initializers, UNDEFINED_OFFSET, UNDEFINED_OFFSET))))
} }
} }
@@ -175,17 +175,16 @@ internal class EnumClassLowering(val context: Context) : ClassLoweringPass {
val defaultClass = IrClassImpl(startOffset, endOffset, IrDeclarationOrigin.DEFINED, defaultClassDescriptor) val defaultClass = IrClassImpl(startOffset, endOffset, IrDeclarationOrigin.DEFINED, defaultClassDescriptor)
val constructors = mutableSetOf<ClassConstructorDescriptor>() val constructors = mutableSetOf<ClassConstructorDescriptor>()
var primaryConstructor: ClassConstructorDescriptor? = null
descriptor.constructors.forEach { descriptor.constructors.forEach {
val loweredEnumConstructor = loweredEnumConstructors[it]!! val loweredEnumConstructor = loweredEnumConstructors[it]!!
val constructorDescriptor = defaultClassDescriptor.createSimpleDelegatingConstructorDescriptor(loweredEnumConstructor) 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) constructors.add(constructorDescriptor)
defaultClass.declarations.add(constructor) defaultClass.declarations.add(constructor)
defaultEnumEntryConstructors.put(loweredEnumConstructor, constructorDescriptor) defaultEnumEntryConstructors.put(loweredEnumConstructor, constructorDescriptor)
if (loweredEnumConstructor.isPrimary)
primaryConstructor = constructorDescriptor
val irConstructor = descriptorToIrConstructorWithDefaultArguments[loweredEnumConstructor] val irConstructor = descriptorToIrConstructorWithDefaultArguments[loweredEnumConstructor]
if (irConstructor != null) { if (irConstructor != null) {
@@ -199,7 +198,7 @@ internal class EnumClassLowering(val context: Context) : ClassLoweringPass {
} }
val memberScope = SimpleMemberScope(irClass.descriptor.unsubstitutedMemberScope.getContributedDescriptors().toList()) val memberScope = SimpleMemberScope(irClass.descriptor.unsubstitutedMemberScope.getContributedDescriptors().toList())
defaultClassDescriptor.initialize(memberScope, constructors, primaryConstructor) defaultClassDescriptor.initialize(memberScope, constructors, null)
return defaultClass return defaultClass
} }
@@ -232,7 +231,9 @@ internal class EnumClassLowering(val context: Context) : ClassLoweringPass {
} }
val constructorOfAny = irClass.descriptor.module.builtIns.any.constructors.first() 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(constructor)
implObject.declarations.add(createSyntheticValuesPropertyDeclaration(enumEntries)) implObject.declarations.add(createSyntheticValuesPropertyDeclaration(enumEntries))
@@ -243,11 +244,11 @@ internal class EnumClassLowering(val context: Context) : ClassLoweringPass {
} }
private fun createSyntheticValuesPropertyDeclaration(enumEntries: List<IrEnumEntry>): IrPropertyImpl { private fun createSyntheticValuesPropertyDeclaration(enumEntries: List<IrEnumEntry>): IrPropertyImpl {
val irValuesInitializer = context.createArrayOfExpression(irClass.descriptor.defaultType,
enumEntries.sortedBy { it.descriptor.name }.map { it.initializerExpression })
val startOffset = irClass.startOffset val startOffset = irClass.startOffset
val endOffset = irClass.endOffset 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, val irField = IrFieldImpl(startOffset, endOffset, DECLARATION_ORIGIN_ENUM,
loweredEnum.valuesProperty, loweredEnum.valuesProperty,
IrExpressionBodyImpl(startOffset, endOffset, irValuesInitializer)) IrExpressionBodyImpl(startOffset, endOffset, irValuesInitializer))