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) {
|
||||
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.
|
||||
|
||||
+74
-48
@@ -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<KtCallableDeclaration>): 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<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 {
|
||||
|
||||
+20
-25
@@ -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)
|
||||
}
|
||||
|
||||
+26
-1
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
+5
-4
@@ -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<out D : DeclarationDescriptor>(val name: String) {
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user