| // TARGET_BACKEND: JS_IR, JS_IR_ES6 | |
| // KJS_WITH_FULL_RUNTIME | |
| /* | |
| This tests that variables (aliases) are created for array literals. | |
| Let's say we have the following JS code: | |
| function f(a) { | |
| a.push(0); | |
| return a; | |
| } | |
| // ... | |
| console.log(f([])); | |
| In this case copying f's argument a without creating a variable is incorrect because it would produce the following code: | |
| [].push(0); | |
| console.log([]); | |
| This is the correct version: | |
| var a = []; | |
| a.push(0); | |
| console.log(a); | |
| The test was created because we don't want to create aliases for literals. | |
| However in our class hierarchy JsArrayLiteral is subclass of JsLiteral, | |
| which makes very easy to implement incorrect aliasing logic. | |
| */ | |
| // FILE: lib.kt | |
| package foo | |
| inline fun Array<Int>.push(element: Int): Unit = asDynamic().push(element) | |
| inline fun Array<Int>.splice(index: Int, howMany: Int): Unit = asDynamic().splice(index, howMany) | |
| data class PairArray<T, R>(val fst: Array<T>, val snd: Array<R>) | |
| inline fun moveTo(source: Array<Int>, sink: Array<Int>): PairArray<Int, Int> { | |
| val size = source.size | |
| for (i in 1..size) { | |
| val element = source[0] | |
| source.splice(0, 1) | |
| sink.push(element) | |
| } | |
| return PairArray(source, sink) | |
| } | |
| // FILE: main.kt | |
| // CHECK_NOT_CALLED: moveTo | |
| // CHECK_BREAKS_COUNT: function=box count=0 | |
| // CHECK_LABELS_COUNT: function=box name=$l$block count=0 | |
| package foo | |
| fun box(): String { | |
| val expected = PairArray<Int, Int>(arrayOf(), arrayOf(1,2,3,4)) | |
| assertTrue(expected.deepEquals(moveTo(arrayOf(3, 4), arrayOf(1, 2)))) | |
| return "OK" | |
| } | |
| fun <T, R> PairArray<T, R>.deepEquals(other: PairArray<T, R>): Boolean { | |
| return fst.asList() == other.fst.asList() && snd.asList() == other.snd.asList() | |
| } |