JS: create new common directory for all generated tests, migrate several tests there
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test
|
||||
|
||||
inline fun <T> block(f: () -> T): T = f()
|
||||
|
||||
fun test() = block(fun(): Int { return 23 })
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(23, test())
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package foo
|
||||
|
||||
fun add(a: Int, b: Int): Int {
|
||||
val o = object {
|
||||
inline fun add(a: Int, b: Int): Int = a + b
|
||||
}
|
||||
|
||||
return o.add(a, b)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(3, add(1, 2))
|
||||
assertEquals(5, add(2, 3))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
package foo
|
||||
|
||||
// CHECK_NOT_CALLED: moveTo
|
||||
|
||||
@native fun Array<Int>.push(element: Int): Unit = noImpl
|
||||
|
||||
@native fun Array<Int>.splice(index: Int, howMany: Int): Unit = noImpl
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
package foo
|
||||
|
||||
// CHECK_FUNCTIONS_HAVE_SAME_LINES: syntaxTestInline syntaxTest
|
||||
|
||||
inline fun syntaxTestInline() {
|
||||
var result: Int = -0
|
||||
|
||||
for (i in 1..10)
|
||||
result += 1
|
||||
|
||||
for (i in arrayOf(10).indices)
|
||||
result += i
|
||||
|
||||
while (result < 30)
|
||||
result += 1
|
||||
|
||||
while (true)
|
||||
break
|
||||
|
||||
while (false)
|
||||
continue
|
||||
|
||||
do
|
||||
result += 1
|
||||
while (result < 40)
|
||||
|
||||
if (true)
|
||||
result += 10
|
||||
|
||||
if (false)
|
||||
result += 0
|
||||
else
|
||||
result += 10
|
||||
|
||||
result += if (true) 10 else 0
|
||||
|
||||
result += if (false) 0 else 10
|
||||
|
||||
when (result) {
|
||||
0 -> result += 0
|
||||
else -> result += 10
|
||||
}
|
||||
|
||||
when (result) {
|
||||
result -> result += 10
|
||||
else -> result += 0
|
||||
}
|
||||
|
||||
result = result + 10 - 10 * 1 / 1
|
||||
|
||||
try {
|
||||
result += 10
|
||||
} catch (e: Exception) {
|
||||
result += 0
|
||||
}
|
||||
|
||||
result++
|
||||
|
||||
--result
|
||||
|
||||
val nullable: String? = null
|
||||
}
|
||||
|
||||
fun syntaxTest() {
|
||||
syntaxTestInline()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
syntaxTest()
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package foo
|
||||
|
||||
// CHECK_NOT_CALLED: inline1
|
||||
// CHECK_NOT_CALLED: inline2
|
||||
// CHECK_NOT_CALLED: inline3
|
||||
|
||||
inline fun inline1(a: Int): Int {
|
||||
return a
|
||||
}
|
||||
|
||||
inline fun inline2(a: Int): Int {
|
||||
val a1 = inline1(a)
|
||||
if (a1 == 0) return 0
|
||||
return a1 + inline1(a)
|
||||
}
|
||||
|
||||
inline fun inline3(a: Int): Int {
|
||||
val i = inline2(a)
|
||||
val i1 = inline1(a) * i
|
||||
if (i == i1) return 0
|
||||
return i1
|
||||
}
|
||||
|
||||
val r1 = inline3(1)
|
||||
val r3 = inline3(3)
|
||||
val r4 = inline3(4)
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(0, r1)
|
||||
assertEquals(18, r3)
|
||||
assertEquals(32, r4)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package foo
|
||||
|
||||
// CHECK_NOT_CALLED: abs
|
||||
|
||||
inline fun abs(a: Int): Int {
|
||||
if (a < 0) {
|
||||
return a * -1
|
||||
} else {
|
||||
return a
|
||||
}
|
||||
}
|
||||
|
||||
val r1 = abs(1)
|
||||
val r2 = abs(-2)
|
||||
val r3 = abs(3)
|
||||
val r4 = abs(-4)
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(1, r1)
|
||||
assertEquals(2, r2)
|
||||
assertEquals(3, r3)
|
||||
assertEquals(4, r4)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: multiplyInline
|
||||
// CHECK_NOT_CALLED: runNoinline
|
||||
|
||||
internal inline fun multiply(a: Int, b: Int) = a * b
|
||||
|
||||
internal inline fun run(a: Int, b: Int, func: (Int, Int) -> Int) = func(a, b)
|
||||
|
||||
internal fun multiplyInline(a: Int, b: Int) = run(a, b, ::multiply)
|
||||
|
||||
|
||||
internal inline fun runNoinline(a: Int, b: Int, noinline func: (Int, Int) -> Int) = func(a, b)
|
||||
|
||||
internal fun multiplyNoinline(a: Int, b: Int) = runNoinline(a, b, ::multiply)
|
||||
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(6, multiplyInline(2, 3))
|
||||
assertEquals(6, multiplyNoinline(2, 3))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package foo
|
||||
|
||||
fun multiplyBy(x: Int): () -> ((Int) -> Int) {
|
||||
inline fun applyMultiplication(y: Int): Int = x * y
|
||||
|
||||
return { ::applyMultiplication }
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(6, multiplyBy(2)()(3))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copy of JVM-backend test
|
||||
* Found at: compiler/testData/codegen/boxInline/simple/classObject.1.kt
|
||||
*/
|
||||
|
||||
package foo
|
||||
|
||||
inline fun inline(s: () -> String): String {
|
||||
return s()
|
||||
}
|
||||
|
||||
class InlineAll {
|
||||
|
||||
inline fun inline(s: () -> String): String {
|
||||
return s()
|
||||
}
|
||||
|
||||
companion object {
|
||||
inline fun inline(s: () -> String): String {
|
||||
return s()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun testClassObjectCall(): String {
|
||||
return InlineAll.inline({"classobject"})
|
||||
}
|
||||
|
||||
fun testInstanceCall(): String {
|
||||
val inlineX = InlineAll()
|
||||
return inlineX.inline({"instance"})
|
||||
}
|
||||
|
||||
fun testPackageCall(): String {
|
||||
return inline({"package"})
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
if (testClassObjectCall() != "classobject") return "test1: ${testClassObjectCall()}"
|
||||
if (testInstanceCall() != "instance") return "test2: ${testInstanceCall()}"
|
||||
if (testPackageCall() != "package") return "test3: ${testPackageCall()}"
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package foo
|
||||
|
||||
inline fun block(p: () -> Int) = p()
|
||||
|
||||
fun createFunction(x: Int): () -> Int = { x }
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(23, block(createFunction(23)))
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test
|
||||
|
||||
// A copy of stdlib run function.
|
||||
// Copied to not to depend on run implementation.
|
||||
// It's important, that the body is just `return fn()`.
|
||||
internal inline fun <T> evaluate(fn: ()->T): T = fn()
|
||||
|
||||
internal fun test(n: Int): Int {
|
||||
return evaluate {
|
||||
var i = n
|
||||
var sum = 0
|
||||
|
||||
while (i > 0) {
|
||||
sum += i
|
||||
i--
|
||||
}
|
||||
|
||||
sum
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(6, test(3))
|
||||
assertEquals(0, test(0))
|
||||
assertEquals(0, test(-1))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copy of JVM-backend test
|
||||
* Found at: compiler/testData/codegen/boxInline/simple/extension.1.kt
|
||||
*/
|
||||
|
||||
package foo
|
||||
|
||||
inline fun Inline.calcExt(s: (Int) -> Int, p: Int) : Int {
|
||||
return s(p)
|
||||
}
|
||||
|
||||
inline fun Inline.calcExt2(s: Int.() -> Int, p: Int) : Int {
|
||||
return p.s()
|
||||
}
|
||||
|
||||
class InlineX(val value : Int) {}
|
||||
|
||||
class Inline(val res: Int) {
|
||||
|
||||
inline fun InlineX.calcInt(s: (Int, Int) -> Int) : Int {
|
||||
return s(res, this.value)
|
||||
}
|
||||
|
||||
inline fun Double.calcDouble(s: (Int, Double) -> Double) : Double {
|
||||
return s(res, this)
|
||||
}
|
||||
|
||||
fun doWork(l : InlineX) : Int {
|
||||
return l.calcInt({ a: Int, b: Int -> a + b})
|
||||
}
|
||||
|
||||
fun doWorkWithDouble(s : Double) : Double {
|
||||
return s.calcDouble({ a: Int, b: Double -> a + b})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun test1(): Int {
|
||||
val inlineX = Inline(9)
|
||||
return inlineX.calcExt({ z: Int -> z}, 25)
|
||||
}
|
||||
|
||||
fun test2(): Int {
|
||||
val inlineX = Inline(9)
|
||||
return inlineX.calcExt2({ -> this}, 25)
|
||||
}
|
||||
|
||||
fun test3(): Int {
|
||||
val inlineX = Inline(9)
|
||||
return inlineX.doWork(InlineX(11))
|
||||
}
|
||||
|
||||
fun test4(): Double {
|
||||
val inlineX = Inline(9)
|
||||
return inlineX.doWorkWithDouble(11.0)
|
||||
}
|
||||
|
||||
fun test5(): Double {
|
||||
val inlineX = Inline(9)
|
||||
with(inlineX) {
|
||||
11.0.calcDouble{ a: Int, b: Double -> a + b}
|
||||
}
|
||||
return inlineX.doWorkWithDouble(11.0)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
if (test1() != 25) return "test1: ${test1()}"
|
||||
if (test2() != 25) return "test2: ${test2()}"
|
||||
if (test3() != 20) return "test3: ${test3()}"
|
||||
if (test4() != 20.0) return "test4: ${test4()}"
|
||||
if (test5() != 20.0) return "test5: ${test5()}"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package foo
|
||||
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: scope=multiply function=multiply$f
|
||||
|
||||
internal class A(val a: Int)
|
||||
|
||||
internal inline fun <T, R> with2(receiver: T, arg1: R, arg2: R, f: T.(R, R) -> R): R = receiver.f(arg1, arg2)
|
||||
|
||||
internal fun multiply(a: Int, b: Int, c: Int): Int = with2(A(a), b, c) { x, y -> a*x*y }
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(105, multiply(3, 5, 7))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package foo
|
||||
|
||||
class A
|
||||
|
||||
inline fun compare1(a: A): Boolean {
|
||||
return a === a
|
||||
}
|
||||
|
||||
inline fun compare2(a1: A, a2: A): Boolean {
|
||||
return a1 === a2
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(true, compare1(A()), "compare1(A())")
|
||||
assertEquals(false, compare2(A(), A()), "compare2(A(), A())")
|
||||
|
||||
val a = A()
|
||||
assertEquals(true, compare2(a, a), "compare2(a, a)")
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package foo
|
||||
|
||||
// CHECK_NOT_CALLED: inc
|
||||
// CHECK_NOT_CALLED: run
|
||||
|
||||
class Countable {
|
||||
var count = 0
|
||||
}
|
||||
|
||||
inline fun inc(countable: Countable) = countable.count++
|
||||
|
||||
inline fun run(func: () -> Unit) = func()
|
||||
|
||||
fun incNoInline(countable: Countable) = run { inc(countable) }
|
||||
|
||||
fun box(): String {
|
||||
val c = Countable()
|
||||
|
||||
incNoInline(c)
|
||||
assertEquals(1, c.count)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package foo
|
||||
|
||||
// CHECK_NOT_CALLED: sumEvenInRange
|
||||
|
||||
fun sum(a: Int, b: Int): Int {
|
||||
return a + b
|
||||
}
|
||||
|
||||
fun even(a: Int): Boolean {
|
||||
return a % 2 == 0
|
||||
}
|
||||
|
||||
inline fun sumEvenInRange(a: Int, b: Int): Int {
|
||||
var c = 0
|
||||
|
||||
for (i in a..b) {
|
||||
if (even(i)) {
|
||||
c = sum(c, i)
|
||||
}
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val sum6 = sumEvenInRange(1, 5)
|
||||
assertEquals(6, sum6)
|
||||
|
||||
val sum12 = sumEvenInRange(0, 7)
|
||||
assertEquals(12, sum12)
|
||||
|
||||
val sum20 = sumEvenInRange(0, 9)
|
||||
assertEquals(20, sum20)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test
|
||||
|
||||
inline fun block(p: () -> Unit) = p()
|
||||
|
||||
class A(val x: Int) {
|
||||
fun test(): Int {
|
||||
var result: Int = 0
|
||||
block {
|
||||
result = x
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(23, A(23).test())
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: squareMultipliedByTwo
|
||||
|
||||
internal inline fun inline1(a: Int): Int {
|
||||
return a
|
||||
}
|
||||
|
||||
internal inline fun inline2(a: Int): Int {
|
||||
return inline1(a) + inline1(a)
|
||||
}
|
||||
|
||||
internal inline fun inline3(a: Int): Int {
|
||||
return inline1(a) * inline2(a)
|
||||
}
|
||||
|
||||
internal fun squareMultipliedByTwo(a: Int): Int {
|
||||
return inline3(a)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(2, squareMultipliedByTwo(1))
|
||||
assertEquals(18, squareMultipliedByTwo(3))
|
||||
assertEquals(32, squareMultipliedByTwo(4))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: squareMultipliedByTwo
|
||||
|
||||
internal inline fun inline1(a: Int): Int {
|
||||
return a
|
||||
}
|
||||
|
||||
internal inline fun inline2(a: Int): Int {
|
||||
val a1 = inline1(a)
|
||||
if (a1 == 0) return 0
|
||||
return a1 + inline1(a)
|
||||
}
|
||||
|
||||
internal inline fun inline3(a: Int): Int {
|
||||
val i = inline2(a)
|
||||
val i1 = inline1(a) * i
|
||||
if (i == i1) return 0
|
||||
return i1
|
||||
}
|
||||
|
||||
internal fun squareMultipliedByTwo(a: Int): Int {
|
||||
return inline3(a)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(0, squareMultipliedByTwo(1))
|
||||
assertEquals(18, squareMultipliedByTwo(3))
|
||||
assertEquals(32, squareMultipliedByTwo(4))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: identity
|
||||
// CHECK_CONTAINS_NO_CALLS: sumNoInline
|
||||
|
||||
internal inline fun sum(a: Int, b: Int = 0): Int {
|
||||
return a + b
|
||||
}
|
||||
|
||||
internal fun identity(a: Int): Int {
|
||||
return sum(a)
|
||||
}
|
||||
|
||||
internal fun sumNoInline(a: Int, b: Int): Int {
|
||||
return sum(a, b)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(1, identity(1))
|
||||
assertEquals(2, identity(2))
|
||||
assertEquals(3, sumNoInline(1, 2))
|
||||
assertEquals(5, sumNoInline(2, 3))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: doNothingNoInline
|
||||
|
||||
internal inline fun <T> doNothing1(a: T): T {
|
||||
return a
|
||||
}
|
||||
|
||||
internal inline fun <T> doNothing2(a: T, f: (T) -> T): T {
|
||||
return f(a)
|
||||
}
|
||||
|
||||
internal fun doNothingNoInline(a: Int): Int {
|
||||
return doNothing2(a, { x -> doNothing1(x)})
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(1, doNothingNoInline(1))
|
||||
assertEquals(12, doNothingNoInline(12))
|
||||
assertEquals(12, doNothingNoInline(12))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: doNothingInt
|
||||
// CHECK_CONTAINS_NO_CALLS: doNothingStr
|
||||
|
||||
internal inline fun <T> doNothing(a: T): T {
|
||||
return a
|
||||
}
|
||||
|
||||
internal fun doNothingInt(a: Int): Int {
|
||||
return doNothing(a)
|
||||
}
|
||||
|
||||
internal fun doNothingStr(a: String): String {
|
||||
return doNothing(a)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(1, doNothingInt(1))
|
||||
assertEquals(2, doNothingInt(2))
|
||||
assertEquals("ab", doNothingStr("ab"))
|
||||
assertEquals("abc", doNothingStr("abc"))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: testIf1
|
||||
// CHECK_CONTAINS_NO_CALLS: testIf2
|
||||
// CHECK_CONTAINS_NO_CALLS: testIf3
|
||||
|
||||
inline fun if1(f: (Int) -> Int, a: Int, b: Int, c: Int): Int {
|
||||
val result = f(a)
|
||||
|
||||
if (result == b) {
|
||||
return f(a)
|
||||
}
|
||||
|
||||
return f(c)
|
||||
}
|
||||
|
||||
inline fun if2(f: (Int) -> Int, a: Int, b: Int, c: Int): Int {
|
||||
if (f(a) == b) {
|
||||
return f(a)
|
||||
}
|
||||
|
||||
return f(c)
|
||||
}
|
||||
|
||||
inline fun if3(f: (Int) -> Int, a: Int, b: Int, c: Int): Int {
|
||||
if (f(a) == b) {
|
||||
return f(a)
|
||||
} else {
|
||||
return f(c)
|
||||
}
|
||||
}
|
||||
|
||||
fun testIf1(): String {
|
||||
val test1 = if1({it}, 1, 2, 3)
|
||||
if (test1 != 3) return "testIf1: test1 fail"
|
||||
|
||||
val test2 = if1({it}, 2, 2, 3)
|
||||
if (test2 != 2) return "testIf1: test 2 fail"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
fun testIf2(): String {
|
||||
val test1 = if2({it}, 1, 2, 3)
|
||||
if (test1 != 3) return "testIf2: test1 fail"
|
||||
|
||||
val test2 = if2({it}, 2, 2, 3)
|
||||
if (test2 != 2) return "testIf2: test 2 fail"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
fun testIf3(): String {
|
||||
val test1 = if3({it}, 1, 2, 3)
|
||||
if (test1 != 3) return "testIf3: test1 fail"
|
||||
|
||||
val test2 = if3({it}, 2, 2, 3)
|
||||
if (test2 != 2) return "testIf3: test 2 fail"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals("OK", testIf1())
|
||||
assertEquals("OK", testIf2())
|
||||
assertEquals("OK", testIf3())
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: multiplyNoInline
|
||||
|
||||
internal inline fun multiply(a: Int, b: Int): Int {
|
||||
return a * b
|
||||
}
|
||||
|
||||
internal fun multiplyNoInline(a: Int, b: Int): Int {
|
||||
var c = a - 1
|
||||
var d = b - 1
|
||||
return (c++) + (d++) + multiply(c, d) - (--c + --d)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(0, multiplyNoInline(1, 0))
|
||||
assertEquals(1, multiplyNoInline(1, 1))
|
||||
assertEquals(2, multiplyNoInline(1, 2))
|
||||
assertEquals(6, multiplyNoInline(2, 3))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: doNothing1
|
||||
// CHECK_CONTAINS_NO_CALLS: doNothing2
|
||||
// CHECK_CONTAINS_NO_CALLS: doNothing3
|
||||
|
||||
internal class Inline {
|
||||
public inline fun <T> identity1 (x: T): T {
|
||||
return x
|
||||
}
|
||||
|
||||
public inline fun <T> identity2 (x: T, f: (T) -> T): T {
|
||||
return f(x)
|
||||
}
|
||||
|
||||
public inline fun <T> identity3 (f: () -> T): T {
|
||||
return f()
|
||||
}
|
||||
}
|
||||
|
||||
internal fun doNothing1 (inline1: Inline, a: Int): Int {
|
||||
return inline1.identity1(a)
|
||||
}
|
||||
|
||||
internal fun doNothing2 (inline2: Inline, a: Int): Int {
|
||||
return inline2.identity2(a, {it})
|
||||
}
|
||||
|
||||
internal fun doNothing3 (inline3: Inline): Int {
|
||||
return inline3.identity3({11})
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val inline = Inline()
|
||||
assertEquals(1, doNothing1(inline, 1))
|
||||
assertEquals(2, doNothing1(inline, 2))
|
||||
assertEquals(3, doNothing2(inline, 3))
|
||||
assertEquals(4, doNothing2(inline, 4))
|
||||
assertEquals(11, doNothing3(inline))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: sumEven
|
||||
|
||||
internal inline fun filteredReduce(a: Array<Int>, predicate: (Int) -> Boolean, reduceFun: (Int, Int) -> Int): Int {
|
||||
var result = 0
|
||||
|
||||
for (element in a) {
|
||||
val satisfyPred = predicate(element)
|
||||
if (satisfyPred) {
|
||||
result = reduceFun(result, element)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
internal fun sumEven(a: Array<Int>): Int {
|
||||
return filteredReduce(a, { x -> x % 2 == 0}, { x, y -> x + y})
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(0, sumEven(arrayOf()))
|
||||
assertEquals(6, sumEven(arrayOf(1,2,3,4)))
|
||||
assertEquals(12, sumEven(arrayOf(1,2,3,4,6,7,9)))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: maxBySquare
|
||||
|
||||
internal data class Result(var value: Int = 0, var invocationCount: Int = 0)
|
||||
|
||||
internal inline fun maxBy(a: Array<Int>, keyFun: (Int) -> Int): Int {
|
||||
var maxVal = a[0]
|
||||
var maxKey = keyFun(maxVal)
|
||||
|
||||
for (element in a) {
|
||||
val key = keyFun(element)
|
||||
|
||||
if (key > maxKey) {
|
||||
maxVal = element
|
||||
maxKey = key
|
||||
}
|
||||
}
|
||||
|
||||
return maxVal
|
||||
}
|
||||
|
||||
internal fun maxBySquare(a: Array<Int>, r: Result): Result {
|
||||
var invocationCount = 0
|
||||
val maxVal = maxBy(a, { x -> invocationCount++; x * x;})
|
||||
|
||||
r.value = maxVal
|
||||
r.invocationCount = invocationCount
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var r1 = maxBySquare(arrayOf(1,2,3,4,5), Result())
|
||||
assertEquals(Result(5, 6), r1)
|
||||
|
||||
var r2 = maxBySquare(arrayOf(-5,1,2,3,4), Result())
|
||||
assertEquals(Result(-5, 6), r2)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: add
|
||||
|
||||
internal data class IntPair(public var fst: Int, public var snd: Int) {
|
||||
inline public fun getFst(): Int { return fst }
|
||||
inline public fun setFst(v: Int) { fst = v }
|
||||
|
||||
inline public fun getSnd(): Int { return this.snd }
|
||||
inline public fun setSnd(v: Int) { this.snd = v }
|
||||
}
|
||||
|
||||
internal fun add(p: IntPair, toFst: Int, toSnd: Int) {
|
||||
val fst = p.getFst()
|
||||
p.setFst(fst + toFst)
|
||||
|
||||
val snd = p.getSnd()
|
||||
p.setSnd(snd + toSnd)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val p = IntPair(0, 0)
|
||||
add(p, 1, 2)
|
||||
assertEquals(IntPair(1, 2), p)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: factAbsNoInline1
|
||||
|
||||
internal class State(value: Int) {
|
||||
public var value: Int = value
|
||||
}
|
||||
|
||||
internal inline fun multiply(state: State, factor: Int) {
|
||||
state.value *= factor
|
||||
}
|
||||
|
||||
internal inline fun abs(state: State) {
|
||||
val value = state.value
|
||||
if (value < 0) {
|
||||
multiply(state, -1)
|
||||
}
|
||||
}
|
||||
|
||||
internal inline fun factAbs(state: State) {
|
||||
abs(state)
|
||||
|
||||
if (state.value == 0) {
|
||||
state.value = 1
|
||||
return
|
||||
}
|
||||
|
||||
var n = state.value
|
||||
while (n > 1) {
|
||||
n--
|
||||
multiply(state, n)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun factAbsNoInline1(state: State): Int {
|
||||
factAbs(state)
|
||||
return state.value
|
||||
}
|
||||
|
||||
internal fun factAbsNoInline2(n: Int): Int {
|
||||
return factAbsNoInline1(State(n))
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(1, factAbsNoInline2(0))
|
||||
assertEquals(2, factAbsNoInline2(2))
|
||||
assertEquals(6, factAbsNoInline2(-3))
|
||||
assertEquals(120, factAbsNoInline2(5))
|
||||
assertEquals(720, factAbsNoInline2(-6))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package foo
|
||||
|
||||
// CHECK_FUNCTIONS_HAVE_SAME_LINES: declaredBefore declaredAfter match=(h|g)1 replace=$1
|
||||
|
||||
fun declaredBefore(): Int {
|
||||
val a = g() + h()
|
||||
return a
|
||||
}
|
||||
|
||||
inline fun g(): Int {
|
||||
val a = h()
|
||||
return a
|
||||
}
|
||||
|
||||
inline fun h(): Int {
|
||||
val a = 1
|
||||
return a
|
||||
}
|
||||
|
||||
inline fun g1(): Int {
|
||||
val a = h1()
|
||||
return a
|
||||
}
|
||||
|
||||
inline fun h1(): Int {
|
||||
val a = 1
|
||||
return a
|
||||
}
|
||||
|
||||
fun declaredAfter(): Int {
|
||||
val a = g1() + h1()
|
||||
return a
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(declaredBefore(), declaredAfter())
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package foo
|
||||
|
||||
// CHECK_NOT_CALLED: sum
|
||||
|
||||
inline fun sum(a: Int, b: Int): Int {
|
||||
return a + b
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val sum3 = sum(1, 2)
|
||||
assertEquals(3, sum3)
|
||||
|
||||
val sum6 = sum(sum3, 3)
|
||||
assertEquals(6, sum6)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package foo
|
||||
|
||||
inline fun<T> with1(value: T, p: T.() -> Unit) = value.p()
|
||||
|
||||
class A(val expected: String) {
|
||||
val b = B()
|
||||
|
||||
fun foo(): A {
|
||||
with1(b) {
|
||||
y = expected
|
||||
}
|
||||
return this
|
||||
}
|
||||
}
|
||||
class B() {
|
||||
var y = ""
|
||||
}
|
||||
|
||||
fun box() = A("OK").foo().b.y
|
||||
@@ -0,0 +1,12 @@
|
||||
package foo
|
||||
|
||||
inline fun bar(f: () -> Int): Array<Int> = arrayOf(f())
|
||||
|
||||
fun box(): String {
|
||||
val iterator = bar { 23 }.iterator()
|
||||
assertEquals(true, iterator.hasNext())
|
||||
assertEquals(23, iterator.next())
|
||||
assertEquals(false, iterator.hasNext())
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test
|
||||
|
||||
internal inline fun sum(x: Int, y: Int): Int = js("x + y")
|
||||
|
||||
internal fun test(x: Int, y: Int): Int = sum(sum(x, x), sum(y, y))
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(4, test(1, 1))
|
||||
assertEquals(8, test(1, 3))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test
|
||||
|
||||
internal inline fun sum(x: Int, y: Int): Int = js("var a = x; a + y")
|
||||
|
||||
internal fun test(x: Int, y: Int): Int {
|
||||
val xx = sum(x, x)
|
||||
js("var a = 0;")
|
||||
val yy = sum(y, y)
|
||||
|
||||
return sum(xx, yy)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(4, test(1, 1))
|
||||
assertEquals(8, test(1, 3))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CALLED_IN_SCOPE: scope=multiplyBy2 function=multiplyBy2$f
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: scope=multiplyBy2 function=multiplyBy2$f_0
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: scope=multiplyBy2 function=run
|
||||
|
||||
internal inline fun <T> runLambdaInLambda(noinline inner: (T) -> T, outer: ((T) -> T, T) -> T, arg: T): T {
|
||||
return outer(inner, arg)
|
||||
}
|
||||
|
||||
internal fun multiplyBy2(x: Int): Int {
|
||||
return runLambdaInLambda({ it * 2 }, { f, x -> f(x) }, x)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(0, multiplyBy2(0))
|
||||
assertEquals(4, multiplyBy2(2))
|
||||
assertEquals(8, multiplyBy2(4))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package foo
|
||||
|
||||
inline fun run(func: () -> Int): Int {
|
||||
return func()
|
||||
}
|
||||
|
||||
fun bar(): Int {
|
||||
var f = { -> 0 }
|
||||
var get0 = f
|
||||
|
||||
f = { -> 1 }
|
||||
var get1 = f
|
||||
|
||||
var get2 = get1
|
||||
f = { -> 2 }
|
||||
get2 = f
|
||||
|
||||
return run(get0) + run(get1) + run(get2)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(3, bar())
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package foo
|
||||
|
||||
data class IntPair(public var fst: Int, public var snd: Int)
|
||||
|
||||
inline fun run(func: () -> Int): Int {
|
||||
return func()
|
||||
}
|
||||
|
||||
fun bar(p: IntPair): Int {
|
||||
var f = { -> p.fst++ }
|
||||
var get0 = f
|
||||
|
||||
f = { -> ++p.snd }
|
||||
var get1 = f
|
||||
|
||||
var get2 = get1
|
||||
f = { -> ++p.fst }
|
||||
get2 = f
|
||||
|
||||
return run(get0) + run(get1) + run(get2)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val p = IntPair(0, 0)
|
||||
assertEquals(3, bar(p))
|
||||
assertEquals(IntPair(2, 1), p)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: capturedInLambda
|
||||
// CHECK_CONTAINS_NO_CALLS: declaredInLambda
|
||||
|
||||
internal data class State(var count: Int = 0)
|
||||
|
||||
internal inline fun repeatAction(times: Int, action: () -> Unit) {
|
||||
for (i in 1..times) {
|
||||
action()
|
||||
}
|
||||
}
|
||||
|
||||
internal fun capturedInLambda(state: State, a: Int, b: Int): Int {
|
||||
inline fun State.inc() {
|
||||
count++
|
||||
}
|
||||
|
||||
repeatAction(a + b) {
|
||||
state.inc()
|
||||
}
|
||||
|
||||
return state.count
|
||||
}
|
||||
|
||||
|
||||
internal fun declaredInLambda(state: State, a: Int, b: Int): Int {
|
||||
repeatAction(a) {
|
||||
inline fun State.inc() {
|
||||
count++
|
||||
}
|
||||
|
||||
repeatAction(b) {
|
||||
state.inc()
|
||||
}
|
||||
}
|
||||
|
||||
return state.count
|
||||
}
|
||||
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(3, capturedInLambda(State(), 1, 2), "capturedInLambda")
|
||||
assertEquals(9, capturedInLambda(State(), 4, 5), "capturedInLambda")
|
||||
|
||||
assertEquals(2, declaredInLambda(State(), 1, 2), "declaredInLambda")
|
||||
assertEquals(20, declaredInLambda(State(), 4, 5), "declaredInLambda")
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: localWithCapture
|
||||
// CHECK_CONTAINS_NO_CALLS: localWithoutCapture
|
||||
|
||||
internal inline fun repeatAction(times: Int, action: () -> Unit) {
|
||||
for (i in 1..times) {
|
||||
action()
|
||||
}
|
||||
}
|
||||
|
||||
internal fun localWithoutCapture(a: Int, b: Int): Int {
|
||||
var sum = 0
|
||||
|
||||
inline fun inc(x: Int): Int {
|
||||
return x + 1
|
||||
}
|
||||
|
||||
repeatAction(a + b) {
|
||||
sum = inc(sum)
|
||||
}
|
||||
|
||||
return sum
|
||||
}
|
||||
|
||||
internal fun localWithCapture(a: Int, b: Int): Int {
|
||||
var sum = 0
|
||||
|
||||
inline fun inc() {
|
||||
sum++
|
||||
}
|
||||
|
||||
repeatAction(a + b) {
|
||||
inc()
|
||||
}
|
||||
|
||||
return sum
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(3, localWithoutCapture(1, 2), "localWithoutCapture")
|
||||
assertEquals(9, localWithoutCapture(4, 5), "localWithoutCapture")
|
||||
|
||||
assertEquals(3, localWithCapture(1, 2), "localWithCapture")
|
||||
assertEquals(9, localWithCapture(4, 5), "localWithCapture")
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: add
|
||||
|
||||
internal data class State(var count: Int = 0)
|
||||
|
||||
internal inline fun repeatAction(times: Int, action: () -> Unit) {
|
||||
for (i in 1..times) {
|
||||
action()
|
||||
}
|
||||
}
|
||||
|
||||
internal fun add(state: State, a: Int, b: Int): Int {
|
||||
inline fun inc(a: Int): Int {
|
||||
return a + 1
|
||||
}
|
||||
|
||||
inline fun inc1(a: Int): Int {
|
||||
return inc(a)
|
||||
}
|
||||
|
||||
repeatAction(a) {
|
||||
inline fun inc2(a: Int): Int {
|
||||
return inc1(a)
|
||||
}
|
||||
|
||||
repeatAction(b) {
|
||||
inline fun State.inc() {
|
||||
count = inc2(count)
|
||||
}
|
||||
|
||||
state.inc()
|
||||
}
|
||||
}
|
||||
|
||||
return state.count
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(20, add(State(), 4, 5))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: localWithCapture
|
||||
// CHECK_CONTAINS_NO_CALLS: localWithoutCapture
|
||||
|
||||
internal inline fun repeatAction(times: Int, action: () -> Unit) {
|
||||
for (i in 1..times) {
|
||||
action()
|
||||
}
|
||||
}
|
||||
|
||||
internal fun localWithoutCapture(a: Int, b: Int): Int {
|
||||
var mult = 0
|
||||
|
||||
repeatAction(a) {
|
||||
inline fun inc(x: Int): Int {
|
||||
return x + 1
|
||||
}
|
||||
|
||||
repeatAction(b) {
|
||||
mult = inc(mult)
|
||||
}
|
||||
}
|
||||
|
||||
return mult
|
||||
}
|
||||
|
||||
internal fun localWithCapture(a: Int, b: Int): Int {
|
||||
var mult = 0
|
||||
|
||||
repeatAction(a) {
|
||||
inline fun inc() {
|
||||
mult++
|
||||
}
|
||||
|
||||
repeatAction(b) {
|
||||
inc()
|
||||
}
|
||||
}
|
||||
|
||||
return mult
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(2, localWithoutCapture(1, 2), "localWithoutCapture")
|
||||
assertEquals(20, localWithoutCapture(4, 5), "localWithoutCapture")
|
||||
|
||||
assertEquals(2, localWithCapture(1, 2), "localWithCapture")
|
||||
assertEquals(20, localWithCapture(4, 5), "localWithCapture")
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: add
|
||||
|
||||
internal inline fun run(action: () -> Int): Int {
|
||||
return action()
|
||||
}
|
||||
|
||||
internal fun add(a: Int, b: Int): Int {
|
||||
var sum = a + b
|
||||
|
||||
inline fun getSum(): Int {
|
||||
return sum
|
||||
}
|
||||
|
||||
return run {
|
||||
var sum = 0
|
||||
|
||||
run {
|
||||
sum = -1
|
||||
getSum()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(3, add(1, 2))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package foo
|
||||
|
||||
fun multiplyBy(a: Int): (Int) -> Int {
|
||||
inline fun multiply(b: Int): Int = a * b
|
||||
|
||||
return ::multiply
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(6, multiplyBy(2)(3))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test1
|
||||
// CHECK_CONTAINS_NO_CALLS: test2
|
||||
// CHECK_CONTAINS_NO_CALLS: test3
|
||||
// CHECK_CONTAINS_NO_CALLS: test4_buocd8$
|
||||
// CHECK_CONTAINS_NO_CALLS: test5
|
||||
// CHECK_HAS_INLINE_METADATA: apply_hiyix$
|
||||
// CHECK_HAS_INLINE_METADATA: applyL_hiyix$
|
||||
// CHECK_HAS_INLINE_METADATA: applyM_hiyix$
|
||||
// CHECK_HAS_NO_INLINE_METADATA: applyN
|
||||
// CHECK_HAS_NO_INLINE_METADATA: applyO_hiyix$
|
||||
|
||||
inline
|
||||
public fun <T> apply(arg: T, func: (T)->T): T = func(arg)
|
||||
|
||||
public open class L {
|
||||
inline
|
||||
protected fun <T> applyL(arg: T, func: (T)->T): T = func(arg)
|
||||
fun test4(l: L, x: Int, y: Int): Int = l.applyL(x) { it * y }
|
||||
}
|
||||
|
||||
public class M {
|
||||
inline
|
||||
public fun <T> applyM(arg: T, func: (T)->T): T = func(arg)
|
||||
}
|
||||
|
||||
internal class N {
|
||||
inline
|
||||
public fun <T> applyN(arg: T, func: (T)->T): T = func(arg)
|
||||
}
|
||||
|
||||
private object O {
|
||||
public object OInner {
|
||||
inline
|
||||
public fun <T> applyO(arg: T, func: (T)->T): T = func(arg)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun test1(x: Int, y: Int): Int = apply(x) { it * y }
|
||||
|
||||
internal fun test2(m: M, x: Int, y: Int): Int = m.applyM(x) { it * y }
|
||||
|
||||
internal fun test3(n: N, x: Int, y: Int): Int = n.applyN(x) { it * y }
|
||||
|
||||
internal fun test5(x: Int, y: Int): Int = O.OInner.applyO(x) { it * y }
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(6, test1(2, 3))
|
||||
assertEquals(20, test1(5, 4))
|
||||
|
||||
assertEquals(6, test2(M(), 2, 3))
|
||||
assertEquals(20, test2(M(), 5, 4))
|
||||
|
||||
assertEquals(6, test3(N(), 2, 3))
|
||||
assertEquals(20, test3(N(), 5, 4))
|
||||
|
||||
assertEquals(6, L().test4(L(), 2, 3))
|
||||
assertEquals(20, L().test4(L(), 5, 4))
|
||||
|
||||
assertEquals(6, test5(2, 3))
|
||||
assertEquals(20, test5(5, 4))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package foo
|
||||
|
||||
// CHECK_NOT_CALLED: component1
|
||||
// CHECK_NOT_CALLED: component2
|
||||
|
||||
class A(val a: Int, val b: Int)
|
||||
|
||||
inline operator fun A.component1(): Int = a
|
||||
inline operator fun A.component2(): Int = b
|
||||
|
||||
fun box(): String {
|
||||
val (a, b) = A(1, 2)
|
||||
assertEquals(1, a)
|
||||
assertEquals(2, b)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CALLED_IN_SCOPE: scope=multiplyBy2 function=multiplyBy2$f
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: scope=multiplyBy2 function=run
|
||||
|
||||
internal inline fun <T> run(noinline func: (T) -> T, arg: T): T {
|
||||
return func(arg)
|
||||
}
|
||||
|
||||
internal fun multiplyBy2(x: Int): Int {
|
||||
return run({ it * 2 }, x)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(0, multiplyBy2(0))
|
||||
assertEquals(4, multiplyBy2(2))
|
||||
assertEquals(8, multiplyBy2(4))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copy of JVM-backend test
|
||||
* Found at: compiler/testData/codegen/boxInline/simple/params.1.kt
|
||||
*/
|
||||
|
||||
package foo
|
||||
|
||||
class Inline() {
|
||||
|
||||
inline fun foo1Int(s : (l: Int) -> Int, param: Int) : Int {
|
||||
return s(param)
|
||||
}
|
||||
|
||||
inline fun foo1Double(param: Double, s : (l: Double) -> Double) : Double {
|
||||
return s(param)
|
||||
}
|
||||
|
||||
inline fun foo2Param(param1: Double, s : (i: Int, l: Double) -> Double, param2: Int) : Double {
|
||||
return s(param2, param1)
|
||||
}
|
||||
}
|
||||
|
||||
fun test1(): Int {
|
||||
val inlineX = Inline()
|
||||
return inlineX.foo1Int({ z: Int -> z}, 25)
|
||||
}
|
||||
|
||||
fun test2(): Double {
|
||||
val inlineX = Inline()
|
||||
return inlineX.foo1Double(25.0, { z: Double -> z})
|
||||
}
|
||||
|
||||
fun test3(): Double {
|
||||
val inlineX = Inline()
|
||||
return inlineX.foo2Param(15.0, { z1: Int, z2: Double -> z1 + z2}, 10)
|
||||
}
|
||||
|
||||
fun test3WithCaptured(): Double {
|
||||
val inlineX = Inline()
|
||||
var c = 11.0;
|
||||
return inlineX.foo2Param(15.0, { z1: Int, z2: Double -> z1 + z2 + c}, 10)
|
||||
}
|
||||
|
||||
|
||||
fun box(): String {
|
||||
if (test1() != 25) return "test1: ${test1()}"
|
||||
if (test2() != 25.0) return "test2: ${test2()}"
|
||||
if (test3() != 25.0) return "test3: ${test3()}"
|
||||
if (test3WithCaptured() != 36.0) return "test3WithCaptured: ${test3WithCaptured()}"
|
||||
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copy of JVM-backend test
|
||||
* Found at: compiler/testData/codegen/boxInline/simple/rootConstructor.1.kt
|
||||
*/
|
||||
|
||||
package foo
|
||||
|
||||
|
||||
inline fun <R> doWork(crossinline job: ()-> R) : R {
|
||||
return notInline({job()})
|
||||
}
|
||||
|
||||
fun <R> notInline(job: ()-> R) : R {
|
||||
return job()
|
||||
}
|
||||
|
||||
val s = doWork({11})
|
||||
|
||||
fun box(): String {
|
||||
if (s != 11) return "test1: ${s}"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: sum
|
||||
|
||||
inline fun <T : Any, R> T.doLet(f: (T) -> R): R = f(this)
|
||||
|
||||
private fun sum(x: Int?, y: Int): Int =
|
||||
x?.doLet { it + y } ?: 0
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(5, sum(2, 3))
|
||||
assertEquals(0, sum(null, 3))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copy of JVM-backend test
|
||||
* Found at: compiler/testData/codegen/boxInline/simple/severalClosures.1.kt
|
||||
*/
|
||||
|
||||
package foo
|
||||
|
||||
class Inline() {
|
||||
|
||||
inline fun foo1(closure1 : (l: Int) -> Int, param1: Int, closure2 : (l: Double) -> Double, param2: Double) : Double {
|
||||
return closure1(param1) + closure2(param2)
|
||||
}
|
||||
|
||||
inline fun foo2(closure1 : (Int, Int) -> Int, param1: Int, closure2 : (Double, Int, Int) -> Double, param2: Double, param3: Int) : Double {
|
||||
return closure1(param1, param3) + closure2(param2, param1, param3)
|
||||
}
|
||||
}
|
||||
|
||||
fun test1(): Double {
|
||||
val inlineX = Inline()
|
||||
return inlineX.foo1({ z: Int -> z}, 25, { z: Double -> z}, 11.5)
|
||||
}
|
||||
|
||||
fun test1WithCaptured(): Double {
|
||||
val inlineX = Inline()
|
||||
var d = 0.0;
|
||||
return inlineX.foo1({ z: Int -> d = 1.0; z}, 25, { z: Double -> z + d}, 11.5)
|
||||
}
|
||||
|
||||
fun test2(): Double {
|
||||
val inlineX = Inline()
|
||||
return inlineX.foo2({ z: Int, p: Int -> z + p}, 25, { x: Double, y: Int, z: Int -> z + x + y}, 11.5, 2)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
if (test1() != 36.5) return "test1: ${test1()}"
|
||||
if (test1WithCaptured() != 37.5) return "test1WithCaptured: ${test1WithCaptured()}"
|
||||
if (test2() != 65.5) return "test2: ${test2()}"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copy of JVM-backend test
|
||||
* Found at: compiler/testData/codegen/boxInline/simple/severalUsage.1.kt
|
||||
*/
|
||||
|
||||
package foo
|
||||
|
||||
public inline fun <R> runTest(f: () -> R): R {
|
||||
return f()
|
||||
}
|
||||
|
||||
public inline fun <R> minByTest(f: (Int) -> R): R {
|
||||
var minValue = f(1)
|
||||
val v = f(1)
|
||||
return v
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val result = runTest{minByTest<Int> { it }}
|
||||
|
||||
if (result != 1) return "test1: ${result}"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copy of JVM-backend test
|
||||
* Found at: compiler/testData/codegen/boxInline/simple/simpleDouble.1.kt
|
||||
*/
|
||||
|
||||
package foo
|
||||
|
||||
class InlineDouble(val res : Double) {
|
||||
|
||||
inline fun foo(s : () -> Double) : Double {
|
||||
val f = "fooStart"
|
||||
val z = s()
|
||||
return z
|
||||
}
|
||||
|
||||
inline fun foo11(s : (l: Double) -> Double) : Double {
|
||||
return s(11.0)
|
||||
}
|
||||
|
||||
inline fun fooRes(s : (l: Double) -> Double) : Double {
|
||||
val z = s(res)
|
||||
return z
|
||||
}
|
||||
|
||||
inline fun fooRes2(s : (l: Double, t: Double) -> Double) : Double {
|
||||
val f = "fooRes2Start"
|
||||
val z = s(1.0, 11.0)
|
||||
return z
|
||||
}
|
||||
}
|
||||
|
||||
fun test0Param(): Double {
|
||||
val inlineX = InlineDouble(10.0)
|
||||
return inlineX.foo({ -> 1.0})
|
||||
}
|
||||
|
||||
fun test1Param(): Double {
|
||||
val inlineX = InlineDouble(10.0)
|
||||
return inlineX.foo11({ z: Double -> z})
|
||||
}
|
||||
|
||||
fun test1ParamCaptured(): Double {
|
||||
val s = 100.0
|
||||
val inlineX = InlineDouble(10.0)
|
||||
return inlineX.foo11({ z: Double -> s})
|
||||
}
|
||||
|
||||
fun test1ParamMissed() : Double {
|
||||
val inlineX = InlineDouble(10.0)
|
||||
return inlineX.foo11({ z: Double -> 111.0})
|
||||
}
|
||||
|
||||
fun test1ParamFromCallContext() : Double {
|
||||
val inlineX = InlineDouble(1000.0)
|
||||
return inlineX.fooRes({ z: Double -> z})
|
||||
}
|
||||
|
||||
fun test2Params() : Double {
|
||||
val inlineX = InlineDouble(1000.0)
|
||||
return inlineX.fooRes2({ y: Double, z: Double -> 2.0 * y + 3.0 * z})
|
||||
}
|
||||
|
||||
fun test2ParamsWithCaptured() : Double {
|
||||
val inlineX = InlineDouble(1000.0)
|
||||
val s = 9.0
|
||||
var t = 1.0
|
||||
return inlineX.fooRes2({ y: Double, z: Double -> 2.0 * s + t})
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
if (test0Param() != 1.0) return "test0Param"
|
||||
if (test1Param() != 11.0) return "test1Param()"
|
||||
if (test1ParamCaptured() != 100.0) return "testtest1ParamCaptured()"
|
||||
if (test1ParamMissed() != 111.0) return "test1ParamMissed()"
|
||||
if (test1ParamFromCallContext() != 1000.0) return "test1ParamFromCallContext()"
|
||||
if (test2Params() != 35.0) return "test2Params()"
|
||||
if (test2ParamsWithCaptured() != 19.0) return "test2ParamsWithCaptured()"
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copy of JVM-backend test
|
||||
* Found at: compiler/testData/codegen/boxInline/simple/simpleEnum.1.kt
|
||||
*/
|
||||
|
||||
package foo
|
||||
|
||||
enum class MyEnum {
|
||||
K;
|
||||
|
||||
//TODO: KT-4693
|
||||
inline fun <T> doSmth(a: T) : String {
|
||||
return a.toString() + K.name
|
||||
}
|
||||
}
|
||||
|
||||
fun test1(): String {
|
||||
return MyEnum.K.doSmth("O")
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val result = test1()
|
||||
if (result != "OK") return "fail1: ${result}"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copy of JVM-backend test
|
||||
* Found at: compiler/testData/codegen/boxInline/simple/simpleInt.1.kt
|
||||
*/
|
||||
|
||||
package foo
|
||||
|
||||
class Inline(val res : Int) {
|
||||
|
||||
inline fun foo(s : () -> Int) : Int {
|
||||
val f = "fooStart"
|
||||
val z = s()
|
||||
return z
|
||||
}
|
||||
|
||||
inline fun foo11(s : (l: Int) -> Int) : Int {
|
||||
return s(11)
|
||||
}
|
||||
|
||||
inline fun fooRes(s : (l: Int) -> Int) : Int {
|
||||
val z = s(res)
|
||||
return z
|
||||
}
|
||||
|
||||
inline fun fooRes2(s : (l: Int, t: Int) -> Int) : Int {
|
||||
val f = "fooRes2Start"
|
||||
val z = s(1, 11)
|
||||
return z
|
||||
}
|
||||
}
|
||||
|
||||
fun test0Param(): Int {
|
||||
val inlineX = Inline(10)
|
||||
return inlineX.foo({ -> 1})
|
||||
}
|
||||
|
||||
fun test1Param(): Int {
|
||||
val inlineX = Inline(10)
|
||||
return inlineX.foo11({ z: Int -> z})
|
||||
}
|
||||
|
||||
fun test1ParamCaptured(): Int {
|
||||
val s = 100
|
||||
val inlineX = Inline(10)
|
||||
return inlineX.foo11({ z: Int -> s})
|
||||
}
|
||||
|
||||
fun test1ParamMissed() : Int {
|
||||
val inlineX = Inline(10)
|
||||
return inlineX.foo11({ z: Int -> 111})
|
||||
}
|
||||
|
||||
fun test1ParamFromCallContext() : Int {
|
||||
val inlineX = Inline(1000)
|
||||
return inlineX.fooRes({ z: Int -> z})
|
||||
}
|
||||
|
||||
fun test2Params() : Int {
|
||||
val inlineX = Inline(1000)
|
||||
return inlineX.fooRes2({ y: Int, z: Int -> 2 * y + 3 * z})
|
||||
}
|
||||
|
||||
fun test2ParamsWithCaptured() : Int {
|
||||
val inlineX = Inline(1000)
|
||||
val s = 9
|
||||
var t = 1
|
||||
return inlineX.fooRes2({ y: Int, z: Int -> 2 * s + t})
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
if (test0Param() != 1) return "test0Param: ${test0Param()}"
|
||||
if (test1Param() != 11) return "test1Param: ${test1Param()}"
|
||||
if (test1ParamCaptured() != 100) return "test1ParamCaptured: ${test1ParamCaptured()}"
|
||||
if (test1ParamMissed() != 111) return "test1ParamMissed: ${test1ParamMissed()}"
|
||||
if (test1ParamFromCallContext() != 1000) return "test1ParamFromCallContext: ${test1ParamFromCallContext()}"
|
||||
if (test2Params() != 35) return "test2Params: ${test2Params()}"
|
||||
if (test2ParamsWithCaptured() != 19) return "test2ParamsWithCaptured: ${test2ParamsWithCaptured()}"
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copy of JVM-backend test
|
||||
* Found at: compiler/testData/codegen/boxInline/simple/simpleLambda.1.kt
|
||||
*/
|
||||
|
||||
package foo
|
||||
|
||||
public class Data()
|
||||
|
||||
public inline fun <T, R> T.use(block: (T)-> R) : R {
|
||||
return block(this)
|
||||
}
|
||||
|
||||
public inline fun use2() : Int {
|
||||
val s = 100
|
||||
return s
|
||||
}
|
||||
|
||||
class Z {}
|
||||
|
||||
fun test1() : Int {
|
||||
val input = Z()
|
||||
return input.use<Z, Int>{
|
||||
100
|
||||
}
|
||||
}
|
||||
|
||||
fun test2() : Int {
|
||||
val x = 1000
|
||||
return use2() + x
|
||||
}
|
||||
|
||||
|
||||
fun box(): String {
|
||||
if (test1() != 100) return "test1: ${test1()}"
|
||||
if (test2() != 1100) return "test1: ${test2()}"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copy of JVM-backend test
|
||||
* Found at: compiler/testData/codegen/boxInline/simple/simpleObject.1.kt
|
||||
*/
|
||||
|
||||
package foo
|
||||
|
||||
class InlineString(val res : String) {
|
||||
|
||||
inline fun foo(s : () -> String) : String {
|
||||
val f = "fooStart"
|
||||
val z = s()
|
||||
return z
|
||||
}
|
||||
|
||||
inline fun foo11(s : (l: String) -> String) : String {
|
||||
return s("11")
|
||||
}
|
||||
|
||||
inline fun fooRes(s : (l: String) -> String) : String {
|
||||
val z = s(res)
|
||||
return z
|
||||
}
|
||||
|
||||
inline fun fooRes2(s : (l: String, t: String) -> String) : String {
|
||||
val f = "fooRes2Start"
|
||||
val z = s("1", "11")
|
||||
return z
|
||||
}
|
||||
}
|
||||
|
||||
fun test0Param(): String {
|
||||
val inlineX = InlineString("10")
|
||||
return inlineX.foo({ -> "1"})
|
||||
}
|
||||
|
||||
fun test1Param(): String {
|
||||
val inlineX = InlineString("10")
|
||||
return inlineX.foo11({ z: String -> z})
|
||||
}
|
||||
|
||||
fun test1ParamCaptured(): String {
|
||||
val s = "100"
|
||||
val inlineX = InlineString("10")
|
||||
return inlineX.foo11({ z: String -> s})
|
||||
}
|
||||
|
||||
fun test1ParamMissed() : String {
|
||||
val inlineX = InlineString("10")
|
||||
return inlineX.foo11({ z: String -> "111"})
|
||||
}
|
||||
|
||||
fun test1ParamFromCallContext() : String {
|
||||
val inlineX = InlineString("1000")
|
||||
return inlineX.fooRes({ z: String -> z})
|
||||
}
|
||||
|
||||
fun test2Params() : String {
|
||||
val inlineX = InlineString("1000")
|
||||
return inlineX.fooRes2({ y: String, z: String -> y + "0" + z})
|
||||
}
|
||||
|
||||
fun test2ParamsWithCaptured() : String {
|
||||
val inlineX = InlineString("1000")
|
||||
val s = "9"
|
||||
var t = "1"
|
||||
return inlineX.fooRes2({ y: String, z: String -> s + t})
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
if (test0Param() != "1") return "test0Param: ${test0Param()}"
|
||||
if (test1Param() != "11") return "test1Param: ${test1Param()}"
|
||||
if (test1ParamCaptured() != "100") return "test1ParamCaptured: ${test1ParamCaptured()}"
|
||||
if (test1ParamMissed() != "111") return "test1ParamMissed: ${test1ParamMissed()}"
|
||||
if (test1ParamFromCallContext() != "1000") return "test1ParamFromCallContext: ${test1ParamFromCallContext()}"
|
||||
if (test2Params() != "1011") return "test2Params: ${test2Params()}"
|
||||
if (test2ParamsWithCaptured() != "91") return "test2ParamsWithCaptured: ${test2ParamsWithCaptured()}"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package foo
|
||||
|
||||
var flag = false
|
||||
fun toggle(): Boolean {
|
||||
flag = !flag
|
||||
|
||||
return flag
|
||||
}
|
||||
|
||||
inline fun run(noinline f: () -> Int): Int {
|
||||
return f()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
run({ toggle(); 4 })
|
||||
assertEquals(true, flag)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package foo
|
||||
|
||||
data class State(public var value: Int = 10)
|
||||
|
||||
inline fun withState(state: State, ext: State.() -> Unit) {
|
||||
state.ext()
|
||||
return
|
||||
state.value = 0
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val state = State()
|
||||
|
||||
withState(state) {
|
||||
value = 111
|
||||
}
|
||||
|
||||
assertEquals(111, state.value)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package foo
|
||||
|
||||
class Runner {
|
||||
public fun run(f: () -> Unit): Unit = f()
|
||||
}
|
||||
|
||||
class Counter() {
|
||||
var count = 0
|
||||
val runner = Runner()
|
||||
|
||||
public fun count(n: Int) {
|
||||
for (i in 1..n) {
|
||||
tick()
|
||||
}
|
||||
}
|
||||
|
||||
public fun getCount(): Int = count
|
||||
|
||||
private inline fun tick() {
|
||||
runner.run { count++ }
|
||||
}
|
||||
}
|
||||
|
||||
fun add(a: Int, b: Int): Int {
|
||||
val counter = Counter()
|
||||
counter.count(a)
|
||||
counter.count(b)
|
||||
return counter.getCount()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(3, add(1, 2))
|
||||
assertEquals(7, add(3, 4))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package foo
|
||||
|
||||
class A() {
|
||||
public var param: Int = 0
|
||||
|
||||
inline public fun setParam(value: Int) {
|
||||
val b = B(value)
|
||||
b.setParam(this)
|
||||
}
|
||||
}
|
||||
|
||||
class B(val value: Int) {
|
||||
inline fun setParam(a: A) {
|
||||
a.param = this.value
|
||||
}
|
||||
}
|
||||
|
||||
public fun box(): String {
|
||||
val a = A()
|
||||
a.setParam(10)
|
||||
assertEquals(10, a.param)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package foo
|
||||
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test1
|
||||
// CHECK_CONTAINS_NO_CALLS: test2
|
||||
// CHECK_CONTAINS_NO_CALLS: test3 except=slice
|
||||
|
||||
internal inline fun concat(vararg strings: String): String {
|
||||
var result = ""
|
||||
|
||||
for (string in strings) {
|
||||
result += string
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
internal fun test1(): String {
|
||||
return concat()
|
||||
}
|
||||
|
||||
internal fun test2(): String {
|
||||
return concat("a", "b", "c")
|
||||
}
|
||||
|
||||
internal fun test3(list: Array<String>): String {
|
||||
return concat(*list)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals("", test1())
|
||||
assertEquals("abc", test2())
|
||||
assertEquals("abcd", test3(arrayOf("a", "b", "c", "d")))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Reference in New Issue
Block a user