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:
@@ -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),
|
||||
|
||||
+1
-2
@@ -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
|
||||
|
||||
+24
-4
@@ -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>
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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;
|
||||
}
|
||||
|
||||
+12
-1
@@ -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()
|
||||
|
||||
+4
-6
@@ -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) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-1
@@ -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,
|
||||
|
||||
+14
-7
@@ -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
|
||||
}
|
||||
|
||||
+1
-1
@@ -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 }
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
+1
-1
@@ -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)
|
||||
}
|
||||
|
||||
+11
@@ -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,
|
||||
|
||||
-61
@@ -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()
|
||||
|
||||
+16
-23
@@ -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(
|
||||
|
||||
+98
@@ -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()
|
||||
Reference in New Issue
Block a user