diff --git a/native/base/src/main/kotlin/org/jetbrains/kotlin/backend/konan/InlineClasses.kt b/native/base/src/main/kotlin/org/jetbrains/kotlin/backend/konan/InlineClasses.kt index fc5bcb11aea..bb8e4c5695d 100644 --- a/native/base/src/main/kotlin/org/jetbrains/kotlin/backend/konan/InlineClasses.kt +++ b/native/base/src/main/kotlin/org/jetbrains/kotlin/backend/konan/InlineClasses.kt @@ -29,9 +29,9 @@ fun KotlinType.binaryRepresentationIsNullable() = KotlinTypeInlineClassesSupport @InternalKotlinNativeApi inline fun KotlinType.unwrapToPrimitiveOrReference( - eachInlinedClass: (inlinedClass: ClassDescriptor, nullable: Boolean) -> Unit, - ifPrimitive: (primitiveType: KonanPrimitiveType, nullable: Boolean) -> R, - ifReference: (type: KotlinType) -> R + eachInlinedClass: (inlinedClass: ClassDescriptor, nullable: Boolean) -> Unit, + ifPrimitive: (primitiveType: KonanPrimitiveType, nullable: Boolean) -> R, + ifReference: (type: KotlinType) -> R, ): R = KotlinTypeInlineClassesSupport.unwrapToPrimitiveOrReference(this, eachInlinedClass, ifPrimitive, ifReference) @@ -39,7 +39,7 @@ inline fun KotlinType.unwrapToPrimitiveOrReference( fun KotlinType.binaryTypeIsReference(): Boolean = this.computePrimitiveBinaryTypeOrNull() == null fun KotlinType.computePrimitiveBinaryTypeOrNull(): PrimitiveBinaryType? = - this.computeBinaryType().primitiveBinaryTypeOrNull() + this.computeBinaryType().primitiveBinaryTypeOrNull() fun KotlinType.computeBinaryType(): BinaryType = KotlinTypeInlineClassesSupport.computeBinaryType(this) @@ -74,9 +74,9 @@ enum class KonanPrimitiveType(val classId: ClassId, val binaryType: BinaryType.P assert(!it.classId.isNestedClass) it.classId.packageFqName }.fold({ _, _ -> mutableMapOf() }, - { _, accumulator, element -> - accumulator.also { it[element.classId.shortClassName] = element } - }) + { _, accumulator, element -> + accumulator.also { it[element.classId.shortClassName] = element } + }) } } @@ -84,12 +84,14 @@ enum class KonanPrimitiveType(val classId: ClassId, val binaryType: BinaryType.P abstract class InlineClassesSupport { @InternalKotlinNativeApi abstract fun isNullable(type: Type): Boolean + @InternalKotlinNativeApi abstract fun makeNullable(type: Type): Type protected abstract fun erase(type: Type): Class protected abstract fun computeFullErasure(type: Type): Sequence protected abstract fun hasInlineModifier(clazz: Class): Boolean protected abstract fun getNativePointedSuperclass(clazz: Class): Class? + @InternalKotlinNativeApi abstract fun getInlinedClassUnderlyingType(clazz: Class): Type protected abstract fun getPackageFqName(clazz: Class): FqName? @@ -103,19 +105,20 @@ abstract class InlineClassesSupport { fun isUsedAsBoxClass(clazz: Class) = getInlinedClass(clazz) == clazz // To handle NativePointed subclasses. fun getInlinedClass(type: Type): Class? = - getInlinedClass(erase(type), isNullable(type)) + getInlinedClass(erase(type), isNullable(type)) @InternalKotlinNativeApi fun getKonanPrimitiveType(clazz: Class): KonanPrimitiveType? = - if (isTopLevelClass(clazz)) - KonanPrimitiveType.byFqNameParts[getPackageFqName(clazz)]?.get(getName(clazz)) - else null + if (isTopLevelClass(clazz)) + KonanPrimitiveType.byFqNameParts[getPackageFqName(clazz)]?.get(getName(clazz)) + else null @InternalKotlinNativeApi fun isImplicitInlineClass(clazz: Class): Boolean = - isTopLevelClass(clazz) && (getKonanPrimitiveType(clazz) != null || - getName(clazz) == KonanFqNames.nativePtr.shortName() && getPackageFqName(clazz) == KonanFqNames.internalPackageName || - getName(clazz) == InteropFqNames.cPointer.shortName() && getPackageFqName(clazz) == InteropFqNames.cPointer.parent().toSafe()) + isTopLevelClass(clazz) && (getKonanPrimitiveType(clazz) != null || + getName(clazz) == KonanFqNames.nativePtr.shortName() && getPackageFqName(clazz) == KonanFqNames.internalPackageName || + getName(clazz) == InteropFqNames.cPointer.shortName() && getPackageFqName(clazz) == InteropFqNames.cPointer.parent() + .toSafe()) private fun getInlinedClass(erased: Class, isNullable: Boolean): Class? { val inlinedClass = getInlinedClass(erased) ?: return null @@ -144,17 +147,17 @@ abstract class InlineClassesSupport { @JvmName("classGetInlinedClass") private fun getInlinedClass(clazz: Class): Class? = - if (hasInlineModifier(clazz) || isImplicitInlineClass(clazz)) { - clazz - } else { - getNativePointedSuperclass(clazz) - } + if (hasInlineModifier(clazz) || isImplicitInlineClass(clazz)) { + clazz + } else { + getNativePointedSuperclass(clazz) + } inline fun unwrapToPrimitiveOrReference( - type: Type, - eachInlinedClass: (inlinedClass: Class, nullable: Boolean) -> Unit, - ifPrimitive: (primitiveType: KonanPrimitiveType, nullable: Boolean) -> R, - ifReference: (type: Type) -> R + type: Type, + eachInlinedClass: (inlinedClass: Class, nullable: Boolean) -> Unit, + ifPrimitive: (primitiveType: KonanPrimitiveType, nullable: Boolean) -> R, + ifReference: (type: Type) -> R, ): R { var currentType: Type = type @@ -179,10 +182,10 @@ abstract class InlineClassesSupport { fun representationIsNullable(type: Type): Boolean { unwrapToPrimitiveOrReference( - type, - eachInlinedClass = { _, nullable -> if (nullable) return true }, - ifPrimitive = { _, nullable -> return nullable }, - ifReference = { return isNullable(it) } + type, + eachInlinedClass = { _, nullable -> if (nullable) return true }, + ifPrimitive = { _, nullable -> return nullable }, + ifReference = { return isNullable(it) } ) } @@ -204,7 +207,7 @@ abstract class InlineClassesSupport { } private fun createReferenceBinaryType(type: Type): BinaryType.Reference = - BinaryType.Reference(computeFullErasure(type), true) + BinaryType.Reference(computeFullErasure(type), true) } @InternalKotlinNativeApi @@ -230,16 +233,16 @@ object KotlinTypeInlineClassesSupport : InlineClassesSupport { fun getSubPackages(fqName: FqName) { result.add(fqName) val subPackages = packageFragmentProvider?.getSubPackagesOf(fqName) { true } - ?: module.getSubPackagesOf(fqName) { true } + ?: module.getSubPackagesOf(fqName) { true } subPackages.forEach { getSubPackages(it) } } @@ -120,16 +120,16 @@ private fun getPackagesFqNames(module: ModuleDescriptor): Set { } fun ModuleDescriptor.getPackageFragments(): List = - getPackagesFqNames(this).flatMap { - getPackage(it).fragments.filter { it.module == this }.toSet() - } + getPackagesFqNames(this).flatMap { + getPackage(it).fragments.filter { it.module == this }.toSet() + } val ClassDescriptor.enumEntries: List get() { assert(this.kind == ClassKind.ENUM_CLASS) return this.unsubstitutedMemberScope.getContributedDescriptors() - .filterIsInstance() - .filter { it.kind == ClassKind.ENUM_ENTRY } + .filterIsInstance() + .filter { it.kind == ClassKind.ENUM_ENTRY } } @InternalKotlinNativeApi @@ -138,27 +138,27 @@ val DeclarationDescriptor.isExpectMember: Boolean @InternalKotlinNativeApi val arrayTypes = setOf( - "kotlin.Array", - "kotlin.ByteArray", - "kotlin.CharArray", - "kotlin.ShortArray", - "kotlin.IntArray", - "kotlin.LongArray", - "kotlin.FloatArray", - "kotlin.DoubleArray", - "kotlin.BooleanArray", - "kotlin.native.ImmutableBlob", - "kotlin.native.internal.NativePtrArray" + "kotlin.Array", + "kotlin.ByteArray", + "kotlin.CharArray", + "kotlin.ShortArray", + "kotlin.IntArray", + "kotlin.LongArray", + "kotlin.FloatArray", + "kotlin.DoubleArray", + "kotlin.BooleanArray", + "kotlin.native.ImmutableBlob", + "kotlin.native.internal.NativePtrArray" ) @InternalKotlinNativeApi val arraysWithFixedSizeItems = setOf( - "kotlin.ByteArray", - "kotlin.CharArray", - "kotlin.ShortArray", - "kotlin.IntArray", - "kotlin.LongArray", - "kotlin.FloatArray", - "kotlin.DoubleArray", - "kotlin.BooleanArray" + "kotlin.ByteArray", + "kotlin.CharArray", + "kotlin.ShortArray", + "kotlin.IntArray", + "kotlin.LongArray", + "kotlin.FloatArray", + "kotlin.DoubleArray", + "kotlin.BooleanArray" ) \ No newline at end of file diff --git a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/CustomTypeMapper.kt b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/CustomTypeMapper.kt index 89a3d750518..ad483f091de 100644 --- a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/CustomTypeMapper.kt +++ b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/CustomTypeMapper.kt @@ -18,14 +18,18 @@ import org.jetbrains.kotlin.types.TypeUtils @InternalKotlinNativeApi fun ClassDescriptor.isMappedFunctionClass() = - this.getFunctionTypeKind() == FunctionTypeKind.Function && - // Type parameters include return type. - declaredTypeParameters.size - 1 < CustomTypeMappers.functionTypeMappersArityLimit + this.getFunctionTypeKind() == FunctionTypeKind.Function && + // Type parameters include return type. + declaredTypeParameters.size - 1 < CustomTypeMappers.functionTypeMappersArityLimit @InternalKotlinNativeApi interface CustomTypeMapper { val mappedClassId: ClassId - fun mapType(mappedSuperType: KotlinType, translator: ObjCExportTranslatorImpl, objCExportScope: ObjCExportScope): ObjCNonNullReferenceType + fun mapType( + mappedSuperType: KotlinType, + translator: ObjCExportTranslatorImpl, + objCExportScope: ObjCExportScope, + ): ObjCNonNullReferenceType } internal object CustomTypeMappers { @@ -89,44 +93,52 @@ internal object CustomTypeMappers { * Note: can be generated programmatically, but requires stdlib in this case. */ val hiddenTypes: Set = listOf( - "kotlin.Any", - "kotlin.CharSequence", - "kotlin.Comparable", - "kotlin.Function", - "kotlin.Number", - "kotlin.collections.Collection", - "kotlin.collections.Iterable", - "kotlin.collections.MutableCollection", - "kotlin.collections.MutableIterable" + "kotlin.Any", + "kotlin.CharSequence", + "kotlin.Comparable", + "kotlin.Function", + "kotlin.Number", + "kotlin.collections.Collection", + "kotlin.collections.Iterable", + "kotlin.collections.MutableCollection", + "kotlin.collections.MutableIterable" ).map { ClassId.topLevel(FqName(it)) }.toSet() private class Simple( - override val mappedClassId: ClassId, - private val getObjCClassName: ObjCExportTranslatorImpl.() -> String + override val mappedClassId: ClassId, + private val getObjCClassName: ObjCExportTranslatorImpl.() -> String, ) : CustomTypeMapper { constructor( - mappedClassId: ClassId, - objCClassName: String + mappedClassId: ClassId, + objCClassName: String, ) : this(mappedClassId, { objCClassName }) - override fun mapType(mappedSuperType: KotlinType, translator: ObjCExportTranslatorImpl, objCExportScope: ObjCExportScope): ObjCNonNullReferenceType = - ObjCClassType(translator.getObjCClassName()) + override fun mapType( + mappedSuperType: KotlinType, + translator: ObjCExportTranslatorImpl, + objCExportScope: ObjCExportScope, + ): ObjCNonNullReferenceType = + ObjCClassType(translator.getObjCClassName()) } private class Collection( - mappedClassFqName: FqName, - private val getObjCClassName: ObjCExportTranslatorImpl.() -> String + mappedClassFqName: FqName, + private val getObjCClassName: ObjCExportTranslatorImpl.() -> String, ) : CustomTypeMapper { constructor( - mappedClassFqName: FqName, - objCClassName: String + mappedClassFqName: FqName, + objCClassName: String, ) : this(mappedClassFqName, { objCClassName }) override val mappedClassId = ClassId.topLevel(mappedClassFqName) - override fun mapType(mappedSuperType: KotlinType, translator: ObjCExportTranslatorImpl, objCExportScope: ObjCExportScope): ObjCNonNullReferenceType { + override fun mapType( + mappedSuperType: KotlinType, + translator: ObjCExportTranslatorImpl, + objCExportScope: ObjCExportScope, + ): ObjCNonNullReferenceType { val typeArguments = mappedSuperType.arguments.map { val argument = it.type if (TypeUtils.isNullableType(argument)) { @@ -145,7 +157,11 @@ internal object CustomTypeMappers { override val mappedClassId: ClassId get() = StandardNames.getFunctionClassId(parameterCount) - override fun mapType(mappedSuperType: KotlinType, translator: ObjCExportTranslatorImpl, objCExportScope: ObjCExportScope): ObjCNonNullReferenceType { + override fun mapType( + mappedSuperType: KotlinType, + translator: ObjCExportTranslatorImpl, + objCExportScope: ObjCExportScope, + ): ObjCNonNullReferenceType { return translator.mapFunctionTypeIgnoringNullability(mappedSuperType, objCExportScope, returnsVoid = false) } } diff --git a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/MainPackageGuesser.kt b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/MainPackageGuesser.kt index 8a3d0d0c881..26c7859b39b 100644 --- a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/MainPackageGuesser.kt +++ b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/MainPackageGuesser.kt @@ -18,14 +18,14 @@ import org.jetbrains.kotlin.name.isSubpackageOf @InternalKotlinNativeApi class MainPackageGuesser { fun guess( - moduleDescriptor: ModuleDescriptor, - includedLibraryDescriptors: List, - exportedDependencies: List, + moduleDescriptor: ModuleDescriptor, + includedLibraryDescriptors: List, + exportedDependencies: List, ): FqName { // Consider exported libraries only if we cannot infer the package from sources or included libs. return guessMainPackage(includedLibraryDescriptors + moduleDescriptor) - ?: guessMainPackage(exportedDependencies) - ?: FqName.ROOT + ?: guessMainPackage(exportedDependencies) + ?: FqName.ROOT } private fun guessMainPackage(modules: List): FqName? { @@ -38,12 +38,12 @@ class MainPackageGuesser { } val nonEmptyPackages = allPackages - .filter { it.getMemberScope().getContributedDescriptors().isNotEmpty() } - .map { it.fqName }.distinct() + .filter { it.getMemberScope().getContributedDescriptors().isNotEmpty() } + .map { it.fqName }.distinct() return allPackages.map { it.fqName }.distinct() - .filter { candidate -> nonEmptyPackages.all { it.isSubpackageOf(candidate) } } - // Now there are all common ancestors of non-empty packages. Longest of them is the least common accessor: - .maxByOrNull { it.asString().length } + .filter { candidate -> nonEmptyPackages.all { it.isSubpackageOf(candidate) } } + // Now there are all common ancestors of non-empty packages. Longest of them is the least common accessor: + .maxByOrNull { it.asString().length } } } \ No newline at end of file diff --git a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/MethodBridge.kt b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/MethodBridge.kt index 4101bbd772b..f9adaa0bb67 100644 --- a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/MethodBridge.kt +++ b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/MethodBridge.kt @@ -9,9 +9,6 @@ import org.jetbrains.kotlin.backend.common.descriptors.allParameters import org.jetbrains.kotlin.backend.konan.InternalKotlinNativeApi import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.ParameterDescriptor -import org.jetbrains.kotlin.ir.declarations.IrFunction -import org.jetbrains.kotlin.ir.declarations.IrValueParameter -import org.jetbrains.kotlin.ir.util.allParameters @InternalKotlinNativeApi sealed class TypeBridge @@ -21,8 +18,8 @@ object ReferenceBridge : TypeBridge() @InternalKotlinNativeApi data class BlockPointerBridge( - val numberOfParameters: Int, - val returnsVoid: Boolean + val numberOfParameters: Int, + val returnsVoid: Boolean, ) : TypeBridge() @InternalKotlinNativeApi @@ -50,9 +47,9 @@ sealed class MethodBridgeValueParameter : MethodBridgeParameter() { @InternalKotlinNativeApi data class MethodBridge( - val returnBridge: ReturnValue, - val receiver: MethodBridgeReceiver, - val valueParameters: List + val returnBridge: ReturnValue, + val receiver: MethodBridgeReceiver, + val valueParameters: List, ) { sealed class ReturnValue { @@ -73,15 +70,17 @@ data class MethodBridge( } val paramBridges: List = - listOf(receiver) + MethodBridgeSelector + valueParameters + listOf(receiver) + MethodBridgeSelector + valueParameters // TODO: it is not exactly true in potential future cases. - val isInstance: Boolean get() = when (receiver) { - MethodBridgeReceiver.Static, - MethodBridgeReceiver.Factory -> false + val isInstance: Boolean + get() = when (receiver) { + MethodBridgeReceiver.Static, + MethodBridgeReceiver.Factory, + -> false - MethodBridgeReceiver.Instance -> true - } + MethodBridgeReceiver.Instance -> true + } val returnsError: Boolean get() = returnBridge is ReturnValue.WithError @@ -89,7 +88,7 @@ data class MethodBridge( @InternalKotlinNativeApi fun MethodBridge.valueParametersAssociated( - descriptor: FunctionDescriptor + descriptor: FunctionDescriptor, ): List> { val kotlinParameters = descriptor.allParameters.iterator() val skipFirstKotlinParameter = when (this.receiver) { @@ -105,7 +104,8 @@ fun MethodBridge.valueParametersAssociated( is MethodBridgeValueParameter.Mapped -> it to kotlinParameters.next() is MethodBridgeValueParameter.SuspendCompletion, - is MethodBridgeValueParameter.ErrorOutParameter -> it to null + is MethodBridgeValueParameter.ErrorOutParameter, + -> it to null } }.also { assert(!kotlinParameters.hasNext()) } } diff --git a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGenerator.kt b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGenerator.kt index 595ea199538..c8fb407befb 100644 --- a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGenerator.kt +++ b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGenerator.kt @@ -7,7 +7,10 @@ package org.jetbrains.kotlin.backend.konan.objcexport import org.jetbrains.kotlin.backend.common.serialization.findSourceFile import org.jetbrains.kotlin.backend.konan.* -import org.jetbrains.kotlin.backend.konan.descriptors.* +import org.jetbrains.kotlin.backend.konan.descriptors.enumEntries +import org.jetbrains.kotlin.backend.konan.descriptors.getPackageFragments +import org.jetbrains.kotlin.backend.konan.descriptors.isArray +import org.jetbrains.kotlin.backend.konan.descriptors.isInterface import org.jetbrains.kotlin.backend.konan.serialization.KonanManglerDesc import org.jetbrains.kotlin.builtins.* import org.jetbrains.kotlin.builtins.KotlinBuiltIns.isAny @@ -22,9 +25,9 @@ import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue import org.jetbrains.kotlin.resolve.descriptorUtil.* import org.jetbrains.kotlin.resolve.scopes.MemberScope -import org.jetbrains.kotlin.types.error.ErrorUtils import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils +import org.jetbrains.kotlin.types.error.ErrorUtils import org.jetbrains.kotlin.types.typeUtil.builtIns import org.jetbrains.kotlin.types.typeUtil.isInterface import org.jetbrains.kotlin.types.typeUtil.isTypeParameter @@ -58,7 +61,7 @@ class ObjCExportTranslatorImpl( val mapper: ObjCExportMapper, val namer: ObjCExportNamer, val problemCollector: ObjCExportProblemCollector, - val objcGenerics: Boolean + val objcGenerics: Boolean, ) : ObjCExportTranslator { private val kotlinAnyName = namer.kotlinAnyName @@ -75,9 +78,9 @@ class ObjCExportTranslatorImpl( // TODO: add comment to the header. add { ObjCInterfaceImpl( - namer.kotlinAnyName.objCName, - superProtocols = listOf("NSCopying"), - categoryName = "${namer.kotlinAnyName.objCName}Copying" + namer.kotlinAnyName.objCName, + superProtocols = listOf("NSCopying"), + categoryName = "${namer.kotlinAnyName.objCName}Copying" ) } @@ -85,10 +88,10 @@ class ObjCExportTranslatorImpl( add { val generics = listOf("ObjectType") objCInterface( - namer.mutableSetName, - generics = generics, - superClass = "NSMutableSet", - superClassGenerics = generics + namer.mutableSetName, + generics = generics, + superClass = "NSMutableSet", + superClassGenerics = generics ) } @@ -96,10 +99,10 @@ class ObjCExportTranslatorImpl( add { val generics = listOf("KeyType", "ObjectType") objCInterface( - namer.mutableMapName, - generics = generics, - superClass = "NSMutableDictionary", - superClassGenerics = generics + namer.mutableMapName, + generics = generics, + superClass = "NSMutableDictionary", + superClassGenerics = generics ) } @@ -124,9 +127,9 @@ class ObjCExportTranslatorImpl( } add { objCInterface( - namer.kotlinNumberName, - superClass = "NSNumber", - members = members + namer.kotlinNumberName, + superClass = "NSNumber", + members = members ) } @@ -145,50 +148,50 @@ class ObjCExportTranslatorImpl( add { nsNumberInit(kind) } } return objCInterface( - name, - superClass = namer.kotlinNumberName.objCName, - members = members + name, + superClass = namer.kotlinNumberName.objCName, + members = members ) } private fun nsNumberInit(kind: NSNumberKind, attributes: List = emptyList()): ObjCMethod { return ObjCMethod( - null, - false, - ObjCInstanceType, - listOf(kind.factorySelector), - listOf(ObjCParameter("value", null, kind.objCType)), - attributes + null, + false, + ObjCInstanceType, + listOf(kind.factorySelector), + listOf(ObjCParameter("value", null, kind.objCType)), + attributes ) } private fun nsNumberFactory(kind: NSNumberKind, attributes: List = emptyList()): ObjCMethod { return ObjCMethod( - null, - true, - ObjCInstanceType, - listOf(kind.initSelector), - listOf(ObjCParameter("value", null, kind.objCType)), - attributes + null, + true, + ObjCInstanceType, + listOf(kind.initSelector), + listOf(ObjCParameter("value", null, kind.objCType)), + attributes ) } override fun getClassIfExtension(receiverType: KotlinType): ClassDescriptor? = - mapper.getClassIfCategory(receiverType) + mapper.getClassIfCategory(receiverType) internal fun translateUnexposedClassAsUnavailableStub(descriptor: ClassDescriptor): ObjCInterface = objCInterface( - namer.getClassOrProtocolName(descriptor), - descriptor = descriptor, - superClass = "NSObject", - attributes = attributesForUnexposed(descriptor) + namer.getClassOrProtocolName(descriptor), + descriptor = descriptor, + superClass = "NSObject", + attributes = attributesForUnexposed(descriptor) ) internal fun translateUnexposedInterfaceAsUnavailableStub(descriptor: ClassDescriptor): ObjCProtocol = objCProtocol( - namer.getClassOrProtocolName(descriptor), - descriptor = descriptor, - superProtocols = emptyList(), - members = emptyList(), - attributes = attributesForUnexposed(descriptor) + namer.getClassOrProtocolName(descriptor), + descriptor = descriptor, + superProtocols = emptyList(), + members = emptyList(), + attributes = attributesForUnexposed(descriptor) ) private fun attributesForUnexposed(descriptor: ClassDescriptor): List { @@ -247,17 +250,17 @@ class ObjCExportTranslatorImpl( private val ClassDescriptor.superProtocols: List get() = getSuperInterfaces() - .asSequence() - .filter { mapper.shouldBeExposed(it) } - .map { - generator?.generateExtraInterfaceEarly(it) - referenceProtocol(it).objCName - } - .toList() + .asSequence() + .filter { mapper.shouldBeExposed(it) } + .map { + generator?.generateExtraInterfaceEarly(it) + referenceProtocol(it).objCName + } + .toList() override fun translateExtensions( - classDescriptor: ClassDescriptor, - declarations: List + classDescriptor: ClassDescriptor, + declarations: List, ): ObjCInterface { generator?.generateExtraClassEarly(classDescriptor) @@ -276,10 +279,10 @@ class ObjCExportTranslatorImpl( translatePlainMembers(declarations, ObjCRootExportScope) } return objCInterface( - name, - superClass = namer.kotlinAnyName.objCName, - members = members, - attributes = listOf(OBJC_SUBCLASSING_RESTRICTED) + name, + superClass = namer.kotlinAnyName.objCName, + members = members, + attributes = listOf(OBJC_SUBCLASSING_RESTRICTED) ) } @@ -316,20 +319,22 @@ class ObjCExportTranslatorImpl( val presentConstructors = mutableSetOf() descriptor.constructors - .makeMethodsOrderStable() - .asSequence() - .filter { mapper.shouldBeExposed(it) } - .forEach { - val selector = getSelector(it) - if (!descriptor.isArray) presentConstructors += selector + .makeMethodsOrderStable() + .asSequence() + .filter { mapper.shouldBeExposed(it) } + .forEach { + val selector = getSelector(it) + if (!descriptor.isArray) presentConstructors += selector - add { buildMethod(it, it, genericExportScope) } - exportThrown(it) - if (selector == "init") add { - ObjCMethod(it, false, ObjCInstanceType, listOf("new"), emptyList(), - listOf("availability(swift, unavailable, message=\"use object initializers instead\")")) - } + add { buildMethod(it, it, genericExportScope) } + exportThrown(it) + if (selector == "init") add { + ObjCMethod( + it, false, ObjCInstanceType, listOf("new"), emptyList(), + listOf("availability(swift, unavailable, message=\"use object initializers instead\")") + ) } + } if (descriptor.isArray || descriptor.kind == ClassKind.OBJECT || descriptor.kind == ClassKind.ENUM_CLASS) { add { ObjCMethod(null, false, ObjCInstanceType, listOf("alloc"), emptyList(), listOf("unavailable")) } @@ -340,30 +345,30 @@ class ObjCExportTranslatorImpl( // Hide "unimplemented" super constructors: superClass?.constructors - ?.makeMethodsOrderStable() - ?.asSequence() - ?.filter { mapper.shouldBeExposed(it) } - ?.forEach { - val selector = getSelector(it) - if (selector !in presentConstructors) { - add { buildMethod(it, it, ObjCRootExportScope, unavailable = true) } + ?.makeMethodsOrderStable() + ?.asSequence() + ?.filter { mapper.shouldBeExposed(it) } + ?.forEach { + val selector = getSelector(it) + if (selector !in presentConstructors) { + add { buildMethod(it, it, ObjCRootExportScope, unavailable = true) } - if (selector == "init") { - add { ObjCMethod(null, false, ObjCInstanceType, listOf("new"), emptyList(), listOf("unavailable")) } - } - - // TODO: consider adding exception-throwing impls for these. + if (selector == "init") { + add { ObjCMethod(null, false, ObjCInstanceType, listOf("new"), emptyList(), listOf("unavailable")) } } + + // TODO: consider adding exception-throwing impls for these. } + } if (descriptor.needCompanionObjectProperty(namer, mapper)) { add { ObjCProperty( - ObjCExportNamer.companionObjectPropertyName, null, - mapReferenceType(descriptor.companionObjectDescriptor!!.defaultType, genericExportScope), - listOf("class", "readonly"), - getterName = namer.getCompanionObjectPropertySelector(descriptor), - declarationAttributes = listOf(swiftNameAttribute(ObjCExportNamer.companionObjectPropertyName)) + ObjCExportNamer.companionObjectPropertyName, null, + mapReferenceType(descriptor.companionObjectDescriptor!!.defaultType, genericExportScope), + listOf("class", "readonly"), + getterName = namer.getCompanionObjectPropertySelector(descriptor), + declarationAttributes = listOf(swiftNameAttribute(ObjCExportNamer.companionObjectPropertyName)) ) } } @@ -372,17 +377,17 @@ class ObjCExportTranslatorImpl( ClassKind.OBJECT -> { add { ObjCMethod( - null, false, ObjCInstanceType, - listOf(namer.getObjectInstanceSelector(descriptor)), emptyList(), - listOf(swiftNameAttribute("init()")) + null, false, ObjCInstanceType, + listOf(namer.getObjectInstanceSelector(descriptor)), emptyList(), + listOf(swiftNameAttribute("init()")) ) } add { ObjCProperty( - ObjCExportNamer.objectPropertyName, null, - mapReferenceType(descriptor.defaultType, genericExportScope), listOf("class", "readonly"), - getterName = namer.getObjectPropertySelector(descriptor), - declarationAttributes = listOf(swiftNameAttribute(ObjCExportNamer.objectPropertyName)) + ObjCExportNamer.objectPropertyName, null, + mapReferenceType(descriptor.defaultType, genericExportScope), listOf("class", "readonly"), + getterName = namer.getObjectPropertySelector(descriptor), + declarationAttributes = listOf(swiftNameAttribute(ObjCExportNamer.objectPropertyName)) ) } } @@ -393,8 +398,10 @@ class ObjCExportTranslatorImpl( val entryName = namer.getEnumEntrySelector(it) val swiftName = namer.getEnumEntrySwiftName(it) add { - ObjCProperty(entryName, it, type, listOf("class", "readonly"), - declarationAttributes = listOf(swiftNameAttribute(swiftName))) + ObjCProperty( + entryName, it, type, listOf("class", "readonly"), + declarationAttributes = listOf(swiftNameAttribute(swiftName)) + ) } } @@ -428,15 +435,15 @@ class ObjCExportTranslatorImpl( val superClassGenerics = superClassGenerics(genericExportScope) return objCInterface( - name, - generics = generics, - descriptor = descriptor, - superClass = superName.objCName, - superClassGenerics = superClassGenerics, - superProtocols = superProtocols, - members = members, - attributes = attributes, - comment = objCCommentOrNull(mustBeDocumentedAttributeList(descriptor.annotations)) + name, + generics = generics, + descriptor = descriptor, + superClass = superName.objCName, + superClassGenerics = superClassGenerics, + superProtocols = superProtocols, + members = members, + attributes = attributes, + comment = objCCommentOrNull(mustBeDocumentedAttributeList(descriptor.annotations)) ) } @@ -449,12 +456,12 @@ class ObjCExportTranslatorImpl( private fun buildThrowableAsErrorMethod(): ObjCMethod { val asError = ObjCExportNamer.kotlinThrowableAsErrorMethodName return ObjCMethod( - descriptor = null, - isInstanceMethod = true, - returnType = ObjCClassType("NSError"), - selectors = listOf(asError), - parameters = emptyList(), - attributes = listOf(swiftNameAttribute("$asError()")) + descriptor = null, + isInstanceMethod = true, + returnType = ObjCClassType("NSError"), + selectors = listOf(asError), + parameters = emptyList(), + attributes = listOf(swiftNameAttribute("$asError()")) ) } @@ -468,40 +475,40 @@ class ObjCExportTranslatorImpl( } private fun buildEnumValuesMethod( - enumValues: SimpleFunctionDescriptor, - genericExportScope: ObjCExportScope + enumValues: SimpleFunctionDescriptor, + genericExportScope: ObjCExportScope, ): ObjCMethod { val selector = namer.getEnumStaticMemberSelector(enumValues) return ObjCMethod( - enumValues, - isInstanceMethod = false, - returnType = mapReferenceType(enumValues.returnType!!, genericExportScope), - selectors = splitSelector(selector), - parameters = emptyList(), - attributes = listOf(swiftNameAttribute("$selector()")) + enumValues, + isInstanceMethod = false, + returnType = mapReferenceType(enumValues.returnType!!, genericExportScope), + selectors = splitSelector(selector), + parameters = emptyList(), + attributes = listOf(swiftNameAttribute("$selector()")) ) } private fun buildEnumEntriesProperty( - enumEntries: PropertyDescriptor, - genericExportScope: ObjCExportScope + enumEntries: PropertyDescriptor, + genericExportScope: ObjCExportScope, ): ObjCProperty { val selector = namer.getEnumStaticMemberSelector(enumEntries) return ObjCProperty( - selector, - enumEntries, - type = mapReferenceType(enumEntries.type, genericExportScope), - propertyAttributes = listOf("class", "readonly"), - declarationAttributes = listOf(swiftNameAttribute(selector)) + selector, + enumEntries, + type = mapReferenceType(enumEntries.type, genericExportScope), + propertyAttributes = listOf("class", "readonly"), + declarationAttributes = listOf(swiftNameAttribute(selector)) ) } private fun ClassDescriptor.getExposedMembers(): List = - this.unsubstitutedMemberScope.getContributedDescriptors() - .asSequence() - .filterIsInstance() - .filter { mapper.shouldBeExposed(it) } - .toList() + this.unsubstitutedMemberScope.getContributedDescriptors() + .asSequence() + .filterIsInstance() + .filter { mapper.shouldBeExposed(it) } + .toList() private fun StubBuilder>.translateClassMembers(descriptor: ClassDescriptor, objCExportScope: ObjCExportScope) { require(!descriptor.isInterface) @@ -514,8 +521,8 @@ class ObjCExportTranslatorImpl( } private fun List.toObjCMembers( - methodsBuffer: MutableList, - propertiesBuffer: MutableList + methodsBuffer: MutableList, + propertiesBuffer: MutableList, ) = this.forEach { when (it) { is FunctionDescriptor -> methodsBuffer += it @@ -530,8 +537,8 @@ class ObjCExportTranslatorImpl( } private fun StubBuilder>.translateClassMembers( - members: List, - objCExportScope: ObjCExportScope + members: List, + objCExportScope: ObjCExportScope, ) { // TODO: add some marks about modality. @@ -547,18 +554,18 @@ class ObjCExportTranslatorImpl( methods.makeMethodsOrderStable().forEach { method -> mapper.getBaseMethods(method) - .makeMethodsOrderStable() - .asSequence() - .distinctBy { namer.getSelector(it) } - .forEach { base -> add { buildMethod(method, base, objCExportScope) } } + .makeMethodsOrderStable() + .asSequence() + .distinctBy { namer.getSelector(it) } + .forEach { base -> add { buildMethod(method, base, objCExportScope) } } } properties.makePropertiesOrderStable().forEach { property -> mapper.getBaseProperties(property) - .makePropertiesOrderStable() - .asSequence() - .distinctBy { namer.getPropertyName(it) } - .forEach { base -> add { buildProperty(property, base, objCExportScope) } } + .makePropertiesOrderStable() + .asSequence() + .distinctBy { namer.getPropertyName(it) } + .forEach { base -> add { buildProperty(property, base, objCExportScope) } } } } @@ -597,7 +604,11 @@ class ObjCExportTranslatorImpl( translatePlainMembers(methods, properties, objCExportScope) } - private fun StubBuilder>.translatePlainMembers(methods: List, properties: List, objCExportScope: ObjCExportScope) { + private fun StubBuilder>.translatePlainMembers( + methods: List, + properties: List, + objCExportScope: ObjCExportScope, + ) { methods.makeMethodsOrderStable().forEach { add { buildMethod(it, it, objCExportScope) } } properties.makePropertiesOrderStable().forEach { add { buildProperty(it, it, objCExportScope) } } } @@ -607,7 +618,11 @@ class ObjCExportTranslatorImpl( return namer.getSelector(method) } - private fun buildProperty(property: PropertyDescriptor, baseProperty: PropertyDescriptor, objCExportScope: ObjCExportScope): ObjCProperty { + private fun buildProperty( + property: PropertyDescriptor, + baseProperty: PropertyDescriptor, + objCExportScope: ObjCExportScope, + ): ObjCProperty { assert(mapper.isBaseProperty(baseProperty)) assert(mapper.isObjCProperty(baseProperty)) @@ -646,10 +661,10 @@ class ObjCExportTranslatorImpl( } internal fun buildMethod( - method: FunctionDescriptor, - baseMethod: FunctionDescriptor, - objCExportScope: ObjCExportScope, - unavailable: Boolean = false + method: FunctionDescriptor, + baseMethod: FunctionDescriptor, + objCExportScope: ObjCExportScope, + unavailable: Boolean = false, ): ObjCMethod { fun collectParameters(baseMethodBridge: MethodBridge, method: FunctionDescriptor): List { fun unifyName(initialName: String, usedNames: Set): String { @@ -698,11 +713,11 @@ class ObjCExportTranslatorImpl( } } ObjCBlockPointerType( - returnType = ObjCVoidType, - parameterTypes = listOfNotNull( - resultType, - ObjCNullableReferenceType(ObjCClassType("NSError")) - ) + returnType = ObjCVoidType, + parameterTypes = listOfNotNull( + resultType, + ObjCNullableReferenceType(ObjCClassType("NSError")) + ) ) } } @@ -726,7 +741,8 @@ class ObjCExportTranslatorImpl( attributes += method.getSwiftPrivateAttribute() ?: swiftNameAttribute(swiftName) if (baseMethodBridge.returnBridge is MethodBridge.ReturnValue.WithError.ZeroForError - && baseMethodBridge.returnBridge.successMayBeZero) { + && baseMethodBridge.returnBridge.successMayBeZero + ) { // Method may return zero on success, but // standard Objective-C convention doesn't suppose this happening. @@ -771,12 +787,12 @@ class ObjCExportTranslatorImpl( effectiveThrows.isNotEmpty() -> { listOf( - buildString { - append("@note This method converts instances of ") - effectiveThrows.joinTo(this) { it.relativeClassName.asString() } - append(" to errors.") - }, - "Other uncaught Kotlin exceptions are fatal." + buildString { + append("@note This method converts instances of ") + effectiveThrows.joinTo(this) { it.relativeClassName.asString() } + append(" to errors.") + }, + "Other uncaught Kotlin exceptions are fatal." ) } @@ -829,13 +845,15 @@ class ObjCExportTranslatorImpl( } } - private val mustBeDocumentedAnnotationsStopList = setOf(StandardNames.FqNames.deprecated, KonanFqNames.objCName, KonanFqNames.shouldRefineInSwift) + private val mustBeDocumentedAnnotationsStopList = + setOf(StandardNames.FqNames.deprecated, KonanFqNames.objCName, KonanFqNames.shouldRefineInSwift) + private fun mustBeDocumentedAnnotations(annotations: Annotations): List { return annotations.mapNotNull { it -> it.annotationClass?.let { annotationClass -> if (!mustBeDocumentedAnnotationsStopList.contains(annotationClass.fqNameSafe) && annotationClass.annotations.any { metaAnnotation -> - metaAnnotation.fqName == StandardNames.FqNames.mustBeDocumented - }) + metaAnnotation.fqName == StandardNames.FqNames.mustBeDocumented + }) renderAnnotation(it, annotationClass) else null } @@ -851,8 +869,8 @@ class ObjCExportTranslatorImpl( private fun exportThrown(method: FunctionDescriptor) { getDefinedThrows(method) - ?.mapNotNull { method.module.findClassAcrossModuleDependencies(it) } - ?.forEach { generator?.requireClassOrInterface(it) } + ?.mapNotNull { method.module.findClassAcrossModuleDependencies(it) } + ?.forEach { generator?.requireClassOrInterface(it) } } private fun getDefinedThrows(method: FunctionDescriptor): Sequence? { @@ -863,13 +881,13 @@ class ObjCExportTranslatorImpl( if (throwsAnnotation != null) { val argumentsArrayValue = throwsAnnotation.firstArgument() as? ArrayValue return argumentsArrayValue?.value?.asSequence().orEmpty() - .filterIsInstance() - .mapNotNull { - when (val value = it.value) { - is KClassValue.Value.NormalClass -> value.classId - is KClassValue.Value.LocalClass -> null - } + .filterIsInstance() + .mapNotNull { + when (val value = it.value) { + is KClassValue.Value.NormalClass -> value.classId + is KClassValue.Value.LocalClass -> null } + } } if (method.isSuspend && method.overriddenDescriptors.isEmpty()) { @@ -881,9 +899,14 @@ class ObjCExportTranslatorImpl( private val implicitSuspendThrows = sequenceOf(ClassId.topLevel(KonanFqNames.cancellationException)) - private fun mapReturnType(returnBridge: MethodBridge.ReturnValue, method: FunctionDescriptor, objCExportScope: ObjCExportScope): ObjCType = when (returnBridge) { + private fun mapReturnType( + returnBridge: MethodBridge.ReturnValue, + method: FunctionDescriptor, + objCExportScope: ObjCExportScope, + ): ObjCType = when (returnBridge) { MethodBridge.ReturnValue.Suspend, - MethodBridge.ReturnValue.Void -> ObjCVoidType + MethodBridge.ReturnValue.Void, + -> ObjCVoidType MethodBridge.ReturnValue.HashCode -> ObjCPrimitiveType.NSUInteger is MethodBridge.ReturnValue.Mapped -> mapType(method.returnType!!, returnBridge.bridge, objCExportScope) MethodBridge.ReturnValue.WithError.Success -> ObjCPrimitiveType.BOOL @@ -891,8 +914,10 @@ class ObjCExportTranslatorImpl( val successReturnType = mapReturnType(returnBridge.successBridge, method, objCExportScope) if (!returnBridge.successMayBeZero) { - check(successReturnType is ObjCNonNullReferenceType - || (successReturnType is ObjCPointerType && !successReturnType.nullable)) { + check( + successReturnType is ObjCNonNullReferenceType + || (successReturnType is ObjCPointerType && !successReturnType.nullable) + ) { "Unexpected return type: $successReturnType in $method" } } @@ -901,18 +926,19 @@ class ObjCExportTranslatorImpl( } MethodBridge.ReturnValue.Instance.InitResult, - MethodBridge.ReturnValue.Instance.FactoryResult -> ObjCInstanceType + MethodBridge.ReturnValue.Instance.FactoryResult, + -> ObjCInstanceType } internal fun mapReferenceType(kotlinType: KotlinType, objCExportScope: ObjCExportScope): ObjCReferenceType = - mapReferenceTypeIgnoringNullability(kotlinType, objCExportScope).withNullabilityOf(kotlinType) + mapReferenceTypeIgnoringNullability(kotlinType, objCExportScope).withNullabilityOf(kotlinType) private fun ObjCNonNullReferenceType.withNullabilityOf(kotlinType: KotlinType): ObjCReferenceType = - if (kotlinType.binaryRepresentationIsNullable()) { - ObjCNullableReferenceType(this) - } else { - this - } + if (kotlinType.binaryRepresentationIsNullable()) { + ObjCNullableReferenceType(this) + } else { + this + } internal fun mapReferenceTypeIgnoringNullability(kotlinType: KotlinType, objCExportScope: ObjCExportScope): ObjCNonNullReferenceType { class TypeMappingMatch(val type: KotlinType, val descriptor: ClassDescriptor, val mapper: CustomTypeMapper) @@ -928,7 +954,7 @@ class ObjCExportTranslatorImpl( val mostSpecificMatches = typeMappingMatches.filter { match -> typeMappingMatches.all { otherMatch -> otherMatch.descriptor == match.descriptor || - !otherMatch.descriptor.isSubclassOf(match.descriptor) + !otherMatch.descriptor.isSubclassOf(match.descriptor) } } @@ -938,8 +964,9 @@ class ObjCExportTranslatorImpl( val secondType = types[1] problemCollector.reportWarning( - "Exposed type '$kotlinType' is '$firstType' and '$secondType' at the same time. " + - "This most likely wouldn't work as expected.") + "Exposed type '$kotlinType' is '$firstType' and '$secondType' at the same time. " + + "This most likely wouldn't work as expected." + ) // TODO: the same warning for such classes. } @@ -954,8 +981,8 @@ class ObjCExportTranslatorImpl( if (objcGenerics && kotlinType.isTypeParameter()) { val genericTypeUsage = objCExportScope - .nearestScopeOfType() - ?.getGenericTypeUsage(TypeUtils.getTypeParameterDescriptorOrNull(kotlinType)) + .nearestScopeOfType() + ?.getGenericTypeUsage(TypeUtils.getTypeParameterDescriptorOrNull(kotlinType)) if (genericTypeUsage != null) return genericTypeUsage } @@ -1030,29 +1057,29 @@ class ObjCExportTranslatorImpl( } internal fun mapFunctionTypeIgnoringNullability( - functionType: KotlinType, - objCExportScope: ObjCExportScope, - returnsVoid: Boolean + functionType: KotlinType, + objCExportScope: ObjCExportScope, + returnsVoid: Boolean, ): ObjCBlockPointerType { val parameterTypes = listOfNotNull(functionType.getReceiverTypeFromFunctionType()) + - functionType.getValueParameterTypesFromFunctionType().map { it.type } + functionType.getValueParameterTypesFromFunctionType().map { it.type } return ObjCBlockPointerType( - if (returnsVoid) { - ObjCVoidType - } else { - mapReferenceType(functionType.getReturnTypeFromFunctionType(), objCExportScope) - }, - parameterTypes.map { - mapReferenceType(it, objCExportScope) - } + if (returnsVoid) { + ObjCVoidType + } else { + mapReferenceType(functionType.getReturnTypeFromFunctionType(), objCExportScope) + }, + parameterTypes.map { + mapReferenceType(it, objCExportScope) + } ) } private fun mapFunctionType( - kotlinType: KotlinType, - objCExportScope: ObjCExportScope, - typeBridge: BlockPointerBridge + kotlinType: KotlinType, + objCExportScope: ObjCExportScope, + typeBridge: BlockPointerBridge, ): ObjCReferenceType { val expectedDescriptor = kotlinType.builtIns.getFunction(typeBridge.numberOfParameters) @@ -1061,11 +1088,11 @@ class ObjCExportTranslatorImpl( kotlinType } else { kotlinType.supertypes().singleOrNull { TypeUtils.getClassDescriptor(it) == expectedDescriptor } - ?: expectedDescriptor.defaultType // Should not happen though. + ?: expectedDescriptor.defaultType // Should not happen though. } return mapFunctionTypeIgnoringNullability(functionType, objCExportScope, typeBridge.returnsVoid) - .withNullabilityOf(kotlinType) + .withNullabilityOf(kotlinType) } private fun mapType(kotlinType: KotlinType, typeBridge: TypeBridge, objCExportScope: ObjCExportScope): ObjCType = when (typeBridge) { @@ -1094,7 +1121,7 @@ class ObjCExportTranslatorImpl( private inline fun buildTopLevel(block: StubBuilder>.() -> Unit) = buildStubs(block) private inline fun buildMembers(block: StubBuilder>.() -> Unit) = buildStubs(block) private inline fun > buildStubs(block: StubBuilder.() -> Unit): List = - StubBuilder(problemCollector).apply(block).build() + StubBuilder(problemCollector).apply(block).build() } abstract class ObjCExportHeaderGenerator @InternalKotlinNativeApi constructor( @@ -1102,7 +1129,7 @@ abstract class ObjCExportHeaderGenerator @InternalKotlinNativeApi constructor( internal val mapper: ObjCExportMapper, val namer: ObjCExportNamer, val objcGenerics: Boolean, - problemCollector: ObjCExportProblemCollector + problemCollector: ObjCExportProblemCollector, ) { private val stubs = mutableListOf>() @@ -1143,14 +1170,14 @@ abstract class ObjCExportHeaderGenerator @InternalKotlinNativeApi constructor( add("NS_ASSUME_NONNULL_BEGIN") add("#pragma clang diagnostic push") listOf( - "-Wunknown-warning-option", + "-Wunknown-warning-option", - // Protocols don't have generics, classes do. So generated header may contain - // overriding property with "incompatible" type, e.g. `Generic`-typed property - // overriding `Generic`. Suppress these warnings: - "-Wincompatible-property-type", + // Protocols don't have generics, classes do. So generated header may contain + // overriding property with "incompatible" type, e.g. `Generic`-typed property + // overriding `Generic`. Suppress these warnings: + "-Wincompatible-property-type", - "-Wnullability" + "-Wnullability" ).forEach { add("#pragma clang diagnostic ignored \"$it\"") } @@ -1223,39 +1250,39 @@ abstract class ObjCExportHeaderGenerator @InternalKotlinNativeApi constructor( */ private fun MemberScope.collectClasses(collector: MutableCollection) { getContributedDescriptors() - .asSequence() - .filterIsInstance() - .forEach { - collector += it - // Avoid collecting nested declarations from unexposed classes. - if (mapper.shouldBeExposed(it)) { - it.unsubstitutedMemberScope.collectClasses(collector) - } + .asSequence() + .filterIsInstance() + .forEach { + collector += it + // Avoid collecting nested declarations from unexposed classes. + if (mapper.shouldBeExposed(it)) { + it.unsubstitutedMemberScope.collectClasses(collector) } + } } private fun translatePackageFragments() { val packageFragments = moduleDescriptors - .flatMap { it.getPackageFragments() } - .makePackagesOrderStable() + .flatMap { it.getPackageFragments() } + .makePackagesOrderStable() packageFragments.forEach { packageFragment -> packageFragment.getMemberScope().getContributedDescriptors() - .asSequence() - .filterIsInstance() - .filter { mapper.shouldBeExposed(it) } - .forEach { - val classDescriptor = mapper.getClassIfCategory(it) - if (classDescriptor != null) { - // If a class is hidden from Objective-C API then it is meaningless - // to export its extensions. - if (!classDescriptor.isHiddenFromObjC()) { - extensions.getOrPut(classDescriptor, { mutableListOf() }) += it - } - } else { - topLevel.getOrPut(it.findSourceFile(), { mutableListOf() }) += it + .asSequence() + .filterIsInstance() + .filter { mapper.shouldBeExposed(it) } + .forEach { + val classDescriptor = mapper.getClassIfCategory(it) + if (classDescriptor != null) { + // If a class is hidden from Objective-C API then it is meaningless + // to export its extensions. + if (!classDescriptor.isHiddenFromObjC()) { + extensions.getOrPut(classDescriptor, { mutableListOf() }) += it } + } else { + topLevel.getOrPut(it.findSourceFile(), { mutableListOf() }) += it } + } } val classesToTranslate = mutableListOf() @@ -1374,66 +1401,66 @@ abstract class ObjCExportHeaderGenerator @InternalKotlinNativeApi constructor( } private fun objCInterface( - name: ObjCExportNamer.ClassOrProtocolName, - generics: List, - superClass: String, - superClassGenerics: List + name: ObjCExportNamer.ClassOrProtocolName, + generics: List, + superClass: String, + superClassGenerics: List, ): ObjCInterface = objCInterface( - name, - generics = generics.map { ObjCGenericTypeRawDeclaration(it) }, - superClass = superClass, - superClassGenerics = superClassGenerics.map { ObjCGenericTypeRawUsage(it) } + name, + generics = generics.map { ObjCGenericTypeRawDeclaration(it) }, + superClass = superClass, + superClassGenerics = superClassGenerics.map { ObjCGenericTypeRawUsage(it) } ) private fun objCInterface( - name: ObjCExportNamer.ClassOrProtocolName, - generics: List = emptyList(), - descriptor: ClassDescriptor? = null, - superClass: String? = null, - superClassGenerics: List = emptyList(), - superProtocols: List = emptyList(), - members: List> = emptyList(), - attributes: List = emptyList(), - comment: ObjCComment? = null + name: ObjCExportNamer.ClassOrProtocolName, + generics: List = emptyList(), + descriptor: ClassDescriptor? = null, + superClass: String? = null, + superClassGenerics: List = emptyList(), + superProtocols: List = emptyList(), + members: List> = emptyList(), + attributes: List = emptyList(), + comment: ObjCComment? = null, ): ObjCInterface = ObjCInterfaceImpl( - name.objCName, - generics, - descriptor, - superClass, - superClassGenerics, - superProtocols, - null, - members, - attributes + name.toNameAttributes(), - comment + name.objCName, + generics, + descriptor, + superClass, + superClassGenerics, + superProtocols, + null, + members, + attributes + name.toNameAttributes(), + comment ) private fun objCProtocol( - name: ObjCExportNamer.ClassOrProtocolName, - descriptor: ClassDescriptor, - superProtocols: List, - members: List>, - attributes: List = emptyList(), - comment: ObjCComment? = null + name: ObjCExportNamer.ClassOrProtocolName, + descriptor: ClassDescriptor, + superProtocols: List, + members: List>, + attributes: List = emptyList(), + comment: ObjCComment? = null, ): ObjCProtocol = ObjCProtocolImpl( - name.objCName, - descriptor, - superProtocols, - members, - attributes + name.toNameAttributes(), - comment + name.objCName, + descriptor, + superProtocols, + members, + attributes + name.toNameAttributes(), + comment ) internal fun ObjCExportNamer.ClassOrProtocolName.toNameAttributes(): List = listOfNotNull( - binaryName.takeIf { it != objCName }?.let { objcRuntimeNameAttribute(it) }, - swiftName.takeIf { it != objCName }?.let { swiftNameAttribute(it) } + binaryName.takeIf { it != objCName }?.let { objcRuntimeNameAttribute(it) }, + swiftName.takeIf { it != objCName }?.let { swiftNameAttribute(it) } ) private fun swiftNameAttribute(swiftName: String) = "swift_name(\"$swiftName\")" private fun objcRuntimeNameAttribute(name: String) = "objc_runtime_name(\"$name\")" private fun computeSuperClassType(descriptor: ClassDescriptor): KotlinType? = - descriptor.typeConstructor.supertypes.firstOrNull { !it.isInterface() } + descriptor.typeConstructor.supertypes.firstOrNull { !it.isInterface() } internal const val OBJC_SUBCLASSING_RESTRICTED = "objc_subclassing_restricted" @@ -1443,9 +1470,9 @@ fun ClassDescriptor.needCompanionObjectProperty(namer: ObjCExportNamer, mapper: if (companionObject == null || !mapper.shouldBeExposed(companionObject)) return false if (kind == ClassKind.ENUM_CLASS && enumEntries.any { - namer.getEnumEntrySelector(it) == ObjCExportNamer.companionObjectPropertyName || - namer.getEnumEntrySwiftName(it) == ObjCExportNamer.companionObjectPropertyName - } + namer.getEnumEntrySelector(it) == ObjCExportNamer.companionObjectPropertyName || + namer.getEnumEntrySwiftName(it) == ObjCExportNamer.companionObjectPropertyName + } ) return false // 'companion' property would clash with enum entry, don't generate it. return true @@ -1475,7 +1502,7 @@ private fun CallableMemberDescriptor.isRefinedInSwift(): Boolean = when { } private fun CallableMemberDescriptor.getSwiftPrivateAttribute(): String? = - if (isRefinedInSwift()) "swift_private" else null + if (isRefinedInSwift()) "swift_private" else null private fun quoteAsCStringLiteral(str: String): String = buildString { append('"') @@ -1497,35 +1524,35 @@ private fun quoteAsCStringLiteral(str: String): String = buildString { // This family of `make*OrderStable` functions helps ObjCExport generate declarations in a stable order. // See KT-58863. private fun List.makePropertiesOrderStable() = - this.sortedBy { it.name } + this.sortedBy { it.name } private fun Collection.makeMethodsOrderStable() = - // The crucial part here is that we sort methods here by their signatures, which means - // that we should be extra careful with signature evolution as it might affect method order. - // Comparison of method names and number of parameters reduces the influence of signatures on the order of methods. - // Also, it acts as an optimization. - this.sortedWith( - compareBy( - { it.name }, - { it.valueParameters.size }, - { KonanManglerDesc.run { it.signatureString(false) } } - ) +// The crucial part here is that we sort methods here by their signatures, which means +// that we should be extra careful with signature evolution as it might affect method order. +// Comparison of method names and number of parameters reduces the influence of signatures on the order of methods. + // Also, it acts as an optimization. + this.sortedWith( + compareBy( + { it.name }, + { it.valueParameters.size }, + { KonanManglerDesc.run { it.signatureString(false) } } ) + ) private fun List.makePackagesOrderStable() = - this.sortedBy { it.fqName.asString() } + this.sortedBy { it.fqName.asString() } /** * Sort order of files. Order of declarations will be stabilized in the corresponding functions later. */ private fun Map>.makeFilesOrderStable() = - this.entries.sortedBy { it.key.name } + this.entries.sortedBy { it.key.name } /** * Sort order of categories. Order of extensions will be stabilized in the corresponding functions later. */ private fun Map>.makeCategoriesOrderStable() = - this.entries.sortedBy { it.key.classId.toString() } + this.entries.sortedBy { it.key.classId.toString() } private fun List.makeClassesOrderStable() = - this.sortedBy { it.classId.toString() } \ No newline at end of file + this.sortedBy { it.classId.toString() } \ No newline at end of file diff --git a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGeneratorImpl.kt b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGeneratorImpl.kt index df98ea8c368..29e43221d48 100644 --- a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGeneratorImpl.kt +++ b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGeneratorImpl.kt @@ -8,14 +8,14 @@ package org.jetbrains.kotlin.backend.konan.objcexport import org.jetbrains.kotlin.descriptors.ModuleDescriptor internal class ObjCExportHeaderGeneratorImpl( - moduleDescriptors: List, - mapper: ObjCExportMapper, - namer: ObjCExportNamer, - problemCollector: ObjCExportProblemCollector, - objcGenerics: Boolean, - override val shouldExportKDoc: Boolean, - private val additionalImports: List, + moduleDescriptors: List, + mapper: ObjCExportMapper, + namer: ObjCExportNamer, + problemCollector: ObjCExportProblemCollector, + objcGenerics: Boolean, + override val shouldExportKDoc: Boolean, + private val additionalImports: List, ) : ObjCExportHeaderGenerator(moduleDescriptors, mapper, namer, objcGenerics, problemCollector) { override fun getAdditionalImports(): List = - additionalImports + additionalImports } diff --git a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportLazy.kt b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportLazy.kt index f01d91c6c6f..4a9b5e02ddc 100644 --- a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportLazy.kt +++ b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportLazy.kt @@ -9,12 +9,12 @@ import com.intellij.psi.PsiElement import org.jetbrains.kotlin.analyzer.ModuleInfo import org.jetbrains.kotlin.backend.konan.InternalKotlinNativeApi import org.jetbrains.kotlin.backend.konan.UnitSuspendFunctionObjCExport -import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl +import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName @@ -61,35 +61,35 @@ interface ObjCExportLazy { @JvmOverloads fun createObjCExportLazy( - configuration: ObjCExportLazy.Configuration, - problemCollector: ObjCExportProblemCollector, - codeAnalyzer: KotlinCodeAnalyzer, - typeResolver: TypeResolver, - descriptorResolver: DescriptorResolver, - fileScopeProvider: FileScopeProvider, - builtIns: KotlinBuiltIns, - deprecationResolver: DeprecationResolver? = null + configuration: ObjCExportLazy.Configuration, + problemCollector: ObjCExportProblemCollector, + codeAnalyzer: KotlinCodeAnalyzer, + typeResolver: TypeResolver, + descriptorResolver: DescriptorResolver, + fileScopeProvider: FileScopeProvider, + builtIns: KotlinBuiltIns, + deprecationResolver: DeprecationResolver? = null, ): ObjCExportLazy = ObjCExportLazyImpl( - configuration, - problemCollector, - codeAnalyzer, - typeResolver, - descriptorResolver, - fileScopeProvider, - builtIns, - deprecationResolver + configuration, + problemCollector, + codeAnalyzer, + typeResolver, + descriptorResolver, + fileScopeProvider, + builtIns, + deprecationResolver ) @InternalKotlinNativeApi class ObjCExportLazyImpl( - private val configuration: ObjCExportLazy.Configuration, - problemCollector: ObjCExportProblemCollector, - private val codeAnalyzer: KotlinCodeAnalyzer, - private val typeResolver: TypeResolver, - private val descriptorResolver: DescriptorResolver, - private val fileScopeProvider: FileScopeProvider, - builtIns: KotlinBuiltIns, - deprecationResolver: DeprecationResolver? + private val configuration: ObjCExportLazy.Configuration, + problemCollector: ObjCExportProblemCollector, + private val codeAnalyzer: KotlinCodeAnalyzer, + private val typeResolver: TypeResolver, + private val descriptorResolver: DescriptorResolver, + private val fileScopeProvider: FileScopeProvider, + builtIns: KotlinBuiltIns, + deprecationResolver: DeprecationResolver?, ) : ObjCExportLazy { private val namerConfiguration = createNamerConfiguration(configuration) @@ -101,11 +101,11 @@ class ObjCExportLazyImpl( private val namer = ObjCExportNamerImpl(namerConfiguration, builtIns, mapper, problemCollector, local = true) private val translator: ObjCExportTranslator = ObjCExportTranslatorImpl( - null, - mapper, - namer, - problemCollector, - configuration.objcGenerics + null, + mapper, + namer, + problemCollector, + configuration.objcGenerics ) private val isValid: Boolean @@ -114,14 +114,15 @@ class ObjCExportLazyImpl( override fun generateBase() = translator.generateBaseDeclarations() override fun translate(file: KtFile): List> = - translateClasses(file) + translateTopLevels(file) + translateClasses(file) + translateTopLevels(file) private fun translateClasses(container: KtDeclarationContainer): List> { val result = mutableListOf>() container.declarations.forEach { declaration -> // Supposed to be true if ObjCExportMapper.shouldBeVisible is true. if (declaration is KtClassOrObject && declaration.isPublic && declaration !is KtEnumEntry - && !declaration.hasExpectModifier()) { + && !declaration.hasExpectModifier() + ) { if (!declaration.isAnnotation() && !declaration.hasModifier(KtTokens.INLINE_KEYWORD)) { result += translateClass(declaration) @@ -144,7 +145,7 @@ class ObjCExportLazyImpl( LazyObjCProtocolImpl(name, ktClassOrObject, this) } else { val isFinal = ktClassOrObject.modalityModifier() == null || - ktClassOrObject.hasModifier(KtTokens.FINAL_KEYWORD) + ktClassOrObject.hasModifier(KtTokens.FINAL_KEYWORD) val attributes = if (isFinal) { listOf(OBJC_SUBCLASSING_RESTRICTED) @@ -152,30 +153,32 @@ class ObjCExportLazyImpl( emptyList() } - LazyObjCInterfaceImpl(name, - attributes, - generics = translateGenerics(ktClassOrObject), - psi = ktClassOrObject, - lazy = this) + LazyObjCInterfaceImpl( + name, + attributes, + generics = translateGenerics(ktClassOrObject), + psi = ktClassOrObject, + lazy = this + ) } } private fun translateGenerics(ktClassOrObject: KtClassOrObject): List = if (configuration.objcGenerics) { ktClassOrObject.typeParametersWithOuter - .map { - ObjCGenericTypeRawDeclaration( - nameTranslator.getTypeParameterName(it), - ObjCVariance.fromKotlinVariance(it.variance) - ) - } - .toList() + .map { + ObjCGenericTypeRawDeclaration( + nameTranslator.getTypeParameterName(it), + ObjCVariance.fromKotlinVariance(it.variance) + ) + } + .toList() } else { emptyList() } private fun translateTopLevels(file: KtFile): List { val extensions = - mutableMapOf>() + mutableMapOf>() val topLevel = mutableListOf() @@ -212,9 +215,9 @@ class ObjCExportLazyImpl( } private fun translateExtensions( - file: KtFile, - classDescriptor: ClassDescriptor, - declarations: List + file: KtFile, + classDescriptor: ClassDescriptor, + declarations: List, ): ObjCInterface { // TODO: consider using file-based categories in compiler too. @@ -228,13 +231,13 @@ class ObjCExportLazyImpl( } private fun resolveDeclaration(ktDeclaration: KtDeclaration): DeclarationDescriptor = - codeAnalyzer.resolveToDescriptor(ktDeclaration) + codeAnalyzer.resolveToDescriptor(ktDeclaration) private fun resolve(ktClassOrObject: KtClassOrObject) = - resolveDeclaration(ktClassOrObject) as ClassDescriptor + resolveDeclaration(ktClassOrObject) as ClassDescriptor private fun resolve(ktCallableDeclaration: KtCallableDeclaration) = - resolveDeclaration(ktCallableDeclaration) as CallableMemberDescriptor + resolveDeclaration(ktCallableDeclaration) as CallableMemberDescriptor private fun getClassIfExtension(topLevelDeclaration: KtCallableDeclaration): ClassDescriptor? { val receiverType = topLevelDeclaration.receiverTypeReference ?: return null @@ -243,19 +246,19 @@ class ObjCExportLazyImpl( val trace = BindingTraceContext() // TODO: revise. val kotlinReceiverType = typeResolver.resolveType( - createHeaderScope(topLevelDeclaration, fileScope, trace), - receiverType, - trace, - checkBounds = false + createHeaderScope(topLevelDeclaration, fileScope, trace), + receiverType, + trace, + checkBounds = false ) return translator.getClassIfExtension(kotlinReceiverType) } private fun createHeaderScope( - declaration: KtCallableDeclaration, - parent: LexicalScope, - trace: BindingTrace + declaration: KtCallableDeclaration, + parent: LexicalScope, + trace: BindingTrace, ): LexicalScope { if (declaration.typeParameters.isEmpty()) return parent @@ -268,30 +271,30 @@ class ObjCExportLazyImpl( when (declaration) { is KtFunction -> { descriptor = SimpleFunctionDescriptorImpl.create( - parent.ownerDescriptor, - Annotations.EMPTY, - fakeName, - CallableMemberDescriptor.Kind.DECLARATION, - sourceElement + parent.ownerDescriptor, + Annotations.EMPTY, + fakeName, + CallableMemberDescriptor.Kind.DECLARATION, + sourceElement ) scopeKind = LexicalScopeKind.FUNCTION_HEADER } is KtProperty -> { descriptor = PropertyDescriptorImpl.create( - parent.ownerDescriptor, - Annotations.EMPTY, - Modality.FINAL, - DescriptorVisibilities.PUBLIC, - declaration.isVar, - fakeName, - CallableMemberDescriptor.Kind.DECLARATION, - sourceElement, - false, - false, - false, - false, - false, - false + parent.ownerDescriptor, + Annotations.EMPTY, + Modality.FINAL, + DescriptorVisibilities.PUBLIC, + declaration.isVar, + fakeName, + CallableMemberDescriptor.Kind.DECLARATION, + sourceElement, + false, + false, + false, + false, + false, + false ) scopeKind = LexicalScopeKind.PROPERTY_HEADER } @@ -299,19 +302,19 @@ class ObjCExportLazyImpl( } val result = LexicalWritableScope( - parent, - descriptor, - false, - LocalRedeclarationChecker.DO_NOTHING, - scopeKind + parent, + descriptor, + false, + LocalRedeclarationChecker.DO_NOTHING, + scopeKind ) val typeParameters = descriptorResolver.resolveTypeParametersForDescriptor( - descriptor, - result, - result, - declaration.typeParameters, - trace + descriptor, + result, + result, + declaration.typeParameters, + trace ) descriptorResolver.resolveGenericBounds(declaration, descriptor, result, typeParameters, trace) @@ -322,7 +325,7 @@ class ObjCExportLazyImpl( private class LazyObjCProtocolImpl( name: ObjCExportNamer.ClassOrProtocolName, override val psi: KtClassOrObject, - private val lazy: ObjCExportLazyImpl + private val lazy: ObjCExportLazyImpl, ) : LazyObjCProtocol(name) { override val descriptor: ClassDescriptor by lazy { lazy.resolve(psi) } @@ -337,7 +340,7 @@ class ObjCExportLazyImpl( attributes: List, generics: List, override val psi: KtClassOrObject, - private val lazy: ObjCExportLazyImpl + private val lazy: ObjCExportLazyImpl, ) : LazyObjCInterface(name = name, generics = generics, categoryName = null, attributes = attributes) { override val descriptor: ClassDescriptor by lazy { lazy.resolve(psi) } @@ -351,7 +354,7 @@ class ObjCExportLazyImpl( name: ObjCExportNamer.ClassOrProtocolName, private val file: KtFile, private val declarations: List, - private val lazy: ObjCExportLazyImpl + private val lazy: ObjCExportLazyImpl, ) : LazyObjCInterface(name = name, generics = emptyList(), categoryName = null, attributes = listOf(OBJC_SUBCLASSING_RESTRICTED)) { override val descriptor: ClassDescriptor? get() = null @@ -377,7 +380,7 @@ class ObjCExportLazyImpl( categoryName: String, private val classDescriptor: ClassDescriptor, private val declarations: List, - private val lazy: ObjCExportLazyImpl + private val lazy: ObjCExportLazyImpl, ) : LazyObjCInterface(name = name.objCName, generics = emptyList(), categoryName = categoryName, attributes = emptyList()) { override val descriptor: ClassDescriptor? get() = null @@ -400,17 +403,17 @@ class ObjCExportLazyImpl( private abstract class LazyObjCInterface : ObjCInterface { constructor( - name: ObjCExportNamer.ClassOrProtocolName, - generics: List, - categoryName: String?, - attributes: List + name: ObjCExportNamer.ClassOrProtocolName, + generics: List, + categoryName: String?, + attributes: List, ) : super(name.objCName, generics, categoryName, attributes + name.toNameAttributes()) constructor( - name: String, - generics: List, - categoryName: String, - attributes: List + name: String, + generics: List, + categoryName: String, + attributes: List, ) : super(name, generics, categoryName, attributes) protected abstract fun computeRealStub(): ObjCInterface @@ -431,7 +434,7 @@ private abstract class LazyObjCInterface : ObjCInterface { } private abstract class LazyObjCProtocol( - name: ObjCExportNamer.ClassOrProtocolName + name: ObjCExportNamer.ClassOrProtocolName, ) : ObjCProtocol(name.objCName, name.toNameAttributes()) { protected abstract fun computeRealStub(): ObjCProtocol @@ -469,7 +472,7 @@ private val kotlinSequenceClassId = ClassId.topLevel(FqName("kotlin.sequences.Se // This is a special workaround needed for resolve in the IDE. private fun ModuleDescriptor.isCommonStdlibCheckSpecificallyForIDE() = - findClassAcrossModuleDependencies(kotlinSequenceClassId)?.module == this + findClassAcrossModuleDependencies(kotlinSequenceClassId)?.module == this private val KtModifierListOwner.isPublic: Boolean get() = this.visibilityModifierTypeOrDefault() == KtTokens.PUBLIC_KEYWORD @@ -479,4 +482,4 @@ internal val KtPureClassOrObject.isInterface: Boolean internal val KtClassOrObject.typeParametersWithOuter get() = generateSequence(this, { if (it is KtClass && it.isInner()) it.containingClassOrObject else null }) - .flatMap { it.typeParameters.asSequence() } + .flatMap { it.typeParameters.asSequence() } diff --git a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportLazyUtils.kt b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportLazyUtils.kt index 7d21f04654e..2705d38fad0 100644 --- a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportLazyUtils.kt +++ b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportLazyUtils.kt @@ -12,7 +12,7 @@ import org.jetbrains.kotlin.psi.KtFile @InternalKotlinNativeApi fun ObjCExportLazy.dumpObjCHeader(files: Collection, outputFile: String, shouldExportKDoc: Boolean) { val lines = (this.generateBase() + files.flatMap { this.translate(it) }) - .flatMap { StubRenderer.render(it, shouldExportKDoc) + listOf("") } + .flatMap { StubRenderer.render(it, shouldExportKDoc) + listOf("") } File(outputFile).writeLines(lines) } \ No newline at end of file diff --git a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportMapper.kt b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportMapper.kt index f61aed9a49d..803ddfeb435 100644 --- a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportMapper.kt +++ b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportMapper.kt @@ -13,7 +13,7 @@ import org.jetbrains.kotlin.backend.konan.descriptors.isInterface import org.jetbrains.kotlin.builtins.* import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.incremental.components.NoLookupLocation -import org.jetbrains.kotlin.ir.objcinterop.* +import org.jetbrains.kotlin.ir.objcinterop.isObjCObjectType import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.resolve.DataClassResolver import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo @@ -29,7 +29,7 @@ import org.jetbrains.kotlin.types.typeUtil.isUnit class ObjCExportMapper( internal val deprecationResolver: DeprecationResolver? = null, private val local: Boolean = false, - internal val unitSuspendFunctionExport: UnitSuspendFunctionObjCExport + internal val unitSuspendFunctionExport: UnitSuspendFunctionObjCExport, ) { fun getCustomTypeMapper(descriptor: ClassDescriptor): CustomTypeMapper? = CustomTypeMappers.getMapper(descriptor) @@ -38,7 +38,7 @@ class ObjCExportMapper( fun isSpecialMapped(descriptor: ClassDescriptor): Boolean { // TODO: this method duplicates some of the [ObjCExportTranslatorImpl.mapReferenceType] logic. return KotlinBuiltIns.isAny(descriptor) || - descriptor.getAllSuperClassifiers().any { it is ClassDescriptor && CustomTypeMappers.hasMapper(it) } + descriptor.getAllSuperClassifiers().any { it is ClassDescriptor && CustomTypeMappers.hasMapper(it) } } private val methodBridgeCache = mutableMapOf() @@ -122,13 +122,14 @@ internal fun ClassDescriptor.isHiddenFromObjC(): Boolean = when { } internal fun ObjCExportMapper.shouldBeExposed(descriptor: ClassDescriptor): Boolean = - shouldBeVisible(descriptor) && !isSpecialMapped(descriptor) && !descriptor.defaultType.isObjCObjectType() + shouldBeVisible(descriptor) && !isSpecialMapped(descriptor) && !descriptor.defaultType.isObjCObjectType() private fun ObjCExportMapper.isHiddenByDeprecation(descriptor: CallableMemberDescriptor): Boolean { // Note: ObjCExport generally expect overrides of exposed methods to be exposed. // So don't hide a "deprecated hidden" method which overrides non-hidden one: if (deprecationResolver != null && deprecationResolver.isDeprecatedHidden(descriptor) && - descriptor.overriddenDescriptors.all { isHiddenByDeprecation(it) }) { + descriptor.overriddenDescriptors.all { isHiddenByDeprecation(it) } + ) { return true } @@ -185,14 +186,14 @@ private fun ObjCExportMapper.isHiddenByDeprecation(descriptor: ClassDescriptor): // Note: the logic is partially duplicated in ObjCExportLazyImpl.translateClasses. internal fun ObjCExportMapper.shouldBeVisible(descriptor: ClassDescriptor): Boolean = - descriptor.isEffectivelyPublicApi && when (descriptor.kind) { + descriptor.isEffectivelyPublicApi && when (descriptor.kind) { ClassKind.CLASS, ClassKind.INTERFACE, ClassKind.ENUM_CLASS, ClassKind.OBJECT -> true ClassKind.ENUM_ENTRY, ClassKind.ANNOTATION_CLASS -> false } && !descriptor.isExpect && !descriptor.isInlined() && !isHiddenByDeprecation(descriptor) && !descriptor.isHiddenFromObjC() private fun ObjCExportMapper.isBase(descriptor: CallableMemberDescriptor): Boolean = - descriptor.overriddenDescriptors.all { !shouldBeExposed(it) } - // e.g. it is not `override`, or overrides only unexposed methods. + descriptor.overriddenDescriptors.all { !shouldBeExposed(it) } +// e.g. it is not `override`, or overrides only unexposed methods. /** * Check that given [descriptor] is a so-called "base method", i.e. method @@ -240,21 +241,21 @@ fun ObjCExportMapper.getBaseProperties(descriptor: PropertyDescriptor): List( - eachInlinedClass = { inlinedClass, _ -> - when (inlinedClass.classId) { - UnsignedType.UBYTE.classId -> return ValueTypeBridge(ObjCValueType.UNSIGNED_CHAR) - UnsignedType.USHORT.classId -> return ValueTypeBridge(ObjCValueType.UNSIGNED_SHORT) - UnsignedType.UINT.classId -> return ValueTypeBridge(ObjCValueType.UNSIGNED_INT) - UnsignedType.ULONG.classId -> return ValueTypeBridge(ObjCValueType.UNSIGNED_LONG_LONG) - } - }, - ifPrimitive = { primitiveType, _ -> - val objCValueType = when (primitiveType) { - KonanPrimitiveType.BOOLEAN -> ObjCValueType.BOOL - KonanPrimitiveType.CHAR -> ObjCValueType.UNICHAR - KonanPrimitiveType.BYTE -> ObjCValueType.CHAR - KonanPrimitiveType.SHORT -> ObjCValueType.SHORT - KonanPrimitiveType.INT -> ObjCValueType.INT - KonanPrimitiveType.LONG -> ObjCValueType.LONG_LONG - KonanPrimitiveType.FLOAT -> ObjCValueType.FLOAT - KonanPrimitiveType.DOUBLE -> ObjCValueType.DOUBLE - KonanPrimitiveType.NON_NULL_NATIVE_PTR -> ObjCValueType.POINTER - KonanPrimitiveType.VECTOR128 -> TODO() - } - ValueTypeBridge(objCValueType) - }, - ifReference = { - if (kotlinType.isFunctionType) { - bridgeFunctionType(kotlinType) - } else { - ReferenceBridge - } + eachInlinedClass = { inlinedClass, _ -> + when (inlinedClass.classId) { + UnsignedType.UBYTE.classId -> return ValueTypeBridge(ObjCValueType.UNSIGNED_CHAR) + UnsignedType.USHORT.classId -> return ValueTypeBridge(ObjCValueType.UNSIGNED_SHORT) + UnsignedType.UINT.classId -> return ValueTypeBridge(ObjCValueType.UNSIGNED_INT) + UnsignedType.ULONG.classId -> return ValueTypeBridge(ObjCValueType.UNSIGNED_LONG_LONG) } + }, + ifPrimitive = { primitiveType, _ -> + val objCValueType = when (primitiveType) { + KonanPrimitiveType.BOOLEAN -> ObjCValueType.BOOL + KonanPrimitiveType.CHAR -> ObjCValueType.UNICHAR + KonanPrimitiveType.BYTE -> ObjCValueType.CHAR + KonanPrimitiveType.SHORT -> ObjCValueType.SHORT + KonanPrimitiveType.INT -> ObjCValueType.INT + KonanPrimitiveType.LONG -> ObjCValueType.LONG_LONG + KonanPrimitiveType.FLOAT -> ObjCValueType.FLOAT + KonanPrimitiveType.DOUBLE -> ObjCValueType.DOUBLE + KonanPrimitiveType.NON_NULL_NATIVE_PTR -> ObjCValueType.POINTER + KonanPrimitiveType.VECTOR128 -> TODO() + } + ValueTypeBridge(objCValueType) + }, + ifReference = { + if (kotlinType.isFunctionType) { + bridgeFunctionType(kotlinType) + } else { + ReferenceBridge + } + } ) private fun ObjCExportMapper.bridgeFunctionType(kotlinType: KotlinType): TypeBridge { @@ -323,8 +324,8 @@ private fun ObjCExportMapper.bridgeParameter(parameter: ParameterDescriptor): Me MethodBridgeValueParameter.Mapped(bridgeType(parameter.type)) private fun ObjCExportMapper.bridgeReturnType( - descriptor: FunctionDescriptor, - convertExceptionsToErrors: Boolean + descriptor: FunctionDescriptor, + convertExceptionsToErrors: Boolean, ): MethodBridge.ReturnValue { val returnType = descriptor.returnType!! return when { @@ -343,7 +344,7 @@ private fun ObjCExportMapper.bridgeReturnType( } descriptor.containingDeclaration.let { it is ClassDescriptor && KotlinBuiltIns.isAny(it) } && - descriptor.name.asString() == "hashCode" -> { + descriptor.name.asString() == "hashCode" -> { assert(!convertExceptionsToErrors) MethodBridge.ReturnValue.HashCode } @@ -365,8 +366,8 @@ private fun ObjCExportMapper.bridgeReturnType( if (convertExceptionsToErrors) { val canReturnZero = !returnTypeBridge.isReferenceOrPointer() || TypeUtils.isNullableType(returnType) MethodBridge.ReturnValue.WithError.ZeroForError( - successReturnValueBridge, - successMayBeZero = canReturnZero + successReturnValueBridge, + successMayBeZero = canReturnZero ) } else { successReturnValueBridge @@ -457,7 +458,7 @@ enum class NSNumberKind(val mappedKotlinClassId: ClassId?, val objCType: ObjCTyp // UNSIGNED_SHORT -> unsignedShort private val kindName = this.name.split('_') - .joinToString("") { it.lowercase().replaceFirstChar(Char::uppercaseChar) }.replaceFirstChar(Char::lowercaseChar) + .joinToString("") { it.lowercase().replaceFirstChar(Char::uppercaseChar) }.replaceFirstChar(Char::lowercaseChar) val valueSelector = kindName // unsignedShort @@ -465,13 +466,13 @@ enum class NSNumberKind(val mappedKotlinClassId: ClassId?, val objCType: ObjCTyp val factorySelector = "numberWith${kindName.replaceFirstChar(Char::uppercaseChar)}:" // numberWithUnsignedShort: constructor( - primitiveType: PrimitiveType, - objCPrimitiveType: ObjCPrimitiveType + primitiveType: PrimitiveType, + objCPrimitiveType: ObjCPrimitiveType, ) : this(ClassId.topLevel(primitiveType.typeFqName), objCPrimitiveType) constructor( - unsignedType: UnsignedType, - objCPrimitiveType: ObjCPrimitiveType + unsignedType: UnsignedType, + objCPrimitiveType: ObjCPrimitiveType, ) : this(unsignedType.classId, objCPrimitiveType) constructor(objCPrimitiveType: ObjCPrimitiveType) : this(null, objCPrimitiveType) diff --git a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportNamer.kt b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportNamer.kt index aa8a2030427..71f1a571484 100644 --- a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportNamer.kt +++ b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportNamer.kt @@ -39,7 +39,7 @@ internal interface ObjCExportNameTranslator { fun getCategoryName(file: KtFile): String fun getClassOrProtocolName( - ktClassOrObject: KtClassOrObject + ktClassOrObject: KtClassOrObject, ): ObjCExportNamer.ClassOrProtocolName fun getTypeParameterName(ktTypeParameter: KtTypeParameter): String @@ -90,57 +90,61 @@ interface ObjCExportNamer { companion object { @InternalKotlinNativeApi const val kotlinThrowableAsErrorMethodName: String = "asError" + @InternalKotlinNativeApi const val objectPropertyName: String = "shared" + @InternalKotlinNativeApi const val companionObjectPropertyName: String = "companion" } } -fun createNamer(moduleDescriptor: ModuleDescriptor, - topLevelNamePrefix: String): ObjCExportNamer = - createNamer(moduleDescriptor, emptyList(), topLevelNamePrefix) +fun createNamer( + moduleDescriptor: ModuleDescriptor, + topLevelNamePrefix: String, +): ObjCExportNamer = + createNamer(moduleDescriptor, emptyList(), topLevelNamePrefix) fun createNamer( - moduleDescriptor: ModuleDescriptor, - exportedDependencies: List, - topLevelNamePrefix: String + moduleDescriptor: ModuleDescriptor, + exportedDependencies: List, + topLevelNamePrefix: String, ): ObjCExportNamer = ObjCExportNamerImpl( - (exportedDependencies + moduleDescriptor).toSet(), - moduleDescriptor.builtIns, - ObjCExportMapper(local = true, unitSuspendFunctionExport = UnitSuspendFunctionObjCExport.DEFAULT), - ObjCExportProblemCollector.SILENT, - topLevelNamePrefix, - local = true + (exportedDependencies + moduleDescriptor).toSet(), + moduleDescriptor.builtIns, + ObjCExportMapper(local = true, unitSuspendFunctionExport = UnitSuspendFunctionObjCExport.DEFAULT), + ObjCExportProblemCollector.SILENT, + topLevelNamePrefix, + local = true ) // Note: this class duplicates some of ObjCExportNamerImpl logic, // but operates on different representation. internal open class ObjCExportNameTranslatorImpl( - private val configuration: ObjCExportNamer.Configuration + private val configuration: ObjCExportNamer.Configuration, ) : ObjCExportNameTranslator { private val helper = ObjCExportNamingHelper(configuration.topLevelNamePrefix, configuration.objcGenerics) override fun getFileClassName(file: KtFile): ObjCExportNamer.ClassOrProtocolName = - helper.getFileClassName(file) + helper.getFileClassName(file) override fun getCategoryName(file: KtFile): String = - helper.translateFileName(file) + helper.translateFileName(file) override fun getClassOrProtocolName(ktClassOrObject: KtClassOrObject): ObjCExportNamer.ClassOrProtocolName = - ObjCExportNamer.ClassOrProtocolName( - swiftName = getClassOrProtocolAsSwiftName(ktClassOrObject, true), - objCName = buildString { - getClassOrProtocolAsSwiftName(ktClassOrObject, false).split('.').forEachIndexed { index, part -> - append(if (index == 0) part else part.replaceFirstChar(Char::uppercaseChar)) - } - } - ) + ObjCExportNamer.ClassOrProtocolName( + swiftName = getClassOrProtocolAsSwiftName(ktClassOrObject, true), + objCName = buildString { + getClassOrProtocolAsSwiftName(ktClassOrObject, false).split('.').forEachIndexed { index, part -> + append(if (index == 0) part else part.replaceFirstChar(Char::uppercaseChar)) + } + } + ) private fun getClassOrProtocolAsSwiftName( - ktClassOrObject: KtClassOrObject, - forSwift: Boolean + ktClassOrObject: KtClassOrObject, + forSwift: Boolean, ): String = buildString { val objCName = ktClassOrObject.getObjCName() if (objCName.isExact) { @@ -157,20 +161,20 @@ internal open class ObjCExportNameTranslatorImpl( } private fun StringBuilder.appendNameWithContainer( - ktClassOrObject: KtClassOrObject, - objCName: ObjCName, - outerClass: KtClassOrObject, - forSwift: Boolean + ktClassOrObject: KtClassOrObject, + objCName: ObjCName, + outerClass: KtClassOrObject, + forSwift: Boolean, ) = helper.appendNameWithContainer( - this, - ktClassOrObject, objCName.asIdentifier(forSwift), - outerClass, getClassOrProtocolAsSwiftName(outerClass, forSwift), - object : ObjCExportNamingHelper.ClassInfoProvider { - override fun hasGenerics(clazz: KtClassOrObject): Boolean = - clazz.typeParametersWithOuter.count() != 0 + this, + ktClassOrObject, objCName.asIdentifier(forSwift), + outerClass, getClassOrProtocolAsSwiftName(outerClass, forSwift), + object : ObjCExportNamingHelper.ClassInfoProvider { + override fun hasGenerics(clazz: KtClassOrObject): Boolean = + clazz.typeParametersWithOuter.count() != 0 - override fun isInterface(clazz: KtClassOrObject): Boolean = ktClassOrObject.isInterface - } + override fun isInterface(clazz: KtClassOrObject): Boolean = ktClassOrObject.isInterface + } ) override fun getTypeParameterName(ktTypeParameter: KtTypeParameter): String = buildString { @@ -180,12 +184,12 @@ internal open class ObjCExportNameTranslatorImpl( } private class ObjCExportNamingHelper( - private val topLevelNamePrefix: String, - private val objcGenerics: Boolean + private val topLevelNamePrefix: String, + private val objcGenerics: Boolean, ) { fun translateFileName(fileName: String): String = - PackagePartClassUtils.getFilePartShortName(fileName).toIdentifier() + PackagePartClassUtils.getFilePartShortName(fileName).toIdentifier() fun translateFileName(file: KtFile): String = translateFileName(file.name) @@ -195,15 +199,15 @@ private class ObjCExportNamingHelper( } fun getFileClassName(file: KtFile): ObjCExportNamer.ClassOrProtocolName = - getFileClassName(file.name) + getFileClassName(file.name) fun appendNameWithContainer( - builder: StringBuilder, - clazz: T, - ownName: String, - containingClass: T, - containerName: String, - provider: ClassInfoProvider + builder: StringBuilder, + clazz: T, + ownName: String, + containingClass: T, + containerName: String, + provider: ClassInfoProvider, ) = builder.apply { if (clazz.canBeSwiftInner(provider)) { append(containerName) @@ -271,54 +275,56 @@ private class ObjCExportNamingHelper( fun isTypeParameterNameReserved(name: String): Boolean = name in reservedTypeParameterNames - private val reservedTypeParameterNames = setOf("id", "NSObject", "NSArray", "NSCopying", "NSNumber", "NSInteger", - "NSUInteger", "NSString", "NSSet", "NSDictionary", "NSMutableArray", "int", "unsigned", "short", - "char", "long", "float", "double", "int32_t", "int64_t", "int16_t", "int8_t", "unichar") + private val reservedTypeParameterNames = setOf( + "id", "NSObject", "NSArray", "NSCopying", "NSNumber", "NSInteger", + "NSUInteger", "NSString", "NSSet", "NSDictionary", "NSMutableArray", "int", "unsigned", "short", + "char", "long", "float", "double", "int32_t", "int64_t", "int16_t", "int8_t", "unichar" + ) } @InternalKotlinNativeApi class ObjCExportNamerImpl( - private val configuration: ObjCExportNamer.Configuration, - builtIns: KotlinBuiltIns, - private val mapper: ObjCExportMapper, - private val problemCollector: ObjCExportProblemCollector, - private val local: Boolean + private val configuration: ObjCExportNamer.Configuration, + builtIns: KotlinBuiltIns, + private val mapper: ObjCExportMapper, + private val problemCollector: ObjCExportProblemCollector, + private val local: Boolean, ) : ObjCExportNamer { constructor( - moduleDescriptors: Set, - builtIns: KotlinBuiltIns, - mapper: ObjCExportMapper, - problemCollector: ObjCExportProblemCollector, - topLevelNamePrefix: String, - local: Boolean, - objcGenerics: Boolean = false, - disableSwiftMemberNameMangling: Boolean = false, - ignoreInterfaceMethodCollisions: Boolean = false, - reportNameCollisions: Boolean = false, + moduleDescriptors: Set, + builtIns: KotlinBuiltIns, + mapper: ObjCExportMapper, + problemCollector: ObjCExportProblemCollector, + topLevelNamePrefix: String, + local: Boolean, + objcGenerics: Boolean = false, + disableSwiftMemberNameMangling: Boolean = false, + ignoreInterfaceMethodCollisions: Boolean = false, + reportNameCollisions: Boolean = false, ) : this( - object : ObjCExportNamer.Configuration { - override val topLevelNamePrefix: String - get() = topLevelNamePrefix + object : ObjCExportNamer.Configuration { + override val topLevelNamePrefix: String + get() = topLevelNamePrefix - override fun getAdditionalPrefix(module: ModuleDescriptor): String? = - if (module in moduleDescriptors) null else module.objCExportAdditionalNamePrefix + override fun getAdditionalPrefix(module: ModuleDescriptor): String? = + if (module in moduleDescriptors) null else module.objCExportAdditionalNamePrefix - override val objcGenerics: Boolean - get() = objcGenerics + override val objcGenerics: Boolean + get() = objcGenerics - override val disableSwiftMemberNameMangling: Boolean - get() = disableSwiftMemberNameMangling + override val disableSwiftMemberNameMangling: Boolean + get() = disableSwiftMemberNameMangling - override val ignoreInterfaceMethodCollisions: Boolean - get() = ignoreInterfaceMethodCollisions + override val ignoreInterfaceMethodCollisions: Boolean + get() = ignoreInterfaceMethodCollisions - override val reportNameCollisions: Boolean - get() = reportNameCollisions - }, - builtIns, - mapper, - problemCollector, - local + override val reportNameCollisions: Boolean + get() = reportNameCollisions + }, + builtIns, + mapper, + problemCollector, + local ) private val objcGenerics get() = configuration.objcGenerics @@ -326,8 +332,8 @@ class ObjCExportNamerImpl( private val helper = ObjCExportNamingHelper(configuration.topLevelNamePrefix, objcGenerics) private fun String.toSpecialStandardClassOrProtocolName() = ObjCExportNamer.ClassOrProtocolName( - swiftName = "Kotlin$this", - objCName = "${topLevelNamePrefix}$this" + swiftName = "Kotlin$this", + objCName = "${topLevelNamePrefix}$this" ) override val kotlinAnyName = "Base".toSpecialStandardClassOrProtocolName() @@ -336,7 +342,7 @@ class ObjCExportNamerImpl( override val mutableMapName = "MutableDictionary".toSpecialStandardClassOrProtocolName() override fun numberBoxName(classId: ClassId): ObjCExportNamer.ClassOrProtocolName = - classId.shortClassName.asString().toSpecialStandardClassOrProtocolName() + classId.shortClassName.asString().toSpecialStandardClassOrProtocolName() override val kotlinNumberName = "Number".toSpecialStandardClassOrProtocolName() @@ -345,15 +351,15 @@ class ObjCExportNamerImpl( // Try to avoid clashing with critical NSObject instance methods: private val reserved = setOf( - "retain", "release", "autorelease", - "class", "superclass", - "hash" + "retain", "release", "autorelease", + "class", "superclass", + "hash" ) override fun reserved(name: String) = name in reserved override fun conflict(first: FunctionDescriptor, second: FunctionDescriptor): Boolean = - !mapper.canHaveSameSelector(first, second, configuration.ignoreInterfaceMethodCollisions) + !mapper.canHaveSameSelector(first, second, configuration.ignoreInterfaceMethodCollisions) } private val methodSwiftNames = object : Mapping() { @@ -393,11 +399,11 @@ class ObjCExportNamerImpl( // Try to avoid clashing with NSObject class methods: private val reserved = setOf( - "retain", "release", "autorelease", - "initialize", "load", "alloc", "new", "class", "superclass", - "classFallbacksForKeyedArchiver", "classForKeyedUnarchiver", - "description", "debugDescription", "version", "hash", - "useStoredAccessor" + "retain", "release", "autorelease", + "initialize", "load", "alloc", "new", "class", "superclass", + "classFallbacksForKeyedArchiver", "classForKeyedUnarchiver", + "description", "debugDescription", "version", "hash", + "useStoredAccessor" ) override fun reserved(name: String) = (name in reserved) || (name in cKeywords) @@ -409,7 +415,7 @@ class ObjCExportNamerImpl( private inner class EnumNameMapping : ClassSelectorNameMapping() { override fun conflict(first: DeclarationDescriptor, second: DeclarationDescriptor) = - first.containingDeclaration == second.containingDeclaration + first.containingDeclaration == second.containingDeclaration } private val enumClassSelectors = EnumNameMapping() @@ -440,13 +446,13 @@ class ObjCExportNamerImpl( } override fun getClassOrProtocolName(descriptor: ClassDescriptor): ObjCExportNamer.ClassOrProtocolName = - ObjCExportNamer.ClassOrProtocolName( - swiftName = getClassOrProtocolSwiftName(descriptor), - objCName = getClassOrProtocolObjCName(descriptor) - ) + ObjCExportNamer.ClassOrProtocolName( + swiftName = getClassOrProtocolSwiftName(descriptor), + objCName = getClassOrProtocolObjCName(descriptor) + ) private fun getClassOrProtocolSwiftName( - descriptor: ClassDescriptor + descriptor: ClassDescriptor, ): String = swiftClassAndProtocolNames.getOrPut(descriptor) { StringBuilder().apply { val objCName = descriptor.getObjCName() @@ -466,19 +472,19 @@ class ObjCExportNamerImpl( } private fun StringBuilder.appendSwiftNameWithContainer( - clazz: ClassDescriptor, - objCName: ObjCName, - containingClass: ClassDescriptor + clazz: ClassDescriptor, + objCName: ObjCName, + containingClass: ClassDescriptor, ) = helper.appendNameWithContainer( - this, - clazz, objCName.asIdentifier(true), - containingClass, getClassOrProtocolSwiftName(containingClass), - object : ObjCExportNamingHelper.ClassInfoProvider { - override fun hasGenerics(clazz: ClassDescriptor): Boolean = - clazz.typeConstructor.parameters.isNotEmpty() + this, + clazz, objCName.asIdentifier(true), + containingClass, getClassOrProtocolSwiftName(containingClass), + object : ObjCExportNamingHelper.ClassInfoProvider { + override fun hasGenerics(clazz: ClassDescriptor): Boolean = + clazz.typeConstructor.parameters.isNotEmpty() - override fun isInterface(clazz: ClassDescriptor): Boolean = clazz.isInterface - } + override fun isInterface(clazz: ClassDescriptor): Boolean = clazz.isInterface + } ) private fun getClassOrProtocolObjCName(descriptor: ClassDescriptor): String { @@ -492,7 +498,7 @@ class ObjCExportNamerImpl( val containingDeclaration = descriptor.containingDeclaration if (containingDeclaration is ClassDescriptor) { append(getClassOrProtocolObjCName(containingDeclaration)) - .append(objCName.asIdentifier(false).replaceFirstChar(Char::uppercaseChar)) + .append(objCName.asIdentifier(false).replaceFirstChar(Char::uppercaseChar)) } else if (containingDeclaration is PackageFragmentDescriptor) { append(topLevelNamePrefix).appendTopLevelClassBaseName(descriptor, objCName, false) } else { @@ -537,12 +543,14 @@ class ObjCExportNamerImpl( } if (index == 0) { - append(when { - bridge is MethodBridgeValueParameter.ErrorOutParameter -> "AndReturn" - bridge is MethodBridgeValueParameter.SuspendCompletion -> "With" - method is ConstructorDescriptor -> "With" - else -> "" - }) + append( + when { + bridge is MethodBridgeValueParameter.ErrorOutParameter -> "AndReturn" + bridge is MethodBridgeValueParameter.SuspendCompletion -> "With" + method is ConstructorDescriptor -> "With" + else -> "" + } + ) append(name.replaceFirstChar(Char::uppercaseChar)) } else { append(name) @@ -618,8 +626,8 @@ class ObjCExportNamerImpl( } } return ObjCExportNamer.PropertyName( - swiftName = swiftPropertyNames.getOrPut(true), - objCName = objCPropertyNames.getOrPut(false) + swiftName = swiftPropertyNames.getOrPut(true), + objCName = objCPropertyNames.getOrPut(false) ) } @@ -628,7 +636,7 @@ class ObjCExportNamerImpl( return objectInstanceSelectors.getOrPut(descriptor) { val name = descriptor.getObjCName().asString(false) - .replaceFirstChar(Char::lowercaseChar).toIdentifier().mangleIfSpecialFamily("get") + .replaceFirstChar(Char::lowercaseChar).toIdentifier().mangleIfSpecialFamily("get") StringBuilder(name).mangledBySuffixUnderscores() } } @@ -701,9 +709,9 @@ class ObjCExportNamerImpl( val any = builtIns.any val predefinedClassNames = mapOf( - builtIns.any to kotlinAnyName, - builtIns.mutableSet to mutableSetName, - builtIns.mutableMap to mutableMapName + builtIns.any to kotlinAnyName, + builtIns.mutableSet to mutableSetName, + builtIns.mutableMap to mutableMapName ) predefinedClassNames.forEach { (descriptor, name) -> @@ -712,10 +720,10 @@ class ObjCExportNamerImpl( } fun ClassDescriptor.method(name: Name) = - this.unsubstitutedMemberScope.getContributedFunctions( - name, - NoLookupLocation.FROM_BACKEND - ).single() + this.unsubstitutedMemberScope.getContributedFunctions( + name, + NoLookupLocation.FROM_BACKEND + ).single() Predefined.anyMethodSelectors.forEach { (name, selector) -> methodSelectors.forceAssign(any.method(name), selector) @@ -728,21 +736,21 @@ class ObjCExportNamerImpl( private object Predefined { val anyMethodSelectors = mapOf( - "hashCode" to "hash", - "toString" to "description", - "equals" to "isEqual:" + "hashCode" to "hash", + "toString" to "description", + "equals" to "isEqual:" ).mapKeys { Name.identifier(it.key) } val anyMethodSwiftNames = mapOf( - "hashCode" to "hash()", - "toString" to "description()", - "equals" to "isEqual(_:)" + "hashCode" to "hash()", + "toString" to "description()", + "equals" to "isEqual(_:)" ).mapKeys { Name.identifier(it.key) } } private object Reserved { val propertyNames = cKeywords + - setOf("description") // https://youtrack.jetbrains.com/issue/KT-38641 + setOf("description") // https://youtrack.jetbrains.com/issue/KT-38641 } private fun FunctionDescriptor.getMangledName(forSwift: Boolean): String { @@ -777,7 +785,7 @@ class ObjCExportNamerImpl( } private fun String.startsWithWords(words: String) = this.startsWith(words) && - (this.length == words.length || !this[words.length].isLowerCase()) + (this.length == words.length || !this[words.length].isLowerCase()) private inner class GenericTypeParameterNameMapping { private val elementToName = mutableMapOf() @@ -818,7 +826,7 @@ class ObjCExportNamerImpl( assert(element.containingDeclaration is ClassDescriptor) return !objCClassNames.nameExists(name) && !objCProtocolNames.nameExists(name) && - (local || name !in classNameSet(element)) + (local || name !in classNameSet(element)) } private fun classNameSet(element: TypeParameterDescriptor): MutableSet { @@ -893,14 +901,18 @@ class ObjCExportNamerImpl( } private inline fun StringBuilder.mangledSequence(crossinline mangle: StringBuilder.() -> Unit) = - generateSequence(this.toString()) { - this@mangledSequence.mangle() - this@mangledSequence.toString() - } + generateSequence(this.toString()) { + this@mangledSequence.mangle() + this@mangledSequence.toString() + } private fun StringBuilder.mangledBySuffixUnderscores() = this.mangledSequence { append("_") } -private fun ObjCExportMapper.canHaveCommonSubtype(first: ClassDescriptor, second: ClassDescriptor, ignoreInterfaceMethodCollisions: Boolean): Boolean { +private fun ObjCExportMapper.canHaveCommonSubtype( + first: ClassDescriptor, + second: ClassDescriptor, + ignoreInterfaceMethodCollisions: Boolean, +): Boolean { if (first.isSubclassOf(second) || second.isSubclassOf(first)) { return true } @@ -913,13 +925,13 @@ private fun ObjCExportMapper.canHaveCommonSubtype(first: ClassDescriptor, second } private fun ObjCExportMapper.canBeInheritedBySameClass( - first: CallableMemberDescriptor, - second: CallableMemberDescriptor, - ignoreInterfaceMethodCollisions: Boolean + first: CallableMemberDescriptor, + second: CallableMemberDescriptor, + ignoreInterfaceMethodCollisions: Boolean, ): Boolean { if (this.isTopLevel(first) || this.isTopLevel(second)) { return this.isTopLevel(first) && this.isTopLevel(second) && - first.propertyIfAccessor.findSourceFile() == second.propertyIfAccessor.findSourceFile() + first.propertyIfAccessor.findSourceFile() == second.propertyIfAccessor.findSourceFile() } val firstClass = this.getClassIfCategory(first) ?: first.containingDeclaration as ClassDescriptor @@ -936,7 +948,11 @@ private fun ObjCExportMapper.canBeInheritedBySameClass( return canHaveCommonSubtype(firstClass, secondClass, ignoreInterfaceMethodCollisions) } -private fun ObjCExportMapper.canHaveSameSelector(first: FunctionDescriptor, second: FunctionDescriptor, ignoreInterfaceMethodCollisions: Boolean): Boolean { +private fun ObjCExportMapper.canHaveSameSelector( + first: FunctionDescriptor, + second: FunctionDescriptor, + ignoreInterfaceMethodCollisions: Boolean, +): Boolean { assert(isBaseMethod(first)) assert(isBaseMethod(second)) @@ -968,7 +984,11 @@ private fun ObjCExportMapper.canHaveSameSelector(first: FunctionDescriptor, seco return bridgeMethod(first) == bridgeMethod(second) } -private fun ObjCExportMapper.canHaveSameName(first: PropertyDescriptor, second: PropertyDescriptor, ignoreInterfaceMethodCollisions: Boolean): Boolean { +private fun ObjCExportMapper.canHaveSameName( + first: PropertyDescriptor, + second: PropertyDescriptor, + ignoreInterfaceMethodCollisions: Boolean, +): Boolean { assert(isBaseProperty(first)) assert(isObjCProperty(first)) assert(isBaseProperty(second)) @@ -991,17 +1011,17 @@ private fun ObjCExportMapper.canHaveSameName(first: PropertyDescriptor, second: } private class ObjCName( - private val kotlinName: String, - private val objCName: String?, - private val swiftName: String?, - val isExact: Boolean + private val kotlinName: String, + private val objCName: String?, + private val swiftName: String?, + val isExact: Boolean, ) { // TODO: Prevent mangling when objCName or swiftName is provided fun asString(forSwift: Boolean): String = swiftName.takeIf { forSwift } ?: objCName ?: kotlinName fun asIdentifier(forSwift: Boolean, default: (String) -> String = { it.toIdentifier() }): String = - swiftName.takeIf { forSwift } ?: objCName ?: default(kotlinName) + swiftName.takeIf { forSwift } ?: objCName ?: default(kotlinName) } private fun DeclarationDescriptor.getObjCName(): ObjCName { @@ -1019,7 +1039,7 @@ private fun DeclarationDescriptor.getObjCName(): ObjCName { private fun T.upcast(): T = this private fun CallableDescriptor.getObjCName(): ObjCName = - overriddenDescriptors.firstOrNull()?.getObjCName() ?: upcast().getObjCName() + overriddenDescriptors.firstOrNull()?.getObjCName() ?: upcast().getObjCName() private fun ParameterDescriptor.getObjCName(): ObjCName { val callableDescriptor = containingDeclaration as? CallableDescriptor ?: return upcast().getObjCName() @@ -1053,7 +1073,7 @@ private fun KtClassOrObject.getObjCName(): ObjCName { } fun ValueArgument.getBooleanValue(): Boolean = - (getArgumentExpression() as? KtConstantExpression)?.text?.toBooleanStrictOrNull() ?: false + (getArgumentExpression() as? KtConstantExpression)?.text?.toBooleanStrictOrNull() ?: false val argNames = setOf("name", "swiftName", "exact") val processedArgs = mutableSetOf() @@ -1070,26 +1090,27 @@ private fun KtClassOrObject.getObjCName(): ObjCName { return ObjCName(name!!, objCName, swiftName, isExact) } -internal val ModuleDescriptor.objCExportAdditionalNamePrefix: String get() { - if (this.isNativeStdlib()) return "Kotlin" +internal val ModuleDescriptor.objCExportAdditionalNamePrefix: String + get() { + if (this.isNativeStdlib()) return "Kotlin" - val fullPrefix = when(val module = this.klibModuleOrigin) { - CurrentKlibModuleOrigin -> - error("expected deserialized module, got $this (origin = $module)") - SyntheticModulesOrigin -> - this.name.asString().let { it.substring(1, it.lastIndex) } - is DeserializedKlibModuleOrigin -> - module.library.let { it.shortName ?: it.uniqueName } + val fullPrefix = when (val module = this.klibModuleOrigin) { + CurrentKlibModuleOrigin -> + error("expected deserialized module, got $this (origin = $module)") + SyntheticModulesOrigin -> + this.name.asString().let { it.substring(1, it.lastIndex) } + is DeserializedKlibModuleOrigin -> + module.library.let { it.shortName ?: it.uniqueName } + } + + return abbreviate(fullPrefix) } - return abbreviate(fullPrefix) -} - fun abbreviate(name: String): String { val normalizedName = name - .replaceFirstChar(Char::uppercaseChar) - .replace("-|\\.".toRegex(), "_") + .replaceFirstChar(Char::uppercaseChar) + .replace("-|\\.".toRegex(), "_") val uppers = normalizedName.filterIndexed { index, character -> index == 0 || character.isUpperCase() } if (uppers.length >= 3) return uppers @@ -1104,8 +1125,8 @@ internal fun String.toValidObjCSwiftIdentifier(): String { if (this.isEmpty()) return "__" return this.replace('$', '_') // TODO: handle more special characters. - .let { if (it.first().isDigit()) "_$it" else it } - .let { if (it == "_") "__" else it } + .let { if (it.first().isDigit()) "_$it" else it } + .let { if (it == "_") "__" else it } } // Private shortcut. diff --git a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportScope.kt b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportScope.kt index daee7d38492..66f739a711b 100644 --- a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportScope.kt +++ b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportScope.kt @@ -22,7 +22,7 @@ interface ObjCExportScope { fun deriveForType(kotlinType: KotlinType): ObjCTypeExportScope = ObjCTypeExportScopeImpl(kotlinType, this) fun deriveForClass(container: DeclarationDescriptor, namer: ObjCExportNamer): ObjCClassExportScope = - ObjCClassExportScopeImpl(container, namer, this) + ObjCClassExportScopeImpl(container, namer, this) } internal inline fun ObjCExportScope.nearestScopeOfType(): T? { @@ -44,16 +44,16 @@ interface ObjCClassExportScope : ObjCExportScope { } private class ObjCClassExportScopeImpl constructor( - container: DeclarationDescriptor, - val namer: ObjCExportNamer, - override val parent: ObjCExportScope?, + container: DeclarationDescriptor, + val namer: ObjCExportNamer, + override val parent: ObjCExportScope?, ) : ObjCClassExportScope { private val typeParameterNames: List = - if (container is ClassDescriptor && !container.isInterface) { - container.typeConstructor.parameters - } else { - emptyList() - } + if (container is ClassDescriptor && !container.isInterface) { + container.typeConstructor.parameters + } else { + emptyList() + } override fun getGenericTypeUsage(typeParameterDescriptor: TypeParameterDescriptor?): ObjCGenericTypeUsage? { return typeParameterDescriptor?.let { descriptor -> diff --git a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportTranslatorMobile.kt b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportTranslatorMobile.kt index aefb97d1f0a..ee03b6b685b 100644 --- a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportTranslatorMobile.kt +++ b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportTranslatorMobile.kt @@ -12,7 +12,15 @@ class ObjCExportTranslatorMobile internal constructor(private val delegate: ObjC companion object { fun create(namer: ObjCExportNamer, configuration: ObjCExportLazy.Configuration): ObjCExportTranslatorMobile { val mapper = ObjCExportMapper(local = true, unitSuspendFunctionExport = configuration.unitSuspendFunctionExport) - return ObjCExportTranslatorMobile(ObjCExportTranslatorImpl(null, mapper, namer, ObjCExportProblemCollector.SILENT, configuration.objcGenerics)) + return ObjCExportTranslatorMobile( + ObjCExportTranslatorImpl( + null, + mapper, + namer, + ObjCExportProblemCollector.SILENT, + configuration.objcGenerics + ) + ) } } diff --git a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportedInterface.kt b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportedInterface.kt index ea02f1a1a9e..4c75849d0b3 100644 --- a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportedInterface.kt +++ b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportedInterface.kt @@ -17,5 +17,5 @@ class ObjCExportedInterface internal constructor( val topLevel: Map>, val headerLines: List, val namer: ObjCExportNamer, - val mapper: ObjCExportMapper + val mapper: ObjCExportMapper, ) \ No newline at end of file diff --git a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportedStubs.kt b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportedStubs.kt index 38bdd428e40..9529776a249 100644 --- a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportedStubs.kt +++ b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportedStubs.kt @@ -8,5 +8,5 @@ package org.jetbrains.kotlin.backend.konan.objcexport data class ObjCExportedStubs( val classForwardDeclarations: Set, val protocolForwardDeclarations: Set, - val stubs: List> + val stubs: List>, ) \ No newline at end of file diff --git a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCHeaderWriter.kt b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCHeaderWriter.kt index 3ee3471db43..48df8661b09 100644 --- a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCHeaderWriter.kt +++ b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjCHeaderWriter.kt @@ -11,9 +11,9 @@ import org.jetbrains.kotlin.konan.file.File // Later it will accept an object with ObjC declarations instead of lines. class ObjCHeaderWriter { fun write( - headerName: String, - headerLines: List, - headersDirectory: File, + headerName: String, + headerLines: List, + headersDirectory: File, ) { headersDirectory.child(headerName).writeLines(headerLines) } diff --git a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjcExportHeaderGeneratorMobile.kt b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjcExportHeaderGeneratorMobile.kt index 2034274d65b..06cdbf87a1c 100644 --- a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjcExportHeaderGeneratorMobile.kt +++ b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/ObjcExportHeaderGeneratorMobile.kt @@ -7,23 +7,24 @@ import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver import org.jetbrains.kotlin.resolve.descriptorUtil.module class ObjcExportHeaderGeneratorMobile internal constructor( - moduleDescriptors: List, - mapper: ObjCExportMapper, - namer: ObjCExportNamer, - problemCollector: ObjCExportProblemCollector, - objcGenerics: Boolean, - private val restrictToLocalModules: Boolean + moduleDescriptors: List, + mapper: ObjCExportMapper, + namer: ObjCExportNamer, + problemCollector: ObjCExportProblemCollector, + objcGenerics: Boolean, + private val restrictToLocalModules: Boolean, ) : ObjCExportHeaderGenerator(moduleDescriptors, mapper, namer, objcGenerics, problemCollector) { companion object { fun createInstance( - configuration: ObjCExportLazy.Configuration, - problemCollector: ObjCExportProblemCollector, - builtIns: KotlinBuiltIns, - moduleDescriptors: List, - deprecationResolver: DeprecationResolver? = null, - local: Boolean = false, - restrictToLocalModules: Boolean = false): ObjCExportHeaderGenerator { + configuration: ObjCExportLazy.Configuration, + problemCollector: ObjCExportProblemCollector, + builtIns: KotlinBuiltIns, + moduleDescriptors: List, + deprecationResolver: DeprecationResolver? = null, + local: Boolean = false, + restrictToLocalModules: Boolean = false, + ): ObjCExportHeaderGenerator { val mapper = ObjCExportMapper(deprecationResolver, local, configuration.unitSuspendFunctionExport) val namerConfiguration = createNamerConfiguration(configuration) val namer = ObjCExportNamerImpl(namerConfiguration, builtIns, mapper, problemCollector, local) diff --git a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/StubRenderer.kt b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/StubRenderer.kt index 1a1165432d8..d4c7d61d4af 100644 --- a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/StubRenderer.kt +++ b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/StubRenderer.kt @@ -5,11 +5,11 @@ package org.jetbrains.kotlin.backend.konan.objcexport +import org.jetbrains.kotlin.backend.common.serialization.extractSerializedKdocString +import org.jetbrains.kotlin.backend.common.serialization.metadata.findKDocString import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource -import org.jetbrains.kotlin.backend.common.serialization.extractSerializedKdocString -import org.jetbrains.kotlin.backend.common.serialization.metadata.findKDocString object StubRenderer { fun render(stub: Stub<*>): List = render(stub, false) @@ -39,7 +39,8 @@ object StubRenderer { if (it.startsWith("/**") && it.endsWith("*/")) { // Nested comment is allowed inside of preformatted ``` block in kdoc but not in ObjC val kdocClean = "/**${it.substring(3, it.length - 2).replace("*/", "**").replace("/*", "**")}$kDocEnding" - kdocClean.lines().map { it.trim().let { + kdocClean.lines().map { + it.trim().let { if (it.isNotEmpty() && it[0] == '*') " $it" else it } @@ -51,7 +52,7 @@ object StubRenderer { val kDocAndComment = kDoc?.filterNot { it.isEmpty() }.orEmpty().toMutableList() comment?.contentLines?.let { commentLine -> if (!kDoc.isNullOrEmpty()) kDocAndComment.add(" *") // Separator between nonempty kDoc and nonempty comment - commentLine.forEach { kDocAndComment.add(findPositionToInsertGeneratedCommentLine(kDocAndComment, it), " * $it")} + commentLine.forEach { kDocAndComment.add(findPositionToInsertGeneratedCommentLine(kDocAndComment, it), " * $it") } } if (kDocAndComment.isNotEmpty()) { +"" // Probably makes the output more readable. @@ -137,8 +138,10 @@ object StubRenderer { } fun appendParameters() { - assert(method.selectors.size == method.parameters.size || - method.selectors.size == 1 && method.parameters.size == 0) + assert( + method.selectors.size == method.parameters.size || + method.selectors.size == 1 && method.parameters.size == 0 + ) if (method.selectors.size == 1 && method.parameters.size == 0) { append(method.selectors[0]) @@ -248,5 +251,5 @@ fun formatGenerics(buffer: Appendable, generics: List) { private fun DeclarationDescriptor.extractKDocString(): String? { return (this as? DeclarationDescriptorWithSource)?.findKDocString() - ?: extractSerializedKdocString() + ?: extractSerializedKdocString() } diff --git a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/objcTypes.kt b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/objcTypes.kt index 8740c604144..cc6cf1b008b 100644 --- a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/objcTypes.kt +++ b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/objcTypes.kt @@ -17,11 +17,11 @@ sealed class ObjCType { fun render() = render("") protected fun String.withAttrsAndName(attrsAndName: String) = - if (attrsAndName.isEmpty()) this else "$this ${attrsAndName.trimStart()}" + if (attrsAndName.isEmpty()) this else "$this ${attrsAndName.trimStart()}" } data class ObjCRawType( - val rawText: String + val rawText: String, ) : ObjCType() { override fun render(attrsAndName: String): String = rawText.withAttrsAndName(attrsAndName) } @@ -31,8 +31,8 @@ sealed class ObjCReferenceType : ObjCType() sealed class ObjCNonNullReferenceType : ObjCReferenceType() data class ObjCNullableReferenceType( - val nonNullType: ObjCNonNullReferenceType, - val isNullableResult: Boolean = false + val nonNullType: ObjCNonNullReferenceType, + val isNullableResult: Boolean = false, ) : ObjCReferenceType() { override fun render(attrsAndName: String): String { val attribute = if (isNullableResult) objcNullableResultAttribute else objcNullableAttribute @@ -41,8 +41,8 @@ data class ObjCNullableReferenceType( } data class ObjCClassType( - val className: String, - val typeArguments: List = emptyList() + val className: String, + val typeArguments: List = emptyList(), ) : ObjCNonNullReferenceType() { override fun render(attrsAndName: String) = buildString { @@ -57,7 +57,7 @@ data class ObjCClassType( } } -sealed class ObjCGenericTypeUsage: ObjCNonNullReferenceType() { +sealed class ObjCGenericTypeUsage : ObjCNonNullReferenceType() { abstract val typeName: String final override fun render(attrsAndName: String): String { return typeName.withAttrsAndName(attrsAndName) @@ -67,15 +67,15 @@ sealed class ObjCGenericTypeUsage: ObjCNonNullReferenceType() { data class ObjCGenericTypeRawUsage(override val typeName: String) : ObjCGenericTypeUsage() data class ObjCGenericTypeParameterUsage( - val typeParameterDescriptor: TypeParameterDescriptor, - val namer: ObjCExportNamer + val typeParameterDescriptor: TypeParameterDescriptor, + val namer: ObjCExportNamer, ) : ObjCGenericTypeUsage() { override val typeName: String get() = namer.getTypeParameterName(typeParameterDescriptor) } data class ObjCProtocolType( - val protocolName: String + val protocolName: String, ) : ObjCNonNullReferenceType() { override fun render(attrsAndName: String) = "id<$protocolName>".withAttrsAndName(attrsAndName) } @@ -89,8 +89,8 @@ object ObjCInstanceType : ObjCNonNullReferenceType() { } data class ObjCBlockPointerType( - val returnType: ObjCType, - val parameterTypes: List + val returnType: ObjCType, + val parameterTypes: List, ) : ObjCNonNullReferenceType() { override fun render(attrsAndName: String) = returnType.render(buildString { @@ -108,7 +108,7 @@ object ObjCMetaClassType : ObjCNonNullReferenceType() { } sealed class ObjCPrimitiveType( - val cName: String + val cName: String, ) : ObjCType() { object NSUInteger : ObjCPrimitiveType("NSUInteger") object BOOL : ObjCPrimitiveType("BOOL") @@ -125,29 +125,33 @@ sealed class ObjCPrimitiveType( object double : ObjCPrimitiveType("double") object NSInteger : ObjCPrimitiveType("NSInteger") object char : ObjCPrimitiveType("char") - object unsigned_char: ObjCPrimitiveType("unsigned char") - object unsigned_short: ObjCPrimitiveType("unsigned short") - object int: ObjCPrimitiveType("int") - object unsigned_int: ObjCPrimitiveType("unsigned int") - object long: ObjCPrimitiveType("long") - object unsigned_long: ObjCPrimitiveType("unsigned long") - object long_long: ObjCPrimitiveType("long long") - object unsigned_long_long: ObjCPrimitiveType("unsigned long long") - object short: ObjCPrimitiveType("short") + object unsigned_char : ObjCPrimitiveType("unsigned char") + object unsigned_short : ObjCPrimitiveType("unsigned short") + object int : ObjCPrimitiveType("int") + object unsigned_int : ObjCPrimitiveType("unsigned int") + object long : ObjCPrimitiveType("long") + object unsigned_long : ObjCPrimitiveType("unsigned long") + object long_long : ObjCPrimitiveType("long long") + object unsigned_long_long : ObjCPrimitiveType("unsigned long long") + object short : ObjCPrimitiveType("short") override fun render(attrsAndName: String) = cName.withAttrsAndName(attrsAndName) } data class ObjCPointerType( - val pointee: ObjCType, - val nullable: Boolean = false + val pointee: ObjCType, + val nullable: Boolean = false, ) : ObjCType() { override fun render(attrsAndName: String) = - pointee.render("*${if (nullable) { - " $objcNullableAttribute".withAttrsAndName(attrsAndName) - } else { - attrsAndName - }}") + pointee.render( + "*${ + if (nullable) { + " $objcNullableAttribute".withAttrsAndName(attrsAndName) + } else { + attrsAndName + } + }" + ) } object ObjCVoidType : ObjCType() { @@ -158,6 +162,7 @@ object ObjCVoidType : ObjCType() { enum class ObjCValueType(val encoding: String) { BOOL("c"), UNICHAR("S"), + // TODO: Switch to explicit SIGNED_CHAR CHAR("c"), SHORT("s"), @@ -193,13 +198,13 @@ sealed class ObjCGenericTypeDeclaration { } data class ObjCGenericTypeRawDeclaration( - override val typeName: String, - override val variance: ObjCVariance = ObjCVariance.INVARIANT + override val typeName: String, + override val variance: ObjCVariance = ObjCVariance.INVARIANT, ) : ObjCGenericTypeDeclaration() data class ObjCGenericTypeParameterDeclaration( - val typeParameterDescriptor: TypeParameterDescriptor, - val namer: ObjCExportNamer + val typeParameterDescriptor: TypeParameterDescriptor, + val namer: ObjCExportNamer, ) : ObjCGenericTypeDeclaration() { override val typeName: String get() = namer.getTypeParameterName(typeParameterDescriptor) diff --git a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/stubs.kt b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/stubs.kt index 0e3b65fad82..d2033e3cd93 100644 --- a/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/stubs.kt +++ b/native/objcexport-header-generator/src/main/kotlin/org/jetbrains/kotlin/backend/konan/objcexport/stubs.kt @@ -6,7 +6,10 @@ package org.jetbrains.kotlin.backend.konan.objcexport import com.intellij.psi.PsiElement -import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource +import org.jetbrains.kotlin.descriptors.ParameterDescriptor import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.source.PsiSourceElement @@ -15,8 +18,8 @@ class ObjCComment(val contentLines: List) { } data class ObjCClassForwardDeclaration( - val className: String, - val typeDeclarations: List = emptyList() + val className: String, + val typeDeclarations: List = emptyList(), ) abstract class Stub(val name: String, val comment: ObjCComment? = null) { @@ -29,78 +32,89 @@ abstract class Stub(val name: String, val comment abstract class ObjCTopLevel(name: String, comment: ObjCComment? = null) : Stub(name, comment) -abstract class ObjCClass(name: String, - val attributes: List, - comment: ObjCComment? = null) : ObjCTopLevel(name, comment) { +abstract class ObjCClass( + name: String, + val attributes: List, + comment: ObjCComment? = null, +) : ObjCTopLevel(name, comment) { abstract val superProtocols: List abstract val members: List> } -abstract class ObjCProtocol(name: String, - attributes: List, - comment: ObjCComment? = null) : ObjCClass(name, attributes, comment) +abstract class ObjCProtocol( + name: String, + attributes: List, + comment: ObjCComment? = null, +) : ObjCClass(name, attributes, comment) class ObjCProtocolImpl( - name: String, - override val descriptor: ClassDescriptor, - override val superProtocols: List, - override val members: List>, - attributes: List = emptyList(), - comment: ObjCComment? = null) : ObjCProtocol(name, attributes, comment) + name: String, + override val descriptor: ClassDescriptor, + override val superProtocols: List, + override val members: List>, + attributes: List = emptyList(), + comment: ObjCComment? = null, +) : ObjCProtocol(name, attributes, comment) -abstract class ObjCInterface(name: String, - val generics: List, - val categoryName: String?, - attributes: List, - comment: ObjCComment? = null) : ObjCClass(name, attributes, comment) { +abstract class ObjCInterface( + name: String, + val generics: List, + val categoryName: String?, + attributes: List, + comment: ObjCComment? = null, +) : ObjCClass(name, attributes, comment) { abstract val superClass: String? abstract val superClassGenerics: List } class ObjCInterfaceImpl( - name: String, - generics: List = emptyList(), - override val descriptor: ClassDescriptor? = null, - override val superClass: String? = null, - override val superClassGenerics: List = emptyList(), - override val superProtocols: List = emptyList(), - categoryName: String? = null, - override val members: List> = emptyList(), - attributes: List = emptyList(), - comment: ObjCComment? = null + name: String, + generics: List = emptyList(), + override val descriptor: ClassDescriptor? = null, + override val superClass: String? = null, + override val superClassGenerics: List = emptyList(), + override val superProtocols: List = emptyList(), + categoryName: String? = null, + override val members: List> = emptyList(), + attributes: List = emptyList(), + comment: ObjCComment? = null, ) : ObjCInterface(name, generics, categoryName, attributes, comment) class ObjCMethod( - override val descriptor: DeclarationDescriptor?, - val isInstanceMethod: Boolean, - val returnType: ObjCType, - val selectors: List, - val parameters: List, - val attributes: List, - comment: ObjCComment? = null + override val descriptor: DeclarationDescriptor?, + val isInstanceMethod: Boolean, + val returnType: ObjCType, + val selectors: List, + val parameters: List, + val attributes: List, + comment: ObjCComment? = null, ) : Stub(buildMethodName(selectors, parameters), comment) -class ObjCParameter(name: String, - override val descriptor: ParameterDescriptor?, - val type: ObjCType) : Stub(name) +class ObjCParameter( + name: String, + override val descriptor: ParameterDescriptor?, + val type: ObjCType, +) : Stub(name) -class ObjCProperty(name: String, - override val descriptor: DeclarationDescriptorWithSource?, - val type: ObjCType, - val propertyAttributes: List, - val setterName: String? = null, - val getterName: String? = null, - val declarationAttributes: List = emptyList(), - comment: ObjCComment? = null) : Stub(name, comment) { +class ObjCProperty( + name: String, + override val descriptor: DeclarationDescriptorWithSource?, + val type: ObjCType, + val propertyAttributes: List, + val setterName: String? = null, + val getterName: String? = null, + val declarationAttributes: List = emptyList(), + comment: ObjCComment? = null, +) : Stub(name, comment) { @Deprecated("", ReplaceWith("this.propertyAttributes"), DeprecationLevel.WARNING) val attributes: List get() = propertyAttributes } private fun buildMethodName(selectors: List, parameters: List): String = - if (selectors.size == 1 && parameters.size == 0) { - selectors[0] - } else { - assert(selectors.size == parameters.size) - selectors.joinToString(separator = "") - } + if (selectors.size == 1 && parameters.size == 0) { + selectors[0] + } else { + assert(selectors.size == parameters.size) + selectors.joinToString(separator = "") + } diff --git a/native/objcexport-header-generator/src/test/kotlin/org/jetbrains/kotlin/backend/konan/testUtils/AbstractObjCExportHeaderGeneratorTest.kt b/native/objcexport-header-generator/src/test/kotlin/org/jetbrains/kotlin/backend/konan/testUtils/AbstractObjCExportHeaderGeneratorTest.kt index 49b0303aa0f..b1d84fa1431 100644 --- a/native/objcexport-header-generator/src/test/kotlin/org/jetbrains/kotlin/backend/konan/testUtils/AbstractObjCExportHeaderGeneratorTest.kt +++ b/native/objcexport-header-generator/src/test/kotlin/org/jetbrains/kotlin/backend/konan/testUtils/AbstractObjCExportHeaderGeneratorTest.kt @@ -13,7 +13,7 @@ import java.io.File import kotlin.test.fail abstract class AbstractObjCExportHeaderGeneratorTest( - private val generator: ObjCExportHeaderGenerator + private val generator: ObjCExportHeaderGenerator, ) { fun interface ObjCExportHeaderGenerator { diff --git a/native/objcexport-header-generator/src/test/kotlin/org/jetbrains/kotlin/backend/konan/testUtils/Fe10Utils.kt b/native/objcexport-header-generator/src/test/kotlin/org/jetbrains/kotlin/backend/konan/testUtils/Fe10Utils.kt index 3d1387ec799..8dcf179c1b7 100644 --- a/native/objcexport-header-generator/src/test/kotlin/org/jetbrains/kotlin/backend/konan/testUtils/Fe10Utils.kt +++ b/native/objcexport-header-generator/src/test/kotlin/org/jetbrains/kotlin/backend/konan/testUtils/Fe10Utils.kt @@ -39,7 +39,7 @@ import java.io.File fun createModuleDescriptor( environment: KotlinCoreEnvironment, tempDir: File, - kotlinSources: List + kotlinSources: List, ): ModuleDescriptor { val testModuleRoot = tempDir.resolve("testModule") testModuleRoot.mkdirs() @@ -74,7 +74,7 @@ fun createModuleDescriptor( } fun createKotlinCoreEnvironment( - disposable: Disposable, compilerConfiguration: CompilerConfiguration = createCompilerConfiguration() + disposable: Disposable, compilerConfiguration: CompilerConfiguration = createCompilerConfiguration(), ): KotlinCoreEnvironment { return KotlinCoreEnvironment.createForTests( parentDisposable = disposable, diff --git a/native/objcexport-header-generator/src/test/kotlin/org/jetbrains/kotlin/backend/konan/testUtils/ObjCExportUtils.kt b/native/objcexport-header-generator/src/test/kotlin/org/jetbrains/kotlin/backend/konan/testUtils/ObjCExportUtils.kt index 2911d17380d..b6374c7828c 100644 --- a/native/objcexport-header-generator/src/test/kotlin/org/jetbrains/kotlin/backend/konan/testUtils/ObjCExportUtils.kt +++ b/native/objcexport-header-generator/src/test/kotlin/org/jetbrains/kotlin/backend/konan/testUtils/ObjCExportUtils.kt @@ -18,7 +18,7 @@ import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver internal fun createObjCExportNamerConfiguration( topLevelNamePrefix: String = "", - additionalPrefix: (moduleName: Name) -> String? = { null } + additionalPrefix: (moduleName: Name) -> String? = { null }, ): ObjCExportNamer.Configuration { return object : ObjCExportNamer.Configuration { override val topLevelNamePrefix: String get() = topLevelNamePrefix @@ -30,7 +30,7 @@ internal fun createObjCExportNamerConfiguration( internal fun createObjCExportMapper( deprecationResolver: DeprecationResolver? = null, local: Boolean = false, - unitSuspendFunctionObjCExport: UnitSuspendFunctionObjCExport = UnitSuspendFunctionObjCExport.DEFAULT + unitSuspendFunctionObjCExport: UnitSuspendFunctionObjCExport = UnitSuspendFunctionObjCExport.DEFAULT, ): ObjCExportMapper { return ObjCExportMapper(deprecationResolver, local, unitSuspendFunctionObjCExport) } diff --git a/native/objcexport-header-generator/src/test/kotlin/org/jetbrains/kotlin/backend/konan/tests/ObjCExportMapperTest.kt b/native/objcexport-header-generator/src/test/kotlin/org/jetbrains/kotlin/backend/konan/tests/ObjCExportMapperTest.kt index d96d7dc3a77..780ff9a2eee 100644 --- a/native/objcexport-header-generator/src/test/kotlin/org/jetbrains/kotlin/backend/konan/tests/ObjCExportMapperTest.kt +++ b/native/objcexport-header-generator/src/test/kotlin/org/jetbrains/kotlin/backend/konan/tests/ObjCExportMapperTest.kt @@ -84,9 +84,11 @@ class ObjCExportMapperTest : InlineSourceTestEnvironment { val intClassDescriptor = module.findClassAcrossModuleDependencies(ClassId.fromString("kotlin/Int"))!! /* Represents List */ - val listOfIntType = KotlinTypeFactory.simpleNotNullType(TypeAttributes.Empty, listClassDescriptor, listOf( - TypeProjectionImpl(KotlinTypeFactory.simpleNotNullType(TypeAttributes.Empty, intClassDescriptor, emptyList())) - )) + val listOfIntType = KotlinTypeFactory.simpleNotNullType( + TypeAttributes.Empty, listClassDescriptor, listOf( + TypeProjectionImpl(KotlinTypeFactory.simpleNotNullType(TypeAttributes.Empty, intClassDescriptor, emptyList())) + ) + ) val typeMapper = assertNotNull(objcExportMapper.getCustomTypeMapper(listClassDescriptor)) assertEquals(ClassId.fromString("kotlin/collections/List"), typeMapper.mappedClassId) diff --git a/native/objcexport-header-generator/src/test/kotlin/org/jetbrains/kotlin/backend/konan/tests/ObjCExportNamerTest.kt b/native/objcexport-header-generator/src/test/kotlin/org/jetbrains/kotlin/backend/konan/tests/ObjCExportNamerTest.kt index cb5ad65a9a0..a005399d38d 100644 --- a/native/objcexport-header-generator/src/test/kotlin/org/jetbrains/kotlin/backend/konan/tests/ObjCExportNamerTest.kt +++ b/native/objcexport-header-generator/src/test/kotlin/org/jetbrains/kotlin/backend/konan/tests/ObjCExportNamerTest.kt @@ -96,12 +96,14 @@ class ObjCExportNamerTest : InlineSourceTestEnvironment { val foo = module.getPackage(FqName.ROOT).memberScope.findFirstVariable("foo") { true }!! assertEquals( PropertyName("foo", "foo"), - createObjCExportNamer(createObjCExportNamerConfiguration(topLevelNamePrefix = "X")).getPropertyName(foo)) + createObjCExportNamer(createObjCExportNamerConfiguration(topLevelNamePrefix = "X")).getPropertyName(foo) + ) } @Test fun `test - function inside class`() { - val module = createModuleDescriptor(""" + val module = createModuleDescriptor( + """ package bar class Foo { fun someFunction(a: Int, b: Int) = a + b @@ -117,10 +119,12 @@ class ObjCExportNamerTest : InlineSourceTestEnvironment { @Test fun `test - class with ObjCName annotation`() { - val module = createModuleDescriptor(""" + val module = createModuleDescriptor( + """ @kotlin.native.ObjCName("ObjCFoo", "SwiftFoo") class Foo - """.trimIndent()) + """.trimIndent() + ) val fooClass = module.findClassAcrossModuleDependencies(ClassId.fromString("Foo"))!! assertEquals( @@ -139,10 +143,12 @@ class ObjCExportNamerTest : InlineSourceTestEnvironment { @Test fun `test - parameter with ObjCName annotation`() { - val module = createModuleDescriptor(""" + val module = createModuleDescriptor( + """ import kotlin.native.ObjCName fun foo(@ObjCName("aObjC", "aSwift") a: Int) - """.trimIndent()) + """.trimIndent() + ) val foo = module.getPackage(FqName.ROOT).memberScope.findSingleFunction(Name.identifier("foo")) val parameterA = foo.valueParameters.find { it.name == Name.identifier("a") }!! @@ -152,14 +158,18 @@ class ObjCExportNamerTest : InlineSourceTestEnvironment { @Test fun `test - class mangling`() { val module = createModuleDescriptor { - source(""" + source( + """ package a class Foo - """.trimIndent()) - source(""" + """.trimIndent() + ) + source( + """ package b class Foo - """.trimIndent()) + """.trimIndent() + ) } val aFoo = module.findClassAcrossModuleDependencies(ClassId.fromString("a/Foo"))!! @@ -175,11 +185,13 @@ class ObjCExportNamerTest : InlineSourceTestEnvironment { @Test fun `test - simple enum`() { - val module = createModuleDescriptor(""" + val module = createModuleDescriptor( + """ enum class Foo { A, B, C } - """.trimIndent()) + """.trimIndent() + ) val foo = module.findClassAcrossModuleDependencies(ClassId.fromString("Foo"))!! val fooA = foo.enumEntries.find { it.name == Name.identifier("A") }!!