From f9edbd825a21ad1c02418052f860384864c7432a Mon Sep 17 00:00:00 2001 From: Leonid Startsev Date: Fri, 10 Apr 2020 17:57:21 +0300 Subject: [PATCH] Introduce support for plugin-defined intrinsics in old JVM backend: (Old is created first because all intrinsics emit bytecode anyway) Provide intrinsic for serializer() function so it won't invoke typeOf() construction and KType->KSerializer conversion making it fast and truly reflectionless Add support for recalculating stack size in plugin-defined intrinsics since it is needed for correct work: Unify method for recalculating stack size with existing typeOf intrinsic Add testdata for IR for future intrinsic in IR --- .../extensions/ExpressionCodegenExtension.kt | 38 +- .../kotlin/codegen/inline/PsiInlineCodegen.kt | 4 +- .../inline/PsiInlineIntrinsicsSupport.kt | 16 + .../codegen/inline/ReifiedTypeInliner.kt | 58 ++- .../codegen/inline/inlineCodegenUtils.kt | 15 +- .../common/SerializableCompanionCodegen.kt | 28 +- .../compiler/backend/jvm/JVMCodegenUtil.kt | 94 ++-- .../backend/jvm/JvmSerializerIntrinsic.kt | 124 +++++ .../SerializationCodegenExtension.kt | 45 +- .../compiler/backend/common/TypeUtil.kt | 10 +- .../testData/codegen/Intrinsics.ir.txt | 465 ++++++++++++++++++ .../testData/codegen/Intrinsics.kt | 43 ++ .../testData/codegen/Intrinsics.txt | 260 ++++++++++ ...mLikeInstructionsListingTestGenerated.java | 6 + ...mLikeInstructionsListingTestGenerated.java | 6 + 15 files changed, 1114 insertions(+), 98 deletions(-) create mode 100644 plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/JvmSerializerIntrinsic.kt create mode 100644 plugins/kotlinx-serialization/testData/codegen/Intrinsics.ir.txt create mode 100644 plugins/kotlinx-serialization/testData/codegen/Intrinsics.kt create mode 100644 plugins/kotlinx-serialization/testData/codegen/Intrinsics.txt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/extensions/ExpressionCodegenExtension.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/extensions/ExpressionCodegenExtension.kt index 0ff3094f2fb..e69710718a9 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/extensions/ExpressionCodegenExtension.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/extensions/ExpressionCodegenExtension.kt @@ -1,17 +1,6 @@ /* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2020 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.kotlin.codegen.extensions @@ -19,10 +8,17 @@ package org.jetbrains.kotlin.codegen.extensions import org.jetbrains.kotlin.codegen.ExpressionCodegen import org.jetbrains.kotlin.codegen.ImplementationBodyCodegen import org.jetbrains.kotlin.codegen.StackValue +import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper +import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall +import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext +import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter +import org.jetbrains.org.objectweb.asm.tree.InsnList +import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode interface ExpressionCodegenExtension { companion object : ProjectExtensionDescriptor( @@ -46,6 +42,22 @@ interface ExpressionCodegenExtension { */ fun applyFunction(receiver: StackValue, resolvedCall: ResolvedCall<*>, c: Context): StackValue? = null + /** + * Called when inliner encounters [ReifiedTypeInliner.OperationKind.PLUGIN_DEFINED] marker + * to perform extension-specific operation with reified type parameter. + * + * @return Required stack size for method after inlining is performed, 0 if the size is unknown, or -1 if extension ignores this marker + */ + fun applyPluginDefinedReifiedOperationMarker( + insn: MethodInsnNode, + instructions: InsnList, + type: KotlinType, + asmType: Type, + typeMapper: KotlinTypeMapper, + typeSystem: TypeSystemCommonBackendContext, + module: ModuleDescriptor + ): Int = -1 + fun generateClassSyntheticParts(codegen: ImplementationBodyCodegen) {} val shouldGenerateClassSyntheticPartsInLightClassesMode: Boolean diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiInlineCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiInlineCodegen.kt index 03695bbb90b..6d3ed519115 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiInlineCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiInlineCodegen.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2020 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. */ @@ -42,7 +42,7 @@ class PsiInlineCodegen( ) : InlineCodegen( codegen, state, signature, typeParameterMappings, sourceCompiler, ReifiedTypeInliner( - typeParameterMappings, PsiInlineIntrinsicsSupport(state, reportErrorsOn), codegen.typeSystem, + typeParameterMappings, PsiInlineIntrinsicsSupport(state, reportErrorsOn, codegen.typeSystem), codegen.typeSystem, state.languageVersionSettings, state.unifiedNullChecks ), ), CallGenerator { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiInlineIntrinsicsSupport.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiInlineIntrinsicsSupport.kt index fa4622ebb5a..927fcec9d45 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiInlineIntrinsicsSupport.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiInlineIntrinsicsSupport.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.codegen.inline import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap import org.jetbrains.kotlin.codegen.* +import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor @@ -19,15 +20,19 @@ import org.jetbrains.kotlin.resolve.jvm.AsmTypes.* import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm.TYPEOF_NON_REIFIED_TYPE_PARAMETER_WITH_RECURSIVE_BOUND import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm.TYPEOF_SUSPEND_TYPE import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext import org.jetbrains.kotlin.types.model.TypeParameterMarker import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type.INT_TYPE import org.jetbrains.org.objectweb.asm.Type.VOID_TYPE import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter +import org.jetbrains.org.objectweb.asm.tree.InsnList +import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode class PsiInlineIntrinsicsSupport( override val state: GenerationState, private val reportErrorsOn: KtElement, + private val typeSystem: TypeSystemCommonBackendContext ) : ReifiedTypeInliner.IntrinsicsSupport { override fun putClassInstance(v: InstructionAdapter, type: KotlinType) { DescriptorAsmUtil.putJavaLangClassInstance(v, state.typeMapper.mapType(type), type, state.typeMapper) @@ -79,4 +84,15 @@ class PsiInlineIntrinsicsSupport( override fun reportNonReifiedTypeParameterWithRecursiveBoundUnsupported(typeParameterName: Name) { state.diagnostics.report(TYPEOF_NON_REIFIED_TYPE_PARAMETER_WITH_RECURSIVE_BOUND.on(reportErrorsOn, typeParameterName.asString())) } + + override fun applyPluginDefinedReifiedOperationMarker( + insn: MethodInsnNode, + instructions: InsnList, + type: KotlinType, + asmType: Type + ): Int { + return ExpressionCodegenExtension.getInstances(state.project) + .map { it.applyPluginDefinedReifiedOperationMarker(insn, instructions, type, asmType, state.typeMapper, typeSystem, state.module) } + .maxOrNull() ?: -1 + } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/ReifiedTypeInliner.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/ReifiedTypeInliner.kt index 7c3f5c0491a..657f4e5e6d3 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/ReifiedTypeInliner.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/ReifiedTypeInliner.kt @@ -1,17 +1,6 @@ /* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2020 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.kotlin.codegen.inline @@ -57,11 +46,12 @@ class ReifiedTypeInliner( private val unifiedNullChecks: Boolean, ) { enum class OperationKind { - NEW_ARRAY, AS, SAFE_AS, IS, JAVA_CLASS, ENUM_REIFIED, TYPE_OF; + NEW_ARRAY, AS, SAFE_AS, IS, JAVA_CLASS, ENUM_REIFIED, TYPE_OF, PLUGIN_DEFINED; val id: Int get() = ordinal } + interface IntrinsicsSupport { val state: GenerationState @@ -75,6 +65,16 @@ class ReifiedTypeInliner( fun reportSuspendTypeUnsupported() fun reportNonReifiedTypeParameterWithRecursiveBoundUnsupported(typeParameterName: Name) + + /** + * @return Required stack size for method after inlining is performed, 0 if the size is unknown, or -1 if plugin was not applied + */ + fun applyPluginDefinedReifiedOperationMarker( + insn: MethodInsnNode, + instructions: InsnList, + type: KotlinType, + asmType: Type + ): Int = -1 } companion object { @@ -181,6 +181,7 @@ class ReifiedTypeInliner( OperationKind.JAVA_CLASS -> processJavaClass(insn, asmType) OperationKind.ENUM_REIFIED -> processSpecialEnumFunction(insn, instructions, asmType) OperationKind.TYPE_OF -> processTypeOf(insn, instructions, type) + OperationKind.PLUGIN_DEFINED -> processPluginDefined(insn, instructions, type, asmType) } ) { instructions.remove(insn.previous.previous!!) // PUSH operation ID @@ -196,6 +197,23 @@ class ReifiedTypeInliner( } } + private fun processPluginDefined( + insn: MethodInsnNode, + instructions: InsnList, + type: KT, + asmType: Type + ): Boolean { + val applyResult = intrinsicsSupport.applyPluginDefinedReifiedOperationMarker( + insn, + instructions, + intrinsicsSupport.toKotlinType(type), + asmType + ) + if (applyResult == -1) return false + maxStackSize = max(maxStackSize, applyResult) + return true + } + private fun reify(argument: ReificationArgument, replacementAsmType: Type, type: KT): Pair = with(typeSystem) { val arrayType = type.arrayOf(argument.arrayDepth) @@ -269,15 +287,11 @@ class ReifiedTypeInliner( instructions: InsnList, type: KT ) = rewriteNextTypeInsn(insn, Opcodes.ACONST_NULL) { stubConstNull: AbstractInsnNode -> - val newMethodNode = MethodNode(Opcodes.API_VERSION, "fake", "()V", null, null) - val mv = wrapWithMaxLocalCalc(newMethodNode) - typeSystem.generateTypeOf(InstructionAdapter(mv), type, intrinsicsSupport) + val newMethodNode = newMethodNodeWithCorrectStackSize { + typeSystem.generateTypeOf(it, type, intrinsicsSupport) + } - // Adding a fake return (and removing it below) to trigger maxStack calculation - mv.visitInsn(Opcodes.RETURN) - mv.visitMaxs(-1, -1) - - instructions.insert(insn, newMethodNode.instructions.apply { remove(last) }) + instructions.insert(insn, newMethodNode.instructions) instructions.remove(stubConstNull) maxStackSize = max(maxStackSize, newMethodNode.maxStack) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineCodegenUtils.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineCodegenUtils.kt index 6173f49ebe5..84f777647cd 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineCodegenUtils.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineCodegenUtils.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2020 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. */ @@ -229,6 +229,19 @@ internal fun isAnonymousClass(internalName: String) = fun wrapWithMaxLocalCalc(methodNode: MethodNode) = MaxStackFrameSizeAndLocalsCalculator(Opcodes.API_VERSION, methodNode.access, methodNode.desc, methodNode) +fun newMethodNodeWithCorrectStackSize(block: (InstructionAdapter) -> Unit): MethodNode { + val newMethodNode = MethodNode(Opcodes.API_VERSION, "fake", "()V", null, null) + val mv = wrapWithMaxLocalCalc(newMethodNode) + block(InstructionAdapter(mv)) + + // Adding a fake return (and removing it below) to trigger maxStack calculation + mv.visitInsn(Opcodes.RETURN) + mv.visitMaxs(-1, -1) + + newMethodNode.instructions.apply { remove(last) } + return newMethodNode +} + private fun String.isInteger(radix: Int = 10) = toIntOrNull(radix) != null internal fun isCapturedFieldName(fieldName: String): Boolean { diff --git a/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializableCompanionCodegen.kt b/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializableCompanionCodegen.kt index 14fa5653c4a..47d36c65d79 100644 --- a/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializableCompanionCodegen.kt +++ b/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializableCompanionCodegen.kt @@ -12,6 +12,9 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlinx.serialization.compiler.resolve.* import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.SERIALIZER_PROVIDER_NAME +import org.jetbrains.kotlinx.serialization.compiler.resolve.getSerializableClassDescriptorByCompanion +import org.jetbrains.kotlinx.serialization.compiler.resolve.isKSerializer +import org.jetbrains.kotlinx.serialization.compiler.resolve.isSerializableObject abstract class SerializableCompanionCodegen( protected val companionDescriptor: ClassDescriptor, @@ -20,15 +23,7 @@ abstract class SerializableCompanionCodegen( protected val serializableDescriptor: ClassDescriptor = getSerializableClassDescriptorByCompanion(companionDescriptor)!! open fun getSerializerGetterDescriptor(): FunctionDescriptor { - return companionDescriptor.unsubstitutedMemberScope.getContributedFunctions( - SERIALIZER_PROVIDER_NAME, - NoLookupLocation.FROM_BACKEND - ).firstOrNull { - it.valueParameters.size == serializableDescriptor.declaredTypeParameters.size - && it.kind == CallableMemberDescriptor.Kind.SYNTHESIZED - && it.valueParameters.all { p -> isKSerializer(p.type) } - && it.returnType != null && isKSerializer(it.returnType) - } ?: throw IllegalStateException( + return findSerializerGetterOnCompanion(serializableDescriptor) ?: throw IllegalStateException( "Can't find synthesized 'Companion.serializer()' function to generate, " + "probably clash with user-defined function has occurred" ) @@ -52,4 +47,19 @@ abstract class SerializableCompanionCodegen( protected open fun generateLazySerializerGetter(methodDescriptor: FunctionDescriptor) { generateSerializerGetter(methodDescriptor) } + + companion object { + fun findSerializerGetterOnCompanion(serializableDescriptor: ClassDescriptor): FunctionDescriptor? { + val companionObjectDesc = if (serializableDescriptor.isSerializableObject) serializableDescriptor else serializableDescriptor.companionObjectDescriptor + return companionObjectDesc?.unsubstitutedMemberScope?.getContributedFunctions( + SERIALIZER_PROVIDER_NAME, + NoLookupLocation.FROM_BACKEND + )?.firstOrNull { + it.valueParameters.size == serializableDescriptor.declaredTypeParameters.size + && it.kind == CallableMemberDescriptor.Kind.SYNTHESIZED + && it.valueParameters.all { p -> isKSerializer(p.type) } + && it.returnType != null && isKSerializer(it.returnType) + } + } + } } diff --git a/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/JVMCodegenUtil.kt b/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/JVMCodegenUtil.kt index 51236151e2d..b04b10b395a 100644 --- a/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/JVMCodegenUtil.kt +++ b/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/JVMCodegenUtil.kt @@ -8,7 +8,9 @@ package org.jetbrains.kotlinx.serialization.compiler.backend.jvm import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.codegen.* import org.jetbrains.kotlin.codegen.context.ClassContext +import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl @@ -247,56 +249,88 @@ internal fun InstructionAdapter.stackValueSerializerInstanceFromSerializer( } } +internal fun AbstractSerialGenerator?.stackValueSerializerInstance( + expressionCodegen: ExpressionCodegen, codegen: ClassBodyCodegen, module: ModuleDescriptor, kType: KotlinType, maybeSerializer: ClassDescriptor?, + iv: InstructionAdapter?, + genericIndex: Int? = null, + genericSerializerFieldGetter: (InstructionAdapter.(Int, KotlinType) -> Unit)? = null +): Boolean { + return stackValueSerializerInstance( + expressionCodegen,codegen.typeMapper, + module, + kType, + maybeSerializer, + iv, + genericIndex, + false, + genericSerializerFieldGetter + ) +} + // returns false is cannot not use serializer // use iv == null to check only (do not emit serializer onto stack) -internal fun AbstractSerialGenerator.stackValueSerializerInstance(expressionCodegen: ExpressionCodegen, classCodegen: ClassBodyCodegen, module: ModuleDescriptor, kType: KotlinType, maybeSerializer: ClassDescriptor?, - iv: InstructionAdapter?, - genericIndex: Int? = null, - genericSerializerFieldGetter: (InstructionAdapter.(Int, KotlinType) -> Unit)? = null +internal fun AbstractSerialGenerator?.stackValueSerializerInstance( + expressionCodegen: ExpressionCodegen?, typeMapper: KotlinTypeMapper, module: ModuleDescriptor, kType: KotlinType, maybeSerializer: ClassDescriptor?, + iv: InstructionAdapter?, + genericIndex: Int? = null, + insertExceptionOnNoSerializer: Boolean = false, + genericSerializerFieldGetter: (InstructionAdapter.(Int, KotlinType) -> Unit)? = null, ): Boolean { if (maybeSerializer == null && genericIndex != null) { // get field from serializer object iv?.run { genericSerializerFieldGetter?.invoke(this, genericIndex, kType) } return true } - val serializer = maybeSerializer ?: return false + val serializer = maybeSerializer ?: run { + if (insertExceptionOnNoSerializer) iv?.apply { + aconst(kType.getJetTypeFqName(false)) + invokestatic( + "kotlinx/serialization/SerializersKt", + "noCompiledSerializer", + "(Ljava/lang/String;)Lkotlinx/serialization/KSerializer;", + false + ) + } + return false + } if (serializer.kind == ClassKind.OBJECT) { // singleton serializer -- just get it if (iv != null) - StackValue.singleton(serializer, classCodegen.typeMapper).put(kSerializerType, iv) + StackValue.singleton(serializer, typeMapper).put(kSerializerType, iv) return true } // serializer is not singleton object and shall be instantiated val argSerializers = kType.arguments.map { projection -> - // bail out from stackValueSerializerInstance if any type argument is not serializable + // check if any type argument is not serializable val argType = projection.type - val argSerializer = if (argType.isTypeParameter()) null else { - findTypeSerializerOrContext(module, argType, sourceElement = classCodegen.descriptor.findPsi()) - ?: return false - } + val argSerializer = + if (argType.isTypeParameter()) null else findTypeSerializerOrContextUnchecked(module, argType) // check if it can be properly serialized with its args recursively if (!stackValueSerializerInstance( expressionCodegen, - classCodegen, + typeMapper, module, argType, argSerializer, null, argType.genericIndex, + insertExceptionOnNoSerializer = false, genericSerializerFieldGetter ) - ) - return false + ) { + // bail out only if we do not need to insert exception + if (!insertExceptionOnNoSerializer) return false + } Pair(argType, argSerializer) } // new serializer if needed iv?.apply { - val serializerType = classCodegen.typeMapper.mapClass(serializer) + val serializerType = typeMapper.mapClass(serializer) val classDescriptor = kType.toClassDescriptor!! if (serializer.classId == enumSerializerId && !classDescriptor.useGeneratedEnumSerializer) { // runtime contains enum serializer factory functions val javaEnumArray = Type.getType("[Ljava/lang/Enum;") - val enumJavaType = classCodegen.typeMapper.mapType(kType, null, TypeMappingMode.GENERIC_ARGUMENT) + val enumJavaType = typeMapper.mapType(kType, null, TypeMappingMode.GENERIC_ARGUMENT) val serialName = classDescriptor.serialName() if (classDescriptor.isEnumWithSerialInfoAnnotation()) { @@ -323,7 +357,7 @@ internal fun AbstractSerialGenerator.stackValueSerializerInstance(expressionCode } else { fillArray(annotationType, annotations) { _, annotation -> val (annotationClass, args, consParams) = annotation - expressionCodegen.generateSyntheticAnnotationOnStack(annotationClass, args, consParams) + expressionCodegen?.generateSyntheticAnnotationOnStack(annotationClass, args, consParams) } } } @@ -361,14 +395,15 @@ internal fun AbstractSerialGenerator.stackValueSerializerInstance(expressionCode assert( stackValueSerializerInstance( expressionCodegen, - classCodegen, + typeMapper, module, argType, argSerializer, this, argType.genericIndex, + insertExceptionOnNoSerializer, genericSerializerFieldGetter - ) + ) || insertExceptionOnNoSerializer ) // wrap into nullable serializer if argType is nullable if (argType.isMarkedNullable) wrapStackValueIntoNullableSerializer() @@ -381,16 +416,16 @@ internal fun AbstractSerialGenerator.stackValueSerializerInstance(expressionCode // support legacy serializer instantiation by constructor for old runtimes aconst(serialName) signature.append("Ljava/lang/String;") - val enumJavaType = classCodegen.typeMapper.mapType(kType, null, TypeMappingMode.GENERIC_ARGUMENT) + val enumJavaType = typeMapper.mapType(kType, null, TypeMappingMode.GENERIC_ARGUMENT) val javaEnumArray = Type.getType("[Ljava/lang/Enum;") - invokestatic(enumJavaType.internalName, "values","()[${enumJavaType.descriptor}", false) + invokestatic(enumJavaType.internalName, "values", "()[${enumJavaType.descriptor}", false) checkcast(javaEnumArray) signature.append(javaEnumArray.descriptor) } contextSerializerId, polymorphicSerializerId -> { // a special way to instantiate enum -- need a enum KClass reference // GENERIC_ARGUMENT forces boxing in order to obtain KClass - aconst(classCodegen.typeMapper.mapType(kType, null, TypeMappingMode.GENERIC_ARGUMENT)) + aconst(typeMapper.mapType(kType, null, TypeMappingMode.GENERIC_ARGUMENT)) AsmUtil.wrapJavaClassIntoKClass(this) signature.append(AsmTypes.K_CLASS_TYPE.descriptor) if (serializer.classId == contextSerializerId && serializer.constructors.any { it.valueParameters.size == 3 }) { @@ -410,7 +445,7 @@ internal fun AbstractSerialGenerator.stackValueSerializerInstance(expressionCode } referenceArraySerializerId -> { // a special way to instantiate reference array serializer -- need an element KClass reference - aconst(classCodegen.typeMapper.mapType(kType.arguments[0].type, null, TypeMappingMode.GENERIC_ARGUMENT)) + aconst(typeMapper.mapType(kType.arguments[0].type, null, TypeMappingMode.GENERIC_ARGUMENT)) AsmUtil.wrapJavaClassIntoKClass(this) signature.append(AsmTypes.K_CLASS_TYPE.descriptor) // Reference array serializer still needs serializer for its argument type @@ -419,13 +454,13 @@ internal fun AbstractSerialGenerator.stackValueSerializerInstance(expressionCode sealedSerializerId -> { aconst(serialName) signature.append("Ljava/lang/String;") - aconst(classCodegen.typeMapper.mapType(kType, null, TypeMappingMode.GENERIC_ARGUMENT)) + aconst(typeMapper.mapType(kType, null, TypeMappingMode.GENERIC_ARGUMENT)) AsmUtil.wrapJavaClassIntoKClass(this) signature.append(AsmTypes.K_CLASS_TYPE.descriptor) val (subClasses, subSerializers) = allSealedSerializableSubclassesFor(kType.toClassDescriptor!!, module) // KClasses vararg fillArray(AsmTypes.K_CLASS_TYPE, subClasses) { _, type -> - aconst(classCodegen.typeMapper.mapType(type, null, TypeMappingMode.GENERIC_ARGUMENT)) + aconst(typeMapper.mapType(type, null, TypeMappingMode.GENERIC_ARGUMENT)) AsmUtil.wrapJavaClassIntoKClass(this) } signature.append(AsmTypes.K_CLASS_ARRAY_TYPE.descriptor) @@ -435,7 +470,7 @@ internal fun AbstractSerialGenerator.stackValueSerializerInstance(expressionCode assert( stackValueSerializerInstance( expressionCodegen, - classCodegen, + typeMapper, module, argType, argSerializer, @@ -446,11 +481,12 @@ internal fun AbstractSerialGenerator.stackValueSerializerInstance(expressionCode assert( stackValueSerializerInstance( expressionCodegen, - classCodegen, + typeMapper, module, (genericType.constructor.declarationDescriptor as TypeParameterDescriptor).representativeUpperBound, module.getClassFromSerializationPackage(SpecialBuiltins.polymorphicSerializer), - this + this, + insertExceptionOnNoSerializer = insertExceptionOnNoSerializer ) ) } @@ -462,7 +498,7 @@ internal fun AbstractSerialGenerator.stackValueSerializerInstance(expressionCode objectSerializerId -> { aconst(serialName) signature.append("Ljava/lang/String;") - StackValue.singleton(kType.toClassDescriptor!!, classCodegen.typeMapper).put(Type.getType("Ljava/lang/Object;"), iv) + StackValue.singleton(kType.toClassDescriptor!!, typeMapper).put(Type.getType("Ljava/lang/Object;"), iv) signature.append("Ljava/lang/Object;") } // all serializers get arguments with serializers of their generic types diff --git a/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/JvmSerializerIntrinsic.kt b/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/JvmSerializerIntrinsic.kt new file mode 100644 index 00000000000..dc3e020158c --- /dev/null +++ b/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/JvmSerializerIntrinsic.kt @@ -0,0 +1,124 @@ +/* + * Copyright 2010-2022 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.jvm + +import org.jetbrains.kotlin.codegen.StackValue +import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension +import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner +import org.jetbrains.kotlin.codegen.inline.newMethodNodeWithCorrectStackSize +import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor +import org.jetbrains.kotlin.ir.expressions.typeParametersCount +import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe +import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.SimpleType +import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext +import org.jetbrains.kotlinx.serialization.compiler.backend.common.AbstractSerialGenerator +import org.jetbrains.kotlinx.serialization.compiler.backend.common.SerializableCompanionCodegen +import org.jetbrains.kotlinx.serialization.compiler.backend.common.findTypeSerializerOrContextUnchecked +import org.jetbrains.kotlinx.serialization.compiler.resolve.isSerializableObject +import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter +import org.jetbrains.org.objectweb.asm.tree.InsnList +import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode + +object JvmSerializerIntrinsic { + fun applyFunction(resolvedCall: ResolvedCall<*>, c: ExpressionCodegenExtension.Context): StackValue? { + val targetFunction = resolvedCall.resultingDescriptor as? FunctionDescriptor ?: return null + val isSerializerReifiedFunction = + targetFunction.fqNameSafe.asString() == "kotlinx.serialization.serializer" + && targetFunction.valueParameters.isEmpty() + && targetFunction.typeParametersCount == 1 + && targetFunction.dispatchReceiverParameter == null + && targetFunction.extensionReceiverParameter == null + if (!isSerializerReifiedFunction) return null + val typeArgument = + resolvedCall.typeArguments.entries.singleOrNull()?.value ?: error("serializer() function has exactly one type parameter") + return StackValue.functionCall(kSerializerType, targetFunction.returnType) { iv -> + generateSerializerForType(typeArgument, iv, c.typeMapper, c.codegen.typeSystem, module = c.codegen.state.module) + } + } + + fun applyPluginDefinedReifiedOperationMarker( + insn: MethodInsnNode, + instructions: InsnList, + type: KotlinType, + typeMapper: KotlinTypeMapper, + typeSystem: TypeSystemCommonBackendContext, + module: ModuleDescriptor + ): Int { + val newMethodNode = newMethodNodeWithCorrectStackSize { + generateSerializerForType(type, it, typeMapper, typeSystem, module) + } + + instructions.remove(insn.next) + instructions.insert(insn, newMethodNode.instructions) + + return newMethodNode.maxStack + } + + private fun InstructionAdapter.putReifyMarkerIfNeeded(type: KotlinType, typeSystem: TypeSystemCommonBackendContext): Boolean { + val typeDescriptor = (type as SimpleType).constructor.declarationDescriptor!! + if (typeDescriptor is TypeParameterDescriptor) { // need further reification + ReifiedTypeInliner.putReifiedOperationMarkerIfNeeded( + typeDescriptor, + false, + ReifiedTypeInliner.OperationKind.PLUGIN_DEFINED, + this, + typeSystem + ) + invokestatic("kotlinx/serialization/SerializersKt", "serializer", "()Lkotlinx/serialization/KSerializer;", false) + return true + } + return false + } + + private fun generateSerializerForType( + type: KotlinType, + adapter: InstructionAdapter, + typeMapper: KotlinTypeMapper, + typeSystem: TypeSystemCommonBackendContext, + module: ModuleDescriptor + ): Unit = with(adapter) { + if (putReifyMarkerIfNeeded(type, typeSystem)) return + val typeDescriptor = (type as SimpleType).constructor.declarationDescriptor!! as ClassDescriptor + + val serializerMethod = SerializableCompanionCodegen.findSerializerGetterOnCompanion(typeDescriptor) + if (serializerMethod != null) { + // fast path + val companionType = if (typeDescriptor.isSerializableObject) typeDescriptor else typeDescriptor.companionObjectDescriptor!! + StackValue.singleton(companionType, typeMapper).put(this) + val args = type.arguments.map { it.type } + args.forEach { generateSerializerForType(it, this, typeMapper, typeSystem, module) } + val signature = kSerializerType.descriptor.repeat(args.size) + invokevirtual( + typeMapper.mapType(companionType).internalName, + "serializer", + "(${signature})${kSerializerType.descriptor}", + false + ) + } else { + // More general path, including special ol built-in serializers for e.g. List + val emptyGenerator: AbstractSerialGenerator? = null // stub indicating we do not look into @UseSerializers to avoid confusion + val serializer = emptyGenerator.findTypeSerializerOrContextUnchecked(module, type) + emptyGenerator.stackValueSerializerInstance( + null, + typeMapper, + module, + type, + serializer, + this, + insertExceptionOnNoSerializer = true + ) { _, genericArg -> + assert(putReifyMarkerIfNeeded(genericArg, typeSystem)) + } + if (type.isMarkedNullable) wrapStackValueIntoNullableSerializer() + } + } +} \ No newline at end of file diff --git a/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationCodegenExtension.kt b/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationCodegenExtension.kt index 2a6d75b449e..c969f103a14 100644 --- a/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationCodegenExtension.kt +++ b/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationCodegenExtension.kt @@ -1,27 +1,22 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * 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.extensions import org.jetbrains.kotlin.codegen.ImplementationBodyCodegen +import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension -import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.SerialInfoCodegenImpl -import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.SerializableCodegenImpl -import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.SerializableCompanionCodegenImpl -import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.SerializerCodegenImpl +import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper +import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall +import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext +import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.* +import org.jetbrains.org.objectweb.asm.Type +import org.jetbrains.org.objectweb.asm.tree.InsnList +import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode open class SerializationCodegenExtension @JvmOverloads constructor(val metadataPlugin: SerializationDescriptorSerializerPlugin? = null) : ExpressionCodegenExtension { override fun generateClassSyntheticParts(codegen: ImplementationBodyCodegen) { @@ -31,6 +26,22 @@ open class SerializationCodegenExtension @JvmOverloads constructor(val metadataP SerializableCompanionCodegenImpl.generateSerializableExtensions(codegen) } + override fun applyFunction(receiver: StackValue, resolvedCall: ResolvedCall<*>, c: ExpressionCodegenExtension.Context): StackValue? { + return JvmSerializerIntrinsic.applyFunction(resolvedCall, c) + } + + override fun applyPluginDefinedReifiedOperationMarker( + insn: MethodInsnNode, + instructions: InsnList, + type: KotlinType, + asmType: Type, + typeMapper: KotlinTypeMapper, + typeSystem: TypeSystemCommonBackendContext, + module: ModuleDescriptor + ): Int { + return JvmSerializerIntrinsic.applyPluginDefinedReifiedOperationMarker(insn, instructions, type, typeMapper, typeSystem, module) + } + override val shouldGenerateClassSyntheticPartsInLightClassesMode: Boolean get() = false } \ No newline at end of file diff --git a/plugins/kotlinx-serialization/kotlinx-serialization.k1/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/TypeUtil.kt b/plugins/kotlinx-serialization/kotlinx-serialization.k1/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/TypeUtil.kt index d96e2b90790..adb26e2b55d 100644 --- a/plugins/kotlinx-serialization/kotlinx-serialization.k1/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/TypeUtil.kt +++ b/plugins/kotlinx-serialization/kotlinx-serialization.k1/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/TypeUtil.kt @@ -77,7 +77,7 @@ fun AbstractSerialGenerator.getSerialTypeInfo(property: SerializableProperty): S } } -fun AbstractSerialGenerator.allSealedSerializableSubclassesFor( +fun AbstractSerialGenerator?.allSealedSerializableSubclassesFor( klass: ClassDescriptor, module: ModuleDescriptor ): Pair, List> { @@ -119,20 +119,20 @@ fun analyzeSpecialSerializers( else -> null } -fun AbstractSerialGenerator.findTypeSerializerOrContextUnchecked( +fun AbstractSerialGenerator?.findTypeSerializerOrContextUnchecked( module: ModuleDescriptor, kType: KotlinType ): ClassDescriptor? { val annotations = kType.annotations if (kType.isTypeParameter()) return null annotations.serializableWith(module)?.let { return it.toClassDescriptor } - additionalSerializersInScopeOfCurrentFile[kType.toClassDescriptor to kType.isMarkedNullable]?.let { return it } + this?.additionalSerializersInScopeOfCurrentFile?.get(kType.toClassDescriptor to kType.isMarkedNullable)?.let { return it } if (kType.isMarkedNullable) return findTypeSerializerOrContextUnchecked(module, kType.makeNotNullable()) - if (kType in contextualKClassListInCurrentFile) return module.getClassFromSerializationPackage(SpecialBuiltins.contextSerializer) + if (this?.contextualKClassListInCurrentFile?.contains(kType) == true) return module.getClassFromSerializationPackage(SpecialBuiltins.contextSerializer) return analyzeSpecialSerializers(module, annotations) ?: findTypeSerializer(module, kType) } -fun AbstractSerialGenerator.findTypeSerializerOrContext( +fun AbstractSerialGenerator?.findTypeSerializerOrContext( module: ModuleDescriptor, kType: KotlinType, sourceElement: PsiElement? = null diff --git a/plugins/kotlinx-serialization/testData/codegen/Intrinsics.ir.txt b/plugins/kotlinx-serialization/testData/codegen/Intrinsics.ir.txt new file mode 100644 index 00000000000..37bf68045ff --- /dev/null +++ b/plugins/kotlinx-serialization/testData/codegen/Intrinsics.ir.txt @@ -0,0 +1,465 @@ +public final class Box$$serializer : java/lang/Object, kotlinx/serialization/internal/GeneratedSerializer { + private final kotlinx.serialization.internal.PluginGeneratedSerialDescriptor descriptor + + private final kotlinx.serialization.KSerializer typeSerial0 + + private void () + + public void (kotlinx.serialization.KSerializer typeSerial0) + + public kotlinx.serialization.KSerializer[] childSerializers() + + public Box deserialize(kotlinx.serialization.encoding.Decoder decoder) + + public java.lang.Object deserialize(kotlinx.serialization.encoding.Decoder decoder) + + public kotlinx.serialization.descriptors.SerialDescriptor getDescriptor() + + private final kotlinx.serialization.KSerializer getTypeSerial0() + + public void serialize(kotlinx.serialization.encoding.Encoder encoder, Box value) + + public void serialize(kotlinx.serialization.encoding.Encoder encoder, java.lang.Object value) + + public kotlinx.serialization.KSerializer[] typeParametersSerializers() +} + +public final class Box$Companion : java/lang/Object { + private void () + + public void (kotlin.jvm.internal.DefaultConstructorMarker $constructor_marker) + + private final kotlinx.serialization.descriptors.SerialDescriptor get$cachedDescriptor() + + public final kotlinx.serialization.KSerializer serializer(kotlinx.serialization.KSerializer typeSerial0) +} + +public final class Box : java/lang/Object { + private final static kotlinx.serialization.descriptors.SerialDescriptor $cachedDescriptor + + public final static Box$Companion Companion + + private final java.lang.Object boxed + + static void () + + public void (java.lang.Object boxed) + + public void (int seen1, java.lang.Object boxed, kotlinx.serialization.internal.SerializationConstructorMarker serializationConstructorMarker) + + public final static kotlinx.serialization.descriptors.SerialDescriptor access$get$cachedDescriptor$cp() + + public final java.lang.Object component1() + + public final Box copy(java.lang.Object boxed) + + public static Box copy$default(Box p0, java.lang.Object p1, int p2, java.lang.Object p3) + + public boolean equals(java.lang.Object other) + + public final java.lang.Object getBoxed() + + public int hashCode() + + public java.lang.String toString() + + public final static void write$Self(Box self, kotlinx.serialization.encoding.CompositeEncoder output, kotlinx.serialization.descriptors.SerialDescriptor serialDesc, kotlinx.serialization.KSerializer typeSerial0) +} + +public final class IntrinsicsKt : java/lang/Object { + public final static kotlinx.serialization.KSerializer getBoxSer() + + public final static kotlinx.serialization.KSerializer getSer() + + public final static kotlinx.serialization.KSerializer listSer() + + public final static void test() { + LABEL (L0) + LINENUMBER (28) + ICONST_0 + ISTORE (0) + LABEL (L1) + LDC (LSimple;) + INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;)Lkotlin/reflect/KType;) + LABEL (L2) + LINENUMBER (50) + INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;) + ASTORE (1) + LABEL (L3) + ICONST_0 + ISTORE (2) + LABEL (L4) + LINENUMBER (51) + ALOAD (1) + LDC (null cannot be cast to non-null type kotlinx.serialization.KSerializer) + INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNull, (Ljava/lang/Object;Ljava/lang/String;)V) + LABEL (L5) + LINENUMBER (50) + NOP + LABEL (L6) + LINENUMBER (29) + ICONST_0 + ISTORE (0) + LABEL (L7) + LINENUMBER (52) + ICONST_0 + ISTORE (1) + LABEL (L8) + LDC (LSimple;) + INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;)Lkotlin/reflect/KType;) + LABEL (L9) + LINENUMBER (53) + INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;) + ASTORE (2) + LABEL (L10) + ICONST_0 + ISTORE (3) + LABEL (L11) + LINENUMBER (54) + ALOAD (2) + LDC (null cannot be cast to non-null type kotlinx.serialization.KSerializer) + INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNull, (Ljava/lang/Object;Ljava/lang/String;)V) + LABEL (L12) + LINENUMBER (53) + NOP + LABEL (L13) + LINENUMBER (52) + NOP + LABEL (L14) + LINENUMBER (30) + ICONST_0 + ISTORE (0) + LABEL (L15) + LINENUMBER (55) + ICONST_0 + ISTORE (1) + LABEL (L16) + LDC (LBox;) + GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;) + LDC (LSimple;) + INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;)Lkotlin/reflect/KType;) + INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;) + INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;) + LABEL (L17) + LINENUMBER (56) + INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;) + ASTORE (2) + LABEL (L18) + ICONST_0 + ISTORE (3) + LABEL (L19) + LINENUMBER (57) + ALOAD (2) + LDC (null cannot be cast to non-null type kotlinx.serialization.KSerializer) + INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNull, (Ljava/lang/Object;Ljava/lang/String;)V) + LABEL (L20) + LINENUMBER (56) + NOP + LABEL (L21) + LINENUMBER (55) + NOP + LABEL (L22) + LINENUMBER (31) + ICONST_0 + ISTORE (0) + LABEL (L23) + LINENUMBER (58) + ICONST_0 + ISTORE (1) + LABEL (L24) + LDC (LBox;) + GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;) + LDC (LSimple;) + INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;)Lkotlin/reflect/KType;) + INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;) + INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;) + LABEL (L25) + LINENUMBER (59) + INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;) + ASTORE (2) + LABEL (L26) + ICONST_0 + ISTORE (3) + LABEL (L27) + LINENUMBER (60) + ALOAD (2) + LDC (null cannot be cast to non-null type kotlinx.serialization.KSerializer) + INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNull, (Ljava/lang/Object;Ljava/lang/String;)V) + LABEL (L28) + LINENUMBER (59) + NOP + LABEL (L29) + LINENUMBER (58) + NOP + LABEL (L30) + LINENUMBER (32) + ICONST_0 + ISTORE (0) + LABEL (L31) + LINENUMBER (61) + ICONST_0 + ISTORE (1) + LABEL (L32) + LDC (Ljava/util/List;) + GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;) + LDC (LSimple;) + INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;)Lkotlin/reflect/KType;) + INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;) + INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;) + LABEL (L33) + LINENUMBER (62) + INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;) + ASTORE (2) + LABEL (L34) + ICONST_0 + ISTORE (3) + LABEL (L35) + LINENUMBER (63) + ALOAD (2) + LDC (null cannot be cast to non-null type kotlinx.serialization.KSerializer) + INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNull, (Ljava/lang/Object;Ljava/lang/String;)V) + LABEL (L36) + LINENUMBER (62) + NOP + LABEL (L37) + LINENUMBER (61) + NOP + LABEL (L38) + LINENUMBER (34) + ICONST_0 + ISTORE (0) + LABEL (L39) + LDC (LBox;) + GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;) + LDC (Ljava/util/List;) + GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;) + LDC (LSimple;) + INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;)Lkotlin/reflect/KType;) + INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;) + INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;) + INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;) + INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;) + LABEL (L40) + LINENUMBER (64) + INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;) + ASTORE (1) + LABEL (L41) + ICONST_0 + ISTORE (2) + LABEL (L42) + LINENUMBER (65) + ALOAD (1) + LDC (null cannot be cast to non-null type kotlinx.serialization.KSerializer) + INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNull, (Ljava/lang/Object;Ljava/lang/String;)V) + LABEL (L43) + LINENUMBER (64) + NOP + LABEL (L44) + LINENUMBER (36) + ICONST_0 + ISTORE (0) + LABEL (L45) + LINENUMBER (66) + ICONST_0 + ISTORE (1) + LABEL (L46) + LDC (Ljava/util/List;) + GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;) + LDC (LBox;) + GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;) + LDC (Ljava/util/List;) + GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;) + LDC (LSimple;) + INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;)Lkotlin/reflect/KType;) + INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;) + INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;) + INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;) + INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;) + INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;) + INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;) + LABEL (L47) + LINENUMBER (67) + INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;) + ASTORE (2) + LABEL (L48) + ICONST_0 + ISTORE (3) + LABEL (L49) + LINENUMBER (68) + ALOAD (2) + LDC (null cannot be cast to non-null type kotlinx.serialization.KSerializer) + INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNull, (Ljava/lang/Object;Ljava/lang/String;)V) + LABEL (L50) + LINENUMBER (67) + NOP + LABEL (L51) + LINENUMBER (66) + NOP + LABEL (L52) + LINENUMBER (38) + ICONST_0 + ISTORE (0) + LABEL (L53) + GETSTATIC (java/lang/Integer, TYPE, Ljava/lang/Class;) + INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;)Lkotlin/reflect/KType;) + LABEL (L54) + LINENUMBER (69) + INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;) + ASTORE (1) + LABEL (L55) + ICONST_0 + ISTORE (2) + LABEL (L56) + LINENUMBER (70) + ALOAD (1) + LDC (null cannot be cast to non-null type kotlinx.serialization.KSerializer) + INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNull, (Ljava/lang/Object;Ljava/lang/String;)V) + LABEL (L57) + LINENUMBER (69) + NOP + LABEL (L58) + LINENUMBER (40) + ICONST_0 + ISTORE (0) + LABEL (L59) + LDC (LSerializableObject;) + INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;)Lkotlin/reflect/KType;) + LABEL (L60) + LINENUMBER (71) + INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;) + ASTORE (1) + LABEL (L61) + ICONST_0 + ISTORE (2) + LABEL (L62) + LINENUMBER (72) + ALOAD (1) + LDC (null cannot be cast to non-null type kotlinx.serialization.KSerializer) + INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNull, (Ljava/lang/Object;Ljava/lang/String;)V) + LABEL (L63) + LINENUMBER (71) + NOP + LABEL (L64) + LINENUMBER (42) + ICONST_0 + ISTORE (0) + LABEL (L65) + LINENUMBER (73) + ICONST_0 + ISTORE (1) + LABEL (L66) + LDC (Ljava/util/List;) + GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;) + LDC (Ljava/util/List;) + GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;) + LDC (LBox;) + GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;) + GETSTATIC (java/lang/Integer, TYPE, Ljava/lang/Class;) + INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;)Lkotlin/reflect/KType;) + INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;) + INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;) + INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;) + INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;) + INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;) + INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;) + LABEL (L67) + LINENUMBER (74) + INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;) + ASTORE (2) + LABEL (L68) + ICONST_0 + ISTORE (3) + LABEL (L69) + LINENUMBER (75) + ALOAD (2) + LDC (null cannot be cast to non-null type kotlinx.serialization.KSerializer) + INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNull, (Ljava/lang/Object;Ljava/lang/String;)V) + LABEL (L70) + LINENUMBER (74) + NOP + LABEL (L71) + LINENUMBER (73) + NOP + LABEL (L72) + LINENUMBER (43) + RETURN + } +} + +final class SerializableObject$$cachedSerializer$delegate$1 : kotlin/jvm/internal/Lambda, kotlin/jvm/functions/Function0 { + public final static SerializableObject$$cachedSerializer$delegate$1 INSTANCE + + static void () + + void () + + public final kotlinx.serialization.KSerializer invoke() + + public java.lang.Object invoke() +} + +public final class SerializableObject : java/lang/Object { + private final static kotlin.Lazy $cachedSerializer$delegate + + public final static SerializableObject INSTANCE + + static void () + + private void () + + private final kotlin.Lazy get$cachedSerializer$delegate() + + public final kotlinx.serialization.KSerializer serializer() +} + +public final class Simple$$serializer : java/lang/Object, kotlinx/serialization/internal/GeneratedSerializer { + public final static Simple$$serializer INSTANCE + + private final static kotlinx.serialization.internal.PluginGeneratedSerialDescriptor descriptor + + static void () + + private void () + + public kotlinx.serialization.KSerializer[] childSerializers() + + public Simple deserialize(kotlinx.serialization.encoding.Decoder decoder) + + public java.lang.Object deserialize(kotlinx.serialization.encoding.Decoder decoder) + + public kotlinx.serialization.descriptors.SerialDescriptor getDescriptor() + + public void serialize(kotlinx.serialization.encoding.Encoder encoder, Simple value) + + public void serialize(kotlinx.serialization.encoding.Encoder encoder, java.lang.Object value) + + public kotlinx.serialization.KSerializer[] typeParametersSerializers() +} + +public final class Simple$Companion : java/lang/Object { + private void () + + public void (kotlin.jvm.internal.DefaultConstructorMarker $constructor_marker) + + public final kotlinx.serialization.KSerializer serializer() +} + +public final class Simple : java/lang/Object { + public final static Simple$Companion Companion + + private final java.lang.String firstName + + private final java.lang.String lastName + + static void () + + public void (java.lang.String firstName, java.lang.String lastName) + + public void (int seen1, java.lang.String firstName, java.lang.String lastName, kotlinx.serialization.internal.SerializationConstructorMarker serializationConstructorMarker) + + public final java.lang.String getFirstName() + + public final java.lang.String getLastName() + + public final static void write$Self(Simple self, kotlinx.serialization.encoding.CompositeEncoder output, kotlinx.serialization.descriptors.SerialDescriptor serialDesc) +} diff --git a/plugins/kotlinx-serialization/testData/codegen/Intrinsics.kt b/plugins/kotlinx-serialization/testData/codegen/Intrinsics.kt new file mode 100644 index 00000000000..6f4e3ad3e00 --- /dev/null +++ b/plugins/kotlinx-serialization/testData/codegen/Intrinsics.kt @@ -0,0 +1,43 @@ +// CURIOUS_ABOUT test +// WITH_STDLIB + +import kotlinx.serialization.* + +@Serializable +class Simple(val firstName: String, val lastName: String) + +@Serializable +data class Box(val boxed: T) + +@Serializable +object SerializableObject {} + +inline fun getSer(): KSerializer { + return serializer() +} + +inline fun getBoxSer(): KSerializer> { + return serializer>() +} + +inline fun listSer(): KSerializer> { + return serializer>() +} + +fun test() { + serializer() + getSer() + getSer>() + getBoxSer() + listSer() + + serializer>>() + + listSer>>() + + serializer() + + serializer() + + listSer>>() +} \ No newline at end of file diff --git a/plugins/kotlinx-serialization/testData/codegen/Intrinsics.txt b/plugins/kotlinx-serialization/testData/codegen/Intrinsics.txt new file mode 100644 index 00000000000..f6e7083bbfe --- /dev/null +++ b/plugins/kotlinx-serialization/testData/codegen/Intrinsics.txt @@ -0,0 +1,260 @@ +public final class Box$$serializer : java/lang/Object, kotlinx/serialization/internal/GeneratedSerializer { + private final kotlinx.serialization.descriptors.SerialDescriptor $$serialDesc + + private kotlinx.serialization.KSerializer typeSerial0 + + private void () + + public void (kotlinx.serialization.KSerializer typeSerial0) + + public kotlinx.serialization.KSerializer[] childSerializers() + + public Box deserialize(kotlinx.serialization.encoding.Decoder decoder) + + public java.lang.Object deserialize(kotlinx.serialization.encoding.Decoder p0) + + public kotlinx.serialization.descriptors.SerialDescriptor getDescriptor() + + public void serialize(kotlinx.serialization.encoding.Encoder encoder, Box value) + + public void serialize(kotlinx.serialization.encoding.Encoder p0, java.lang.Object p1) + + public kotlinx.serialization.KSerializer[] typeParametersSerializers() +} + +public final class Box$Companion : java/lang/Object { + private void () + + public void (kotlin.jvm.internal.DefaultConstructorMarker $constructor_marker) + + public final kotlinx.serialization.KSerializer serializer(kotlinx.serialization.KSerializer typeSerial0) +} + +public final class Box : java/lang/Object { + private final static kotlinx.serialization.descriptors.SerialDescriptor $cachedDescriptor + + public final static Box$Companion Companion + + private final java.lang.Object boxed + + static void () + + public void (java.lang.Object boxed) + + public void (int seen1, java.lang.Object boxed, kotlinx.serialization.internal.SerializationConstructorMarker serializationConstructorMarker) + + public final java.lang.Object component1() + + public final Box copy(java.lang.Object boxed) + + public static Box copy$default(Box p0, java.lang.Object p1, int p2, java.lang.Object p3) + + public boolean equals(java.lang.Object p0) + + public final java.lang.Object getBoxed() + + public int hashCode() + + public java.lang.String toString() + + public final static void write$Self(Box self, kotlinx.serialization.encoding.CompositeEncoder output, kotlinx.serialization.descriptors.SerialDescriptor serialDesc, kotlinx.serialization.KSerializer typeSerial0) +} + +public final class IntrinsicsKt : java/lang/Object { + public final static kotlinx.serialization.KSerializer getBoxSer() + + public final static kotlinx.serialization.KSerializer getSer() + + public final static kotlinx.serialization.KSerializer listSer() + + public final static void test() { + LABEL (L0) + LINENUMBER (28) + GETSTATIC (Simple, Companion, LSimple$Companion;) + INVOKEVIRTUAL (Simple$Companion, serializer, ()Lkotlinx/serialization/KSerializer;) + POP + LABEL (L1) + LINENUMBER (29) + ICONST_0 + ISTORE (0) + LABEL (L2) + LINENUMBER (44) + GETSTATIC (Simple, Companion, LSimple$Companion;) + INVOKEVIRTUAL (Simple$Companion, serializer, ()Lkotlinx/serialization/KSerializer;) + LABEL (L3) + POP + LABEL (L4) + LINENUMBER (30) + ICONST_0 + ISTORE (0) + LABEL (L5) + LINENUMBER (45) + GETSTATIC (Box, Companion, LBox$Companion;) + GETSTATIC (Simple, Companion, LSimple$Companion;) + INVOKEVIRTUAL (Simple$Companion, serializer, ()Lkotlinx/serialization/KSerializer;) + INVOKEVIRTUAL (Box$Companion, serializer, (Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/KSerializer;) + LABEL (L6) + POP + LABEL (L7) + LINENUMBER (31) + ICONST_0 + ISTORE (0) + LABEL (L8) + LINENUMBER (46) + GETSTATIC (Box, Companion, LBox$Companion;) + GETSTATIC (Simple, Companion, LSimple$Companion;) + INVOKEVIRTUAL (Simple$Companion, serializer, ()Lkotlinx/serialization/KSerializer;) + INVOKEVIRTUAL (Box$Companion, serializer, (Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/KSerializer;) + LABEL (L9) + POP + LABEL (L10) + LINENUMBER (32) + ICONST_0 + ISTORE (0) + LABEL (L11) + LINENUMBER (47) + NEW (kotlinx/serialization/internal/ArrayListSerializer) + DUP + GETSTATIC (Simple, Companion, LSimple$Companion;) + INVOKEVIRTUAL (Simple$Companion, serializer, ()Lkotlinx/serialization/KSerializer;) + INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, , (Lkotlinx/serialization/KSerializer;)V) + LABEL (L12) + POP + LABEL (L13) + LINENUMBER (34) + GETSTATIC (Box, Companion, LBox$Companion;) + NEW (kotlinx/serialization/internal/ArrayListSerializer) + DUP + GETSTATIC (Simple$$serializer, INSTANCE, LSimple$$serializer;) + CHECKCAST (kotlinx/serialization/KSerializer) + INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, , (Lkotlinx/serialization/KSerializer;)V) + INVOKEVIRTUAL (Box$Companion, serializer, (Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/KSerializer;) + POP + LABEL (L14) + LINENUMBER (36) + ICONST_0 + ISTORE (0) + LABEL (L15) + LINENUMBER (48) + NEW (kotlinx/serialization/internal/ArrayListSerializer) + DUP + GETSTATIC (Box, Companion, LBox$Companion;) + NEW (kotlinx/serialization/internal/ArrayListSerializer) + DUP + GETSTATIC (Simple$$serializer, INSTANCE, LSimple$$serializer;) + CHECKCAST (kotlinx/serialization/KSerializer) + INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, , (Lkotlinx/serialization/KSerializer;)V) + INVOKEVIRTUAL (Box$Companion, serializer, (Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/KSerializer;) + INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, , (Lkotlinx/serialization/KSerializer;)V) + LABEL (L16) + POP + LABEL (L17) + LINENUMBER (38) + GETSTATIC (kotlinx/serialization/internal/IntSerializer, INSTANCE, Lkotlinx/serialization/internal/IntSerializer;) + CHECKCAST (kotlinx/serialization/KSerializer) + POP + LABEL (L18) + LINENUMBER (40) + GETSTATIC (SerializableObject, INSTANCE, LSerializableObject;) + INVOKEVIRTUAL (SerializableObject, serializer, ()Lkotlinx/serialization/KSerializer;) + POP + LABEL (L19) + LINENUMBER (42) + ICONST_0 + ISTORE (0) + LABEL (L20) + LINENUMBER (49) + NEW (kotlinx/serialization/internal/ArrayListSerializer) + DUP + NEW (kotlinx/serialization/internal/ArrayListSerializer) + DUP + NEW (Box$$serializer) + DUP + GETSTATIC (kotlinx/serialization/internal/IntSerializer, INSTANCE, Lkotlinx/serialization/internal/IntSerializer;) + CHECKCAST (kotlinx/serialization/KSerializer) + INVOKESPECIAL (Box$$serializer, , (Lkotlinx/serialization/KSerializer;)V) + INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, , (Lkotlinx/serialization/KSerializer;)V) + INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, , (Lkotlinx/serialization/KSerializer;)V) + LABEL (L21) + POP + LABEL (L22) + LINENUMBER (43) + RETURN + } +} + +final class SerializableObject$serializer$1 : kotlin/jvm/internal/Lambda, kotlin/jvm/functions/Function0 { + public final static SerializableObject$serializer$1 INSTANCE + + static void () + + public void () + + public final kotlinx.serialization.KSerializer invoke() + + public final java.lang.Object invoke() +} + +public final class SerializableObject : java/lang/Object { + private final static kotlin.Lazy $cachedSerializer$delegate + + public final static SerializableObject INSTANCE + + static void () + + private void () + + public final kotlinx.serialization.KSerializer serializer() +} + +public final class Simple$$serializer : java/lang/Object, kotlinx/serialization/internal/GeneratedSerializer { + private final static kotlinx.serialization.descriptors.SerialDescriptor $$serialDesc + + public final static Simple$$serializer INSTANCE + + static void () + + private void () + + public kotlinx.serialization.KSerializer[] childSerializers() + + public Simple deserialize(kotlinx.serialization.encoding.Decoder decoder) + + public java.lang.Object deserialize(kotlinx.serialization.encoding.Decoder p0) + + public kotlinx.serialization.descriptors.SerialDescriptor getDescriptor() + + public void serialize(kotlinx.serialization.encoding.Encoder encoder, Simple value) + + public void serialize(kotlinx.serialization.encoding.Encoder p0, java.lang.Object p1) + + public kotlinx.serialization.KSerializer[] typeParametersSerializers() +} + +public final class Simple$Companion : java/lang/Object { + private void () + + public void (kotlin.jvm.internal.DefaultConstructorMarker $constructor_marker) + + public final kotlinx.serialization.KSerializer serializer() +} + +public final class Simple : java/lang/Object { + public final static Simple$Companion Companion + + private final java.lang.String firstName + + private final java.lang.String lastName + + static void () + + public void (java.lang.String firstName, java.lang.String lastName) + + public void (int seen1, java.lang.String firstName, java.lang.String lastName, kotlinx.serialization.internal.SerializationConstructorMarker serializationConstructorMarker) + + public final java.lang.String getFirstName() + + public final java.lang.String getLastName() + + public final static void write$Self(Simple self, kotlinx.serialization.encoding.CompositeEncoder output, kotlinx.serialization.descriptors.SerialDescriptor serialDesc) +} \ No newline at end of file diff --git a/plugins/kotlinx-serialization/tests-gen/org/jetbrains/kotlinx/serialization/runners/SerializationAsmLikeInstructionsListingTestGenerated.java b/plugins/kotlinx-serialization/tests-gen/org/jetbrains/kotlinx/serialization/runners/SerializationAsmLikeInstructionsListingTestGenerated.java index ff947ba5627..780e19e44d3 100644 --- a/plugins/kotlinx-serialization/tests-gen/org/jetbrains/kotlinx/serialization/runners/SerializationAsmLikeInstructionsListingTestGenerated.java +++ b/plugins/kotlinx-serialization/tests-gen/org/jetbrains/kotlinx/serialization/runners/SerializationAsmLikeInstructionsListingTestGenerated.java @@ -37,6 +37,12 @@ public class SerializationAsmLikeInstructionsListingTestGenerated extends Abstra runTest("plugins/kotlinx-serialization/testData/codegen/Delegated.kt"); } + @Test + @TestMetadata("Intrinsics.kt") + public void testIntrinsics() throws Exception { + runTest("plugins/kotlinx-serialization/testData/codegen/Intrinsics.kt"); + } + @Test @TestMetadata("Sealed.kt") public void testSealed() throws Exception { diff --git a/plugins/kotlinx-serialization/tests-gen/org/jetbrains/kotlinx/serialization/runners/SerializationIrAsmLikeInstructionsListingTestGenerated.java b/plugins/kotlinx-serialization/tests-gen/org/jetbrains/kotlinx/serialization/runners/SerializationIrAsmLikeInstructionsListingTestGenerated.java index c1956a8c374..5ae9d3c1538 100644 --- a/plugins/kotlinx-serialization/tests-gen/org/jetbrains/kotlinx/serialization/runners/SerializationIrAsmLikeInstructionsListingTestGenerated.java +++ b/plugins/kotlinx-serialization/tests-gen/org/jetbrains/kotlinx/serialization/runners/SerializationIrAsmLikeInstructionsListingTestGenerated.java @@ -37,6 +37,12 @@ public class SerializationIrAsmLikeInstructionsListingTestGenerated extends Abst runTest("plugins/kotlinx-serialization/testData/codegen/Delegated.kt"); } + @Test + @TestMetadata("Intrinsics.kt") + public void testIntrinsics() throws Exception { + runTest("plugins/kotlinx-serialization/testData/codegen/Intrinsics.kt"); + } + @Test @TestMetadata("Sealed.kt") public void testSealed() throws Exception {