[ObjCExport] Extract generation of ObjC base declarations into shared code
KT-64226
This commit is contained in:
committed by
Space Team
parent
aab9a606ce
commit
72f135396c
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.objcexport.testUtils
|
||||
|
||||
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCTopLevel
|
||||
import org.jetbrains.kotlin.backend.konan.tests.ObjCExportBaseDeclarationsTest
|
||||
import org.junit.jupiter.api.extension.ExtensionContext
|
||||
import org.junit.jupiter.api.extension.ParameterContext
|
||||
import org.junit.jupiter.api.extension.ParameterResolver
|
||||
|
||||
class AnalysisApiBaseDeclarationsGeneratorExtension : ParameterResolver {
|
||||
override fun supportsParameter(parameterContext: ParameterContext, extensionContext: ExtensionContext): Boolean {
|
||||
return parameterContext.parameter.type == ObjCExportBaseDeclarationsTest.BaseDeclarationsGenerator::class.java
|
||||
}
|
||||
|
||||
override fun resolveParameter(parameterContext: ParameterContext, extensionContext: ExtensionContext): Any {
|
||||
return AnalysisApiBaseDeclarationsGenerator
|
||||
}
|
||||
}
|
||||
|
||||
object AnalysisApiBaseDeclarationsGenerator : ObjCExportBaseDeclarationsTest.BaseDeclarationsGenerator {
|
||||
override fun invoke(topLevelPrefix: String): List<ObjCTopLevel> {
|
||||
TODO("Analysis Api based 'base declaration generation' in not yet implemented")
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -3,4 +3,5 @@
|
||||
# Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
#
|
||||
org.jetbrains.kotlin.objcexport.testUtils.AnalysisApiHeaderGeneratorExtension
|
||||
org.jetbrains.kotlin.objcexport.testUtils.InlineSourceCodeAnalysisExtension
|
||||
org.jetbrains.kotlin.objcexport.testUtils.InlineSourceCodeAnalysisExtension
|
||||
org.jetbrains.kotlin.objcexport.testUtils.AnalysisApiBaseDeclarationsGeneratorExtension
|
||||
-41
@@ -436,44 +436,3 @@ internal fun ObjCExportMapper.bridgePropertyType(descriptor: PropertyDescriptor)
|
||||
return bridgeType(descriptor.type)
|
||||
}
|
||||
|
||||
@InternalKotlinNativeApi
|
||||
enum class NSNumberKind(val mappedKotlinClassId: ClassId?, val objCType: ObjCType) {
|
||||
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)
|
||||
|
||||
;
|
||||
|
||||
// UNSIGNED_SHORT -> unsignedShort
|
||||
private val kindName = this.name.split('_')
|
||||
.joinToString("") { it.lowercase().replaceFirstChar(Char::uppercaseChar) }.replaceFirstChar(Char::lowercaseChar)
|
||||
|
||||
|
||||
val valueSelector = kindName // unsignedShort
|
||||
val initSelector = "initWith${kindName.replaceFirstChar(Char::uppercaseChar)}:" // initWithUnsignedShort:
|
||||
val factorySelector = "numberWith${kindName.replaceFirstChar(Char::uppercaseChar)}:" // numberWithUnsignedShort:
|
||||
|
||||
constructor(
|
||||
primitiveType: PrimitiveType,
|
||||
objCPrimitiveType: ObjCPrimitiveType,
|
||||
) : this(ClassId.topLevel(primitiveType.typeFqName), objCPrimitiveType)
|
||||
|
||||
constructor(
|
||||
unsignedType: UnsignedType,
|
||||
objCPrimitiveType: ObjCPrimitiveType,
|
||||
) : this(unsignedType.classId, objCPrimitiveType)
|
||||
|
||||
constructor(objCPrimitiveType: ObjCPrimitiveType) : this(null, objCPrimitiveType)
|
||||
}
|
||||
|
||||
+8
-109
@@ -52,115 +52,14 @@ class ObjCExportTranslatorImpl(
|
||||
|
||||
private val kotlinAnyName = namer.kotlinAnyName
|
||||
|
||||
override fun generateBaseDeclarations(): List<ObjCTopLevel> = buildTopLevel {
|
||||
add {
|
||||
objCInterface(namer.kotlinAnyName, superClass = "NSObject", members = buildMembers {
|
||||
add { ObjCMethod(null, true, ObjCInstanceType, listOf("init"), emptyList(), listOf("unavailable")) }
|
||||
add { ObjCMethod(null, false, ObjCInstanceType, listOf("new"), emptyList(), listOf("unavailable")) }
|
||||
add { ObjCMethod(null, false, ObjCVoidType, listOf("initialize"), emptyList(), listOf("objc_requires_super")) }
|
||||
})
|
||||
}
|
||||
|
||||
// TODO: add comment to the header.
|
||||
add {
|
||||
ObjCInterfaceImpl(
|
||||
namer.kotlinAnyName.objCName,
|
||||
superProtocols = listOf("NSCopying"),
|
||||
categoryName = "${namer.kotlinAnyName.objCName}Copying"
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: only if appears
|
||||
add {
|
||||
val generics = listOf("ObjectType")
|
||||
objCInterface(
|
||||
namer.mutableSetName,
|
||||
generics = generics,
|
||||
superClass = "NSMutableSet",
|
||||
superClassGenerics = generics
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: only if appears
|
||||
add {
|
||||
val generics = listOf("KeyType", "ObjectType")
|
||||
objCInterface(
|
||||
namer.mutableMapName,
|
||||
generics = generics,
|
||||
superClass = "NSMutableDictionary",
|
||||
superClassGenerics = generics
|
||||
)
|
||||
}
|
||||
|
||||
val nsErrorCategoryName = "NSError${namer.topLevelNamePrefix}KotlinException"
|
||||
add {
|
||||
ObjCInterfaceImpl("NSError", categoryName = nsErrorCategoryName, members = buildMembers {
|
||||
add { ObjCProperty("kotlinException", null, ObjCNullableReferenceType(ObjCIdType), listOf("readonly")) }
|
||||
})
|
||||
}
|
||||
|
||||
genKotlinNumbers()
|
||||
}
|
||||
|
||||
private fun StubBuilder<ObjCTopLevel>.genKotlinNumbers() {
|
||||
val members = buildMembers {
|
||||
NSNumberKind.entries.forEach {
|
||||
add { nsNumberFactory(it, listOf("unavailable")) }
|
||||
}
|
||||
NSNumberKind.entries.forEach {
|
||||
add { nsNumberInit(it, listOf("unavailable")) }
|
||||
}
|
||||
}
|
||||
add {
|
||||
objCInterface(
|
||||
namer.kotlinNumberName,
|
||||
superClass = "NSNumber",
|
||||
members = members
|
||||
)
|
||||
}
|
||||
|
||||
NSNumberKind.entries.forEach {
|
||||
if (it.mappedKotlinClassId != null) add {
|
||||
genKotlinNumber(it.mappedKotlinClassId, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun genKotlinNumber(kotlinClassId: ClassId, kind: NSNumberKind): ObjCInterface {
|
||||
val name = namer.numberBoxName(kotlinClassId)
|
||||
|
||||
val members = buildMembers {
|
||||
add { nsNumberFactory(kind) }
|
||||
add { nsNumberInit(kind) }
|
||||
}
|
||||
return objCInterface(
|
||||
name,
|
||||
superClass = namer.kotlinNumberName.objCName,
|
||||
members = members
|
||||
)
|
||||
}
|
||||
|
||||
private fun nsNumberInit(kind: NSNumberKind, attributes: List<String> = emptyList()): ObjCMethod {
|
||||
return ObjCMethod(
|
||||
null,
|
||||
false,
|
||||
ObjCInstanceType,
|
||||
listOf(kind.factorySelector),
|
||||
listOf(ObjCParameter("value", null, kind.objCType)),
|
||||
attributes
|
||||
)
|
||||
}
|
||||
|
||||
private fun nsNumberFactory(kind: NSNumberKind, attributes: List<String> = emptyList()): ObjCMethod {
|
||||
return ObjCMethod(
|
||||
null,
|
||||
true,
|
||||
ObjCInstanceType,
|
||||
listOf(kind.initSelector),
|
||||
listOf(ObjCParameter("value", null, kind.objCType)),
|
||||
attributes
|
||||
)
|
||||
}
|
||||
override fun generateBaseDeclarations(): List<ObjCTopLevel> = objCBaseDeclarations(
|
||||
topLevelNamePrefix = namer.topLevelNamePrefix,
|
||||
objCNameOfAny = namer.kotlinAnyName,
|
||||
objCNameOfNumber = namer.kotlinNumberName,
|
||||
objCNameOfMutableMap = namer.mutableMapName,
|
||||
objCNameOfMutableSet = namer.mutableSetName,
|
||||
objCNameForNumberBox = { classId -> namer.numberBoxName(classId) }
|
||||
)
|
||||
|
||||
override fun getClassIfExtension(receiverType: KotlinType): ClassDescriptor? =
|
||||
mapper.getClassIfCategory(receiverType)
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.konan.testUtils
|
||||
|
||||
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportProblemCollector
|
||||
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportTranslatorImpl
|
||||
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCTopLevel
|
||||
import org.jetbrains.kotlin.backend.konan.tests.ObjCExportBaseDeclarationsTest
|
||||
import org.junit.jupiter.api.extension.ExtensionContext
|
||||
import org.junit.jupiter.api.extension.ParameterContext
|
||||
import org.junit.jupiter.api.extension.ParameterResolver
|
||||
|
||||
|
||||
class Fe10BaseDeclarationsGeneratorExtension : ParameterResolver {
|
||||
override fun supportsParameter(parameterContext: ParameterContext, extensionContext: ExtensionContext): Boolean {
|
||||
return parameterContext.parameter.type == ObjCExportBaseDeclarationsTest.BaseDeclarationsGenerator::class.java
|
||||
}
|
||||
|
||||
override fun resolveParameter(parameterContext: ParameterContext, extensionContext: ExtensionContext): Any {
|
||||
return Fe10BaseDeclarationsGenerator
|
||||
}
|
||||
}
|
||||
|
||||
private object Fe10BaseDeclarationsGenerator : ObjCExportBaseDeclarationsTest.BaseDeclarationsGenerator {
|
||||
override fun invoke(topLevelPrefix: String): List<ObjCTopLevel> {
|
||||
val translator = ObjCExportTranslatorImpl(
|
||||
generator = null,
|
||||
mapper = createObjCExportMapper(),
|
||||
namer = createObjCExportNamer(configuration = createObjCExportNamerConfiguration(topLevelNamePrefix = topLevelPrefix)),
|
||||
problemCollector = ObjCExportProblemCollector.SILENT,
|
||||
objcGenerics = true
|
||||
)
|
||||
|
||||
return translator.generateBaseDeclarations()
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -2,4 +2,5 @@
|
||||
# Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
# Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
#
|
||||
org.jetbrains.kotlin.backend.konan.testUtils.Fe10HeaderGeneratorExtension
|
||||
org.jetbrains.kotlin.backend.konan.testUtils.Fe10HeaderGeneratorExtension
|
||||
org.jetbrains.kotlin.backend.konan.testUtils.Fe10BaseDeclarationsGeneratorExtension
|
||||
Reference in New Issue
Block a user