diff --git a/native/native.tests/testData/caches/ic/addDeleteFile/lib/lib.file1.kt b/native/native.tests/testData/caches/ic/addDeleteFile/lib/lib.file1.kt new file mode 100644 index 00000000000..859b384ad7f --- /dev/null +++ b/native/native.tests/testData/caches/ic/addDeleteFile/lib/lib.file1.kt @@ -0,0 +1 @@ +fun foo() = 42 \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/addDeleteFile/lib/lib.file2.kt b/native/native.tests/testData/caches/ic/addDeleteFile/lib/lib.file2.kt new file mode 100644 index 00000000000..f88d6a28022 --- /dev/null +++ b/native/native.tests/testData/caches/ic/addDeleteFile/lib/lib.file2.kt @@ -0,0 +1 @@ +fun bar() = 117 \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/addDeleteFile/main/main.1.kt b/native/native.tests/testData/caches/ic/addDeleteFile/main/main.1.kt new file mode 100644 index 00000000000..f7e6f22377a --- /dev/null +++ b/native/native.tests/testData/caches/ic/addDeleteFile/main/main.1.kt @@ -0,0 +1,7 @@ +import kotlin.test.* + +@Test +fun runTest() { + assertEquals(42, foo()) + assertEquals(117, bar()) +} \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/addDeleteFile/main/main.kt b/native/native.tests/testData/caches/ic/addDeleteFile/main/main.kt new file mode 100644 index 00000000000..5c9bf773c76 --- /dev/null +++ b/native/native.tests/testData/caches/ic/addDeleteFile/main/main.kt @@ -0,0 +1,4 @@ +import kotlin.test.* + +@Test +fun runTest() = assertEquals(42, foo()) \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/addMethodToInterface1/lib1/lib1.1.kt b/native/native.tests/testData/caches/ic/addMethodToInterface1/lib1/lib1.1.kt new file mode 100644 index 00000000000..3179d70ebc6 --- /dev/null +++ b/native/native.tests/testData/caches/ic/addMethodToInterface1/lib1/lib1.1.kt @@ -0,0 +1,6 @@ +package test1 + +interface I { + fun baz(): String + fun foo(): Int +} \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/addMethodToInterface1/lib1/lib1.kt b/native/native.tests/testData/caches/ic/addMethodToInterface1/lib1/lib1.kt new file mode 100644 index 00000000000..7d3961f17a7 --- /dev/null +++ b/native/native.tests/testData/caches/ic/addMethodToInterface1/lib1/lib1.kt @@ -0,0 +1,5 @@ +package test1 + +interface I { + fun foo(): Int +} \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/addMethodToInterface1/lib2/lib2.kt b/native/native.tests/testData/caches/ic/addMethodToInterface1/lib2/lib2.kt new file mode 100644 index 00000000000..f3a646a76f6 --- /dev/null +++ b/native/native.tests/testData/caches/ic/addMethodToInterface1/lib2/lib2.kt @@ -0,0 +1,5 @@ +package test2 + +import test1.* + +fun bar(x: I) = x.foo() \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/addMethodToInterface1/main/main.1.kt b/native/native.tests/testData/caches/ic/addMethodToInterface1/main/main.1.kt new file mode 100644 index 00000000000..25b51a978f9 --- /dev/null +++ b/native/native.tests/testData/caches/ic/addMethodToInterface1/main/main.1.kt @@ -0,0 +1,13 @@ +import kotlin.test.* +import test1.* +import test2.* + +class IImpl : I { + override fun baz() = "zzz" + override fun foo() = 42 +} + +@Test +fun runTest() { + assertEquals(42, bar(IImpl())) +} \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/addMethodToInterface1/main/main.kt b/native/native.tests/testData/caches/ic/addMethodToInterface1/main/main.kt new file mode 100644 index 00000000000..577db7b81fa --- /dev/null +++ b/native/native.tests/testData/caches/ic/addMethodToInterface1/main/main.kt @@ -0,0 +1,12 @@ +import kotlin.test.* +import test1.* +import test2.* + +class IImpl : I { + override fun foo() = 42 +} + +@Test +fun runTest() { + assertEquals(42, bar(IImpl())) +} \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/addMethodToInterface2/lib1/lib1.file1.1.kt b/native/native.tests/testData/caches/ic/addMethodToInterface2/lib1/lib1.file1.1.kt new file mode 100644 index 00000000000..3179d70ebc6 --- /dev/null +++ b/native/native.tests/testData/caches/ic/addMethodToInterface2/lib1/lib1.file1.1.kt @@ -0,0 +1,6 @@ +package test1 + +interface I { + fun baz(): String + fun foo(): Int +} \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/addMethodToInterface2/lib1/lib1.file1.kt b/native/native.tests/testData/caches/ic/addMethodToInterface2/lib1/lib1.file1.kt new file mode 100644 index 00000000000..7d3961f17a7 --- /dev/null +++ b/native/native.tests/testData/caches/ic/addMethodToInterface2/lib1/lib1.file1.kt @@ -0,0 +1,5 @@ +package test1 + +interface I { + fun foo(): Int +} \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/addMethodToInterface2/lib1/lib1.file2.kt b/native/native.tests/testData/caches/ic/addMethodToInterface2/lib1/lib1.file2.kt new file mode 100644 index 00000000000..2972c841912 --- /dev/null +++ b/native/native.tests/testData/caches/ic/addMethodToInterface2/lib1/lib1.file2.kt @@ -0,0 +1,5 @@ +package test1 + +interface J : I { + fun bar(): String +} \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/addMethodToInterface2/lib2/lib2.kt b/native/native.tests/testData/caches/ic/addMethodToInterface2/lib2/lib2.kt new file mode 100644 index 00000000000..d213b3e2b23 --- /dev/null +++ b/native/native.tests/testData/caches/ic/addMethodToInterface2/lib2/lib2.kt @@ -0,0 +1,5 @@ +package test2 + +import test1.* + +fun bar(x: J) = x.bar() \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/addMethodToInterface2/main/main.1.kt b/native/native.tests/testData/caches/ic/addMethodToInterface2/main/main.1.kt new file mode 100644 index 00000000000..e6f4145d653 --- /dev/null +++ b/native/native.tests/testData/caches/ic/addMethodToInterface2/main/main.1.kt @@ -0,0 +1,14 @@ +import kotlin.test.* +import test1.* +import test2.* + +class JImpl : J { + override fun baz() = "qxx" + override fun foo() = 42 + override fun bar() = "zzz" +} + +@Test +fun runTest() { + assertEquals("zzz", bar(JImpl())) +} \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/addMethodToInterface2/main/main.kt b/native/native.tests/testData/caches/ic/addMethodToInterface2/main/main.kt new file mode 100644 index 00000000000..49424eade32 --- /dev/null +++ b/native/native.tests/testData/caches/ic/addMethodToInterface2/main/main.kt @@ -0,0 +1,13 @@ +import kotlin.test.* +import test1.* +import test2.* + +class JImpl : J { + override fun foo() = 42 + override fun bar() = "zzz" +} + +@Test +fun runTest() { + assertEquals("zzz", bar(JImpl())) +} \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/addMethodToOpenClass1/lib1/lib1.1.kt b/native/native.tests/testData/caches/ic/addMethodToOpenClass1/lib1/lib1.1.kt new file mode 100644 index 00000000000..48799f4b41c --- /dev/null +++ b/native/native.tests/testData/caches/ic/addMethodToOpenClass1/lib1/lib1.1.kt @@ -0,0 +1,6 @@ +package test1 + +open class A { + open fun baz() = "zzz" + open fun foo() = 117 +} \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/addMethodToOpenClass1/lib1/lib1.kt b/native/native.tests/testData/caches/ic/addMethodToOpenClass1/lib1/lib1.kt new file mode 100644 index 00000000000..fec136cb8be --- /dev/null +++ b/native/native.tests/testData/caches/ic/addMethodToOpenClass1/lib1/lib1.kt @@ -0,0 +1,5 @@ +package test1 + +open class A { + open fun foo() = 117 +} \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/addMethodToOpenClass1/lib2/lib2.kt b/native/native.tests/testData/caches/ic/addMethodToOpenClass1/lib2/lib2.kt new file mode 100644 index 00000000000..52485686499 --- /dev/null +++ b/native/native.tests/testData/caches/ic/addMethodToOpenClass1/lib2/lib2.kt @@ -0,0 +1,5 @@ +package test2 + +import test1.* + +fun bar(a: A) = a.foo() \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/addMethodToOpenClass1/main/main.kt b/native/native.tests/testData/caches/ic/addMethodToOpenClass1/main/main.kt new file mode 100644 index 00000000000..1ff28a19efb --- /dev/null +++ b/native/native.tests/testData/caches/ic/addMethodToOpenClass1/main/main.kt @@ -0,0 +1,12 @@ +import kotlin.test.* +import test1.* +import test2.* + +class B : A() { + override fun foo() = 42 +} + +@Test +fun runTest() { + assertEquals(42, bar(B())) +} \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/addMethodToOpenClass2/lib1/lib1.file1.1.kt b/native/native.tests/testData/caches/ic/addMethodToOpenClass2/lib1/lib1.file1.1.kt new file mode 100644 index 00000000000..94f335af63c --- /dev/null +++ b/native/native.tests/testData/caches/ic/addMethodToOpenClass2/lib1/lib1.file1.1.kt @@ -0,0 +1,6 @@ +package test1 + +open class A { + open fun baz() = "qxx" + open fun foo() = 117 +} \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/addMethodToOpenClass2/lib1/lib1.file1.kt b/native/native.tests/testData/caches/ic/addMethodToOpenClass2/lib1/lib1.file1.kt new file mode 100644 index 00000000000..fec136cb8be --- /dev/null +++ b/native/native.tests/testData/caches/ic/addMethodToOpenClass2/lib1/lib1.file1.kt @@ -0,0 +1,5 @@ +package test1 + +open class A { + open fun foo() = 117 +} \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/addMethodToOpenClass2/lib1/lib1.file2.kt b/native/native.tests/testData/caches/ic/addMethodToOpenClass2/lib1/lib1.file2.kt new file mode 100644 index 00000000000..6339265d0ad --- /dev/null +++ b/native/native.tests/testData/caches/ic/addMethodToOpenClass2/lib1/lib1.file2.kt @@ -0,0 +1,5 @@ +package test1 + +open class B : A() { + open fun bar() = "zzz" +} \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/addMethodToOpenClass2/lib2/lib2.kt b/native/native.tests/testData/caches/ic/addMethodToOpenClass2/lib2/lib2.kt new file mode 100644 index 00000000000..129f69c96a7 --- /dev/null +++ b/native/native.tests/testData/caches/ic/addMethodToOpenClass2/lib2/lib2.kt @@ -0,0 +1,5 @@ +package test2 + +import test1.* + +fun bar(b: B) = b.bar() \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/addMethodToOpenClass2/main/main.kt b/native/native.tests/testData/caches/ic/addMethodToOpenClass2/main/main.kt new file mode 100644 index 00000000000..68ee49f8f7d --- /dev/null +++ b/native/native.tests/testData/caches/ic/addMethodToOpenClass2/main/main.kt @@ -0,0 +1,12 @@ +import kotlin.test.* +import test1.* +import test2.* + +class C : B() { + override fun bar() = "qzz" +} + +@Test +fun runTest() { + assertEquals("qzz", bar(C())) +} \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/changeFileIndex/lib/lib.file1.kt b/native/native.tests/testData/caches/ic/changeFileIndex/lib/lib.file1.kt new file mode 100644 index 00000000000..8c7cbc7de5a --- /dev/null +++ b/native/native.tests/testData/caches/ic/changeFileIndex/lib/lib.file1.kt @@ -0,0 +1,5 @@ +inline fun foo(arr: IntArray, transform: (Int) -> Int): Int { + var sum = 0 + for (x in arr) sum += transform(x) + return sum +} \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/changeFileIndex/lib/lib.file2.kt b/native/native.tests/testData/caches/ic/changeFileIndex/lib/lib.file2.kt new file mode 100644 index 00000000000..49f96ae6200 --- /dev/null +++ b/native/native.tests/testData/caches/ic/changeFileIndex/lib/lib.file2.kt @@ -0,0 +1,8 @@ +inline fun bar(arr: IntArray, transform: (Int) -> Int): Int { + var max = Int.MIN_VALUE + for (x in arr) { + val y = transform(x) + if (y > max) max = y + } + return max +} \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/changeFileIndex/main/main.kt b/native/native.tests/testData/caches/ic/changeFileIndex/main/main.kt new file mode 100644 index 00000000000..688459d3213 --- /dev/null +++ b/native/native.tests/testData/caches/ic/changeFileIndex/main/main.kt @@ -0,0 +1,11 @@ +import kotlin.test.* + +@Test +fun checkFoo() { + assertEquals(42, foo(intArrayOf(1, 2, 3, 4, 5, 6)) { it * 2 }) +} + +@Test +fun checkBar() { + assertEquals(42, bar(intArrayOf(1, 3, 7)) { it * 6 }) +} \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/externalDependency/externalLib/file1.kt b/native/native.tests/testData/caches/ic/externalDependency/externalLib/file1.kt new file mode 100644 index 00000000000..8253325fbda --- /dev/null +++ b/native/native.tests/testData/caches/ic/externalDependency/externalLib/file1.kt @@ -0,0 +1,3 @@ +package external + +fun foo() = 42 \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/externalDependency/externalLib/file2.1.kt b/native/native.tests/testData/caches/ic/externalDependency/externalLib/file2.1.kt new file mode 100644 index 00000000000..7872181160c --- /dev/null +++ b/native/native.tests/testData/caches/ic/externalDependency/externalLib/file2.1.kt @@ -0,0 +1,3 @@ +package external + +fun foo2() = 128 \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/externalDependency/externalLib/file2.kt b/native/native.tests/testData/caches/ic/externalDependency/externalLib/file2.kt new file mode 100644 index 00000000000..ef95e0ea0f0 --- /dev/null +++ b/native/native.tests/testData/caches/ic/externalDependency/externalLib/file2.kt @@ -0,0 +1,3 @@ +package external + +fun foo2() = 117 \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/externalDependency/main/main.kt b/native/native.tests/testData/caches/ic/externalDependency/main/main.kt new file mode 100644 index 00000000000..502cd31e988 --- /dev/null +++ b/native/native.tests/testData/caches/ic/externalDependency/main/main.kt @@ -0,0 +1,6 @@ +import kotlin.test.* + +@Test +fun doTest() { + assertEquals(42, bar()) +} \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/externalDependency/main/main2.1.kt b/native/native.tests/testData/caches/ic/externalDependency/main/main2.1.kt new file mode 100644 index 00000000000..f36f38707ba --- /dev/null +++ b/native/native.tests/testData/caches/ic/externalDependency/main/main2.1.kt @@ -0,0 +1,6 @@ +import kotlin.test.* + +@Test +fun doTest2() { + assertEquals(128, bar2()) +} \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/externalDependency/main/main2.kt b/native/native.tests/testData/caches/ic/externalDependency/main/main2.kt new file mode 100644 index 00000000000..2e7a1a0b9bb --- /dev/null +++ b/native/native.tests/testData/caches/ic/externalDependency/main/main2.kt @@ -0,0 +1,6 @@ +import kotlin.test.* + +@Test +fun doTest2() { + assertEquals(117, bar2()) +} \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/externalDependency/userLib/file1.kt b/native/native.tests/testData/caches/ic/externalDependency/userLib/file1.kt new file mode 100644 index 00000000000..701fe0158e7 --- /dev/null +++ b/native/native.tests/testData/caches/ic/externalDependency/userLib/file1.kt @@ -0,0 +1 @@ +fun bar() = external.foo() \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/externalDependency/userLib/file2.kt b/native/native.tests/testData/caches/ic/externalDependency/userLib/file2.kt new file mode 100644 index 00000000000..20869cb15ee --- /dev/null +++ b/native/native.tests/testData/caches/ic/externalDependency/userLib/file2.kt @@ -0,0 +1 @@ +fun bar2() = external.foo2() \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/fileDependencies1/lib/lib.file1.1.kt b/native/native.tests/testData/caches/ic/fileDependencies1/lib/lib.file1.1.kt new file mode 100644 index 00000000000..61631ae6f4d --- /dev/null +++ b/native/native.tests/testData/caches/ic/fileDependencies1/lib/lib.file1.1.kt @@ -0,0 +1,3 @@ +package test + +fun foo() = 20 \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/fileDependencies1/lib/lib.file1.kt b/native/native.tests/testData/caches/ic/fileDependencies1/lib/lib.file1.kt new file mode 100644 index 00000000000..d78e0613902 --- /dev/null +++ b/native/native.tests/testData/caches/ic/fileDependencies1/lib/lib.file1.kt @@ -0,0 +1,3 @@ +package test + +fun foo() = 21 \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/fileDependencies1/lib/lib.file2.kt b/native/native.tests/testData/caches/ic/fileDependencies1/lib/lib.file2.kt new file mode 100644 index 00000000000..b3108d5fbab --- /dev/null +++ b/native/native.tests/testData/caches/ic/fileDependencies1/lib/lib.file2.kt @@ -0,0 +1,3 @@ +package test + +fun bar() = 117 \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/fileDependencies1/lib/lib.file3.kt b/native/native.tests/testData/caches/ic/fileDependencies1/lib/lib.file3.kt new file mode 100644 index 00000000000..fe5bdcb7ff4 --- /dev/null +++ b/native/native.tests/testData/caches/ic/fileDependencies1/lib/lib.file3.kt @@ -0,0 +1,3 @@ +package test + +fun baz() = foo() * 2 \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/fileDependencies1/main/main.1.kt b/native/native.tests/testData/caches/ic/fileDependencies1/main/main.1.kt new file mode 100644 index 00000000000..b5268527823 --- /dev/null +++ b/native/native.tests/testData/caches/ic/fileDependencies1/main/main.1.kt @@ -0,0 +1,8 @@ +import kotlin.test.* +import test.* + +@Test +fun runTest() { + assertEquals(117, bar()) + assertEquals(40, baz()) +} \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/fileDependencies1/main/main.kt b/native/native.tests/testData/caches/ic/fileDependencies1/main/main.kt new file mode 100644 index 00000000000..aad1f1facbe --- /dev/null +++ b/native/native.tests/testData/caches/ic/fileDependencies1/main/main.kt @@ -0,0 +1,8 @@ +import kotlin.test.* +import test.* + +@Test +fun runTest() { + assertEquals(117, bar()) + assertEquals(42, baz()) +} \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/fileDependencies2/lib1/lib1.1.kt b/native/native.tests/testData/caches/ic/fileDependencies2/lib1/lib1.1.kt new file mode 100644 index 00000000000..27b7d050a8b --- /dev/null +++ b/native/native.tests/testData/caches/ic/fileDependencies2/lib1/lib1.1.kt @@ -0,0 +1,3 @@ +package test1 + +fun foo() = 20 \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/fileDependencies2/lib1/lib1.kt b/native/native.tests/testData/caches/ic/fileDependencies2/lib1/lib1.kt new file mode 100644 index 00000000000..60e31080b08 --- /dev/null +++ b/native/native.tests/testData/caches/ic/fileDependencies2/lib1/lib1.kt @@ -0,0 +1,3 @@ +package test1 + +fun foo() = 21 \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/fileDependencies2/lib2/lib2.file1.kt b/native/native.tests/testData/caches/ic/fileDependencies2/lib2/lib2.file1.kt new file mode 100644 index 00000000000..9cf29f59fef --- /dev/null +++ b/native/native.tests/testData/caches/ic/fileDependencies2/lib2/lib2.file1.kt @@ -0,0 +1,3 @@ +package test2 + +fun bar() = 117 \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/fileDependencies2/lib2/lib2.file2.kt b/native/native.tests/testData/caches/ic/fileDependencies2/lib2/lib2.file2.kt new file mode 100644 index 00000000000..c75d1a11c08 --- /dev/null +++ b/native/native.tests/testData/caches/ic/fileDependencies2/lib2/lib2.file2.kt @@ -0,0 +1,5 @@ +package test2 + +import test1.* + +fun baz() = foo() * 2 \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/fileDependencies2/main/main.1.kt b/native/native.tests/testData/caches/ic/fileDependencies2/main/main.1.kt new file mode 100644 index 00000000000..fb10ac7ca1f --- /dev/null +++ b/native/native.tests/testData/caches/ic/fileDependencies2/main/main.1.kt @@ -0,0 +1,9 @@ +import kotlin.test.* +import test1.* +import test2.* + +@Test +fun runTest() { + assertEquals(117, bar()) + assertEquals(40, baz()) +} \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/fileDependencies2/main/main.kt b/native/native.tests/testData/caches/ic/fileDependencies2/main/main.kt new file mode 100644 index 00000000000..d18ca92fb22 --- /dev/null +++ b/native/native.tests/testData/caches/ic/fileDependencies2/main/main.kt @@ -0,0 +1,9 @@ +import kotlin.test.* +import test1.* +import test2.* + +@Test +fun runTest() { + assertEquals(117, bar()) + assertEquals(42, baz()) +} \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/renameFileOrPackage/lib/lib.1.kt b/native/native.tests/testData/caches/ic/renameFileOrPackage/lib/lib.1.kt new file mode 100644 index 00000000000..638729eef10 --- /dev/null +++ b/native/native.tests/testData/caches/ic/renameFileOrPackage/lib/lib.1.kt @@ -0,0 +1,3 @@ +package tezd + +fun foo() = 42 \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/renameFileOrPackage/lib/lib.kt b/native/native.tests/testData/caches/ic/renameFileOrPackage/lib/lib.kt new file mode 100644 index 00000000000..12689fb716b --- /dev/null +++ b/native/native.tests/testData/caches/ic/renameFileOrPackage/lib/lib.kt @@ -0,0 +1,3 @@ +package test + +fun foo() = 42 \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/renameFileOrPackage/main/main.1.kt b/native/native.tests/testData/caches/ic/renameFileOrPackage/main/main.1.kt new file mode 100644 index 00000000000..060d54f476e --- /dev/null +++ b/native/native.tests/testData/caches/ic/renameFileOrPackage/main/main.1.kt @@ -0,0 +1,5 @@ +import kotlin.test.* +import tezd.* + +@Test +fun runTest() = assertEquals(42, foo()) \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/renameFileOrPackage/main/main.kt b/native/native.tests/testData/caches/ic/renameFileOrPackage/main/main.kt new file mode 100644 index 00000000000..061acd0976d --- /dev/null +++ b/native/native.tests/testData/caches/ic/renameFileOrPackage/main/main.kt @@ -0,0 +1,5 @@ +import kotlin.test.* +import test.* + +@Test +fun runTest() = assertEquals(42, foo()) \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/simple/lib/lib.1.kt b/native/native.tests/testData/caches/ic/simple/lib/lib.1.kt new file mode 100644 index 00000000000..3d6f5da9372 --- /dev/null +++ b/native/native.tests/testData/caches/ic/simple/lib/lib.1.kt @@ -0,0 +1 @@ +fun foo() = 41 \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/simple/lib/lib.kt b/native/native.tests/testData/caches/ic/simple/lib/lib.kt new file mode 100644 index 00000000000..859b384ad7f --- /dev/null +++ b/native/native.tests/testData/caches/ic/simple/lib/lib.kt @@ -0,0 +1 @@ +fun foo() = 42 \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/simple/main/main.1.kt b/native/native.tests/testData/caches/ic/simple/main/main.1.kt new file mode 100644 index 00000000000..bdb2717a65f --- /dev/null +++ b/native/native.tests/testData/caches/ic/simple/main/main.1.kt @@ -0,0 +1,4 @@ +import kotlin.test.* + +@Test +fun runTest() = assertEquals(41, foo()) \ No newline at end of file diff --git a/native/native.tests/testData/caches/ic/simple/main/main.kt b/native/native.tests/testData/caches/ic/simple/main/main.kt new file mode 100644 index 00000000000..5c9bf773c76 --- /dev/null +++ b/native/native.tests/testData/caches/ic/simple/main/main.kt @@ -0,0 +1,4 @@ +import kotlin.test.* + +@Test +fun runTest() = assertEquals(42, foo()) \ No newline at end of file diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/CachesAutoBuildTest.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/CachesAutoBuildTest.kt index 794a949acca..c995648b9e7 100644 --- a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/CachesAutoBuildTest.kt +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/CachesAutoBuildTest.kt @@ -42,7 +42,7 @@ class CachesAutoBuildTest : AbstractNativeSimpleTest() { val lib = compileToLibrary(rootDir.resolve("lib"), buildDir) val main = compileToExecutable(rootDir.resolve("main"), autoCacheFrom = buildDir, emptyList(), lib) - assertTrue(main.executableFile.exists()) + assertTrue(main.exists()) assertTrue(autoCacheDir.resolve(cacheFlavor).resolve("lib").exists()) } @@ -58,7 +58,7 @@ class CachesAutoBuildTest : AbstractNativeSimpleTest() { externalLib, userLib ) - assertTrue(main.executableFile.exists()) + assertTrue(main.exists()) assertTrue(autoCacheDir.resolve(cacheFlavor).resolve("externalLib").exists()) assertFalse(autoCacheDir.resolve(cacheFlavor).resolve("userLib").exists()) } @@ -75,12 +75,13 @@ class CachesAutoBuildTest : AbstractNativeSimpleTest() { assertTrue(cacheDir.resolve("lib-${if (makePerFileCache) "per-file-cache" else "cache"}").exists()) val main = compileToExecutable(rootDir.resolve("main"), autoCacheFrom = buildDir, listOf(cacheDir), lib) - assertTrue(main.executableFile.exists()) + assertTrue(main.exists()) assertFalse(autoCacheDir.resolve(cacheFlavor).resolve("lib").exists()) } - private fun compileToExecutable(sourcesDir: File, autoCacheFrom: File, cacheDirectories: List, vararg dependencies: KLIB) = - compileToExecutable( + private fun compileToExecutable(sourcesDir: File, autoCacheFrom: File, cacheDirectories: List, vararg dependencies: KLIB): File { + autoCacheDir.mkdirs() + return compileToExecutable( sourcesDir, freeCompilerArgs = TestCompilerArgs( listOf( @@ -89,7 +90,8 @@ class CachesAutoBuildTest : AbstractNativeSimpleTest() { ) + cacheDirectories.map { "-Xcache-directory=${it.absolutePath}" } ), *dependencies - ).assertSuccess().resultingArtifact + ).executableFile + } private val autoCacheDir: File get() = buildDir.resolve("__auto_cache__") private val cacheFlavor: String diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/IncrementalCompilationTest.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/IncrementalCompilationTest.kt new file mode 100644 index 00000000000..9ea7ce31d1a --- /dev/null +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/IncrementalCompilationTest.kt @@ -0,0 +1,542 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.konan.blackboxtest + +import com.intellij.testFramework.TestDataPath +import org.jetbrains.kotlin.konan.blackboxtest.CachesAutoBuildTest.Companion.TEST_SUITE_PATH +import org.jetbrains.kotlin.konan.blackboxtest.support.EnforcedHostTarget +import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationArtifact +import org.jetbrains.kotlin.konan.blackboxtest.support.group.UsePartialLinkage +import org.jetbrains.kotlin.konan.blackboxtest.support.settings.CacheMode +import org.jetbrains.kotlin.konan.blackboxtest.support.settings.KotlinNativeTargets +import org.jetbrains.kotlin.konan.blackboxtest.support.settings.OptimizationMode +import org.jetbrains.kotlin.test.TestMetadata +import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertTrue +import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertFalse +import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertEquals +import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertNotEquals +import org.junit.jupiter.api.Assumptions +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Tag +import org.junit.jupiter.api.Test +import java.io.File + +@Tag("caches") +@EnforcedHostTarget +@TestMetadata(TEST_SUITE_PATH) +@TestDataPath("\$PROJECT_ROOT") +@UsePartialLinkage(UsePartialLinkage.Mode.DISABLED) +class IncrementalCompilationTest : AbstractNativeSimpleTest() { + @BeforeEach + fun assumeCachesAreEnabled() { + Assumptions.assumeFalse(testRunSettings.get() == CacheMode.WithoutCache) + } + + @Test + @TestMetadata("simple") + fun testSimple() = withRootDir(File("$TEST_SUITE_PATH/simple")) { + val lib = compileLibrary("lib") { "lib/lib.kt" copyTo "lib.kt" } + val main = compileToExecutable("main", lib) { "main/main.kt" copyTo "main.kt" } + + // Check, has been compiled to cache. + assertTrue(main.executableFile.exists()) + val libKtCacheDir = getLibraryFileCache("lib", "lib/lib.kt", "") + assertTrue(libKtCacheDir.exists()) + runExecutableAndVerify(main.testCase, main.testExecutable) + + // Check, 's cache won't be recompiled if nothing has changed. + val modified = libKtCacheDir.lastModified() + compileToExecutable("main", lib) { "main/main.kt" copyTo "main.kt" } + assertTrue(libKtCacheDir.exists()) + assertEquals(modified, libKtCacheDir.lastModified()) + } + + @Test + @TestMetadata("modifiedFile") + fun testModifiedFile() = withRootDir(File("$TEST_SUITE_PATH/simple")) { + val lib = compileLibrary("lib") { "lib/lib.kt" copyTo "lib.kt" } + val main = compileToExecutable("main", lib) { "main/main.kt" copyTo "main.kt" } + + // Check, has been compiled to cache. + assertTrue(main.executableFile.exists()) + val libKtCacheDir = getLibraryFileCache("lib", "lib/lib.kt", "") + assertTrue(libKtCacheDir.exists()) + runExecutableAndVerify(main.testCase, main.testExecutable) + + // Check, 's cache will be recompiled after changing the file. + val modified = libKtCacheDir.lastModified() + val lib1 = compileLibrary("lib") { "lib/lib.1.kt" copyTo "lib.kt" } + val main1 = compileToExecutable("main", lib1) { "main/main.1.kt" copyTo "main.kt" } + assertTrue(libKtCacheDir.exists()) + assertNotEquals(modified, libKtCacheDir.lastModified()) + runExecutableAndVerify(main1.testCase, main1.testExecutable) + } + + @Test + @TestMetadata("addedFile") + fun testAddedFile() = withRootDir(File("$TEST_SUITE_PATH/addDeleteFile")) { + val lib = compileLibrary("lib") { "lib/lib.file1.kt" copyTo "lib.file1.kt" } + val main = compileToExecutable("main", lib) { "main/main.kt" copyTo "main.kt" } + + // Check, has been compiled to cache. + assertTrue(main.executableFile.exists()) + val libFile1KtCacheDir = getLibraryFileCache("lib", "lib/lib.file1.kt", "") + assertTrue(libFile1KtCacheDir.exists()) + runExecutableAndVerify(main.testCase, main.testExecutable) + + // Check, 's file1 cache won't change after adding an independent file. + val modified = libFile1KtCacheDir.lastModified() + val lib1 = compileLibrary("lib") { + "lib/lib.file1.kt" copyTo "lib.file1.kt" + "lib/lib.file2.kt" copyTo "lib.file2.kt" + } + val main1 = compileToExecutable("main", lib1) { "main/main.1.kt" copyTo "main.kt" } + assertTrue(libFile1KtCacheDir.exists()) + assertEquals(modified, libFile1KtCacheDir.lastModified()) + val libFile2KtCacheDir = getLibraryFileCache("lib", "lib/lib.file2.kt", "") + assertTrue(libFile2KtCacheDir.exists()) + runExecutableAndVerify(main1.testCase, main1.testExecutable) + } + + @Test + @TestMetadata("removedFile") + fun testRemovedFile() = withRootDir(File("$TEST_SUITE_PATH/addDeleteFile")) { + val lib = compileLibrary("lib") { + "lib/lib.file1.kt" copyTo "lib.file1.kt" + "lib/lib.file2.kt" copyTo "lib.file2.kt" + } + val main = compileToExecutable("main", lib) { "main/main.1.kt" copyTo "main.kt" } + + // Check, has been compiled to cache. + assertTrue(main.executableFile.exists()) + val libFile1KtCacheDir = getLibraryFileCache("lib", "lib/lib.file1.kt", "") + assertTrue(libFile1KtCacheDir.exists()) + val libFile2KtCacheDir = getLibraryFileCache("lib", "lib/lib.file2.kt", "") + assertTrue(libFile2KtCacheDir.exists()) + runExecutableAndVerify(main.testCase, main.testExecutable) + + // Check, 's file1 cache won't change after removing an independent file. + val modified = libFile1KtCacheDir.lastModified() + val lib1 = compileLibrary("lib") { "lib/lib.file1.kt" copyTo "lib.file1.kt" } + val main1 = compileToExecutable("main", lib1) { "main/main.kt" copyTo "main.kt" } + assertTrue(libFile1KtCacheDir.exists()) + assertEquals(modified, libFile1KtCacheDir.lastModified()) + // Check, 's file2 cache has been removed. + assertFalse(libFile2KtCacheDir.exists()) + runExecutableAndVerify(main1.testCase, main1.testExecutable) + } + + @Test + @TestMetadata("renamedFile") + fun testRenamedFile() = withRootDir(File("$TEST_SUITE_PATH/renameFileOrPackage")) { + val lib = compileLibrary("lib") { "lib/lib.kt" copyTo "lib.kt" } + val main = compileToExecutable("main", lib) { "main/main.kt" copyTo "main.kt" } + + // Check, has been compiled to cache. + assertTrue(main.executableFile.exists()) + val libKtCacheDir = getLibraryFileCache("lib", "lib/lib.kt", "test") + assertTrue(libKtCacheDir.exists()) + runExecutableAndVerify(main.testCase, main.testExecutable) + + // Check, 's file cache is moved to other directory. + val lib1 = compileLibrary("lib") { "lib/lib.kt" copyTo "lib.changed.kt" } + val main1 = compileToExecutable("main", lib1) { "main/main.kt" copyTo "main.kt" } + assertFalse(libKtCacheDir.exists()) + val changedLibKtCacheDir = getLibraryFileCache("lib", "lib/lib.changed.kt", "test") + assertTrue(changedLibKtCacheDir.exists()) + runExecutableAndVerify(main1.testCase, main1.testExecutable) + } + + @Test + @TestMetadata("renamedPackage") + fun testRenamedPackage() = withRootDir(File("$TEST_SUITE_PATH/renameFileOrPackage")) { + val lib = compileLibrary("lib") { "lib/lib.kt" copyTo "lib.kt" } + val main = compileToExecutable("main", lib) { "main/main.kt" copyTo "main.kt" } + + // Check, has been compiled to cache. + assertTrue(main.executableFile.exists()) + val libKtCacheDir = getLibraryFileCache("lib", "lib/lib.kt", "test") + assertTrue(libKtCacheDir.exists()) + runExecutableAndVerify(main.testCase, main.testExecutable) + + // Check, 's file cache is moved to other directory. + val lib1 = compileLibrary("lib") { "lib/lib.1.kt" copyTo "lib.kt" } + val main1 = compileToExecutable("main", lib1) { "main/main.1.kt" copyTo "main.kt" } + assertFalse(libKtCacheDir.exists()) + val changedLibKtCacheDir = getLibraryFileCache("lib", "lib/lib.kt", "tezd") + assertTrue(changedLibKtCacheDir.exists()) + runExecutableAndVerify(main1.testCase, main1.testExecutable) + } + + @Test + @TestMetadata("changedFileIndex") + fun testChangedFileIndex() = withRootDir(File("$TEST_SUITE_PATH/changeFileIndex")) { + val lib = compileLibrary("lib") { + "lib/lib.file1.kt" copyTo "libB.kt" + "lib/lib.file2.kt" copyTo "libC.kt" + } + val main = compileToExecutable("main", lib) { "main/main.kt" copyTo "main.kt" } + + assertTrue(main.executableFile.exists()) + val libBKtCacheDir = getLibraryFileCache("lib", "lib/libB.kt", "") + assertTrue(libBKtCacheDir.exists()) + runExecutableAndVerify(main.testCase, main.testExecutable) + + val modified = libBKtCacheDir.lastModified() + val lib1 = compileLibrary("lib") { + "lib/lib.file1.kt" copyTo "libB.kt" + "lib/lib.file2.kt" copyTo "libA.kt" + } + val main1 = compileToExecutable("main", lib1) { "main/main.kt" copyTo "main.kt" } + assertTrue(libBKtCacheDir.exists()) + assertEquals(modified, libBKtCacheDir.lastModified()) + runExecutableAndVerify(main1.testCase, main1.testExecutable) + } + + @Test + @TestMetadata("changedExternalDependencyVersion") + fun testChangedExternalDependencyVersion() = withRootDir(File("$TEST_SUITE_PATH/externalDependency")) { + val externalLib = compileLibrary("externalLib") { + libraryVersion = "1.0" + outputDir = "external" + "externalLib/file1.kt" copyTo "file1.kt" + } + val userLib = compileLibrary("userLib", externalLib) { "userLib/file1.kt" copyTo "file1.kt" } + val main = compileToExecutable("main", externalLib, userLib) { "main/main.kt" copyTo "main.kt" } + + assertTrue(main.executableFile.exists()) + val libFile1KtCacheDir = getLibraryFileCache("userLib", "userLib/file1.kt", "") + assertTrue(libFile1KtCacheDir.exists()) + runExecutableAndVerify(main.testCase, main.testExecutable) + + val modified = libFile1KtCacheDir.lastModified() + val externalLib1 = compileLibrary("externalLib") { + libraryVersion = "1.1" + outputDir = "external" + "externalLib/file1.kt" copyTo "file1.kt" + } + val userLib1 = compileLibrary("userLib", externalLib1) { "userLib/file1.kt" copyTo "file1.kt" } + val main1 = compileToExecutable("main", externalLib1, userLib1) { "main/main.kt" copyTo "main.kt" } + assertTrue(libFile1KtCacheDir.exists()) + assertNotEquals(modified, libFile1KtCacheDir.lastModified()) + runExecutableAndVerify(main1.testCase, main1.testExecutable) + } + + @Test + @TestMetadata("changedExternalDependency") + fun testChangedExternalDependency() = withRootDir(File("$TEST_SUITE_PATH/externalDependency")) { + val externalLib = compileLibrary("externalLib") { + outputDir = "external" + "externalLib/file1.kt" copyTo "file1.kt" + "externalLib/file2.kt" copyTo "file2.kt" + } + val userLib = compileLibrary("userLib", externalLib) { + "userLib/file1.kt" copyTo "file1.kt" + "userLib/file2.kt" copyTo "file2.kt" + } + val main = compileToExecutable("main", externalLib, userLib) { + "main/main.kt" copyTo "main.kt" + "main/main2.kt" copyTo "main2.kt" + } + + assertTrue(main.executableFile.exists()) + val libFile1KtCacheDir = getLibraryFileCache("userLib", "userLib/file1.kt", "") + val libFile2KtCacheDir = getLibraryFileCache("userLib", "userLib/file2.kt", "") + assertTrue(libFile1KtCacheDir.exists()) + assertTrue(libFile2KtCacheDir.exists()) + runExecutableAndVerify(main.testCase, main.testExecutable) + + // Check, both file caches will be recompiled after changing only one file in the external library. + val modified1 = libFile1KtCacheDir.lastModified() + val modified2 = libFile2KtCacheDir.lastModified() + val externalLib1 = compileLibrary("externalLib") { + outputDir = "external" + "externalLib/file1.kt" copyTo "file1.kt" + "externalLib/file2.1.kt" copyTo "file2.kt" + } + val main1 = compileToExecutable("main", externalLib1, userLib) { + "main/main.kt" copyTo "main.kt" + "main/main2.1.kt" copyTo "main2.kt" + } + assertTrue(libFile1KtCacheDir.exists()) + assertNotEquals(modified1, libFile1KtCacheDir.lastModified()) + assertTrue(libFile2KtCacheDir.exists()) + assertNotEquals(modified2, libFile2KtCacheDir.lastModified()) + runExecutableAndVerify(main1.testCase, main1.testExecutable) + } + + @Test + @TestMetadata("fileDependencies1") + fun testFileDependencies1() = withRootDir(File("$TEST_SUITE_PATH/fileDependencies1")) { + val lib = compileLibrary("lib") { + "lib/lib.file1.kt" copyTo "file1.kt" + "lib/lib.file2.kt" copyTo "file2.kt" + "lib/lib.file3.kt" copyTo "file3.kt" + } + val main = compileToExecutable("main", lib) { "main/main.kt" copyTo "main.kt" } + + // Check, has been compiled to cache. + assertTrue(main.executableFile.exists()) + val file1KtCacheDir = getLibraryFileCache("lib", "lib/file1.kt", "test") + val file2KtCacheDir = getLibraryFileCache("lib", "lib/file2.kt", "test") + val file3KtCacheDir = getLibraryFileCache("lib", "lib/file3.kt", "test") + assertTrue(file1KtCacheDir.exists()) + assertTrue(file2KtCacheDir.exists()) + assertTrue(file3KtCacheDir.exists()) + val modified1 = file1KtCacheDir.lastModified() + val modified2 = file2KtCacheDir.lastModified() + val modified3 = file3KtCacheDir.lastModified() + runExecutableAndVerify(main.testCase, main.testExecutable) + + // Check, 's file1 and file3 caches will be recompiled after changing file1. + val lib1 = compileLibrary("lib") { + "lib/lib.file1.1.kt" copyTo "file1.kt" + "lib/lib.file2.kt" copyTo "file2.kt" + "lib/lib.file3.kt" copyTo "file3.kt" + } + val main1 = compileToExecutable("main", lib1) { "main/main.1.kt" copyTo "main.kt" } + assertTrue(main1.executableFile.exists()) + assertTrue(file1KtCacheDir.exists()) + assertTrue(file2KtCacheDir.exists()) + assertTrue(file3KtCacheDir.exists()) + assertNotEquals(modified1, file1KtCacheDir.lastModified()) + assertEquals(modified2, file2KtCacheDir.lastModified()) + assertNotEquals(modified3, file3KtCacheDir.lastModified()) + runExecutableAndVerify(main1.testCase, main1.testExecutable) + } + + @Test + @TestMetadata("fileDependencies2") + fun testFileDependencies2() = withRootDir(File("$TEST_SUITE_PATH/fileDependencies2")) { + val lib1 = compileLibrary("lib1") { "lib1/lib1.kt" copyTo "lib1.kt" } + val lib2 = compileLibrary("lib2", lib1) { + "lib2/lib2.file1.kt" copyTo "file1.kt" + "lib2/lib2.file2.kt" copyTo "file2.kt" + } + val main = compileToExecutable("main", lib1, lib2) { "main/main.kt" copyTo "main.kt" } + + // Check, has been compiled to cache. + assertTrue(main.executableFile.exists()) + val lib1KtCacheDir = getLibraryFileCache("lib1", "lib1/lib1.kt", "test1") + val lib2File1KtCacheDir = getLibraryFileCache("lib2", "lib2/file1.kt", "test2") + val lib2File2KtCacheDir = getLibraryFileCache("lib2", "lib2/file2.kt", "test2") + assertTrue(lib1KtCacheDir.exists()) + assertTrue(lib2File1KtCacheDir.exists()) + assertTrue(lib2File2KtCacheDir.exists()) + val modified11 = lib1KtCacheDir.lastModified() + val modified21 = lib2File1KtCacheDir.lastModified() + val modified22 = lib2File2KtCacheDir.lastModified() + runExecutableAndVerify(main.testCase, main.testExecutable) + + // Check, 's file2 cache will be recompiled after changing lib1/lib1.kt. + val lib11 = compileLibrary("lib1") { "lib1/lib1.1.kt" copyTo "lib1.kt" } + val lib21 = compileLibrary("lib2", lib11) { + "lib2/lib2.file1.kt" copyTo "file1.kt" + "lib2/lib2.file2.kt" copyTo "file2.kt" + } + val main1 = compileToExecutable("main", lib11, lib21) { "main/main.1.kt" copyTo "main.kt" } + assertTrue(main1.executableFile.exists()) + assertTrue(lib1KtCacheDir.exists()) + assertTrue(lib2File1KtCacheDir.exists()) + assertTrue(lib2File2KtCacheDir.exists()) + assertNotEquals(modified11, lib1KtCacheDir.lastModified()) + assertEquals(modified21, lib2File1KtCacheDir.lastModified()) + assertNotEquals(modified22, lib2File2KtCacheDir.lastModified()) + runExecutableAndVerify(main1.testCase, main1.testExecutable) + } + + @Test + @TestMetadata("addMethodToOpenClass1") + fun addMethodToOpenClass1() = withRootDir(File("$TEST_SUITE_PATH/addMethodToOpenClass1")) { + val lib1 = compileLibrary("lib1") { "lib1/lib1.kt" copyTo "lib1.kt" } + val lib2 = compileLibrary("lib2", lib1) { "lib2/lib2.kt" copyTo "lib2.kt" } + val main = compileToExecutable("main", lib1, lib2) { "main/main.kt" copyTo "main.kt" } + + // Check, has been compiled to cache. + assertTrue(main.executableFile.exists()) + val lib1KtCacheDir = getLibraryFileCache("lib1", "lib1/lib1.kt", "test1") + val lib2KtCacheDir = getLibraryFileCache("lib2", "lib2/lib2.kt", "test2") + assertTrue(lib1KtCacheDir.exists()) + assertTrue(lib2KtCacheDir.exists()) + val modified1 = lib1KtCacheDir.lastModified() + val modified2 = lib2KtCacheDir.lastModified() + runExecutableAndVerify(main.testCase, main.testExecutable) + + // Check, 's cache won't be recompiled after changing lib1/lib1.kt. + val lib11 = compileLibrary("lib1") { "lib1/lib1.1.kt" copyTo "lib1.kt" } + val lib21 = compileLibrary("lib2", lib11) { "lib2/lib2.kt" copyTo "lib2.kt" } + val main1 = compileToExecutable("main", lib11, lib21) { "main/main.kt" copyTo "main.kt" } + assertTrue(main1.executableFile.exists()) + assertTrue(lib1KtCacheDir.exists()) + assertTrue(lib2KtCacheDir.exists()) + assertNotEquals(modified1, lib1KtCacheDir.lastModified()) + assertEquals(modified2, lib2KtCacheDir.lastModified()) + runExecutableAndVerify(main1.testCase, main1.testExecutable) + } + + @Test + @TestMetadata("addMethodToOpenClass2") + fun addMethodToOpenClass2() = withRootDir(File("$TEST_SUITE_PATH/addMethodToOpenClass2")) { + val lib1 = compileLibrary("lib1") { + "lib1/lib1.file1.kt" copyTo "lib1.file1.kt" + "lib1/lib1.file2.kt" copyTo "lib1.file2.kt" + } + val lib2 = compileLibrary("lib2", lib1) { "lib2/lib2.kt" copyTo "lib2.kt" } + val main = compileToExecutable("main", lib1, lib2) { "main/main.kt" copyTo "main.kt" } + + // Check, has been compiled to cache. + assertTrue(main.executableFile.exists()) + val lib1File1KtCacheDir = getLibraryFileCache("lib1", "lib1/lib1.file1.kt", "test1") + val lib1File2KtCacheDir = getLibraryFileCache("lib1", "lib1/lib1.file2.kt", "test1") + val lib2KtCacheDir = getLibraryFileCache("lib2", "lib2/lib2.kt", "test2") + assertTrue(lib1File1KtCacheDir.exists()) + assertTrue(lib1File2KtCacheDir.exists()) + assertTrue(lib2KtCacheDir.exists()) + val modified11 = lib1File1KtCacheDir.lastModified() + val modified12 = lib1File2KtCacheDir.lastModified() + val modified2 = lib2KtCacheDir.lastModified() + runExecutableAndVerify(main.testCase, main.testExecutable) + + // Check, 's cache won't be recompiled after changing lib1/lib1.file1.kt. + val lib11 = compileLibrary("lib1") { + "lib1/lib1.file1.1.kt" copyTo "lib1.file1.kt" + "lib1/lib1.file2.kt" copyTo "lib1.file2.kt" + } + val lib21 = compileLibrary("lib2", lib11) { "lib2/lib2.kt" copyTo "lib2.kt" } + val main1 = compileToExecutable("main", lib11, lib21) { "main/main.kt" copyTo "main.kt" } + assertTrue(main1.executableFile.exists()) + assertTrue(lib1File1KtCacheDir.exists()) + assertTrue(lib1File2KtCacheDir.exists()) + assertTrue(lib2KtCacheDir.exists()) + assertNotEquals(modified11, lib1File1KtCacheDir.lastModified()) + assertNotEquals(modified12, lib1File2KtCacheDir.lastModified()) + assertEquals(modified2, lib2KtCacheDir.lastModified()) + runExecutableAndVerify(main1.testCase, main1.testExecutable) + } + + @Test + @TestMetadata("addMethodToInterface1") + fun addMethodToInterface1() = withRootDir(File("$TEST_SUITE_PATH/addMethodToInterface1")) { + val lib1 = compileLibrary("lib1") { "lib1/lib1.kt" copyTo "lib1.kt" } + val lib2 = compileLibrary("lib2", lib1) { "lib2/lib2.kt" copyTo "lib2.kt" } + val main = compileToExecutable("main", lib1, lib2) { "main/main.kt" copyTo "main.kt" } + + // Check, has been compiled to cache. + assertTrue(main.executableFile.exists()) + val lib1KtCacheDir = getLibraryFileCache("lib1", "lib1/lib1.kt", "test1") + val lib2KtCacheDir = getLibraryFileCache("lib2", "lib2/lib2.kt", "test2") + assertTrue(lib1KtCacheDir.exists()) + assertTrue(lib2KtCacheDir.exists()) + val modified1 = lib1KtCacheDir.lastModified() + val modified2 = lib2KtCacheDir.lastModified() + runExecutableAndVerify(main.testCase, main.testExecutable) + + // Check, 's cache won't be recompiled after changing lib1/lib1.kt. + val lib11 = compileLibrary("lib1") { "lib1/lib1.1.kt" copyTo "lib1.kt" } + val lib21 = compileLibrary("lib2", lib11) { "lib2/lib2.kt" copyTo "lib2.kt" } + val main1 = compileToExecutable("main", lib11, lib21) { "main/main.1.kt" copyTo "main.kt" } + assertTrue(main1.executableFile.exists()) + assertTrue(lib1KtCacheDir.exists()) + assertTrue(lib2KtCacheDir.exists()) + assertNotEquals(modified1, lib1KtCacheDir.lastModified()) + assertEquals(modified2, lib2KtCacheDir.lastModified()) + runExecutableAndVerify(main1.testCase, main1.testExecutable) + } + + @Test + @TestMetadata("addMethodToInterface2") + fun addMethodToInterface2() = withRootDir(File("$TEST_SUITE_PATH/addMethodToInterface2")) { + val lib1 = compileLibrary("lib1") { + "lib1/lib1.file1.kt" copyTo "lib1.file1.kt" + "lib1/lib1.file2.kt" copyTo "lib1.file2.kt" + } + val lib2 = compileLibrary("lib2", lib1) { "lib2/lib2.kt" copyTo "lib2.kt" } + val main = compileToExecutable("main", lib1, lib2) { "main/main.kt" copyTo "main.kt" } + + // Check, has been compiled to cache. + assertTrue(main.executableFile.exists()) + val lib1File1KtCacheDir = getLibraryFileCache("lib1", "lib1/lib1.file1.kt", "test1") + val lib1File2KtCacheDir = getLibraryFileCache("lib1", "lib1/lib1.file2.kt", "test1") + val lib2KtCacheDir = getLibraryFileCache("lib2", "lib2/lib2.kt", "test2") + assertTrue(lib1File1KtCacheDir.exists()) + assertTrue(lib1File2KtCacheDir.exists()) + assertTrue(lib2KtCacheDir.exists()) + val modified11 = lib1File1KtCacheDir.lastModified() + val modified12 = lib1File2KtCacheDir.lastModified() + val modified2 = lib2KtCacheDir.lastModified() + runExecutableAndVerify(main.testCase, main.testExecutable) + + // Check, 's cache won't be recompiled after changing lib1/lib1.file1.kt. + val lib11 = compileLibrary("lib1") { + "lib1/lib1.file1.1.kt" copyTo "lib1.file1.kt" + "lib1/lib1.file2.kt" copyTo "lib1.file2.kt" + } + val lib21 = compileLibrary("lib2", lib11) { "lib2/lib2.kt" copyTo "lib2.kt" } + val main1 = compileToExecutable("main", lib11, lib21) { "main/main.1.kt" copyTo "main.kt" } + assertTrue(main1.executableFile.exists()) + assertTrue(lib1File1KtCacheDir.exists()) + assertTrue(lib1File2KtCacheDir.exists()) + assertTrue(lib2KtCacheDir.exists()) + assertNotEquals(modified11, lib1File1KtCacheDir.lastModified()) + assertNotEquals(modified12, lib1File2KtCacheDir.lastModified()) + assertEquals(modified2, lib2KtCacheDir.lastModified()) + runExecutableAndVerify(main1.testCase, main1.testExecutable) + } + + private inline fun withRootDir(rootDir: File, block: RootDirHolder.() -> Unit) = RootDirHolder(rootDir).block() + + private inner class RootDirHolder(val rootDir: File) { + inline fun compileLibrary( + targetSrc: String, + vararg dependencies: TestCompilationArtifact.KLIB, + block: LibraryBuilder.() -> Unit + ) = with(LibraryBuilder(this@IncrementalCompilationTest, rootDir, targetSrc, dependencies.asList())) { + block() + build() + } + + inline fun compileToExecutable( + targetSrc: String, + vararg dependencies: TestCompilationArtifact.KLIB, + block: ExecutableBuilder.() -> Unit + ) = with(ExecutableBuilder(this@IncrementalCompilationTest, rootDir, targetSrc, dependencies.asList())) { + externalLibsDir.mkdirs() + icCacheDir.mkdirs() + autoCacheDir.mkdirs() + +"-Xauto-cache-from=${externalLibsDir.absolutePath}" + +"-Xauto-cache-dir=${autoCacheDir.absolutePath}" + +"-Xic-cache-dir=${icCacheDir.absolutePath}" + +"-Xenable-incremental-compilation" + +"-verbose" + block() + build() + } + } + + private val externalLibsDir: File get() = buildDir.resolve("external") + private val autoCacheDir: File get() = buildDir.resolve("__auto_cache__") + private val icCacheDir: File get() = buildDir.resolve("__ic_cache__") + private val cacheFlavor: String + get() = CacheMode.computeCacheDirName( + testRunSettings.get().testTarget, + "STATIC", + testRunSettings.get() == OptimizationMode.DEBUG, + partialLinkageEnabled = false + ) + + private fun getLibraryFileCache(libName: String, libFileRelativePath: String, fqName: String): File { + val libCacheDir = icCacheDir.resolve(cacheFlavor).resolve("$libName-per-file-cache") + val fileId = cacheFileId(fqName, buildDir.resolve(libFileRelativePath).absolutePath) + return libCacheDir.resolve(fileId) + } + + private fun cacheFileId(fqName: String, filePath: String) = + "${if (fqName == "") "ROOT" else fqName}.${filePath.hashCode().toString(Character.MAX_RADIX)}" + + companion object { + const val TEST_SUITE_PATH = "native/native.tests/testData/caches/ic" + } +} diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/NativeSimpleTestUtils.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/NativeSimpleTestUtils.kt index 60ba0e80e8c..1730981b75d 100644 --- a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/NativeSimpleTestUtils.kt +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/NativeSimpleTestUtils.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilati import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationDependencyType import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationResult import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationResult.Companion.assertSuccess +import org.jetbrains.kotlin.konan.blackboxtest.support.runner.TestExecutable import org.jetbrains.kotlin.konan.blackboxtest.support.runner.TestRunChecks import org.jetbrains.kotlin.konan.blackboxtest.support.settings.KotlinNativeTargets import org.jetbrains.kotlin.konan.blackboxtest.support.settings.PipelineType @@ -36,6 +37,83 @@ import java.io.File private val DEFAULT_EXTRAS = TestCase.WithTestRunnerExtras(TestRunnerType.DEFAULT) +internal abstract class ArtifactBuilder( + val test: AbstractNativeSimpleTest, + val rootDir: File, + val targetSrc: String, + dependencies: List +) { + private val buildDir = test.buildDir + var outputDir: String = "" + + private val sources = mutableListOf>() + private val dependencies = dependencies.toMutableList() + + infix fun String.copyTo(to: String) { + sources.add(Pair(this, to)) + } + + fun dependsOn(klib: TestCompilationArtifact.KLIB) { + dependencies.add(klib) + } + + protected abstract fun build(sourcesDir: File, outputDir: File, dependencies: List): T + + fun build(): T { + val targetSrc = buildDir.resolve(targetSrc) + targetSrc.deleteRecursively() + targetSrc.mkdirs() + val outputDir = if (outputDir == "") buildDir else buildDir.resolve(outputDir) + sources.forEach { + val source = rootDir.resolve(it.first) + val target = targetSrc.resolve(it.second) + target.mkdirs() + if (source.isFile) + source.copyTo(target, true) + else + source.copyRecursively(target, true) + } + return build(targetSrc, outputDir, dependencies) + } +} + +internal class LibraryBuilder( + test: AbstractNativeSimpleTest, + rootDir: File, + targetSrc: String, + dependencies: List +) : ArtifactBuilder(test, rootDir, targetSrc, dependencies) { + var libraryVersion: String? = null + + override fun build(sourcesDir: File, outputDir: File, dependencies: List) = + test.compileToLibrary( + sourcesDir, + outputDir, + freeCompilerArgs = libraryVersion?.let { TestCompilerArgs(listOf("-library-version=$it")) } ?: TestCompilerArgs.EMPTY, + dependencies + ) +} + +internal class ExecutableBuilder( + test: AbstractNativeSimpleTest, + rootDir: File, + targetSrc: String, + dependencies: List +) : ArtifactBuilder(test, rootDir, targetSrc, dependencies) { + private val freeCompilerArgs = mutableListOf() + + operator fun String.unaryPlus() { + freeCompilerArgs.add(this) + } + + override fun build(sourcesDir: File, outputDir: File, dependencies: List) = + test.compileToExecutable( + sourcesDir, + freeCompilerArgs = if (freeCompilerArgs.isEmpty()) TestCompilerArgs.EMPTY else TestCompilerArgs(freeCompilerArgs), + dependencies + ) +} + internal val AbstractNativeSimpleTest.buildDir: File get() = testRunSettings.get().testBuildDir internal fun TestCompilationArtifact.KLIB.asLibraryDependency() = @@ -54,19 +132,42 @@ internal fun AbstractNativeSimpleTest.compileToLibrary( sourcesDir: File, outputDir: File, vararg dependencies: TestCompilationArtifact.KLIB +): TestCompilationArtifact.KLIB = compileToLibrary(sourcesDir, outputDir, TestCompilerArgs.EMPTY, dependencies.asList()) + +internal fun AbstractNativeSimpleTest.compileToLibrary( + sourcesDir: File, + outputDir: File, + freeCompilerArgs: TestCompilerArgs, + dependencies: List ): TestCompilationArtifact.KLIB { - val testCase: TestCase = generateTestCaseWithSingleModule(sourcesDir) + val testCase: TestCase = generateTestCaseWithSingleModule(sourcesDir, freeCompilerArgs) val compilationResult = compileToLibrary(testCase, outputDir, dependencies.map { it.asLibraryDependency() }) return compilationResult.resultingArtifact } +internal class CompiledExecutable( + val testCase: TestCase, + val compilationResult: TestCompilationResult.Success +) { + val executableFile: File get() = compilationResult.resultingArtifact.executableFile + + val testExecutable by lazy { TestExecutable.fromCompilationResult(testCase, compilationResult) } +} + internal fun AbstractNativeSimpleTest.compileToExecutable( sourcesDir: File, freeCompilerArgs: TestCompilerArgs, vararg dependencies: TestCompilationArtifact.KLIB -): TestCompilationResult { +) = compileToExecutable(sourcesDir, freeCompilerArgs, dependencies.asList()) + +internal fun AbstractNativeSimpleTest.compileToExecutable( + sourcesDir: File, + freeCompilerArgs: TestCompilerArgs, + dependencies: List +): CompiledExecutable { val testCase: TestCase = generateTestCaseWithSingleModule(sourcesDir, freeCompilerArgs) - return compileToExecutable(testCase, dependencies.map { it.asLibraryDependency() }) + val compilationResult = compileToExecutable(testCase, dependencies.map { it.asLibraryDependency() }) + return CompiledExecutable(testCase, compilationResult.assertSuccess()) } internal fun AbstractNativeSimpleTest.compileToExecutable(testCase: TestCase, vararg dependencies: TestCompilationDependency<*>) =