Move everything under kotlin-native folder
I was forced to manually do update the following files, because otherwise they would be ignored according .gitignore settings. Probably they should be deleted from repo. Interop/.idea/compiler.xml Interop/.idea/gradle.xml Interop/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_runtime_1_0_3.xml Interop/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_stdlib_1_0_3.xml Interop/.idea/modules.xml Interop/.idea/modules/Indexer/Indexer.iml Interop/.idea/modules/Runtime/Runtime.iml Interop/.idea/modules/StubGenerator/StubGenerator.iml backend.native/backend.native.iml backend.native/bc.frontend/bc.frontend.iml backend.native/cli.bc/cli.bc.iml backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt backend.native/tests/link/lib/foo.kt backend.native/tests/link/lib/foo2.kt backend.native/tests/teamcity-test.property
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
import kotlinx.cinterop.*
|
||||
import objclib.*
|
||||
import kotlin.native.ref.*
|
||||
|
||||
fun run(): List<Any?> {
|
||||
val result = mutableListOf<Any?>()
|
||||
result.add(foo1(42))
|
||||
val list = foo2(117)
|
||||
if (list != null) {
|
||||
result.add(list.size)
|
||||
for (x in list)
|
||||
result.add(x)
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
language = Objective-C
|
||||
headers = Foundation/NSArray.h Foundation/NSValue.h Foundation/NSString.h
|
||||
headerFilter = **/objclib.h Foundation/NSArray.h Foundation/NSValue.h Foundation/NSString.h
|
||||
@@ -0,0 +1,11 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NSString* foo1(int x) {
|
||||
return [NSString stringWithFormat:@"%d", x];
|
||||
}
|
||||
|
||||
NSArray* foo2(int x) {
|
||||
NSValue* xx = @(x);
|
||||
NSString* s = @"zzz";
|
||||
return [NSArray arrayWithObjects: xx, s, nil];
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import Foundation
|
||||
import Gh3343
|
||||
|
||||
func testGh3343() throws {
|
||||
let list = KtlibKt.run()
|
||||
try assertEquals(actual: list[0] as? String, expected: "42")
|
||||
try assertEquals(actual: list[1] as? Int, expected: 2)
|
||||
try assertEquals(actual: list[2] as? Int, expected: 117)
|
||||
try assertEquals(actual: list[3] as? String, expected: "zzz")
|
||||
}
|
||||
|
||||
// -------- Execution of the test --------
|
||||
|
||||
class UselibTests : TestProvider {
|
||||
var tests: [TestCase] = []
|
||||
|
||||
init() {
|
||||
providers.append(self)
|
||||
tests = [
|
||||
TestCase(name: "Gh3343", method: withAutorelease(testGh3343)),
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// The following 2 singletons are unused. However, since we are generating ObjC bindings for them,
|
||||
// they should be marked as used, so that the code generator emits their deinitialization.
|
||||
|
||||
object A {
|
||||
fun foo() = 1
|
||||
}
|
||||
|
||||
class B {
|
||||
companion object {
|
||||
fun foo() = 2
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import Kt42397
|
||||
|
||||
class Results {
|
||||
var aFoo: Int32 = 0
|
||||
var bFoo: Int32 = 0
|
||||
}
|
||||
|
||||
func runTestKt42397(pointer: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer? {
|
||||
autoreleasepool {
|
||||
let results = pointer.bindMemory(to: Results.self, capacity: 1).pointee
|
||||
results.aFoo = A().foo()
|
||||
results.bFoo = B.Companion().foo()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func testKt42397() throws {
|
||||
let results = Results()
|
||||
let resultsPtr = UnsafeMutablePointer<Results>.allocate(capacity: 1)
|
||||
resultsPtr.initialize(to: results)
|
||||
var thread: pthread_t? = nil
|
||||
let result = pthread_create(&thread, nil, runTestKt42397, resultsPtr)
|
||||
try assertEquals(actual: result, expected: 0)
|
||||
pthread_join(thread!, nil)
|
||||
|
||||
try assertEquals(actual: results.aFoo, expected: 1)
|
||||
try assertEquals(actual: results.bFoo, expected: 2)
|
||||
}
|
||||
|
||||
// -------- Execution of the test --------
|
||||
|
||||
class TestTests : SimpleTestProvider {
|
||||
override init() {
|
||||
super.init()
|
||||
|
||||
test("Kt42397", testKt42397)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
|
||||
enum TestError : Error {
|
||||
case assertFailed(String)
|
||||
case failure
|
||||
case testsFailed([String])
|
||||
}
|
||||
|
||||
// ---------------- Assertions ----------------
|
||||
|
||||
private func throwAssertFailed(message: String, file: String, line: Int) throws -> Never {
|
||||
throw TestError.assertFailed("\(file):\(line): \(message)")
|
||||
}
|
||||
|
||||
func assertEquals<T: Equatable>(actual: T, expected: T,
|
||||
_ message: String = "Assertion failed:",
|
||||
file: String = #file, line: Int = #line) throws {
|
||||
if (actual != expected) {
|
||||
try throwAssertFailed(message: message + " Expected value: \(expected), but got: \(actual)",
|
||||
file: file, line: line)
|
||||
}
|
||||
}
|
||||
|
||||
func assertSame(actual: AnyObject?, expected: AnyObject?,
|
||||
_ message: String = "Assertion failed:",
|
||||
file: String = #file, line: Int = #line) throws {
|
||||
if (actual !== expected) {
|
||||
try throwAssertFailed(message: message + " Expected value: \(expected), but got: \(actual)",
|
||||
file: file, line: line)
|
||||
}
|
||||
}
|
||||
|
||||
func assertEquals<T: Equatable>(actual: [T], expected: [T],
|
||||
_ message: String = "Assertion failed: arrays not equal",
|
||||
file: String = #file, line: Int = #line) throws {
|
||||
try assertEquals(actual: actual.count, expected: expected.count, "Size differs", file: file, line: line)
|
||||
try assertTrue(actual.elementsEqual(expected), "Arrays elements are not equal", file: file, line: line)
|
||||
}
|
||||
|
||||
func assertTrue(_ value: Bool,
|
||||
_ message: String = "Assertion failed:",
|
||||
file: String = #file, line: Int = #line) throws {
|
||||
if (value != true) {
|
||||
try throwAssertFailed(message: message + " Expected value to be TRUE, but got: \(value)",
|
||||
file: file, line: line)
|
||||
}
|
||||
}
|
||||
|
||||
func assertFalse(_ value: Bool,
|
||||
_ message: String = "Assertion failed:",
|
||||
file: String = #file, line: Int = #line) throws {
|
||||
if (value != false) {
|
||||
try throwAssertFailed(message: message + " Expected value to be FALSE, but got: \(value)",
|
||||
file: file, line: line)
|
||||
}
|
||||
}
|
||||
|
||||
func assertNil(_ value: Any?,
|
||||
_ message: String = "Assertion failed:",
|
||||
file: String = #file, line: Int = #line) throws {
|
||||
if (value != nil) {
|
||||
try throwAssertFailed(message: message + " Expected value to be nil, but got: \(value!)",
|
||||
file: file, line: line)
|
||||
}
|
||||
}
|
||||
|
||||
func fail(_ message: String = "Should not reach here", file: String = #file, line: Int = #line) throws -> Never {
|
||||
try throwAssertFailed(message: message, file: file, line: line)
|
||||
}
|
||||
|
||||
func assertFailsWith<T : Error>(_ errorType: T.Type,
|
||||
_ message: String = "Assertion failed:",
|
||||
file: String = #file, line: Int = #line,
|
||||
block: () throws -> Void) throws {
|
||||
do {
|
||||
try block()
|
||||
} catch let error {
|
||||
if error is T { return }
|
||||
try throwAssertFailed(message: message + " Expected error \(errorType), got \(error)",
|
||||
file: file, line: line)
|
||||
}
|
||||
|
||||
try throwAssertFailed(message: message + " Expected error \(errorType), but finished successfully",
|
||||
file: file, line: line)
|
||||
}
|
||||
|
||||
func assertFailsWithKotlin<T>(_ exceptionType: T.Type,
|
||||
_ message: String = "Assertion failed:",
|
||||
file: String = #file, line: Int = #line,
|
||||
block: () throws -> Void) throws {
|
||||
do {
|
||||
try block()
|
||||
} catch let error {
|
||||
let kotlinException = error.kotlinException
|
||||
if kotlinException is T { return }
|
||||
let got = kotlinException ?? error
|
||||
try throwAssertFailed(message: message + " Expected Kotlin exception \(exceptionType), got \(got)",
|
||||
file: file, line: line)
|
||||
}
|
||||
|
||||
try throwAssertFailed(message: message + " Expected Kotlin exception \(exceptionType), but finished successfully",
|
||||
file: file, line: line)
|
||||
}
|
||||
|
||||
|
||||
// ---------------- Utils --------------------
|
||||
|
||||
func withAutorelease( _ method: @escaping () throws -> Void) -> () throws -> Void {
|
||||
return { () throws -> Void in
|
||||
try autoreleasepool { try method() }
|
||||
}
|
||||
}
|
||||
|
||||
extension Error {
|
||||
var kotlinException: Any? {
|
||||
get {
|
||||
return (self as NSError).userInfo["KotlinException"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------- Execution ----------------
|
||||
|
||||
private final class Statistics : CustomStringConvertible {
|
||||
var passed: [String] = []
|
||||
var failed: [String] = []
|
||||
|
||||
var description: String {
|
||||
return """
|
||||
---- RESULTS:
|
||||
PASSED: \(passed.count)
|
||||
FAILED: \(failed.count)
|
||||
"""
|
||||
}
|
||||
|
||||
static let instance = Statistics()
|
||||
|
||||
static func getInstance() -> Statistics {
|
||||
return instance
|
||||
}
|
||||
|
||||
func start(_ name: String) {
|
||||
print("---- Starting test: \(name)")
|
||||
}
|
||||
|
||||
func passed(_ name: String) {
|
||||
print("---- PASSED test: \(name)")
|
||||
passed.append(name)
|
||||
}
|
||||
|
||||
func failed(_ name: String, error: Error) {
|
||||
print("---- FAILED test: \(name) with error: \(error)")
|
||||
failed.append(name)
|
||||
}
|
||||
}
|
||||
/**
|
||||
* TestCase represents a single test
|
||||
*/
|
||||
struct TestCase {
|
||||
let name: String
|
||||
let method: () throws -> Void
|
||||
|
||||
init(name: String, method: @escaping () throws -> Void) {
|
||||
self.name = name
|
||||
self.method = method
|
||||
}
|
||||
|
||||
func run() {
|
||||
let stats = Statistics.getInstance()
|
||||
stats.start(name)
|
||||
do {
|
||||
try method()
|
||||
stats.passed(name)
|
||||
} catch {
|
||||
stats.failed(name, error: error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protocol TestProvider {
|
||||
var tests: [TestCase] { get }
|
||||
}
|
||||
|
||||
class SimpleTestProvider : TestProvider {
|
||||
var tests: [TestCase] = []
|
||||
|
||||
init() {
|
||||
providers.append(self)
|
||||
}
|
||||
|
||||
func test(_ name: String, _ method: @escaping () throws -> Void) {
|
||||
tests.append(TestCase(name: name, method: withAutorelease(method)))
|
||||
}
|
||||
}
|
||||
|
||||
var providers: [TestProvider] = []
|
||||
|
||||
private func execute(tests: [TestCase]) {
|
||||
for test in tests {
|
||||
test.run()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Entry point of the test
|
||||
*/
|
||||
private func main() {
|
||||
// Generated method that instantiates test providers.
|
||||
registerProviders()
|
||||
|
||||
let stats = Statistics.getInstance()
|
||||
for pr in providers {
|
||||
let name = String(describing: type(of: pr))
|
||||
print("-- \(name) started")
|
||||
execute(tests: pr.tests)
|
||||
print("-- \(name) finished")
|
||||
}
|
||||
print(stats)
|
||||
|
||||
let failed = stats.failed
|
||||
if !failed.isEmpty {
|
||||
print()
|
||||
print("Tests failed:")
|
||||
for testName in failed {
|
||||
print(":: \(testName)")
|
||||
}
|
||||
abort()
|
||||
}
|
||||
}
|
||||
|
||||
main()
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
@file:Suppress("UNUSED")
|
||||
|
||||
package multiple
|
||||
|
||||
interface I1 {
|
||||
fun getFortyTwo(): Int
|
||||
}
|
||||
|
||||
class I1Impl : I1 {
|
||||
override fun getFortyTwo(): Int = 42
|
||||
}
|
||||
|
||||
fun getI1() = object : I1 {
|
||||
override fun getFortyTwo(): Int = 42
|
||||
}
|
||||
|
||||
class C
|
||||
|
||||
fun getUnit(): Unit? = Unit
|
||||
|
||||
/*
|
||||
// Disabled for now to avoid depending on platform libs.
|
||||
fun getAnonymousObject() = object : platform.darwin.NSObject() {}
|
||||
class NamedObject : platform.darwin.NSObject()
|
||||
fun getNamedObject() = NamedObject()
|
||||
*/
|
||||
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
@file:Suppress("UNUSED")
|
||||
|
||||
package multiple
|
||||
|
||||
val name = "first"
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
@file:Suppress("UNUSED")
|
||||
|
||||
package multiple
|
||||
|
||||
interface I2 {
|
||||
fun getFortyTwo(): Int
|
||||
}
|
||||
|
||||
fun getFortyTwoFrom(i2: I2): Int = i2.getFortyTwo()
|
||||
|
||||
fun getI2() = object : I2 {
|
||||
override fun getFortyTwo(): Int = 42
|
||||
}
|
||||
|
||||
class C
|
||||
|
||||
fun isUnit(obj: Any?): Boolean = (obj === Unit)
|
||||
|
||||
/*
|
||||
// Disabled for now to avoid depending on platform libs.
|
||||
fun getAnonymousObject() = object : platform.darwin.NSObject() {}
|
||||
class NamedObject : platform.darwin.NSObject()
|
||||
fun getNamedObject() = NamedObject()
|
||||
*/
|
||||
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
@file:Suppress("UNUSED")
|
||||
|
||||
package multiple
|
||||
|
||||
val name = "second"
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
import First
|
||||
import Second
|
||||
|
||||
func testClashingNames() throws {
|
||||
try assertEquals(actual: "first", expected: First.TestKt.name)
|
||||
try assertEquals(actual: "second", expected: Second.TestKt.name)
|
||||
|
||||
let c1 = First.C()
|
||||
let c2 = Second.C()
|
||||
try assertTrue(type(of: c1) == First.C.self)
|
||||
try assertTrue(type(of: c2) == Second.C.self)
|
||||
try assertTrue(First.C.self != Second.C.self)
|
||||
try assertTrue(objc_getClass(class_getName(First.C.self)) as AnyObject === First.C.self)
|
||||
try assertTrue(objc_getClass(class_getName(Second.C.self)) as AnyObject === Second.C.self)
|
||||
}
|
||||
|
||||
extension I1Impl : I2 {}
|
||||
|
||||
func testInteraction() throws {
|
||||
try assertEquals(actual: SecondKt.getFortyTwoFrom(i2: I1Impl()), expected: 42)
|
||||
}
|
||||
|
||||
func testIsolation1() throws {
|
||||
try assertFalse(SecondKt.isUnit(obj: FirstKt.getUnit()))
|
||||
|
||||
// Ensure frameworks don't share the same runtime (state):
|
||||
try assertFalse(First.RuntimeState().consumeChange())
|
||||
try assertFalse(Second.RuntimeState().consumeChange())
|
||||
Second.RuntimeState().produceChange()
|
||||
try assertFalse(First.RuntimeState().consumeChange())
|
||||
try assertTrue(Second.RuntimeState().consumeChange())
|
||||
}
|
||||
|
||||
func testIsolation2() throws {
|
||||
try assertEquals(actual: FirstKt.getI1().getFortyTwo(), expected: 42)
|
||||
try assertEquals(actual: SecondKt.getI2().getFortyTwo(), expected: 42)
|
||||
}
|
||||
|
||||
func testIsolation3() throws {
|
||||
#if false // Disabled for now to avoid depending on platform libs.
|
||||
FirstKt.getAnonymousObject()
|
||||
SecondKt.getAnonymousObject()
|
||||
FirstKt.getNamedObject()
|
||||
SecondKt.getNamedObject()
|
||||
#endif
|
||||
}
|
||||
|
||||
// https://youtrack.jetbrains.com/issue/KT-34261
|
||||
// When First and Second are static frameworks with caches, this test fails due to bad cache isolation:
|
||||
// Caches included into both frameworks have 'ktypew' globals (with same name, hidden visibility and common linkage)
|
||||
// for writable part of this "unexposed stdlib class" TypeInfo.
|
||||
// ld ignores hidden visibility and merges common globals, so two independent frameworks happen to share
|
||||
// the same global instead of two different globals. Things go wrong at runtime then: this writable TypeInfo part
|
||||
// is used to store Obj-C class for this Kotlin class. So after the first object is obtained in Swift, both TypeInfos
|
||||
// have its class, and the second object is wrong then.
|
||||
func testIsolation4() throws {
|
||||
let obj1: Any = First.SharedKt.getUnexposedStdlibClassInstance()
|
||||
try assertTrue(obj1 is First.KotlinBase)
|
||||
try assertFalse(obj1 is Second.KotlinBase)
|
||||
|
||||
let obj2: Any = Second.SharedKt.getUnexposedStdlibClassInstance()
|
||||
try assertFalse(obj2 is First.KotlinBase)
|
||||
try assertTrue(obj2 is Second.KotlinBase)
|
||||
}
|
||||
|
||||
class MultipleTests : TestProvider {
|
||||
var tests: [TestCase] = []
|
||||
|
||||
init() {
|
||||
tests = [
|
||||
TestCase(name: "TestClashingNames", method: withAutorelease(testClashingNames)),
|
||||
TestCase(name: "TestInteraction", method: withAutorelease(testInteraction)),
|
||||
TestCase(name: "TestIsolation1", method: withAutorelease(testIsolation1)),
|
||||
TestCase(name: "TestIsolation2", method: withAutorelease(testIsolation2)),
|
||||
TestCase(name: "TestIsolation3", method: withAutorelease(testIsolation3)),
|
||||
TestCase(name: "TestIsolation4", method: withAutorelease(testIsolation4)),
|
||||
]
|
||||
providers.append(self)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import kotlin.native.concurrent.Worker
|
||||
|
||||
object RuntimeState {
|
||||
fun produceChange() {
|
||||
Worker.current.executeAfter {}
|
||||
}
|
||||
|
||||
fun consumeChange(): Boolean {
|
||||
return Worker.current.processQueue()
|
||||
}
|
||||
}
|
||||
|
||||
// Note: this assumes that IntRange class is not exposed by the enclosing framework.
|
||||
fun getUnexposedStdlibClassInstance(): Any = 0..2
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
@file:Suppress("UNUSED")
|
||||
|
||||
package stdlib
|
||||
|
||||
fun <K, V> isEmpty(map: Map<K, V>) = map.isEmpty()
|
||||
|
||||
fun <K, V> getKeysAsSet(map: Map<K, V>) = map.keys
|
||||
fun <K, V> getKeysAsList(map: Map<K, V>) = map.keys.toList()
|
||||
|
||||
fun <K, V> toMutableMap(map: HashMap<K, V>) = map.toMutableMap()
|
||||
|
||||
fun <E> getFirstElement(collection: Collection<E>) = collection.first()
|
||||
|
||||
class GenericExtensionClass<K, out V, out T : Map<K, V>> (private val holder: T?) {
|
||||
fun getFirstKey(): K? = holder?.entries?.first()?.key
|
||||
|
||||
fun getFirstValue() : V? {
|
||||
holder?.entries?.forEach { e -> println("KEY: ${e.key} VALUE: ${e.value}") }
|
||||
return holder?.entries?.first()?.value
|
||||
}
|
||||
}
|
||||
|
||||
fun <K, V> createPair():
|
||||
Pair<LinkedHashMap<K, V>, GenericExtensionClass<K, V, Map<K, V>>> {
|
||||
val l = createLinkedMap<K, V>()
|
||||
val g = GenericExtensionClass(l)
|
||||
return Pair(l, g)
|
||||
}
|
||||
|
||||
fun <K, V> createLinkedMap() = linkedMapOf<K, V>()
|
||||
|
||||
fun createTypedMutableMap() = linkedMapOf<Int, String>()
|
||||
|
||||
fun addSomeElementsToMap(map: MutableMap<String, Int>) {
|
||||
map.put(key = "XYZ", value = 321)
|
||||
map.put(key = "TMP", value = 451)
|
||||
}
|
||||
|
||||
fun list(vararg elements: Any?): Any = listOf(*elements)
|
||||
fun set(vararg elements: Any?): Any = setOf(*elements)
|
||||
fun map(vararg keysAndValues: Any?): Any = mutableMapOf<Any?, Any?>().apply {
|
||||
(0 until keysAndValues.size step 2).forEach {index ->
|
||||
this[keysAndValues[index]] = keysAndValues[index + 1]
|
||||
}
|
||||
}
|
||||
|
||||
fun emptyMutableList(): Any = mutableListOf<Any?>()
|
||||
fun emptyMutableSet(): Any = mutableSetOf<Any?>()
|
||||
fun emptyMutableMap(): Any = mutableMapOf<Any?, Any?>()
|
||||
|
||||
data class TripleVals<T>(val first: T, val second: T, val third: T)
|
||||
|
||||
data class TripleVars<T>(var first: T, var second: T, var third: T) {
|
||||
override fun toString(): String {
|
||||
return "[$first, $second, $third]"
|
||||
}
|
||||
}
|
||||
|
||||
fun gc() = kotlin.native.internal.GC.collect()
|
||||
@@ -0,0 +1,462 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
import Stdlib
|
||||
|
||||
extension NSEnumerator {
|
||||
func remainingObjects() -> [Any?] {
|
||||
var result = [Any?]()
|
||||
while (true) {
|
||||
if let next = self.nextObject() {
|
||||
result.append(next as AnyObject as Any?)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
class StdlibTests : TestProvider {
|
||||
var tests: [TestCase] = []
|
||||
|
||||
init() {
|
||||
tests = [
|
||||
TestCase(name: "TestEmptyDictionary", method: withAutorelease(testEmptyDictionary)),
|
||||
TestCase(name: "TestGenericMapUsage", method: withAutorelease(testGenericMapUsage)),
|
||||
TestCase(name: "TestOrderedMapStored", method: withAutorelease(testOrderedMapStored)),
|
||||
TestCase(name: "TestTypedMapUsage", method: withAutorelease(testTypedMapUsage)),
|
||||
TestCase(name: "TestFirstElement", method: withAutorelease(testFirstElement)),
|
||||
TestCase(name: "TestAddDictionary", method: withAutorelease(testAddDictionary)),
|
||||
TestCase(name: "TestList", method: withAutorelease(testList)),
|
||||
TestCase(name: "TestMutableList", method: withAutorelease(testMutableList)),
|
||||
TestCase(name: "TestSet", method: withAutorelease(testSet)),
|
||||
TestCase(name: "TestMutableSet", method: withAutorelease(testMutableSet)),
|
||||
TestCase(name: "TestMap", method: withAutorelease(testMap)),
|
||||
TestCase(name: "TestMutableMap", method: withAutorelease(testMutableMap)),
|
||||
TestCase(name: "TestKotlinMutableSetInit", method: withAutorelease(testKotlinMutableSetInit)),
|
||||
TestCase(name: "TestKotlinMutableDictionaryInit", method: withAutorelease(testKotlinMutableDictionaryInit)),
|
||||
]
|
||||
providers.append(self)
|
||||
}
|
||||
|
||||
/**
|
||||
* Pass empty dictionary to Kotlin.
|
||||
*/
|
||||
func testEmptyDictionary() throws {
|
||||
let immutableEmptyDict = [String: Int]()
|
||||
try assertTrue(StdlibKt.isEmpty(map: immutableEmptyDict), "Empty dictionary")
|
||||
let keys = StdlibKt.getKeysAsSet(map: immutableEmptyDict)
|
||||
try assertTrue(keys.isEmpty, "Should have empty set")
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests usage of a map with generics.
|
||||
*/
|
||||
func testGenericMapUsage() throws {
|
||||
let map = StdlibKt.createLinkedMap()
|
||||
map[1] = "One"
|
||||
map[10] = "Ten"
|
||||
map[11] = "Eleven"
|
||||
map["10"] = "Ten as string"
|
||||
for (k, v) in map {
|
||||
print("MAP: \(k) - \(v)")
|
||||
}
|
||||
|
||||
try assertEquals(actual: map[11] as! String, expected: "Eleven", "An element of the map for key: 11")
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks order of the underlying LinkedHashMap.
|
||||
*/
|
||||
func testOrderedMapStored() throws {
|
||||
let pair = StdlibKt.createPair()
|
||||
let map = pair.first as? NSMutableDictionary
|
||||
|
||||
map?[1] = "One"
|
||||
map?[10] = "Ten"
|
||||
map?[11] = "Eleven"
|
||||
map?["10"] = "Ten as string"
|
||||
|
||||
let gen = pair.second as! GenericExtensionClass
|
||||
let value: String? = gen.getFirstValue() as? String
|
||||
try assertEquals(actual: value!, expected: "One", "First value of the map")
|
||||
|
||||
let key: Int? = gen.getFirstKey() as? Int
|
||||
try assertEquals(actual: key!, expected: 1, "First key of the map")
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests typed map created in Kotlin.
|
||||
*/
|
||||
func testTypedMapUsage() throws {
|
||||
let map = StdlibKt.createTypedMutableMap()
|
||||
map[1] = "One"
|
||||
map[1.0 as Float] = "Float"
|
||||
map[11] = "Eleven"
|
||||
map["10"] = "Ten as string"
|
||||
|
||||
try assertEquals(actual: map["10"] as! String, expected: "Ten as string", "String key")
|
||||
try assertEquals(actual: map[1.0 as Float] as! String, expected: "Float", "Float key")
|
||||
}
|
||||
|
||||
/**
|
||||
* Get first element of the collection.
|
||||
*/
|
||||
func testFirstElement() throws {
|
||||
let m = StdlibKt.createTypedMutableMap()
|
||||
m[10] = "Str"
|
||||
try assertEquals(actual: StdlibKt.getFirstElement(collection: m.allKeys) as! Int, expected: 10, "First key")
|
||||
|
||||
try assertEquals(actual: StdlibKt.getFirstElement(collection: StdlibKt.getKeysAsList(map: m as! Dictionary)) as! Int,
|
||||
expected: 10, "First key from a list")
|
||||
}
|
||||
|
||||
/**
|
||||
* Add element to dictionary in Kotlin
|
||||
*/
|
||||
func testAddDictionary() throws {
|
||||
let m = [ "ABC": 10, "CDE": 12, "FGH": 3 ]
|
||||
StdlibKt.addSomeElementsToMap(map: KotlinMutableDictionary(dictionary: m))
|
||||
for (k, v) in m {
|
||||
print("MAP: \(k) - \(v)")
|
||||
}
|
||||
|
||||
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")
|
||||
|
||||
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) -> KotlinArray<AnyObject> { return KotlinArray<AnyObject>(size: n) { $0 } }
|
||||
|
||||
func testList() throws {
|
||||
let elements = zeroTo(5)
|
||||
elements.set(index: 1, value: nil)
|
||||
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 = StdlibKt.emptyMutableList() as! NSMutableArray
|
||||
let nsList = NSMutableArray()
|
||||
|
||||
func apply<T : Equatable>(op: (NSMutableArray)->T) throws {
|
||||
let actual = op(kotlinList)
|
||||
let expected = op(nsList)
|
||||
try assertEquals(actual: actual, expected: expected)
|
||||
try assertEquals(actual: kotlinList, expected: nsList)
|
||||
try assertEquals(actual: kotlinList.hash, expected: nsList.hash)
|
||||
}
|
||||
|
||||
func applyVoid(op: (NSMutableArray)->Void) throws {
|
||||
op(kotlinList)
|
||||
op(nsList)
|
||||
try assertEquals(actual: kotlinList, expected: nsList)
|
||||
try assertEquals(actual: kotlinList.hash, expected: nsList.hash)
|
||||
}
|
||||
|
||||
try apply { $0.count }
|
||||
try applyVoid { $0.insert(0, at: 0) }
|
||||
try applyVoid { $0.insert(1, at: 0) }
|
||||
try applyVoid { $0.insert(2, at: 1) }
|
||||
try applyVoid { $0.removeObject(at: 0) }
|
||||
try applyVoid { $0.add("foo") }
|
||||
try applyVoid { $0.removeLastObject() }
|
||||
try applyVoid { $0.replaceObject(at: 0, with: "bar") }
|
||||
let NULL: Any? = nil
|
||||
try applyVoid { $0.add(NULL as Any) }
|
||||
try applyVoid { $0.insert(NULL as Any, at: 2) }
|
||||
try applyVoid { $0.replaceObject(at: 1, with: NULL as Any) }
|
||||
try apply { $0.count }
|
||||
}
|
||||
|
||||
func testMutableSet() throws {
|
||||
let kotlinSet = StdlibKt.emptyMutableSet() as! NSMutableSet
|
||||
let nsSet = NSMutableSet()
|
||||
|
||||
func apply<T : Equatable>(op: (NSMutableSet)->T) throws {
|
||||
let actual = op(kotlinSet)
|
||||
let expected = op(nsSet)
|
||||
try assertEquals(actual: actual, expected: expected)
|
||||
try assertEquals(actual: kotlinSet, expected: nsSet)
|
||||
try assertEquals(actual: kotlinSet.hash, expected: nsSet.hash)
|
||||
}
|
||||
|
||||
func applyVoid(op: (NSMutableSet)->Void) throws {
|
||||
op(kotlinSet)
|
||||
op(nsSet)
|
||||
try assertEquals(actual: kotlinSet, expected: nsSet)
|
||||
try assertEquals(actual: kotlinSet.hash, expected: nsSet.hash)
|
||||
}
|
||||
|
||||
try apply { $0.count }
|
||||
try applyVoid { $0.add("foo") }
|
||||
try applyVoid { $0.add("bar") }
|
||||
try applyVoid { $0.remove("baz") }
|
||||
try applyVoid { $0.add("baz") }
|
||||
try applyVoid { $0.add(TripleVals<NSNumber>(first: 1, second: 2, third: 3)) }
|
||||
try apply { $0.member(TripleVals<NSNumber>(first: 1, second: 2, third: 3)) as! TripleVals<NSNumber> }
|
||||
try apply { $0.member(42) == nil }
|
||||
try applyVoid { $0.remove(TripleVals<NSNumber>(first: 1, second: 2, third: 3)) }
|
||||
|
||||
let NULL0: Any? = nil
|
||||
let NULL = NULL0 as Any
|
||||
|
||||
try applyVoid { $0.add(NULL) }
|
||||
try apply { $0.member(NULL) == nil }
|
||||
try apply { $0.member(NULL) as! NSObject }
|
||||
try applyVoid { $0.remove(NULL) }
|
||||
try apply { $0.member(NULL) == nil }
|
||||
|
||||
try apply { NSSet(array: $0.objectEnumerator().remainingObjects()) }
|
||||
|
||||
try apply { $0.count }
|
||||
}
|
||||
|
||||
func testMutableMap() throws {
|
||||
// TODO: test KotlinMutableSet/Dictionary constructors
|
||||
let kotlinMap = StdlibKt.emptyMutableMap() as! NSMutableDictionary
|
||||
let nsMap = NSMutableDictionary()
|
||||
|
||||
func apply<T : Equatable>(op: (NSMutableDictionary)->T) throws {
|
||||
let actual = op(kotlinMap)
|
||||
let expected = op(nsMap)
|
||||
try assertEquals(actual: actual, expected: expected)
|
||||
try assertEquals(actual: kotlinMap, expected: nsMap)
|
||||
try assertEquals(actual: kotlinMap.hash, expected: nsMap.hash)
|
||||
}
|
||||
|
||||
func applyVoid(op: (NSMutableDictionary) throws -> Void) throws {
|
||||
try op(kotlinMap)
|
||||
try op(nsMap)
|
||||
try assertEquals(actual: kotlinMap, expected: nsMap)
|
||||
try assertEquals(actual: kotlinMap.hash, expected: nsMap.hash)
|
||||
}
|
||||
|
||||
try apply { $0.count }
|
||||
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 = TripleVals<NSNumber>(first: 3, second: 2, third: 1)
|
||||
try applyVoid { $0.setObject("bar", forKey: triple) }
|
||||
try applyVoid { $0.removeObject(forKey: 42) }
|
||||
try apply { $0.count }
|
||||
try apply { $0.object(forKey: 42) == nil }
|
||||
try apply { $0.object(forKey: "foo") as! NSObject }
|
||||
try apply { $0.object(forKey: triple) as! NSObject }
|
||||
|
||||
try apply { NSSet(array: $0.keyEnumerator().remainingObjects()) }
|
||||
|
||||
let NULL0: Any? = nil
|
||||
let NULL = NULL0 as Any
|
||||
|
||||
try apply { $0.object(forKey: NULL) == nil }
|
||||
|
||||
|
||||
try applyVoid { $0.setObject(42, forKey: NULL as! NSCopying) }
|
||||
try applyVoid { $0.setObject(NULL, forKey: "baz" as NSString) }
|
||||
try apply { $0.object(forKey: NULL) as! NSObject }
|
||||
try apply { $0.object(forKey: "baz") as! NSObject }
|
||||
|
||||
try apply { NSSet(array: $0.keyEnumerator().remainingObjects()) }
|
||||
|
||||
try applyVoid { $0.removeObject(forKey: NULL) }
|
||||
try applyVoid { $0.removeObject(forKey: "baz") }
|
||||
|
||||
try applyVoid { $0.removeAllObjects() }
|
||||
|
||||
let myKey = MyKey()
|
||||
try applyVoid { $0.setObject(myKey, forKey: myKey) }
|
||||
try applyVoid {
|
||||
let key = $0.allKeys[0] as! MyKey
|
||||
let value = $0.allValues[0] as! MyKey
|
||||
try assertFalse(key === myKey)
|
||||
try assertTrue(value === myKey)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@objc class MyKey : NSObject, NSCopying {
|
||||
override var hash: Int {
|
||||
return 42
|
||||
}
|
||||
|
||||
override func isEqual(_ object: Any?) -> Bool {
|
||||
return object is MyKey
|
||||
}
|
||||
|
||||
func copy(with: NSZone? = nil) -> Any {
|
||||
return MyKey()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func testSet() throws {
|
||||
let elements = KotlinArray<AnyObject>(size: 2) { index in nil }
|
||||
elements.set(index: 0, value: nil)
|
||||
elements.set(index: 1, value: 42 as NSNumber)
|
||||
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))
|
||||
try assertTrue(set.member(17) == nil)
|
||||
try assertFalse(set.member(42) as AnyObject === NSNumber(value: 42 as Int32))
|
||||
try assertTrue(set.contains(42))
|
||||
try assertTrue(set.contains(nil as Any?))
|
||||
try assertFalse(set.contains(17))
|
||||
|
||||
try assertEquals(actual: NSSet(array: set.objectEnumerator().remainingObjects()), expected: NSSet(array: [nil, 42] as [AnyObject]))
|
||||
}
|
||||
|
||||
func testMap() throws {
|
||||
let elements = KotlinArray<AnyObject>(size: 6) { index in nil }
|
||||
elements.set(index: 0, value: nil)
|
||||
elements.set(index: 1, value: 42 as NSNumber)
|
||||
elements.set(index: 2, value: "foo" as NSString)
|
||||
elements.set(index: 3, value: "bar" as NSString)
|
||||
elements.set(index: 4, value: 42 as NSNumber)
|
||||
elements.set(index: 5, value: nil)
|
||||
|
||||
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))
|
||||
try assertEquals(actual: map.object(forKey: "foo") as! String, expected: "bar")
|
||||
try assertEquals(actual: map.object(forKey: 42) as! NSNull, expected: NSNull())
|
||||
try assertTrue(map.object(forKey: "bar") == nil)
|
||||
|
||||
try assertEquals(actual: NSSet(array: map.keyEnumerator().remainingObjects()), expected: NSSet(array: [nil, 42, "foo"] as [AnyObject]))
|
||||
}
|
||||
|
||||
func testKotlinMutableSetInit() throws {
|
||||
func test(
|
||||
_ set: KotlinMutableSet<NSString>,
|
||||
_ check: (KotlinMutableSet<NSString>) throws -> Void = { _ in }
|
||||
) throws {
|
||||
try assertEquals(actual: String(describing: type(of: set)), expected: "StdlibMutableSet")
|
||||
try check(set)
|
||||
try assertFalse(set.contains("1"))
|
||||
set.add("1")
|
||||
try assertTrue(set.contains("1"))
|
||||
}
|
||||
|
||||
try test(KotlinMutableSet())
|
||||
try test(KotlinMutableSet(capacity: 1))
|
||||
try test(KotlinMutableSet(object: "2")) {
|
||||
try assertTrue($0.contains("2"))
|
||||
}
|
||||
|
||||
var threeAndFour = ["3", "4"] as [AnyObject]
|
||||
try test(KotlinMutableSet(objects: &threeAndFour, count: 2)) {
|
||||
try assertTrue($0.contains("3"))
|
||||
try assertTrue($0.contains("4"))
|
||||
}
|
||||
|
||||
try test(KotlinMutableSet(array: ["5", "6"])) {
|
||||
try assertTrue($0.contains("5"))
|
||||
try assertTrue($0.contains("6"))
|
||||
}
|
||||
|
||||
try test(KotlinMutableSet(set: ["7", "8"])) {
|
||||
try assertTrue($0.contains("7"))
|
||||
try assertTrue($0.contains("8"))
|
||||
}
|
||||
|
||||
for flag in [false, true] {
|
||||
try test(KotlinMutableSet(set: ["9", "10"], copyItems: flag)) {
|
||||
try assertTrue($0.contains("9"))
|
||||
try assertTrue($0.contains("10"))
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
TODO: doesn't work, KotlinMutableSet seems to be serialized as NSMutableSet.
|
||||
if #available(macOS 10.13, *) {
|
||||
let data = try! NSKeyedArchiver.archivedData(
|
||||
withRootObject: KotlinMutableSet<NSString>(array: ["11", "12"]),
|
||||
requiringSecureCoding: false
|
||||
)
|
||||
|
||||
try test(try! NSKeyedUnarchiver.unarchivedObject(ofClass: KotlinMutableSet.self, from: data)!) {
|
||||
try assertTrue($0.contains("11"))
|
||||
try assertTrue($0.contains("12"))
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
StdlibKt.gc() // To reproduce https://github.com/JetBrains/kotlin-native/issues/3259
|
||||
}
|
||||
|
||||
func testKotlinMutableDictionaryInit() throws {
|
||||
func test(
|
||||
_ dict: KotlinMutableDictionary<NSString, NSString>,
|
||||
_ check: (KotlinMutableDictionary<NSString, NSString>) throws -> Void = { _ in }
|
||||
) throws {
|
||||
try assertEquals(actual: String(describing: type(of: dict)), expected: "StdlibMutableDictionary")
|
||||
try check(dict)
|
||||
try assertTrue(dict["1"] == nil)
|
||||
dict["1"] = "2"
|
||||
try assertTrue(dict["1"] as? NSString == "2")
|
||||
}
|
||||
|
||||
try test(KotlinMutableDictionary())
|
||||
try test(KotlinMutableDictionary(capacity: 4))
|
||||
|
||||
// TODO: test [initWithCoder:].
|
||||
|
||||
try test(KotlinMutableDictionary(objects: ["3", "4"], forKeys: ["4", "3"] as [NSString])) {
|
||||
try assertEquals(actual: $0["3"] as? String, expected: "4")
|
||||
try assertEquals(actual: $0["4"] as? String, expected: "3")
|
||||
}
|
||||
|
||||
var fiveAndSix = ["5", "6"] as [AnyObject]
|
||||
var sixAndFive = ["6", "5"] as [NSCopying]
|
||||
try test(KotlinMutableDictionary(objects: &fiveAndSix, forKeys: &sixAndFive, count: 2)) {
|
||||
try assertEquals(actual: $0["5"] as? String, expected: "6")
|
||||
try assertEquals(actual: $0["6"] as? String, expected: "5")
|
||||
}
|
||||
|
||||
try test(KotlinMutableDictionary(object: "7", forKey: "8" as NSString)) {
|
||||
try assertEquals(actual: $0["8"] as? String, expected: "7")
|
||||
}
|
||||
|
||||
try test(KotlinMutableDictionary(dictionary: ["10" : "9"])) {
|
||||
try assertEquals(actual: $0["10"] as? String, expected: "9")
|
||||
}
|
||||
|
||||
for flag in [false, true] {
|
||||
try test(KotlinMutableDictionary(dictionary: ["12" : "11"], copyItems: flag)) {
|
||||
try assertEquals(actual: $0["12"] as? String, expected: "11")
|
||||
}
|
||||
}
|
||||
|
||||
try test(KotlinMutableDictionary(dictionaryLiteral: ("14", "13"))) {
|
||||
try assertEquals(actual: $0["14"] as? String, expected: "13")
|
||||
}
|
||||
|
||||
StdlibKt.gc() // To reproduce https://github.com/JetBrains/kotlin-native/issues/3259
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
import ValuesGenerics
|
||||
|
||||
// -------- Tests --------
|
||||
|
||||
func testVararg() throws {
|
||||
let ktArray = KotlinArray<KotlinInt>(size: 3, init: { (_) -> KotlinInt in return KotlinInt(int:42) })
|
||||
let arr: [Int] = ValuesKt.varargToList(args: ktArray as! KotlinArray<AnyObject>) as! [Int]
|
||||
try assertEquals(actual: arr, expected: [42, 42, 42])
|
||||
}
|
||||
|
||||
func testDataClass() throws {
|
||||
let f = "1" as NSString
|
||||
let s = "2" as NSString
|
||||
let t = "3" as NSString
|
||||
|
||||
let tripleVal = TripleVals<NSString>(first: f, second: s, third: t)
|
||||
try assertEquals(actual: tripleVal.first, expected: f, "Data class' value")
|
||||
try assertEquals(actual: tripleVal.first, expected: "1", "Data class' value literal")
|
||||
try assertEquals(actual: tripleVal.component2(), expected: s, "Data class' component")
|
||||
print(tripleVal)
|
||||
try assertEquals(actual: String(describing: tripleVal), expected: "TripleVals(first=\(f), second=\(s), third=\(t))")
|
||||
|
||||
let tripleVar = TripleVars<NSString>(first: f, second: s, third: t)
|
||||
try assertEquals(actual: tripleVar.first, expected: f, "Data class' value")
|
||||
try assertEquals(actual: tripleVar.component2(), expected: s, "Data class' component")
|
||||
print(tripleVar)
|
||||
try assertEquals(actual: String(describing: tripleVar), expected: "[\(f), \(s), \(t)]")
|
||||
|
||||
tripleVar.first = t
|
||||
tripleVar.second = f
|
||||
tripleVar.third = s
|
||||
try assertEquals(actual: tripleVar.component2(), expected: f, "Data class' component")
|
||||
try assertEquals(actual: String(describing: tripleVar), expected: "[\(t), \(f), \(s)]")
|
||||
}
|
||||
|
||||
func testInlineClasses() throws {
|
||||
let ic1: Int32 = 42
|
||||
let ic1N = ValuesKt.box(ic1: 17)
|
||||
let ic2 = "foo"
|
||||
let ic2N = "bar"
|
||||
let ic3 = TripleVals<AnyObject>(first: KotlinInt(int:1), second: KotlinInt(int:2), third: KotlinInt(int:3))
|
||||
let ic3N = ValuesKt.box(ic3: nil)
|
||||
|
||||
try assertEquals(
|
||||
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: ValuesKt.concatenateInlineClassValues(ic1: ic1, ic1N: nil, ic2: ic2, ic2N: nil, ic3: nil, ic3N: nil),
|
||||
expected: "42 null foo null null null"
|
||||
)
|
||||
|
||||
try assertEquals(actual: ValuesKt.getValue1(ic1), expected: 42)
|
||||
try assertEquals(actual: ValuesKt.getValueOrNull1(ic1N) as! Int, expected: 17)
|
||||
|
||||
try assertEquals(actual: ValuesKt.getValue2(ic2), expected: "foo")
|
||||
try assertEquals(actual: ValuesKt.getValueOrNull2(ic2N), expected: "bar")
|
||||
|
||||
try assertEquals(actual: ValuesKt.getValue3(ic3), expected: ic3)
|
||||
try assertEquals(actual: ValuesKt.getValueOrNull3(ic3N), expected: nil)
|
||||
}
|
||||
|
||||
func testGeneric() throws {
|
||||
let a = SomeGeneric<SomeData>(t: SomeData(num: 52))
|
||||
let asd : SomeData = a.myVal()!
|
||||
try assertEquals(actual: asd.num, expected: 52)
|
||||
|
||||
let nulls = GenOpen<SomeData>(arg: SomeData(num: 62))
|
||||
let nullssd : SomeData = nulls.arg!
|
||||
try assertEquals(actual: nullssd.num, expected: 62)
|
||||
|
||||
let isnull = GenOpen<SomeData>(arg: nil)
|
||||
try assertEquals(actual: isnull.arg, expected: nil)
|
||||
|
||||
let nonnulls = GenNonNull<SomeData>(arg: SomeData(num: 72))
|
||||
let nonnullssd : SomeData = nonnulls.arg
|
||||
try assertEquals(actual: nonnullssd.num, expected: 72)
|
||||
try assertEquals(actual: (Values_genericsKt.starGeneric(arg: nonnulls as! GenNonNull<AnyObject>) as! SomeData).num, expected: 72)
|
||||
|
||||
let sd = SomeData(num: 33)
|
||||
let nullColl = GenCollectionsNull<SomeData>(arg: sd, coll: [sd])
|
||||
let nonNullColl = GenCollectionsNonNull<SomeData>(arg: sd, coll: [sd])
|
||||
|
||||
try assertEquals(actual: (nullColl.coll[0] as! SomeData).num, expected: 33)
|
||||
let nonNullCollSd : SomeData = nonNullColl.coll[0]
|
||||
try assertEquals(actual: nonNullCollSd.num, expected: 33)
|
||||
try assertEquals(actual: nonNullColl.arg, expected: nonNullCollSd)
|
||||
|
||||
let mixed = GenNullability<SomeData>(arg: sd, nArg: sd)
|
||||
try assertEquals(actual: mixed.asNullable()?.num, expected: 33)
|
||||
try assertEquals(actual: mixed.pAsNullable?.num, expected: 33)
|
||||
let mixedSd : SomeData? = mixed.pAsNullable
|
||||
try assertEquals(actual: mixedSd, expected: mixed.nArg)
|
||||
}
|
||||
|
||||
// Swift ignores the variance and lets you force-cast to whatever you need, for better or worse.
|
||||
// This would *not* work with direct Swift interop.
|
||||
func testGenericVariance() throws {
|
||||
let sd = SomeData(num: 22)
|
||||
|
||||
let variOut = GenVarOut<SomeData>(arg: sd)
|
||||
let variOutAny : GenVarOut<BaseData> = variOut as! GenVarOut<BaseData>
|
||||
let variOutOther : GenVarOut<SomeOtherData> = variOut as! GenVarOut<SomeOtherData>
|
||||
|
||||
let variOutCheck = "variOut: \(variOut.arg.asString()), variOutAny: \(variOutAny.arg.asString()), variOutOther: \(variOutOther.arg.asString())"
|
||||
try assertEquals(actual: variOutCheck, expected: "variOut: 22, variOutAny: 22, variOutOther: 22")
|
||||
|
||||
let variIn = GenVarIn<SomeData>(tArg: sd)
|
||||
let variInAny : GenVarIn<BaseData> = variIn as! GenVarIn<BaseData>
|
||||
let variInOther : GenVarIn<SomeOtherData> = variIn as! GenVarIn<SomeOtherData>
|
||||
|
||||
let varInCheck = "variIn: \(variIn.valString()), variInAny: \(variInAny.valString()), variInOther: \(variInOther.valString())"
|
||||
try assertEquals(actual: varInCheck, expected: "variIn: SomeData(num=22), variInAny: SomeData(num=22), variInOther: SomeData(num=22)")
|
||||
|
||||
let variCoType:GenVarOut<BaseData> = Values_genericsKt.variCoType()
|
||||
try assertEquals(actual: "890", expected: variCoType.arg.asString())
|
||||
|
||||
let variContraType:GenVarIn<SomeData> = Values_genericsKt.variContraType()
|
||||
try assertEquals(actual: "SomeData(num=1890)", expected: variContraType.valString())
|
||||
}
|
||||
|
||||
// Swift should completely ignore this, as should objc. Really verifying that the header generator
|
||||
// deals with this
|
||||
func testGenericUseSiteVariance() throws {
|
||||
let sd = SomeData(num: 22)
|
||||
|
||||
let varUse = GenVarUse<BaseData>(arg: sd)
|
||||
let varUseArg = GenVarUse<BaseData>(arg: sd)
|
||||
|
||||
varUse.varUse(a: varUseArg, b: GenVarUse<SomeData>(arg: sd) as! GenVarUse<BaseData>)
|
||||
}
|
||||
|
||||
func testGenericInterface() throws {
|
||||
let a: NoGeneric = SomeGeneric<SomeData>(t: SomeData(num: 52))
|
||||
try assertEquals(actual: (a.myVal() as! SomeData).num, expected: 52)
|
||||
}
|
||||
|
||||
func testGenericInheritance() throws {
|
||||
let ge = GenEx<SomeData, SomeOtherData>(myT:SomeOtherData(str:"Hello"), baseT:SomeData(num: 11))
|
||||
let geT : SomeData = ge.t
|
||||
try assertEquals(actual: geT.num, expected: 11)
|
||||
let gemyT : SomeOtherData = ge.myT
|
||||
try assertEquals(actual: gemyT.str, expected: "Hello")
|
||||
let geBase = ge as GenBase<SomeData>
|
||||
let geBaseT : SomeData = geBase.t
|
||||
try assertEquals(actual: geBaseT.num, expected: 11)
|
||||
|
||||
//Similar to above but param names don't match and will dupe property definitions on child class
|
||||
//Functional, but should be fixed
|
||||
let ge2 = GenEx2<SomeData, SomeOtherData>(myT:SomeOtherData(str:"Hello2"), baseT:SomeData(num: 22))
|
||||
let ge2Val : SomeData = ge2.t
|
||||
let ge2SODVal : SomeOtherData = ge2.myT
|
||||
let ge2base : GenBase<SomeData> = ge2 as GenBase<SomeData>
|
||||
let ge2BaseVal : SomeData = ge2base.t
|
||||
try assertEquals(actual: ge2Val, expected: ge2BaseVal)
|
||||
|
||||
let geAny = GenExAny<SomeData, SomeOtherData>(myT:SomeOtherData(str:"Hello"), baseT:SomeData(num: 131))
|
||||
try assertEquals(actual: (geAny.t as! SomeData).num, expected: 131)
|
||||
let geBaseAny = geAny as! GenBase<SomeData>
|
||||
let geBaseAnyT : SomeData = geBaseAny.t
|
||||
try assertEquals(actual: geBaseAnyT.num, expected: 131)
|
||||
}
|
||||
|
||||
func testGenericInnerClass() throws {
|
||||
|
||||
let nestedClass = GenOuterGenNested<SomeData>(b: SomeData(num: 543))
|
||||
let nestedClassB : SomeData = nestedClass.b
|
||||
try assertEquals(actual: nestedClassB.num, expected: 543)
|
||||
|
||||
let innerClass = GenOuterGenInner<SomeData, SomeOtherData>(GenOuter<SomeOtherData>(a: SomeOtherData(str: "ggg")), c: SomeData(num: 66), aInner: SomeOtherData(str: "ttt"))
|
||||
let innerClassC : SomeData = innerClass.c
|
||||
try assertEquals(actual: innerClassC.num, expected: 66)
|
||||
let outerFun : SomeOtherData = innerClass.outerFun()
|
||||
let outerVal : SomeOtherData = innerClass.outerVal
|
||||
try assertEquals(actual: outerFun, expected: outerVal)
|
||||
try assertEquals(actual: outerFun.str, expected: "ggg")
|
||||
|
||||
Values_genericsKt.genInnerFunc(obj: innerClass)
|
||||
Values_genericsKt.genInnerFuncAny(obj: innerClass as! GenOuterGenInner<AnyObject, AnyObject>)
|
||||
|
||||
let innerReturned : GenOuterGenInner<SomeOtherData, SomeData> = Values_genericsKt.genInnerCreate()
|
||||
let innerReturnedInner : SomeOtherData = innerReturned.c
|
||||
try assertEquals(actual: innerReturnedInner.str, expected: "ppp")
|
||||
|
||||
let nestedClassSame = GenOuterSameGenNestedSame<SomeData>(a: SomeData(num: 545))
|
||||
let nestedClassSameA : SomeData = nestedClassSame.a
|
||||
try assertEquals(actual: nestedClassSameA.num, expected: 545)
|
||||
|
||||
let nested = GenOuterSameNestedNoGeneric()
|
||||
|
||||
let innerClassSame = GenOuterSameGenInnerSame<SomeOtherData, SomeData>(GenOuterSame<SomeData>(a: SomeData(num: 44)), a: SomeOtherData(str: "rrr"))
|
||||
let innerClassSameA : SomeOtherData = innerClassSame.a
|
||||
try assertEquals(actual: innerClassSame.a.str, expected: "rrr")
|
||||
|
||||
let gob : GenOuterBlankGenInner<SomeOtherData> = GenOuterBlankGenInner<SomeOtherData>(GenOuterBlank(sd: SomeData(num: 321)), arg: SomeOtherData(str: "aaa"))
|
||||
let gob2 : GenOuterBlank2GenInner<SomeOtherData> = GenOuterBlank2GenInner<SomeOtherData>(GenOuterBlank2(oarg: SomeOtherData(str: "ooo")), arg: SomeOtherData(str: "bbb"))
|
||||
|
||||
let gobsod : SomeOtherData = gob.arg!
|
||||
try assertEquals(actual: gobsod.str, expected: "aaa")
|
||||
|
||||
let gob2arg : SomeOtherData = gob2.arg!
|
||||
let gob2out : SomeOtherData = gob2.fromOuter()!
|
||||
|
||||
try assertEquals(actual: gob2arg.str, expected: "bbb")
|
||||
try assertEquals(actual: gob2out.str, expected: "ooo")
|
||||
|
||||
let inarg = GenOuterDeepGenShallowInner<SomeOtherData>(GenOuterDeep<SomeOtherData>(oarg: SomeOtherData(str: "fff")))
|
||||
let godeep : GenOuterDeepGenShallowInnerGenDeepInner<SomeOtherData> = GenOuterDeepGenShallowInnerGenDeepInner<SomeOtherData>(inarg)
|
||||
let deepval : SomeOtherData = godeep.o()!
|
||||
try assertEquals(actual: deepval.str, expected: "fff")
|
||||
|
||||
let deep2 = GenOuterDeep2()
|
||||
let deep2Before = GenOuterDeep2.Before(deep2)
|
||||
let deep2After = GenOuterDeep2.After(deep2)
|
||||
let deep2soi = GenOuterDeep2.GenShallowOuterInner(deep2)
|
||||
let deep2si = GenOuterDeep2GenShallowOuterInnerGenShallowInner<SomeData>(deep2soi)
|
||||
let deep2i = GenOuterDeep2GenShallowOuterInnerGenShallowInnerGenDeepInner<SomeData>(deep2si)
|
||||
|
||||
let gbb : GenBothBlank.GenInner = GenBothBlank.GenInner(GenBothBlank(a: SomeData(num: 22)), b: SomeOtherData(str: "ttt"))
|
||||
try assertEquals(actual: gbb.b.str, expected: "ttt")
|
||||
}
|
||||
|
||||
func testGenericClashing() throws {
|
||||
let gcId = GenClashId<SomeData, SomeOtherData>(arg: SomeData(num: 22), arg2: SomeOtherData(str: "lll"))
|
||||
try assertEquals(actual: gcId.x() as! NSString, expected: "Foo")
|
||||
let gcIdArg : SomeData = gcId.arg
|
||||
try assertEquals(actual: gcIdArg.num, expected: 22)
|
||||
let gcIdArg2 : SomeOtherData = gcId.arg2
|
||||
try assertEquals(actual: gcIdArg2.str, expected: "lll")
|
||||
|
||||
let gcClass = GenClashClass<SomeData, SomeOtherData, NSString>(arg: SomeData(num: 432), arg2: SomeOtherData(str: "lll"), arg3: "Bar")
|
||||
try assertEquals(actual: gcClass.int(), expected: 55)
|
||||
try assertEquals(actual: gcClass.sd().num, expected: 88)
|
||||
try assertEquals(actual: gcClass.list()[1].num, expected: 22)
|
||||
try assertEquals(actual: gcClass.arg.num, expected: 432)
|
||||
try assertEquals(actual: gcClass.clash().str, expected: "aaa")
|
||||
try assertEquals(actual: gcClass.arg2.str, expected: "lll")
|
||||
try assertEquals(actual: gcClass.arg3, expected: "Bar")
|
||||
|
||||
//GenClashNames uses type parameter names that force the Objc class name itself to be mangled. Swift keeps names however
|
||||
let clashNames = GenClashNames<SomeData, SomeData, SomeData, SomeData>()
|
||||
try assertEquals(actual: clashNames.foo().str, expected: "nnn")
|
||||
try assertEquals(actual: clashNames.bar().str, expected: "qqq")
|
||||
try assertTrue(clashNames.baz(arg: ClashnameParam(str: "meh")), "ClashnameParam issue")
|
||||
|
||||
let clashNamesEx = GenClashEx<SomeData>()
|
||||
|
||||
let geClash = GenExClash<SomeOtherData>(myT:SomeOtherData(str:"Hello"))
|
||||
try assertEquals(actual: geClash.t.num, expected: 55)
|
||||
try assertEquals(actual: geClash.myT.str, expected: "Hello")
|
||||
}
|
||||
|
||||
func testGenericExtensions() throws {
|
||||
let gnn = GenNonNull<SomeData>(arg: SomeData(num: 432))
|
||||
try assertEquals(actual: (gnn.foo() as! SomeData).num, expected: 432)
|
||||
}
|
||||
|
||||
// -------- Execution of the test --------
|
||||
|
||||
class ValuesTests : TestProvider {
|
||||
var tests: [TestCase] = []
|
||||
|
||||
init() {
|
||||
providers.append(self)
|
||||
tests = [
|
||||
TestCase(name: "TestVararg", method: withAutorelease(testVararg)),
|
||||
TestCase(name: "TestDataClass", method: withAutorelease(testDataClass)),
|
||||
TestCase(name: "TestInlineClasses", method: withAutorelease(testInlineClasses)),
|
||||
TestCase(name: "TestGeneric", method: withAutorelease(testGeneric)),
|
||||
TestCase(name: "TestGenericVariance", method: withAutorelease(testGenericVariance)),
|
||||
TestCase(name: "TestGenericUseSiteVariance", method: withAutorelease(testGenericUseSiteVariance)),
|
||||
TestCase(name: "TestGenericInheritance", method: withAutorelease(testGenericInheritance)),
|
||||
TestCase(name: "TestGenericInterface", method: withAutorelease(testGenericInterface)),
|
||||
TestCase(name: "TestGenericInnerClass", method: withAutorelease(testGenericInnerClass)),
|
||||
TestCase(name: "TestGenericClashing", method: withAutorelease(testGenericClashing)),
|
||||
TestCase(name: "TestGenericExtensions", method: withAutorelease(testGenericExtensions)),
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
// All classes and methods should be used in tests
|
||||
@file:Suppress("UNUSED")
|
||||
|
||||
package conversions
|
||||
|
||||
import kotlin.native.concurrent.isFrozen
|
||||
import kotlin.properties.ReadWriteProperty
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
// Generics
|
||||
abstract class BaseData{
|
||||
abstract fun asString():String
|
||||
}
|
||||
|
||||
data class SomeData(val num:Int = 42):BaseData() {
|
||||
override fun asString(): String = num.toString()
|
||||
}
|
||||
|
||||
data class SomeOtherData(val str:String):BaseData() {
|
||||
fun anotherFun(){}
|
||||
override fun asString(): String = str
|
||||
}
|
||||
|
||||
interface NoGeneric<T> {
|
||||
fun myVal():T
|
||||
}
|
||||
|
||||
data class SomeGeneric<T>(val t:T):NoGeneric<T>{
|
||||
override fun myVal(): T = t
|
||||
}
|
||||
|
||||
class GenOpen<T:Any?>(val arg:T)
|
||||
class GenNonNull<T:Any>(val arg:T)
|
||||
|
||||
class GenCollectionsNull<T>(val arg: T, val coll: List<T>)
|
||||
class GenCollectionsNonNull<T:Any>(val arg: T, val coll: List<T>)
|
||||
|
||||
//Force @class declaration at top of file with Objc variance
|
||||
object ForceUse {
|
||||
val gvo = GenVarOut(SomeData())
|
||||
}
|
||||
|
||||
class GenVarOut<out T:Any>(val arg:T)
|
||||
|
||||
class GenVarIn<in T:Any>(tArg:T){
|
||||
private val t = tArg
|
||||
|
||||
fun valString():String = t.toString()
|
||||
|
||||
fun goIn(t:T){
|
||||
//Just taking a val
|
||||
}
|
||||
}
|
||||
|
||||
class GenVarUse<T:Any>(val arg:T){
|
||||
fun varUse(a:GenVarUse<out T>, b:GenVarUse<in T>){
|
||||
//Should complile but do nothing
|
||||
}
|
||||
}
|
||||
|
||||
fun variCoType():GenVarOut<BaseData>{
|
||||
val compileVarOutSD:GenVarOut<SomeData> = GenVarOut(SomeData(890))
|
||||
val compileVarOut:GenVarOut<BaseData> = compileVarOutSD
|
||||
return compileVarOut
|
||||
}
|
||||
|
||||
fun variContraType():GenVarIn<SomeData>{
|
||||
val compileVariIn:GenVarIn<BaseData> = GenVarIn(SomeData(1890))
|
||||
val compileVariInSD:GenVarIn<SomeData> = compileVariIn
|
||||
return compileVariInSD
|
||||
}
|
||||
|
||||
open class GenBase<T:Any>(val t:T)
|
||||
class GenEx<TT:Any, T:Any>(val myT:T, baseT:TT):GenBase<TT>(baseT)
|
||||
class GenEx2<T:Any, S:Any>(val myT:S, baseT:T):GenBase<T>(baseT)
|
||||
|
||||
class GenExAny<TT:Any, T:Any>(val myT:T, baseT:TT):GenBase<Any>(baseT)
|
||||
|
||||
class GenNullability<T:Any>(val arg: T, val nArg:T?){
|
||||
fun asNullable():T? = arg
|
||||
val pAsNullable:T?
|
||||
get() = arg
|
||||
}
|
||||
|
||||
fun starGeneric(arg: GenNonNull<*>):Any{
|
||||
return arg.arg
|
||||
}
|
||||
|
||||
class GenOuter<A:Any>(val a:A){
|
||||
class GenNested<B:Any>(val b:B)
|
||||
inner class GenInner<C:Any>(val c:C, val aInner:A) {
|
||||
fun outerFun(): A = a
|
||||
val outerVal: A = a
|
||||
}
|
||||
}
|
||||
|
||||
class GenOuterSame<A:Any>(val a:A){
|
||||
class GenNestedSame<A:Any>(val a:A)
|
||||
inner class GenInnerSame<A:Any>(val a:A)
|
||||
class NestedNoGeneric()
|
||||
}
|
||||
|
||||
fun genInnerFunc(obj: GenOuter<SomeOtherData>.GenInner<SomeData>) {}
|
||||
fun <A:Any, C:Any> genInnerFuncAny(obj: GenOuter<A>.GenInner<C>){}
|
||||
|
||||
fun genInnerCreate(): GenOuter<SomeData>.GenInner<SomeOtherData> =
|
||||
GenOuter(SomeData(33)).GenInner(SomeOtherData("ppp"), SomeData(77))
|
||||
|
||||
class GenOuterBlank(val sd: SomeData) {
|
||||
inner class GenInner<T>(val arg: T){
|
||||
fun fromOuter(): SomeData = sd
|
||||
}
|
||||
}
|
||||
|
||||
class GenOuterBlank2<T>(val oarg: T) {
|
||||
inner class GenInner(val arg: T){
|
||||
fun fromOuter(): T = oarg
|
||||
}
|
||||
}
|
||||
|
||||
class GenOuterDeep<T>(val oarg: T) {
|
||||
inner class GenShallowInner(){
|
||||
inner class GenDeepInner(){
|
||||
fun o(): T = oarg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GenOuterDeep2() {
|
||||
inner class Before()
|
||||
inner class GenShallowOuterInner() {
|
||||
inner class GenShallowInner<T>() {
|
||||
inner class GenDeepInner()
|
||||
}
|
||||
}
|
||||
inner class After()
|
||||
}
|
||||
|
||||
class GenBothBlank(val a: SomeData) {
|
||||
inner class GenInner(val b: SomeOtherData)
|
||||
}
|
||||
|
||||
class GenClashId<id : Any, id_ : Any>(val arg: id, val arg2: id_){
|
||||
fun x(): Any = "Foo"
|
||||
}
|
||||
|
||||
class GenClashClass<ValuesGenericsClashingData : Any, NSArray : Any, int32_t : Any>(
|
||||
val arg: ValuesGenericsClashingData, val arg2: NSArray, val arg3: int32_t
|
||||
) {
|
||||
fun sd(): SomeData = SomeData(88)
|
||||
fun list(): List<SomeData> = listOf(SomeData(11), SomeData(22))
|
||||
fun int(): Int = 55
|
||||
fun clash(): ClashingData = ClashingData("aaa")
|
||||
}
|
||||
|
||||
data class ClashingData(val str: String)
|
||||
|
||||
class GenClashNames<ValuesGenericsClashnameClass, ValuesGenericsClashnameProtocol, ValuesGenericsClashnameParam, ValuesGenericsValues_genericsKt>() {
|
||||
fun foo() = ClashnameClass("nnn")
|
||||
|
||||
fun bar(): ClashnameProtocol = object : ClashnameProtocol{
|
||||
override val str = "qqq"
|
||||
}
|
||||
|
||||
fun baz(arg: ClashnameParam): Boolean {
|
||||
return arg.str == "meh"
|
||||
}
|
||||
}
|
||||
|
||||
class GenClashEx<ValuesGenericsClashnameClass>: ClashnameClass("ttt"){
|
||||
fun foo() = ClashnameClass("nnn")
|
||||
}
|
||||
|
||||
open class ClashnameClass(val str: String)
|
||||
interface ClashnameProtocol {
|
||||
val str: String
|
||||
}
|
||||
data class ClashnameParam(val str: String)
|
||||
|
||||
class GenExClash<ValuesGenericsSomeData:Any>(val myT:ValuesGenericsSomeData):GenBase<SomeData>(SomeData(55))
|
||||
|
||||
class SelfRef : GenBasic<SelfRef>()
|
||||
|
||||
open class GenBasic<T>()
|
||||
|
||||
//Extensions
|
||||
fun <T:Any> GenNonNull<T>.foo(): T = arg
|
||||
|
||||
class StarProjectionInfiniteRecursion<T : StarProjectionInfiniteRecursion<T>>
|
||||
|
||||
fun testStarProjectionInfiniteRecursion(x: StarProjectionInfiniteRecursion<*>) {}
|
||||
Reference in New Issue
Block a user