[JS IR] Add tests for JS IR IC + PL

^KT-57347 related
This commit is contained in:
Alexander Korepanov
2023-05-08 16:54:30 +02:00
committed by Space Team
parent 97620030c6
commit 82a1242f22
96 changed files with 710 additions and 3 deletions
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.generators.tests
import org.jetbrains.kotlin.generators.generateTestGroupSuiteWithJUnit5
import org.jetbrains.kotlin.generators.impl.generateTestGroupSuite
import org.jetbrains.kotlin.incremental.AbstractJsIrES6InvalidationTest
import org.jetbrains.kotlin.incremental.AbstractJsIrInvalidationWithPLTest
import org.jetbrains.kotlin.incremental.AbstractJsIrInvalidationTest
import org.jetbrains.kotlin.incremental.AbstractJsFirInvalidationTest
import org.jetbrains.kotlin.js.test.*
@@ -82,6 +83,10 @@ fun main(args: Array<String>) {
testClass<AbstractJsFirInvalidationTest> {
model("incremental/invalidation/", pattern = "^([^_](.+))$", targetBackend = TargetBackend.JS_IR, recursive = false)
}
testClass<AbstractJsIrInvalidationWithPLTest> {
model("incremental/invalidationWithPL/", pattern = "^([^_](.+))$", targetBackend = TargetBackend.JS_IR, recursive = false)
}
}
testGroup("js/js.tests/tests-gen", "js/js.translator/testData", testRunnerMethodName = "runTest0") {
@@ -121,7 +121,7 @@ abstract class AbstractInvalidationTest(private val targetBackend: TargetBackend
return File(File(buildDir, moduleName), "$moduleName.klib")
}
private fun createConfiguration(moduleName: String, language: List<String>, moduleKind: ModuleKind): CompilerConfiguration {
protected open fun createConfiguration(moduleName: String, language: List<String>, moduleKind: ModuleKind): CompilerConfiguration {
val copy = environment.configuration.copy()
copy.put(CommonConfigurationKeys.MODULE_NAME, moduleName)
copy.put(JSConfigurationKeys.GENERATE_DTS, true)
@@ -11,12 +11,35 @@ import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.ir.backend.js.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
import org.jetbrains.kotlin.ir.linkage.partial.PartialLinkageConfig
import org.jetbrains.kotlin.ir.linkage.partial.PartialLinkageLogLevel
import org.jetbrains.kotlin.ir.linkage.partial.PartialLinkageMode
import org.jetbrains.kotlin.ir.linkage.partial.setupPartialLinkageConfig
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.serialization.js.ModuleKind
import org.jetbrains.kotlin.test.TargetBackend
import java.io.File
abstract class AbstractJsIrInvalidationTest : IrAbstractInvalidationTest(TargetBackend.JS_IR, "incrementalOut/invalidation")
abstract class AbstractJsIrES6InvalidationTest : IrAbstractInvalidationTest(TargetBackend.JS_IR_ES6, "incrementalOut/invalidationES6")
abstract class AbstractJsIrInvalidationTest : IrAbstractInvalidationTest(
targetBackend = TargetBackend.JS_IR,
workingDirPath = "incrementalOut/invalidation"
)
abstract class AbstractJsIrES6InvalidationTest : IrAbstractInvalidationTest(
targetBackend = TargetBackend.JS_IR_ES6,
workingDirPath = "incrementalOut/invalidationES6"
)
abstract class AbstractJsIrInvalidationWithPLTest : IrAbstractInvalidationTest(
targetBackend = TargetBackend.JS_IR,
workingDirPath = "incrementalOut/invalidationWithPL"
) {
override fun createConfiguration(moduleName: String, language: List<String>, moduleKind: ModuleKind): CompilerConfiguration {
val config = super.createConfiguration(moduleName, language, moduleKind)
config.setupPartialLinkageConfig(PartialLinkageConfig(PartialLinkageMode.ENABLE, PartialLinkageLogLevel.WARNING))
return config
}
}
abstract class IrAbstractInvalidationTest(
targetBackend: TargetBackend,
@@ -0,0 +1,75 @@
/*
* Copyright 2010-2023 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.incremental;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.util.KtTestUtil;
import org.jetbrains.kotlin.test.TargetBackend;
import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.GenerateJsTestsKt}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("js/js.translator/testData/incremental/invalidationWithPL")
@TestDataPath("$PROJECT_ROOT")
public class JsIrInvalidationWithPLTestGenerated extends AbstractJsIrInvalidationWithPLTest {
@Test
public void testAllFilesPresentInInvalidationWithPL() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/incremental/invalidationWithPL"), Pattern.compile("^([^_](.+))$"), null, TargetBackend.JS_IR, false);
}
@Test
@TestMetadata("changeFunctionSignature")
public void testChangeFunctionSignature() throws Exception {
runTest("js/js.translator/testData/incremental/invalidationWithPL/changeFunctionSignature/");
}
@Test
@TestMetadata("interfaceBecomeClass")
public void testInterfaceBecomeClass() throws Exception {
runTest("js/js.translator/testData/incremental/invalidationWithPL/interfaceBecomeClass/");
}
@Test
@TestMetadata("removeFunction")
public void testRemoveFunction() throws Exception {
runTest("js/js.translator/testData/incremental/invalidationWithPL/removeFunction/");
}
@Test
@TestMetadata("removeFunctionFromBlock")
public void testRemoveFunctionFromBlock() throws Exception {
runTest("js/js.translator/testData/incremental/invalidationWithPL/removeFunctionFromBlock/");
}
@Test
@TestMetadata("removeFunctionFromChainCall")
public void testRemoveFunctionFromChainCall() throws Exception {
runTest("js/js.translator/testData/incremental/invalidationWithPL/removeFunctionFromChainCall/");
}
@Test
@TestMetadata("removeFunctionFromElvis")
public void testRemoveFunctionFromElvis() throws Exception {
runTest("js/js.translator/testData/incremental/invalidationWithPL/removeFunctionFromElvis/");
}
@Test
@TestMetadata("removeFunctionFromInline")
public void testRemoveFunctionFromInline() throws Exception {
runTest("js/js.translator/testData/incremental/invalidationWithPL/removeFunctionFromInline/");
}
@Test
@TestMetadata("removeInlineFunction")
public void testRemoveInlineFunction() throws Exception {
runTest("js/js.translator/testData/incremental/invalidationWithPL/removeInlineFunction/");
}
}
@@ -0,0 +1 @@
fun foo() = 0
@@ -0,0 +1 @@
fun foo(x: Int) = x + 1
@@ -0,0 +1 @@
fun foo() = 2
@@ -0,0 +1,3 @@
// this is known issue, that return type doesn not affect IdSignature
// https://youtrack.jetbrains.com/issue/KT-51707
fun foo() = "4"
@@ -0,0 +1 @@
fun foo(x: Int = 1) = "${x + 5}"
@@ -0,0 +1,27 @@
STEP 0:
modifications:
U : l1.0.kt -> l1.kt
added file: l1.kt
STEP 1:
modifications:
U : l1.1.kt -> l1.kt
modified ir: l1.kt
updated exports: l1.kt
STEP 2:
modifications:
U : l1.2.kt -> l1.kt
modified ir: l1.kt
updated exports: l1.kt
STEP 3:
STEP 4:
modifications:
U : l1.4.bug.kt -> l1.kt
modified ir: l1.kt
STEP 5:
STEP 6:
modifications:
U : l1.6.kt -> l1.kt
modified ir: l1.kt
updated exports: l1.kt
STEP 7:
updated exports: l1.kt
@@ -0,0 +1,11 @@
fun box(stepId: Int): String {
val x = test()
if (stepId == 4) {
// this is known issue, that return type doesn not affect IdSignature
// https://youtrack.jetbrains.com/issue/KT-51707
if (x != 41) return "Fail; got $x"
} else {
if (stepId != x) return "Fail; got $x"
}
return "OK"
}
@@ -0,0 +1,28 @@
STEP 0:
dependencies: lib1
modifications:
U : test.0.kt -> test.kt
added file: m.kt, test.kt
STEP 1..2:
dependencies: lib1
rebuild klib: false
updated imports: test.kt
STEP 3:
dependencies: lib1
modifications:
U : test.3.kt -> test.kt
modified ir: test.kt
STEP 4:
dependencies: lib1
rebuild klib: false
updated imports: test.kt
STEP 5:
dependencies: lib1
modified ir: test.kt
STEP 6:
dependencies: lib1
rebuild klib: false
updated imports: test.kt
STEP 7:
dependencies: lib1
modified ir: test.kt
@@ -0,0 +1,7 @@
fun test(): Int {
try {
return foo()
} catch (e: Error) {
return 1
}
}
@@ -0,0 +1,7 @@
fun test(): Int {
try {
return foo().toInt() + 1
} catch (e: Error) {
return 6
}
}
@@ -0,0 +1,20 @@
MODULES: lib1, main
STEP 0..2:
libs: lib1, main
dirty js: lib1, main
STEP 3:
libs: lib1, main
dirty js: main
STEP 4:
libs: lib1, main
dirty js: lib1, main
STEP 5:
libs: lib1, main
dirty js: main
STEP 6:
libs: lib1, main
dirty js: lib1, main
STEP 7:
libs: lib1, main
dirty js: lib1, main
@@ -0,0 +1,3 @@
interface Foo {
fun getSomething() = 0
}
@@ -0,0 +1,3 @@
open class Foo {
fun getSomething() = 77
}
@@ -0,0 +1,3 @@
interface Foo {
fun getSomething() = 2
}
@@ -0,0 +1,3 @@
open class Foo {
open fun getSomething() = 7
}
@@ -0,0 +1,21 @@
STEP 0:
modifications:
U : l1.0.kt -> l1.kt
added file: l1.kt
STEP 1:
modifications:
U : l1.1.kt -> l1.kt
modified ir: l1.kt
STEP 2:
modifications:
U : l1.2.kt -> l1.kt
modified ir: l1.kt
STEP 3..4:
STEP 5:
modifications:
U : l1.5.kt -> l1.kt
modified ir: l1.kt
STEP 6:
updated exports: l1.kt
STEP 7:
@@ -0,0 +1,2 @@
open class Bar : Foo {
}
@@ -0,0 +1,3 @@
open class Bar : Foo {
override fun getSomething() = 3
}
@@ -0,0 +1,3 @@
interface Bar : Foo {
override fun getSomething() = 4
}
@@ -0,0 +1,3 @@
open class Bar : Foo() {
override fun getSomething() = 6
}
@@ -0,0 +1,2 @@
open class Bar : Foo() {
}
@@ -0,0 +1,34 @@
STEP 0:
dependencies: lib1
modifications:
U : l2.0.kt -> l2.kt
added file: l2.kt
STEP 1..2:
dependencies: lib1
rebuild klib: false
updated imports: l2.kt
STEP 3:
dependencies: lib1
modifications:
U : l2.3.kt -> l2.kt
modified ir: l2.kt
STEP 4:
dependencies: lib1
modifications:
U : l2.4.kt -> l2.kt
modified ir: l2.kt
STEP 5:
dependencies: lib1
rebuild klib: false
updated exports: l2.kt
updated imports: l2.kt
STEP 6:
dependencies: lib1
modifications:
U : l2.6.kt -> l2.kt
modified ir: l2.kt
STEP 7:
dependencies: lib1
modifications:
U : l2.7.kt -> l2.kt
modified ir: l2.kt
@@ -0,0 +1,2 @@
class Klass: Bar() {
}
@@ -0,0 +1,2 @@
class Klass: Bar {
}
@@ -0,0 +1,3 @@
class Klass: Bar() {
override fun getSomething() = super.getSomething()
}
@@ -0,0 +1,5 @@
fun box(stepId: Int): String {
val x = test()
if (stepId != x) return "Fail; got $x"
return "OK"
}
@@ -0,0 +1,35 @@
STEP 0:
dependencies: lib1, lib2
modifications:
U : klass.0.kt -> klass.kt
U : test.0.kt -> test.kt
added file: m.kt, test.kt, klass.kt
STEP 1..2:
dependencies: lib1, lib2
rebuild klib: false
updated imports: test.kt, klass.kt
STEP 3:
dependencies: lib1, lib2
rebuild klib: false
STEP 4:
dependencies: lib1, lib2
modifications:
U : klass.4.kt -> klass.kt
U : test.4.kt -> test.kt
modified ir: klass.kt, test.kt
STEP 5:
dependencies: lib1, lib2
rebuild klib: false
updated exports: klass.kt
updated imports: test.kt, klass.kt
STEP 6:
dependencies: lib1, lib2
modifications:
U : klass.6.kt -> klass.kt
modified ir: klass.kt
updated exports: klass.kt
updated imports: test.kt
STEP 7:
dependencies: lib1, lib2
rebuild klib: false
updated imports: klass.kt
@@ -0,0 +1,7 @@
fun test(): Int {
try {
return Klass().getSomething()
} catch (e: Error) {
return 1
}
}
@@ -0,0 +1,7 @@
fun test(): Int {
try {
return Klass().getSomething()
} catch (e: Error) {
return 5
}
}
@@ -0,0 +1,17 @@
MODULES: lib1, lib2, main
STEP 0..2:
libs: lib1, lib2, main
dirty js: lib1, lib2, main
STEP 3:
libs: lib1, lib2, main
dirty js: lib1, lib2
STEP 4:
libs: lib1, lib2, main
dirty js: lib2, main
STEP 5..6:
libs: lib1, lib2, main
dirty js: lib1, lib2, main
STEP 7:
libs: lib1, lib2, main
dirty js: lib2, main
@@ -0,0 +1 @@
fun foo() = 0
@@ -0,0 +1 @@
fun bar() = 2
@@ -0,0 +1 @@
fun foo() = 2
@@ -0,0 +1,14 @@
STEP 0:
modifications:
U : l1.0.kt -> l1.kt
added file: l1.kt
STEP 1:
modifications:
U : l1.1.kt -> l1.kt
modified ir: l1.kt
updated exports: l1.kt
STEP 2:
modifications:
U : l1.2.kt -> l1.kt
modified ir: l1.kt
updated exports: l1.kt
@@ -0,0 +1,5 @@
fun box(stepId: Int): String {
val x = test()
if (stepId != x) return "Fail; got $x"
return "OK"
}
@@ -0,0 +1,8 @@
STEP 0:
dependencies: lib1
modifications:
added file: m.kt, test.kt
STEP 1..2:
dependencies: lib1
rebuild klib: false
updated imports: test.kt
@@ -0,0 +1,7 @@
fun test(): Int {
try {
return foo().toInt()
} catch (e: Error) {
return 1
}
}
@@ -0,0 +1,5 @@
MODULES: lib1, main
STEP 0..2:
libs: lib1, main
dirty js: lib1, main
@@ -0,0 +1,3 @@
fun foo() {
fooX = 0
}
@@ -0,0 +1,3 @@
fun bar() {
fooX = 1
}
@@ -0,0 +1,3 @@
fun foo() {
fooX = 2
}
@@ -0,0 +1 @@
inline fun baz() = 10
@@ -0,0 +1 @@
inline fun baz() = 11
@@ -0,0 +1 @@
var fooX = -100
@@ -0,0 +1,19 @@
STEP 0:
modifications:
U : l1a.0.kt -> l1a.kt
U : l1b.0.kt -> l1b.kt
added file: l1a.kt, l1b.kt, l1c.kt
STEP 1:
modifications:
U : l1a.1.kt -> l1a.kt
modified ir: l1a.kt
updated exports: l1a.kt, l1c.kt
STEP 2:
modifications:
U : l1a.2.kt -> l1a.kt
modified ir: l1a.kt
updated exports: l1a.kt, l1c.kt
STEP 3:
modifications:
U : l1b.3.kt -> l1b.kt
modified ir: l1b.kt
@@ -0,0 +1,5 @@
fun box(stepId: Int): String {
val x = test()
if (stepId != x) return "Fail; got $x"
return "OK"
}
@@ -0,0 +1,8 @@
STEP 0:
dependencies: lib1
modifications:
added file: m.kt, test.kt
STEP 1..3:
dependencies: lib1
rebuild klib: false
updated imports: test.kt
@@ -0,0 +1,13 @@
internal fun doTest() : Int {
foo()
val y = baz()
return y + fooX - 10
}
fun test(): Int {
try {
return doTest()
} catch (e: Error) {
return 1
}
}
@@ -0,0 +1,5 @@
MODULES: lib1, main
STEP 0..3:
libs: lib1, main
dirty js: lib1, main
@@ -0,0 +1,3 @@
class Klass {
inline fun foo() = 0
}
@@ -0,0 +1,3 @@
class Klass {
inline fun foo() = 3
}
@@ -0,0 +1,3 @@
class Klass {
inline fun foo() = 4
}
@@ -0,0 +1 @@
fun makeKlass() = Klass()
@@ -0,0 +1 @@
fun makeKlassOther() = Klass()
@@ -0,0 +1 @@
fun makeKlass() = Klass()
@@ -0,0 +1,23 @@
STEP 0:
modifications:
U : klass.0.kt -> klass.kt
U : l1a.0.kt -> l1a.kt
added file: l1a.kt, klass.kt
STEP 1:
modifications:
U : l1a.1.kt -> l1a.kt
modified ir: l1a.kt
updated exports: l1a.kt, klass.kt
STEP 2:
modifications:
U : klass.2.kt -> klass.kt
modified ir: klass.kt
STEP 3:
modifications:
U : l1a.3.kt -> l1a.kt
modified ir: l1a.kt
updated exports: l1a.kt, klass.kt
STEP 4:
modifications:
U : klass.4.kt -> klass.kt
modified ir: klass.kt
@@ -0,0 +1,11 @@
fun box(stepId: Int): String {
val x = test()
val expected = when (stepId) {
0, 1, 3, 4 -> stepId
2 -> 1
else -> return "Unknown"
}
if (expected != x) return "Fail; $expected != $x"
return "OK"
}
@@ -0,0 +1,8 @@
STEP 0:
dependencies: lib1
modifications:
added file: m.kt, test.kt
STEP 1..4:
dependencies: lib1
rebuild klib: false
updated imports: test.kt
@@ -0,0 +1,7 @@
fun test(): Int {
try {
return makeKlass().foo()
} catch (e: Error) {
return 1
}
}
@@ -0,0 +1,5 @@
MODULES: lib1, main
STEP 0..4:
libs: lib1, main
dirty js: lib1, main
@@ -0,0 +1 @@
inline fun foo(): Int? = null
@@ -0,0 +1 @@
inline fun foo77(): Int? = 77
@@ -0,0 +1 @@
inline fun foo(): Int? = 3
@@ -0,0 +1 @@
inline fun foo(): Int? = null
@@ -0,0 +1 @@
inline fun bar() = 0
@@ -0,0 +1 @@
inline fun bar() = 4
@@ -0,0 +1,23 @@
STEP 0:
modifications:
U : l1a.0.kt -> l1a.kt
U : l1b.0.kt -> l1b.kt
added file: l1a.kt, l1b.kt
STEP 1:
modifications:
U : l1a.1.kt -> l1a.kt
modified ir: l1a.kt
updated exports: l1a.kt
STEP 2:
modifications:
U : l1b.2.kt -> l1b.kt
modified ir: l1b.kt
STEP 3:
modifications:
U : l1a.3.kt -> l1a.kt
modified ir: l1a.kt
updated exports: l1a.kt
STEP 4:
modifications:
U : l1a.4.kt -> l1a.kt
modified ir: l1a.kt
@@ -0,0 +1,11 @@
fun box(stepId: Int): String {
val x = test()
val expected = when (stepId) {
0, 1, 3, 4 -> stepId
2 -> 1
else -> return "Unknown"
}
if (expected != x) return "Fail; $expected != $x"
return "OK"
}
@@ -0,0 +1,8 @@
STEP 0:
dependencies: lib1
modifications:
added file: m.kt, test.kt
STEP 1..4:
dependencies: lib1
rebuild klib: false
updated imports: test.kt
@@ -0,0 +1,7 @@
fun test(): Int {
try {
return foo() ?: bar()
} catch (e: Error) {
return 1
}
}
@@ -0,0 +1,5 @@
MODULES: lib1, main
STEP 0..4:
libs: lib1, main
dirty js: lib1, main
@@ -0,0 +1 @@
fun foo() = 0
@@ -0,0 +1 @@
fun bar() = 77
@@ -0,0 +1 @@
fun foo() = 2
@@ -0,0 +1,14 @@
STEP 0:
modifications:
U : l1.0.kt -> l1.kt
added file: l1.kt
STEP 1:
modifications:
U : l1.1.kt -> l1.kt
modified ir: l1.kt
updated exports: l1.kt
STEP 2:
modifications:
U : l1.2.kt -> l1.kt
modified ir: l1.kt
updated exports: l1.kt
@@ -0,0 +1 @@
inline fun inlineFun() = foo()
@@ -0,0 +1,7 @@
STEP 0:
dependencies: lib1
added file: l2.kt
STEP 1..2:
dependencies: lib1
rebuild klib: false
updated imports: l2.kt
@@ -0,0 +1,5 @@
fun box(stepId: Int): String {
val x = test()
if (x != stepId) return "Fail; got $x"
return "OK"
}
@@ -0,0 +1,7 @@
STEP 0:
dependencies: lib1, lib2
added file: m.kt, test.kt
STEP 1..2:
dependencies: lib1, lib2
rebuild klib: false
updated imports: test.kt
@@ -0,0 +1,7 @@
fun test(): Int {
try {
return inlineFun()
} catch (e: Error) {
return 1
}
}
@@ -0,0 +1,5 @@
MODULES: lib1, lib2, main
STEP 0..2:
libs: lib1, lib2, main
dirty js: lib1, lib2, main
@@ -0,0 +1 @@
inline fun foo() = -1
@@ -0,0 +1 @@
inline fun foo() = 1
@@ -0,0 +1 @@
inline fun inlineFoo(f: () -> Int) = f() + 1
@@ -0,0 +1 @@
inline fun inlineBar(f: () -> Int) = f() + 1
@@ -0,0 +1 @@
inline fun inlineFoo(f: () -> Int) = f() + 2
@@ -0,0 +1 @@
inline fun inlineFoo(f: () -> Int) = f() + 3
@@ -0,0 +1,23 @@
STEP 0:
modifications:
U : l1a.0.kt -> l1a.kt
U : l1b.0.kt -> l1b.kt
added file: l1a.kt, l1b.kt
STEP 1:
modifications:
U : l1b.1.kt -> l1b.kt
modified ir: l1b.kt
updated exports: l1b.kt
STEP 2:
modifications:
U : l1a.2.kt -> l1a.kt
modified ir: l1a.kt
STEP 3:
modifications:
U : l1b.3.kt -> l1b.kt
modified ir: l1b.kt
updated exports: l1b.kt
STEP 4:
modifications:
U : l1b.4.kt -> l1b.kt
modified ir: l1b.kt
@@ -0,0 +1,11 @@
fun box(stepId: Int): String {
val x = test()
val expected = when (stepId) {
0, 1, 3, 4 -> stepId
2 -> 1
else -> return "Unknown"
}
if (expected != x) return "Fail; $expected != $x"
return "OK"
}
@@ -0,0 +1,8 @@
STEP 0:
dependencies: lib1
modifications:
added file: m.kt, test.kt
STEP 1..4:
dependencies: lib1
rebuild klib: false
updated imports: test.kt
@@ -0,0 +1,7 @@
fun test(): Int {
try {
return inlineFoo { foo() }
} catch (e: Error) {
return 1
}
}
@@ -0,0 +1,5 @@
MODULES: lib1, main
STEP 0..4:
libs: lib1, main
dirty js: lib1, main