Support new ContextSerializer signature
This commit is contained in:
+139
-115
@@ -29,10 +29,7 @@ import org.jetbrains.kotlin.types.*
|
|||||||
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
|
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
|
||||||
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
||||||
import org.jetbrains.kotlin.types.typeUtil.representativeUpperBound
|
import org.jetbrains.kotlin.types.typeUtil.representativeUpperBound
|
||||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.AbstractSerialGenerator
|
import org.jetbrains.kotlinx.serialization.compiler.backend.common.*
|
||||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.allSealedSerializableSubclassesFor
|
|
||||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.findTypeSerializerOrContext
|
|
||||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.serialName
|
|
||||||
import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.*
|
import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.*
|
||||||
import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationPluginContext
|
import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationPluginContext
|
||||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.*
|
import org.jetbrains.kotlinx.serialization.compiler.resolve.*
|
||||||
@@ -567,118 +564,145 @@ interface IrBuilderExtension {
|
|||||||
}
|
}
|
||||||
if (serializerClassOriginal.kind == ClassKind.OBJECT) {
|
if (serializerClassOriginal.kind == ClassKind.OBJECT) {
|
||||||
return irGetObject(serializerClassOriginal)
|
return irGetObject(serializerClassOriginal)
|
||||||
} else {
|
|
||||||
fun instantiate(serializer: ClassDescriptor?, type: KotlinType): IrExpression? {
|
|
||||||
val expr = serializerInstance(
|
|
||||||
enclosingGenerator,
|
|
||||||
serializer,
|
|
||||||
module,
|
|
||||||
type,
|
|
||||||
type.genericIndex,
|
|
||||||
genericGetter
|
|
||||||
) ?: return null
|
|
||||||
return wrapWithNullableSerializerIfNeeded(module, type, expr, nullableSerClass)
|
|
||||||
}
|
|
||||||
var serializerClass = serializerClassOriginal
|
|
||||||
var args: List<IrExpression>
|
|
||||||
var typeArgs: List<IrType?>
|
|
||||||
val thisIrType = kType.toIrType()
|
|
||||||
when (serializerClassOriginal.classId) {
|
|
||||||
contextSerializerId, polymorphicSerializerId -> {
|
|
||||||
args = listOf(classReference(kType))
|
|
||||||
typeArgs = listOf(thisIrType)
|
|
||||||
}
|
|
||||||
objectSerializerId -> {
|
|
||||||
args = listOf(irString(kType.serialName()), irGetObject(kType.toClassDescriptor!!))
|
|
||||||
typeArgs = listOf(thisIrType)
|
|
||||||
}
|
|
||||||
sealedSerializerId -> {
|
|
||||||
args = mutableListOf<IrExpression>().apply {
|
|
||||||
add(irString(kType.serialName()))
|
|
||||||
add(classReference(kType))
|
|
||||||
val (subclasses, subSerializers) = enclosingGenerator.allSealedSerializableSubclassesFor(
|
|
||||||
kType.toClassDescriptor!!,
|
|
||||||
module
|
|
||||||
)
|
|
||||||
val projectedOutCurrentKClass = kClassTypeFor(TypeProjectionImpl(Variance.OUT_VARIANCE, kType))
|
|
||||||
add(
|
|
||||||
createArrayOfExpression(
|
|
||||||
projectedOutCurrentKClass.toIrType(),
|
|
||||||
subclasses.map { classReference(it) }
|
|
||||||
)
|
|
||||||
)
|
|
||||||
add(
|
|
||||||
createArrayOfExpression(
|
|
||||||
wrapIrTypeIntoKSerializerIrType(module, thisIrType, variance = Variance.OUT_VARIANCE),
|
|
||||||
subSerializers.mapIndexed { i, serializer ->
|
|
||||||
val type = subclasses[i]
|
|
||||||
val expr = serializerInstance(
|
|
||||||
enclosingGenerator,
|
|
||||||
serializer,
|
|
||||||
module,
|
|
||||||
type,
|
|
||||||
type.genericIndex
|
|
||||||
) { _, genericType ->
|
|
||||||
serializerInstance(
|
|
||||||
enclosingGenerator,
|
|
||||||
module.getClassFromSerializationPackage(
|
|
||||||
SpecialBuiltins.polymorphicSerializer
|
|
||||||
),
|
|
||||||
module,
|
|
||||||
(genericType.constructor.declarationDescriptor as TypeParameterDescriptor).representativeUpperBound
|
|
||||||
)!!
|
|
||||||
}!!
|
|
||||||
wrapWithNullableSerializerIfNeeded(module, type, expr, nullableSerClass)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
typeArgs = listOf(thisIrType)
|
|
||||||
}
|
|
||||||
enumSerializerId -> {
|
|
||||||
serializerClass = module.getClassFromInternalSerializationPackage(SpecialBuiltins.enumSerializer)
|
|
||||||
args = kType.toClassDescriptor!!.let { enumDesc ->
|
|
||||||
listOf(
|
|
||||||
irString(enumDesc.serialName()),
|
|
||||||
irCall(findEnumValuesMethod(enumDesc))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
typeArgs = listOf(thisIrType)
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
args = kType.arguments.map {
|
|
||||||
val argSer = enclosingGenerator.findTypeSerializerOrContext(
|
|
||||||
module,
|
|
||||||
it.type,
|
|
||||||
sourceElement = serializerClassOriginal.findPsi()
|
|
||||||
)
|
|
||||||
instantiate(argSer, it.type) ?: return null
|
|
||||||
}
|
|
||||||
typeArgs = kType.arguments.map { it.type.toIrType() }
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if (serializerClassOriginal.classId == referenceArraySerializerId) {
|
|
||||||
args = listOf(classReference(kType.arguments[0].type)) + args
|
|
||||||
typeArgs = listOf(typeArgs[0].makeNotNull()) + typeArgs
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
val serializable = getSerializableClassDescriptorBySerializer(serializerClass)
|
|
||||||
val ctor = if (serializable?.declaredTypeParameters?.isNotEmpty() == true) {
|
|
||||||
requireNotNull(
|
|
||||||
findSerializerConstructorForTypeArgumentsSerializers(serializerClass)
|
|
||||||
) { "Generated serializer does not have constructor with required number of arguments" }
|
|
||||||
} else {
|
|
||||||
compilerContext.referenceConstructors(serializerClass.fqNameSafe).single { it.owner.isPrimary }
|
|
||||||
}
|
|
||||||
// Return type should be correctly substituted
|
|
||||||
assert(ctor.isBound)
|
|
||||||
val ctorDecl = ctor.owner
|
|
||||||
val typeParameters = ctorDecl.parentAsClass.typeParameters
|
|
||||||
val substitutedReturnType = ctorDecl.returnType.substitute(typeParameters, typeArgs)
|
|
||||||
return irInvoke(null, ctor, typeArguments = typeArgs, valueArguments = args, returnTypeHint = substitutedReturnType)
|
|
||||||
}
|
}
|
||||||
|
fun instantiate(serializer: ClassDescriptor?, type: KotlinType): IrExpression? {
|
||||||
|
val expr = serializerInstance(
|
||||||
|
enclosingGenerator,
|
||||||
|
serializer,
|
||||||
|
module,
|
||||||
|
type,
|
||||||
|
type.genericIndex,
|
||||||
|
genericGetter
|
||||||
|
) ?: return null
|
||||||
|
return wrapWithNullableSerializerIfNeeded(module, type, expr, nullableSerClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
var serializerClass = serializerClassOriginal
|
||||||
|
var args: List<IrExpression>
|
||||||
|
var typeArgs: List<IrType?>
|
||||||
|
val thisIrType = kType.toIrType()
|
||||||
|
val hasNewCtxSerCtor =
|
||||||
|
serializerClassOriginal.classId == contextSerializerId && compilerContext.referenceConstructors(serializerClass.fqNameSafe)
|
||||||
|
.any { it.owner.valueParameters.size == 3 }
|
||||||
|
when (serializerClassOriginal.classId) {
|
||||||
|
contextSerializerId, polymorphicSerializerId -> {
|
||||||
|
args = listOf(classReference(kType))
|
||||||
|
typeArgs = listOf(thisIrType)
|
||||||
|
|
||||||
|
if (hasNewCtxSerCtor) {
|
||||||
|
// new signature of context serializer
|
||||||
|
args = args + mutableListOf<IrExpression>().apply {
|
||||||
|
val fallbackDefaultSerializer = findTypeSerializer(module, kType)
|
||||||
|
add(instantiate(fallbackDefaultSerializer, kType) ?: irNull())
|
||||||
|
add(
|
||||||
|
createArrayOfExpression(
|
||||||
|
wrapIrTypeIntoKSerializerIrType(
|
||||||
|
module,
|
||||||
|
thisIrType,
|
||||||
|
variance = Variance.OUT_VARIANCE
|
||||||
|
),
|
||||||
|
kType.arguments.map {
|
||||||
|
val argSer = enclosingGenerator.findTypeSerializerOrContext(
|
||||||
|
module,
|
||||||
|
it.type,
|
||||||
|
sourceElement = serializerClassOriginal.findPsi()
|
||||||
|
)
|
||||||
|
instantiate(argSer, it.type)!!
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
objectSerializerId -> {
|
||||||
|
args = listOf(irString(kType.serialName()), irGetObject(kType.toClassDescriptor!!))
|
||||||
|
typeArgs = listOf(thisIrType)
|
||||||
|
}
|
||||||
|
sealedSerializerId -> {
|
||||||
|
args = mutableListOf<IrExpression>().apply {
|
||||||
|
add(irString(kType.serialName()))
|
||||||
|
add(classReference(kType))
|
||||||
|
val (subclasses, subSerializers) = enclosingGenerator.allSealedSerializableSubclassesFor(
|
||||||
|
kType.toClassDescriptor!!,
|
||||||
|
module
|
||||||
|
)
|
||||||
|
val projectedOutCurrentKClass = kClassTypeFor(TypeProjectionImpl(Variance.OUT_VARIANCE, kType))
|
||||||
|
add(
|
||||||
|
createArrayOfExpression(
|
||||||
|
projectedOutCurrentKClass.toIrType(),
|
||||||
|
subclasses.map { classReference(it) }
|
||||||
|
)
|
||||||
|
)
|
||||||
|
add(
|
||||||
|
createArrayOfExpression(
|
||||||
|
wrapIrTypeIntoKSerializerIrType(module, thisIrType, variance = Variance.OUT_VARIANCE),
|
||||||
|
subSerializers.mapIndexed { i, serializer ->
|
||||||
|
val type = subclasses[i]
|
||||||
|
val expr = serializerInstance(
|
||||||
|
enclosingGenerator,
|
||||||
|
serializer,
|
||||||
|
module,
|
||||||
|
type,
|
||||||
|
type.genericIndex
|
||||||
|
) { _, genericType ->
|
||||||
|
serializerInstance(
|
||||||
|
enclosingGenerator,
|
||||||
|
module.getClassFromSerializationPackage(
|
||||||
|
SpecialBuiltins.polymorphicSerializer
|
||||||
|
),
|
||||||
|
module,
|
||||||
|
(genericType.constructor.declarationDescriptor as TypeParameterDescriptor).representativeUpperBound
|
||||||
|
)!!
|
||||||
|
}!!
|
||||||
|
wrapWithNullableSerializerIfNeeded(module, type, expr, nullableSerClass)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
typeArgs = listOf(thisIrType)
|
||||||
|
}
|
||||||
|
enumSerializerId -> {
|
||||||
|
serializerClass = module.getClassFromInternalSerializationPackage(SpecialBuiltins.enumSerializer)
|
||||||
|
args = kType.toClassDescriptor!!.let { enumDesc ->
|
||||||
|
listOf(
|
||||||
|
irString(enumDesc.serialName()),
|
||||||
|
irCall(findEnumValuesMethod(enumDesc))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
typeArgs = listOf(thisIrType)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
args = kType.arguments.map {
|
||||||
|
val argSer = enclosingGenerator.findTypeSerializerOrContext(
|
||||||
|
module,
|
||||||
|
it.type,
|
||||||
|
sourceElement = serializerClassOriginal.findPsi()
|
||||||
|
)
|
||||||
|
instantiate(argSer, it.type) ?: return null
|
||||||
|
}
|
||||||
|
typeArgs = kType.arguments.map { it.type.toIrType() }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (serializerClassOriginal.classId == referenceArraySerializerId) {
|
||||||
|
args = listOf(classReference(kType.arguments[0].type)) + args
|
||||||
|
typeArgs = listOf(typeArgs[0].makeNotNull()) + typeArgs
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val serializable = getSerializableClassDescriptorBySerializer(serializerClass)
|
||||||
|
val ctor = if (serializable?.declaredTypeParameters?.isNotEmpty() == true) {
|
||||||
|
requireNotNull(
|
||||||
|
findSerializerConstructorForTypeArgumentsSerializers(serializerClass)
|
||||||
|
) { "Generated serializer does not have constructor with required number of arguments" }
|
||||||
|
} else {
|
||||||
|
compilerContext.referenceConstructors(serializerClass.fqNameSafe).single { it.owner.isPrimary }
|
||||||
|
}
|
||||||
|
// Return type should be correctly substituted
|
||||||
|
assert(ctor.isBound)
|
||||||
|
val ctorDecl = ctor.owner
|
||||||
|
val typeParameters = ctorDecl.parentAsClass.typeParameters
|
||||||
|
val substitutedReturnType = ctorDecl.returnType.substitute(typeParameters, typeArgs)
|
||||||
|
return irInvoke(null, ctor, typeArguments = typeArgs, valueArguments = args, returnTypeHint = substitutedReturnType)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findSerializerConstructorForTypeArgumentsSerializers(serializer: ClassDescriptor): IrConstructorSymbol? {
|
private fun findSerializerConstructorForTypeArgumentsSerializers(serializer: ClassDescriptor): IrConstructorSymbol? {
|
||||||
|
|||||||
+87
-84
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2017 JetBrains s.r.o.
|
* 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.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlinx.serialization.compiler.backend.js
|
package org.jetbrains.kotlinx.serialization.compiler.backend.js
|
||||||
@@ -151,78 +140,92 @@ internal fun AbstractSerialGenerator.serializerInstance(
|
|||||||
}
|
}
|
||||||
if (serializerClass.kind == ClassKind.OBJECT) {
|
if (serializerClass.kind == ClassKind.OBJECT) {
|
||||||
return context.serializerObjectGetter(serializerClass)
|
return context.serializerObjectGetter(serializerClass)
|
||||||
} else {
|
|
||||||
fun instantiate(serializer: ClassDescriptor?, type: KotlinType): JsExpression? {
|
|
||||||
val expr = serializerInstance(context, serializer, module, type, type.genericIndex, genericGetter) ?: return null
|
|
||||||
return if (type.isMarkedNullable) JsNew(nullableSerClass, listOf(expr)) else expr
|
|
||||||
}
|
|
||||||
var args = when {
|
|
||||||
serializerClass.classId == contextSerializerId || serializerClass.classId == polymorphicSerializerId -> listOf(
|
|
||||||
ExpressionVisitor.getObjectKClass(context, kType.toClassDescriptor!!)
|
|
||||||
)
|
|
||||||
serializerClass.classId == enumSerializerId -> listOf(
|
|
||||||
JsStringLiteral(kType.serialName()),
|
|
||||||
// EnumClass.values() invocation
|
|
||||||
JsInvocation(
|
|
||||||
context.getInnerNameForDescriptor(
|
|
||||||
DescriptorUtils.getFunctionByName(
|
|
||||||
kType.toClassDescriptor!!.staticScope,
|
|
||||||
DescriptorUtils.ENUM_VALUES
|
|
||||||
)
|
|
||||||
).makeRef()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
serializerClass.classId == objectSerializerId -> listOf(
|
|
||||||
JsStringLiteral(kType.serialName()),
|
|
||||||
context.serializerObjectGetter(kType.toClassDescriptor!!)
|
|
||||||
)
|
|
||||||
serializerClass.classId == sealedSerializerId -> mutableListOf<JsExpression>().apply {
|
|
||||||
add(JsStringLiteral(kType.serialName()))
|
|
||||||
add(ExpressionVisitor.getObjectKClass(context, kType.toClassDescriptor!!))
|
|
||||||
val (subclasses, subSerializers) = allSealedSerializableSubclassesFor(
|
|
||||||
kType.toClassDescriptor!!,
|
|
||||||
module
|
|
||||||
)
|
|
||||||
add(JsArrayLiteral(subclasses.map {
|
|
||||||
ExpressionVisitor.getObjectKClass(
|
|
||||||
context,
|
|
||||||
it.toClassDescriptor!!
|
|
||||||
)
|
|
||||||
}))
|
|
||||||
add(JsArrayLiteral(subSerializers.mapIndexed { i, serializer ->
|
|
||||||
val type = subclasses[i]
|
|
||||||
val expr = serializerInstance(context, serializer, module, type, type.genericIndex) { _, genericType ->
|
|
||||||
serializerInstance(
|
|
||||||
context,
|
|
||||||
module.getClassFromSerializationPackage(SpecialBuiltins.polymorphicSerializer),
|
|
||||||
module,
|
|
||||||
(genericType.constructor.declarationDescriptor as TypeParameterDescriptor).representativeUpperBound
|
|
||||||
)!!
|
|
||||||
}!!
|
|
||||||
if (type.isMarkedNullable) JsNew(nullableSerClass, listOf(expr)) else expr
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
else -> kType.arguments.map {
|
|
||||||
val argSer = findTypeSerializerOrContext(module, it.type, sourceElement = serializerClass.findPsi())
|
|
||||||
instantiate(argSer, it.type) ?: return null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (serializerClass.classId == referenceArraySerializerId)
|
|
||||||
args = listOf(ExpressionVisitor.getObjectKClass(context, kType.arguments[0].type.toClassDescriptor!!)) + args
|
|
||||||
val serializable = getSerializableClassDescriptorBySerializer(serializerClass)
|
|
||||||
val ref = if (serializable?.declaredTypeParameters?.isNotEmpty() == true) {
|
|
||||||
val desc = requireNotNull(
|
|
||||||
findSerializerConstructorForTypeArgumentsSerializers(serializerClass)
|
|
||||||
) { "Generated serializer does not have constructor with required number of arguments" }
|
|
||||||
if (!desc.isPrimary)
|
|
||||||
JsInvocation(context.getInnerReference(desc), args)
|
|
||||||
else
|
|
||||||
JsNew(context.getInnerReference(desc), args)
|
|
||||||
} else {
|
|
||||||
JsNew(context.translateQualifiedReference(serializerClass), args)
|
|
||||||
}
|
|
||||||
return ref
|
|
||||||
}
|
}
|
||||||
|
val hasNewCtxSerCtor =
|
||||||
|
serializerClass.classId == contextSerializerId && serializerClass.constructors.any { it.valueParameters.size == 3 }
|
||||||
|
|
||||||
|
fun instantiate(serializer: ClassDescriptor?, type: KotlinType): JsExpression? {
|
||||||
|
val expr = serializerInstance(context, serializer, module, type, type.genericIndex, genericGetter) ?: return null
|
||||||
|
return if (type.isMarkedNullable) JsNew(nullableSerClass, listOf(expr)) else expr
|
||||||
|
}
|
||||||
|
|
||||||
|
var args = when {
|
||||||
|
hasNewCtxSerCtor -> {
|
||||||
|
mutableListOf<JsExpression>().apply {
|
||||||
|
add(ExpressionVisitor.getObjectKClass(context, kType.toClassDescriptor!!))
|
||||||
|
val fallbackDefaultSerializer = findTypeSerializer(module, kType)
|
||||||
|
add(instantiate(fallbackDefaultSerializer, kType) ?: JsNullLiteral())
|
||||||
|
add(JsArrayLiteral(kType.arguments.map {
|
||||||
|
val argSer = findTypeSerializerOrContext(module, it.type, sourceElement = serializerClass.findPsi())
|
||||||
|
instantiate(argSer, it.type)!!
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
serializerClass.classId == contextSerializerId || serializerClass.classId == polymorphicSerializerId -> listOf(
|
||||||
|
ExpressionVisitor.getObjectKClass(context, kType.toClassDescriptor!!)
|
||||||
|
)
|
||||||
|
serializerClass.classId == enumSerializerId -> listOf(
|
||||||
|
JsStringLiteral(kType.serialName()),
|
||||||
|
// EnumClass.values() invocation
|
||||||
|
JsInvocation(
|
||||||
|
context.getInnerNameForDescriptor(
|
||||||
|
DescriptorUtils.getFunctionByName(
|
||||||
|
kType.toClassDescriptor!!.staticScope,
|
||||||
|
DescriptorUtils.ENUM_VALUES
|
||||||
|
)
|
||||||
|
).makeRef()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
serializerClass.classId == objectSerializerId -> listOf(
|
||||||
|
JsStringLiteral(kType.serialName()),
|
||||||
|
context.serializerObjectGetter(kType.toClassDescriptor!!)
|
||||||
|
)
|
||||||
|
serializerClass.classId == sealedSerializerId -> mutableListOf<JsExpression>().apply {
|
||||||
|
add(JsStringLiteral(kType.serialName()))
|
||||||
|
add(ExpressionVisitor.getObjectKClass(context, kType.toClassDescriptor!!))
|
||||||
|
val (subclasses, subSerializers) = allSealedSerializableSubclassesFor(
|
||||||
|
kType.toClassDescriptor!!,
|
||||||
|
module
|
||||||
|
)
|
||||||
|
add(JsArrayLiteral(subclasses.map {
|
||||||
|
ExpressionVisitor.getObjectKClass(
|
||||||
|
context,
|
||||||
|
it.toClassDescriptor!!
|
||||||
|
)
|
||||||
|
}))
|
||||||
|
add(JsArrayLiteral(subSerializers.mapIndexed { i, serializer ->
|
||||||
|
val type = subclasses[i]
|
||||||
|
val expr = serializerInstance(context, serializer, module, type, type.genericIndex) { _, genericType ->
|
||||||
|
serializerInstance(
|
||||||
|
context,
|
||||||
|
module.getClassFromSerializationPackage(SpecialBuiltins.polymorphicSerializer),
|
||||||
|
module,
|
||||||
|
(genericType.constructor.declarationDescriptor as TypeParameterDescriptor).representativeUpperBound
|
||||||
|
)!!
|
||||||
|
}!!
|
||||||
|
if (type.isMarkedNullable) JsNew(nullableSerClass, listOf(expr)) else expr
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
else -> kType.arguments.map {
|
||||||
|
val argSer = findTypeSerializerOrContext(module, it.type, sourceElement = serializerClass.findPsi())
|
||||||
|
instantiate(argSer, it.type) ?: return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (serializerClass.classId == referenceArraySerializerId)
|
||||||
|
args = listOf(ExpressionVisitor.getObjectKClass(context, kType.arguments[0].type.toClassDescriptor!!)) + args
|
||||||
|
val serializable = getSerializableClassDescriptorBySerializer(serializerClass)
|
||||||
|
val ref = if (serializable?.declaredTypeParameters?.isNotEmpty() == true) {
|
||||||
|
val desc = requireNotNull(
|
||||||
|
findSerializerConstructorForTypeArgumentsSerializers(serializerClass)
|
||||||
|
) { "Generated serializer does not have constructor with required number of arguments" }
|
||||||
|
if (!desc.isPrimary)
|
||||||
|
JsInvocation(context.getInnerReference(desc), args)
|
||||||
|
else
|
||||||
|
JsNew(context.getInnerReference(desc), args)
|
||||||
|
} else {
|
||||||
|
JsNew(context.translateQualifiedReference(serializerClass), args)
|
||||||
|
}
|
||||||
|
return ref
|
||||||
}
|
}
|
||||||
|
|
||||||
fun TranslationContext.buildInitializersRemapping(
|
fun TranslationContext.buildInitializersRemapping(
|
||||||
|
|||||||
+16
-13
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2017 JetBrains s.r.o.
|
* 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.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlinx.serialization.compiler.backend.jvm
|
package org.jetbrains.kotlinx.serialization.compiler.backend.jvm
|
||||||
@@ -302,6 +291,20 @@ internal fun AbstractSerialGenerator.stackValueSerializerInstance(codegen: Class
|
|||||||
aconst(codegen.typeMapper.mapType(kType, null, TypeMappingMode.GENERIC_ARGUMENT))
|
aconst(codegen.typeMapper.mapType(kType, null, TypeMappingMode.GENERIC_ARGUMENT))
|
||||||
AsmUtil.wrapJavaClassIntoKClass(this)
|
AsmUtil.wrapJavaClassIntoKClass(this)
|
||||||
signature.append(AsmTypes.K_CLASS_TYPE.descriptor)
|
signature.append(AsmTypes.K_CLASS_TYPE.descriptor)
|
||||||
|
if (serializer.classId == contextSerializerId && serializer.constructors.any { it.valueParameters.size == 3 }) {
|
||||||
|
// append new additional arguments
|
||||||
|
val fallbackDefaultSerializer = findTypeSerializer(module, kType)
|
||||||
|
if (fallbackDefaultSerializer != null) {
|
||||||
|
instantiate(kType to fallbackDefaultSerializer, writeSignature = false)
|
||||||
|
} else {
|
||||||
|
aconst(null)
|
||||||
|
}
|
||||||
|
signature.append(kSerializerType.descriptor)
|
||||||
|
fillArray(kSerializerType, argSerializers) { _, serializer ->
|
||||||
|
instantiate(serializer, writeSignature = false)
|
||||||
|
}
|
||||||
|
signature.append(kSerializerArrayType.descriptor)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
referenceArraySerializerId -> {
|
referenceArraySerializerId -> {
|
||||||
// a special way to instantiate reference array serializer -- need an element KClass reference
|
// a special way to instantiate reference array serializer -- need an element KClass reference
|
||||||
|
|||||||
Reference in New Issue
Block a user