-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSerializationLoweringExtension.kt
50 lines (44 loc) · 2.49 KB
/
SerializationLoweringExtension.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.checkDeclarationParents
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.backend.common.ir.copyTo
import org.jetbrains.kotlin.backend.common.lower
import org.jetbrains.kotlin.ir.builders.irGetObject
import org.jetbrains.kotlin.ir.builders.irReturn
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.util.companionObject
import org.jetbrains.kotlin.ir.util.functions
class SerializationLoweringExtension : IrGenerationExtension {
override fun generate(moduleFragment: IrModuleFragment, pluginContext: IrPluginContext) {
SerializationLoweringPass(pluginContext).lower(moduleFragment)
moduleFragment.checkDeclarationParents()
}
}
private class SerializationLoweringPass(private val pluginContext: IrPluginContext) : ClassLoweringPass {
override fun lower(irClass: IrClass) {
if (irClass.descriptor.isSerializable) {
val serializerClass = generateSerializerImpl(irClass)
generateSerializerFactory(irClass.companionObject() as IrClass, serializerClass)
}
}
private fun generateSerializerImpl(irClass: IrClass): IrClass =
SerializationLoweringClassGeneration(pluginContext).createSerializerImpl(irClass)
/**
* FUN name:serializer visibility:public modality:FINAL <> ($this:<root>.Data.Companion) returnType:kotlinx.serialization.KSerializer<<root>.Data>
* $this: VALUE_PARAMETER name:<this> type:<root>.Data.Companion
* BLOCK_BODY
* RETURN type=kotlin.Nothing from='public final fun serializer (): kotlinx.serialization.KSerializer<<root>.Data> declared in <root>.Data.Companion'
* GET_OBJECT 'CLASS OBJECT name:$serializer modality:FINAL visibility:private superTypes:[kotlinx.serialization.KSerializer<<root>.Data>]' type=<root>.Data.$serializer
*/
private fun generateSerializerFactory(companionClass: IrClass, serializerClass: IrClass) {
val function = companionClass.functions.first { it.name == Names.SERIALIZER_METHOD }
function.dispatchReceiverParameter = companionClass.thisReceiver?.copyTo(function)
function.body = pluginContext.blockBody(function.symbol) {
+ irReturn(
irGetObject(serializerClass.symbol)
)
}
}
}