diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ConstructorCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ConstructorCodegen.java index a46c4455e6a..8e53656771d 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ConstructorCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ConstructorCodegen.java @@ -130,6 +130,8 @@ public class ConstructorCodegen { ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor, typeMapper); KtSecondaryConstructor constructor = (KtSecondaryConstructor) descriptorToDeclaration(constructorDescriptor); + // Synthetic constructors don't have corresponding declarations + if (constructor == null) return; functionCodegen.generateMethod( JvmDeclarationOriginKt.OtherOrigin(constructor, constructorDescriptor), diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/synthetics/SyntheticClassOrObjectDescriptor.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/synthetics/SyntheticClassOrObjectDescriptor.kt index 7d61d67ddc1..dd20f2e8001 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/synthetics/SyntheticClassOrObjectDescriptor.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/synthetics/SyntheticClassOrObjectDescriptor.kt @@ -44,6 +44,7 @@ class SyntheticClassOrObjectDescriptor( outerScope: LexicalScope, private val modality: Modality, private val visibility: Visibility, + override val annotations: Annotations, constructorVisibility: Visibility, private val kind: ClassKind, private val isCompanionObject: Boolean @@ -71,8 +72,6 @@ class SyntheticClassOrObjectDescriptor( this.typeParameters = typeParameters } - override val annotations: Annotations get() = Annotations.EMPTY - override fun getModality() = modality override fun getVisibility() = visibility override fun getKind() = kind diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/extensions/SyntheticResolveExtension.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/extensions/SyntheticResolveExtension.kt index cf81ccb1a4f..c60958e919d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/extensions/SyntheticResolveExtension.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/extensions/SyntheticResolveExtension.kt @@ -17,10 +17,7 @@ package org.jetbrains.kotlin.resolve.extensions import com.intellij.openapi.project.Project -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor -import org.jetbrains.kotlin.descriptors.PropertyDescriptor -import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor +import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.BindingContext @@ -113,6 +110,22 @@ interface SyntheticResolveExtension { ) } } + + override fun generateSyntheticSecondaryConstructors( + thisDescriptor: ClassDescriptor, + bindingContext: BindingContext, + result: MutableCollection + ) { + instances.forEach { + withLinkageErrorLogger(it) { + generateSyntheticSecondaryConstructors( + thisDescriptor, + bindingContext, + result + ) + } + } + } } } } @@ -160,4 +173,11 @@ interface SyntheticResolveExtension { result: MutableSet ) { } + + fun generateSyntheticSecondaryConstructors( + thisDescriptor: ClassDescriptor, + bindingContext: BindingContext, + result: MutableCollection + ) { + } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java index 72f06fa749d..06513e7087f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java @@ -444,7 +444,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes /* parentClassOrObject= */ classOrObject, this, syntheticCompanionName, getSource(), /* outerScope= */ getOuterScope(), - Modality.FINAL, PUBLIC, PRIVATE, ClassKind.OBJECT, true); + Modality.FINAL, PUBLIC, Annotations.Companion.getEMPTY(), PRIVATE, ClassKind.OBJECT, true); companionDescriptor.initialize(); return companionDescriptor; } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassMemberScope.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassMemberScope.kt index 226742d6566..3d0fe63e311 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassMemberScope.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassMemberScope.kt @@ -415,7 +415,18 @@ open class LazyClassMemberScope( } private val secondaryConstructors: NotNullLazyValue> = - c.storageManager.createLazyValue { resolveSecondaryConstructors() } + c.storageManager.createLazyValue { doGetConstructors() } + + private fun doGetConstructors(): Collection { + val result = mutableListOf() + result.addAll(resolveSecondaryConstructors()) + addSyntheticSecondaryConstructors(result) + return result + } + + private fun addSyntheticSecondaryConstructors(result: MutableCollection) { + c.syntheticResolveExtension.generateSyntheticSecondaryConstructors(thisDescriptor, trace.bindingContext, result) + } fun getConstructors(): Collection { val result = secondaryConstructors() 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 d6334ea2ccb..13839ad2086 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 @@ -20,10 +20,8 @@ import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlinx.serialization.compiler.resolve.KSerializerDescriptorResolver -import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializableProperties -import org.jetbrains.kotlinx.serialization.compiler.resolve.classSerializer -import org.jetbrains.kotlinx.serialization.compiler.resolve.isAbstractSerializableClass +import org.jetbrains.kotlin.resolve.descriptorUtil.secondaryConstructors +import org.jetbrains.kotlinx.serialization.compiler.resolve.* abstract class SerializableCodegen( protected val serializableDescriptor: ClassDescriptor, @@ -39,7 +37,7 @@ abstract class SerializableCodegen( private fun generateSyntheticInternalConstructor() { val serializerDescriptor = serializableDescriptor.classSerializer ?: return if (isAbstractSerializableClass(serializableDescriptor) || SerializerCodegen.getSyntheticLoadMember(serializerDescriptor) != null) { - val constrDesc = KSerializerDescriptorResolver.createLoadConstructorDescriptor(serializableDescriptor, bindingContext) + val constrDesc = serializableDescriptor.secondaryConstructors.find(ClassConstructorDescriptor::isSerializationCtor) ?: return generateInternalConstructor(constrDesc) } } @@ -57,4 +55,4 @@ abstract class SerializableCodegen( protected open fun generateWriteSelfMethod(methodDescriptor: FunctionDescriptor) { } -} \ No newline at end of file +} 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 96dee484593..b3546c1b472 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 @@ -24,7 +24,6 @@ import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered import org.jetbrains.kotlinx.serialization.compiler.resolve.* -import org.jetbrains.kotlinx.serialization.compiler.resolve.KSerializerDescriptorResolver.findSerializerConstructorForTypeArgumentsSerializers abstract class SerializerCodegen( protected val serializerDescriptor: ClassDescriptor, diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/GeneratorHelpers.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/GeneratorHelpers.kt index c85008e47eb..f09d819f765 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/GeneratorHelpers.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/GeneratorHelpers.kt @@ -18,9 +18,12 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.* -import org.jetbrains.kotlin.ir.types.* +import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection +import org.jetbrains.kotlin.ir.types.makeNotNull +import org.jetbrains.kotlin.ir.types.toKotlinType +import org.jetbrains.kotlin.ir.types.typeWith import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi import org.jetbrains.kotlin.name.ClassId @@ -77,6 +80,7 @@ interface IrBuilderExtension { fun IrClass.contributeConstructor( descriptor: ClassConstructorDescriptor, fromStubs: Boolean = false, + overwriteValueParameters: Boolean = false, bodyGen: IrBlockBodyBuilder.(IrConstructor) -> Unit ) { val c = if (!fromStubs) compilerContext.localSymbolTable.declareConstructor( @@ -87,7 +91,7 @@ interface IrBuilderExtension { ) else compilerContext.externalSymbols.referenceConstructor(descriptor).owner c.parent = this c.returnType = descriptor.returnType.toIrType() - if (!fromStubs) c.createParameterDeclarations(receiver = null) + if (!fromStubs || overwriteValueParameters) c.createParameterDeclarations(receiver = null, overwriteValueParameters = overwriteValueParameters) if (c.typeParameters.isEmpty()) { c.copyTypeParamsFromDescriptor() } @@ -346,7 +350,7 @@ interface IrBuilderExtension { } } - fun IrFunction.createParameterDeclarations(receiver: IrValueParameter?) { + fun IrFunction.createParameterDeclarations(receiver: IrValueParameter?, overwriteValueParameters: Boolean = false) { fun ParameterDescriptor.irValueParameter() = IrValueParameterImpl( this@createParameterDeclarations.startOffset, this@createParameterDeclarations.endOffset, SERIALIZABLE_PLUGIN_ORIGIN, @@ -360,8 +364,11 @@ interface IrBuilderExtension { dispatchReceiverParameter = descriptor.dispatchReceiverParameter?.irValueParameter() extensionReceiverParameter = descriptor.extensionReceiverParameter?.irValueParameter() - assert(valueParameters.isEmpty()) - descriptor.valueParameters.mapTo(valueParameters) { it.irValueParameter() } + if (!overwriteValueParameters) + assert(valueParameters.isEmpty()) + else + valueParameters.clear() + valueParameters.addAll(descriptor.valueParameters.map { it.irValueParameter() }) assert(typeParameters.isEmpty()) copyTypeParamsFromDescriptor() @@ -524,7 +531,7 @@ interface IrBuilderExtension { val serializable = getSerializableClassDescriptorBySerializer(serializerClass) val ctor = if (serializable?.declaredTypeParameters?.isNotEmpty() == true) { requireNotNull( - KSerializerDescriptorResolver.findSerializerConstructorForTypeArgumentsSerializers(serializerClass) + findSerializerConstructorForTypeArgumentsSerializers(serializerClass) ) { "Generated serializer does not have constructor with required number of arguments" } .let { compilerContext.externalSymbols.referenceConstructor(it) } } else { @@ -537,5 +544,5 @@ interface IrBuilderExtension { } fun IrClass.serializableSyntheticConstructor(): IrConstructorSymbol = - this.constructors.single { it.origin == SERIALIZABLE_PLUGIN_ORIGIN }.symbol + this.constructors.single { it.descriptor.isSerializationCtor() }.symbol } diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializableCompanionIrGenerator.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializableCompanionIrGenerator.kt index e85c65b562f..2fd98978173 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializableCompanionIrGenerator.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializableCompanionIrGenerator.kt @@ -58,7 +58,7 @@ class SerializableCompanionIrGenerator( } else -> { val desc = requireNotNull( - KSerializerDescriptorResolver.findSerializerConstructorForTypeArgumentsSerializers(serializer) + findSerializerConstructorForTypeArgumentsSerializers(serializer) ) { "Generated serializer does not have constructor with required number of arguments" } val ctor = compilerContext.externalSymbols.referenceConstructor(desc) val typeArgs = getter.typeParameters.map { it.defaultType } 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 ef2f3becf2d..1869159bcd1 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 @@ -38,7 +38,7 @@ class SerializableIrGenerator( get() = _table override fun generateInternalConstructor(constructorDescriptor: ClassConstructorDescriptor) = - irClass.contributeConstructor(constructorDescriptor) { ctor -> + irClass.contributeConstructor(constructorDescriptor, fromStubs = true, overwriteValueParameters = true) { ctor -> val transformFieldInitializer = buildInitializersRemapping(irClass) // Missing field exception parts diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/JsCodegenUtil.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/JsCodegenUtil.kt index d9792eaa8a9..d99452959ee 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/JsCodegenUtil.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/JsCodegenUtil.kt @@ -158,7 +158,7 @@ internal fun SerializerJsTranslator.serializerInstance( val serializable = getSerializableClassDescriptorBySerializer(serializerClass) val ref = if (serializable?.declaredTypeParameters?.isNotEmpty() == true) { val desc = requireNotNull( - KSerializerDescriptorResolver.findSerializerConstructorForTypeArgumentsSerializers(serializerClass) + findSerializerConstructorForTypeArgumentsSerializers(serializerClass) ) { "Generated serializer does not have constructor with required number of arguments" } if (!desc.isPrimary) JsInvocation(context.getInnerReference(desc), args) diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/SerializableCompanionJsTranslator.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/SerializableCompanionJsTranslator.kt index e5283d0f10d..7459e809c5d 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/SerializableCompanionJsTranslator.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/SerializableCompanionJsTranslator.kt @@ -46,7 +46,7 @@ class SerializableCompanionJsTranslator( val args = jsFun.parameters.map { JsNameRef(it.name) } val ref = context.getInnerNameForDescriptor( requireNotNull( - KSerializerDescriptorResolver.findSerializerConstructorForTypeArgumentsSerializers(serializer) + findSerializerConstructorForTypeArgumentsSerializers(serializer) ) { "Generated serializer does not have constructor with required number of arguments" }) JsInvocation(ref.makeRef(), args) } diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationResolveExtension.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationResolveExtension.kt index ec5cb42b7f6..553c5fe1d1a 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationResolveExtension.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationResolveExtension.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlinx.serialization.compiler.extensions +import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor @@ -69,6 +70,16 @@ open class SerializationResolveExtension : SyntheticResolveExtension { KSerializerDescriptorResolver.addSerializerSupertypes(thisDescriptor, supertypes) } + override fun generateSyntheticSecondaryConstructors( + thisDescriptor: ClassDescriptor, + bindingContext: BindingContext, + result: MutableCollection + ) { + if (thisDescriptor.isInternalSerializable) { + result.add(KSerializerDescriptorResolver.createLoadConstructorDescriptor(thisDescriptor, bindingContext)) + } + } + override fun generateSyntheticMethods( thisDescriptor: ClassDescriptor, name: Name, 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 971c03f1efc..2e782af7bed 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 @@ -18,13 +18,9 @@ package org.jetbrains.kotlinx.serialization.compiler.resolve import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.descriptors.annotations.Annotated import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.psi.ValueArgument -import org.jetbrains.kotlin.resolve.constants.KClassValue import org.jetbrains.kotlin.resolve.descriptorUtil.classId import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyAnnotationDescriptor @@ -37,7 +33,6 @@ 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 -import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationPackages.packageFqName internal fun isAllowedToHaveAutoGeneratedSerializerMethods( classDescriptor: ClassDescriptor, @@ -219,59 +214,3 @@ internal fun ClassDescriptor.checkLoadMethodParameters(parameters: List Annotations.findAnnotationConstantValue(annotationFqName: FqName, property: String): R? = - findAnnotation(annotationFqName)?.let { annotation -> - annotation.allValueArguments.entries.singleOrNull { it.key.asString() == property }?.value?.value - } as? R - -internal fun Annotations.findAnnotationKotlinTypeValue( - annotationFqName: FqName, - moduleForResolve: ModuleDescriptor, - property: String -): KotlinType? = - findAnnotation(annotationFqName)?.let { annotation -> - val maybeKClass = annotation.allValueArguments.entries.singleOrNull { it.key.asString() == property }?.value as? KClassValue - maybeKClass?.getArgumentType(moduleForResolve) - } - -// Search utils - -internal fun ClassDescriptor.getKSerializerConstructorMarker(): ClassDescriptor = - module.findClassAcrossModuleDependencies(ClassId(packageFqName, SerialEntityNames.SERIAL_CTOR_MARKER_NAME))!! - -internal fun ModuleDescriptor.getClassFromInternalSerializationPackage(classSimpleName: String) = - getFromPackage(SerializationPackages.internalPackageFqName, classSimpleName) - -internal fun ModuleDescriptor.getClassFromSerializationPackage(classSimpleName: String) = - getFromPackage(SerializationPackages.packageFqName, classSimpleName) - -private fun ModuleDescriptor.getFromPackage(packageFqName: FqName, classSimpleName: String) = requireNotNull( - findClassAcrossModuleDependencies( - ClassId( - packageFqName, - Name.identifier(classSimpleName) - ) - ) -) { "Can't locate class $classSimpleName from package $packageFqName" } - -internal fun ClassDescriptor.getClassFromSerializationPackage(classSimpleName: String) = - requireNotNull(module.findClassAcrossModuleDependencies(ClassId(packageFqName, Name.identifier(classSimpleName)))) {"Can't locate class $classSimpleName"} - -internal fun ClassDescriptor.getClassFromInternalSerializationPackage(classSimpleName: String) = - module.getClassFromInternalSerializationPackage(classSimpleName) - -fun ClassDescriptor.toSimpleType(nullable: Boolean = true) = KotlinTypeFactory.simpleType(Annotations.EMPTY, this.typeConstructor, emptyList(), nullable) - -internal fun Annotated.annotationsWithArguments(): List, List>> = - annotations.asSequence() - .filter { it.type.toClassDescriptor?.isSerialInfoAnnotation == true } - .filterIsInstance() - .mapNotNull { annDesc -> - annDesc.type.toClassDescriptor?.let { - Triple(it, annDesc.annotationEntry.valueArguments, it.unsubstitutedPrimaryConstructor?.valueParameters.orEmpty()) - } - } - .toList() 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 e9890e93f32..f4166779043 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 @@ -18,8 +18,10 @@ package org.jetbrains.kotlinx.serialization.compiler.resolve import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl import org.jetbrains.kotlin.descriptors.annotations.Annotations +import org.jetbrains.kotlin.descriptors.annotations.createDeprecatedAnnotation import org.jetbrains.kotlin.descriptors.impl.* import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.name.ClassId @@ -47,6 +49,10 @@ import java.util.* object KSerializerDescriptorResolver { + private fun createDeprecatedHiddenAnnotation(module: ModuleDescriptor): AnnotationDescriptor { + return module.builtIns.createDeprecatedAnnotation("This synthesized declaration should not be used directly", level = "HIDDEN") + } + fun isSerialInfoImpl(thisDescriptor: ClassDescriptor): Boolean { return thisDescriptor.name == IMPL_NAME && thisDescriptor.containingDeclaration is LazyClassDescriptor @@ -92,6 +98,7 @@ object KSerializerDescriptorResolver { scope, Modality.FINAL, Visibilities.PUBLIC, + Annotations.create(listOf(createDeprecatedHiddenAnnotation(interfaceDesc.module))), primaryCtorVisibility, ClassKind.CLASS, false @@ -114,7 +121,9 @@ object KSerializerDescriptorResolver { thisDeclaration, thisDescriptor, SERIALIZER_CLASS_NAME, thisDescriptor.source, scope, - Modality.FINAL, Visibilities.PUBLIC, Visibilities.PRIVATE, + Modality.FINAL, Visibilities.PUBLIC, + Annotations.create(listOf(createDeprecatedHiddenAnnotation(thisDescriptor.module))), + Visibilities.PRIVATE, serializerKind, false ) val typeParameters: List = @@ -276,9 +285,9 @@ object KSerializerDescriptorResolver { val functionDescriptor = ClassConstructorDescriptorImpl.createSynthesized( classDescriptor, - Annotations.EMPTY, + Annotations.create(listOf(createDeprecatedHiddenAnnotation(classDescriptor.module))), false, - classDescriptor.source + SourceElement.NO_SOURCE ) val markerDesc = classDescriptor.getKSerializerConstructorMarker() @@ -314,29 +323,13 @@ object KSerializerDescriptorResolver { functionDescriptor.initialize( consParams, - Visibilities.PUBLIC + Visibilities.INTERNAL ) functionDescriptor.returnType = classDescriptor.defaultType return functionDescriptor } - // finds constructor (KSerializer, KSerializer...) on a KSerializer> - fun findSerializerConstructorForTypeArgumentsSerializers( - serializerDescriptor: ClassDescriptor, - onlyIfSynthetic: Boolean = false - ): ClassConstructorDescriptor? { - val serializableImplementationTypeArguments = extractKSerializerArgumentFromImplementation(serializerDescriptor)?.arguments - ?: throw AssertionError("Serializer does not implement KSerializer??") - - val typeParamsCount = serializableImplementationTypeArguments.size - if (typeParamsCount == 0) return null //don't need it - val ctor = serializerDescriptor.constructors.find { ctor -> - ctor.valueParameters.size == typeParamsCount && ctor.valueParameters.all { isKSerializer(it.type) } - } - return if (!onlyIfSynthetic) ctor else ctor?.takeIf { it.kind == CallableMemberDescriptor.Kind.SYNTHESIZED } - } - private fun createTypedSerializerConstructorDescriptor( classDescriptor: ClassDescriptor, serializableDescriptor: ClassDescriptor, @@ -344,7 +337,7 @@ object KSerializerDescriptorResolver { ): ClassConstructorDescriptor { val constrDesc = ClassConstructorDescriptorImpl.createSynthesized( classDescriptor, - Annotations.EMPTY, + Annotations.create(listOf(createDeprecatedHiddenAnnotation(classDescriptor.module))), false, classDescriptor.source ) @@ -437,8 +430,8 @@ object KSerializerDescriptorResolver { private fun KotlinType.makeNullableIfNotPrimitive() = - if (KotlinBuiltIns.isPrimitiveType(this)) this - else this.makeNullable() + if (KotlinBuiltIns.isPrimitiveType(this)) this + else this.makeNullable() fun createWriteSelfFunctionDescriptor(thisClass: ClassDescriptor): FunctionDescriptor { val jvmStaticClass = thisClass.module.findClassAcrossModuleDependencies( diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/SearchUtils.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/SearchUtils.kt new file mode 100644 index 00000000000..4dc008087b2 --- /dev/null +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/SearchUtils.kt @@ -0,0 +1,98 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. 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.resolve + +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.annotations.Annotated +import org.jetbrains.kotlin.descriptors.annotations.Annotations +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.psi.ValueArgument +import org.jetbrains.kotlin.resolve.constants.KClassValue +import org.jetbrains.kotlin.resolve.descriptorUtil.module +import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyAnnotationDescriptor +import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.KotlinTypeFactory + +internal fun ClassConstructorDescriptor.isSerializationCtor(): Boolean = + kind == CallableMemberDescriptor.Kind.SYNTHESIZED && valueParameters.lastOrNull()?.name == SerialEntityNames.dummyParamName + +// finds constructor (KSerializer, KSerializer...) on a KSerializer> +internal fun findSerializerConstructorForTypeArgumentsSerializers( + serializerDescriptor: ClassDescriptor, + onlyIfSynthetic: Boolean = false +): ClassConstructorDescriptor? { + val serializableImplementationTypeArguments = extractKSerializerArgumentFromImplementation(serializerDescriptor)?.arguments + ?: throw AssertionError("Serializer does not implement KSerializer??") + + val typeParamsCount = serializableImplementationTypeArguments.size + if (typeParamsCount == 0) return null //don't need it + val ctor = serializerDescriptor.constructors.find { ctor -> + ctor.valueParameters.size == typeParamsCount && ctor.valueParameters.all { isKSerializer(it.type) } + } + return if (!onlyIfSynthetic) ctor else ctor?.takeIf { it.kind == CallableMemberDescriptor.Kind.SYNTHESIZED } +} + +inline fun Annotations.findAnnotationConstantValue(annotationFqName: FqName, property: String): R? = + findAnnotation(annotationFqName)?.let { annotation -> + annotation.allValueArguments.entries.singleOrNull { it.key.asString() == property }?.value?.value + } as? R + +internal fun Annotations.findAnnotationKotlinTypeValue( + annotationFqName: FqName, + moduleForResolve: ModuleDescriptor, + property: String +): KotlinType? = + findAnnotation(annotationFqName)?.let { annotation -> + val maybeKClass = annotation.allValueArguments.entries.singleOrNull { it.key.asString() == property }?.value as? KClassValue + maybeKClass?.getArgumentType(moduleForResolve) + } + +internal fun ClassDescriptor.getKSerializerConstructorMarker(): ClassDescriptor = + module.findClassAcrossModuleDependencies(ClassId(SerializationPackages.packageFqName, SerialEntityNames.SERIAL_CTOR_MARKER_NAME))!! + +internal fun ModuleDescriptor.getClassFromInternalSerializationPackage(classSimpleName: String) = + getFromPackage(SerializationPackages.internalPackageFqName, classSimpleName) + +internal fun ModuleDescriptor.getClassFromSerializationPackage(classSimpleName: String) = + getFromPackage(SerializationPackages.packageFqName, classSimpleName) + +private fun ModuleDescriptor.getFromPackage(packageFqName: FqName, classSimpleName: String) = requireNotNull( + findClassAcrossModuleDependencies( + ClassId( + packageFqName, + Name.identifier(classSimpleName) + ) + ) +) { "Can't locate class $classSimpleName from package $packageFqName" } + +internal fun ClassDescriptor.getClassFromSerializationPackage(classSimpleName: String) = + requireNotNull( + module.findClassAcrossModuleDependencies( + ClassId( + SerializationPackages.packageFqName, + Name.identifier(classSimpleName) + ) + ) + ) { "Can't locate class $classSimpleName" } + +internal fun ClassDescriptor.getClassFromInternalSerializationPackage(classSimpleName: String) = + module.getClassFromInternalSerializationPackage(classSimpleName) + +fun ClassDescriptor.toSimpleType(nullable: Boolean = true) = + KotlinTypeFactory.simpleType(Annotations.EMPTY, this.typeConstructor, emptyList(), nullable) + +internal fun Annotated.annotationsWithArguments(): List, List>> = + annotations.asSequence() + .filter { it.type.toClassDescriptor?.isSerialInfoAnnotation == true } + .filterIsInstance() + .mapNotNull { annDesc -> + annDesc.type.toClassDescriptor?.let { + Triple(it, annDesc.annotationEntry.valueArguments, it.unsubstitutedPrimaryConstructor?.valueParameters.orEmpty()) + } + } + .toList()