diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/HashCalculatorForIC.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/HashCalculatorForIC.kt index 7f9b5f5cb68..ada2ac95f7d 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/HashCalculatorForIC.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/HashCalculatorForIC.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.CrossModuleReferences import org.jetbrains.kotlin.ir.IrElement +import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.util.DumpIrTreeVisitor @@ -110,6 +111,13 @@ internal fun IrSymbol.irSymbolHashForIC() = HashCalculatorForIC().also { it.update(typeParameter.symbol.toString()) } } + (owner as? IrFunction)?.let { irFunction -> + it.updateForEach(irFunction.valueParameters) { functionParam -> + // symbol rendering doesn't print default params information + // it is important to understand if default params were added or removed + it.update(functionParam.defaultValue?.let { 1 } ?: 0) + } + } }.finalize() internal fun String.stringHashForIC() = HashCalculatorForIC().also { it.update(this) }.finalize() diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/incremental/InvalidationTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/incremental/InvalidationTestGenerated.java index 2a54659c2ea..8616fb6dff4 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/incremental/InvalidationTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/incremental/InvalidationTestGenerated.java @@ -200,6 +200,11 @@ public class InvalidationTestGenerated extends AbstractInvalidationTest { runTest("js/js.translator/testData/incremental/invalidation/inlineFunctionWithObject/"); } + @TestMetadata("interfaceWithDefaultParams") + public void testInterfaceWithDefaultParams() throws Exception { + runTest("js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/"); + } + @TestMetadata("jsCode") public void testJsCode() throws Exception { runTest("js/js.translator/testData/incremental/invalidation/jsCode/"); diff --git a/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib1/l1.0.kt b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib1/l1.0.kt new file mode 100644 index 00000000000..a29d8e3ecdb --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib1/l1.0.kt @@ -0,0 +1,3 @@ +interface InterfaceA { + fun functionA(x: Int, s: String, b: Boolean? = null): Int +} diff --git a/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib1/l1.1.kt b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib1/l1.1.kt new file mode 100644 index 00000000000..17ea90661ab --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib1/l1.1.kt @@ -0,0 +1,3 @@ +interface InterfaceA { + fun functionA(x: Int, s: String, b: Boolean?): Int +} diff --git a/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib1/l1.2.kt b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib1/l1.2.kt new file mode 100644 index 00000000000..d9a7fb98521 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib1/l1.2.kt @@ -0,0 +1,3 @@ +interface InterfaceA { + fun functionA(x: Int, s: String, b: Boolean? = true): Int +} diff --git a/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib1/l1.4.kt b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib1/l1.4.kt new file mode 100644 index 00000000000..18400594fb5 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib1/l1.4.kt @@ -0,0 +1,3 @@ +interface InterfaceA { + fun functionA(x: Int, s: String, b: Boolean? = true, i: Int = 1): Int +} diff --git a/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib1/l1.6.kt b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib1/l1.6.kt new file mode 100644 index 00000000000..4e15ef246ae --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib1/l1.6.kt @@ -0,0 +1,3 @@ +interface InterfaceA { + fun functionA(x: Int, s: String = "xy", b: Boolean? = true, i: Int): Int +} diff --git a/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib1/l1.8.kt b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib1/l1.8.kt new file mode 100644 index 00000000000..dc1ed832bee --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib1/l1.8.kt @@ -0,0 +1,3 @@ +interface InterfaceA { + fun functionA(x: Int, s: String = "xyz!", b: Boolean? = false, i: Int): Int +} diff --git a/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib1/module.info b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib1/module.info new file mode 100644 index 00000000000..4748735eba8 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib1/module.info @@ -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 +STEP 2: + modifications: + U : l1.2.kt -> l1.kt + modified ir: l1.kt +STEP 3: +STEP 4: + modifications: + U : l1.4.kt -> l1.kt + modified ir: l1.kt +STEP 5: +STEP 6: + modifications: + U : l1.6.kt -> l1.kt + modified ir: l1.kt +STEP 7: +STEP 8: + modifications: + U : l1.8.kt -> l1.kt + modified ir: l1.kt diff --git a/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib2/l2.0.kt b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib2/l2.0.kt new file mode 100644 index 00000000000..28335a4afdb --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib2/l2.0.kt @@ -0,0 +1,5 @@ +class ClassA : InterfaceA { + override fun functionA(x: Int, s: String, b: Boolean?): Int { + return x + s.length + if (b == true) 1 else 0 + } +} diff --git a/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib2/l2.4.kt b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib2/l2.4.kt new file mode 100644 index 00000000000..846ca1f63c3 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib2/l2.4.kt @@ -0,0 +1,5 @@ +class ClassA : InterfaceA { + override fun functionA(x: Int, s: String, b: Boolean?, i: Int): Int { + return i - 1 + x + s.length + if (b == true) 1 else 0 + } +} diff --git a/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib2/l2test.0.kt b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib2/l2test.0.kt new file mode 100644 index 00000000000..2f9ae6b9e8d --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib2/l2test.0.kt @@ -0,0 +1,7 @@ +private fun test(setepId: Int, i: InterfaceA): Int { + return i.functionA(setepId, "", false) +} + +fun testDefaltParam(setepId: Int): Int { + return test(setepId, ClassA()) +} diff --git a/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib2/l2test.3.kt b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib2/l2test.3.kt new file mode 100644 index 00000000000..457e91a6074 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib2/l2test.3.kt @@ -0,0 +1,7 @@ +private fun test(setepId: Int, i: InterfaceA): Int { + return i.functionA(setepId - 1, "") +} + +fun testDefaltParam(setepId: Int): Int { + return test(setepId, ClassA()) +} diff --git a/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib2/l2test.5.kt b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib2/l2test.5.kt new file mode 100644 index 00000000000..dd9b3d8e3b3 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib2/l2test.5.kt @@ -0,0 +1,12 @@ +private fun test(setepId: Int, i: InterfaceA): Int { + return i.functionA( + x = setepId - 2, + s = "s", + b = false, + i = 2 + ) +} + +fun testDefaltParam(setepId: Int): Int { + return test(setepId, ClassA()) +} diff --git a/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib2/l2test.7.kt b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib2/l2test.7.kt new file mode 100644 index 00000000000..00e9d81d224 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib2/l2test.7.kt @@ -0,0 +1,10 @@ +private fun test(setepId: Int, i: InterfaceA): Int { + return i.functionA( + x = 3, + i = 2 + ) +} + +fun testDefaltParam(setepId: Int): Int { + return test(setepId, ClassA()) +} diff --git a/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib2/module.info b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib2/module.info new file mode 100644 index 00000000000..69cc0eac0b1 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/lib2/module.info @@ -0,0 +1,34 @@ +STEP 0: + dependencies: lib1 + modifications: + U : l2.0.kt -> l2.kt + U : l2test.0.kt -> l2test.kt + added file: l2.kt, l2test.kt +STEP 1..2: + dependencies: lib1 + updated imports: l2test.kt, l2.kt +STEP 3: + dependencies: lib1 + modifications: + U : l2test.3.kt -> l2test.kt + modified ir: l2test.kt +STEP 4: + dependencies: lib1 + modifications: + U : l2.4.kt -> l2.kt + modified ir: l2.kt, l2test.kt +STEP 5: + dependencies: lib1 + modifications: + U : l2test.5.kt -> l2test.kt + modified ir: l2test.kt +STEP 6: + dependencies: lib1 + updated imports: l2.kt, l2test.kt +STEP 7: + dependencies: lib1 + modifications: + U : l2test.7.kt -> l2test.kt + modified ir: l2test.kt +STEP 8: + dependencies: lib1 diff --git a/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/main/m.kt b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/main/m.kt new file mode 100644 index 00000000000..e2012d1f849 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/main/m.kt @@ -0,0 +1,7 @@ +fun box(stepId: Int): String { + val x = testDefaltParam(stepId) + if (x != stepId) { + return "Fail, got $x, expected $stepId" + } + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/main/module.info b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/main/module.info new file mode 100644 index 00000000000..2c1bc274a52 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/main/module.info @@ -0,0 +1,5 @@ +STEP 0: + dependencies: lib1, lib2 + added file: m.kt +STEP 1..8: + dependencies: lib1, lib2 diff --git a/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/project.info b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/project.info new file mode 100644 index 00000000000..0a516bb94a3 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/interfaceWithDefaultParams/project.info @@ -0,0 +1,26 @@ +MODULES: lib1, lib2, main + +STEP 0: + libs: lib1, lib2, main + dirty js: lib1, lib2, main +STEP 1..2: + libs: lib1, lib2, main + dirty js: lib1, lib2 +STEP 3: + libs: lib1, lib2, main + dirty js: lib2 +STEP 4: + libs: lib1, lib2, main + dirty js: lib1, lib2 +STEP 5: + libs: lib1, lib2, main + dirty js: lib2 +STEP 6: + libs: lib1, lib2, main + dirty js: lib1, lib2 +STEP 7: + libs: lib1, lib2, main + dirty js: lib2 +STEP 8: + libs: lib1, lib2, main + dirty js: lib1