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 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)
@@ -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>): IrExpression {
arrayElements: List<IrExpression>,
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)
}
}
@@ -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))))
}
}
@@ -175,17 +175,16 @@ internal class EnumClassLowering(val context: Context) : ClassLoweringPass {
val defaultClass = IrClassImpl(startOffset, endOffset, IrDeclarationOrigin.DEFINED, defaultClassDescriptor)
val constructors = mutableSetOf<ClassConstructorDescriptor>()
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<IrEnumEntry>): 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))