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 6bc32cedbe71c..6a9e7adc8c8f6 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 @@ -13,6 +13,8 @@ import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.CrossModuleReferen import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrAnnotationContainer import org.jetbrains.kotlin.ir.declarations.IrFunction +import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction +import org.jetbrains.kotlin.ir.declarations.IrProperty import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.util.DumpIrTreeVisitor @@ -139,6 +141,11 @@ internal class ICHasher { } } (symbol.owner as? IrAnnotationContainer)?.let(hashCalculator::updateAnnotationContainer) + (symbol.owner as? IrProperty)?.let { irProperty -> + if (irProperty.isConst) { + irProperty.backingField?.initializer?.let(hashCalculator::update) + } + } return hashCalculator.finalize() } } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/jsCode.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/jsCode.kt index a8c6af82cf889..e976b2284eded 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/jsCode.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/jsCode.kt @@ -63,7 +63,7 @@ private fun translateJsCodeIntoStatementList( return parseExpressionOrStatement(jsCode, ThrowExceptionOnErrorReporter, currentScope, CodePosition(startLine, offset), fileName) } -fun foldString(expression: IrExpression, context: JsIrBackendContext?): String? { +private fun foldString(expression: IrExpression, context: JsIrBackendContext?): String? { val builder = StringBuilder() var foldingFailed = false expression.acceptVoid(object : IrElementVisitorVoid { @@ -92,6 +92,7 @@ fun foldString(expression: IrExpression, context: JsIrBackendContext?): String? override fun visitCall(expression: IrCall) { val owner = expression.symbol.owner + val propertySymbol = owner.correspondingPropertySymbol return when { expression.origin == IrStatementOrigin.PLUS -> expression.acceptChildrenVoid(this) @@ -99,8 +100,17 @@ fun foldString(expression: IrExpression, context: JsIrBackendContext?): String? owner.body?.acceptChildrenVoid(InitFunVisitor(context)) expression.acceptChildrenVoid(this) } - owner == owner.correspondingPropertySymbol?.owner?.getter -> { - owner.body?.acceptChildrenVoid(this) + propertySymbol != null && owner == propertySymbol.owner.getter -> { + if (propertySymbol.owner.isConst) { + val initializer = propertySymbol.owner.backingField?.initializer + if (initializer != null) { + initializer.acceptChildrenVoid(this) + } else { + foldingFailed = true + } + } else { + owner.body?.acceptChildrenVoid(this) + } expression.acceptChildrenVoid(this) } else -> super.visitCall(expression) diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/incremental/JsIrES6InvalidationTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/incremental/JsIrES6InvalidationTestGenerated.java index 1137cd32c10df..d9c879317aa18 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/incremental/JsIrES6InvalidationTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/incremental/JsIrES6InvalidationTestGenerated.java @@ -250,6 +250,11 @@ public void testJsCode() throws Exception { runTest("js/js.translator/testData/incremental/invalidation/jsCode/"); } + @TestMetadata("jsCodeWithConstString") + public void testJsCodeWithConstString() throws Exception { + runTest("js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/"); + } + @TestMetadata("jsExport") public void testJsExport() throws Exception { runTest("js/js.translator/testData/incremental/invalidation/jsExport/"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/incremental/JsIrInvalidationTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/incremental/JsIrInvalidationTestGenerated.java index 81aced2458ceb..040c47454abea 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/incremental/JsIrInvalidationTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/incremental/JsIrInvalidationTestGenerated.java @@ -250,6 +250,11 @@ public void testJsCode() throws Exception { runTest("js/js.translator/testData/incremental/invalidation/jsCode/"); } + @TestMetadata("jsCodeWithConstString") + public void testJsCodeWithConstString() throws Exception { + runTest("js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/"); + } + @TestMetadata("jsExport") public void testJsExport() throws Exception { runTest("js/js.translator/testData/incremental/invalidation/jsExport/"); diff --git a/js/js.translator/testData/incremental/invalidation/constVals/lib2/module.info b/js/js.translator/testData/incremental/invalidation/constVals/lib2/module.info index d1d31ca561885..e3581e75e4a55 100644 --- a/js/js.translator/testData/incremental/invalidation/constVals/lib2/module.info +++ b/js/js.translator/testData/incremental/invalidation/constVals/lib2/module.info @@ -3,3 +3,4 @@ STEP 0: added file: l2.kt STEP 1: dependencies: lib1 + updated imports: l2.kt diff --git a/js/js.translator/testData/incremental/invalidation/constVals/project.info b/js/js.translator/testData/incremental/invalidation/constVals/project.info index 3a84c058f4efe..f1968258cbddd 100644 --- a/js/js.translator/testData/incremental/invalidation/constVals/project.info +++ b/js/js.translator/testData/incremental/invalidation/constVals/project.info @@ -5,4 +5,4 @@ STEP 0: dirty js: lib1, lib2, main STEP 1: libs: lib1, lib2, main - dirty js: lib1 + dirty js: lib1, lib2 diff --git a/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/js.0.kt b/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/js.0.kt new file mode 100644 index 0000000000000..58b0cb0bceaf2 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/js.0.kt @@ -0,0 +1,3 @@ +fun test() : dynamic { + return js("var testObj = { $constKey: 0 }; testObj.$constKey") +} diff --git a/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/js.1.kt b/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/js.1.kt new file mode 100644 index 0000000000000..0178a191ccedf --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/js.1.kt @@ -0,0 +1,3 @@ +fun test() : dynamic { + return js("var testObj = { $constKey: 1 }; testObj.$constKey") +} diff --git a/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/js.2.kt b/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/js.2.kt new file mode 100644 index 0000000000000..875fefa0a0238 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/js.2.kt @@ -0,0 +1,3 @@ +fun test() : dynamic { + return js("var testObj = { $constKey: $constVal }; testObj.$constKey") +} diff --git a/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/js.6.kt b/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/js.6.kt new file mode 100644 index 0000000000000..882e6b8832eac --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/js.6.kt @@ -0,0 +1,3 @@ +fun test() : dynamic { + return js("var testObj = { ${constKey1}__bar: $constVal + 1 }; testObj.foo__$constKey2") +} diff --git a/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/l1.0.kt b/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/l1.0.kt new file mode 100644 index 0000000000000..10bd1daa5d87b --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/l1.0.kt @@ -0,0 +1,4 @@ +internal const val constKey = "foo" + +internal const val constVal = "2" + diff --git a/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/l1.3.kt b/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/l1.3.kt new file mode 100644 index 0000000000000..d28821835bd9a --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/l1.3.kt @@ -0,0 +1,7 @@ +internal const val constKey1 = "foo" +internal const val constKey2 = "bar" + +internal const val constKey = constKey1 + "_" + constKey2 + +internal const val constVal = "3" + diff --git a/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/l1.5.kt b/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/l1.5.kt new file mode 100644 index 0000000000000..ea30024b87673 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/l1.5.kt @@ -0,0 +1,7 @@ +internal const val constKey1 = "foo" +internal const val constKey2 = "bar" + +internal const val constKey = constKey1 + "__" + constKey2 + +internal const val constVal = "4" + diff --git a/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/l1.7.kt b/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/l1.7.kt new file mode 100644 index 0000000000000..a2fc3ba44dd3d --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/l1.7.kt @@ -0,0 +1,7 @@ +internal const val constKey1 = "foo" +internal const val constKey2 = "bar" + +internal const val constKey = constKey1 + "__" + constKey2 + +internal const val constVal = 5 + diff --git a/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/module.info b/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/module.info new file mode 100644 index 0000000000000..d0496c3a3e87d --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/module.info @@ -0,0 +1,38 @@ +STEP 0: + modifications: + U : l1.0.kt -> l1.kt + U : js.0.kt -> js.kt + U : test.0.kt -> test.kt + added file: l1.kt, js.kt, test.kt +STEP 1: + modifications: + U : js.1.kt -> js.kt + modified ir: js.kt +STEP 2: + modifications: + U : js.2.kt -> js.kt + modified ir: js.kt + updated exports: l1.kt +STEP 3: + modifications: + U : l1.3.kt -> l1.kt + modified ir: l1.kt + updated imports: js.kt +STEP 4: + modifications: + U : test.4.kt -> test.kt + modified ir: test.kt +STEP 5: + modifications: + U : l1.5.kt -> l1.kt + modified ir: l1.kt + updated imports: js.kt +STEP 6: + modifications: + U : js.6.kt -> js.kt + modified ir: js.kt + updated exports: l1.kt +STEP 7: + modifications: + U : l1.7.kt -> l1.kt + modified ir: l1.kt, js.kt diff --git a/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/test.0.kt b/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/test.0.kt new file mode 100644 index 0000000000000..7d2b2081795fb --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/test.0.kt @@ -0,0 +1 @@ +fun doTest() = test() diff --git a/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/test.4.kt b/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/test.4.kt new file mode 100644 index 0000000000000..e5dbf0f159fc8 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/lib1/test.4.kt @@ -0,0 +1 @@ +fun doTest() = test() + 1 diff --git a/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/main/m.kt b/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/main/m.kt new file mode 100644 index 0000000000000..dfd50ba62caae --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/main/m.kt @@ -0,0 +1,8 @@ +fun box(stepId: Int): String { + val x = doTest() + when (stepId) { + in 0..7 -> if (x != stepId) return "Fail, got $x" + else -> return "Unknown" + } + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/main/module.info b/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/main/module.info new file mode 100644 index 0000000000000..586221fecd540 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/main/module.info @@ -0,0 +1,5 @@ +STEP 0: + dependencies: lib1 + added file: m.kt +STEP 1..7: + dependencies: lib1 diff --git a/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/project.info b/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/project.info new file mode 100644 index 0000000000000..aa728a8c0c3d3 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/jsCodeWithConstString/project.info @@ -0,0 +1,8 @@ +MODULES: lib1, main + +STEP 0: + libs: lib1, main + dirty js: lib1, main +STEP 1..7: + libs: lib1, main + dirty js: lib1