Fix compilation error when @Serializable expect class has explicit companion

as it may have no primary constructor (only actual class has it).

Refactor & rename Fir2IrGeneratorUtils.kt as having 'Fir' in stacktrace
when actual K2 compiler is not used is very confusing.

Fixes https://github.com/Kotlin/kotlinx.serialization/issues/2134
#KT-55683 Fixed
This commit is contained in:
Leonid Startsev
2022-12-21 18:13:11 +01:00
committed by Space Team
parent 6d3812c259
commit 2634303055
7 changed files with 56 additions and 9 deletions
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl
import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.util.constructors
import org.jetbrains.kotlin.ir.util.primaryConstructor
// TODO KT-53096
@@ -38,9 +37,7 @@ fun IrPluginContext.generateBodyForDefaultConstructor(declaration: IrConstructor
return irFactory.createBlockBody(-1, -1, listOf(delegatingAnyCall, initializerCall))
}
val Sequence<IrConstructor>.primary get() = find { it.isPrimary } ?: error("Expected to have a primary constructor")
fun IrClass.addDefaultConstructorIfAbsent(ctx: IrPluginContext) {
val declaration = constructors.primary
fun IrClass.addDefaultConstructorBodyIfAbsent(ctx: IrPluginContext) {
val declaration = primaryConstructor ?: return
if (declaration.body == null) declaration.body = ctx.generateBodyForDefaultConstructor(declaration)
}
@@ -208,6 +208,9 @@ internal val List<IrConstructorCall>.hasAnySerialAnnotation: Boolean
internal val List<IrConstructorCall>.serialNameValue: String?
get() = findAnnotation(SerializationAnnotations.serialNameAnnotationFqName)?.getStringConstArgument(0) // @SerialName("foo")
val IrClass.primaryConstructorOrFail get() = primaryConstructor ?: error("$this is expected to have a primary constructor")
/**
* True — ALWAYS
* False — NEVER
@@ -53,7 +53,7 @@ class SerializableCompanionIrGenerator(
val serializableClass = getSerializableClassByCompanion(companionDescriptor) ?: return
if (serializableClass.shouldHaveGeneratedMethodsInCompanion) {
SerializableCompanionIrGenerator(irClass, getSerializableClassByCompanion(irClass)!!, context).generate()
irClass.addDefaultConstructorIfAbsent(context)
irClass.addDefaultConstructorBodyIfAbsent(context)
irClass.patchDeclarationParents(irClass.parent)
}
}
@@ -199,7 +199,7 @@ open class SerializerIrGenerator(
fun generateGenericFieldsAndConstructor(typedConstructorDescriptor: IrConstructor) =
addFunctionBody(typedConstructorDescriptor) { ctor ->
// generate call to primary ctor to init serialClassDesc and super()
val primaryCtor = irClass.constructors.primary
val primaryCtor = irClass.primaryConstructorOrFail
+IrDelegatingConstructorCallImpl.fromSymbolOwner(
startOffset,
endOffset,
@@ -518,7 +518,7 @@ open class SerializerIrGenerator(
generateGoldenMaskCheck(bitMasks, properties, localSerialDesc.get())
val ctor: IrConstructorSymbol = serializableIrClass.constructors.primary.symbol
val ctor: IrConstructorSymbol = serializableIrClass.primaryConstructorOrFail.symbol
val params = ctor.owner.valueParameters
val variableByParamReplacer: (ValueParameterDescriptor) -> IrExpression? = { vpd ->
@@ -642,7 +642,7 @@ open class SerializerIrGenerator(
// replace origin only for plugin generated serializers
irClass.origin = SERIALIZATION_PLUGIN_ORIGIN
}
irClass.addDefaultConstructorIfAbsent(context)
irClass.addDefaultConstructorBodyIfAbsent(context)
irClass.patchDeclarationParents(irClass.parent)
}
}