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);
|
ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor, typeMapper);
|
||||||
|
|
||||||
KtSecondaryConstructor constructor = (KtSecondaryConstructor) descriptorToDeclaration(constructorDescriptor);
|
KtSecondaryConstructor constructor = (KtSecondaryConstructor) descriptorToDeclaration(constructorDescriptor);
|
||||||
|
// Synthetic constructors don't have corresponding declarations
|
||||||
|
if (constructor == null) return;
|
||||||
|
|
||||||
functionCodegen.generateMethod(
|
functionCodegen.generateMethod(
|
||||||
JvmDeclarationOriginKt.OtherOrigin(constructor, constructorDescriptor),
|
JvmDeclarationOriginKt.OtherOrigin(constructor, constructorDescriptor),
|
||||||
|
|||||||
+1
-2
@@ -44,6 +44,7 @@ class SyntheticClassOrObjectDescriptor(
|
|||||||
outerScope: LexicalScope,
|
outerScope: LexicalScope,
|
||||||
private val modality: Modality,
|
private val modality: Modality,
|
||||||
private val visibility: Visibility,
|
private val visibility: Visibility,
|
||||||
|
override val annotations: Annotations,
|
||||||
constructorVisibility: Visibility,
|
constructorVisibility: Visibility,
|
||||||
private val kind: ClassKind,
|
private val kind: ClassKind,
|
||||||
private val isCompanionObject: Boolean
|
private val isCompanionObject: Boolean
|
||||||
@@ -71,8 +72,6 @@ class SyntheticClassOrObjectDescriptor(
|
|||||||
this.typeParameters = typeParameters
|
this.typeParameters = typeParameters
|
||||||
}
|
}
|
||||||
|
|
||||||
override val annotations: Annotations get() = Annotations.EMPTY
|
|
||||||
|
|
||||||
override fun getModality() = modality
|
override fun getModality() = modality
|
||||||
override fun getVisibility() = visibility
|
override fun getVisibility() = visibility
|
||||||
override fun getKind() = kind
|
override fun getKind() = kind
|
||||||
|
|||||||
+24
-4
@@ -17,10 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.resolve.extensions
|
package org.jetbrains.kotlin.resolve.extensions
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
|
||||||
import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor
|
import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
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>
|
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,
|
/* parentClassOrObject= */ classOrObject,
|
||||||
this, syntheticCompanionName, getSource(),
|
this, syntheticCompanionName, getSource(),
|
||||||
/* outerScope= */ getOuterScope(),
|
/* outerScope= */ getOuterScope(),
|
||||||
Modality.FINAL, PUBLIC, PRIVATE, ClassKind.OBJECT, true);
|
Modality.FINAL, PUBLIC, Annotations.Companion.getEMPTY(), PRIVATE, ClassKind.OBJECT, true);
|
||||||
companionDescriptor.initialize();
|
companionDescriptor.initialize();
|
||||||
return companionDescriptor;
|
return companionDescriptor;
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-1
@@ -415,7 +415,18 @@ open class LazyClassMemberScope(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val secondaryConstructors: NotNullLazyValue<Collection<ClassConstructorDescriptor>> =
|
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> {
|
fun getConstructors(): Collection<ClassConstructorDescriptor> {
|
||||||
val result = secondaryConstructors()
|
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.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.KSerializerDescriptorResolver
|
import org.jetbrains.kotlin.resolve.descriptorUtil.secondaryConstructors
|
||||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializableProperties
|
import org.jetbrains.kotlinx.serialization.compiler.resolve.*
|
||||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.classSerializer
|
|
||||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.isAbstractSerializableClass
|
|
||||||
|
|
||||||
abstract class SerializableCodegen(
|
abstract class SerializableCodegen(
|
||||||
protected val serializableDescriptor: ClassDescriptor,
|
protected val serializableDescriptor: ClassDescriptor,
|
||||||
@@ -39,7 +37,7 @@ abstract class SerializableCodegen(
|
|||||||
private fun generateSyntheticInternalConstructor() {
|
private fun generateSyntheticInternalConstructor() {
|
||||||
val serializerDescriptor = serializableDescriptor.classSerializer ?: return
|
val serializerDescriptor = serializableDescriptor.classSerializer ?: return
|
||||||
if (isAbstractSerializableClass(serializableDescriptor) || SerializerCodegen.getSyntheticLoadMember(serializerDescriptor) != null) {
|
if (isAbstractSerializableClass(serializableDescriptor) || SerializerCodegen.getSyntheticLoadMember(serializerDescriptor) != null) {
|
||||||
val constrDesc = KSerializerDescriptorResolver.createLoadConstructorDescriptor(serializableDescriptor, bindingContext)
|
val constrDesc = serializableDescriptor.secondaryConstructors.find(ClassConstructorDescriptor::isSerializationCtor) ?: return
|
||||||
generateInternalConstructor(constrDesc)
|
generateInternalConstructor(constrDesc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -57,4 +55,4 @@ abstract class SerializableCodegen(
|
|||||||
protected open fun generateWriteSelfMethod(methodDescriptor: FunctionDescriptor) {
|
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.descriptorUtil.fqNameUnsafe
|
||||||
import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
|
import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
|
||||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.*
|
import org.jetbrains.kotlinx.serialization.compiler.resolve.*
|
||||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.KSerializerDescriptorResolver.findSerializerConstructorForTypeArgumentsSerializers
|
|
||||||
|
|
||||||
abstract class SerializerCodegen(
|
abstract class SerializerCodegen(
|
||||||
protected val serializerDescriptor: ClassDescriptor,
|
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.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.*
|
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.IrSimpleTypeImpl
|
||||||
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
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.ir.util.*
|
||||||
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
|
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
@@ -77,6 +80,7 @@ interface IrBuilderExtension {
|
|||||||
fun IrClass.contributeConstructor(
|
fun IrClass.contributeConstructor(
|
||||||
descriptor: ClassConstructorDescriptor,
|
descriptor: ClassConstructorDescriptor,
|
||||||
fromStubs: Boolean = false,
|
fromStubs: Boolean = false,
|
||||||
|
overwriteValueParameters: Boolean = false,
|
||||||
bodyGen: IrBlockBodyBuilder.(IrConstructor) -> Unit
|
bodyGen: IrBlockBodyBuilder.(IrConstructor) -> Unit
|
||||||
) {
|
) {
|
||||||
val c = if (!fromStubs) compilerContext.localSymbolTable.declareConstructor(
|
val c = if (!fromStubs) compilerContext.localSymbolTable.declareConstructor(
|
||||||
@@ -87,7 +91,7 @@ interface IrBuilderExtension {
|
|||||||
) else compilerContext.externalSymbols.referenceConstructor(descriptor).owner
|
) else compilerContext.externalSymbols.referenceConstructor(descriptor).owner
|
||||||
c.parent = this
|
c.parent = this
|
||||||
c.returnType = descriptor.returnType.toIrType()
|
c.returnType = descriptor.returnType.toIrType()
|
||||||
if (!fromStubs) c.createParameterDeclarations(receiver = null)
|
if (!fromStubs || overwriteValueParameters) c.createParameterDeclarations(receiver = null, overwriteValueParameters = overwriteValueParameters)
|
||||||
if (c.typeParameters.isEmpty()) {
|
if (c.typeParameters.isEmpty()) {
|
||||||
c.copyTypeParamsFromDescriptor()
|
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(
|
fun ParameterDescriptor.irValueParameter() = IrValueParameterImpl(
|
||||||
this@createParameterDeclarations.startOffset, this@createParameterDeclarations.endOffset,
|
this@createParameterDeclarations.startOffset, this@createParameterDeclarations.endOffset,
|
||||||
SERIALIZABLE_PLUGIN_ORIGIN,
|
SERIALIZABLE_PLUGIN_ORIGIN,
|
||||||
@@ -360,8 +364,11 @@ interface IrBuilderExtension {
|
|||||||
dispatchReceiverParameter = descriptor.dispatchReceiverParameter?.irValueParameter()
|
dispatchReceiverParameter = descriptor.dispatchReceiverParameter?.irValueParameter()
|
||||||
extensionReceiverParameter = descriptor.extensionReceiverParameter?.irValueParameter()
|
extensionReceiverParameter = descriptor.extensionReceiverParameter?.irValueParameter()
|
||||||
|
|
||||||
assert(valueParameters.isEmpty())
|
if (!overwriteValueParameters)
|
||||||
descriptor.valueParameters.mapTo(valueParameters) { it.irValueParameter() }
|
assert(valueParameters.isEmpty())
|
||||||
|
else
|
||||||
|
valueParameters.clear()
|
||||||
|
valueParameters.addAll(descriptor.valueParameters.map { it.irValueParameter() })
|
||||||
|
|
||||||
assert(typeParameters.isEmpty())
|
assert(typeParameters.isEmpty())
|
||||||
copyTypeParamsFromDescriptor()
|
copyTypeParamsFromDescriptor()
|
||||||
@@ -524,7 +531,7 @@ interface IrBuilderExtension {
|
|||||||
val serializable = getSerializableClassDescriptorBySerializer(serializerClass)
|
val serializable = getSerializableClassDescriptorBySerializer(serializerClass)
|
||||||
val ctor = if (serializable?.declaredTypeParameters?.isNotEmpty() == true) {
|
val ctor = if (serializable?.declaredTypeParameters?.isNotEmpty() == true) {
|
||||||
requireNotNull(
|
requireNotNull(
|
||||||
KSerializerDescriptorResolver.findSerializerConstructorForTypeArgumentsSerializers(serializerClass)
|
findSerializerConstructorForTypeArgumentsSerializers(serializerClass)
|
||||||
) { "Generated serializer does not have constructor with required number of arguments" }
|
) { "Generated serializer does not have constructor with required number of arguments" }
|
||||||
.let { compilerContext.externalSymbols.referenceConstructor(it) }
|
.let { compilerContext.externalSymbols.referenceConstructor(it) }
|
||||||
} else {
|
} else {
|
||||||
@@ -537,5 +544,5 @@ interface IrBuilderExtension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun IrClass.serializableSyntheticConstructor(): IrConstructorSymbol =
|
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 -> {
|
else -> {
|
||||||
val desc = requireNotNull(
|
val desc = requireNotNull(
|
||||||
KSerializerDescriptorResolver.findSerializerConstructorForTypeArgumentsSerializers(serializer)
|
findSerializerConstructorForTypeArgumentsSerializers(serializer)
|
||||||
) { "Generated serializer does not have constructor with required number of arguments" }
|
) { "Generated serializer does not have constructor with required number of arguments" }
|
||||||
val ctor = compilerContext.externalSymbols.referenceConstructor(desc)
|
val ctor = compilerContext.externalSymbols.referenceConstructor(desc)
|
||||||
val typeArgs = getter.typeParameters.map { it.defaultType }
|
val typeArgs = getter.typeParameters.map { it.defaultType }
|
||||||
|
|||||||
+1
-1
@@ -38,7 +38,7 @@ class SerializableIrGenerator(
|
|||||||
get() = _table
|
get() = _table
|
||||||
|
|
||||||
override fun generateInternalConstructor(constructorDescriptor: ClassConstructorDescriptor) =
|
override fun generateInternalConstructor(constructorDescriptor: ClassConstructorDescriptor) =
|
||||||
irClass.contributeConstructor(constructorDescriptor) { ctor ->
|
irClass.contributeConstructor(constructorDescriptor, fromStubs = true, overwriteValueParameters = true) { ctor ->
|
||||||
val transformFieldInitializer = buildInitializersRemapping(irClass)
|
val transformFieldInitializer = buildInitializersRemapping(irClass)
|
||||||
|
|
||||||
// Missing field exception parts
|
// Missing field exception parts
|
||||||
|
|||||||
+1
-1
@@ -158,7 +158,7 @@ internal fun SerializerJsTranslator.serializerInstance(
|
|||||||
val serializable = getSerializableClassDescriptorBySerializer(serializerClass)
|
val serializable = getSerializableClassDescriptorBySerializer(serializerClass)
|
||||||
val ref = if (serializable?.declaredTypeParameters?.isNotEmpty() == true) {
|
val ref = if (serializable?.declaredTypeParameters?.isNotEmpty() == true) {
|
||||||
val desc = requireNotNull(
|
val desc = requireNotNull(
|
||||||
KSerializerDescriptorResolver.findSerializerConstructorForTypeArgumentsSerializers(serializerClass)
|
findSerializerConstructorForTypeArgumentsSerializers(serializerClass)
|
||||||
) { "Generated serializer does not have constructor with required number of arguments" }
|
) { "Generated serializer does not have constructor with required number of arguments" }
|
||||||
if (!desc.isPrimary)
|
if (!desc.isPrimary)
|
||||||
JsInvocation(context.getInnerReference(desc), args)
|
JsInvocation(context.getInnerReference(desc), args)
|
||||||
|
|||||||
+1
-1
@@ -46,7 +46,7 @@ class SerializableCompanionJsTranslator(
|
|||||||
val args = jsFun.parameters.map { JsNameRef(it.name) }
|
val args = jsFun.parameters.map { JsNameRef(it.name) }
|
||||||
val ref = context.getInnerNameForDescriptor(
|
val ref = context.getInnerNameForDescriptor(
|
||||||
requireNotNull(
|
requireNotNull(
|
||||||
KSerializerDescriptorResolver.findSerializerConstructorForTypeArgumentsSerializers(serializer)
|
findSerializerConstructorForTypeArgumentsSerializers(serializer)
|
||||||
) { "Generated serializer does not have constructor with required number of arguments" })
|
) { "Generated serializer does not have constructor with required number of arguments" })
|
||||||
JsInvocation(ref.makeRef(), args)
|
JsInvocation(ref.makeRef(), args)
|
||||||
}
|
}
|
||||||
|
|||||||
+11
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlinx.serialization.compiler.extensions
|
package org.jetbrains.kotlinx.serialization.compiler.extensions
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
||||||
@@ -69,6 +70,16 @@ open class SerializationResolveExtension : SyntheticResolveExtension {
|
|||||||
KSerializerDescriptorResolver.addSerializerSupertypes(thisDescriptor, supertypes)
|
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(
|
override fun generateSyntheticMethods(
|
||||||
thisDescriptor: ClassDescriptor,
|
thisDescriptor: ClassDescriptor,
|
||||||
name: Name,
|
name: Name,
|
||||||
|
|||||||
-61
@@ -18,13 +18,9 @@ package org.jetbrains.kotlinx.serialization.compiler.resolve
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotated
|
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
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.classId
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||||
import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyAnnotationDescriptor
|
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.backend.jvm.polymorphicSerializerId
|
||||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.KSERIALIZER_CLASS
|
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.SerializationAnnotations.serialInfoFqName
|
||||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationPackages.packageFqName
|
|
||||||
|
|
||||||
internal fun isAllowedToHaveAutoGeneratedSerializerMethods(
|
internal fun isAllowedToHaveAutoGeneratedSerializerMethods(
|
||||||
classDescriptor: ClassDescriptor,
|
classDescriptor: ClassDescriptor,
|
||||||
@@ -219,59 +214,3 @@ internal fun ClassDescriptor.checkLoadMethodParameters(parameters: List<ValuePar
|
|||||||
|
|
||||||
internal fun ClassDescriptor.checkLoadMethodResult(type: KotlinType): Boolean =
|
internal fun ClassDescriptor.checkLoadMethodResult(type: KotlinType): Boolean =
|
||||||
getSerializableClassDescriptorBySerializer(this)?.defaultType == type
|
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.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
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.AnnotationDescriptorImpl
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.createDeprecatedAnnotation
|
||||||
import org.jetbrains.kotlin.descriptors.impl.*
|
import org.jetbrains.kotlin.descriptors.impl.*
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
@@ -47,6 +49,10 @@ import java.util.*
|
|||||||
|
|
||||||
object KSerializerDescriptorResolver {
|
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 {
|
fun isSerialInfoImpl(thisDescriptor: ClassDescriptor): Boolean {
|
||||||
return thisDescriptor.name == IMPL_NAME
|
return thisDescriptor.name == IMPL_NAME
|
||||||
&& thisDescriptor.containingDeclaration is LazyClassDescriptor
|
&& thisDescriptor.containingDeclaration is LazyClassDescriptor
|
||||||
@@ -92,6 +98,7 @@ object KSerializerDescriptorResolver {
|
|||||||
scope,
|
scope,
|
||||||
Modality.FINAL,
|
Modality.FINAL,
|
||||||
Visibilities.PUBLIC,
|
Visibilities.PUBLIC,
|
||||||
|
Annotations.create(listOf(createDeprecatedHiddenAnnotation(interfaceDesc.module))),
|
||||||
primaryCtorVisibility,
|
primaryCtorVisibility,
|
||||||
ClassKind.CLASS,
|
ClassKind.CLASS,
|
||||||
false
|
false
|
||||||
@@ -114,7 +121,9 @@ object KSerializerDescriptorResolver {
|
|||||||
thisDeclaration,
|
thisDeclaration,
|
||||||
thisDescriptor, SERIALIZER_CLASS_NAME, thisDescriptor.source,
|
thisDescriptor, SERIALIZER_CLASS_NAME, thisDescriptor.source,
|
||||||
scope,
|
scope,
|
||||||
Modality.FINAL, Visibilities.PUBLIC, Visibilities.PRIVATE,
|
Modality.FINAL, Visibilities.PUBLIC,
|
||||||
|
Annotations.create(listOf(createDeprecatedHiddenAnnotation(thisDescriptor.module))),
|
||||||
|
Visibilities.PRIVATE,
|
||||||
serializerKind, false
|
serializerKind, false
|
||||||
)
|
)
|
||||||
val typeParameters: List<TypeParameterDescriptor> =
|
val typeParameters: List<TypeParameterDescriptor> =
|
||||||
@@ -276,9 +285,9 @@ object KSerializerDescriptorResolver {
|
|||||||
|
|
||||||
val functionDescriptor = ClassConstructorDescriptorImpl.createSynthesized(
|
val functionDescriptor = ClassConstructorDescriptorImpl.createSynthesized(
|
||||||
classDescriptor,
|
classDescriptor,
|
||||||
Annotations.EMPTY,
|
Annotations.create(listOf(createDeprecatedHiddenAnnotation(classDescriptor.module))),
|
||||||
false,
|
false,
|
||||||
classDescriptor.source
|
SourceElement.NO_SOURCE
|
||||||
)
|
)
|
||||||
|
|
||||||
val markerDesc = classDescriptor.getKSerializerConstructorMarker()
|
val markerDesc = classDescriptor.getKSerializerConstructorMarker()
|
||||||
@@ -314,29 +323,13 @@ object KSerializerDescriptorResolver {
|
|||||||
|
|
||||||
functionDescriptor.initialize(
|
functionDescriptor.initialize(
|
||||||
consParams,
|
consParams,
|
||||||
Visibilities.PUBLIC
|
Visibilities.INTERNAL
|
||||||
)
|
)
|
||||||
|
|
||||||
functionDescriptor.returnType = classDescriptor.defaultType
|
functionDescriptor.returnType = classDescriptor.defaultType
|
||||||
return functionDescriptor
|
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(
|
private fun createTypedSerializerConstructorDescriptor(
|
||||||
classDescriptor: ClassDescriptor,
|
classDescriptor: ClassDescriptor,
|
||||||
serializableDescriptor: ClassDescriptor,
|
serializableDescriptor: ClassDescriptor,
|
||||||
@@ -344,7 +337,7 @@ object KSerializerDescriptorResolver {
|
|||||||
): ClassConstructorDescriptor {
|
): ClassConstructorDescriptor {
|
||||||
val constrDesc = ClassConstructorDescriptorImpl.createSynthesized(
|
val constrDesc = ClassConstructorDescriptorImpl.createSynthesized(
|
||||||
classDescriptor,
|
classDescriptor,
|
||||||
Annotations.EMPTY,
|
Annotations.create(listOf(createDeprecatedHiddenAnnotation(classDescriptor.module))),
|
||||||
false,
|
false,
|
||||||
classDescriptor.source
|
classDescriptor.source
|
||||||
)
|
)
|
||||||
@@ -437,8 +430,8 @@ object KSerializerDescriptorResolver {
|
|||||||
|
|
||||||
|
|
||||||
private fun KotlinType.makeNullableIfNotPrimitive() =
|
private fun KotlinType.makeNullableIfNotPrimitive() =
|
||||||
if (KotlinBuiltIns.isPrimitiveType(this)) this
|
if (KotlinBuiltIns.isPrimitiveType(this)) this
|
||||||
else this.makeNullable()
|
else this.makeNullable()
|
||||||
|
|
||||||
fun createWriteSelfFunctionDescriptor(thisClass: ClassDescriptor): FunctionDescriptor {
|
fun createWriteSelfFunctionDescriptor(thisClass: ClassDescriptor): FunctionDescriptor {
|
||||||
val jvmStaticClass = thisClass.module.findClassAcrossModuleDependencies(
|
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