Extract ObjCExport lazy declarations to named classes (#3489)
Also convert `ObjCPrimitiveType` to a sealed class.
This commit is contained in:
committed by
GitHub
parent
7c3e0bb801
commit
5aca1db362
+14
-14
@@ -729,9 +729,9 @@ internal class ObjCExportTranslatorImpl(
|
|||||||
|
|
||||||
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.Void -> ObjCVoidType
|
MethodBridge.ReturnValue.Void -> ObjCVoidType
|
||||||
MethodBridge.ReturnValue.HashCode -> ObjCPrimitiveType("NSUInteger")
|
MethodBridge.ReturnValue.HashCode -> ObjCPrimitiveType.NSUInteger
|
||||||
is MethodBridge.ReturnValue.Mapped -> mapType(method.returnType!!, returnBridge.bridge, objCExportScope)
|
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 -> {
|
is MethodBridge.ReturnValue.WithError.RefOrNull -> {
|
||||||
val successReturnType = mapReturnType(returnBridge.successBridge, method, objCExportScope) as? ObjCNonNullReferenceType
|
val successReturnType = mapReturnType(returnBridge.successBridge, method, objCExportScope) as? ObjCNonNullReferenceType
|
||||||
?: error("Function is expected to have non-null return type: $method")
|
?: 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 BlockPointerBridge -> mapFunctionType(kotlinType, objCExportScope, typeBridge)
|
||||||
is ValueTypeBridge -> {
|
is ValueTypeBridge -> {
|
||||||
when (typeBridge.objCValueType) {
|
when (typeBridge.objCValueType) {
|
||||||
ObjCValueType.BOOL -> ObjCPrimitiveType("BOOL")
|
ObjCValueType.BOOL -> ObjCPrimitiveType.BOOL
|
||||||
ObjCValueType.UNICHAR -> ObjCPrimitiveType("unichar")
|
ObjCValueType.UNICHAR -> ObjCPrimitiveType.unichar
|
||||||
ObjCValueType.CHAR -> ObjCPrimitiveType("int8_t")
|
ObjCValueType.CHAR -> ObjCPrimitiveType.int8_t
|
||||||
ObjCValueType.SHORT -> ObjCPrimitiveType("int16_t")
|
ObjCValueType.SHORT -> ObjCPrimitiveType.int16_t
|
||||||
ObjCValueType.INT -> ObjCPrimitiveType("int32_t")
|
ObjCValueType.INT -> ObjCPrimitiveType.int32_t
|
||||||
ObjCValueType.LONG_LONG -> ObjCPrimitiveType("int64_t")
|
ObjCValueType.LONG_LONG -> ObjCPrimitiveType.int64_t
|
||||||
ObjCValueType.UNSIGNED_CHAR -> ObjCPrimitiveType("uint8_t")
|
ObjCValueType.UNSIGNED_CHAR -> ObjCPrimitiveType.uint8_t
|
||||||
ObjCValueType.UNSIGNED_SHORT -> ObjCPrimitiveType("uint16_t")
|
ObjCValueType.UNSIGNED_SHORT -> ObjCPrimitiveType.uint16_t
|
||||||
ObjCValueType.UNSIGNED_INT -> ObjCPrimitiveType("uint32_t")
|
ObjCValueType.UNSIGNED_INT -> ObjCPrimitiveType.uint32_t
|
||||||
ObjCValueType.UNSIGNED_LONG_LONG -> ObjCPrimitiveType("uint64_t")
|
ObjCValueType.UNSIGNED_LONG_LONG -> ObjCPrimitiveType.uint64_t
|
||||||
ObjCValueType.FLOAT -> ObjCPrimitiveType("float")
|
ObjCValueType.FLOAT -> ObjCPrimitiveType.float
|
||||||
ObjCValueType.DOUBLE -> ObjCPrimitiveType("double")
|
ObjCValueType.DOUBLE -> ObjCPrimitiveType.double
|
||||||
ObjCValueType.POINTER -> ObjCPointerType(ObjCVoidType, kotlinType.binaryRepresentationIsNullable())
|
ObjCValueType.POINTER -> ObjCPointerType(ObjCVoidType, kotlinType.binaryRepresentationIsNullable())
|
||||||
}
|
}
|
||||||
// TODO: consider other namings.
|
// TODO: consider other namings.
|
||||||
|
|||||||
+74
-48
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.konan.objcexport
|
package org.jetbrains.kotlin.backend.konan.objcexport
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
@@ -126,11 +127,7 @@ internal class ObjCExportLazyImpl(
|
|||||||
// Note: some attributes may be missing (e.g. "unavailable" for unexposed classes).
|
// Note: some attributes may be missing (e.g. "unavailable" for unexposed classes).
|
||||||
|
|
||||||
return if (ktClassOrObject.isInterface) {
|
return if (ktClassOrObject.isInterface) {
|
||||||
object : LazyObjCProtocol(name) {
|
LazyObjCProtocolImpl(name, ktClassOrObject, this)
|
||||||
override val descriptor: ClassDescriptor by lazy { resolve(ktClassOrObject) }
|
|
||||||
|
|
||||||
override fun computeRealStub(): ObjCProtocol = translator.translateInterface(descriptor)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
val isFinal = ktClassOrObject.modalityModifier() == null ||
|
val isFinal = ktClassOrObject.modalityModifier() == null ||
|
||||||
ktClassOrObject.hasModifier(KtTokens.FINAL_KEYWORD)
|
ktClassOrObject.hasModifier(KtTokens.FINAL_KEYWORD)
|
||||||
@@ -141,16 +138,11 @@ internal class ObjCExportLazyImpl(
|
|||||||
emptyList()
|
emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
object : LazyObjCInterface(
|
LazyObjCInterfaceImpl(name,
|
||||||
name,
|
attributes,
|
||||||
generics = if (configuration.objcGenerics) TODO() else emptyList(),
|
generics = if (configuration.objcGenerics) TODO() else emptyList(),
|
||||||
categoryName = null,
|
psi = ktClassOrObject,
|
||||||
attributes = attributes
|
lazy = this)
|
||||||
) {
|
|
||||||
override val descriptor: ClassDescriptor by lazy { resolve(ktClassOrObject) }
|
|
||||||
|
|
||||||
override fun computeRealStub(): ObjCInterface = translator.translateClass(descriptor)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,23 +177,7 @@ internal class ObjCExportLazyImpl(
|
|||||||
|
|
||||||
private fun translateFileClass(file: KtFile, declarations: List<KtCallableDeclaration>): ObjCInterface {
|
private fun translateFileClass(file: KtFile, declarations: List<KtCallableDeclaration>): ObjCInterface {
|
||||||
val name = nameTranslator.getFileClassName(file)
|
val name = nameTranslator.getFileClassName(file)
|
||||||
|
return LazyObjCFileInterface(name, file, declarations, this)
|
||||||
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) }
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateExtensions(
|
private fun translateExtensions(
|
||||||
@@ -217,22 +193,7 @@ internal class ObjCExportLazyImpl(
|
|||||||
namer.getClassOrProtocolName(classDescriptor)
|
namer.getClassOrProtocolName(classDescriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
return object : LazyObjCInterface(
|
return LazyObjCExtensionInterface(name, nameTranslator.getCategoryName(file), classDescriptor, declarations, this)
|
||||||
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) }
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun resolveDeclaration(ktDeclaration: KtDeclaration): DeclarationDescriptor =
|
private fun resolveDeclaration(ktDeclaration: KtDeclaration): DeclarationDescriptor =
|
||||||
@@ -326,6 +287,71 @@ internal class ObjCExportLazyImpl(
|
|||||||
|
|
||||||
return result
|
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<String>,
|
||||||
|
generics: List<String>,
|
||||||
|
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<KtCallableDeclaration>,
|
||||||
|
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<KtCallableDeclaration>,
|
||||||
|
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 {
|
private abstract class LazyObjCInterface : ObjCInterface {
|
||||||
|
|||||||
+20
-25
@@ -320,21 +320,21 @@ internal fun ObjCExportMapper.bridgePropertyType(descriptor: PropertyDescriptor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal enum class NSNumberKind(val mappedKotlinClassId: ClassId?, val objCType: ObjCType) {
|
internal enum class NSNumberKind(val mappedKotlinClassId: ClassId?, val objCType: ObjCType) {
|
||||||
CHAR(PrimitiveType.BYTE, "char"),
|
CHAR(PrimitiveType.BYTE, ObjCPrimitiveType.char),
|
||||||
UNSIGNED_CHAR(UnsignedType.UBYTE, "unsigned char"),
|
UNSIGNED_CHAR(UnsignedType.UBYTE, ObjCPrimitiveType.unsigned_char),
|
||||||
SHORT(PrimitiveType.SHORT, "short"),
|
SHORT(PrimitiveType.SHORT, ObjCPrimitiveType.short),
|
||||||
UNSIGNED_SHORT(UnsignedType.USHORT, "unsigned short"),
|
UNSIGNED_SHORT(UnsignedType.USHORT, ObjCPrimitiveType.unsigned_short),
|
||||||
INT(PrimitiveType.INT, "int"),
|
INT(PrimitiveType.INT, ObjCPrimitiveType.int),
|
||||||
UNSIGNED_INT(UnsignedType.UINT, "unsigned int"),
|
UNSIGNED_INT(UnsignedType.UINT, ObjCPrimitiveType.unsigned_int),
|
||||||
LONG("long"),
|
LONG(ObjCPrimitiveType.long),
|
||||||
UNSIGNED_LONG("unsigned long"),
|
UNSIGNED_LONG(ObjCPrimitiveType.unsigned_long),
|
||||||
LONG_LONG(PrimitiveType.LONG, "long long"),
|
LONG_LONG(PrimitiveType.LONG, ObjCPrimitiveType.long_long),
|
||||||
UNSIGNED_LONG_LONG(UnsignedType.ULONG, "unsigned long long"),
|
UNSIGNED_LONG_LONG(UnsignedType.ULONG, ObjCPrimitiveType.unsigned_long_long),
|
||||||
FLOAT(PrimitiveType.FLOAT, "float"),
|
FLOAT(PrimitiveType.FLOAT, ObjCPrimitiveType.float),
|
||||||
DOUBLE(PrimitiveType.DOUBLE, "double"),
|
DOUBLE(PrimitiveType.DOUBLE, ObjCPrimitiveType.double),
|
||||||
BOOL(PrimitiveType.BOOLEAN, "BOOL"),
|
BOOL(PrimitiveType.BOOLEAN, ObjCPrimitiveType.BOOL),
|
||||||
INTEGER("NSInteger"),
|
INTEGER(ObjCPrimitiveType.NSInteger),
|
||||||
UNSIGNED_INTEGER("NSUInteger")
|
UNSIGNED_INTEGER(ObjCPrimitiveType.NSUInteger)
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -347,20 +347,15 @@ internal enum class NSNumberKind(val mappedKotlinClassId: ClassId?, val objCType
|
|||||||
val initSelector = "initWith${kindName.capitalize()}:" // initWithUnsignedShort:
|
val initSelector = "initWith${kindName.capitalize()}:" // initWithUnsignedShort:
|
||||||
val factorySelector = "numberWith${kindName.capitalize()}:" // numberWithUnsignedShort:
|
val factorySelector = "numberWith${kindName.capitalize()}:" // numberWithUnsignedShort:
|
||||||
|
|
||||||
constructor(
|
|
||||||
mappedKotlinClassId: ClassId?,
|
|
||||||
objCPrimitiveTypeName: String
|
|
||||||
) : this(mappedKotlinClassId, ObjCPrimitiveType(objCPrimitiveTypeName))
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
primitiveType: PrimitiveType,
|
primitiveType: PrimitiveType,
|
||||||
objCPrimitiveTypeName: String
|
objCPrimitiveType: ObjCPrimitiveType
|
||||||
) : this(ClassId.topLevel(primitiveType.typeFqName), objCPrimitiveTypeName)
|
) : this(ClassId.topLevel(primitiveType.typeFqName), objCPrimitiveType)
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
unsignedType: UnsignedType,
|
unsignedType: UnsignedType,
|
||||||
objCPrimitiveTypeName: String
|
objCPrimitiveType: ObjCPrimitiveType
|
||||||
) : this(unsignedType.classId, objCPrimitiveTypeName)
|
) : this(unsignedType.classId, objCPrimitiveType)
|
||||||
|
|
||||||
constructor(objCPrimitiveTypeName: String) : this(null, ObjCPrimitiveType(objCPrimitiveTypeName))
|
constructor(objCPrimitiveType: ObjCPrimitiveType) : this(null, objCPrimitiveType)
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-1
@@ -93,9 +93,34 @@ object ObjCMetaClassType : ObjCNonNullReferenceType() {
|
|||||||
override fun render(attrsAndName: String): String = "Class".withAttrsAndName(attrsAndName)
|
override fun render(attrsAndName: String): String = "Class".withAttrsAndName(attrsAndName)
|
||||||
}
|
}
|
||||||
|
|
||||||
class ObjCPrimitiveType(
|
sealed class ObjCPrimitiveType(
|
||||||
val cName: String
|
val cName: String
|
||||||
) : ObjCType() {
|
) : 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)
|
override fun render(attrsAndName: String) = cName.withAttrsAndName(attrsAndName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-4
@@ -5,13 +5,14 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.konan.objcexport
|
package org.jetbrains.kotlin.backend.konan.objcexport
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
|
||||||
|
|
||||||
abstract class Stub<out D : DeclarationDescriptor>(val name: String) {
|
abstract class Stub<out D : DeclarationDescriptor>(val name: String) {
|
||||||
abstract val descriptor: D?
|
abstract val descriptor: D?
|
||||||
|
open val psi: PsiElement?
|
||||||
|
get() = ((descriptor as? DeclarationDescriptorWithSource)?.source as? PsiSourceElement)?.psi
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class ObjCTopLevel<out D : DeclarationDescriptor>(name: String) : Stub<D>(name)
|
abstract class ObjCTopLevel<out D : DeclarationDescriptor>(name: String) : Stub<D>(name)
|
||||||
|
|||||||
Reference in New Issue
Block a user