Add synthetic constructors to class member scope, so they won't fly 'in the air' in the backends

This is required mainly for Native compiler since it wont't work correctly on descriptors that are not present in the class.
This commit is contained in:
Leonid Startsev
2019-04-03 14:31:47 +03:00
parent 406896eaf0
commit 6bec6e6905
16 changed files with 187 additions and 110 deletions
@@ -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),
@@ -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
@@ -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<ClassConstructorDescriptor>
) {
instances.forEach {
withLinkageErrorLogger(it) {
generateSyntheticSecondaryConstructors(
thisDescriptor,
bindingContext,
result
)
}
}
}
}
}
}
@@ -160,4 +173,11 @@ interface SyntheticResolveExtension {
result: MutableSet<PropertyDescriptor>
) {
}
fun generateSyntheticSecondaryConstructors(
thisDescriptor: ClassDescriptor,
bindingContext: BindingContext,
result: MutableCollection<ClassConstructorDescriptor>
) {
}
}
@@ -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;
}
@@ -415,7 +415,18 @@ open class LazyClassMemberScope(
}
private val secondaryConstructors: NotNullLazyValue<Collection<ClassConstructorDescriptor>> =
c.storageManager.createLazyValue { resolveSecondaryConstructors() }
c.storageManager.createLazyValue { doGetConstructors() }
private fun doGetConstructors(): Collection<ClassConstructorDescriptor> {
val result = mutableListOf<ClassConstructorDescriptor>()
result.addAll(resolveSecondaryConstructors())
addSyntheticSecondaryConstructors(result)
return result
}
private fun addSyntheticSecondaryConstructors(result: MutableCollection<ClassConstructorDescriptor>) {
c.syntheticResolveExtension.generateSyntheticSecondaryConstructors(thisDescriptor, trace.bindingContext, result)
}
fun getConstructors(): Collection<ClassConstructorDescriptor> {
val result = secondaryConstructors()
@@ -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) {
}
}
}
@@ -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,
@@ -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
}
@@ -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 }
@@ -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
@@ -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)
@@ -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)
}
@@ -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<ClassConstructorDescriptor>
) {
if (thisDescriptor.isInternalSerializable) {
result.add(KSerializerDescriptorResolver.createLoadConstructorDescriptor(thisDescriptor, bindingContext))
}
}
override fun generateSyntheticMethods(
thisDescriptor: ClassDescriptor,
name: Name,
@@ -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<ValuePar
internal fun ClassDescriptor.checkLoadMethodResult(type: KotlinType): Boolean =
getSerializableClassDescriptorBySerializer(this)?.defaultType == type
// ----------------
inline fun <reified R> 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<Triple<ClassDescriptor, List<ValueArgument>, List<ValueParameterDescriptor>>> =
annotations.asSequence()
.filter { it.type.toClassDescriptor?.isSerialInfoAnnotation == true }
.filterIsInstance<LazyAnnotationDescriptor>()
.mapNotNull { annDesc ->
annDesc.type.toClassDescriptor?.let {
Triple(it, annDesc.annotationEntry.valueArguments, it.unsubstitutedPrimaryConstructor?.valueParameters.orEmpty())
}
}
.toList()
@@ -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<TypeParameterDescriptor> =
@@ -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<T0>, KSerializer<T1>...) on a KSerializer<T<T0, T1...>>
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(
@@ -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<T0>, KSerializer<T1>...) on a KSerializer<T<T0, T1...>>
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 <reified R> 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<Triple<ClassDescriptor, List<ValueArgument>, List<ValueParameterDescriptor>>> =
annotations.asSequence()
.filter { it.type.toClassDescriptor?.isSerialInfoAnnotation == true }
.filterIsInstance<LazyAnnotationDescriptor>()
.mapNotNull { annDesc ->
annDesc.type.toClassDescriptor?.let {
Triple(it, annDesc.annotationEntry.valueArguments, it.unsubstitutedPrimaryConstructor?.valueParameters.orEmpty())
}
}
.toList()