Fix for Kotlin/kotlinx.serialization/118
Fix for Kotlin/kotlinx.serialization/123: resolve annotation parameters in-place Fix for Kotlin/kotlinx.serialization/125 Now polymorphic serializer required by all modalities expect final
This commit is contained in:
+5
-11
@@ -75,9 +75,10 @@ fun getSerialTypeInfo(property: SerializableProperty): SerialTypeInfo {
|
||||
}
|
||||
|
||||
fun findTypeSerializer(module: ModuleDescriptor, kType: KotlinType): ClassDescriptor? {
|
||||
return if (kType.requiresPolymorphism()) findPolymorphicSerializer(module)
|
||||
else if (kType.isTypeParameter()) return null
|
||||
else kType.typeSerializer.toClassDescriptor // check for serializer defined on the type
|
||||
if (kType.requiresPolymorphism()) return findPolymorphicSerializer(module)
|
||||
if (kType.isTypeParameter()) return null
|
||||
if (KotlinBuiltIns.isArray(kType)) return module.findClassAcrossModuleDependencies(referenceArraySerializerId)
|
||||
return kType.typeSerializer.toClassDescriptor // check for serializer defined on the type
|
||||
?: findStandardKotlinTypeSerializer(module, kType) // otherwise see if there is a standard serializer
|
||||
?: findEnumTypeSerializer(module, kType)
|
||||
?: module.findClassAcrossModuleDependencies(contextSerializerId)
|
||||
@@ -116,7 +117,7 @@ fun findEnumTypeSerializer(module: ModuleDescriptor, kType: KotlinType): ClassDe
|
||||
|
||||
fun KotlinType.requiresPolymorphism(): Boolean {
|
||||
return this.toClassDescriptor?.getSuperClassNotAny()?.isInternalSerializable == true
|
||||
|| (this.toClassDescriptor?.modality == Modality.OPEN && this.toClassDescriptor?.unsubstitutedPrimaryConstructor != null) // open not java class
|
||||
|| (this.toClassDescriptor?.modality != Modality.FINAL && this.toClassDescriptor?.unsubstitutedPrimaryConstructor != null) // open not java class
|
||||
|| this.containsTypeProjectionsInTopLevelArguments() // List<*>
|
||||
}
|
||||
|
||||
@@ -142,10 +143,3 @@ fun KtPureClassOrObject.anonymousInitializers() = declarations
|
||||
.filterIsInstance<KtAnonymousInitializer>()
|
||||
.mapNotNull { it.body }
|
||||
.toList()
|
||||
|
||||
fun SerializableProperty.annotationVarsAndDesc(annotationClass: ClassDescriptor): Pair<List<ValueArgument>, List<ValueParameterDescriptor>> {
|
||||
val args: List<ValueArgument> = (this.descriptor.annotations.findAnnotation(annotationClass.fqNameSafe) as? LazyAnnotationDescriptor)?.annotationEntry?.valueArguments.orEmpty()
|
||||
val consParams = annotationClass.unsubstitutedPrimaryConstructor?.valueParameters.orEmpty()
|
||||
if (args.size != consParams.size) throw IllegalArgumentException("Can't use arguments with defaults for serializable annotations yet")
|
||||
return args to consParams
|
||||
}
|
||||
+1
-3
@@ -34,7 +34,6 @@ import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.SerializerCodegen
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.annotationVarsAndDesc
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.findTypeSerializer
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.getSerialTypeInfo
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.contextSerializerId
|
||||
@@ -75,8 +74,7 @@ class SerializerJsTranslator(declaration: KtPureClassOrObject,
|
||||
val call = JsInvocation(JsNameRef(context.getNameForDescriptor(addFunc), serialClassDescRef), JsStringLiteral(prop.name))
|
||||
translator.addInitializerStatement(call.makeStmt())
|
||||
// serialDesc.pushAnnotation(...)
|
||||
for (annotationClass in prop.annotations) {
|
||||
val (args, _) = prop.annotationVarsAndDesc(annotationClass)
|
||||
for ((annotationClass , args, _) in prop.annotationsWithArguments) {
|
||||
val argExprs = args.map { arg ->
|
||||
Translation.translateAsExpression(arg.getArgumentExpression()!!, context)
|
||||
}
|
||||
|
||||
+6
-5
@@ -252,11 +252,12 @@ fun getSerialTypeInfo(property: SerializableProperty, type: Type): JVMSerialType
|
||||
}
|
||||
|
||||
fun findTypeSerializer(module: ModuleDescriptor, kType: KotlinType, asmType: Type): ClassDescriptor? {
|
||||
return if (kType.requiresPolymorphism()) findPolymorphicSerializer(module)
|
||||
else kType.typeSerializer.toClassDescriptor // check for serializer defined on the type
|
||||
?: findStandardAsmTypeSerializer(module, asmType) // otherwise see if there is a standard serializer
|
||||
?: findEnumTypeSerializer(module, kType)
|
||||
?: module.findClassAcrossModuleDependencies(contextSerializerId)
|
||||
if (kType.requiresPolymorphism()) return findPolymorphicSerializer(module)
|
||||
if (KotlinBuiltIns.isArray(kType)) return module.findClassAcrossModuleDependencies(referenceArraySerializerId)
|
||||
return kType.typeSerializer.toClassDescriptor // check for serializer defined on the type
|
||||
?: findStandardAsmTypeSerializer(module, asmType) // otherwise see if there is a standard serializer
|
||||
?: findEnumTypeSerializer(module, kType)
|
||||
?: module.findClassAcrossModuleDependencies(contextSerializerId)
|
||||
}
|
||||
|
||||
fun findStandardAsmTypeSerializer(module: ModuleDescriptor, asmType: Type): ClassDescriptor? {
|
||||
|
||||
+1
-3
@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.SerializerCodegen
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.annotationVarsAndDesc
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.KSerializerDescriptorResolver
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.KSerializerDescriptorResolver.typeArgPrefix
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.getSerializableClassDescriptorBySerializer
|
||||
@@ -89,14 +88,13 @@ class SerializerCodegenImpl(
|
||||
aconst(property.name)
|
||||
invokevirtual(descImplType.internalName, "addElement", "(Ljava/lang/String;)V", false)
|
||||
// pushing annotations
|
||||
for (annotationClass in property.annotations) {
|
||||
for ((annotationClass, args, consParams) in property.annotationsWithArguments) {
|
||||
load(classDescVar, descImplType)
|
||||
val implType = codegen.typeMapper.mapType(annotationClass).internalName + "\$" + KSerializerDescriptorResolver.IMPL_NAME.identifier
|
||||
// new Annotation$Impl(...)
|
||||
anew(Type.getObjectType(implType))
|
||||
dup()
|
||||
val sb = StringBuilder("(")
|
||||
val (args, consParams) = property.annotationVarsAndDesc(annotationClass)
|
||||
for (i in consParams.indices) {
|
||||
val decl = args[i]
|
||||
val desc = consParams[i]
|
||||
|
||||
+14
-3
@@ -16,8 +16,12 @@
|
||||
|
||||
package org.jetbrains.kotlinx.serialization.compiler.resolve
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.psi.ValueArgument
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyAnnotationDescriptor
|
||||
|
||||
class SerializableProperty(val descriptor: PropertyDescriptor, val isConstructorParameterWithDefault: Boolean) {
|
||||
val name = descriptor.annotations.serialNameValue ?: descriptor.name.asString()
|
||||
@@ -27,7 +31,14 @@ class SerializableProperty(val descriptor: PropertyDescriptor, val isConstructor
|
||||
val serializableWith = descriptor.annotations.serializableWith?.let { checkSerializerNullability(type, it) }
|
||||
val optional = descriptor.annotations.serialOptional
|
||||
val transient = descriptor.annotations.serialTransient
|
||||
val annotations = descriptor.annotations
|
||||
.mapNotNull { it.type.toClassDescriptor }
|
||||
.filter { it.annotations.hasAnnotation(serialInfoFqName) }
|
||||
val annotationsWithArguments: List<Triple<ClassDescriptor, List<ValueArgument>, List<ValueParameterDescriptor>>> =
|
||||
descriptor.annotations.asSequence()
|
||||
.filter { it.type.toClassDescriptor?.annotations?.hasAnnotation(serialInfoFqName) == true }
|
||||
.filterIsInstance<LazyAnnotationDescriptor>()
|
||||
.mapNotNull { annDesc ->
|
||||
annDesc.type.toClassDescriptor?.let {
|
||||
Triple(it, annDesc.annotationEntry.valueArguments, it.unsubstitutedPrimaryConstructor?.valueParameters.orEmpty())
|
||||
}
|
||||
}
|
||||
.toList()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user