diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializableCodegen.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializableCodegen.kt index cfde3f05396..4072ef73755 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializableCodegen.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializableCodegen.kt @@ -21,15 +21,13 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.descriptorUtil.secondaryConstructors -import org.jetbrains.kotlinx.serialization.compiler.diagnostic.SERIALIZABLE_PROPERTIES import org.jetbrains.kotlinx.serialization.compiler.resolve.* abstract class SerializableCodegen( protected val serializableDescriptor: ClassDescriptor, bindingContext: BindingContext ) : AbstractSerialGenerator(bindingContext, serializableDescriptor) { - protected val properties = bindingContext.get(SERIALIZABLE_PROPERTIES, serializableDescriptor) - ?: SerializableProperties(serializableDescriptor, bindingContext) + protected val properties = bindingContext.serializablePropertiesFor(serializableDescriptor) fun generate() { generateSyntheticInternalConstructor() diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializerCodegen.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializerCodegen.kt index b3546c1b472..a4a82e52fce 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializerCodegen.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializerCodegen.kt @@ -31,7 +31,7 @@ abstract class SerializerCodegen( ) : AbstractSerialGenerator(bindingContext, serializerDescriptor) { val serializableDescriptor: ClassDescriptor = getSerializableClassDescriptorBySerializer(serializerDescriptor)!! protected val serialName: String = serializableDescriptor.annotations.serialNameValue ?: serializableDescriptor.fqNameUnsafe.asString() - protected val properties = SerializableProperties(serializableDescriptor, bindingContext) + protected val properties = bindingContext.serializablePropertiesFor(serializableDescriptor) protected val serializableProperties = properties.serializableProperties private fun checkSerializability() { diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/TypeUtil.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/TypeUtil.kt index bc03ba50693..b1689955a59 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/TypeUtil.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/TypeUtil.kt @@ -115,12 +115,7 @@ fun AbstractSerialGenerator.findTypeSerializerOrContext( annotations.serializableWith(module)?.let { return it.toClassDescriptor } additionalSerializersInScopeOfCurrentFile[kType]?.let { return it } if (kType in contextualKClassListInCurrentFile) return module.getClassFromSerializationPackage(SpecialBuiltins.contextSerializer) - return analyzeSpecialSerializers(module, annotations) ?: findTypeSerializer(module, kType) /*?: throw CompilationException( - "Serializer for element of type $kType has not been found.\n" + - "To use context serializer as fallback, explicitly annotate element with @ContextualSerialization", - null, - sourceElement - )*/ + return analyzeSpecialSerializers(module, annotations) ?: findTypeSerializer(module, kType) } fun findTypeSerializer(module: ModuleDescriptor, kType: KotlinType): ClassDescriptor? { diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializableIrGenerator.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializableIrGenerator.kt index 5194427581c..b1cded3806d 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializableIrGenerator.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializableIrGenerator.kt @@ -11,8 +11,6 @@ import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.IrExpression -import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin -import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.acceptVoid @@ -138,7 +136,7 @@ class SerializableIrGenerator( ): Int { check(superClass.isInternalSerializable) val superCtorRef = compilerContext.externalSymbols.serializableSyntheticConstructor(superClass) - val superProperties = SerializableProperties(superClass, bindingContext).serializableProperties + val superProperties = bindingContext.serializablePropertiesFor(superClass).serializableProperties val superSlots = superProperties.bitMaskSlotCount() val arguments = allValueParameters.subList(0, superSlots) + allValueParameters.subList(propertiesStart, propertiesStart + superProperties.size) + diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/SerializableJsTranslator.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/SerializableJsTranslator.kt index 9897aabc98a..004631b326b 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/SerializableJsTranslator.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/SerializableJsTranslator.kt @@ -20,8 +20,8 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.codegen.CompilationException import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.js.backend.ast.* import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi import org.jetbrains.kotlin.js.translate.context.Namer @@ -141,7 +141,7 @@ class SerializableJsTranslator( ): Int { val constrDesc = KSerializerDescriptorResolver.createLoadConstructorDescriptor(superClass, context.bindingContext()) val constrRef = context.getInnerNameForDescriptor(constrDesc).makeRef() - val superProperties = SerializableProperties(superClass, bindingContext).serializableProperties + val superProperties = bindingContext.serializablePropertiesFor(superClass).serializableProperties val superSlots = superProperties.bitMaskSlotCount() val arguments = parameters.subList(0, superSlots) + parameters.subList(propertiesStart, propertiesStart + superProperties.size) + diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/SerializableCodegenImpl.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/SerializableCodegenImpl.kt index 19f2299bac4..66f273ba3bd 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/SerializableCodegenImpl.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/SerializableCodegenImpl.kt @@ -93,7 +93,7 @@ class SerializableCodegenImpl( val superClass = serializableDescriptor.getSuperClassOrAny() val myPropsStart: Int if (superClass.isInternalSerializable) { - myPropsStart = SerializableProperties(superClass, classCodegen.bindingContext).serializableProperties.size + myPropsStart = bindingContext.serializablePropertiesFor(superClass).serializableProperties.size val superTypeArguments = serializableDescriptor.typeConstructor.supertypes.single { it.toClassDescriptor?.isInternalSerializable == true }.arguments //super.writeSelf(output, serialDesc) @@ -259,7 +259,7 @@ class SerializableCodegenImpl( invokespecial(superType, "", desc, false) return 0 to propStartVar } else { - val superProps = SerializableProperties(superClass, classCodegen.bindingContext).serializableProperties + val superProps = bindingContext.serializablePropertiesFor(superClass).serializableProperties val creator = buildInternalConstructorDesc(propStartVar, 1, classCodegen, superProps) invokespecial(superType, "", creator, false) return superProps.size to propStartVar + superProps.sumBy { it.asmType.size } diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/DeclarationCheckers.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationPluginDeclarationChecker.kt similarity index 97% rename from plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/DeclarationCheckers.kt rename to plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationPluginDeclarationChecker.kt index 7d5daa8837d..77f0da7b9ae 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/DeclarationCheckers.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationPluginDeclarationChecker.kt @@ -29,7 +29,6 @@ import org.jetbrains.kotlinx.serialization.compiler.backend.common.primaryConstr import org.jetbrains.kotlinx.serialization.compiler.resolve.* internal val SERIALIZABLE_PROPERTIES: WritableSlice = Slices.createSimpleSlice() -internal val SERIALIZER_FOR_PROPERTY: WritableSlice = Slices.createSimpleSlice() class SerializationPluginDeclarationChecker : DeclarationChecker { override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) { @@ -55,7 +54,6 @@ class SerializationPluginDeclarationChecker : DeclarationChecker { } } - // todo: also check on a side of external serializer private fun buildSerializableProperties(descriptor: ClassDescriptor, trace: BindingTrace): SerializableProperties? { if (!descriptor.annotations.hasAnnotation(SerializationAnnotations.serializableAnnotationFqName)) return null if (!descriptor.isInternalSerializable) return null @@ -123,7 +121,6 @@ class SerializationPluginDeclarationChecker : DeclarationChecker { val element = ktType.typeElement ?: return checkSerializerNullability(it.type, serializer.defaultType, element, trace) generatorContextForAnalysis.checkTypeArguments(it.module, it.type, element, trace) - trace.record(SERIALIZER_FOR_PROPERTY, it.descriptor, serializer) } else { generatorContextForAnalysis.checkType(it.module, it.type, ktType, trace) } diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializationUtil.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializationUtil.kt index 8b3c7642d55..c094abd8fba 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializationUtil.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializationUtil.kt @@ -29,11 +29,9 @@ import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyAnnotationDescriptor import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf -import org.jetbrains.kotlin.types.typeUtil.supertypes import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.contextSerializerId import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.enumSerializerId import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.polymorphicSerializerId -import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.KSERIALIZER_CLASS import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationAnnotations.serialInfoFqName internal fun isAllowedToHaveAutoGeneratedSerializerMethods( @@ -62,7 +60,7 @@ internal fun ClassDescriptor.createSerializerTypeFor(argument: SimpleType, baseS val projectionType = Variance.INVARIANT val types = listOf(TypeProjectionImpl(projectionType, argument)) val descriptor = module.findClassAcrossModuleDependencies(ClassId.topLevel(baseSerializerInterface)) - ?: throw IllegalArgumentException("Can't locate $baseSerializerInterface") + ?: throw IllegalArgumentException("Can't locate $baseSerializerInterface. Is kotlinx-serialization library present in compile classpath?") return KotlinTypeFactory.simpleNotNullType(Annotations.EMPTY, descriptor, types) } diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializerDescriptorResolver.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializerDescriptorResolver.kt index c3ab84673e3..04eb0feaed7 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializerDescriptorResolver.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializerDescriptorResolver.kt @@ -293,7 +293,7 @@ object KSerializerDescriptorResolver { val markerDesc = classDescriptor.getKSerializerConstructorMarker() val markerType = markerDesc.toSimpleType() - val serializableProperties = SerializableProperties(classDescriptor, bindingContext).serializableProperties + val serializableProperties = bindingContext.serializablePropertiesFor(classDescriptor).serializableProperties val parameterDescsAsProps = serializableProperties.map { it.descriptor } val bitMaskSlotsCount = serializableProperties.bitMaskSlotCount() var i = 0 diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/SerializableProperties.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/SerializableProperties.kt index c77ffe4f71f..8ac8d35a2b5 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/SerializableProperties.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/SerializableProperties.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny import org.jetbrains.kotlin.resolve.hasBackingField import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter +import org.jetbrains.kotlinx.serialization.compiler.diagnostic.SERIALIZABLE_PROPERTIES class SerializableProperties(private val serializableClass: ClassDescriptor, val bindingContext: BindingContext) { private val primaryConstructorParameters: List = @@ -75,4 +76,7 @@ class SerializableProperties(private val serializableClass: ClassDescriptor, val } internal fun List.bitMaskSlotCount() = size / 32 + 1 -internal fun bitMaskSlotAt(propertyIndex: Int) = propertyIndex / 32 \ No newline at end of file +internal fun bitMaskSlotAt(propertyIndex: Int) = propertyIndex / 32 + +internal fun BindingContext.serializablePropertiesFor(classDescriptor: ClassDescriptor): SerializableProperties = + this.get(SERIALIZABLE_PROPERTIES, classDescriptor) ?: SerializableProperties(classDescriptor, this) \ No newline at end of file