Improve naming in produced framework

*   Group top-level declarations by file name instead of package name
*   Remove main prefix from Swift class names
*   Use 'Kotlin' prefix
    * Instead of 'Stdlib'
    * In Swift names for KotlinMutableSet/Dictionary, KotlinNumber and subclasses
This commit is contained in:
Svyatoslav Scherbina
2018-09-05 11:03:54 +03:00
committed by SvyatoslavScherbina
parent 2f61cf9fa3
commit da2736337e
9 changed files with 331 additions and 267 deletions
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.isUnit
@@ -149,24 +148,28 @@ internal class ObjCExportCodeGenerator(
internal fun emitRtti(
generatedClasses: Collection<ClassDescriptor>,
topLevel: Map<FqName, List<CallableMemberDescriptor>>
topLevel: Map<SourceFile, List<CallableMemberDescriptor>>
) {
val objCTypeAdapters = mutableListOf<ObjCTypeAdapter>()
generatedClasses.forEach {
objCTypeAdapters += createTypeAdapter(it)
val className = namer.getClassOrProtocolName(it)
val superClass = it.getSuperClassOrAny()
val superClassName = namer.getClassOrProtocolName(superClass)
dataGenerator.emitEmptyClass(className, superClassName)
// Note: it is generated only to be visible for linker.
// Methods will be added at runtime.
if (!it.isInterface) {
val className = namer.getClassOrProtocolName(it).binaryName
val superClass = it.getSuperClassOrAny()
val superClassName = namer.getClassOrProtocolName(superClass).binaryName
dataGenerator.emitEmptyClass(className, superClassName)
// Note: it is generated only to be visible for linker.
// Methods will be added at runtime.
}
}
topLevel.forEach { fqName, declarations ->
objCTypeAdapters += createTypeAdapterForPackage(fqName, declarations)
dataGenerator.emitEmptyClass(namer.getPackageName(fqName), namer.kotlinAnyName)
topLevel.forEach { sourceFile, declarations ->
objCTypeAdapters += createTypeAdapterForFileClass(sourceFile, declarations)
val name = namer.getFileClassName(sourceFile).binaryName
dataGenerator.emitEmptyClass(name, namer.kotlinAnyName.binaryName)
}
NSNumberKind.values().mapNotNull { it.mappedKotlinClassId }.forEach {
@@ -831,11 +834,11 @@ private fun ObjCExportCodeGenerator.vtableIndex(descriptor: FunctionDescriptor):
}
}
private fun ObjCExportCodeGenerator.createTypeAdapterForPackage(
fqName: FqName,
private fun ObjCExportCodeGenerator.createTypeAdapterForFileClass(
sourceFile: SourceFile,
declarations: List<CallableMemberDescriptor>
): ObjCExportCodeGenerator.ObjCTypeAdapter {
val name = namer.getPackageName(fqName)
val name = namer.getFileClassName(sourceFile).binaryName
val adapters = declarations.toMethods().map { createMethodAdapter(it, it) }
@@ -934,7 +937,7 @@ private fun ObjCExportCodeGenerator.createTypeAdapter(
val irClass = context.ir.get(descriptor)
val typeInfo = constPointer(codegen.typeInfoValue(irClass))
val objCName = namer.getClassOrProtocolName(descriptor)
val objCName = namer.getClassOrProtocolName(descriptor).binaryName
val vtableSize = if (descriptor.kind == ClassKind.INTERFACE) {
-1
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.backend.konan.llvm.objcexport.ObjCExportCodeGenerato
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.SourceFile
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.konan.target.KonanTarget
@@ -33,7 +34,7 @@ internal class ObjCExport(val codegen: CodeGenerator) {
val objCCodeGenerator: ObjCExportCodeGenerator
val generatedClasses: Set<ClassDescriptor>
val topLevelDeclarations: Map<FqName, List<CallableMemberDescriptor>>
val topLevelDeclarations: Map<SourceFile, List<CallableMemberDescriptor>>
if (context.config.produce == CompilerOutputKind.FRAMEWORK) {
val headerGenerator = ObjCExportHeaderGeneratorImpl(context)
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.builtins.UnsignedType
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.constants.ArrayValue
import org.jetbrains.kotlin.resolve.constants.KClassValue
@@ -43,7 +42,7 @@ abstract class ObjCExportHeaderGenerator(
internal val namer = ObjCExportNamerImpl(moduleDescriptor, builtIns, mapper, topLevelNamePrefix)
internal val generatedClasses = mutableSetOf<ClassDescriptor>()
internal val topLevel = mutableMapOf<FqName, MutableList<CallableMemberDescriptor>>()
internal val topLevel = mutableMapOf<SourceFile, MutableList<CallableMemberDescriptor>>()
private val mappedToNSNumber: List<ClassDescriptor> = with(builtIns) {
val result = mutableListOf(boolean, byte, short, int, long, float, double)
@@ -63,15 +62,15 @@ abstract class ObjCExportHeaderGenerator(
result += CustomTypeMapper.Collection(generator, list, "NSArray")
result += CustomTypeMapper.Collection(generator, mutableList, "NSMutableArray")
result += CustomTypeMapper.Collection(generator, set, "NSSet")
result += CustomTypeMapper.Collection(generator, mutableSet, namer.mutableSetName)
result += CustomTypeMapper.Collection(generator, mutableSet, namer.mutableSetName.objCName)
result += CustomTypeMapper.Collection(generator, map, "NSDictionary")
result += CustomTypeMapper.Collection(generator, mutableMap, namer.mutableMapName)
result += CustomTypeMapper.Collection(generator, mutableMap, namer.mutableMapName.objCName)
NSNumberKind.values().forEach {
// TODO: NSNumber seem to have different equality semantics.
if (it.mappedKotlinClassId != null) {
val descriptor = moduleDescriptor.findClassAcrossModuleDependencies(it.mappedKotlinClassId)!!
result += CustomTypeMapper.Simple(descriptor, namer.numberBoxName(descriptor))
result += CustomTypeMapper.Simple(descriptor, namer.numberBoxName(descriptor).objCName)
}
}
@@ -99,7 +98,7 @@ abstract class ObjCExportHeaderGenerator(
private val kotlinAnyName = namer.kotlinAnyName
private val stubs = mutableListOf<Stub<*>>()
private val classOrInterfaceToName = mutableMapOf<ClassDescriptor, String>()
private val classOrInterfaceToName = mutableMapOf<ClassDescriptor, ObjCExportNamer.ClassOrProtocolName>()
private val classForwardDeclarations = mutableSetOf<String>()
private val protocolForwardDeclarations = mutableSetOf<String>()
@@ -107,37 +106,74 @@ abstract class ObjCExportHeaderGenerator(
private val extensions = mutableMapOf<ClassDescriptor, MutableList<CallableMemberDescriptor>>()
private val extraClassesToTranslate = mutableSetOf<ClassDescriptor>()
private fun objCInterface(
name: ObjCExportNamer.ClassOrProtocolName,
generics: List<String> = emptyList(),
descriptor: ClassDescriptor? = null,
superClass: String? = null,
superProtocols: List<String> = emptyList(),
categoryName: String? = null,
members: List<Stub<*>> = emptyList(),
attributes: List<String> = emptyList()
): ObjCInterface = ObjCInterface(
name.objCName,
generics,
descriptor,
superClass,
superProtocols,
categoryName,
members,
attributes + name.toNameAttributes()
)
private fun objCProtocol(
name: ObjCExportNamer.ClassOrProtocolName,
descriptor: ClassDescriptor,
superProtocols: List<String>,
members: List<Stub<*>>,
attributes: List<String> = emptyList()
): ObjCProtocol = ObjCProtocol(
name.objCName,
descriptor,
superProtocols,
members,
attributes + name.toNameAttributes()
)
private fun ObjCExportNamer.ClassOrProtocolName.toNameAttributes(): List<String> = listOfNotNull(
binaryName.takeIf { it != objCName }?.let { objcRuntimeNameAttribute(it) },
swiftName.takeIf { it != objCName }?.let { swiftNameAttribute(it) }
)
fun translateModule(): List<Stub<*>> {
// TODO: make the translation order stable
// to stabilize name mangling.
stubs.add(ObjCInterface(kotlinAnyName, superClass = "NSObject", members = buildMembers {
stubs.add(objCInterface(kotlinAnyName, superClass = "NSObject", members = buildMembers {
+ObjCMethod(null, true, ObjCInstanceType, listOf("init"), emptyList(), listOf("unavailable"))
+ObjCMethod(null, false, ObjCInstanceType, listOf("new"), emptyList(), listOf("unavailable"))
+ObjCMethod(null, false, ObjCVoidType, listOf("initialize"), emptyList(), listOf("objc_requires_super"))
}))
// TODO: add comment to the header.
stubs.add(ObjCInterface(
stubs.add(objCInterface(
kotlinAnyName,
superProtocols = listOf("NSCopying"),
categoryName = "${kotlinAnyName}Copying"
categoryName = "${kotlinAnyName.objCName}Copying"
))
// TODO: only if appears
stubs.add(ObjCInterface(
stubs.add(objCInterface(
namer.mutableSetName,
generics = listOf("ObjectType"),
superClass = "NSMutableSet<ObjectType>",
attributes = listOf(objcRuntimeNameAttribute("KotlinMutableSet"))
superClass = "NSMutableSet<ObjectType>"
))
// TODO: only if appears
stubs.add(ObjCInterface(
stubs.add(objCInterface(
namer.mutableMapName,
generics = listOf("KeyType", "ObjectType"),
superClass = "NSMutableDictionary<KeyType, ObjectType>",
attributes = listOf(objcRuntimeNameAttribute("KotlinMutableDictionary"))
superClass = "NSMutableDictionary<KeyType, ObjectType>"
))
stubs.add(ObjCInterface("NSError", categoryName = "NSErrorKotlinException", members = buildMembers {
@@ -158,7 +194,7 @@ abstract class ObjCExportHeaderGenerator(
if (classDescriptor != null) {
extensions.getOrPut(classDescriptor, { mutableListOf() }) += it
} else {
topLevel.getOrPut(packageFragment.fqName, { mutableListOf() }) += it
topLevel.getOrPut(it.source.containingFile, { mutableListOf() }) += it
}
}
@@ -188,8 +224,8 @@ abstract class ObjCExportHeaderGenerator(
translateExtensions(classDescriptor, declarations)
}
topLevel.forEach { packageFqName, declarations ->
translateTopLevel(packageFqName, declarations)
topLevel.forEach { sourceFile, declarations ->
translateTopLevel(sourceFile, declarations)
}
while (extraClassesToTranslate.isNotEmpty()) {
@@ -214,11 +250,10 @@ abstract class ObjCExportHeaderGenerator(
+nsNumberInit(it, listOf("unavailable"))
}
}
stubs.add(ObjCInterface(
stubs.add(objCInterface(
namer.kotlinNumberName,
superClass = "NSNumber",
members = members,
attributes = listOf(objcRuntimeNameAttribute("KotlinNumber"))
members = members
))
NSNumberKind.values().forEach {
@@ -236,11 +271,10 @@ abstract class ObjCExportHeaderGenerator(
+nsNumberFactory(kind)
+nsNumberInit(kind)
}
return ObjCInterface(
return objCInterface(
name,
superClass = namer.kotlinNumberName,
members = members,
attributes = listOf(objcRuntimeNameAttribute("Kotlin${kotlinClassId.shortClassName}"))
superClass = namer.kotlinNumberName.objCName,
members = members
)
}
@@ -266,21 +300,21 @@ abstract class ObjCExportHeaderGenerator(
)
}
private fun translateClassName(descriptor: ClassDescriptor): String = classOrInterfaceToName.getOrPut(descriptor) {
private fun translateClassName(descriptor: ClassDescriptor) = classOrInterfaceToName.getOrPut(descriptor) {
assert(mapper.shouldBeExposed(descriptor))
val forwardDeclarations = if (descriptor.isInterface) protocolForwardDeclarations else classForwardDeclarations
namer.getClassOrProtocolName(descriptor).also { forwardDeclarations += it }
namer.getClassOrProtocolName(descriptor).also { forwardDeclarations += it.objCName }
}
private fun translateInterface(descriptor: ClassDescriptor) {
if (!generatedClasses.add(descriptor)) return
val name: String = translateClassName(descriptor)
val name = translateClassName(descriptor)
val members: List<Stub<*>> = buildMembers { translateClassOrInterfaceMembers(descriptor) }
val superProtocols: List<String> = descriptor.superProtocols
val protocolStub = ObjCProtocol(name, descriptor, superProtocols, members)
val protocolStub = objCProtocol(name, descriptor, superProtocols, members)
stubs.add(protocolStub)
}
@@ -292,7 +326,7 @@ abstract class ObjCExportHeaderGenerator(
.filter { mapper.shouldBeExposed(it) }
.map {
translateInterface(it)
translateClassName(it)
translateClassName(it).objCName
}
.toList()
@@ -303,19 +337,19 @@ abstract class ObjCExportHeaderGenerator(
val members = buildMembers {
translateMembers(declarations)
}
stubs.add(ObjCInterface(name, categoryName = "Extensions", members = members))
stubs.add(objCInterface(name, categoryName = "Extensions", members = members))
}
private fun translateTopLevel(packageFqName: FqName, declarations: List<CallableMemberDescriptor>) {
val name = namer.getPackageName(packageFqName)
private fun translateTopLevel(sourceFile: SourceFile, declarations: List<CallableMemberDescriptor>) {
val name = namer.getFileClassName(sourceFile)
// TODO: stop inheriting KotlinBase.
val members = buildMembers {
translateMembers(declarations)
}
stubs.add(ObjCInterface(
stubs.add(objCInterface(
name,
superClass = namer.kotlinAnyName,
superClass = namer.kotlinAnyName.objCName,
members = members,
attributes = listOf("objc_subclassing_restricted")
))
@@ -327,7 +361,7 @@ abstract class ObjCExportHeaderGenerator(
val name = translateClassName(descriptor)
val superClass = descriptor.getSuperClassNotAny()
val superName: String = if (superClass == null) {
val superName = if (superClass == null) {
kotlinAnyName
} else {
translateClass(superClass)
@@ -404,10 +438,10 @@ abstract class ObjCExportHeaderGenerator(
val attributes = if (descriptor.isFinalOrEnum) listOf("objc_subclassing_restricted") else emptyList()
val interfaceStub = ObjCInterface(
val interfaceStub = objCInterface(
name,
descriptor = descriptor,
superClass = superName,
superClass = superName.objCName,
superProtocols = superProtocols,
members = members,
attributes = attributes
@@ -763,9 +797,9 @@ abstract class ObjCExportHeaderGenerator(
scheduleClassToBeGenerated(classDescriptor)
return if (classDescriptor.isInterface) {
ObjCProtocolType(translateClassName(classDescriptor))
ObjCProtocolType(translateClassName(classDescriptor).objCName)
} else {
ObjCClassType(translateClassName(classDescriptor))
ObjCClassType(translateClassName(classDescriptor).objCName)
}
}
@@ -9,14 +9,20 @@ import org.jetbrains.kotlin.backend.konan.descriptors.isArray
import org.jetbrains.kotlin.backend.konan.descriptors.isInterface
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.konan.isKonanStdlib
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.descriptorUtil.*
import org.jetbrains.kotlin.resolve.source.PsiSourceFile
interface ObjCExportNamer {
fun getPackageName(fqName: FqName): String
fun getClassOrProtocolName(descriptor: ClassDescriptor): String
data class ClassOrProtocolName(val swiftName: String, val objCName: String, val binaryName: String = objCName)
fun getFileClassName(file: SourceFile): ClassOrProtocolName
fun getClassOrProtocolName(descriptor: ClassDescriptor): ClassOrProtocolName
fun getSelector(method: FunctionDescriptor): String
fun getSwiftName(method: FunctionDescriptor): String
fun getPropertyName(property: PropertyDescriptor): String
@@ -40,15 +46,27 @@ internal class ObjCExportNamerImpl(
private val topLevelNamePrefix: String = moduleDescriptor.namePrefix
) : ObjCExportNamer {
val kotlinAnyName = "KotlinBase"
private fun String.mangleClassOrProtocolName(): ObjCExportNamer.ClassOrProtocolName =
ObjCExportNamer.ClassOrProtocolName(swiftName = this, objCName = "$topLevelNamePrefix${this}")
private val commonPackageSegments = moduleDescriptor.guessMainPackage().pathSegments()
private fun String.toUnmangledClassOrProtocolName(): ObjCExportNamer.ClassOrProtocolName =
ObjCExportNamer.ClassOrProtocolName(swiftName = this, objCName = this)
val mutableSetName = "${topLevelNamePrefix}MutableSet"
val mutableMapName = "${topLevelNamePrefix}MutableDictionary"
private fun String.toSpecialStandardClassOrProtocolName() = ObjCExportNamer.ClassOrProtocolName(
swiftName = "Kotlin$this",
objCName = "${topLevelNamePrefix}$this",
binaryName = "Kotlin$this"
)
fun numberBoxName(descriptor: ClassDescriptor): String = "$topLevelNamePrefix${descriptor.name.asString()}"
val kotlinNumberName = "${topLevelNamePrefix}Number"
val kotlinAnyName = "KotlinBase".toUnmangledClassOrProtocolName()
val mutableSetName = "MutableSet".toSpecialStandardClassOrProtocolName()
val mutableMapName = "MutableDictionary".toSpecialStandardClassOrProtocolName()
fun numberBoxName(descriptor: ClassDescriptor): ObjCExportNamer.ClassOrProtocolName =
descriptor.name.asString().toSpecialStandardClassOrProtocolName()
val kotlinNumberName = "Number".toSpecialStandardClassOrProtocolName()
private val methodSelectors = object : Mapping<FunctionDescriptor, String>() {
@@ -109,26 +127,26 @@ internal class ObjCExportNamerImpl(
first.containingDeclaration == second.containingDeclaration
}
override fun getPackageName(fqName: FqName): String = classNames.getOrPut(fqName) {
StringBuilder().apply {
append(topLevelNamePrefix)
fqName.pathSegments().forEachIndexed { index, segment ->
if (index < commonPackageSegments.size) {
assert(commonPackageSegments[index] == segment)
} else {
append(segment.asString().capitalize())
}
}
}.mangledSequence { append("_") }
}
override fun getFileClassName(file: SourceFile): ObjCExportNamer.ClassOrProtocolName = classNames.getOrPut(file) {
val psiSourceFile = file as? PsiSourceFile ?: error("SourceFile '$file' is not PsiSourceFile")
val psiFile = psiSourceFile.psiFile
val ktFile = psiFile as? KtFile ?: error("PsiFile '$psiFile' is not KtFile")
StringBuilder(PackagePartClassUtils.getFilePartShortName(ktFile.name)).mangledSequence { append("_") }
}.mangleClassOrProtocolName()
private val predefinedClassNames = mapOf(
builtIns.any to kotlinAnyName,
builtIns.mutableSet to mutableSetName,
builtIns.mutableMap to mutableMapName
)
override fun getClassOrProtocolName(descriptor: ClassDescriptor): ObjCExportNamer.ClassOrProtocolName {
predefinedClassNames[descriptor]?.let { return it }
override fun getClassOrProtocolName(descriptor: ClassDescriptor): String {
val mapping = if (descriptor.isInterface) protocolNames else classNames
return mapping.getOrPut(descriptor) {
StringBuilder().apply {
append(topLevelNamePrefix)
if (descriptor.module != moduleDescriptor) {
append(descriptor.module.namePrefix)
}
@@ -137,7 +155,7 @@ internal class ObjCExportNamerImpl(
.toList().reversed()
.joinTo(this, "") { it.name.asString().capitalize() }
}.mangledSequence { append("_") }
}
}.mangleClassOrProtocolName()
}
override fun getSelector(method: FunctionDescriptor): String = methodSelectors.getOrPut(method) {
@@ -192,7 +210,7 @@ internal class ObjCExportNamerImpl(
assert(mapper.isBaseMethod(method))
val parameters = mapper.bridgeMethod(method).valueParametersAssociated(method)
StringBuilder().apply {
append(method.getMangledName(forSwift = true))
append("(")
@@ -261,9 +279,10 @@ internal class ObjCExportNamerImpl(
init {
val any = builtIns.any
classNames.forceAssign(any, kotlinAnyName)
classNames.forceAssign(builtIns.mutableSet, mutableSetName)
classNames.forceAssign(builtIns.mutableMap, mutableMapName)
predefinedClassNames.forEach { descriptor, name ->
// Note: it is a hack.
classNames.forceAssign(descriptor, name.swiftName)
}
fun ClassDescriptor.method(name: String) =
this.unsubstitutedMemberScope.getContributedFunctions(
@@ -453,6 +472,8 @@ private fun ObjCExportMapper.canHaveSameName(first: PropertyDescriptor, second:
}
internal val ModuleDescriptor.namePrefix: String get() {
if (this.isKonanStdlib()) return "Kotlin"
// <fooBar> -> FooBar
val moduleName = this.name.asString()
.let { it.substring(1, it.lastIndex) }
@@ -12,6 +12,9 @@ object StubRenderer {
stub.run {
when (this) {
is ObjCProtocol -> {
attributes.forEach {
+renderAttribute(it)
}
+renderProtocolHeader()
+"@required"
renderMembers(this)
@@ -15,12 +15,14 @@ open class Stub<out D : DeclarationDescriptor>(val name: String, val descriptor:
abstract class ObjCClass<out D : DeclarationDescriptor>(name: String,
descriptor: D?,
val superProtocols: List<String>,
val members: List<Stub<*>>) : Stub<D>(name, descriptor)
val members: List<Stub<*>>,
val attributes: List<String>) : Stub<D>(name, descriptor)
class ObjCProtocol(name: String,
descriptor: ClassDescriptor,
superProtocols: List<String>,
members: List<Stub<*>>) : ObjCClass<ClassDescriptor>(name, descriptor, superProtocols, members)
members: List<Stub<*>>,
attributes: List<String> = emptyList()) : ObjCClass<ClassDescriptor>(name, descriptor, superProtocols, members, attributes)
class ObjCInterface(name: String,
val generics: List<String> = emptyList(),
@@ -29,7 +31,7 @@ class ObjCInterface(name: String,
superProtocols: List<String> = emptyList(),
val categoryName: String? = null,
members: List<Stub<*>> = emptyList(),
val attributes: List<String> = emptyList()) : ObjCClass<ClassDescriptor>(name, descriptor, superProtocols, members)
attributes: List<String> = emptyList()) : ObjCClass<ClassDescriptor>(name, descriptor, superProtocols, members, attributes)
class ObjCMethod(descriptor: DeclarationDescriptor?,
val isInstanceMethod: Boolean,
@@ -57,8 +57,8 @@ class StdlibTests : TestProvider {
*/
func testEmptyDictionary() throws {
let immutableEmptyDict = [String: Int]()
try assertTrue(Stdlib.isEmpty(map: immutableEmptyDict), "Empty dictionary")
let keys = Stdlib.getKeysAsSet(map: immutableEmptyDict)
try assertTrue(StdlibKt.isEmpty(map: immutableEmptyDict), "Empty dictionary")
let keys = StdlibKt.getKeysAsSet(map: immutableEmptyDict)
try assertTrue(keys.isEmpty, "Should have empty set")
}
@@ -66,7 +66,7 @@ class StdlibTests : TestProvider {
* Tests usage of a map with generics.
*/
func testGenericMapUsage() throws {
let map = Stdlib.createLinkedMap()
let map = StdlibKt.createLinkedMap()
map[1] = "One"
map[10] = "Ten"
map[11] = "Eleven"
@@ -82,7 +82,7 @@ class StdlibTests : TestProvider {
* Checks order of the underlying LinkedHashMap.
*/
func testOrderedMapStored() throws {
let pair = Stdlib.createPair()
let pair = StdlibKt.createPair()
let map = pair.first as? NSMutableDictionary
map?[1] = "One"
@@ -90,7 +90,7 @@ class StdlibTests : TestProvider {
map?[11] = "Eleven"
map?["10"] = "Ten as string"
let gen = pair.second as! StdlibGenericExtensionClass
let gen = pair.second as! GenericExtensionClass
let value: String? = gen.getFirstValue() as? String
try assertEquals(actual: value!, expected: "One", "First value of the map")
@@ -102,7 +102,7 @@ class StdlibTests : TestProvider {
* Tests typed map created in Kotlin.
*/
func testTypedMapUsage() throws {
let map = Stdlib.createTypedMutableMap()
let map = StdlibKt.createTypedMutableMap()
map[1] = "One"
map[1.0 as Float] = "Float"
map[11] = "Eleven"
@@ -116,11 +116,11 @@ class StdlibTests : TestProvider {
* Get first element of the collection.
*/
func testFirstElement() throws {
let m = Stdlib.createTypedMutableMap()
let m = StdlibKt.createTypedMutableMap()
m[10] = "Str"
try assertEquals(actual: Stdlib.getFirstElement(collection: m.allKeys) as! Int, expected: 10, "First key")
try assertEquals(actual: StdlibKt.getFirstElement(collection: m.allKeys) as! Int, expected: 10, "First key")
try assertEquals(actual: Stdlib.getFirstElement(collection: Stdlib.getKeysAsList(map: m as! Dictionary)) as! Int,
try assertEquals(actual: StdlibKt.getFirstElement(collection: StdlibKt.getKeysAsList(map: m as! Dictionary)) as! Int,
expected: 10, "First key from a list")
}
@@ -129,35 +129,35 @@ class StdlibTests : TestProvider {
*/
func testAddDictionary() throws {
let m = [ "ABC": 10, "CDE": 12, "FGH": 3 ]
Stdlib.addSomeElementsToMap(map: StdlibMutableDictionary(dictionary: m))
StdlibKt.addSomeElementsToMap(map: KotlinMutableDictionary(dictionary: m))
for (k, v) in m {
print("MAP: \(k) - \(v)")
}
var smd = StdlibMutableDictionary<NSString, StdlibInt>()
var smd = KotlinMutableDictionary<NSString, KotlinInt>()
smd.setObject(333, forKey: "333" as NSString)
try assertEquals(actual: smd.object(forKey: "333" as NSString) as! Int, expected: 333, "Add element to dict")
Stdlib.addSomeElementsToMap(map: smd)
StdlibKt.addSomeElementsToMap(map: smd)
for (k, v) in smd {
print("MAP: \(k) - \(v)")
}
try assertEquals(actual: smd.object(forKey: "XYZ" as NSString) as! Int, expected: 321, "Get element from Kotlin")
}
func zeroTo(_ n: Int32) -> StdlibStdlibArray { return StdlibStdlibArray(size: n) { $0 } }
func zeroTo(_ n: Int32) -> KotlinArray { return KotlinArray(size: n) { $0 } }
func testList() throws {
let elements = zeroTo(5)
elements.set(index: 1, value: nil)
let list = Stdlib.list(elements: elements) as! NSArray
let list = StdlibKt.list(elements: elements) as! NSArray
try assertEquals(actual: list.object(at: 2) as! NSNumber, expected: NSNumber(value: 2))
try assertEquals(actual: list.object(at: 1) as! NSNull, expected: NSNull())
try assertEquals(actual: list.count, expected: 5)
}
func testMutableList() throws {
let kotlinList = Stdlib.emptyMutableList() as! NSMutableArray
let kotlinList = StdlibKt.emptyMutableList() as! NSMutableArray
let nsList = NSMutableArray()
func apply<T : Equatable>(op: (NSMutableArray)->T) throws {
@@ -191,7 +191,7 @@ class StdlibTests : TestProvider {
}
func testMutableSet() throws {
let kotlinSet = Stdlib.emptyMutableSet() as! NSMutableSet
let kotlinSet = StdlibKt.emptyMutableSet() as! NSMutableSet
let nsSet = NSMutableSet()
func apply<T : Equatable>(op: (NSMutableSet)->T) throws {
@@ -214,10 +214,10 @@ class StdlibTests : TestProvider {
try applyVoid { $0.add("bar") }
try applyVoid { $0.remove("baz") }
try applyVoid { $0.add("baz") }
try applyVoid { $0.add(StdlibTripleVals(first: 1, second: 2, third: 3)) }
try apply { $0.member(StdlibTripleVals(first: 1, second: 2, third: 3)) as! StdlibTripleVals }
try applyVoid { $0.add(TripleVals(first: 1, second: 2, third: 3)) }
try apply { $0.member(TripleVals(first: 1, second: 2, third: 3)) as! TripleVals }
try apply { $0.member(42) == nil }
try applyVoid { $0.remove(StdlibTripleVals(first: 1, second: 2, third: 3)) }
try applyVoid { $0.remove(TripleVals(first: 1, second: 2, third: 3)) }
let NULL0: Any? = nil
let NULL = NULL0 as Any
@@ -235,7 +235,7 @@ class StdlibTests : TestProvider {
func testMutableMap() throws {
// TODO: test KotlinMutableSet/Dictionary constructors
let kotlinMap = Stdlib.emptyMutableMap() as! NSMutableDictionary
let kotlinMap = StdlibKt.emptyMutableMap() as! NSMutableDictionary
let nsMap = NSMutableDictionary()
func apply<T : Equatable>(op: (NSMutableDictionary)->T) throws {
@@ -257,7 +257,7 @@ class StdlibTests : TestProvider {
try apply { $0.object(forKey: 42) == nil }
try applyVoid { $0.setObject(42, forKey: 42 as NSNumber) }
try applyVoid { $0.setObject(17, forKey: "foo" as NSString) }
let triple = StdlibTripleVals(first: 3, second: 2, third: 1)
let triple = TripleVals(first: 3, second: 2, third: 1)
try applyVoid { $0.setObject("bar", forKey: triple) }
try applyVoid { $0.removeObject(forKey: 42) }
try apply { $0.count }
@@ -312,10 +312,10 @@ class StdlibTests : TestProvider {
}
func testSet() throws {
let elements = StdlibStdlibArray(size: 2) { index in nil }
let elements = KotlinArray(size: 2) { index in nil }
elements.set(index: 0, value: nil)
elements.set(index: 1, value: 42)
let set = Stdlib.set(elements: elements) as! NSSet
let set = StdlibKt.set(elements: elements) as! NSSet
try assertEquals(actual: set.count, expected: 2)
try assertEquals(actual: set.member(NSNull()) as! NSNull, expected: NSNull())
try assertEquals(actual: set.member(42) as! NSNumber, expected: NSNumber(value: 42 as Int32))
@@ -329,7 +329,7 @@ class StdlibTests : TestProvider {
}
func testMap() throws {
let elements = StdlibStdlibArray(size: 6) { index in nil }
let elements = KotlinArray(size: 6) { index in nil }
elements.set(index: 0, value: nil)
elements.set(index: 1, value: 42)
elements.set(index: 2, value: "foo")
@@ -337,7 +337,7 @@ class StdlibTests : TestProvider {
elements.set(index: 4, value: 42)
elements.set(index: 5, value: nil)
let map = Stdlib.map(keysAndValues: elements) as! NSDictionary
let map = StdlibKt.map(keysAndValues: elements) as! NSDictionary
try assertEquals(actual: map.count, expected: 3)
try assertEquals(actual: map.object(forKey: NSNull()) as! NSNumber, expected: NSNumber(value: 42))
+152 -152
View File
@@ -21,10 +21,10 @@ import Values
func testVals() throws {
print("Values from Swift")
let dbl = Values.dbl
let flt = Values.flt
let int = Values.integer
let long = Values.longInt
let dbl = ValuesKt.dbl
let flt = ValuesKt.flt
let int = ValuesKt.integer
let long = ValuesKt.longInt
print(dbl)
print(flt)
@@ -39,9 +39,9 @@ func testVals() throws {
func testVars() throws {
print("Variables from Swift")
var intVar = Values.intVar
var strVar = Values.str
var strAsId = Values.strAsAny
var intVar = ValuesKt.intVar
var strVar = ValuesKt.str
var strAsId = ValuesKt.strAsAny
print(intVar)
print(strVar)
@@ -52,133 +52,133 @@ func testVars() throws {
try assertEquals(actual: strAsId as! String, expected: "Kotlin String as Any")
strAsId = "Swift str"
Values.strAsAny = strAsId
print(Values.strAsAny)
try assertEquals(actual: Values.strAsAny as! String, expected: strAsId as! String)
ValuesKt.strAsAny = strAsId
print(ValuesKt.strAsAny)
try assertEquals(actual: ValuesKt.strAsAny as! String, expected: strAsId as! String)
// property with custom getter/setter backed by the Kotlin's var
var intProp : Int32 {
get {
return Values.intVar * 2
return ValuesKt.intVar * 2
}
set(value) {
Values.intVar = 123 + value
ValuesKt.intVar = 123 + value
}
}
intProp += 10
intProp += 10
print(intProp)
print(Values.intVar)
try assertEquals(actual: Values.intVar * 2, expected: intProp, "Property backed by var")
print(ValuesKt.intVar)
try assertEquals(actual: ValuesKt.intVar * 2, expected: intProp, "Property backed by var")
}
func testDoubles() throws {
print("Doubles in Swift")
let minDouble = Values.minDoubleVal as! Double
let maxDouble = Values.maxDoubleVal as! NSNumber
let minDouble = ValuesKt.minDoubleVal as! Double
let maxDouble = ValuesKt.maxDoubleVal as! NSNumber
print(minDouble)
print(maxDouble)
print(Values.nanDoubleVal)
print(Values.nanFloatVal)
print(Values.infDoubleVal)
print(Values.infFloatVal)
print(ValuesKt.nanDoubleVal)
print(ValuesKt.nanFloatVal)
print(ValuesKt.infDoubleVal)
print(ValuesKt.infFloatVal)
try assertEquals(actual: minDouble, expected: Double.leastNonzeroMagnitude, "Min double")
try assertEquals(actual: maxDouble, expected: Double.greatestFiniteMagnitude as NSNumber, "Max double")
try assertTrue(Values.nanDoubleVal.isNaN, "NaN double")
try assertTrue(Values.nanFloatVal.isNaN, "NaN float")
try assertEquals(actual: Values.infDoubleVal, expected: Double.infinity, "Inf double")
try assertEquals(actual: Values.infFloatVal, expected: -Float.infinity, "-Inf float")
try assertTrue(ValuesKt.nanDoubleVal.isNaN, "NaN double")
try assertTrue(ValuesKt.nanFloatVal.isNaN, "NaN float")
try assertEquals(actual: ValuesKt.infDoubleVal, expected: Double.infinity, "Inf double")
try assertEquals(actual: ValuesKt.infFloatVal, expected: -Float.infinity, "-Inf float")
}
func testNumbers() throws {
try assertEquals(actual: ValuesBoolean(value: true).boolValue, expected: true)
try assertEquals(actual: ValuesBoolean(value: false).intValue, expected: 0)
try assertEquals(actual: ValuesBoolean(value: true), expected: true)
try assertFalse(ValuesBoolean(value: false) as! Bool)
try assertEquals(actual: KotlinBoolean(value: true).boolValue, expected: true)
try assertEquals(actual: KotlinBoolean(value: false).intValue, expected: 0)
try assertEquals(actual: KotlinBoolean(value: true), expected: true)
try assertFalse(KotlinBoolean(value: false) as! Bool)
try assertEquals(actual: ValuesByte(value: -1).int8Value, expected: -1)
try assertEquals(actual: ValuesByte(value: -1).int32Value, expected: -1)
try assertEquals(actual: ValuesByte(value: -1).doubleValue, expected: -1.0)
try assertEquals(actual: ValuesByte(value: -1), expected: NSNumber(value: Int64(-1)))
try assertFalse(ValuesByte(value: -1) == NSNumber(value: -1.5))
try assertEquals(actual: ValuesByte(value: -1), expected: -1)
try assertTrue(ValuesByte(value: -1) == -1)
try assertFalse(ValuesByte(value: -1) == 1)
try assertEquals(actual: ValuesByte(value: -1) as! Int32, expected: -1)
try assertEquals(actual: KotlinByte(value: -1).int8Value, expected: -1)
try assertEquals(actual: KotlinByte(value: -1).int32Value, expected: -1)
try assertEquals(actual: KotlinByte(value: -1).doubleValue, expected: -1.0)
try assertEquals(actual: KotlinByte(value: -1), expected: NSNumber(value: Int64(-1)))
try assertFalse(KotlinByte(value: -1) == NSNumber(value: -1.5))
try assertEquals(actual: KotlinByte(value: -1), expected: -1)
try assertTrue(KotlinByte(value: -1) == -1)
try assertFalse(KotlinByte(value: -1) == 1)
try assertEquals(actual: KotlinByte(value: -1) as! Int32, expected: -1)
try assertEquals(actual: ValuesShort(value: 111).int16Value, expected: 111)
try assertEquals(actual: ValuesShort(value: -15) as! Int16, expected: -15)
try assertEquals(actual: ValuesShort(value: 47), expected: 47)
try assertEquals(actual: KotlinShort(value: 111).int16Value, expected: 111)
try assertEquals(actual: KotlinShort(value: -15) as! Int16, expected: -15)
try assertEquals(actual: KotlinShort(value: 47), expected: 47)
try assertEquals(actual: ValuesInt(value: 99).int32Value, expected: 99)
try assertEquals(actual: ValuesInt(value: -1) as! Int32, expected: -1)
try assertEquals(actual: ValuesInt(value: 72), expected: 72)
try assertEquals(actual: KotlinInt(value: 99).int32Value, expected: 99)
try assertEquals(actual: KotlinInt(value: -1) as! Int32, expected: -1)
try assertEquals(actual: KotlinInt(value: 72), expected: 72)
try assertEquals(actual: ValuesLong(value: 65).int64Value, expected: 65)
try assertEquals(actual: ValuesLong(value: 10000000000) as! Int64, expected: 10000000000)
try assertEquals(actual: ValuesLong(value: 8), expected: 8)
try assertEquals(actual: KotlinLong(value: 65).int64Value, expected: 65)
try assertEquals(actual: KotlinLong(value: 10000000000) as! Int64, expected: 10000000000)
try assertEquals(actual: KotlinLong(value: 8), expected: 8)
try assertEquals(actual: ValuesUByte(value: 17).uint8Value, expected: 17)
try assertEquals(actual: ValuesUByte(value: 42) as! UInt8, expected: 42)
try assertEquals(actual: 88, expected: ValuesUByte(value: 88))
try assertEquals(actual: KotlinUByte(value: 17).uint8Value, expected: 17)
try assertEquals(actual: KotlinUByte(value: 42) as! UInt8, expected: 42)
try assertEquals(actual: 88, expected: KotlinUByte(value: 88))
try assertEquals(actual: ValuesUShort(value: 40000).uint16Value, expected: 40000)
try assertEquals(actual: ValuesUShort(value: 1) as! UInt16, expected: UInt16(1))
try assertEquals(actual: ValuesUShort(value: 65000), expected: 65000)
try assertEquals(actual: KotlinUShort(value: 40000).uint16Value, expected: 40000)
try assertEquals(actual: KotlinUShort(value: 1) as! UInt16, expected: UInt16(1))
try assertEquals(actual: KotlinUShort(value: 65000), expected: 65000)
try assertEquals(actual: ValuesUInt(value: 3).uint32Value, expected: 3)
try assertEquals(actual: ValuesUInt(value: UInt32.max) as! UInt32, expected: UInt32.max)
try assertEquals(actual: ValuesUInt(value: 2), expected: 2)
try assertEquals(actual: KotlinUInt(value: 3).uint32Value, expected: 3)
try assertEquals(actual: KotlinUInt(value: UInt32.max) as! UInt32, expected: UInt32.max)
try assertEquals(actual: KotlinUInt(value: 2), expected: 2)
try assertEquals(actual: ValuesULong(value: 55).uint64Value, expected: 55)
try assertEquals(actual: ValuesULong(value: 0) as! UInt64, expected: 0)
try assertEquals(actual: ValuesULong(value: 7), expected: 7)
try assertEquals(actual: KotlinULong(value: 55).uint64Value, expected: 55)
try assertEquals(actual: KotlinULong(value: 0) as! UInt64, expected: 0)
try assertEquals(actual: KotlinULong(value: 7), expected: 7)
try assertEquals(actual: ValuesFloat(value: 1.0).floatValue, expected: 1.0)
try assertEquals(actual: ValuesFloat(value: 22.0) as! Float, expected: 22)
try assertEquals(actual: ValuesFloat(value: 41.0), expected: 41)
try assertEquals(actual: ValuesFloat(value: -5.5), expected: -5.5)
try assertEquals(actual: KotlinFloat(value: 1.0).floatValue, expected: 1.0)
try assertEquals(actual: KotlinFloat(value: 22.0) as! Float, expected: 22)
try assertEquals(actual: KotlinFloat(value: 41.0), expected: 41)
try assertEquals(actual: KotlinFloat(value: -5.5), expected: -5.5)
try assertEquals(actual: ValuesDouble(value: 0.5).doubleValue, expected: 0.5)
try assertEquals(actual: ValuesDouble(value: 45.0) as! Double, expected: 45)
try assertEquals(actual: ValuesDouble(value: 89.0), expected: 89)
try assertEquals(actual: ValuesDouble(value: -3.7), expected: -3.7)
try assertEquals(actual: KotlinDouble(value: 0.5).doubleValue, expected: 0.5)
try assertEquals(actual: KotlinDouble(value: 45.0) as! Double, expected: 45)
try assertEquals(actual: KotlinDouble(value: 89.0), expected: 89)
try assertEquals(actual: KotlinDouble(value: -3.7), expected: -3.7)
Values.ensureEqualBooleans(actual: ValuesBoolean(value: true), expected: true)
Values.ensureEqualBooleans(actual: false, expected: false)
ValuesKt.ensureEqualBooleans(actual: KotlinBoolean(value: true), expected: true)
ValuesKt.ensureEqualBooleans(actual: false, expected: false)
Values.ensureEqualBytes(actual: ValuesByte(value: 42), expected: 42)
Values.ensureEqualBytes(actual: -11, expected: -11)
ValuesKt.ensureEqualBytes(actual: KotlinByte(value: 42), expected: 42)
ValuesKt.ensureEqualBytes(actual: -11, expected: -11)
Values.ensureEqualShorts(actual: ValuesShort(value: 256), expected: 256)
Values.ensureEqualShorts(actual: -1, expected: -1)
ValuesKt.ensureEqualShorts(actual: KotlinShort(value: 256), expected: 256)
ValuesKt.ensureEqualShorts(actual: -1, expected: -1)
Values.ensureEqualInts(actual: ValuesInt(value: 100000), expected: 100000)
Values.ensureEqualInts(actual: -7, expected: -7)
ValuesKt.ensureEqualInts(actual: KotlinInt(value: 100000), expected: 100000)
ValuesKt.ensureEqualInts(actual: -7, expected: -7)
Values.ensureEqualLongs(actual: ValuesLong(value: Int64.max), expected: Int64.max)
Values.ensureEqualLongs(actual: 17, expected: 17)
ValuesKt.ensureEqualLongs(actual: KotlinLong(value: Int64.max), expected: Int64.max)
ValuesKt.ensureEqualLongs(actual: 17, expected: 17)
Values.ensureEqualUBytes(actual: ValuesUByte(value: 6), expected: 6)
Values.ensureEqualUBytes(actual: 255, expected: 255)
ValuesKt.ensureEqualUBytes(actual: KotlinUByte(value: 6), expected: 6)
ValuesKt.ensureEqualUBytes(actual: 255, expected: 255)
Values.ensureEqualUShorts(actual: ValuesUShort(value: 300), expected: 300)
Values.ensureEqualUShorts(actual: 65535, expected: UInt16.max)
ValuesKt.ensureEqualUShorts(actual: KotlinUShort(value: 300), expected: 300)
ValuesKt.ensureEqualUShorts(actual: 65535, expected: UInt16.max)
Values.ensureEqualUInts(actual: ValuesUInt(value: 70000), expected: 70000)
Values.ensureEqualUInts(actual: 48, expected: 48)
ValuesKt.ensureEqualUInts(actual: KotlinUInt(value: 70000), expected: 70000)
ValuesKt.ensureEqualUInts(actual: 48, expected: 48)
Values.ensureEqualULongs(actual: ValuesULong(value: UInt64.max), expected: UInt64.max)
Values.ensureEqualULongs(actual: 39, expected: 39)
ValuesKt.ensureEqualULongs(actual: KotlinULong(value: UInt64.max), expected: UInt64.max)
ValuesKt.ensureEqualULongs(actual: 39, expected: 39)
Values.ensureEqualFloats(actual: ValuesFloat(value: 36.6), expected: 36.6)
Values.ensureEqualFloats(actual: 49.5, expected: 49.5)
Values.ensureEqualFloats(actual: 18, expected: 18.0)
ValuesKt.ensureEqualFloats(actual: KotlinFloat(value: 36.6), expected: 36.6)
ValuesKt.ensureEqualFloats(actual: 49.5, expected: 49.5)
ValuesKt.ensureEqualFloats(actual: 18, expected: 18.0)
Values.ensureEqualDoubles(actual: ValuesDouble(value: 12.34), expected: 12.34)
Values.ensureEqualDoubles(actual: 56.78, expected: 56.78)
Values.ensureEqualDoubles(actual: 3, expected: 3)
ValuesKt.ensureEqualDoubles(actual: KotlinDouble(value: 12.34), expected: 12.34)
ValuesKt.ensureEqualDoubles(actual: 56.78, expected: 56.78)
ValuesKt.ensureEqualDoubles(actual: 3, expected: 3)
func checkBox<T: Equatable, B : NSObject>(_ value: T, _ boxFunction: (T) -> B?) throws {
let box = boxFunction(value)!
@@ -188,27 +188,27 @@ func testNumbers() throws {
try assertTrue(box.isKind(of: B.self))
}
try checkBox(true, Values.box)
try checkBox(Int8(-1), Values.box)
try checkBox(Int16(-2), Values.box)
try checkBox(Int32(-3), Values.box)
try checkBox(Int64(-4), Values.box)
try checkBox(UInt8(5), Values.box)
try checkBox(UInt16(6), Values.box)
try checkBox(UInt32(7), Values.box)
try checkBox(UInt64(8), Values.box)
try checkBox(Float(8.7), Values.box)
try checkBox(Double(9.4), Values.box)
try checkBox(true, ValuesKt.box)
try checkBox(Int8(-1), ValuesKt.box)
try checkBox(Int16(-2), ValuesKt.box)
try checkBox(Int32(-3), ValuesKt.box)
try checkBox(Int64(-4), ValuesKt.box)
try checkBox(UInt8(5), ValuesKt.box)
try checkBox(UInt16(6), ValuesKt.box)
try checkBox(UInt32(7), ValuesKt.box)
try checkBox(UInt64(8), ValuesKt.box)
try checkBox(Float(8.7), ValuesKt.box)
try checkBox(Double(9.4), ValuesKt.box)
}
func testLists() throws {
let numbersList = Values.numbersList
let numbersList = ValuesKt.numbersList
let gold = [1, 2, 13]
for i in 0..<gold.count {
try assertEquals(actual: gold[i], expected: Int(numbersList[i] as! NSNumber), "Numbers list")
}
let anyList = Values.anyList
let anyList = ValuesKt.anyList
for i in anyList {
print(i)
}
@@ -216,7 +216,7 @@ func testLists() throws {
}
func testLazyVal() throws {
let lazyVal = Values.lazyVal
let lazyVal = ValuesKt.lazyVal
print(lazyVal)
try assertEquals(actual: lazyVal, expected: "Lazily initialized string", "lazy value")
}
@@ -224,7 +224,7 @@ func testLazyVal() throws {
let goldenArray = ["Delegated", "global", "array", "property"]
func testDelegatedProp() throws {
let delegatedGlobalArray = Values.delegatedGlobalArray
let delegatedGlobalArray = ValuesKt.delegatedGlobalArray
guard Int(delegatedGlobalArray.size) == goldenArray.count else {
throw TestError.assertFailed("Size differs")
}
@@ -234,7 +234,7 @@ func testDelegatedProp() throws {
}
func testGetterDelegate() throws {
let delegatedList = Values.delegatedList
let delegatedList = ValuesKt.delegatedList
guard delegatedList.count == goldenArray.count else {
throw TestError.assertFailed("Size differs")
}
@@ -244,16 +244,16 @@ func testGetterDelegate() throws {
}
func testNulls() throws {
let nilVal : Any? = Values.nullVal
let nilVal : Any? = ValuesKt.nullVal
try assertTrue(nilVal == nil, "Null value")
Values.nullVar = nil
var nilVar : Any? = Values.nullVar
ValuesKt.nullVar = nil
var nilVar : Any? = ValuesKt.nullVar
try assertTrue(nilVar == nil, "Null variable")
}
func testAnyVar() throws {
let anyVar : Any = Values.anyValue
let anyVar : Any = ValuesKt.anyValue
print(anyVar)
if let str = anyVar as? String {
print(str)
@@ -264,19 +264,19 @@ func testAnyVar() throws {
}
func testFunctions() throws {
let _: Any? = Values.emptyFun()
let _: Any? = ValuesKt.emptyFun()
let str = Values.strFun()
let str = ValuesKt.strFun()
try assertEquals(actual: str, expected: "fooStr")
try assertEquals(actual: Values.argsFun(i: 10, l: 20, d: 3.5, s: "res") as! String,
try assertEquals(actual: ValuesKt.argsFun(i: 10, l: 20, d: 3.5, s: "res") as! String,
expected: "res10203.5")
}
func testFuncType() throws {
let s = "str"
let fFunc: () -> String = { return s }
try assertEquals(actual: Values.funArgument(foo: fFunc), expected: s, "Using function type arguments failed")
try assertEquals(actual: ValuesKt.funArgument(foo: fFunc), expected: s, "Using function type arguments failed")
}
func testGenericsFoo() throws {
@@ -284,48 +284,48 @@ func testGenericsFoo() throws {
// wrap lambda to workaround issue with type conversion inability:
// (Int) -> String can't be cast to (Any?) -> Any?
let wrapper = { (t: Any?) -> Any? in return fun(t as! Int) }
let res = Values.genericFoo(t: 42, foo: wrapper)
let res = ValuesKt.genericFoo(t: 42, foo: wrapper)
try assertEquals(actual: res as! String, expected: "S 42")
}
func testVararg() throws {
let ktArray = ValuesStdlibArray(size: 3, init: { (_) -> Int in return 42 })
let arr: [Int] = Values.varargToList(args: ktArray) as! [Int]
let ktArray = KotlinArray(size: 3, init: { (_) -> Int in return 42 })
let arr: [Int] = ValuesKt.varargToList(args: ktArray) as! [Int]
try assertEquals(actual: arr, expected: [42, 42, 42])
}
func testStrExtFun() throws {
try assertEquals(actual: Values.subExt("String", i: 2), expected: "r")
try assertEquals(actual: Values.subExt("A", i: 2), expected: "nothing")
try assertEquals(actual: ValuesKt.subExt("String", i: 2), expected: "r")
try assertEquals(actual: ValuesKt.subExt("A", i: 2), expected: "nothing")
}
func testAnyToString() throws {
try assertEquals(actual: Values.toString(nil), expected: "null")
try assertEquals(actual: Values.toString(42), expected: "42")
try assertEquals(actual: ValuesKt.toString(nil), expected: "null")
try assertEquals(actual: ValuesKt.toString(42), expected: "42")
}
func testAnyPrint() throws {
print("BEGIN")
Values.print(nil)
Values.print("Print")
Values.print(123456789)
Values.print(3.14)
Values.print([3, 2, 1])
ValuesKt.print(nil)
ValuesKt.print("Print")
ValuesKt.print(123456789)
ValuesKt.print(3.14)
ValuesKt.print([3, 2, 1])
print("END")
}
func testLambda() throws {
try assertEquals(actual: Values.sumLambda(3, 4), expected: 7)
try assertEquals(actual: ValuesKt.sumLambda(3, 4), expected: 7)
}
// -------- Tests for classes and interfaces -------
class ValIEmptyExt : ValuesI {
class ValIEmptyExt : I {
func iFun() -> String {
return "ValIEmptyExt::iFun"
}
}
class ValIExt : ValuesI {
class ValIExt : I {
func iFun() -> String {
return "ValIExt::iFun"
}
@@ -337,19 +337,19 @@ func testInterfaceExtension() throws {
}
func testClassInstances() throws {
try assertEquals(actual: ValuesOpenClassI().iFun(), expected: "OpenClassI::iFun")
try assertEquals(actual: ValuesDefaultInterfaceExt().iFun(), expected: "I::iFun")
try assertEquals(actual: ValuesFinalClassExtOpen().iFun(), expected: "FinalClassExtOpen::iFun")
try assertEquals(actual: ValuesMultiExtClass().iFun(), expected: "PI::iFun")
try assertEquals(actual: ValuesMultiExtClass().piFun() as! Int, expected: 42)
try assertEquals(actual: ValuesConstrClass(i: 1, s: "str", a: "Any").iFun(), expected: "OpenClassI::iFun")
try assertEquals(actual: ValuesExtConstrClass(i: 123).iFun(), expected: "ExtConstrClass::iFun::123-String-AnyS")
try assertEquals(actual: OpenClassI().iFun(), expected: "OpenClassI::iFun")
try assertEquals(actual: DefaultInterfaceExt().iFun(), expected: "I::iFun")
try assertEquals(actual: FinalClassExtOpen().iFun(), expected: "FinalClassExtOpen::iFun")
try assertEquals(actual: MultiExtClass().iFun(), expected: "PI::iFun")
try assertEquals(actual: MultiExtClass().piFun() as! Int, expected: 42)
try assertEquals(actual: ConstrClass(i: 1, s: "str", a: "Any").iFun(), expected: "OpenClassI::iFun")
try assertEquals(actual: ExtConstrClass(i: 123).iFun(), expected: "ExtConstrClass::iFun::123-String-AnyS")
}
func testEnum() throws {
try assertEquals(actual: Values.passEnum().enumValue, expected: 42)
try assertEquals(actual: Values.passEnum().name, expected: "ANSWER")
Values.receiveEnum(e: 1)
try assertEquals(actual: ValuesKt.passEnum().enumValue, expected: 42)
try assertEquals(actual: ValuesKt.passEnum().name, expected: "ANSWER")
ValuesKt.receiveEnum(e: 1)
}
func testDataClass() throws {
@@ -357,13 +357,13 @@ func testDataClass() throws {
let s = "2"
let t = "3"
let tripleVal = ValuesTripleVals(first: f, second: s, third: t)
let tripleVal = TripleVals(first: f, second: s, third: t)
try assertEquals(actual: tripleVal.first as! String, expected: f, "Data class' value")
try assertEquals(actual: tripleVal.component2() as! String, expected: s, "Data class' component")
print(tripleVal)
try assertEquals(actual: String(describing: tripleVal), expected: "TripleVals(first=\(f), second=\(s), third=\(t))")
let tripleVar = ValuesTripleVars(first: f, second: s, third: t)
let tripleVar = TripleVars(first: f, second: s, third: t)
try assertEquals(actual: tripleVar.first as! String, expected: f, "Data class' value")
try assertEquals(actual: tripleVar.component2() as! String, expected: s, "Data class' component")
print(tripleVar)
@@ -377,31 +377,31 @@ func testDataClass() throws {
}
func testCompanionObj() throws {
try assertEquals(actual: ValuesWithCompanionAndObjectCompanion().str, expected: "String")
try assertEquals(actual: Values.getCompanionObject().str, expected: "String")
try assertEquals(actual: WithCompanionAndObjectCompanion().str, expected: "String")
try assertEquals(actual: ValuesKt.getCompanionObject().str, expected: "String")
let namedFromCompanion = Values.getCompanionObject().named
let named = Values.getNamedObject()
let namedFromCompanion = ValuesKt.getCompanionObject().named
let named = ValuesKt.getNamedObject()
try assertTrue(named === namedFromCompanion, "Should be the same Named object")
try assertEquals(actual: Values.getNamedObjectInterface().iFun(), expected: named.iFun(), "Named object's method")
try assertEquals(actual: ValuesKt.getNamedObjectInterface().iFun(), expected: named.iFun(), "Named object's method")
}
func testInlineClasses() throws {
let ic1: Int32 = 42
let ic1N = Values.box(ic1: 17)
let ic1N = ValuesKt.box(ic1: 17)
let ic2 = "foo"
let ic2N = "bar"
let ic3 = ValuesTripleVals(first: 1, second: 2, third: 3)
let ic3N = Values.box(ic3: nil)
let ic3 = TripleVals(first: 1, second: 2, third: 3)
let ic3N = ValuesKt.box(ic3: nil)
try assertEquals(
actual: Values.concatenateInlineClassValues(ic1: ic1, ic1N: ic1N, ic2: ic2, ic2N: ic2N, ic3: ic3, ic3N: ic3N),
actual: ValuesKt.concatenateInlineClassValues(ic1: ic1, ic1N: ic1N, ic2: ic2, ic2N: ic2N, ic3: ic3, ic3N: ic3N),
expected: "42 17 foo bar TripleVals(first=1, second=2, third=3) null"
)
try assertEquals(
actual: Values.concatenateInlineClassValues(ic1: ic1, ic1N: nil, ic2: ic2, ic2N: nil, ic3: nil, ic3N: nil),
actual: ValuesKt.concatenateInlineClassValues(ic1: ic1, ic1N: nil, ic2: ic2, ic2N: nil, ic3: nil, ic3N: nil),
expected: "42 null foo null null null"
)
}
@@ -29,7 +29,7 @@ class ViewController: UIViewController, UITextViewDelegate, UICollectionViewData
@IBOutlet var input: UITextView!
@IBOutlet var numpad: UICollectionView!
private let parser = KAPPartialParser(composer: KAPCalculator(), partialComposer: PartialRenderer())
private let parser = PartialParser(composer: Calculator(), partialComposer: PartialRenderer())
@IBAction func numpadButtonPressed(_ sender: UIButton) {
let title = sender.currentTitle!
@@ -112,7 +112,7 @@ private extension String {
}
}
private class PartialRenderer: NSObject, KAPPartialExpressionComposer {
private class PartialRenderer: NSObject, PartialExpressionComposer {
func missing() -> Any {
return "... ".toAttributed()
}