Object serialization for JVM, JS and Native
This commit is contained in:
+13
-1
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.psi.KtPureClassOrObject
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.*
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.enumSerializerId
|
||||
@@ -48,10 +49,15 @@ fun AbstractSerialGenerator.findAddOnSerializer(propertyType: KotlinType, module
|
||||
additionalSerializersInScopeOfCurrentFile[propertyType]?.let { return it }
|
||||
if (propertyType in contextualKClassListInCurrentFile)
|
||||
return module.getClassFromSerializationPackage(SpecialBuiltins.contextSerializer)
|
||||
if (propertyType.toClassDescriptor?.annotations?.hasAnnotation(SerializationAnnotations.polymorphicFqName) == true)
|
||||
return module.getClassFromSerializationPackage(SpecialBuiltins.polymorphicSerializer)
|
||||
if (propertyType.isMarkedNullable) return findAddOnSerializer(propertyType.makeNotNullable(), module)
|
||||
return null
|
||||
}
|
||||
|
||||
fun KotlinType.isSerializableObject() =
|
||||
toClassDescriptor?.run { kind == ClassKind.OBJECT && hasSerializableAnnotationWithoutArgs } == true
|
||||
|
||||
@Suppress("FunctionName", "LocalVariableName")
|
||||
fun AbstractSerialGenerator.getSerialTypeInfo(property: SerializableProperty): SerialTypeInfo {
|
||||
fun SerializableInfo(serializer: ClassDescriptor?) =
|
||||
@@ -76,7 +82,7 @@ fun AbstractSerialGenerator.getSerialTypeInfo(property: SerializableProperty): S
|
||||
)
|
||||
SerializableInfo(serializer)
|
||||
}
|
||||
T.toClassDescriptor?.kind == ClassKind.ENUM_CLASS -> {
|
||||
T.isEnum() -> {
|
||||
val serializer = property.module.findClassAcrossModuleDependencies(enumSerializerId)
|
||||
SerializableInfo(serializer)
|
||||
}
|
||||
@@ -88,6 +94,11 @@ fun AbstractSerialGenerator.getSerialTypeInfo(property: SerializableProperty): S
|
||||
}
|
||||
}
|
||||
|
||||
fun KotlinType.serialName(): String {
|
||||
val serializableDescriptor = this.toClassDescriptor!!
|
||||
return serializableDescriptor.annotations.serialNameValue ?: serializableDescriptor.fqNameUnsafe.asString()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns class descriptor for ContextSerializer or PolymorphicSerializer
|
||||
* if [annotations] contains @Contextual or @Polymorphic annotation
|
||||
@@ -136,6 +147,7 @@ fun findTypeSerializer(module: ModuleDescriptor, kType: KotlinType): ClassDescri
|
||||
if (userOverride != null) return userOverride.toClassDescriptor
|
||||
if (kType.isTypeParameter()) return null
|
||||
if (KotlinBuiltIns.isArray(kType)) return module.getClassFromInternalSerializationPackage(SpecialBuiltins.referenceArraySerializer)
|
||||
if (kType.isSerializableObject()) return module.getClassFromInternalSerializationPackage(SpecialBuiltins.objectSerializer)
|
||||
val stdSer = findStandardKotlinTypeSerializer(module, kType) // see if there is a standard serializer
|
||||
?: findEnumTypeSerializer(module, kType)
|
||||
if (stdSer != null) return stdSer
|
||||
|
||||
+30
-9
@@ -38,11 +38,10 @@ import org.jetbrains.kotlin.types.TypeProjectionImpl
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.AbstractSerialGenerator
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.findTypeSerializerOrContext
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.contextSerializerId
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.enumSerializerId
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.polymorphicSerializerId
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.referenceArraySerializerId
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.serialName
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.*
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.*
|
||||
|
||||
val BackendContext.externalSymbols: ReferenceSymbolTable get() = ir.symbols.externalSymbolTable
|
||||
@@ -513,14 +512,32 @@ interface IrBuilderExtension {
|
||||
module: ModuleDescriptor,
|
||||
kType: KotlinType,
|
||||
genericIndex: Int? = null
|
||||
): IrExpression? = serializerInstance(
|
||||
enclosingGenerator,
|
||||
serializableDescriptor,
|
||||
serializerClassOriginal,
|
||||
module,
|
||||
kType,
|
||||
genericIndex
|
||||
) {
|
||||
val prop = enclosingGenerator.localSerializersFieldsDescriptors[it]
|
||||
irGetField(irGet(dispatchReceiverParameter), compilerContext.localSymbolTable.referenceField(prop).owner)
|
||||
}
|
||||
|
||||
fun IrBuilderWithScope.serializerInstance(
|
||||
enclosingGenerator: AbstractSerialGenerator,
|
||||
serializableDescriptor: ClassDescriptor,
|
||||
serializerClassOriginal: ClassDescriptor?,
|
||||
module: ModuleDescriptor,
|
||||
kType: KotlinType,
|
||||
genericIndex: Int? = null,
|
||||
genericGetter: (Int) -> IrExpression
|
||||
): IrExpression? {
|
||||
val nullableSerClass =
|
||||
compilerContext.externalSymbols.referenceClass(module.getClassFromInternalSerializationPackage(SpecialBuiltins.nullableSerializer))
|
||||
if (serializerClassOriginal == null) {
|
||||
if (genericIndex == null) return null
|
||||
|
||||
val prop = enclosingGenerator.localSerializersFieldsDescriptors[genericIndex]
|
||||
return irGetField(irGet(dispatchReceiverParameter), compilerContext.localSymbolTable.referenceField(prop).owner)
|
||||
return genericGetter(genericIndex)
|
||||
}
|
||||
if (serializerClassOriginal.kind == ClassKind.OBJECT) {
|
||||
return irGetObject(serializerClassOriginal)
|
||||
@@ -533,6 +550,10 @@ interface IrBuilderExtension {
|
||||
args = listOf(classReference(kType))
|
||||
typeArgs = listOf(kType.toIrType())
|
||||
}
|
||||
objectSerializerId -> {
|
||||
args = listOf(irString(kType.serialName()), irGetObject(kType.toClassDescriptor!!))
|
||||
typeArgs = listOf(kType.toIrType())
|
||||
}
|
||||
enumSerializerId -> {
|
||||
serializerClass = serializableDescriptor.getClassFromInternalSerializationPackage("CommonEnumSerializer")
|
||||
args = kType.toClassDescriptor!!.let { enumDesc ->
|
||||
@@ -556,12 +577,12 @@ interface IrBuilderExtension {
|
||||
)
|
||||
val expr = serializerInstance(
|
||||
enclosingGenerator,
|
||||
dispatchReceiverParameter,
|
||||
serializableDescriptor,
|
||||
argSer,
|
||||
module,
|
||||
it.type,
|
||||
it.type.genericIndex
|
||||
it.type.genericIndex,
|
||||
genericGetter
|
||||
)
|
||||
?: return null
|
||||
wrapWithNullableSerializerIfNeeded(module, it.type, expr, nullableSerClass)
|
||||
|
||||
+18
-24
@@ -21,7 +21,10 @@ import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.SerializableCompanionCodegen
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.findTypeSerializer
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.*
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.getSerializableClassDescriptorByCompanion
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.shouldHaveGeneratedMethodsInCompanion
|
||||
|
||||
class SerializableCompanionIrGenerator(
|
||||
val irClass: IrClass,
|
||||
@@ -82,30 +85,21 @@ class SerializableCompanionIrGenerator(
|
||||
|
||||
override fun generateSerializerGetter(methodDescriptor: FunctionDescriptor) =
|
||||
irClass.contributeFunction(methodDescriptor, fromStubs = true) { getter ->
|
||||
val serializer = serializableDescriptor.classSerializer!!
|
||||
val expr = when {
|
||||
serializer.kind == ClassKind.OBJECT -> irGetObject(serializer)
|
||||
serializer.isSerializerWhichRequiersKClass() -> {
|
||||
val serializableType = serializableDescriptor.defaultType
|
||||
irInvoke(
|
||||
null,
|
||||
compilerContext.externalSymbols.referenceConstructor(serializer.unsubstitutedPrimaryConstructor!!),
|
||||
typeArguments = listOf(serializableType.toIrType()),
|
||||
valueArguments = listOf(classReference(serializableType)),
|
||||
returnTypeHint = getter.returnType
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
val desc = requireNotNull(
|
||||
findSerializerConstructorForTypeArgumentsSerializers(serializer)
|
||||
) { "Generated serializer does not have constructor with required number of arguments" }
|
||||
val ctor = compilerContext.externalSymbols.referenceConstructor(desc)
|
||||
val typeArgs = getter.typeParameters.map { it.defaultType }
|
||||
val args: List<IrExpression> = getter.valueParameters.map { irGet(it) }
|
||||
irInvoke(null, ctor, typeArgs, args, returnTypeHint = getter.returnType)
|
||||
}
|
||||
}
|
||||
val serializer = requireNotNull(
|
||||
findTypeSerializer(
|
||||
serializableDescriptor.module,
|
||||
serializableDescriptor.toSimpleType()
|
||||
)
|
||||
)
|
||||
val args: List<IrExpression> = getter.valueParameters.map { irGet(it) }
|
||||
val expr = serializerInstance(
|
||||
this@SerializableCompanionIrGenerator,
|
||||
serializableDescriptor, serializer,
|
||||
serializableDescriptor.module,
|
||||
serializableDescriptor.defaultType
|
||||
) { args[it] }
|
||||
patchSerializableClassWithMarkerAnnotation(serializer)
|
||||
+irReturn(expr)
|
||||
+irReturn(requireNotNull(expr))
|
||||
}
|
||||
|
||||
}
|
||||
+21
-13
@@ -30,9 +30,8 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.bodyPropertiesDescriptorsMap
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.findTypeSerializerOrContext
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.primaryConstructorPropertiesDescriptorsMap
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.*
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.objectSerializerId
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.referenceArraySerializerId
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.*
|
||||
|
||||
@@ -126,31 +125,40 @@ internal fun SerializerJsTranslator.serializerTower(property: SerializableProper
|
||||
property.type,
|
||||
property.descriptor.findPsi()
|
||||
) else null
|
||||
return serializerInstance(serializer, property.module, property.type, property.genericIndex)
|
||||
return serializerInstance(context, serializer, property.module, property.type, property.genericIndex)
|
||||
?.let { expr -> if (property.type.isMarkedNullable) JsNew(nullableSerClass, listOf(expr)) else expr }
|
||||
}
|
||||
|
||||
internal fun SerializerJsTranslator.serializerInstance(
|
||||
internal fun AbstractSerialGenerator.serializerInstance(
|
||||
context: TranslationContext,
|
||||
serializerClass: ClassDescriptor?,
|
||||
module: ModuleDescriptor,
|
||||
kType: KotlinType,
|
||||
genericIndex: Int? = null
|
||||
genericIndex: Int? = null,
|
||||
genericGetter: (Int) -> JsExpression = { JsNameRef(context.scope().declareName("${SerialEntityNames.typeArgPrefix}$it"), JsThisRef()) }
|
||||
): JsExpression? {
|
||||
val nullableSerClass =
|
||||
context.translateQualifiedReference(module.getClassFromInternalSerializationPackage(SpecialBuiltins.nullableSerializer))
|
||||
if (serializerClass == null) {
|
||||
if (genericIndex == null) return null
|
||||
return JsNameRef(context.scope().declareName("${SerialEntityNames.typeArgPrefix}$genericIndex"), JsThisRef())
|
||||
return genericGetter(genericIndex)
|
||||
}
|
||||
if (serializerClass.kind == ClassKind.OBJECT) {
|
||||
return context.serializerObjectGetter(serializerClass)
|
||||
} else {
|
||||
var args = if (serializerClass.isSerializerWhichRequiersKClass())
|
||||
listOf(ExpressionVisitor.getObjectKClass(context, kType.toClassDescriptor!!))
|
||||
else kType.arguments.map {
|
||||
val argSer = findTypeSerializerOrContext(module, it.type, sourceElement = serializerClass.findPsi())
|
||||
val expr = serializerInstance(argSer, module, it.type, it.type.genericIndex) ?: return null
|
||||
if (it.type.isMarkedNullable) JsNew(nullableSerClass, listOf(expr)) else expr
|
||||
var args = when {
|
||||
serializerClass.isSerializerWhichRequiersKClass() -> listOf(
|
||||
ExpressionVisitor.getObjectKClass(context, kType.toClassDescriptor!!)
|
||||
)
|
||||
serializerClass.classId == objectSerializerId -> listOf(
|
||||
JsStringLiteral(kType.serialName()),
|
||||
context.serializerObjectGetter(kType.toClassDescriptor!!)
|
||||
)
|
||||
else -> kType.arguments.map {
|
||||
val argSer = findTypeSerializerOrContext(module, it.type, sourceElement = serializerClass.findPsi())
|
||||
val expr = serializerInstance(context, argSer, module, it.type, it.type.genericIndex, genericGetter) ?: return null
|
||||
if (it.type.isMarkedNullable) JsNew(nullableSerClass, listOf(expr)) else expr
|
||||
}
|
||||
}
|
||||
if (serializerClass.classId == referenceArraySerializerId)
|
||||
args = listOf(ExpressionVisitor.getObjectKClass(context, kType.arguments[0].type.toClassDescriptor!!)) + args
|
||||
|
||||
+26
-21
@@ -17,40 +17,45 @@
|
||||
package org.jetbrains.kotlinx.serialization.compiler.backend.js
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsNameRef
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsReturn
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
||||
import org.jetbrains.kotlin.js.translate.declaration.DeclarationBodyVisitor
|
||||
import org.jetbrains.kotlin.js.translate.expression.ExpressionVisitor
|
||||
import org.jetbrains.kotlin.psi.KtPureClassOrObject
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.SerializableCompanionCodegen
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.*
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.findTypeSerializer
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.getSerializableClassDescriptorByCompanion
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.shouldHaveGeneratedMethodsInCompanion
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.toSimpleType
|
||||
|
||||
class SerializableCompanionJsTranslator(
|
||||
declaration: ClassDescriptor,
|
||||
val translator: DeclarationBodyVisitor,
|
||||
val context: TranslationContext
|
||||
): SerializableCompanionCodegen(declaration, context.bindingContext()) {
|
||||
) : SerializableCompanionCodegen(declaration, context.bindingContext()) {
|
||||
|
||||
override fun generateSerializerGetter(methodDescriptor: FunctionDescriptor) {
|
||||
val f = context.buildFunction(methodDescriptor) {jsFun, context ->
|
||||
val serializer = serializableDescriptor.classSerializer!!
|
||||
val stmt: JsExpression = when {
|
||||
serializer.kind == ClassKind.OBJECT -> context.serializerObjectGetter(serializer)
|
||||
serializer.isSerializerWhichRequiersKClass() -> JsNew(
|
||||
context.translateQualifiedReference(serializer),
|
||||
listOf(ExpressionVisitor.getObjectKClass(context, serializableDescriptor))
|
||||
val f = context.buildFunction(methodDescriptor) { jsFun, context ->
|
||||
val serializer = requireNotNull(
|
||||
findTypeSerializer(
|
||||
serializableDescriptor.module,
|
||||
serializableDescriptor.toSimpleType()
|
||||
)
|
||||
)
|
||||
val args = jsFun.parameters.map { JsNameRef(it.name) }
|
||||
val stmt =
|
||||
requireNotNull(
|
||||
serializerInstance(
|
||||
context,
|
||||
serializer,
|
||||
serializableDescriptor.module,
|
||||
serializableDescriptor.defaultType,
|
||||
genericGetter = {
|
||||
args[it]
|
||||
})
|
||||
)
|
||||
else -> {
|
||||
val args = jsFun.parameters.map { JsNameRef(it.name) }
|
||||
val ref = context.getInnerNameForDescriptor(
|
||||
requireNotNull(
|
||||
findSerializerConstructorForTypeArgumentsSerializers(serializer)
|
||||
) { "Generated serializer does not have constructor with required number of arguments" })
|
||||
JsInvocation(ref.makeRef(), args)
|
||||
}
|
||||
}
|
||||
+JsReturn(stmt)
|
||||
}
|
||||
translator.addFunction(methodDescriptor, f, null)
|
||||
|
||||
+2
-2
@@ -170,7 +170,7 @@ class SerializerJsTranslator(descriptor: ClassDescriptor,
|
||||
if (property.transient) continue
|
||||
// output.writeXxxElementValue(classDesc, index, value)
|
||||
val sti = getSerialTypeInfo(property)
|
||||
val innerSerial = serializerInstance(sti.serializer, property.module, property.type, property.genericIndex)
|
||||
val innerSerial = serializerInstance(context, sti.serializer, property.module, property.type, property.genericIndex)
|
||||
val invocation = if (innerSerial == null) {
|
||||
val writeFunc =
|
||||
kOutputClass.getFuncDesc("${CallingConventions.encode}${sti.elementMethodPrefix}${CallingConventions.elementPostfix}").single()
|
||||
@@ -275,7 +275,7 @@ class SerializerJsTranslator(descriptor: ClassDescriptor,
|
||||
case(JsIntLiteral(i)) {
|
||||
// input.readXxxElementValue
|
||||
val sti = getSerialTypeInfo(property)
|
||||
val innerSerial = serializerInstance(sti.serializer, property.module, property.type, property.genericIndex)
|
||||
val innerSerial = serializerInstance(context, sti.serializer, property.module, property.type, property.genericIndex)
|
||||
val call: JsExpression = if (innerSerial == null) {
|
||||
val unknownSer = (sti.elementMethodPrefix.isEmpty())
|
||||
val readFunc =
|
||||
|
||||
+8
@@ -156,6 +156,7 @@ internal fun ImplementationBodyCodegen.generateMethod(
|
||||
internal val enumSerializerId = ClassId(internalPackageFqName, Name.identifier(SpecialBuiltins.enumSerializer))
|
||||
internal val polymorphicSerializerId = ClassId(packageFqName, Name.identifier(SpecialBuiltins.polymorphicSerializer))
|
||||
internal val referenceArraySerializerId = ClassId(internalPackageFqName, Name.identifier(SpecialBuiltins.referenceArraySerializer))
|
||||
internal val objectSerializerId = ClassId(internalPackageFqName, Name.identifier(SpecialBuiltins.objectSerializer))
|
||||
internal val contextSerializerId = ClassId(packageFqName, Name.identifier(SpecialBuiltins.contextSerializer))
|
||||
|
||||
|
||||
@@ -294,6 +295,13 @@ internal fun AbstractSerialGenerator.stackValueSerializerInstance(codegen: Class
|
||||
// Reference array serializer still needs serializer for its argument type
|
||||
instantiate(argSerializers[0])
|
||||
}
|
||||
objectSerializerId -> {
|
||||
val serialName = kType.serialName()
|
||||
aconst(serialName)
|
||||
signature.append("Ljava/lang/String;")
|
||||
StackValue.singleton(kType.toClassDescriptor!!, codegen.typeMapper).put(Type.getType("Ljava/lang/Object;"), iv)
|
||||
signature.append("Ljava/lang/Object;")
|
||||
}
|
||||
// all serializers get arguments with serializers of their generic types
|
||||
else -> argSerializers.forEach(::instantiate)
|
||||
}
|
||||
|
||||
+8
-2
@@ -20,9 +20,10 @@ import org.jetbrains.kotlin.codegen.ImplementationBodyCodegen
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.SerializableCompanionCodegen
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.classSerializer
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.findTypeSerializer
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.getSerializableClassDescriptorByCompanion
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.shouldHaveGeneratedMethodsInCompanion
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.toSimpleType
|
||||
|
||||
class SerializableCompanionCodegenImpl(private val classCodegen: ImplementationBodyCodegen) :
|
||||
SerializableCompanionCodegen(classCodegen.descriptor, classCodegen.bindingContext) {
|
||||
@@ -36,7 +37,12 @@ class SerializableCompanionCodegenImpl(private val classCodegen: ImplementationB
|
||||
}
|
||||
|
||||
override fun generateSerializerGetter(methodDescriptor: FunctionDescriptor) {
|
||||
val serial = serializableDescriptor.classSerializer ?: return
|
||||
val serial = requireNotNull(
|
||||
findTypeSerializer(
|
||||
serializableDescriptor.module,
|
||||
serializableDescriptor.toSimpleType()
|
||||
)
|
||||
)
|
||||
classCodegen.generateMethod(methodDescriptor) { _, _ ->
|
||||
stackValueSerializerInstance(
|
||||
classCodegen,
|
||||
|
||||
+4
-2
@@ -18,6 +18,7 @@ package org.jetbrains.kotlinx.serialization.compiler.extensions
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -43,7 +44,7 @@ open class SerializationResolveExtension : SyntheticResolveExtension {
|
||||
}
|
||||
|
||||
override fun getSyntheticFunctionNames(thisDescriptor: ClassDescriptor): List<Name> = when {
|
||||
thisDescriptor.isCompanionObject && getSerializableClassDescriptorByCompanion(thisDescriptor) != null ->
|
||||
thisDescriptor.isSerializableObject || thisDescriptor.isCompanionObject && getSerializableClassDescriptorByCompanion(thisDescriptor) != null ->
|
||||
listOf(SerialEntityNames.SERIALIZER_PROVIDER_NAME)
|
||||
else -> emptyList()
|
||||
}
|
||||
@@ -65,7 +66,8 @@ open class SerializationResolveExtension : SyntheticResolveExtension {
|
||||
}
|
||||
|
||||
override fun getSyntheticCompanionObjectNameIfNeeded(thisDescriptor: ClassDescriptor): Name? =
|
||||
if (thisDescriptor.shouldHaveGeneratedMethodsInCompanion) SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT
|
||||
if (thisDescriptor.kind == ClassKind.CLASS && thisDescriptor.annotations.hasAnnotation(SerializationAnnotations.serializableAnnotationFqName))
|
||||
SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT
|
||||
else null
|
||||
|
||||
override fun addSyntheticSupertypes(thisDescriptor: ClassDescriptor, supertypes: MutableList<KotlinType>) {
|
||||
|
||||
+6
-2
@@ -105,7 +105,10 @@ val KotlinType?.toClassDescriptor: ClassDescriptor?
|
||||
}
|
||||
|
||||
internal val ClassDescriptor.shouldHaveGeneratedMethodsInCompanion: Boolean
|
||||
get() = this.kind == ClassKind.CLASS && annotations.hasAnnotation(SerializationAnnotations.serializableAnnotationFqName)
|
||||
get() = this.isSerializableObject || this.kind == ClassKind.CLASS && annotations.hasAnnotation(SerializationAnnotations.serializableAnnotationFqName)
|
||||
|
||||
internal val ClassDescriptor.isSerializableObject: Boolean
|
||||
get() = kind == ClassKind.OBJECT && hasSerializableAnnotationWithoutArgs
|
||||
|
||||
internal val ClassDescriptor.isInternalSerializable: Boolean //todo normal checking
|
||||
get() {
|
||||
@@ -159,7 +162,7 @@ internal val ClassDescriptor?.classSerializer: ClassDescriptor?
|
||||
}
|
||||
|
||||
internal val ClassDescriptor.hasCompanionObjectAsSerializer: Boolean
|
||||
get() = companionObjectDescriptor?.serializerForClass == this.defaultType
|
||||
get() = isSerializableObject || companionObjectDescriptor?.serializerForClass == this.defaultType
|
||||
|
||||
internal fun ClassDescriptor.isSerializerWhichRequiersKClass() = classId in setOf(enumSerializerId, contextSerializerId, polymorphicSerializerId)
|
||||
|
||||
@@ -177,6 +180,7 @@ internal val KotlinType.genericIndex: Int?
|
||||
get() = (this.constructor.declarationDescriptor as? TypeParameterDescriptor)?.index
|
||||
|
||||
internal fun getSerializableClassDescriptorByCompanion(thisDescriptor: ClassDescriptor): ClassDescriptor? {
|
||||
if (thisDescriptor.isSerializableObject) return thisDescriptor
|
||||
if (!thisDescriptor.isCompanionObject) return null
|
||||
val classDescriptor = (thisDescriptor.containingDeclaration as? ClassDescriptor) ?: return null
|
||||
if (!classDescriptor.shouldHaveGeneratedMethodsInCompanion) return null
|
||||
|
||||
+1
@@ -76,6 +76,7 @@ object SerialEntityNames {
|
||||
|
||||
object SpecialBuiltins {
|
||||
const val referenceArraySerializer = "ReferenceArraySerializer"
|
||||
const val objectSerializer = "ObjectSerializer"
|
||||
const val enumSerializer = "EnumSerializer"
|
||||
const val polymorphicSerializer = "PolymorphicSerializer"
|
||||
const val contextSerializer = "ContextSerializer"
|
||||
|
||||
Reference in New Issue
Block a user