diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGenerator.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGenerator.kt index b7e5c99ce84..7ccd62f9c7d 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGenerator.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGenerator.kt @@ -729,9 +729,9 @@ internal class ObjCExportTranslatorImpl( private fun mapReturnType(returnBridge: MethodBridge.ReturnValue, method: FunctionDescriptor, objCExportScope: ObjCExportScope): ObjCType = when (returnBridge) { MethodBridge.ReturnValue.Void -> ObjCVoidType - MethodBridge.ReturnValue.HashCode -> ObjCPrimitiveType("NSUInteger") + MethodBridge.ReturnValue.HashCode -> ObjCPrimitiveType.NSUInteger is MethodBridge.ReturnValue.Mapped -> mapType(method.returnType!!, returnBridge.bridge, objCExportScope) - MethodBridge.ReturnValue.WithError.Success -> ObjCPrimitiveType("BOOL") + MethodBridge.ReturnValue.WithError.Success -> ObjCPrimitiveType.BOOL is MethodBridge.ReturnValue.WithError.RefOrNull -> { val successReturnType = mapReturnType(returnBridge.successBridge, method, objCExportScope) as? ObjCNonNullReferenceType ?: error("Function is expected to have non-null return type: $method") @@ -900,18 +900,18 @@ internal class ObjCExportTranslatorImpl( is BlockPointerBridge -> mapFunctionType(kotlinType, objCExportScope, typeBridge) is ValueTypeBridge -> { when (typeBridge.objCValueType) { - ObjCValueType.BOOL -> ObjCPrimitiveType("BOOL") - ObjCValueType.UNICHAR -> ObjCPrimitiveType("unichar") - ObjCValueType.CHAR -> ObjCPrimitiveType("int8_t") - ObjCValueType.SHORT -> ObjCPrimitiveType("int16_t") - ObjCValueType.INT -> ObjCPrimitiveType("int32_t") - ObjCValueType.LONG_LONG -> ObjCPrimitiveType("int64_t") - ObjCValueType.UNSIGNED_CHAR -> ObjCPrimitiveType("uint8_t") - ObjCValueType.UNSIGNED_SHORT -> ObjCPrimitiveType("uint16_t") - ObjCValueType.UNSIGNED_INT -> ObjCPrimitiveType("uint32_t") - ObjCValueType.UNSIGNED_LONG_LONG -> ObjCPrimitiveType("uint64_t") - ObjCValueType.FLOAT -> ObjCPrimitiveType("float") - ObjCValueType.DOUBLE -> ObjCPrimitiveType("double") + ObjCValueType.BOOL -> ObjCPrimitiveType.BOOL + ObjCValueType.UNICHAR -> ObjCPrimitiveType.unichar + ObjCValueType.CHAR -> ObjCPrimitiveType.int8_t + ObjCValueType.SHORT -> ObjCPrimitiveType.int16_t + ObjCValueType.INT -> ObjCPrimitiveType.int32_t + ObjCValueType.LONG_LONG -> ObjCPrimitiveType.int64_t + ObjCValueType.UNSIGNED_CHAR -> ObjCPrimitiveType.uint8_t + ObjCValueType.UNSIGNED_SHORT -> ObjCPrimitiveType.uint16_t + ObjCValueType.UNSIGNED_INT -> ObjCPrimitiveType.uint32_t + ObjCValueType.UNSIGNED_LONG_LONG -> ObjCPrimitiveType.uint64_t + ObjCValueType.FLOAT -> ObjCPrimitiveType.float + ObjCValueType.DOUBLE -> ObjCPrimitiveType.double ObjCValueType.POINTER -> ObjCPointerType(ObjCVoidType, kotlinType.binaryRepresentationIsNullable()) } // TODO: consider other namings. diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportLazy.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportLazy.kt index d83dc5f7e2c..6cde40dc803 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportLazy.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportLazy.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.backend.konan.objcexport +import com.intellij.psi.PsiElement import org.jetbrains.kotlin.analyzer.ModuleInfo import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.* @@ -126,11 +127,7 @@ internal class ObjCExportLazyImpl( // Note: some attributes may be missing (e.g. "unavailable" for unexposed classes). return if (ktClassOrObject.isInterface) { - object : LazyObjCProtocol(name) { - override val descriptor: ClassDescriptor by lazy { resolve(ktClassOrObject) } - - override fun computeRealStub(): ObjCProtocol = translator.translateInterface(descriptor) - } + LazyObjCProtocolImpl(name, ktClassOrObject, this) } else { val isFinal = ktClassOrObject.modalityModifier() == null || ktClassOrObject.hasModifier(KtTokens.FINAL_KEYWORD) @@ -141,16 +138,11 @@ internal class ObjCExportLazyImpl( emptyList() } - object : LazyObjCInterface( - name, - generics = if (configuration.objcGenerics) TODO() else emptyList(), - categoryName = null, - attributes = attributes - ) { - override val descriptor: ClassDescriptor by lazy { resolve(ktClassOrObject) } - - override fun computeRealStub(): ObjCInterface = translator.translateClass(descriptor) - } + LazyObjCInterfaceImpl(name, + attributes, + generics = if (configuration.objcGenerics) TODO() else emptyList(), + psi = ktClassOrObject, + lazy = this) } } @@ -185,23 +177,7 @@ internal class ObjCExportLazyImpl( private fun translateFileClass(file: KtFile, declarations: List): ObjCInterface { val name = nameTranslator.getFileClassName(file) - - return object : LazyObjCInterface( - name, - generics = emptyList(), - categoryName = null, - attributes = listOf(OBJC_SUBCLASSING_RESTRICTED) - ) { - override val descriptor: ClassDescriptor? - get() = null - - override fun computeRealStub(): ObjCInterface = translator.translateFile( - PsiSourceFile(file), - declarations.mapNotNull { declaration -> - resolve(declaration).takeIf { mapper.shouldBeExposed(it) } - } - ) - } + return LazyObjCFileInterface(name, file, declarations, this) } private fun translateExtensions( @@ -217,22 +193,7 @@ internal class ObjCExportLazyImpl( namer.getClassOrProtocolName(classDescriptor) } - return object : LazyObjCInterface( - name.objCName, - generics = emptyList(), - categoryName = nameTranslator.getCategoryName(file), - attributes = emptyList() - ) { - override val descriptor: ClassDescriptor? - get() = null - - override fun computeRealStub(): ObjCInterface = translator.translateExtensions( - classDescriptor, - declarations.mapNotNull { declaration -> - resolve(declaration).takeIf { mapper.shouldBeExposed(it) } - } - ) - } + return LazyObjCExtensionInterface(name, nameTranslator.getCategoryName(file), classDescriptor, declarations, this) } private fun resolveDeclaration(ktDeclaration: KtDeclaration): DeclarationDescriptor = @@ -326,6 +287,71 @@ internal class ObjCExportLazyImpl( return result } + + private class LazyObjCProtocolImpl( + name: ObjCExportNamer.ClassOrProtocolName, + override val psi: KtClassOrObject, + private val lazy: ObjCExportLazyImpl + ) : LazyObjCProtocol(name) { + override val descriptor: ClassDescriptor by lazy { lazy.resolve(psi) } + + override fun computeRealStub(): ObjCProtocol = lazy.translator.translateInterface(descriptor) + } + + private class LazyObjCInterfaceImpl( + name: ObjCExportNamer.ClassOrProtocolName, + attributes: List, + generics: List, + override val psi: KtClassOrObject, + private val lazy: ObjCExportLazyImpl + ) : LazyObjCInterface(name = name, generics = generics, categoryName = null, attributes = attributes) { + override val descriptor: ClassDescriptor by lazy { lazy.resolve(psi) } + + override fun computeRealStub(): ObjCInterface = lazy.translator.translateClass(descriptor) + } + + private class LazyObjCFileInterface( + name: ObjCExportNamer.ClassOrProtocolName, + private val file: KtFile, + private val declarations: List, + private val lazy: ObjCExportLazyImpl + ) : LazyObjCInterface(name = name, generics = emptyList(), categoryName = null, attributes = listOf(OBJC_SUBCLASSING_RESTRICTED)) { + override val descriptor: ClassDescriptor? + get() = null + + override val psi: PsiElement? + get() = null + + override fun computeRealStub(): ObjCInterface = lazy.translator.translateFile( + PsiSourceFile(file), + declarations.mapNotNull { declaration -> + lazy.resolve(declaration).takeIf { descriptor -> + lazy.mapper.shouldBeExposed(descriptor) + } + } + ) + } + + private class LazyObjCExtensionInterface( + name: ObjCExportNamer.ClassOrProtocolName, + categoryName: String, + private val classDescriptor: ClassDescriptor, + private val declarations: List, + private val lazy: ObjCExportLazyImpl + ) : LazyObjCInterface(name = name.objCName, generics = emptyList(), categoryName = categoryName, attributes = emptyList()) { + override val descriptor: ClassDescriptor? + get() = null + + override val psi: PsiElement? + get() = null + + override fun computeRealStub(): ObjCInterface = lazy.translator.translateExtensions( + classDescriptor, + declarations.mapNotNull { declaration -> + lazy.resolve(declaration).takeIf { lazy.mapper.shouldBeExposed(it) } + } + ) + } } private abstract class LazyObjCInterface : ObjCInterface { diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportMapper.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportMapper.kt index 5b53f811710..0038f19b0f0 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportMapper.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportMapper.kt @@ -320,21 +320,21 @@ internal fun ObjCExportMapper.bridgePropertyType(descriptor: PropertyDescriptor) } internal enum class NSNumberKind(val mappedKotlinClassId: ClassId?, val objCType: ObjCType) { - CHAR(PrimitiveType.BYTE, "char"), - UNSIGNED_CHAR(UnsignedType.UBYTE, "unsigned char"), - SHORT(PrimitiveType.SHORT, "short"), - UNSIGNED_SHORT(UnsignedType.USHORT, "unsigned short"), - INT(PrimitiveType.INT, "int"), - UNSIGNED_INT(UnsignedType.UINT, "unsigned int"), - LONG("long"), - UNSIGNED_LONG("unsigned long"), - LONG_LONG(PrimitiveType.LONG, "long long"), - UNSIGNED_LONG_LONG(UnsignedType.ULONG, "unsigned long long"), - FLOAT(PrimitiveType.FLOAT, "float"), - DOUBLE(PrimitiveType.DOUBLE, "double"), - BOOL(PrimitiveType.BOOLEAN, "BOOL"), - INTEGER("NSInteger"), - UNSIGNED_INTEGER("NSUInteger") + CHAR(PrimitiveType.BYTE, ObjCPrimitiveType.char), + UNSIGNED_CHAR(UnsignedType.UBYTE, ObjCPrimitiveType.unsigned_char), + SHORT(PrimitiveType.SHORT, ObjCPrimitiveType.short), + UNSIGNED_SHORT(UnsignedType.USHORT, ObjCPrimitiveType.unsigned_short), + INT(PrimitiveType.INT, ObjCPrimitiveType.int), + UNSIGNED_INT(UnsignedType.UINT, ObjCPrimitiveType.unsigned_int), + LONG(ObjCPrimitiveType.long), + UNSIGNED_LONG(ObjCPrimitiveType.unsigned_long), + LONG_LONG(PrimitiveType.LONG, ObjCPrimitiveType.long_long), + UNSIGNED_LONG_LONG(UnsignedType.ULONG, ObjCPrimitiveType.unsigned_long_long), + FLOAT(PrimitiveType.FLOAT, ObjCPrimitiveType.float), + DOUBLE(PrimitiveType.DOUBLE, ObjCPrimitiveType.double), + BOOL(PrimitiveType.BOOLEAN, ObjCPrimitiveType.BOOL), + INTEGER(ObjCPrimitiveType.NSInteger), + UNSIGNED_INTEGER(ObjCPrimitiveType.NSUInteger) ; @@ -347,20 +347,15 @@ internal enum class NSNumberKind(val mappedKotlinClassId: ClassId?, val objCType val initSelector = "initWith${kindName.capitalize()}:" // initWithUnsignedShort: val factorySelector = "numberWith${kindName.capitalize()}:" // numberWithUnsignedShort: - constructor( - mappedKotlinClassId: ClassId?, - objCPrimitiveTypeName: String - ) : this(mappedKotlinClassId, ObjCPrimitiveType(objCPrimitiveTypeName)) - constructor( primitiveType: PrimitiveType, - objCPrimitiveTypeName: String - ) : this(ClassId.topLevel(primitiveType.typeFqName), objCPrimitiveTypeName) + objCPrimitiveType: ObjCPrimitiveType + ) : this(ClassId.topLevel(primitiveType.typeFqName), objCPrimitiveType) constructor( unsignedType: UnsignedType, - objCPrimitiveTypeName: String - ) : this(unsignedType.classId, objCPrimitiveTypeName) + objCPrimitiveType: ObjCPrimitiveType + ) : this(unsignedType.classId, objCPrimitiveType) - constructor(objCPrimitiveTypeName: String) : this(null, ObjCPrimitiveType(objCPrimitiveTypeName)) + constructor(objCPrimitiveType: ObjCPrimitiveType) : this(null, objCPrimitiveType) } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/objcTypes.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/objcTypes.kt index 30a3c9785f7..dd83df5c208 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/objcTypes.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/objcTypes.kt @@ -93,9 +93,34 @@ object ObjCMetaClassType : ObjCNonNullReferenceType() { override fun render(attrsAndName: String): String = "Class".withAttrsAndName(attrsAndName) } -class ObjCPrimitiveType( +sealed class ObjCPrimitiveType( val cName: String ) : ObjCType() { + object NSUInteger : ObjCPrimitiveType("NSUInteger") + object BOOL : ObjCPrimitiveType("BOOL") + object unichar : ObjCPrimitiveType("unichar") + object int8_t : ObjCPrimitiveType("int8_t") + object int16_t : ObjCPrimitiveType("int16_t") + object int32_t : ObjCPrimitiveType("int32_t") + object int64_t : ObjCPrimitiveType("int64_t") + object uint8_t : ObjCPrimitiveType("uint8_t") + object uint16_t : ObjCPrimitiveType("uint16_t") + object uint32_t : ObjCPrimitiveType("uint32_t") + object uint64_t : ObjCPrimitiveType("uint64_t") + object float : ObjCPrimitiveType("float") + 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") + override fun render(attrsAndName: String) = cName.withAttrsAndName(attrsAndName) } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/stubs.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/stubs.kt index 761bbdfbae0..d6351f429b4 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/stubs.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/stubs.kt @@ -5,13 +5,14 @@ package org.jetbrains.kotlin.backend.konan.objcexport -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.ParameterDescriptor -import org.jetbrains.kotlin.descriptors.PropertyDescriptor +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.resolve.source.PsiSourceElement abstract class Stub(val name: String) { abstract val descriptor: D? + open val psi: PsiElement? + get() = ((descriptor as? DeclarationDescriptorWithSource)?.source as? PsiSourceElement)?.psi } abstract class ObjCTopLevel(name: String) : Stub(name)