Support static final write$Self method inside serializable classes on IR
to properly serialize class hierarchies with/or private fields. JVM only for now, because Native/JS do not have private fields. Update tests and test data and rebase fix. Unify formEncodeDecodePropertyCall functions. Fix incorrect reference to object in writeSelf, so properties dependent on other properties would be correctly compared with defaults.
This commit is contained in:
+14
-5
@@ -1,15 +1,16 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlinx.serialization.compiler.backend.common
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.secondaryConstructors
|
||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.*
|
||||
|
||||
abstract class SerializableCodegen(
|
||||
@@ -37,7 +38,15 @@ abstract class SerializableCodegen(
|
||||
private fun generateSyntheticMethods() {
|
||||
val serializerDescriptor = serializableDescriptor.classSerializer ?: return
|
||||
if (serializableDescriptor.shouldHaveSpecificSyntheticMethods { SerializerCodegen.getSyntheticSaveMember(serializerDescriptor) }) {
|
||||
val func = KSerializerDescriptorResolver.createWriteSelfFunctionDescriptor(serializableDescriptor)
|
||||
val func =
|
||||
serializableDescriptor.unsubstitutedMemberScope.getContributedFunctions(
|
||||
Name.identifier(SerialEntityNames.WRITE_SELF_NAME.toString()),
|
||||
NoLookupLocation.FROM_BACKEND
|
||||
).singleOrNull { function ->
|
||||
function.kind == CallableMemberDescriptor.Kind.SYNTHESIZED &&
|
||||
function.modality == Modality.FINAL &&
|
||||
function.returnType?.isUnit() ?: false
|
||||
} ?: return
|
||||
generateWriteSelfMethod(func)
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -70,7 +70,7 @@ abstract class SerializerCodegen(
|
||||
serializerDescriptor::checkSerializableClassPropertyResult
|
||||
) { true }
|
||||
|
||||
lateinit var localSerializersFieldsDescriptors: List<Pair<PropertyDescriptor, IrProperty>>
|
||||
var localSerializersFieldsDescriptors: List<Pair<PropertyDescriptor, IrProperty>> = emptyList()
|
||||
protected set
|
||||
|
||||
// Can be false if user specified inheritance from KSerializer explicitly
|
||||
|
||||
+102
-7
@@ -7,6 +7,7 @@ package org.jetbrains.kotlinx.serialization.compiler.backend.ir
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.deepCopyWithVariables
|
||||
import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.lower.irIfThen
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
@@ -59,9 +60,9 @@ interface IrBuilderExtension {
|
||||
return throwMissedFieldExceptionFunc != null && throwMissedFieldExceptionArrayFunc != null
|
||||
}
|
||||
|
||||
fun IrClass.contributeFunction(descriptor: FunctionDescriptor, bodyGen: IrBlockBodyBuilder.(IrFunction) -> Unit) {
|
||||
val f: IrSimpleFunction = searchForDeclaration(descriptor) ?: compilerContext.symbolTable.referenceSimpleFunction(descriptor).owner
|
||||
// TODO: default parameters
|
||||
fun IrClass.contributeFunction(descriptor: FunctionDescriptor, ignoreWhenMissing: Boolean = false, bodyGen: IrBlockBodyBuilder.(IrFunction) -> Unit) {
|
||||
val f: IrSimpleFunction = searchForDeclaration(descriptor)
|
||||
?: (if (ignoreWhenMissing) return else compilerContext.symbolTable.referenceSimpleFunction(descriptor).owner)
|
||||
f.body = DeclarationIrBuilder(compilerContext, f.symbol, this.startOffset, this.endOffset).irBlockBody(
|
||||
this.startOffset,
|
||||
this.endOffset
|
||||
@@ -489,7 +490,7 @@ interface IrBuilderExtension {
|
||||
)
|
||||
}.also { f ->
|
||||
generateOverriddenFunctionSymbols(f, compilerContext.symbolTable)
|
||||
f.createParameterDeclarations(receiver = null)
|
||||
f.createParameterDeclarations(descriptor)
|
||||
f.returnType = descriptor.returnType!!.toIrType()
|
||||
f.correspondingPropertySymbol = fieldSymbol.owner.correspondingPropertySymbol
|
||||
}
|
||||
@@ -572,7 +573,7 @@ interface IrBuilderExtension {
|
||||
}
|
||||
|
||||
fun IrFunction.createParameterDeclarations(
|
||||
receiver: IrValueParameter?,
|
||||
descriptor: FunctionDescriptor,
|
||||
overwriteValueParameters: Boolean = false,
|
||||
copyTypeParameters: Boolean = true
|
||||
) {
|
||||
@@ -589,7 +590,7 @@ interface IrBuilderExtension {
|
||||
|
||||
if (copyTypeParameters) {
|
||||
assert(typeParameters.isEmpty())
|
||||
copyTypeParamsFromDescriptor()
|
||||
copyTypeParamsFromDescriptor(descriptor)
|
||||
}
|
||||
|
||||
dispatchReceiverParameter = descriptor.dispatchReceiverParameter?.let { irValueParameter(it) }
|
||||
@@ -601,7 +602,7 @@ interface IrBuilderExtension {
|
||||
valueParameters = descriptor.valueParameters.map { irValueParameter(it) }
|
||||
}
|
||||
|
||||
fun IrFunction.copyTypeParamsFromDescriptor() {
|
||||
fun IrFunction.copyTypeParamsFromDescriptor(descriptor: FunctionDescriptor) {
|
||||
val newTypeParameters = descriptor.typeParameters.map {
|
||||
factory.createTypeParameter(
|
||||
startOffset, endOffset,
|
||||
@@ -991,4 +992,98 @@ interface IrBuilderExtension {
|
||||
return superClasses.singleOrNull { it.kind == ClassKind.CLASS }
|
||||
}
|
||||
|
||||
fun IrClass.findWriteSelfMethod(): IrSimpleFunction? =
|
||||
declarations.filter { it is IrSimpleFunction && it.name == SerialEntityNames.WRITE_SELF_NAME && !it.isFakeOverride }
|
||||
.takeUnless(Collection<*>::isEmpty)?.single() as IrSimpleFunction?
|
||||
|
||||
fun IrBlockBodyBuilder.serializeAllProperties(
|
||||
generator: AbstractSerialGenerator,
|
||||
serializableIrClass: IrClass,
|
||||
serializableProperties: List<SerializableProperty>,
|
||||
objectToSerialize: IrValueDeclaration,
|
||||
localOutput: IrValueDeclaration,
|
||||
localSerialDesc: IrValueDeclaration,
|
||||
kOutputClass: ClassDescriptor,
|
||||
ignoreIndexTo: Int,
|
||||
initializerAdapter: (IrExpressionBody) -> IrExpression,
|
||||
genericGetter: ((Int, KotlinType) -> IrExpression)?
|
||||
) {
|
||||
|
||||
fun SerializableProperty.irGet(): IrExpression {
|
||||
val ownerType = objectToSerialize.symbol.owner.type
|
||||
return getProperty(
|
||||
irGet(
|
||||
type = ownerType,
|
||||
variable = objectToSerialize.symbol
|
||||
), getIrPropertyFrom(serializableIrClass)
|
||||
)
|
||||
}
|
||||
|
||||
for ((index, property) in serializableProperties.withIndex()) {
|
||||
if (index < ignoreIndexTo) continue
|
||||
// output.writeXxxElementValue(classDesc, index, value)
|
||||
val elementCall = formEncodeDecodePropertyCall(
|
||||
generator,
|
||||
irGet(localOutput),
|
||||
property, { innerSerial, sti ->
|
||||
val f =
|
||||
kOutputClass.referenceFunctionSymbol("${CallingConventions.encode}${sti.elementMethodPrefix}Serializable${CallingConventions.elementPostfix}")
|
||||
f to listOf(
|
||||
irGet(localSerialDesc),
|
||||
irInt(index),
|
||||
innerSerial,
|
||||
property.irGet()
|
||||
)
|
||||
}, {
|
||||
val f =
|
||||
kOutputClass.referenceFunctionSymbol("${CallingConventions.encode}${it.elementMethodPrefix}${CallingConventions.elementPostfix}")
|
||||
val args: MutableList<IrExpression> = mutableListOf(irGet(localSerialDesc), irInt(index))
|
||||
if (it.elementMethodPrefix != "Unit") args.add(property.irGet())
|
||||
f to args
|
||||
},
|
||||
genericGetter
|
||||
)
|
||||
|
||||
// check for call to .shouldEncodeElementDefault
|
||||
if (!property.optional) {
|
||||
// emit call right away
|
||||
+elementCall
|
||||
} else {
|
||||
// emit check:
|
||||
// if (if (output.shouldEncodeElementDefault(this.descriptor, i)) true else {obj.prop != DEFAULT_VALUE} ) {
|
||||
// output.encodeIntElement(this.descriptor, i, obj.prop)// block {obj.prop != DEFAULT_VALUE} may contain several statements
|
||||
val shouldEncodeFunc = kOutputClass.referenceFunctionSymbol(CallingConventions.shouldEncodeDefault)
|
||||
val partA = irInvoke(irGet(localOutput), shouldEncodeFunc, irGet(localSerialDesc), irInt(index))
|
||||
val partB = irNotEquals(property.irGet(), initializerAdapter(property.irField.initializer!!))
|
||||
// Ir infrastructure does not have dedicated symbol for ||, so
|
||||
// `a || b == if (a) true else b`, see org.jetbrains.kotlin.ir.builders.PrimitivesKt.oror
|
||||
val condition = irIfThenElse(compilerContext.irBuiltIns.booleanType, partA, irTrue(), partB)
|
||||
+irIfThen(condition, elementCall)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun IrBlockBodyBuilder.formEncodeDecodePropertyCall(
|
||||
enclosingGenerator: AbstractSerialGenerator,
|
||||
encoder: IrExpression,
|
||||
property: SerializableProperty,
|
||||
whenHaveSerializer: (serializer: IrExpression, sti: SerialTypeInfo) -> FunctionWithArgs,
|
||||
whenDoNot: (sti: SerialTypeInfo) -> FunctionWithArgs,
|
||||
genericGetter: ((Int, KotlinType) -> IrExpression)? = null,
|
||||
returnTypeHint: IrType? = null
|
||||
): IrExpression {
|
||||
val sti = enclosingGenerator.getSerialTypeInfo(property)
|
||||
val innerSerial = serializerInstance(
|
||||
enclosingGenerator,
|
||||
sti.serializer,
|
||||
property.module,
|
||||
property.type,
|
||||
property.genericIndex,
|
||||
genericGetter
|
||||
)
|
||||
val (functionToCall, args: List<IrExpression>) = if (innerSerial != null) whenHaveSerializer(innerSerial, sti) else whenDoNot(sti)
|
||||
val typeArgs = if (functionToCall.descriptor.typeParameters.isNotEmpty()) listOf(property.type.toIrType()) else listOf()
|
||||
return irInvoke(encoder, functionToCall, typeArguments = typeArgs, valueArguments = args, returnTypeHint = returnTypeHint)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+53
-6
@@ -25,9 +25,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.utils.getOrPutNullable
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.SerializableCodegen
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.isStaticSerializable
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.serialName
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.*
|
||||
import org.jetbrains.kotlinx.serialization.compiler.diagnostic.serializableAnnotationIsUseless
|
||||
import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationPluginContext
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.*
|
||||
@@ -284,7 +282,57 @@ class SerializableIrGenerator(
|
||||
}
|
||||
|
||||
override fun generateWriteSelfMethod(methodDescriptor: FunctionDescriptor) {
|
||||
// no-op
|
||||
irClass.contributeFunction(methodDescriptor, ignoreWhenMissing = true) { writeSelfFunction ->
|
||||
val objectToSerialize = writeSelfFunction.valueParameters[0]
|
||||
val localOutput = writeSelfFunction.valueParameters[1]
|
||||
val localSerialDesc = writeSelfFunction.valueParameters[2]
|
||||
val serializableProperties = properties.serializableProperties
|
||||
val kOutputClass = serializableDescriptor.getClassFromSerializationPackage(SerialEntityNames.STRUCTURE_ENCODER_CLASS)
|
||||
|
||||
val propertyByParamReplacer: (ValueParameterDescriptor) -> IrExpression? =
|
||||
createPropertyByParamReplacer(irClass, serializableProperties, objectToSerialize, bindingContext)
|
||||
|
||||
// Since writeSelf is a static method, we have to replace all references to this in property initializers
|
||||
val thisSymbol = irClass.thisReceiver!!.symbol
|
||||
val initializerAdapter: (IrExpressionBody) -> IrExpression = createInitializerAdapter(irClass, propertyByParamReplacer, thisSymbol to { irGet(objectToSerialize) })
|
||||
|
||||
// Compute offset of properties in superclass
|
||||
var ignoreIndexTo = -1
|
||||
val superClass = irClass.getSuperClassOrAny()
|
||||
if (superClass.descriptor.isInternalSerializable) {
|
||||
ignoreIndexTo = bindingContext.serializablePropertiesFor(superClass.descriptor).size
|
||||
|
||||
// call super.writeSelf
|
||||
val superWriteSelfF = superClass.findWriteSelfMethod()
|
||||
if (superWriteSelfF != null) {
|
||||
val args = mutableListOf<IrExpression>(irGet(objectToSerialize), irGet(localOutput), irGet(localSerialDesc))
|
||||
|
||||
val typeArgsForParent = serializableDescriptor.typeConstructor.supertypes.single { it.toClassDescriptor?.isInternalSerializable == true }.arguments
|
||||
val parentWriteSelfSerializers = typeArgsForParent.map { arg ->
|
||||
val genericIdx = serializableDescriptor.defaultType.arguments.indexOf(arg).let { if (it == -1) null else it }
|
||||
val serial = findTypeSerializerOrContext(serializableDescriptor.module, arg.type)
|
||||
serializerInstance(
|
||||
this@SerializableIrGenerator,
|
||||
serial,
|
||||
serializableDescriptor.module,
|
||||
arg.type,
|
||||
genericIdx
|
||||
) { it, _ ->
|
||||
irGet(writeSelfFunction.valueParameters[3 + it])
|
||||
}!!
|
||||
}
|
||||
+irInvoke(null, superWriteSelfF.symbol, typeArgsForParent.map { it.type.toIrType() }, args + parentWriteSelfSerializers)
|
||||
}
|
||||
}
|
||||
|
||||
serializeAllProperties(
|
||||
this@SerializableIrGenerator, irClass, serializableProperties,
|
||||
objectToSerialize, localOutput, localSerialDesc,
|
||||
kOutputClass, ignoreIndexTo, initializerAdapter
|
||||
) { it, _ ->
|
||||
irGet(writeSelfFunction.valueParameters[3 + it])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
@@ -298,8 +346,7 @@ class SerializableIrGenerator(
|
||||
if (serializableClass.isInternalSerializable) {
|
||||
SerializableIrGenerator(irClass, context, bindingContext).generate()
|
||||
irClass.patchDeclarationParents(irClass.parent)
|
||||
}
|
||||
else if (serializableClass.serializableAnnotationIsUseless) {
|
||||
} else if (serializableClass.serializableAnnotationIsUseless) {
|
||||
throw CompilationException(
|
||||
"@Serializable annotation on $serializableClass would be ignored because it is impossible to serialize it automatically. " +
|
||||
"Provide serializer manually via e.g. companion object", null, serializableClass.findPsi()
|
||||
|
||||
+54
-81
@@ -25,9 +25,9 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.SerialTypeInfo
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.SerializerCodegen
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.getSerialTypeInfo
|
||||
import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationDescriptorSerializerPlugin
|
||||
import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationPluginContext
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.*
|
||||
@@ -196,13 +196,13 @@ open class SerializerIrGenerator(
|
||||
val thisAsReceiverParameter = irClass.thisReceiver!!
|
||||
ctor.valueParameters.forEachIndexed { index, param ->
|
||||
val localSerial = localSerializersFieldsDescriptors[index].second.backingField!!
|
||||
+irSetField(generateReceiverExpressionForFieldAccess(
|
||||
thisAsReceiverParameter.symbol,
|
||||
localSerializersFieldsDescriptors[index].first
|
||||
), localSerial, irGet(param))
|
||||
+irSetField(
|
||||
generateReceiverExpressionForFieldAccess(
|
||||
thisAsReceiverParameter.symbol,
|
||||
localSerializersFieldsDescriptors[index].first
|
||||
), localSerial, irGet(param)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
override fun generateChildSerializersGetter(function: FunctionDescriptor) = irClass.contributeFunction(function) { irFun ->
|
||||
@@ -256,69 +256,44 @@ open class SerializerIrGenerator(
|
||||
val objectToSerialize = saveFunc.valueParameters[1]
|
||||
val localOutput = irTemporary(call, "output")
|
||||
|
||||
fun SerializableProperty.irGet(): IrExpression {
|
||||
val ownerType = objectToSerialize.symbol.owner.type
|
||||
return getProperty(
|
||||
irGet(
|
||||
type = ownerType,
|
||||
variable = objectToSerialize.symbol
|
||||
), getIrPropertyFrom(serializableIrClass)
|
||||
)
|
||||
}
|
||||
val writeSelfFunction = serializableIrClass.findWriteSelfMethod()
|
||||
|
||||
// Ignore comparing to default values of properties from superclass,
|
||||
// because we do not have access to their fields (and initializers), if superclass is in another module.
|
||||
// In future, IR analogue of JVM's write$Self should be implemented.
|
||||
val superClass = serializableIrClass.getSuperClassOrAny().descriptor
|
||||
val ignoreIndexTo = if (superClass.isInternalSerializable) {
|
||||
bindingContext.serializablePropertiesFor(superClass).size
|
||||
} else {
|
||||
-1
|
||||
}
|
||||
|
||||
val propertyByParamReplacer: (ValueParameterDescriptor) -> IrExpression? =
|
||||
createPropertyByParamReplacer(serializableIrClass, serializableProperties, objectToSerialize, bindingContext)
|
||||
|
||||
val thisSymbol = serializableIrClass.thisReceiver!!.symbol
|
||||
val initializerAdapter: (IrExpressionBody) -> IrExpression =
|
||||
createInitializerAdapter(serializableIrClass, propertyByParamReplacer, thisSymbol to { irGet(objectToSerialize) })
|
||||
|
||||
// internal serialization via virtual calls?
|
||||
for ((index, property) in serializableProperties.withIndex()) {
|
||||
// output.writeXxxElementValue(classDesc, index, value)
|
||||
val elementCall = formEncodeDecodePropertyCall(irGet(localOutput), saveFunc.dispatchReceiverParameter!!, property, {innerSerial, sti ->
|
||||
val f =
|
||||
kOutputClass.referenceFunctionSymbol("${CallingConventions.encode}${sti.elementMethodPrefix}Serializable${CallingConventions.elementPostfix}")
|
||||
f to listOf(
|
||||
irGet(localSerialDesc),
|
||||
irInt(index),
|
||||
innerSerial,
|
||||
property.irGet()
|
||||
if (writeSelfFunction != null) {
|
||||
// extract Tx from KSerializer<Tx> list
|
||||
val typeArgs =
|
||||
localSerializersFieldsDescriptors.map { (_, ir) -> ir.backingField!!.type.cast<IrSimpleType>().arguments.single().typeOrNull }
|
||||
val args = mutableListOf<IrExpression>(irGet(objectToSerialize), irGet(localOutput), irGet(localSerialDesc))
|
||||
args.addAll(localSerializersFieldsDescriptors.map { (_, ir) ->
|
||||
irGetField(
|
||||
irGet(saveFunc.dispatchReceiverParameter!!),
|
||||
ir.backingField!!
|
||||
)
|
||||
}, {
|
||||
val f =
|
||||
kOutputClass.referenceFunctionSymbol("${CallingConventions.encode}${it.elementMethodPrefix}${CallingConventions.elementPostfix}")
|
||||
val args: MutableList<IrExpression> = mutableListOf(irGet(localSerialDesc), irInt(index))
|
||||
if (it.elementMethodPrefix != "Unit") args.add(property.irGet())
|
||||
f to args
|
||||
})
|
||||
|
||||
// check for call to .shouldEncodeElementDefault
|
||||
if (!property.optional || index < ignoreIndexTo) {
|
||||
// emit call right away
|
||||
+elementCall
|
||||
+irInvoke(null, writeSelfFunction.symbol, typeArgs, args)
|
||||
} else {
|
||||
// No write$Self, old behaviour:
|
||||
// Ignore comparing to default values of properties from superclass,
|
||||
// because we do not have access to their fields (and initializers), if superclass is in another module.
|
||||
val superClass = serializableIrClass.getSuperClassOrAny().descriptor
|
||||
val ignoreIndexTo = if (superClass.isInternalSerializable) {
|
||||
bindingContext.serializablePropertiesFor(superClass).size
|
||||
} else {
|
||||
// emit check:
|
||||
// if ( if (output.shouldEncodeElementDefault(this.descriptor, i)) true else {obj.prop != DEFAULT_VALUE} ) {
|
||||
// output.encodeIntElement(this.descriptor, i, obj.prop)
|
||||
// block {obj.prop != DEFAULT_VALUE} may contain several statements
|
||||
val shouldEncodeFunc = kOutputClass.referenceFunctionSymbol(CallingConventions.shouldEncodeDefault)
|
||||
val partA = irInvoke(irGet(localOutput), shouldEncodeFunc, irGet(localSerialDesc), irInt(index))
|
||||
val partB = irNotEquals(property.irGet(), initializerAdapter(property.irField.initializer!!))
|
||||
// Ir infrastructure does not have dedicated symbol for ||, so
|
||||
// `a || b == if (a) true else b`, see org.jetbrains.kotlin.ir.builders.PrimitivesKt.oror
|
||||
val condition = irIfThenElse(compilerContext.irBuiltIns.booleanType, partA, irTrue(), partB)
|
||||
+irIfThen(condition, elementCall)
|
||||
-1
|
||||
}
|
||||
|
||||
val propertyByParamReplacer: (ValueParameterDescriptor) -> IrExpression? =
|
||||
createPropertyByParamReplacer(serializableIrClass, serializableProperties, objectToSerialize, bindingContext)
|
||||
|
||||
val thisSymbol = serializableIrClass.thisReceiver!!.symbol
|
||||
val initializerAdapter: (IrExpressionBody) -> IrExpression =
|
||||
createInitializerAdapter(serializableIrClass, propertyByParamReplacer, thisSymbol to { irGet(objectToSerialize) })
|
||||
|
||||
serializeAllProperties(
|
||||
this@SerializerIrGenerator, serializableIrClass, serializableProperties, objectToSerialize,
|
||||
localOutput, localSerialDesc, kOutputClass, ignoreIndexTo, initializerAdapter
|
||||
) { it, _ ->
|
||||
val (_, ir) = localSerializersFieldsDescriptors[it]
|
||||
irGetField(irGet(saveFunc.dispatchReceiverParameter!!), ir.backingField!!)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,27 +302,25 @@ open class SerializerIrGenerator(
|
||||
+irInvoke(irGet(localOutput), wEndFunc, irGet(localSerialDesc))
|
||||
}
|
||||
|
||||
protected inline fun IrBlockBodyBuilder.formEncodeDecodePropertyCall(
|
||||
protected fun IrBlockBodyBuilder.formEncodeDecodePropertyCall(
|
||||
encoder: IrExpression,
|
||||
dispatchReceiver: IrValueParameter,
|
||||
property: SerializableProperty,
|
||||
whenHaveSerializer: (serializer: IrExpression, sti: SerialTypeInfo) -> FunctionWithArgs,
|
||||
whenDoNot: (sti: SerialTypeInfo) -> FunctionWithArgs,
|
||||
returnTypeHint: IrType? = null
|
||||
): IrExpression {
|
||||
val sti = getSerialTypeInfo(property)
|
||||
val innerSerial = serializerInstance(
|
||||
this@SerializerIrGenerator,
|
||||
dispatchReceiver,
|
||||
sti.serializer,
|
||||
property.module,
|
||||
property.type,
|
||||
genericIndex = property.genericIndex
|
||||
)
|
||||
val (functionToCall, args: List<IrExpression>) = if (innerSerial != null) whenHaveSerializer(innerSerial, sti) else whenDoNot(sti)
|
||||
val typeArgs = if (functionToCall.descriptor.typeParameters.isNotEmpty()) listOf(property.type.toIrType()) else listOf()
|
||||
return irInvoke(encoder, functionToCall, typeArguments = typeArgs, valueArguments = args, returnTypeHint = returnTypeHint)
|
||||
}
|
||||
): IrExpression = formEncodeDecodePropertyCall(
|
||||
this@SerializerIrGenerator,
|
||||
encoder,
|
||||
property,
|
||||
whenHaveSerializer,
|
||||
whenDoNot,
|
||||
{ it, _ ->
|
||||
val (_, ir) = localSerializersFieldsDescriptors[it]
|
||||
irGetField(irGet(dispatchReceiver), ir.backingField!!)
|
||||
},
|
||||
returnTypeHint
|
||||
)
|
||||
|
||||
// returns null: Any? for boxed types and 0: <number type> for primitives
|
||||
private fun IrBuilderWithScope.defaultValueAndType(descriptor: PropertyDescriptor): Pair<IrExpression, IrType> {
|
||||
|
||||
+18
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -39,9 +39,25 @@ open class SerializationResolveExtension @JvmOverloads constructor(val metadataP
|
||||
override fun getSyntheticFunctionNames(thisDescriptor: ClassDescriptor): List<Name> = when {
|
||||
thisDescriptor.isSerializableObject || thisDescriptor.isCompanionObject && getSerializableClassDescriptorByCompanion(thisDescriptor) != null ->
|
||||
listOf(SerialEntityNames.SERIALIZER_PROVIDER_NAME)
|
||||
thisDescriptor.isInternalSerializable && thisDescriptor.platform?.isJvm() == true && !hasCustomizedSerializeMethod(thisDescriptor) -> {
|
||||
// add write$Self, but only if .serialize was not customized in companion.
|
||||
// It works not only on JVM, but I see no reason to enable it on other platforms —
|
||||
// private fields there have no access control, and additional function
|
||||
// only increases compiled code size.
|
||||
listOf(SerialEntityNames.WRITE_SELF_NAME)
|
||||
}
|
||||
else -> emptyList()
|
||||
}
|
||||
|
||||
private fun hasCustomizedSerializeMethod(serializableClass: ClassDescriptor): Boolean {
|
||||
// We cannot check whether companion has @Serializer(MyClass::class) annotation due to recursive resolve problems
|
||||
// (apparently, resolve MyClass type asks for all function names, which leads us to this function again)
|
||||
// so we rely on less strict check that companion just has non-empty @Serializer annotation.
|
||||
// Anyway, I doubt that serializable class companion would ever be serializer for _another_ class.
|
||||
val companion = serializableClass.companionObjectDescriptor ?: return false
|
||||
return companion.annotations.hasAnnotation(SerializationAnnotations.serializerAnnotationFqName)
|
||||
}
|
||||
|
||||
override fun generateSyntheticClasses(
|
||||
thisDescriptor: ClassDescriptor,
|
||||
name: Name,
|
||||
@@ -91,6 +107,7 @@ open class SerializationResolveExtension @JvmOverloads constructor(val metadataP
|
||||
) {
|
||||
KSerializerDescriptorResolver.generateSerializerMethods(thisDescriptor, fromSupertypes, name, result)
|
||||
KSerializerDescriptorResolver.generateCompanionObjectMethods(thisDescriptor, name, result)
|
||||
KSerializerDescriptorResolver.generateSerializableClassMethods(thisDescriptor, name, result)
|
||||
}
|
||||
|
||||
override fun generateSyntheticProperties(
|
||||
|
||||
+8
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -217,6 +217,11 @@ object KSerializerDescriptorResolver {
|
||||
}
|
||||
}
|
||||
|
||||
fun generateSerializableClassMethods(thisDescriptor: ClassDescriptor, name: Name, result: MutableCollection<SimpleFunctionDescriptor>) {
|
||||
if (thisDescriptor.isInternalSerializable && name == SerialEntityNames.WRITE_SELF_NAME)
|
||||
result.add(createWriteSelfFunctionDescriptor(thisDescriptor))
|
||||
}
|
||||
|
||||
private fun createSerializableClassPropertyDescriptor(
|
||||
companionDescriptor: ClassDescriptor,
|
||||
classDescriptor: ClassDescriptor
|
||||
@@ -490,7 +495,7 @@ object KSerializerDescriptorResolver {
|
||||
if (KotlinBuiltIns.isPrimitiveType(this)) this
|
||||
else this.makeNullable()
|
||||
|
||||
fun createWriteSelfFunctionDescriptor(thisClass: ClassDescriptor): FunctionDescriptor {
|
||||
fun createWriteSelfFunctionDescriptor(thisClass: ClassDescriptor): SimpleFunctionDescriptor {
|
||||
val jvmStaticClass = thisClass.module.findClassAcrossModuleDependencies(
|
||||
ClassId(
|
||||
FqName("kotlin.jvm"),
|
||||
@@ -570,7 +575,7 @@ object KSerializerDescriptorResolver {
|
||||
|
||||
f.initialize(
|
||||
null,
|
||||
thisClass.thisAsReceiverParameter,
|
||||
null,
|
||||
typeArgs,
|
||||
args,
|
||||
returnType,
|
||||
|
||||
+118
-55
@@ -182,18 +182,10 @@ public final class ListOfUsers$$serializer : java/lang/Object, kotlinx/serializa
|
||||
ALOAD (3)
|
||||
INVOKEINTERFACE (kotlinx/serialization/encoding/Encoder, beginStructure, (Lkotlinx/serialization/descriptors/SerialDescriptor;)Lkotlinx/serialization/encoding/CompositeEncoder;)
|
||||
ASTORE (4)
|
||||
ALOAD (2)
|
||||
ALOAD (4)
|
||||
ALOAD (3)
|
||||
ICONST_0
|
||||
NEW
|
||||
DUP
|
||||
GETSTATIC (INSTANCE, LUser$$serializer;)
|
||||
CHECKCAST
|
||||
INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, <init>, (Lkotlinx/serialization/KSerializer;)V)
|
||||
CHECKCAST
|
||||
ALOAD (2)
|
||||
INVOKEVIRTUAL (ListOfUsers, getList, ()Ljava/util/List;)
|
||||
INVOKEINTERFACE (kotlinx/serialization/encoding/CompositeEncoder, encodeSerializableElement, (Lkotlinx/serialization/descriptors/SerialDescriptor;ILkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V)
|
||||
INVOKESTATIC (ListOfUsers, write$Self, (LListOfUsers;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V)
|
||||
ALOAD (4)
|
||||
ALOAD (3)
|
||||
INVOKEINTERFACE (kotlinx/serialization/encoding/CompositeEncoder, endStructure, (Lkotlinx/serialization/descriptors/SerialDescriptor;)V)
|
||||
@@ -293,6 +285,35 @@ public final class ListOfUsers : java/lang/Object {
|
||||
}
|
||||
|
||||
public final java.util.List getList()
|
||||
|
||||
public final static void write$Self(ListOfUsers self, kotlinx.serialization.encoding.CompositeEncoder output, kotlinx.serialization.descriptors.SerialDescriptor serialDesc) {
|
||||
LABEL (L0)
|
||||
ALOAD (0)
|
||||
LDC (self)
|
||||
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNullParameter, (Ljava/lang/Object;Ljava/lang/String;)V)
|
||||
ALOAD (1)
|
||||
LDC (output)
|
||||
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNullParameter, (Ljava/lang/Object;Ljava/lang/String;)V)
|
||||
ALOAD (2)
|
||||
LDC (serialDesc)
|
||||
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNullParameter, (Ljava/lang/Object;Ljava/lang/String;)V)
|
||||
LABEL (L1)
|
||||
LINENUMBER (12)
|
||||
ALOAD (1)
|
||||
ALOAD (2)
|
||||
ICONST_0
|
||||
NEW
|
||||
DUP
|
||||
GETSTATIC (INSTANCE, LUser$$serializer;)
|
||||
CHECKCAST
|
||||
INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, <init>, (Lkotlinx/serialization/KSerializer;)V)
|
||||
CHECKCAST
|
||||
ALOAD (0)
|
||||
GETFIELD (list, Ljava/util/List;)
|
||||
INVOKEINTERFACE (kotlinx/serialization/encoding/CompositeEncoder, encodeSerializableElement, (Lkotlinx/serialization/descriptors/SerialDescriptor;ILkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V)
|
||||
RETURN
|
||||
LABEL (L2)
|
||||
}
|
||||
}
|
||||
|
||||
public final class OptionalUser$$serializer : java/lang/Object, kotlinx/serialization/internal/GeneratedSerializer {
|
||||
@@ -467,47 +488,15 @@ public final class OptionalUser$$serializer : java/lang/Object, kotlinx/serializ
|
||||
ALOAD (3)
|
||||
INVOKEINTERFACE (kotlinx/serialization/encoding/Encoder, beginStructure, (Lkotlinx/serialization/descriptors/SerialDescriptor;)Lkotlinx/serialization/encoding/CompositeEncoder;)
|
||||
ASTORE (4)
|
||||
ALOAD (2)
|
||||
ALOAD (4)
|
||||
ALOAD (3)
|
||||
ICONST_0
|
||||
INVOKEINTERFACE (kotlinx/serialization/encoding/CompositeEncoder, shouldEncodeElementDefault, (Lkotlinx/serialization/descriptors/SerialDescriptor;I)Z)
|
||||
IFEQ (L2)
|
||||
ICONST_1
|
||||
GOTO (L3)
|
||||
LABEL (L2)
|
||||
ALOAD (2)
|
||||
INVOKEVIRTUAL (OptionalUser, getUser, ()LUser;)
|
||||
LABEL (L4)
|
||||
LINENUMBER (10)
|
||||
NEW
|
||||
DUP
|
||||
LDC ()
|
||||
LDC ()
|
||||
INVOKESPECIAL (User, <init>, (Ljava/lang/String;Ljava/lang/String;)V)
|
||||
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, areEqual, (Ljava/lang/Object;Ljava/lang/Object;)Z)
|
||||
IFNE (L5)
|
||||
ICONST_1
|
||||
GOTO (L3)
|
||||
LABEL (L5)
|
||||
ICONST_0
|
||||
LABEL (L3)
|
||||
IFEQ (L6)
|
||||
LABEL (L7)
|
||||
LINENUMBER (9)
|
||||
ALOAD (4)
|
||||
ALOAD (3)
|
||||
ICONST_0
|
||||
GETSTATIC (INSTANCE, LUser$$serializer;)
|
||||
CHECKCAST
|
||||
ALOAD (2)
|
||||
INVOKEVIRTUAL (OptionalUser, getUser, ()LUser;)
|
||||
INVOKEINTERFACE (kotlinx/serialization/encoding/CompositeEncoder, encodeSerializableElement, (Lkotlinx/serialization/descriptors/SerialDescriptor;ILkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V)
|
||||
LABEL (L6)
|
||||
INVOKESTATIC (OptionalUser, write$Self, (LOptionalUser;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V)
|
||||
ALOAD (4)
|
||||
ALOAD (3)
|
||||
INVOKEINTERFACE (kotlinx/serialization/encoding/CompositeEncoder, endStructure, (Lkotlinx/serialization/descriptors/SerialDescriptor;)V)
|
||||
RETURN
|
||||
LABEL (L8)
|
||||
LABEL (L2)
|
||||
}
|
||||
|
||||
public void serialize(kotlinx.serialization.encoding.Encoder encoder, java.lang.Object value) {
|
||||
@@ -650,6 +639,59 @@ public final class OptionalUser : java/lang/Object {
|
||||
}
|
||||
|
||||
public final User getUser()
|
||||
|
||||
public final static void write$Self(OptionalUser self, kotlinx.serialization.encoding.CompositeEncoder output, kotlinx.serialization.descriptors.SerialDescriptor serialDesc) {
|
||||
LABEL (L0)
|
||||
ALOAD (0)
|
||||
LDC (self)
|
||||
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNullParameter, (Ljava/lang/Object;Ljava/lang/String;)V)
|
||||
ALOAD (1)
|
||||
LDC (output)
|
||||
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNullParameter, (Ljava/lang/Object;Ljava/lang/String;)V)
|
||||
ALOAD (2)
|
||||
LDC (serialDesc)
|
||||
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNullParameter, (Ljava/lang/Object;Ljava/lang/String;)V)
|
||||
LABEL (L1)
|
||||
LINENUMBER (9)
|
||||
ALOAD (1)
|
||||
ALOAD (2)
|
||||
ICONST_0
|
||||
INVOKEINTERFACE (kotlinx/serialization/encoding/CompositeEncoder, shouldEncodeElementDefault, (Lkotlinx/serialization/descriptors/SerialDescriptor;I)Z)
|
||||
IFEQ (L2)
|
||||
ICONST_1
|
||||
GOTO (L3)
|
||||
LABEL (L2)
|
||||
ALOAD (0)
|
||||
GETFIELD (user, LUser;)
|
||||
LABEL (L4)
|
||||
LINENUMBER (10)
|
||||
NEW
|
||||
DUP
|
||||
LDC ()
|
||||
LDC ()
|
||||
INVOKESPECIAL (User, <init>, (Ljava/lang/String;Ljava/lang/String;)V)
|
||||
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, areEqual, (Ljava/lang/Object;Ljava/lang/Object;)Z)
|
||||
IFNE (L5)
|
||||
ICONST_1
|
||||
GOTO (L3)
|
||||
LABEL (L5)
|
||||
ICONST_0
|
||||
LABEL (L3)
|
||||
IFEQ (L6)
|
||||
LABEL (L7)
|
||||
LINENUMBER (9)
|
||||
ALOAD (1)
|
||||
ALOAD (2)
|
||||
ICONST_0
|
||||
GETSTATIC (INSTANCE, LUser$$serializer;)
|
||||
CHECKCAST
|
||||
ALOAD (0)
|
||||
GETFIELD (user, LUser;)
|
||||
INVOKEINTERFACE (kotlinx/serialization/encoding/CompositeEncoder, encodeSerializableElement, (Lkotlinx/serialization/descriptors/SerialDescriptor;ILkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V)
|
||||
LABEL (L6)
|
||||
RETURN
|
||||
LABEL (L8)
|
||||
}
|
||||
}
|
||||
|
||||
public final class User$$serializer : java/lang/Object, kotlinx/serialization/internal/GeneratedSerializer {
|
||||
@@ -849,18 +891,10 @@ public final class User$$serializer : java/lang/Object, kotlinx/serialization/in
|
||||
ALOAD (3)
|
||||
INVOKEINTERFACE (kotlinx/serialization/encoding/Encoder, beginStructure, (Lkotlinx/serialization/descriptors/SerialDescriptor;)Lkotlinx/serialization/encoding/CompositeEncoder;)
|
||||
ASTORE (4)
|
||||
ALOAD (2)
|
||||
ALOAD (4)
|
||||
ALOAD (3)
|
||||
ICONST_0
|
||||
ALOAD (2)
|
||||
INVOKEVIRTUAL (User, getFirstName, ()Ljava/lang/String;)
|
||||
INVOKEINTERFACE (kotlinx/serialization/encoding/CompositeEncoder, encodeStringElement, (Lkotlinx/serialization/descriptors/SerialDescriptor;ILjava/lang/String;)V)
|
||||
ALOAD (4)
|
||||
ALOAD (3)
|
||||
ICONST_1
|
||||
ALOAD (2)
|
||||
INVOKEVIRTUAL (User, getLastName, ()Ljava/lang/String;)
|
||||
INVOKEINTERFACE (kotlinx/serialization/encoding/CompositeEncoder, encodeStringElement, (Lkotlinx/serialization/descriptors/SerialDescriptor;ILjava/lang/String;)V)
|
||||
INVOKESTATIC (User, write$Self, (LUser;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V)
|
||||
ALOAD (4)
|
||||
ALOAD (3)
|
||||
INVOKEINTERFACE (kotlinx/serialization/encoding/CompositeEncoder, endStructure, (Lkotlinx/serialization/descriptors/SerialDescriptor;)V)
|
||||
@@ -973,4 +1007,33 @@ public final class User : java/lang/Object {
|
||||
public final java.lang.String getFirstName()
|
||||
|
||||
public final java.lang.String getLastName()
|
||||
|
||||
public final static void write$Self(User self, kotlinx.serialization.encoding.CompositeEncoder output, kotlinx.serialization.descriptors.SerialDescriptor serialDesc) {
|
||||
LABEL (L0)
|
||||
ALOAD (0)
|
||||
LDC (self)
|
||||
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNullParameter, (Ljava/lang/Object;Ljava/lang/String;)V)
|
||||
ALOAD (1)
|
||||
LDC (output)
|
||||
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNullParameter, (Ljava/lang/Object;Ljava/lang/String;)V)
|
||||
ALOAD (2)
|
||||
LDC (serialDesc)
|
||||
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNullParameter, (Ljava/lang/Object;Ljava/lang/String;)V)
|
||||
LABEL (L1)
|
||||
LINENUMBER (6)
|
||||
ALOAD (1)
|
||||
ALOAD (2)
|
||||
ICONST_0
|
||||
ALOAD (0)
|
||||
GETFIELD (firstName, Ljava/lang/String;)
|
||||
INVOKEINTERFACE (kotlinx/serialization/encoding/CompositeEncoder, encodeStringElement, (Lkotlinx/serialization/descriptors/SerialDescriptor;ILjava/lang/String;)V)
|
||||
ALOAD (1)
|
||||
ALOAD (2)
|
||||
ICONST_1
|
||||
ALOAD (0)
|
||||
GETFIELD (lastName, Ljava/lang/String;)
|
||||
INVOKEINTERFACE (kotlinx/serialization/encoding/CompositeEncoder, encodeStringElement, (Lkotlinx/serialization/descriptors/SerialDescriptor;ILjava/lang/String;)V)
|
||||
RETURN
|
||||
LABEL (L2)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER,-UNUSED_VARIABLE
|
||||
|
||||
// WITH_RUNTIME
|
||||
// FILE: test.kt
|
||||
import kotlinx.serialization.*
|
||||
|
||||
|
||||
+3
@@ -7,6 +7,8 @@ package
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
@kotlin.jvm.JvmStatic public final /*synthesized*/ fun `write$Self`(/*0*/ self: Derived, /*1*/ output: kotlinx.serialization.encoding.CompositeEncoder, /*2*/ serialDesc: kotlinx.serialization.descriptors.SerialDescriptor): kotlin.Unit
|
||||
@kotlin.jvm.JvmStatic public final override /*1*/ /*fake_override*/ fun `write$Self`(/*0*/ self: Parent, /*1*/ output: kotlinx.serialization.encoding.CompositeEncoder, /*2*/ serialDesc: kotlinx.serialization.descriptors.SerialDescriptor): kotlin.Unit
|
||||
|
||||
@kotlin.Deprecated(level = DeprecationLevel.HIDDEN, message = "This synthesized declaration should not be used directly", replaceWith = kotlin.ReplaceWith(expression = "", imports = {})) public object `$serializer` : kotlinx.serialization.internal.GeneratedSerializer<Derived> {
|
||||
private constructor `$serializer`()
|
||||
@@ -36,6 +38,7 @@ package
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
@kotlin.jvm.JvmStatic public final /*synthesized*/ fun `write$Self`(/*0*/ self: Parent, /*1*/ output: kotlinx.serialization.encoding.CompositeEncoder, /*2*/ serialDesc: kotlinx.serialization.descriptors.SerialDescriptor): kotlin.Unit
|
||||
|
||||
@kotlin.Deprecated(level = DeprecationLevel.HIDDEN, message = "This synthesized declaration should not be used directly", replaceWith = kotlin.ReplaceWith(expression = "", imports = {})) public object `$serializer` : kotlinx.serialization.internal.GeneratedSerializer<Parent> {
|
||||
private constructor `$serializer`()
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER,-UNUSED_VARIABLE
|
||||
|
||||
// WITH_RUNTIME
|
||||
// FILE: test.kt
|
||||
import kotlinx.serialization.*
|
||||
|
||||
|
||||
+1
@@ -8,6 +8,7 @@ package
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
@kotlin.jvm.JvmStatic public final /*synthesized*/ fun `write$Self`(/*0*/ self: Derived, /*1*/ output: kotlinx.serialization.encoding.CompositeEncoder, /*2*/ serialDesc: kotlinx.serialization.descriptors.SerialDescriptor): kotlin.Unit
|
||||
|
||||
@kotlin.Deprecated(level = DeprecationLevel.HIDDEN, message = "This synthesized declaration should not be used directly", replaceWith = kotlin.ReplaceWith(expression = "", imports = {})) public object `$serializer` : kotlinx.serialization.internal.GeneratedSerializer<Derived> {
|
||||
private constructor `$serializer`()
|
||||
|
||||
Vendored
+1
-1
@@ -1,5 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER,-UNUSED_VARIABLE
|
||||
|
||||
// WITH_RUNTIME
|
||||
// FILE: test.kt
|
||||
import kotlinx.serialization.*
|
||||
|
||||
|
||||
Vendored
+3
@@ -7,6 +7,7 @@ package
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
@kotlin.jvm.JvmStatic public final /*synthesized*/ fun `write$Self`(/*0*/ self: Basic, /*1*/ output: kotlinx.serialization.encoding.CompositeEncoder, /*2*/ serialDesc: kotlinx.serialization.descriptors.SerialDescriptor): kotlin.Unit
|
||||
|
||||
@kotlin.Deprecated(level = DeprecationLevel.HIDDEN, message = "This synthesized declaration should not be used directly", replaceWith = kotlin.ReplaceWith(expression = "", imports = {})) public object `$serializer` : kotlinx.serialization.internal.GeneratedSerializer<Basic> {
|
||||
private constructor `$serializer`()
|
||||
@@ -36,6 +37,7 @@ package
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
@kotlin.jvm.JvmStatic public final /*synthesized*/ fun `write$Self`(/*0*/ self: Inside, /*1*/ output: kotlinx.serialization.encoding.CompositeEncoder, /*2*/ serialDesc: kotlinx.serialization.descriptors.SerialDescriptor): kotlin.Unit
|
||||
|
||||
@kotlin.Deprecated(level = DeprecationLevel.HIDDEN, message = "This synthesized declaration should not be used directly", replaceWith = kotlin.ReplaceWith(expression = "", imports = {})) public object `$serializer` : kotlinx.serialization.internal.GeneratedSerializer<Inside> {
|
||||
private constructor `$serializer`()
|
||||
@@ -72,6 +74,7 @@ public final class NonSerializable {
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
@kotlin.jvm.JvmStatic public final /*synthesized*/ fun `write$Self`(/*0*/ self: WithImplicitType, /*1*/ output: kotlinx.serialization.encoding.CompositeEncoder, /*2*/ serialDesc: kotlinx.serialization.descriptors.SerialDescriptor): kotlin.Unit
|
||||
|
||||
@kotlin.Deprecated(level = DeprecationLevel.HIDDEN, message = "This synthesized declaration should not be used directly", replaceWith = kotlin.ReplaceWith(expression = "", imports = {})) public object `$serializer` : kotlinx.serialization.internal.GeneratedSerializer<WithImplicitType> {
|
||||
private constructor `$serializer`()
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER,-UNUSED_VARIABLE
|
||||
|
||||
// WITH_RUNTIME
|
||||
// FILE: test.kt
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.descriptors.*
|
||||
|
||||
+1
@@ -7,6 +7,7 @@ package
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
@kotlin.jvm.JvmStatic public final /*synthesized*/ fun `write$Self`(/*0*/ self: Foo, /*1*/ output: kotlinx.serialization.encoding.CompositeEncoder, /*2*/ serialDesc: kotlinx.serialization.descriptors.SerialDescriptor): kotlin.Unit
|
||||
|
||||
@kotlin.Deprecated(level = DeprecationLevel.HIDDEN, message = "This synthesized declaration should not be used directly", replaceWith = kotlin.ReplaceWith(expression = "", imports = {})) public object `$serializer` : kotlinx.serialization.internal.GeneratedSerializer<Foo> {
|
||||
private constructor `$serializer`()
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER,-UNUSED_VARIABLE
|
||||
|
||||
// WITH_RUNTIME
|
||||
// FILE: test.kt
|
||||
import kotlinx.serialization.*
|
||||
|
||||
|
||||
+1
@@ -7,6 +7,7 @@ package
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
@kotlin.jvm.JvmStatic public final /*synthesized*/ fun `write$Self`(/*0*/ self: Test, /*1*/ output: kotlinx.serialization.encoding.CompositeEncoder, /*2*/ serialDesc: kotlinx.serialization.descriptors.SerialDescriptor): kotlin.Unit
|
||||
|
||||
@kotlin.Deprecated(level = DeprecationLevel.HIDDEN, message = "This synthesized declaration should not be used directly", replaceWith = kotlin.ReplaceWith(expression = "", imports = {})) public object `$serializer` : kotlinx.serialization.internal.GeneratedSerializer<Test> {
|
||||
private constructor `$serializer`()
|
||||
|
||||
plugins/kotlin-serialization/kotlin-serialization-compiler/testData/diagnostics/SerializableEnums.kt
Vendored
+1
-1
@@ -1,5 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER,-UNUSED_VARIABLE
|
||||
|
||||
// WITH_RUNTIME
|
||||
// FILE: test.kt
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.encoding.*
|
||||
|
||||
+1
@@ -23,6 +23,7 @@ public object EnumSerializer : kotlinx.serialization.KSerializer<ExplicitlyMarke
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
@kotlin.jvm.JvmStatic public final /*synthesized*/ fun `write$Self`(/*0*/ self: EnumUsage, /*1*/ output: kotlinx.serialization.encoding.CompositeEncoder, /*2*/ serialDesc: kotlinx.serialization.descriptors.SerialDescriptor): kotlin.Unit
|
||||
|
||||
@kotlin.Deprecated(level = DeprecationLevel.HIDDEN, message = "This synthesized declaration should not be used directly", replaceWith = kotlin.ReplaceWith(expression = "", imports = {})) public object `$serializer` : kotlinx.serialization.internal.GeneratedSerializer<EnumUsage> {
|
||||
private constructor `$serializer`()
|
||||
|
||||
Vendored
+1
-1
@@ -1,5 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER,-UNUSED_VARIABLE
|
||||
|
||||
// WITH_RUNTIME
|
||||
// FILE: test.kt
|
||||
import kotlinx.serialization.*
|
||||
|
||||
|
||||
Vendored
+1
@@ -11,6 +11,7 @@ package
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
@kotlin.jvm.JvmStatic public final /*synthesized*/ fun `write$Self`(/*0*/ self: WithTransients, /*1*/ output: kotlinx.serialization.encoding.CompositeEncoder, /*2*/ serialDesc: kotlinx.serialization.descriptors.SerialDescriptor): kotlin.Unit
|
||||
|
||||
@kotlin.Deprecated(level = DeprecationLevel.HIDDEN, message = "This synthesized declaration should not be used directly", replaceWith = kotlin.ReplaceWith(expression = "", imports = {})) public object `$serializer` : kotlinx.serialization.internal.GeneratedSerializer<WithTransients> {
|
||||
private constructor `$serializer`()
|
||||
|
||||
Reference in New Issue
Block a user