[SERIALIZATION] Fix kotlinx.serialization plugin
This commit is contained in:
+1
-2
@@ -422,8 +422,7 @@ abstract class KotlinIrLinker(
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected open fun resolveModuleDeserializer(moduleDescriptor: ModuleDescriptor): IrModuleDeserializer {
|
protected open fun resolveModuleDeserializer(moduleDescriptor: ModuleDescriptor): IrModuleDeserializer {
|
||||||
return deserializersForModules[moduleDescriptor] ?:
|
return deserializersForModules[moduleDescriptor] ?: error("No module deserializer found for $moduleDescriptor")
|
||||||
error("No module deserializer found for $moduleDescriptor")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract fun createModuleDeserializer(
|
protected abstract fun createModuleDeserializer(
|
||||||
|
|||||||
+68
-41
@@ -49,12 +49,23 @@ interface IrBuilderExtension {
|
|||||||
val compilerContext: SerializationPluginContext
|
val compilerContext: SerializationPluginContext
|
||||||
|
|
||||||
private fun IrClass.declareSimpleFunctionWithExternalOverrides(descriptor: FunctionDescriptor): IrSimpleFunction {
|
private fun IrClass.declareSimpleFunctionWithExternalOverrides(descriptor: FunctionDescriptor): IrSimpleFunction {
|
||||||
return compilerContext.symbolTable.declareSimpleFunction(startOffset, endOffset, SERIALIZABLE_PLUGIN_ORIGIN, descriptor)
|
val functionSymbol = compilerContext.symbolTable.referenceSimpleFunction(descriptor)
|
||||||
.also { f ->
|
val function = if (functionSymbol.isBound) functionSymbol.owner else {
|
||||||
f.overriddenSymbols = descriptor.overriddenDescriptors.map {
|
compilerContext.symbolTable.declareSimpleFunction(
|
||||||
compilerContext.symbolTable.referenceSimpleFunction(it.original)
|
startOffset,
|
||||||
}
|
endOffset,
|
||||||
|
SERIALIZABLE_PLUGIN_ORIGIN,
|
||||||
|
descriptor
|
||||||
|
).also {
|
||||||
|
it.parent = this
|
||||||
|
addMember(it)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return function.also { f ->
|
||||||
|
f.overriddenSymbols = descriptor.overriddenDescriptors.map {
|
||||||
|
compilerContext.symbolTable.referenceSimpleFunction(it.original)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createFunctionGenerator(): FunctionGenerator = with(compilerContext) {
|
private fun createFunctionGenerator(): FunctionGenerator = with(compilerContext) {
|
||||||
@@ -77,24 +88,17 @@ interface IrBuilderExtension {
|
|||||||
|
|
||||||
fun IrClass.contributeFunction(
|
fun IrClass.contributeFunction(
|
||||||
descriptor: FunctionDescriptor,
|
descriptor: FunctionDescriptor,
|
||||||
declareNew: Boolean = true,
|
|
||||||
bodyGen: IrBlockBodyBuilder.(IrFunction) -> Unit
|
bodyGen: IrBlockBodyBuilder.(IrFunction) -> Unit
|
||||||
) {
|
) {
|
||||||
val f: IrSimpleFunction = if (declareNew) declareSimpleFunctionWithExternalOverrides(
|
val f: IrSimpleFunction = declareSimpleFunctionWithExternalOverrides(descriptor)
|
||||||
descriptor
|
f.buildWithScope {
|
||||||
) else compilerContext.symbolTable.referenceSimpleFunction(descriptor).owner
|
createFunctionGenerator().generateFunctionParameterDeclarationsAndReturnType(f, null, null)
|
||||||
f.parent = this
|
|
||||||
if (declareNew) {
|
|
||||||
f.buildWithScope {
|
|
||||||
createFunctionGenerator().generateFunctionParameterDeclarationsAndReturnType(f, null, null)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
f.body = DeclarationIrBuilder(compilerContext, f.symbol, this.startOffset, this.endOffset).irBlockBody(
|
f.body = DeclarationIrBuilder(compilerContext, f.symbol, this.startOffset, this.endOffset).irBlockBody(
|
||||||
this.startOffset,
|
this.startOffset,
|
||||||
this.endOffset
|
this.endOffset
|
||||||
) { bodyGen(f) }
|
) { bodyGen(f) }
|
||||||
this.addMember(f)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun IrClass.contributeConstructor(
|
fun IrClass.contributeConstructor(
|
||||||
@@ -103,21 +107,32 @@ interface IrBuilderExtension {
|
|||||||
overwriteValueParameters: Boolean = false,
|
overwriteValueParameters: Boolean = false,
|
||||||
bodyGen: IrBlockBodyBuilder.(IrConstructor) -> Unit
|
bodyGen: IrBlockBodyBuilder.(IrConstructor) -> Unit
|
||||||
) {
|
) {
|
||||||
val c = if (declareNew) compilerContext.symbolTable.declareConstructor(
|
val ctorSymbol = compilerContext.symbolTable.referenceConstructor(descriptor)
|
||||||
this.startOffset,
|
val c = if (ctorSymbol.isBound) {
|
||||||
this.endOffset,
|
ctorSymbol.owner
|
||||||
SERIALIZABLE_PLUGIN_ORIGIN,
|
} else {
|
||||||
descriptor
|
compilerContext.symbolTable.declareConstructor(
|
||||||
) else compilerContext.symbolTable.referenceConstructor(descriptor).owner
|
this.startOffset,
|
||||||
c.parent = this
|
this.endOffset,
|
||||||
|
SERIALIZABLE_PLUGIN_ORIGIN,
|
||||||
|
descriptor
|
||||||
|
).also {
|
||||||
|
it.parent = this
|
||||||
|
addMember(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
c.returnType = descriptor.returnType.toIrType()
|
c.returnType = descriptor.returnType.toIrType()
|
||||||
if (declareNew || overwriteValueParameters) c.createParameterDeclarations(
|
if (declareNew || overwriteValueParameters)
|
||||||
|
c.createParameterDeclarations(
|
||||||
receiver = null,
|
receiver = null,
|
||||||
overwriteValueParameters = overwriteValueParameters,
|
overwriteValueParameters = overwriteValueParameters,
|
||||||
copyTypeParameters = false
|
copyTypeParameters = false
|
||||||
)
|
)
|
||||||
c.body = DeclarationIrBuilder(compilerContext, c.symbol, this.startOffset, this.endOffset).irBlockBody(this.startOffset, this.endOffset) { bodyGen(c) }
|
c.body = DeclarationIrBuilder(compilerContext, c.symbol, this.startOffset, this.endOffset).irBlockBody(
|
||||||
this.addMember(c)
|
this.startOffset,
|
||||||
|
this.endOffset
|
||||||
|
) { bodyGen(c) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun IrBuilderWithScope.irInvoke(
|
fun IrBuilderWithScope.irInvoke(
|
||||||
@@ -126,7 +141,7 @@ interface IrBuilderExtension {
|
|||||||
vararg args: IrExpression,
|
vararg args: IrExpression,
|
||||||
typeHint: IrType? = null
|
typeHint: IrType? = null
|
||||||
): IrMemberAccessExpression {
|
): IrMemberAccessExpression {
|
||||||
val returnType = typeHint ?: callee.descriptor.returnType!!.toIrType()
|
val returnType = typeHint ?: callee.run { if (isBound) owner.returnType else descriptor.returnType!!.toIrType() }
|
||||||
val call = irCall(callee, type = returnType)
|
val call = irCall(callee, type = returnType)
|
||||||
call.dispatchReceiver = dispatchReceiver
|
call.dispatchReceiver = dispatchReceiver
|
||||||
args.forEachIndexed(call::putValueArgument)
|
args.forEachIndexed(call::putValueArgument)
|
||||||
@@ -253,12 +268,15 @@ interface IrBuilderExtension {
|
|||||||
propertyDescriptor: PropertyDescriptor,
|
propertyDescriptor: PropertyDescriptor,
|
||||||
propertyParent: IrClass
|
propertyParent: IrClass
|
||||||
): IrProperty {
|
): IrProperty {
|
||||||
val irProperty = IrPropertyImpl(
|
val symbol = compilerContext.symbolTable.referenceProperty(propertyDescriptor)
|
||||||
propertyParent.startOffset, propertyParent.endOffset,
|
val irProperty = if (symbol.isBound) symbol.owner else {
|
||||||
SERIALIZABLE_PLUGIN_ORIGIN, false,
|
compilerContext.symbolTable.declareProperty(propertyParent.startOffset, propertyParent.endOffset, SERIALIZABLE_PLUGIN_ORIGIN, propertyDescriptor) {
|
||||||
propertyDescriptor
|
IrPropertyImpl(propertyParent.startOffset, propertyParent.endOffset, SERIALIZABLE_PLUGIN_ORIGIN, it)
|
||||||
)
|
}.also {
|
||||||
irProperty.parent = propertyParent
|
it.parent = propertyParent
|
||||||
|
propertyParent.addMember(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
irProperty.backingField = generatePropertyBackingField(propertyDescriptor, irProperty).apply {
|
irProperty.backingField = generatePropertyBackingField(propertyDescriptor, irProperty).apply {
|
||||||
parent = propertyParent
|
parent = propertyParent
|
||||||
correspondingPropertySymbol = irProperty.symbol
|
correspondingPropertySymbol = irProperty.symbol
|
||||||
@@ -288,9 +306,12 @@ interface IrBuilderExtension {
|
|||||||
descriptor: PropertyAccessorDescriptor,
|
descriptor: PropertyAccessorDescriptor,
|
||||||
fieldSymbol: IrFieldSymbol
|
fieldSymbol: IrFieldSymbol
|
||||||
): IrSimpleFunction {
|
): IrSimpleFunction {
|
||||||
val declaration = compilerContext.symbolTable.declareSimpleFunctionWithOverrides(fieldSymbol.owner.startOffset,
|
val symbol = compilerContext.symbolTable.referenceSimpleFunction(descriptor)
|
||||||
fieldSymbol.owner.endOffset,
|
|
||||||
SERIALIZABLE_PLUGIN_ORIGIN, descriptor)
|
val declaration = if (symbol.isBound) symbol.owner.also { generateOverriddenFunctionSymbols(it, compilerContext.symbolTable) } else compilerContext.symbolTable.declareSimpleFunctionWithOverrides(fieldSymbol.owner.startOffset,
|
||||||
|
fieldSymbol.owner.endOffset,
|
||||||
|
SERIALIZABLE_PLUGIN_ORIGIN, descriptor)
|
||||||
|
|
||||||
return declaration.buildWithScope { irAccessor ->
|
return declaration.buildWithScope { irAccessor ->
|
||||||
irAccessor.createParameterDeclarations(receiver = null)
|
irAccessor.createParameterDeclarations(receiver = null)
|
||||||
irAccessor.returnType = irAccessor.descriptor.returnType!!.toIrType()
|
irAccessor.returnType = irAccessor.descriptor.returnType!!.toIrType()
|
||||||
@@ -496,15 +517,17 @@ interface IrBuilderExtension {
|
|||||||
nullableSerializerClass: IrClassSymbol
|
nullableSerializerClass: IrClassSymbol
|
||||||
): IrExpression {
|
): IrExpression {
|
||||||
return if (type.isMarkedNullable) {
|
return if (type.isMarkedNullable) {
|
||||||
val nullableConstructor =
|
val classDeclaration = nullableSerializerClass.owner
|
||||||
compilerContext.symbolTable.referenceConstructor(nullableSerializerClass.descriptor.constructors.toList().first())
|
val nullableConstructor = classDeclaration.declarations.first { it is IrConstructor } as IrConstructor
|
||||||
val resultType = type.makeNotNullable()
|
val resultType = type.makeNotNullable()
|
||||||
|
val typeParameters = classDeclaration.typeParameters
|
||||||
|
val typeArguments = listOf(resultType.toIrType())
|
||||||
irInvoke(
|
irInvoke(
|
||||||
null, nullableConstructor,
|
null, nullableConstructor.symbol,
|
||||||
typeArguments = listOf(resultType.toIrType()),
|
typeArguments = typeArguments,
|
||||||
valueArguments = listOf(expression),
|
valueArguments = listOf(expression),
|
||||||
// Return type should be correctly substituted
|
// Return type should be correctly substituted
|
||||||
returnTypeHint = nullableConstructor.descriptor.returnType.replace(listOf(resultType.asTypeProjection())).toIrType()
|
returnTypeHint = nullableConstructor.returnType.substitute(typeParameters, typeArguments)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
expression
|
expression
|
||||||
@@ -663,7 +686,11 @@ interface IrBuilderExtension {
|
|||||||
compilerContext.symbolTable.referenceConstructor(serializerClass.unsubstitutedPrimaryConstructor!!)
|
compilerContext.symbolTable.referenceConstructor(serializerClass.unsubstitutedPrimaryConstructor!!)
|
||||||
}
|
}
|
||||||
// Return type should be correctly substituted
|
// Return type should be correctly substituted
|
||||||
val substitutedReturnType = ctor.descriptor.returnType.replace(typeArgs.map { it.toKotlinType().asTypeProjection() }).toIrType()
|
val substitutedReturnType = if (ctor.isBound) {
|
||||||
|
val ctorDecl = ctor.owner
|
||||||
|
val typeParameters = ctorDecl.parentAsClass.typeParameters
|
||||||
|
ctor.owner.returnType.substitute(typeParameters, typeArgs)
|
||||||
|
} else ctor.descriptor.returnType.replace(typeArgs.map { it.toKotlinType().asTypeProjection() }).toIrType()
|
||||||
return irInvoke(null, ctor, typeArguments = typeArgs, valueArguments = args, returnTypeHint = substitutedReturnType)
|
return irInvoke(null, ctor, typeArguments = typeArgs, valueArguments = args, returnTypeHint = substitutedReturnType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-3
@@ -60,10 +60,9 @@ open class SerializerIrGenerator(val irClass: IrClass, final override val compil
|
|||||||
|
|
||||||
introduceValueParameter(thisAsReceiverParameter)
|
introduceValueParameter(thisAsReceiverParameter)
|
||||||
prop = generateSimplePropertyWithBackingField(thisAsReceiverParameter.symbol, desc, irClass)
|
prop = generateSimplePropertyWithBackingField(thisAsReceiverParameter.symbol, desc, irClass)
|
||||||
irClass.addMember(prop)
|
|
||||||
|
|
||||||
localSerializersFieldsDescriptors.forEach {
|
localSerializersFieldsDescriptors.forEach {
|
||||||
irClass.addMember(generateSimplePropertyWithBackingField(thisAsReceiverParameter.symbol, it, irClass))
|
generateSimplePropertyWithBackingField(thisAsReceiverParameter.symbol, it, irClass)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,7 +232,7 @@ open class SerializerIrGenerator(val irClass: IrClass, final override val compil
|
|||||||
// fun beginStructure(desc: SerialDescriptor, vararg typeParams: KSerializer<*>): StructureEncoder
|
// fun beginStructure(desc: SerialDescriptor, vararg typeParams: KSerializer<*>): StructureEncoder
|
||||||
val beginFunc = encoderClass.referenceMethod(CallingConventions.begin) { it.valueParameters.size == 1 }
|
val beginFunc = encoderClass.referenceMethod(CallingConventions.begin) { it.valueParameters.size == 1 }
|
||||||
|
|
||||||
val call = irCall(beginFunc, type = beginFunc.descriptor.returnType!!.toIrType()).mapValueParametersIndexed { _, _ ->
|
val call = irCall(beginFunc, type = beginFunc.owner.returnType).mapValueParametersIndexed { _, _ ->
|
||||||
irGet(localSerialDesc)
|
irGet(localSerialDesc)
|
||||||
}
|
}
|
||||||
// can it be done in more concise way? e.g. additional builder function?
|
// can it be done in more concise way? e.g. additional builder function?
|
||||||
|
|||||||
Reference in New Issue
Block a user