Skip to content

Commit

Permalink
Extract ObjCExport lazy declarations to named classes (JetBrains#3489)
Browse files Browse the repository at this point in the history
Also convert `ObjCPrimitiveType` to a sealed class.
  • Loading branch information
SvyatoslavScherbina authored Oct 24, 2019
1 parent 7c3e0bb commit 5aca1db
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 92 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.*
Expand Down Expand Up @@ -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)
Expand All @@ -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)
}
}

Expand Down Expand Up @@ -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(
Expand All @@ -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 =
Expand Down Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)

;

Expand All @@ -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)
}
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 5aca1db

Please sign in to comment.