Minor. Reformat

This commit is contained in:
Mikhael Bogdanov
2018-04-27 09:34:44 +02:00
parent ed44327569
commit 077f3a4ed2
3 changed files with 210 additions and 179 deletions
@@ -38,162 +38,174 @@ import org.jetbrains.kotlin.types.*
class JvmSharedVariablesManager(val builtIns: KotlinBuiltIns) : SharedVariablesManager { class JvmSharedVariablesManager(val builtIns: KotlinBuiltIns) : SharedVariablesManager {
private val kotlinJvmInternalPackage = KnownPackageFragmentDescriptor(builtIns.builtInsModule, FqName("kotlin.jvm.internal")) private val kotlinJvmInternalPackage = KnownPackageFragmentDescriptor(builtIns.builtInsModule, FqName("kotlin.jvm.internal"))
private val refNamespaceClass = KnownClassDescriptor.createClass(Name.identifier("Ref"), kotlinJvmInternalPackage, listOf(builtIns.anyType)) private val refNamespaceClass =
KnownClassDescriptor.createClass(Name.identifier("Ref"), kotlinJvmInternalPackage, listOf(builtIns.anyType))
private class PrimitiveRefDescriptorsProvider(type: KotlinType, refClass: ClassDescriptor) { private class PrimitiveRefDescriptorsProvider(type: KotlinType, refClass: ClassDescriptor) {
val refType: KotlinType = refClass.defaultType val refType: KotlinType = refClass.defaultType
val refConstructor: ClassConstructorDescriptor = val refConstructor: ClassConstructorDescriptor =
ClassConstructorDescriptorImpl.create(refClass, Annotations.EMPTY, true, SourceElement.NO_SOURCE).apply { ClassConstructorDescriptorImpl.create(refClass, Annotations.EMPTY, true, SourceElement.NO_SOURCE).apply {
initialize(emptyList(), Visibilities.PUBLIC, emptyList()) initialize(emptyList(), Visibilities.PUBLIC, emptyList())
returnType = refType returnType = refType
} }
val elementField: PropertyDescriptor = val elementField: PropertyDescriptor =
PropertyDescriptorImpl.create( PropertyDescriptorImpl.create(
refClass, Annotations.EMPTY, Modality.FINAL, Visibilities.PUBLIC, true, refClass, Annotations.EMPTY, Modality.FINAL, Visibilities.PUBLIC, true,
Name.identifier("element"), CallableMemberDescriptor.Kind.DECLARATION, SourceElement.NO_SOURCE, Name.identifier("element"), CallableMemberDescriptor.Kind.DECLARATION, SourceElement.NO_SOURCE,
/* lateInit = */ false, /* isConst = */ false, /* isExpect = */ false, /* isActual = */ false, /* lateInit = */ false, /* isConst = */ false, /* isExpect = */ false, /* isActual = */ false,
/* isExternal = */ false, /* isDelegated = */ false /* isExternal = */ false, /* isDelegated = */ false
).initialize(type, dispatchReceiverParameter = refClass.thisAsReceiverParameter) ).initialize(type, dispatchReceiverParameter = refClass.thisAsReceiverParameter)
} }
private val primitiveRefDescriptorProviders: Map<PrimitiveType, PrimitiveRefDescriptorsProvider> = private val primitiveRefDescriptorProviders: Map<PrimitiveType, PrimitiveRefDescriptorsProvider> =
PrimitiveType.values().associate { PrimitiveType.values().associate {
val type = builtIns.getPrimitiveKotlinType(it) val type = builtIns.getPrimitiveKotlinType(it)
val refClassName = Name.identifier(it.typeName.asString() + "Ref") val refClassName = Name.identifier(it.typeName.asString() + "Ref")
val refClass = KnownClassDescriptor.createClass(refClassName, refNamespaceClass, listOf(builtIns.anyType)) val refClass = KnownClassDescriptor.createClass(refClassName, refNamespaceClass, listOf(builtIns.anyType))
it to PrimitiveRefDescriptorsProvider(type, refClass) it to PrimitiveRefDescriptorsProvider(type, refClass)
} }
private inner class ObjectRefDescriptorsProvider { private inner class ObjectRefDescriptorsProvider {
val genericRefClass: ClassDescriptor = val genericRefClass: ClassDescriptor =
KnownClassDescriptor.createClassWithTypeParameters( KnownClassDescriptor.createClassWithTypeParameters(
Name.identifier("ObjectRef"), refNamespaceClass, listOf(builtIns.anyType), listOf(Name.identifier("T")) Name.identifier("ObjectRef"), refNamespaceClass, listOf(builtIns.anyType), listOf(Name.identifier("T"))
) )
val genericRefConstructor: ClassConstructorDescriptor = val genericRefConstructor: ClassConstructorDescriptor =
ClassConstructorDescriptorImpl.create(genericRefClass, Annotations.EMPTY, true, SourceElement.NO_SOURCE).apply { ClassConstructorDescriptorImpl.create(genericRefClass, Annotations.EMPTY, true, SourceElement.NO_SOURCE).apply {
initialize(emptyList(), Visibilities.PUBLIC) initialize(emptyList(), Visibilities.PUBLIC)
val typeParameter = typeParameters[0] val typeParameter = typeParameters[0]
val typeParameterType = KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope(Annotations.EMPTY, typeParameter.typeConstructor, listOf(), false, MemberScope.Empty) val typeParameterType = KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope(
returnType = KotlinTypeFactory.simpleNotNullType(Annotations.EMPTY, genericRefClass, listOf(TypeProjectionImpl(Variance.INVARIANT, typeParameterType))) Annotations.EMPTY,
} typeParameter.typeConstructor,
listOf(),
false,
MemberScope.Empty
)
returnType = KotlinTypeFactory.simpleNotNullType(
Annotations.EMPTY,
genericRefClass,
listOf(TypeProjectionImpl(Variance.INVARIANT, typeParameterType))
)
}
val constructorTypeParameter: TypeParameterDescriptor = val constructorTypeParameter: TypeParameterDescriptor =
genericRefConstructor.typeParameters[0] genericRefConstructor.typeParameters[0]
fun getSubstitutedRefConstructor(valueType: KotlinType): ClassConstructorDescriptor = fun getSubstitutedRefConstructor(valueType: KotlinType): ClassConstructorDescriptor =
genericRefConstructor.substitute(TypeSubstitutor.create( genericRefConstructor.substitute(
mapOf(constructorTypeParameter.typeConstructor to TypeProjectionImpl(Variance.INVARIANT, valueType)) TypeSubstitutor.create(
))!! mapOf(constructorTypeParameter.typeConstructor to TypeProjectionImpl(Variance.INVARIANT, valueType))
)
)!!
val genericElementField: PropertyDescriptor = val genericElementField: PropertyDescriptor =
PropertyDescriptorImpl.create( PropertyDescriptorImpl.create(
genericRefClass, Annotations.EMPTY, Modality.FINAL, Visibilities.PUBLIC, true, genericRefClass, Annotations.EMPTY, Modality.FINAL, Visibilities.PUBLIC, true,
Name.identifier("element"), CallableMemberDescriptor.Kind.DECLARATION, SourceElement.NO_SOURCE, Name.identifier("element"), CallableMemberDescriptor.Kind.DECLARATION, SourceElement.NO_SOURCE,
/* lateInit = */ false, /* isConst = */ false, /* isExpect = */ false, /* isActual = */ false, /* lateInit = */ false, /* isConst = */ false, /* isExpect = */ false, /* isActual = */ false,
/* isExternal = */ false, /* isDelegated = */ false /* isExternal = */ false, /* isDelegated = */ false
).initialize( ).initialize(
type = builtIns.anyType, type = builtIns.anyType,
dispatchReceiverParameter = genericRefClass.thisAsReceiverParameter dispatchReceiverParameter = genericRefClass.thisAsReceiverParameter
) )
fun getRefType(valueType: KotlinType) = fun getRefType(valueType: KotlinType) =
KotlinTypeFactory.simpleNotNullType(Annotations.EMPTY, genericRefClass, listOf(TypeProjectionImpl(Variance.INVARIANT, valueType))) KotlinTypeFactory.simpleNotNullType(
Annotations.EMPTY,
genericRefClass,
listOf(TypeProjectionImpl(Variance.INVARIANT, valueType))
)
} }
private val objectRefDescriptorsProvider = ObjectRefDescriptorsProvider() private val objectRefDescriptorsProvider = ObjectRefDescriptorsProvider()
override fun createSharedVariableDescriptor(variableDescriptor: VariableDescriptor): VariableDescriptor = override fun createSharedVariableDescriptor(variableDescriptor: VariableDescriptor): VariableDescriptor =
LocalVariableDescriptor( LocalVariableDescriptor(
variableDescriptor.containingDeclaration, variableDescriptor.annotations, variableDescriptor.name, variableDescriptor.containingDeclaration, variableDescriptor.annotations, variableDescriptor.name,
getSharedVariableType(variableDescriptor.type), getSharedVariableType(variableDescriptor.type),
false, false, variableDescriptor.isLateInit, variableDescriptor.source false, false, variableDescriptor.isLateInit, variableDescriptor.source
) )
override fun defineSharedValue(sharedVariableDescriptor: VariableDescriptor, originalDeclaration: IrVariable): IrStatement { override fun defineSharedValue(sharedVariableDescriptor: VariableDescriptor, originalDeclaration: IrVariable): IrStatement {
val valueType = originalDeclaration.descriptor.type val valueType = originalDeclaration.descriptor.type
val primitiveRefDescriptorsProvider = primitiveRefDescriptorProviders[getPrimitiveType(valueType)] val primitiveRefDescriptorsProvider = primitiveRefDescriptorProviders[getPrimitiveType(valueType)]
val refConstructor = val refConstructor =
primitiveRefDescriptorsProvider?.refConstructor ?: primitiveRefDescriptorsProvider?.refConstructor ?: objectRefDescriptorsProvider.getSubstitutedRefConstructor(valueType)
objectRefDescriptorsProvider.getSubstitutedRefConstructor(valueType)
val refConstructorTypeArguments = val refConstructorTypeArguments =
if (primitiveRefDescriptorsProvider != null) null if (primitiveRefDescriptorsProvider != null) null
else mapOf(objectRefDescriptorsProvider.constructorTypeParameter to valueType) else mapOf(objectRefDescriptorsProvider.constructorTypeParameter to valueType)
val elementPropertyDescriptor = val elementPropertyDescriptor =
primitiveRefDescriptorsProvider?.elementField ?: primitiveRefDescriptorsProvider?.elementField ?: objectRefDescriptorsProvider.genericElementField
objectRefDescriptorsProvider.genericElementField
val refConstructorCall = IrCallImpl( val refConstructorCall = IrCallImpl(
originalDeclaration.startOffset, originalDeclaration.endOffset, originalDeclaration.startOffset, originalDeclaration.endOffset,
refConstructor, refConstructorTypeArguments refConstructor, refConstructorTypeArguments
) )
val sharedVariableDeclaration = IrVariableImpl( val sharedVariableDeclaration = IrVariableImpl(
originalDeclaration.startOffset, originalDeclaration.endOffset, originalDeclaration.origin, originalDeclaration.startOffset, originalDeclaration.endOffset, originalDeclaration.origin,
sharedVariableDescriptor, refConstructorCall sharedVariableDescriptor, refConstructorCall
) )
val initializer = originalDeclaration.initializer ?: val initializer = originalDeclaration.initializer ?: return sharedVariableDeclaration
return sharedVariableDeclaration
val sharedVariableInitialization = IrSetFieldImpl( val sharedVariableInitialization = IrSetFieldImpl(
initializer.startOffset, initializer.endOffset, initializer.startOffset, initializer.endOffset,
elementPropertyDescriptor, elementPropertyDescriptor,
IrGetValueImpl(initializer.startOffset, initializer.endOffset, sharedVariableDescriptor), IrGetValueImpl(initializer.startOffset, initializer.endOffset, sharedVariableDescriptor),
initializer initializer
) )
return IrCompositeImpl( return IrCompositeImpl(
originalDeclaration.startOffset, originalDeclaration.endOffset, builtIns.unitType, null, originalDeclaration.startOffset, originalDeclaration.endOffset, builtIns.unitType, null,
listOf(sharedVariableDeclaration, sharedVariableInitialization) listOf(sharedVariableDeclaration, sharedVariableInitialization)
) )
} }
private fun getElementFieldDescriptor(valueType: KotlinType): PropertyDescriptor { private fun getElementFieldDescriptor(valueType: KotlinType): PropertyDescriptor {
val primitiveRefDescriptorsProvider = primitiveRefDescriptorProviders[getPrimitiveType(valueType)] val primitiveRefDescriptorsProvider = primitiveRefDescriptorProviders[getPrimitiveType(valueType)]
return primitiveRefDescriptorsProvider?.elementField ?: return primitiveRefDescriptorsProvider?.elementField ?: objectRefDescriptorsProvider.genericElementField
objectRefDescriptorsProvider.genericElementField
} }
override fun getSharedValue(sharedVariableDescriptor: VariableDescriptor, originalGet: IrGetValue): IrExpression = override fun getSharedValue(sharedVariableDescriptor: VariableDescriptor, originalGet: IrGetValue): IrExpression =
IrGetFieldImpl( IrGetFieldImpl(
originalGet.startOffset, originalGet.endOffset, originalGet.startOffset, originalGet.endOffset,
getElementFieldDescriptor(originalGet.descriptor.type), getElementFieldDescriptor(originalGet.descriptor.type),
IrGetValueImpl(originalGet.startOffset, originalGet.endOffset, sharedVariableDescriptor), IrGetValueImpl(originalGet.startOffset, originalGet.endOffset, sharedVariableDescriptor),
originalGet.origin originalGet.origin
) )
override fun setSharedValue(sharedVariableDescriptor: VariableDescriptor, originalSet: IrSetVariable): IrExpression = override fun setSharedValue(sharedVariableDescriptor: VariableDescriptor, originalSet: IrSetVariable): IrExpression =
IrSetFieldImpl( IrSetFieldImpl(
originalSet.startOffset, originalSet.endOffset, originalSet.startOffset, originalSet.endOffset,
getElementFieldDescriptor(originalSet.descriptor.type), getElementFieldDescriptor(originalSet.descriptor.type),
IrGetValueImpl(originalSet.startOffset, originalSet.endOffset, sharedVariableDescriptor), IrGetValueImpl(originalSet.startOffset, originalSet.endOffset, sharedVariableDescriptor),
originalSet.value, originalSet.value,
originalSet.origin originalSet.origin
) )
private fun getSharedVariableType(valueType: KotlinType): KotlinType = private fun getSharedVariableType(valueType: KotlinType): KotlinType =
primitiveRefDescriptorProviders[getPrimitiveType(valueType)]?.refType ?: primitiveRefDescriptorProviders[getPrimitiveType(valueType)]?.refType ?: objectRefDescriptorsProvider.getRefType(valueType)
objectRefDescriptorsProvider.getRefType(valueType)
private fun getPrimitiveType(type: KotlinType): PrimitiveType? = private fun getPrimitiveType(type: KotlinType): PrimitiveType? =
when { when {
KotlinBuiltIns.isBoolean(type) -> PrimitiveType.BOOLEAN KotlinBuiltIns.isBoolean(type) -> PrimitiveType.BOOLEAN
KotlinBuiltIns.isChar(type) -> PrimitiveType.CHAR KotlinBuiltIns.isChar(type) -> PrimitiveType.CHAR
KotlinBuiltIns.isByte(type) -> PrimitiveType.BYTE KotlinBuiltIns.isByte(type) -> PrimitiveType.BYTE
KotlinBuiltIns.isShort(type) -> PrimitiveType.SHORT KotlinBuiltIns.isShort(type) -> PrimitiveType.SHORT
KotlinBuiltIns.isInt(type) -> PrimitiveType.INT KotlinBuiltIns.isInt(type) -> PrimitiveType.INT
KotlinBuiltIns.isLong(type) -> PrimitiveType.LONG KotlinBuiltIns.isLong(type) -> PrimitiveType.LONG
KotlinBuiltIns.isFloat(type) -> PrimitiveType.FLOAT KotlinBuiltIns.isFloat(type) -> PrimitiveType.FLOAT
KotlinBuiltIns.isDouble(type) -> PrimitiveType.DOUBLE KotlinBuiltIns.isDouble(type) -> PrimitiveType.DOUBLE
else -> null else -> null
} }
} }
@@ -118,28 +118,28 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
val constructorDescriptor = enumConstructor.descriptor val constructorDescriptor = enumConstructor.descriptor
val loweredConstructorDescriptor = lowerEnumConstructor(constructorDescriptor) val loweredConstructorDescriptor = lowerEnumConstructor(constructorDescriptor)
return IrConstructorImpl( return IrConstructorImpl(
enumConstructor.startOffset, enumConstructor.endOffset, enumConstructor.origin, enumConstructor.startOffset, enumConstructor.endOffset, enumConstructor.origin,
loweredConstructorDescriptor, loweredConstructorDescriptor,
enumConstructor.body!! // will be transformed later enumConstructor.body!! // will be transformed later
) )
} }
private fun lowerEnumConstructor(constructorDescriptor: ClassConstructorDescriptor): ClassConstructorDescriptor { private fun lowerEnumConstructor(constructorDescriptor: ClassConstructorDescriptor): ClassConstructorDescriptor {
val loweredConstructorDescriptor = ClassConstructorDescriptorImpl.createSynthesized( val loweredConstructorDescriptor = ClassConstructorDescriptorImpl.createSynthesized(
constructorDescriptor.containingDeclaration, constructorDescriptor.containingDeclaration,
constructorDescriptor.annotations, constructorDescriptor.annotations,
constructorDescriptor.isPrimary, constructorDescriptor.isPrimary,
constructorDescriptor.source constructorDescriptor.source
) )
val valueParameters = val valueParameters =
listOf( listOf(
loweredConstructorDescriptor.createValueParameter(0, "name", context.builtIns.stringType), loweredConstructorDescriptor.createValueParameter(0, "name", context.builtIns.stringType),
loweredConstructorDescriptor.createValueParameter(1, "ordinal", context.builtIns.intType) loweredConstructorDescriptor.createValueParameter(1, "ordinal", context.builtIns.intType)
) + ) +
constructorDescriptor.valueParameters.map { constructorDescriptor.valueParameters.map {
lowerConstructorValueParameter(loweredConstructorDescriptor, it) lowerConstructorValueParameter(loweredConstructorDescriptor, it)
} }
loweredConstructorDescriptor.initialize(valueParameters, Visibilities.PROTECTED) loweredConstructorDescriptor.initialize(valueParameters, Visibilities.PROTECTED)
loweredConstructorDescriptor.returnType = constructorDescriptor.returnType loweredConstructorDescriptor.returnType = constructorDescriptor.returnType
@@ -150,13 +150,13 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
} }
private fun lowerConstructorValueParameter( private fun lowerConstructorValueParameter(
loweredConstructorDescriptor: ClassConstructorDescriptor, loweredConstructorDescriptor: ClassConstructorDescriptor,
valueParameterDescriptor: ValueParameterDescriptor valueParameterDescriptor: ValueParameterDescriptor
): ValueParameterDescriptor { ): ValueParameterDescriptor {
val loweredValueParameterDescriptor = valueParameterDescriptor.copy( val loweredValueParameterDescriptor = valueParameterDescriptor.copy(
loweredConstructorDescriptor, loweredConstructorDescriptor,
valueParameterDescriptor.name, valueParameterDescriptor.name,
valueParameterDescriptor.index + 2 valueParameterDescriptor.index + 2
) )
loweredEnumConstructorParameters[valueParameterDescriptor] = loweredValueParameterDescriptor loweredEnumConstructorParameters[valueParameterDescriptor] = loweredValueParameterDescriptor
return loweredValueParameterDescriptor return loweredValueParameterDescriptor
@@ -165,10 +165,11 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
private fun lowerEnumEntries() { private fun lowerEnumEntries() {
irClass.declarations.transformFlat { declaration -> irClass.declarations.transformFlat { declaration ->
if (declaration is IrEnumEntry) { if (declaration is IrEnumEntry) {
listOfNotNull(createFieldForEnumEntry(declaration), listOfNotNull(
lowerEnumEntryClass(declaration.correspondingClass)) createFieldForEnumEntry(declaration),
} lowerEnumEntryClass(declaration.correspondingClass)
else null )
} else null
} }
} }
@@ -188,9 +189,9 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
val enumEntryInitializer = enumEntry.initializerExpression!! val enumEntryInitializer = enumEntry.initializerExpression!!
return IrFieldImpl( return IrFieldImpl(
enumEntry.startOffset, enumEntry.endOffset, JvmLoweredDeclarationOrigin.FIELD_FOR_ENUM_ENTRY, enumEntry.startOffset, enumEntry.endOffset, JvmLoweredDeclarationOrigin.FIELD_FOR_ENUM_ENTRY,
fieldPropertyDescriptor, fieldPropertyDescriptor,
IrExpressionBodyImpl(enumEntryInitializer) IrExpressionBodyImpl(enumEntryInitializer)
) )
} }
@@ -204,14 +205,14 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
} }
private fun findFunctionDescriptorForMemberWithSyntheticBodyKind(kind: IrSyntheticBodyKind): FunctionDescriptor = private fun findFunctionDescriptorForMemberWithSyntheticBodyKind(kind: IrSyntheticBodyKind): FunctionDescriptor =
irClass.declarations irClass.declarations
.first { .first {
it is IrFunction && it is IrFunction &&
it.body.let { body -> it.body.let { body ->
body is IrSyntheticBody && body.kind == kind body is IrSyntheticBody && body.kind == kind
} }
} }
.descriptor as FunctionDescriptor .descriptor as FunctionDescriptor
private fun createSyntheticValuesFieldDeclaration(): IrFieldImpl { private fun createSyntheticValuesFieldDeclaration(): IrFieldImpl {
@@ -220,26 +221,28 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
val irValuesInitializer = createSyntheticValuesFieldInitializerExpression() val irValuesInitializer = createSyntheticValuesFieldInitializerExpression()
return IrFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, JvmLoweredDeclarationOrigin.FIELD_FOR_ENUM_VALUES, return IrFieldImpl(
valuesFieldDescriptor, UNDEFINED_OFFSET, UNDEFINED_OFFSET, JvmLoweredDeclarationOrigin.FIELD_FOR_ENUM_VALUES,
IrExpressionBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irValuesInitializer)) valuesFieldDescriptor,
IrExpressionBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irValuesInitializer)
)
} }
private fun createSyntheticValuesFieldInitializerExpression(): IrExpression = private fun createSyntheticValuesFieldInitializerExpression(): IrExpression =
createArrayOfExpression( createArrayOfExpression(
irClass.descriptor.defaultType, irClass.descriptor.defaultType,
enumEntryFields.map { fieldDescriptor -> enumEntryFields.map { fieldDescriptor ->
IrGetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, fieldDescriptor) IrGetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, fieldDescriptor)
}) })
private fun createSyntheticValuesFieldDescriptor(valuesArrayType: SimpleType): PropertyDescriptorImpl { private fun createSyntheticValuesFieldDescriptor(valuesArrayType: SimpleType): PropertyDescriptorImpl {
return JvmPropertyDescriptorImpl.createStaticVal( return JvmPropertyDescriptorImpl.createStaticVal(
Name.identifier("\$VALUES"), Name.identifier("\$VALUES"),
valuesArrayType, valuesArrayType,
irClass.descriptor, irClass.descriptor,
Annotations.EMPTY, Annotations.EMPTY,
Modality.FINAL, Visibilities.PRIVATE, Opcodes.ACC_SYNTHETIC, Modality.FINAL, Visibilities.PRIVATE, Opcodes.ACC_SYNTHETIC,
irClass.descriptor.source irClass.descriptor.source
) )
} }
@@ -248,7 +251,7 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
} }
private inner class InEnumClassConstructor(val enumClassConstructor: ClassConstructorDescriptor) : private inner class InEnumClassConstructor(val enumClassConstructor: ClassConstructorDescriptor) :
EnumConstructorCallTransformer { EnumConstructorCallTransformer {
override fun transform(enumConstructorCall: IrEnumConstructorCall): IrExpression { override fun transform(enumConstructorCall: IrEnumConstructorCall): IrExpression {
val startOffset = enumConstructorCall.startOffset val startOffset = enumConstructorCall.startOffset
val endOffset = enumConstructorCall.endOffset val endOffset = enumConstructorCall.endOffset
@@ -327,17 +330,21 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
throw AssertionError("Unexpected delegating constructor call within enum entry: $enumEntry") throw AssertionError("Unexpected delegating constructor call within enum entry: $enumEntry")
} }
abstract fun createConstructorCall(startOffset: Int, endOffset: Int, loweredConstructor: ClassConstructorDescriptor): IrMemberAccessExpression abstract fun createConstructorCall(
startOffset: Int,
endOffset: Int,
loweredConstructor: ClassConstructorDescriptor
): IrMemberAccessExpression
} }
private inner class InEnumEntryClassConstructor(enumEntry: ClassDescriptor) : InEnumEntry(enumEntry) { private inner class InEnumEntryClassConstructor(enumEntry: ClassDescriptor) : InEnumEntry(enumEntry) {
override fun createConstructorCall(startOffset: Int, endOffset: Int, loweredConstructor: ClassConstructorDescriptor) = override fun createConstructorCall(startOffset: Int, endOffset: Int, loweredConstructor: ClassConstructorDescriptor) =
IrDelegatingConstructorCallImpl(startOffset, endOffset, loweredConstructor) IrDelegatingConstructorCallImpl(startOffset, endOffset, loweredConstructor)
} }
private inner class InEnumEntryInitializer(enumEntry: ClassDescriptor) : InEnumEntry(enumEntry) { private inner class InEnumEntryInitializer(enumEntry: ClassDescriptor) : InEnumEntry(enumEntry) {
override fun createConstructorCall(startOffset: Int, endOffset: Int, loweredConstructor: ClassConstructorDescriptor) = override fun createConstructorCall(startOffset: Int, endOffset: Int, loweredConstructor: ClassConstructorDescriptor) =
IrCallImpl(startOffset, endOffset, loweredConstructor) IrCallImpl(startOffset, endOffset, loweredConstructor)
} }
private inner class EnumClassBodyTransformer : IrElementTransformerVoid() { private inner class EnumClassBodyTransformer : IrElementTransformerVoid() {
@@ -350,7 +357,7 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
return declaration return declaration
} }
assert(enumConstructorCallTransformer == null) { "Nested enum entry initialization:\n${declaration.dump()}"} assert(enumConstructorCallTransformer == null) { "Nested enum entry initialization:\n${declaration.dump()}" }
enumConstructorCallTransformer = InEnumEntryInitializer(enumEntry) enumConstructorCallTransformer = InEnumEntryInitializer(enumEntry)
@@ -369,11 +376,10 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
val previous = enumConstructorCallTransformer val previous = enumConstructorCallTransformer
if (containingClass.kind == ClassKind.ENUM_ENTRY) { if (containingClass.kind == ClassKind.ENUM_ENTRY) {
assert(enumConstructorCallTransformer == null) { "Nested enum entry initialization:\n${declaration.dump()}"} assert(enumConstructorCallTransformer == null) { "Nested enum entry initialization:\n${declaration.dump()}" }
enumConstructorCallTransformer = InEnumEntryClassConstructor(containingClass) enumConstructorCallTransformer = InEnumEntryClassConstructor(containingClass)
} } else if (containingClass.kind == ClassKind.ENUM_CLASS) {
else if (containingClass.kind == ClassKind.ENUM_CLASS) { assert(enumConstructorCallTransformer == null) { "Nested enum entry initialization:\n${declaration.dump()}" }
assert(enumConstructorCallTransformer == null) { "Nested enum entry initialization:\n${declaration.dump()}"}
enumConstructorCallTransformer = InEnumClassConstructor(constructorDescriptor) enumConstructorCallTransformer = InEnumClassConstructor(constructorDescriptor)
} }
@@ -387,9 +393,10 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
override fun visitEnumConstructorCall(expression: IrEnumConstructorCall): IrExpression { override fun visitEnumConstructorCall(expression: IrEnumConstructorCall): IrExpression {
expression.transformChildrenVoid(this) expression.transformChildrenVoid(this)
val callTransformer = enumConstructorCallTransformer ?: val callTransformer = enumConstructorCallTransformer ?: throw AssertionError(
throw AssertionError("Enum constructor call outside of enum entry initialization or enum class constructor:\n" + "Enum constructor call outside of enum entry initialization or enum class constructor:\n" +
irClass.dump()) irClass.dump()
)
return callTransformer.transform(expression) return callTransformer.transform(expression)
} }
@@ -398,9 +405,10 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
expression.transformChildrenVoid(this) expression.transformChildrenVoid(this)
if (expression.descriptor.containingDeclaration.kind == ClassKind.ENUM_CLASS) { if (expression.descriptor.containingDeclaration.kind == ClassKind.ENUM_CLASS) {
val callTransformer = enumConstructorCallTransformer ?: val callTransformer = enumConstructorCallTransformer ?: throw AssertionError(
throw AssertionError("Enum constructor call outside of enum entry initialization or enum class constructor:\n" + "Enum constructor call outside of enum entry initialization or enum class constructor:\n" +
irClass.dump()) irClass.dump()
)
return callTransformer.transform(expression) return callTransformer.transform(expression)
} }
@@ -412,8 +420,7 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
val loweredParameter = loweredEnumConstructorParameters[expression.descriptor] val loweredParameter = loweredEnumConstructorParameters[expression.descriptor]
return if (loweredParameter != null) { return if (loweredParameter != null) {
IrGetValueImpl(expression.startOffset, expression.endOffset, loweredParameter, expression.origin) IrGetValueImpl(expression.startOffset, expression.endOffset, loweredParameter, expression.origin)
} } else {
else {
expression expression
} }
} }
@@ -436,13 +443,15 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
val typeSubstitutor = TypeSubstitutor.create(mapOf(typeParameterT.typeConstructor to TypeProjectionImpl(enumClassType))) val typeSubstitutor = TypeSubstitutor.create(mapOf(typeParameterT.typeConstructor to TypeProjectionImpl(enumClassType)))
val substitutedValueOf = unsubstitutedValueOf.substitute(typeSubstitutor)!! val substitutedValueOf = unsubstitutedValueOf.substitute(typeSubstitutor)!!
val irValueOfCall = IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, substitutedValueOf, mapOf(typeParameterT to enumClassType)) val irValueOfCall =
IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, substitutedValueOf, mapOf(typeParameterT to enumClassType))
irValueOfCall.putValueArgument( irValueOfCall.putValueArgument(
0, IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, valueOfFunctionDescriptor.valueParameters[0])) 0, IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, valueOfFunctionDescriptor.valueParameters[0])
)
return IrBlockBodyImpl( return IrBlockBodyImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, UNDEFINED_OFFSET, UNDEFINED_OFFSET,
listOf(IrReturnImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, valueOfFunctionDescriptor, irValueOfCall)) listOf(IrReturnImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, valueOfFunctionDescriptor, irValueOfCall))
) )
} }
@@ -454,8 +463,8 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
} }
return IrBlockBodyImpl( return IrBlockBodyImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, UNDEFINED_OFFSET, UNDEFINED_OFFSET,
listOf(IrReturnImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, valuesFunctionDescriptor, irCloneValues)) listOf(IrReturnImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, valuesFunctionDescriptor, irCloneValues))
) )
} }
} }
@@ -55,19 +55,25 @@ class ObjectClassLowering(val context: JvmBackendContext) : IrElementTransformer
val publicInstanceDescriptor = context.descriptorsFactory.getFieldDescriptorForObjectInstance(irClass.descriptor) val publicInstanceDescriptor = context.descriptorsFactory.getFieldDescriptorForObjectInstance(irClass.descriptor)
val constructor = irClass.descriptor.unsubstitutedPrimaryConstructor ?: val constructor = irClass.descriptor.unsubstitutedPrimaryConstructor
throw AssertionError("Object should have a primary constructor: ${irClass.descriptor}") ?: throw AssertionError("Object should have a primary constructor: ${irClass.descriptor}")
val publicInstanceOwner = if (irClass.descriptor.isCompanionObject) parentScope!!.irElement as IrDeclarationContainer else irClass val publicInstanceOwner = if (irClass.descriptor.isCompanionObject) parentScope!!.irElement as IrDeclarationContainer else irClass
if (isCompanionObjectInInterfaceNotIntrinsic(irClass.descriptor)) { if (isCompanionObjectInInterfaceNotIntrinsic(irClass.descriptor)) {
// TODO rename to $$INSTANCE // TODO rename to $$INSTANCE
val privateInstance = publicInstanceDescriptor.copy(irClass.descriptor, Modality.FINAL, Visibilities.PROTECTED/*TODO package local*/, CallableMemberDescriptor.Kind.SYNTHESIZED, false) as PropertyDescriptor val privateInstance = publicInstanceDescriptor.copy(
irClass.descriptor,
Modality.FINAL,
Visibilities.PROTECTED/*TODO package local*/,
CallableMemberDescriptor.Kind.SYNTHESIZED,
false
) as PropertyDescriptor
privateInstance.name privateInstance.name
val field = createInstanceFieldWithInitializer(privateInstance, constructor, irClass) val field = createInstanceFieldWithInitializer(privateInstance, constructor, irClass)
createFieldWithCustomInitializer( createFieldWithCustomInitializer(
publicInstanceDescriptor, publicInstanceDescriptor,
IrGetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, field.symbol), IrGetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, field.symbol),
publicInstanceOwner publicInstanceOwner
) )
} else { } else {
createInstanceFieldWithInitializer(publicInstanceDescriptor, constructor, publicInstanceOwner) createInstanceFieldWithInitializer(publicInstanceDescriptor, constructor, publicInstanceOwner)
@@ -75,22 +81,26 @@ class ObjectClassLowering(val context: JvmBackendContext) : IrElementTransformer
} }
private fun createInstanceFieldWithInitializer( private fun createInstanceFieldWithInitializer(
instanceFieldDescriptor: PropertyDescriptor, instanceFieldDescriptor: PropertyDescriptor,
constructor: ClassConstructorDescriptor, constructor: ClassConstructorDescriptor,
instanceOwner: IrDeclarationContainer instanceOwner: IrDeclarationContainer
): IrField = ): IrField =
createFieldWithCustomInitializer(instanceFieldDescriptor, IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, constructor), instanceOwner) createFieldWithCustomInitializer(
instanceFieldDescriptor,
IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, constructor),
instanceOwner
)
private fun createFieldWithCustomInitializer( private fun createFieldWithCustomInitializer(
instanceFieldDescriptor: PropertyDescriptor, instanceFieldDescriptor: PropertyDescriptor,
instanceInitializer: IrExpression, instanceInitializer: IrExpression,
instanceOwner: IrDeclarationContainer instanceOwner: IrDeclarationContainer
): IrField = ): IrField =
IrFieldImpl( IrFieldImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, JvmLoweredDeclarationOrigin.FIELD_FOR_OBJECT_INSTANCE, UNDEFINED_OFFSET, UNDEFINED_OFFSET, JvmLoweredDeclarationOrigin.FIELD_FOR_OBJECT_INSTANCE,
instanceFieldDescriptor, instanceFieldDescriptor,
IrExpressionBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, instanceInitializer) IrExpressionBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, instanceInitializer)
).also { ).also {
pendingTransformations.add { instanceOwner.declarations.add(it) } pendingTransformations.add { instanceOwner.declarations.add(it) }
} }
} }