[ObjCExport] Extract generation of ObjC base declarations into shared code

KT-64226
This commit is contained in:
Sebastian Sellmair
2023-12-13 18:21:24 +01:00
committed by Space Team
parent aab9a606ce
commit 72f135396c
12 changed files with 659 additions and 153 deletions
@@ -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")
}
}
@@ -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
@@ -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)
}
@@ -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)
@@ -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,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
@@ -0,0 +1,57 @@
/*
* 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.objcexport
import org.jetbrains.kotlin.backend.konan.InternalKotlinNativeApi
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.name.ClassId
/*
Defining ClassIds for Unsigned types:
Cannot reuse 'UnsignedType.kt' from core/descriptors
*/
private val uByteClassId = ClassId.fromString("kotlin/UByte")
private val uShortClassId = ClassId.fromString("kotlin/UShort")
private val uIntClassId = ClassId.fromString("kotlin/UInt")
private val uLongClassId = ClassId.fromString("kotlin/ULong")
@InternalKotlinNativeApi
enum class NSNumberKind(val mappedKotlinClassId: ClassId?, val objCType: ObjCType) {
CHAR(PrimitiveType.BYTE, ObjCPrimitiveType.char),
UNSIGNED_CHAR(uByteClassId, ObjCPrimitiveType.unsigned_char),
SHORT(PrimitiveType.SHORT, ObjCPrimitiveType.short),
UNSIGNED_SHORT(uShortClassId, ObjCPrimitiveType.unsigned_short),
INT(PrimitiveType.INT, ObjCPrimitiveType.int),
UNSIGNED_INT(uIntClassId, ObjCPrimitiveType.unsigned_int),
LONG(ObjCPrimitiveType.long),
UNSIGNED_LONG(ObjCPrimitiveType.unsigned_long),
LONG_LONG(PrimitiveType.LONG, ObjCPrimitiveType.long_long),
UNSIGNED_LONG_LONG(uLongClassId, 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(objCPrimitiveType: ObjCPrimitiveType) : this(null, objCPrimitiveType)
}
@@ -0,0 +1,261 @@
/*
* 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.objcexport
import org.jetbrains.kotlin.backend.konan.InternalKotlinNativeApi
import org.jetbrains.kotlin.name.ClassId
@InternalKotlinNativeApi
fun objCBaseDeclarations(
topLevelNamePrefix: String,
objCNameOfAny: ObjCExportClassOrProtocolName,
objCNameOfNumber: ObjCExportClassOrProtocolName,
objCNameOfMutableMap: ObjCExportClassOrProtocolName,
objCNameOfMutableSet: ObjCExportClassOrProtocolName,
objCNameForNumberBox: (numberClassId: ClassId) -> ObjCExportClassOrProtocolName
): List<ObjCTopLevel> = buildList {
add {
objCInterface(objCNameOfAny, superClass = "NSObject", members = buildList {
add {
ObjCMethod(
origin = null,
comment = null,
isInstanceMethod = true,
returnType = ObjCInstanceType,
selectors = listOf("init"),
parameters = emptyList(),
attributes = listOf("unavailable")
)
}
add {
ObjCMethod(
origin = null,
comment = null,
isInstanceMethod = false,
returnType = ObjCInstanceType,
selectors = listOf("new"),
parameters = emptyList(), attributes = listOf("unavailable")
)
}
add {
ObjCMethod(
origin = null,
comment = null,
isInstanceMethod = false,
returnType = ObjCVoidType,
selectors = listOf("initialize"),
parameters = emptyList(),
attributes = listOf("objc_requires_super")
)
}
})
}
// TODO: add comment to the header.
add {
ObjCInterfaceImpl(
objCNameOfAny.objCName,
superProtocols = listOf("NSCopying"),
categoryName = "${objCNameOfAny.objCName}Copying",
origin = null,
comment = null,
generics = emptyList(),
attributes = emptyList(),
members = emptyList(),
superClass = null,
superClassGenerics = emptyList()
)
}
// TODO: only if appears
add {
val generics = listOf("ObjectType")
objCInterface(
objCNameOfMutableSet,
generics = generics,
superClass = "NSMutableSet",
superClassGenerics = generics
)
}
// TODO: only if appears
add {
val generics = listOf("KeyType", "ObjectType")
objCInterface(
objCNameOfMutableMap,
generics = generics,
superClass = "NSMutableDictionary",
superClassGenerics = generics
)
}
val nsErrorCategoryName = "NSError${topLevelNamePrefix}KotlinException"
add {
ObjCInterfaceImpl(
name = "NSError",
categoryName = nsErrorCategoryName,
members = buildList {
add {
ObjCProperty(
name = "kotlinException",
origin = null,
type = ObjCNullableReferenceType(ObjCIdType),
propertyAttributes = listOf("readonly"),
setterName = null,
getterName = null,
comment = null,
declarationAttributes = emptyList()
)
}
},
attributes = emptyList(),
comment = null,
origin = null,
superProtocols = emptyList(),
generics = emptyList(),
superClass = null,
superClassGenerics = emptyList()
)
}
genKotlinNumbers(objCNameOfNumber = objCNameOfNumber, objCNameForNumberBox = objCNameForNumberBox)
}
private fun MutableList<ObjCTopLevel>.genKotlinNumbers(
objCNameOfNumber: ObjCExportClassOrProtocolName,
objCNameForNumberBox: (numberClassId: ClassId) -> ObjCExportClassOrProtocolName
) {
val members = buildList {
NSNumberKind.entries.forEach {
add(nsNumberFactory(it, listOf("unavailable")))
}
NSNumberKind.entries.forEach {
add(nsNumberInit(it, listOf("unavailable")))
}
}
add {
objCInterface(
objCNameOfNumber,
superClass = "NSNumber",
members = members
)
}
NSNumberKind.entries.forEach {
if (it.mappedKotlinClassId != null) add {
genKotlinNumber(it.mappedKotlinClassId, it, objCNameOfNumber, objCNameForNumberBox)
}
}
}
private fun genKotlinNumber(
kotlinClassId: ClassId,
kind: NSNumberKind,
objCNameOfNumber: ObjCExportClassOrProtocolName,
objCNameForNumberBox: (numberClassId: ClassId) -> ObjCExportClassOrProtocolName
): ObjCInterface {
val name = objCNameForNumberBox(kotlinClassId)
val members = buildList<ObjCExportStub> {
add { nsNumberFactory(kind) }
add { nsNumberInit(kind) }
}
return objCInterface(
name,
superClass = objCNameOfNumber.objCName,
members = members
)
}
private fun nsNumberInit(kind: NSNumberKind, attributes: List<String> = emptyList()): ObjCMethod {
return ObjCMethod(
origin = null,
comment = null,
isInstanceMethod = false,
returnType = ObjCInstanceType,
selectors = listOf(kind.factorySelector),
parameters = listOf(
ObjCParameter(name = "value", origin = null, type = kind.objCType, todo = null)
),
attributes = attributes
)
}
private fun nsNumberFactory(kind: NSNumberKind, attributes: List<String> = emptyList()): ObjCMethod {
return ObjCMethod(
origin = null,
comment = null,
isInstanceMethod = true,
returnType = ObjCInstanceType,
selectors = listOf(kind.initSelector),
parameters = listOf(ObjCParameter("value", null, kind.objCType, todo = null)),
attributes = attributes
)
}
private inline fun <T> MutableList<T>.add(producer: () -> T) {
add(producer())
}
private fun objCInterface(
name: ObjCExportClassOrProtocolName,
generics: List<String>,
superClass: String,
superClassGenerics: List<String>,
): ObjCInterface = objCInterface(
name,
generics = generics.map { ObjCGenericTypeRawDeclaration(it) },
superClass = superClass,
superClassGenerics = superClassGenerics.map { ObjCGenericTypeRawUsage(it) }
)
private fun objCInterface(
name: ObjCExportClassOrProtocolName,
generics: List<ObjCGenericTypeDeclaration> = emptyList(),
superClass: String? = null,
superClassGenerics: List<ObjCNonNullReferenceType> = emptyList(),
superProtocols: List<String> = emptyList(),
members: List<ObjCExportStub> = emptyList(),
attributes: List<String> = emptyList(),
comment: ObjCComment? = null,
): ObjCInterface = ObjCInterfaceImpl(
name = name.objCName,
generics = generics,
origin = null,
superClass = superClass,
superClassGenerics = superClassGenerics,
superProtocols = superProtocols,
members = members,
attributes = attributes.plus(name.toNameAttributes()),
comment = comment,
categoryName = null
)
private fun objCProtocol(
name: ObjCExportClassOrProtocolName,
superProtocols: List<String>,
members: List<ObjCExportStub>,
attributes: List<String> = emptyList(),
comment: ObjCComment? = null,
): ObjCProtocol = ObjCProtocolImpl(
name = name.objCName,
origin = null,
superProtocols = superProtocols,
members = members,
attributes = attributes + name.toNameAttributes(),
comment = comment
)
private fun ObjCExportClassOrProtocolName.toNameAttributes(): List<String> = listOfNotNull(
binaryName.takeIf { it != objCName }?.let { objcRuntimeNameAttribute(it) },
swiftName.takeIf { it != objCName }?.let { swiftNameAttribute(it) }
)
private fun swiftNameAttribute(swiftName: String) = "swift_name(\"$swiftName\")"
private fun objcRuntimeNameAttribute(name: String) = "objc_runtime_name(\"$name\")"
@@ -8,4 +8,5 @@ package org.jetbrains.kotlin.backend.konan.testUtils
import java.io.File
val testDataDir = File("native/objcexport-header-generator/testData")
val headersTestDataDir = testDataDir.resolve("headers")
val headersTestDataDir = testDataDir.resolve("headers")
val baseDeclarationsDir = testDataDir.resolve("baseDeclarations")
@@ -0,0 +1,50 @@
/*
* 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.tests
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCTopLevel
import org.jetbrains.kotlin.backend.konan.objcexport.StubRenderer
import org.jetbrains.kotlin.backend.konan.testUtils.baseDeclarationsDir
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.junit.jupiter.api.Test
import java.io.File
/**
* ## Test Scope
* This test will just invoke the generation of 'base declarations' (basically ObjC stubs that shall always be present)
* The generated declarations will be compared to previously checked-in 'golden' headers.
*/
class ObjCExportBaseDeclarationsTest(
/**
* Injected implementation: Either K1 or based upon Analysis API.
*/
private val generator: BaseDeclarationsGenerator,
) {
@Test
fun `test - noTopLevelPrefix`() {
doTest(baseDeclarationsDir.resolve("!noTopLevelPrefix.h"), "")
}
@Test
fun `test - topLevelPrefix`() {
doTest(baseDeclarationsDir.resolve("!topLevelPrefix.h"), "MyTopLevelPrefix")
}
private fun doTest(headerFile: File, topLevelPrefix: String) {
val declarations = generator(topLevelPrefix)
val renderedDeclarations = declarations
.flatMap { declaration -> StubRenderer.render(declaration) }
.joinToString(System.lineSeparator())
KotlinTestUtils.assertEqualsToFile(headerFile, renderedDeclarations)
}
fun interface BaseDeclarationsGenerator {
operator fun invoke(topLevelPrefix: String): List<ObjCTopLevel>
}
}
@@ -0,0 +1,105 @@
__attribute__((swift_name("KotlinBase")))
@interface Base : NSObject
- (instancetype)init __attribute__((unavailable));
+ (instancetype)new __attribute__((unavailable));
+ (void)initialize __attribute__((objc_requires_super));
@end
@interface Base (BaseCopying) <NSCopying>
@end
__attribute__((swift_name("KotlinMutableSet")))
@interface MutableSet<ObjectType> : NSMutableSet<ObjectType>
@end
__attribute__((swift_name("KotlinMutableDictionary")))
@interface MutableDictionary<KeyType, ObjectType> : NSMutableDictionary<KeyType, ObjectType>
@end
@interface NSError (NSErrorKotlinException)
@property (readonly) id _Nullable kotlinException;
@end
__attribute__((swift_name("KotlinNumber")))
@interface Number : NSNumber
- (instancetype)initWithChar:(char)value __attribute__((unavailable));
- (instancetype)initWithUnsignedChar:(unsigned char)value __attribute__((unavailable));
- (instancetype)initWithShort:(short)value __attribute__((unavailable));
- (instancetype)initWithUnsignedShort:(unsigned short)value __attribute__((unavailable));
- (instancetype)initWithInt:(int)value __attribute__((unavailable));
- (instancetype)initWithUnsignedInt:(unsigned int)value __attribute__((unavailable));
- (instancetype)initWithLong:(long)value __attribute__((unavailable));
- (instancetype)initWithUnsignedLong:(unsigned long)value __attribute__((unavailable));
- (instancetype)initWithLongLong:(long long)value __attribute__((unavailable));
- (instancetype)initWithUnsignedLongLong:(unsigned long long)value __attribute__((unavailable));
- (instancetype)initWithFloat:(float)value __attribute__((unavailable));
- (instancetype)initWithDouble:(double)value __attribute__((unavailable));
- (instancetype)initWithBool:(BOOL)value __attribute__((unavailable));
- (instancetype)initWithInteger:(NSInteger)value __attribute__((unavailable));
- (instancetype)initWithUnsignedInteger:(NSUInteger)value __attribute__((unavailable));
+ (instancetype)numberWithChar:(char)value __attribute__((unavailable));
+ (instancetype)numberWithUnsignedChar:(unsigned char)value __attribute__((unavailable));
+ (instancetype)numberWithShort:(short)value __attribute__((unavailable));
+ (instancetype)numberWithUnsignedShort:(unsigned short)value __attribute__((unavailable));
+ (instancetype)numberWithInt:(int)value __attribute__((unavailable));
+ (instancetype)numberWithUnsignedInt:(unsigned int)value __attribute__((unavailable));
+ (instancetype)numberWithLong:(long)value __attribute__((unavailable));
+ (instancetype)numberWithUnsignedLong:(unsigned long)value __attribute__((unavailable));
+ (instancetype)numberWithLongLong:(long long)value __attribute__((unavailable));
+ (instancetype)numberWithUnsignedLongLong:(unsigned long long)value __attribute__((unavailable));
+ (instancetype)numberWithFloat:(float)value __attribute__((unavailable));
+ (instancetype)numberWithDouble:(double)value __attribute__((unavailable));
+ (instancetype)numberWithBool:(BOOL)value __attribute__((unavailable));
+ (instancetype)numberWithInteger:(NSInteger)value __attribute__((unavailable));
+ (instancetype)numberWithUnsignedInteger:(NSUInteger)value __attribute__((unavailable));
@end
__attribute__((swift_name("KotlinByte")))
@interface Byte : Number
- (instancetype)initWithChar:(char)value;
+ (instancetype)numberWithChar:(char)value;
@end
__attribute__((swift_name("KotlinUByte")))
@interface UByte : Number
- (instancetype)initWithUnsignedChar:(unsigned char)value;
+ (instancetype)numberWithUnsignedChar:(unsigned char)value;
@end
__attribute__((swift_name("KotlinShort")))
@interface Short : Number
- (instancetype)initWithShort:(short)value;
+ (instancetype)numberWithShort:(short)value;
@end
__attribute__((swift_name("KotlinUShort")))
@interface UShort : Number
- (instancetype)initWithUnsignedShort:(unsigned short)value;
+ (instancetype)numberWithUnsignedShort:(unsigned short)value;
@end
__attribute__((swift_name("KotlinInt")))
@interface Int : Number
- (instancetype)initWithInt:(int)value;
+ (instancetype)numberWithInt:(int)value;
@end
__attribute__((swift_name("KotlinUInt")))
@interface UInt : Number
- (instancetype)initWithUnsignedInt:(unsigned int)value;
+ (instancetype)numberWithUnsignedInt:(unsigned int)value;
@end
__attribute__((swift_name("KotlinLong")))
@interface Long : Number
- (instancetype)initWithLongLong:(long long)value;
+ (instancetype)numberWithLongLong:(long long)value;
@end
__attribute__((swift_name("KotlinULong")))
@interface ULong : Number
- (instancetype)initWithUnsignedLongLong:(unsigned long long)value;
+ (instancetype)numberWithUnsignedLongLong:(unsigned long long)value;
@end
__attribute__((swift_name("KotlinFloat")))
@interface Float : Number
- (instancetype)initWithFloat:(float)value;
+ (instancetype)numberWithFloat:(float)value;
@end
__attribute__((swift_name("KotlinDouble")))
@interface Double : Number
- (instancetype)initWithDouble:(double)value;
+ (instancetype)numberWithDouble:(double)value;
@end
__attribute__((swift_name("KotlinBoolean")))
@interface Boolean : Number
- (instancetype)initWithBool:(BOOL)value;
+ (instancetype)numberWithBool:(BOOL)value;
@end
@@ -0,0 +1,105 @@
__attribute__((swift_name("KotlinBase")))
@interface MyTopLevelPrefixBase : NSObject
- (instancetype)init __attribute__((unavailable));
+ (instancetype)new __attribute__((unavailable));
+ (void)initialize __attribute__((objc_requires_super));
@end
@interface MyTopLevelPrefixBase (MyTopLevelPrefixBaseCopying) <NSCopying>
@end
__attribute__((swift_name("KotlinMutableSet")))
@interface MyTopLevelPrefixMutableSet<ObjectType> : NSMutableSet<ObjectType>
@end
__attribute__((swift_name("KotlinMutableDictionary")))
@interface MyTopLevelPrefixMutableDictionary<KeyType, ObjectType> : NSMutableDictionary<KeyType, ObjectType>
@end
@interface NSError (NSErrorMyTopLevelPrefixKotlinException)
@property (readonly) id _Nullable kotlinException;
@end
__attribute__((swift_name("KotlinNumber")))
@interface MyTopLevelPrefixNumber : NSNumber
- (instancetype)initWithChar:(char)value __attribute__((unavailable));
- (instancetype)initWithUnsignedChar:(unsigned char)value __attribute__((unavailable));
- (instancetype)initWithShort:(short)value __attribute__((unavailable));
- (instancetype)initWithUnsignedShort:(unsigned short)value __attribute__((unavailable));
- (instancetype)initWithInt:(int)value __attribute__((unavailable));
- (instancetype)initWithUnsignedInt:(unsigned int)value __attribute__((unavailable));
- (instancetype)initWithLong:(long)value __attribute__((unavailable));
- (instancetype)initWithUnsignedLong:(unsigned long)value __attribute__((unavailable));
- (instancetype)initWithLongLong:(long long)value __attribute__((unavailable));
- (instancetype)initWithUnsignedLongLong:(unsigned long long)value __attribute__((unavailable));
- (instancetype)initWithFloat:(float)value __attribute__((unavailable));
- (instancetype)initWithDouble:(double)value __attribute__((unavailable));
- (instancetype)initWithBool:(BOOL)value __attribute__((unavailable));
- (instancetype)initWithInteger:(NSInteger)value __attribute__((unavailable));
- (instancetype)initWithUnsignedInteger:(NSUInteger)value __attribute__((unavailable));
+ (instancetype)numberWithChar:(char)value __attribute__((unavailable));
+ (instancetype)numberWithUnsignedChar:(unsigned char)value __attribute__((unavailable));
+ (instancetype)numberWithShort:(short)value __attribute__((unavailable));
+ (instancetype)numberWithUnsignedShort:(unsigned short)value __attribute__((unavailable));
+ (instancetype)numberWithInt:(int)value __attribute__((unavailable));
+ (instancetype)numberWithUnsignedInt:(unsigned int)value __attribute__((unavailable));
+ (instancetype)numberWithLong:(long)value __attribute__((unavailable));
+ (instancetype)numberWithUnsignedLong:(unsigned long)value __attribute__((unavailable));
+ (instancetype)numberWithLongLong:(long long)value __attribute__((unavailable));
+ (instancetype)numberWithUnsignedLongLong:(unsigned long long)value __attribute__((unavailable));
+ (instancetype)numberWithFloat:(float)value __attribute__((unavailable));
+ (instancetype)numberWithDouble:(double)value __attribute__((unavailable));
+ (instancetype)numberWithBool:(BOOL)value __attribute__((unavailable));
+ (instancetype)numberWithInteger:(NSInteger)value __attribute__((unavailable));
+ (instancetype)numberWithUnsignedInteger:(NSUInteger)value __attribute__((unavailable));
@end
__attribute__((swift_name("KotlinByte")))
@interface MyTopLevelPrefixByte : MyTopLevelPrefixNumber
- (instancetype)initWithChar:(char)value;
+ (instancetype)numberWithChar:(char)value;
@end
__attribute__((swift_name("KotlinUByte")))
@interface MyTopLevelPrefixUByte : MyTopLevelPrefixNumber
- (instancetype)initWithUnsignedChar:(unsigned char)value;
+ (instancetype)numberWithUnsignedChar:(unsigned char)value;
@end
__attribute__((swift_name("KotlinShort")))
@interface MyTopLevelPrefixShort : MyTopLevelPrefixNumber
- (instancetype)initWithShort:(short)value;
+ (instancetype)numberWithShort:(short)value;
@end
__attribute__((swift_name("KotlinUShort")))
@interface MyTopLevelPrefixUShort : MyTopLevelPrefixNumber
- (instancetype)initWithUnsignedShort:(unsigned short)value;
+ (instancetype)numberWithUnsignedShort:(unsigned short)value;
@end
__attribute__((swift_name("KotlinInt")))
@interface MyTopLevelPrefixInt : MyTopLevelPrefixNumber
- (instancetype)initWithInt:(int)value;
+ (instancetype)numberWithInt:(int)value;
@end
__attribute__((swift_name("KotlinUInt")))
@interface MyTopLevelPrefixUInt : MyTopLevelPrefixNumber
- (instancetype)initWithUnsignedInt:(unsigned int)value;
+ (instancetype)numberWithUnsignedInt:(unsigned int)value;
@end
__attribute__((swift_name("KotlinLong")))
@interface MyTopLevelPrefixLong : MyTopLevelPrefixNumber
- (instancetype)initWithLongLong:(long long)value;
+ (instancetype)numberWithLongLong:(long long)value;
@end
__attribute__((swift_name("KotlinULong")))
@interface MyTopLevelPrefixULong : MyTopLevelPrefixNumber
- (instancetype)initWithUnsignedLongLong:(unsigned long long)value;
+ (instancetype)numberWithUnsignedLongLong:(unsigned long long)value;
@end
__attribute__((swift_name("KotlinFloat")))
@interface MyTopLevelPrefixFloat : MyTopLevelPrefixNumber
- (instancetype)initWithFloat:(float)value;
+ (instancetype)numberWithFloat:(float)value;
@end
__attribute__((swift_name("KotlinDouble")))
@interface MyTopLevelPrefixDouble : MyTopLevelPrefixNumber
- (instancetype)initWithDouble:(double)value;
+ (instancetype)numberWithDouble:(double)value;
@end
__attribute__((swift_name("KotlinBoolean")))
@interface MyTopLevelPrefixBoolean : MyTopLevelPrefixNumber
- (instancetype)initWithBool:(BOOL)value;
+ (instancetype)numberWithBool:(BOOL)value;
@end