diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirFictitiousFunctionClassifiers.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirFictitiousFunctionClassifiers.kt index b5ee79c58b2..61b2c2671e6 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirFictitiousFunctionClassifiers.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirFictitiousFunctionClassifiers.kt @@ -19,7 +19,7 @@ object CirFictitiousFunctionClassifiers : CirProvidedClassifiers { private val FUNCTION_PREFIXES = arrayOf("Function", "SuspendFunction") private val PACKAGE_NAME = CirPackageName.create("kotlin") - private val classifiers: Map = THashMap().apply { + private val classifiers: Map = THashMap().apply { (MIN_ARITY..MAX_ARITY).forEach { arity -> FUNCTION_PREFIXES.forEach { prefix -> buildFictitiousFunctionClass(prefix, arity, this::set) @@ -28,9 +28,9 @@ object CirFictitiousFunctionClassifiers : CirProvidedClassifiers { } override fun hasClassifier(classifierId: CirEntityId) = classifierId in classifiers - override fun classifier(classifierId: CirEntityId): CirProvided.Class? = classifiers[classifierId] + override fun classifier(classifierId: CirEntityId): CirProvided.RegularClass? = classifiers[classifierId] - private inline fun buildFictitiousFunctionClass(prefix: String, arity: Int, consumer: (CirEntityId, CirProvided.Class) -> Unit) { + private inline fun buildFictitiousFunctionClass(prefix: String, arity: Int, consumer: (CirEntityId, CirProvided.RegularClass) -> Unit) { val typeParameters = List(arity + 1) { index -> CirProvided.TypeParameter( index = index, @@ -39,7 +39,7 @@ object CirFictitiousFunctionClassifiers : CirProvidedClassifiers { } val classId = CirEntityId.create(PACKAGE_NAME, CirName.create("$prefix$arity")) - val clazz = CirProvided.Class(typeParameters, Visibilities.Public) + val clazz = CirProvided.RegularClass(typeParameters, Visibilities.Public) consumer(classId, clazz) } diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirProvidedClassifiers.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirProvidedClassifiers.kt index 6fb130027a8..71e75af8e84 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirProvidedClassifiers.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirProvidedClassifiers.kt @@ -5,9 +5,11 @@ package org.jetbrains.kotlin.descriptors.commonizer.mergedtree +import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.descriptors.commonizer.ModulesProvider import org.jetbrains.kotlin.descriptors.commonizer.cir.CirEntityId +import org.jetbrains.kotlin.descriptors.commonizer.utils.isUnderKotlinNativeSyntheticPackages import org.jetbrains.kotlin.types.Variance /** A set of classes and type aliases provided by libraries (either the libraries to commonize, or their dependency libraries)/ */ @@ -59,10 +61,23 @@ object CirProvided { val typeParameters: List } - data class Class( - override val typeParameters: List, + sealed interface Class : Classifier { val visibility: Visibility - ) : Classifier + } + + data class RegularClass( + override val typeParameters: List, + override val visibility: Visibility + ) : Class + + data class ExportedForwardDeclarationClass(val syntheticClassId: CirEntityId) : Class { + init { + check(syntheticClassId.packageName.isUnderKotlinNativeSyntheticPackages) + } + + override val typeParameters: List get() = emptyList() + override val visibility: Visibility get() = Visibilities.Public + } data class TypeAlias( override val typeParameters: List, diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirProvidedClassifiersByModules.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirProvidedClassifiersByModules.kt index e43708bfe60..e6d0448771f 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirProvidedClassifiersByModules.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirProvidedClassifiersByModules.kt @@ -9,6 +9,7 @@ import com.intellij.util.containers.FactoryMap import gnu.trove.THashMap import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.commonizer.ModulesProvider +import org.jetbrains.kotlin.descriptors.commonizer.ModulesProvider.CInteropModuleAttributes import org.jetbrains.kotlin.descriptors.commonizer.cir.CirEntityId import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName import org.jetbrains.kotlin.descriptors.commonizer.cir.CirPackageName @@ -47,9 +48,10 @@ internal class CirProvidedClassifiersByModules private constructor( var hasForwardDeclarations = false modulesProvider.loadModuleInfos().forEach { moduleInfo -> - if (moduleInfo.cInteropAttributes != null) { + moduleInfo.cInteropAttributes?.let { cInteropAttributes -> // this is a C-interop module hasForwardDeclarations = true + readExportedForwardDeclarations(cInteropAttributes, classifiers::set) } val metadata = modulesProvider.loadModuleMetadata(moduleInfo.name) @@ -62,7 +64,28 @@ internal class CirProvidedClassifiersByModules private constructor( return CirProvidedClassifiersByModules(hasForwardDeclarations, classifiers) } - private val FALLBACK_FORWARD_DECLARATION_CLASS = CirProvided.Class(emptyList(), Visibilities.Public) + private val FALLBACK_FORWARD_DECLARATION_CLASS = CirProvided.RegularClass(emptyList(), Visibilities.Public) + } +} + +private fun readExportedForwardDeclarations( + cInteropAttributes: CInteropModuleAttributes, + consumer: (CirEntityId, CirProvided.Classifier) -> Unit +) { + val exportedForwardDeclarations = cInteropAttributes.exportedForwardDeclarations + if (exportedForwardDeclarations.isEmpty()) return + + val mainPackageName = CirPackageName.create(cInteropAttributes.mainPackage) + + exportedForwardDeclarations.forEach { classFqName -> + // Class has synthetic package FQ name (cnames/objcnames). Need to transfer it to the main package. + val syntheticPackageName = CirPackageName.create(classFqName.substringBeforeLast('.', missingDelimiterValue = "")) + val className = CirName.create(classFqName.substringAfterLast('.')) + + val syntheticClassId = CirEntityId.create(syntheticPackageName, className) + val aliasedClassId = CirEntityId.create(mainPackageName, className) + + consumer(aliasedClassId, CirProvided.ExportedForwardDeclarationClass(syntheticClassId)) } } diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/metadata/CirDeserializers.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/metadata/CirDeserializers.kt index f45cb5327f8..d408c9cae90 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/metadata/CirDeserializers.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/metadata/CirDeserializers.kt @@ -27,7 +27,7 @@ object CirDeserializers { private fun annotation(source: KmAnnotation, typeResolver: CirTypeResolver): CirAnnotation { val classId = CirEntityId.create(source.className) - val clazz: CirProvided.Class = typeResolver.resolveClassifier(classId) + val clazz: CirProvided.RegularClass = typeResolver.resolveClassifier(classId) val type = CirClassType.createInterned( classId = classId, @@ -352,7 +352,7 @@ object CirDeserializers { val clazz: CirProvided.Class = typeResolver.resolveClassifier(classId) CirClassType.createInterned( - classId = classId, + classId = (clazz as? CirProvided.ExportedForwardDeclarationClass)?.syntheticClassId ?: classId, outerType = outerType, visibility = clazz.visibility, arguments = arguments(source.arguments, typeResolver),