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 36a0bc1fa87..a365f999deb 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 @@ -10,15 +10,14 @@ import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.CompilerConfigurationKey import org.jetbrains.kotlin.config.KotlinCompilerVersion import org.jetbrains.kotlin.config.languageVersionSettings +import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.CrossModuleReferences 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.IrProperty -import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer +import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.linkage.partial.PartialLinkageConfig import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.util.DumpIrTreeVisitor +import org.jetbrains.kotlin.ir.util.isInterface import org.jetbrains.kotlin.js.config.JSConfigurationKeys import org.jetbrains.kotlin.library.impl.buffer import org.jetbrains.kotlin.protobuf.CodedInputStream @@ -74,6 +73,48 @@ private class HashCalculatorForIC { updateForEach(annotationContainer.annotations, ::update) } + fun updateSymbol(symbol: IrSymbol) { + update(symbol.toString()) + + (symbol.owner as? IrClass)?.takeIf { it.isInterface }?.let { irInterface -> + // Adding or removing a method or property with a default implementation to an interface + // should invalidate all children: we must regenerate JS code for them + val openDeclarationSymbols = buildList { + for (decl in irInterface.declarations) { + if (decl is IrOverridableMember && decl.modality == Modality.OPEN) { + add(decl.symbol) + } + if (decl is IrProperty) { + decl.getter?.takeIf { it.modality == Modality.OPEN }?.symbol?.let(::add) + decl.setter?.takeIf { it.modality == Modality.OPEN }?.symbol?.let(::add) + } + } + } + updateForEach(openDeclarationSymbols, ::updateSymbol) + } + + // symbol rendering prints very little information about type parameters + // TODO may be it make sense to update rendering? + (symbol.owner as? IrTypeParametersContainer)?.let { typeParameters -> + updateForEach(typeParameters.typeParameters) { typeParameter -> + update(typeParameter.symbol.toString()) + } + } + (symbol.owner as? IrFunction)?.let { irFunction -> + updateForEach(irFunction.valueParameters) { functionParam -> + // symbol rendering doesn't print default params information + // it is important to understand if default params were added or removed + update(functionParam.defaultValue?.let { 1 } ?: 0) + } + } + (symbol.owner as? IrAnnotationContainer)?.let(::updateAnnotationContainer) + (symbol.owner as? IrProperty)?.let { irProperty -> + if (irProperty.isConst) { + irProperty.backingField?.initializer?.let(::update) + } + } + } + inline fun updateForEach(collection: Collection, f: (T) -> Unit) { update(collection.size) collection.forEach { f(it) } @@ -92,7 +133,7 @@ private class HashCalculatorForIC { } } - fun finalize(): ICHash { + fun finalizeAndGetHash(): ICHash { val hashBytes = md5Digest.digest() md5Digest.reset() return hashBytes.buffer.asLongBuffer().let { longBuffer -> @@ -142,42 +183,22 @@ internal class ICHasher { } hashCalculator.update(config.languageVersionSettings.toString()) - return hashCalculator.finalize() + return hashCalculator.finalizeAndGetHash() } fun calculateIrFunctionHash(function: IrFunction): ICHash { hashCalculator.update(function) - return hashCalculator.finalize() + return hashCalculator.finalizeAndGetHash() } fun calculateIrAnnotationContainerHash(container: IrAnnotationContainer): ICHash { hashCalculator.updateAnnotationContainer(container) - return hashCalculator.finalize() + return hashCalculator.finalizeAndGetHash() } fun calculateIrSymbolHash(symbol: IrSymbol): ICHash { - hashCalculator.update(symbol.toString()) - // symbol rendering prints very little information about type parameters - // TODO may be it make sense to update rendering? - (symbol.owner as? IrTypeParametersContainer)?.let { typeParameters -> - hashCalculator.updateForEach(typeParameters.typeParameters) { typeParameter -> - hashCalculator.update(typeParameter.symbol.toString()) - } - } - (symbol.owner as? IrFunction)?.let { irFunction -> - hashCalculator.updateForEach(irFunction.valueParameters) { functionParam -> - // symbol rendering doesn't print default params information - // it is important to understand if default params were added or removed - hashCalculator.update(functionParam.defaultValue?.let { 1 } ?: 0) - } - } - (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() + hashCalculator.updateSymbol(symbol) + return hashCalculator.finalizeAndGetHash() } } @@ -213,4 +234,4 @@ internal fun CrossModuleReferences.crossModuleReferencesHashForIC() = HashCalcul update(import.moduleExporter.internalName.toString()) } } -}.finalize() +}.finalizeAndGetHash() diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/incremental/JsFirInvalidationTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/incremental/JsFirInvalidationTestGenerated.java index 630ca17f45e..18b30afcc48 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/incremental/JsFirInvalidationTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/incremental/JsFirInvalidationTestGenerated.java @@ -319,6 +319,12 @@ public class JsFirInvalidationTestGenerated extends AbstractJsFirInvalidationTes runTest("js/js.translator/testData/incremental/invalidation/localInlineFunction/"); } + @Test + @TestMetadata("localObjectsLeakThroughInterface") + public void testLocalObjectsLeakThroughInterface() throws Exception { + runTest("js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/"); + } + @Test @TestMetadata("mainModuleInvalidation") public void testMainModuleInvalidation() throws Exception { @@ -373,6 +379,12 @@ public class JsFirInvalidationTestGenerated extends AbstractJsFirInvalidationTes runTest("js/js.translator/testData/incremental/invalidation/privateInlineFunction1/"); } + @Test + @TestMetadata("privateObjectsLeakThroughSealedInterface") + public void testPrivateObjectsLeakThroughSealedInterface() throws Exception { + runTest("js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/"); + } + @Test @TestMetadata("removeFile") public void testRemoveFile() throws Exception { 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 d98d11c1b80..22d1c96a7f1 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 @@ -319,6 +319,12 @@ public class JsIrES6InvalidationTestGenerated extends AbstractJsIrES6Invalidatio runTest("js/js.translator/testData/incremental/invalidation/localInlineFunction/"); } + @Test + @TestMetadata("localObjectsLeakThroughInterface") + public void testLocalObjectsLeakThroughInterface() throws Exception { + runTest("js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/"); + } + @Test @TestMetadata("mainModuleInvalidation") public void testMainModuleInvalidation() throws Exception { @@ -373,6 +379,12 @@ public class JsIrES6InvalidationTestGenerated extends AbstractJsIrES6Invalidatio runTest("js/js.translator/testData/incremental/invalidation/privateInlineFunction1/"); } + @Test + @TestMetadata("privateObjectsLeakThroughSealedInterface") + public void testPrivateObjectsLeakThroughSealedInterface() throws Exception { + runTest("js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/"); + } + @Test @TestMetadata("removeFile") public void testRemoveFile() throws Exception { 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 6a1bd31e3c8..5c5d2397d8c 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 @@ -319,6 +319,12 @@ public class JsIrInvalidationTestGenerated extends AbstractJsIrInvalidationTest runTest("js/js.translator/testData/incremental/invalidation/localInlineFunction/"); } + @Test + @TestMetadata("localObjectsLeakThroughInterface") + public void testLocalObjectsLeakThroughInterface() throws Exception { + runTest("js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/"); + } + @Test @TestMetadata("mainModuleInvalidation") public void testMainModuleInvalidation() throws Exception { @@ -373,6 +379,12 @@ public class JsIrInvalidationTestGenerated extends AbstractJsIrInvalidationTest runTest("js/js.translator/testData/incremental/invalidation/privateInlineFunction1/"); } + @Test + @TestMetadata("privateObjectsLeakThroughSealedInterface") + public void testPrivateObjectsLeakThroughSealedInterface() throws Exception { + runTest("js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/"); + } + @Test @TestMetadata("removeFile") public void testRemoveFile() throws Exception { diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib1/l1.0.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib1/l1.0.kt index 3766a4b55d2..fc6e0cbe739 100644 --- a/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib1/l1.0.kt +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib1/l1.0.kt @@ -1,3 +1,3 @@ -interface Module2Interface { +interface Module1Interface { public suspend fun testFunction2() = 2 } diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib1/l1.1.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib1/l1.1.kt index 0e7b1c36f47..209b6f4a925 100644 --- a/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib1/l1.1.kt +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib1/l1.1.kt @@ -1,4 +1,4 @@ -interface Module2Interface { +interface Module1Interface { public suspend fun testFunction2() = 2 public fun testFunction22() = 22 } diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib1/l1.2.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib1/l1.2.kt index 6e3f9ff15d3..7d904363b73 100644 --- a/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib1/l1.2.kt +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib1/l1.2.kt @@ -1,4 +1,4 @@ -interface Module2Interface { +interface Module1Interface { public fun testFunction2() = 2 public fun testFunction22() = 22 } diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib1/l1.3.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib1/l1.3.kt index bcf0e97523e..31ae0d67713 100644 --- a/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib1/l1.3.kt +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib1/l1.3.kt @@ -1,4 +1,4 @@ -interface Module2Interface { +interface Module1Interface { public fun testFunction2() = 2 public fun testFunction22() = 22 diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib1/l1.5.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib1/l1.5.kt index 93f491f6412..a629058d84f 100644 --- a/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib1/l1.5.kt +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib1/l1.5.kt @@ -1,4 +1,4 @@ -interface Module2Interface { +interface Module1Interface { public fun testFunction2() = 20 public fun testFunction22() = 220 diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib1/l1.6.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib1/l1.6.kt index e5d0e579872..8d4492e6b69 100644 --- a/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib1/l1.6.kt +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib1/l1.6.kt @@ -1,2 +1,2 @@ -interface Module2Interface { +interface Module1Interface { } diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib1/module.info b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib1/module.info index 3abfddc8e1d..645d764207e 100644 --- a/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib1/module.info +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib1/module.info @@ -15,8 +15,8 @@ STEP 3: modifications: U : l1.3.kt -> l1.kt modified ir: l1.kt -STEP 4: updated exports: l1.kt +STEP 4: STEP 5: modifications: U : l1.5.kt -> l1.kt @@ -30,5 +30,5 @@ STEP 7: modifications: U : l1.0.kt -> l1.kt modified ir: l1.kt -STEP 8: updated exports: l1.kt +STEP 8: diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib2/class2.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib2/class2.kt new file mode 100644 index 00000000000..271dff7e262 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib2/class2.kt @@ -0,0 +1,3 @@ +class Module2Class: Module1Interface { + fun testFunction1() = 1 +} diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib2/l2.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib2/l2.kt deleted file mode 100644 index 674837960c7..00000000000 --- a/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib2/l2.kt +++ /dev/null @@ -1,3 +0,0 @@ -class Module1Class: Module2Interface { - fun testFunction1() = 1 -} diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib2/module.info b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib2/module.info index 90676e5f9a9..61bceeab62e 100644 --- a/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib2/module.info +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib2/module.info @@ -1,25 +1,28 @@ STEP 0: dependencies: lib1 - added file: l2.kt + added file: class2.kt, object2.kt STEP 1: dependencies: lib1 - updated exports: l2.kt + updated exports: class2.kt, object2.kt + updated imports: class2.kt, object2.kt STEP 2: dependencies: lib1 - updated imports: l2.kt + updated imports: class2.kt, object2.kt STEP 3: dependencies: lib1 + updated imports: class2.kt, object2.kt STEP 4: dependencies: lib1 - updated exports: l2.kt + updated exports: class2.kt, object2.kt STEP 5: dependencies: lib1 STEP 6: dependencies: lib1 - updated imports: l2.kt - updated exports: l2.kt + updated imports: class2.kt, object2.kt + updated exports: class2.kt, object2.kt STEP 7: dependencies: lib1 + updated imports: class2.kt, object2.kt STEP 8: dependencies: lib1 - updated exports: l2.kt + updated exports: class2.kt, object2.kt diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib2/object2.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib2/object2.kt new file mode 100644 index 00000000000..af6461642d8 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/lib2/object2.kt @@ -0,0 +1,3 @@ +object Module2Object: Module1Interface { + fun testFunction1() = 1 +} diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/main/m.0.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/main/m.0.kt index f2124ab4831..e2a9603eadf 100644 --- a/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/main/m.0.kt +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/main/m.0.kt @@ -1,8 +1,9 @@ fun box(stepId: Int): String { - val obj = Module1Class() + val obj = Module2Class() when (stepId) { 0, 1, 2, 3, 4, 5, 6, 7, 8 -> { - if (obj.testFunction1() != 1) return "Fail 1" + if (obj.testFunction1() != 1) return "Fail 1 class" + if (Module2Object.testFunction1() != 1) return "Fail 1 object" } else -> return "Unknown" } diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/main/m.1.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/main/m.1.kt index e18abc94cfc..f238101ba33 100644 --- a/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/main/m.1.kt +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/main/m.1.kt @@ -1,9 +1,11 @@ fun box(stepId: Int): String { - val obj = Module1Class() + val obj = Module2Class() when (stepId) { 0, 1, 2, 3, 4, 5, 6, 7, 8 -> { - if (obj.testFunction1() != 1) return "Fail 1" - if (obj.testFunction22() != 22) return "Fail 22" + if (obj.testFunction1() != 1) return "Fail 1 class" + if (obj.testFunction22() != 22) return "Fail 22 class" + if (Module2Object.testFunction1() != 1) return "Fail 1 object" + if (Module2Object.testFunction22() != 22) return "Fail 22 object" } else -> return "Unknown" } diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/main/m.4.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/main/m.4.kt index f1ed003d616..e643b29b986 100644 --- a/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/main/m.4.kt +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/main/m.4.kt @@ -1,15 +1,23 @@ fun box(stepId: Int): String { - val obj = Module1Class() + val obj = Module2Class() when (stepId) { 0, 1, 2, 3, 4, 6, 7, 8 -> { - if (obj.testFunction1() != 1) return "Fail 1" - if (obj.testFunction22() != 22) return "Fail 22" - if (obj.testField222 != 222) return "Fail 222" + if (obj.testFunction1() != 1) return "Fail 1 class" + if (obj.testFunction22() != 22) return "Fail 22 class" + if (obj.testField222 != 222) return "Fail 222 class" + + if (Module2Object.testFunction1() != 1) return "Fail 1 object" + if (Module2Object.testFunction22() != 22) return "Fail 22 object" + if (Module2Object.testField222 != 222) return "Fail 222 object" } 5 -> { - if (obj.testFunction1() != 1) return "Fail 1" - if (obj.testFunction22() != 220) return "Fail 220" - if (obj.testField222 != 2220) return "Fail 2220" + if (obj.testFunction1() != 1) return "Fail 1 class" + if (obj.testFunction22() != 220) return "Fail 220 class" + if (obj.testField222 != 2220) return "Fail 2220 class" + + if (Module2Object.testFunction1() != 1) return "Fail 1 object" + if (Module2Object.testFunction22() != 220) return "Fail 220 object" + if (Module2Object.testField222 != 2220) return "Fail 2220 object" } else -> return "Unknown" } diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/main/m.8.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/main/m.8.kt index 9f2392d026e..28cabf1cc13 100644 --- a/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/main/m.8.kt +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/main/m.8.kt @@ -1,13 +1,18 @@ -suspend fun testCrossReference(): Int { - val obj = Module1Class() +suspend fun testCrossReferenceClass(): Int { + val obj = Module2Class() return obj.testFunction2() } +suspend fun testCrossReferenceObject(): Int { + return Module2Object.testFunction2() +} + fun box(stepId: Int): String { - val obj = Module1Class() + val obj = Module2Class() when (stepId) { 0, 1, 2, 3, 4, 5, 6, 7, 8 -> { - if (obj.testFunction1() != 1) return "Fail 1" + if (obj.testFunction1() != 1) return "Fail 1 class" + if (Module2Object.testFunction1() != 1) return "Fail 1 object" } else -> return "Unknown" } diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/project.info b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/project.info index 7f222b38181..05bcd8b3fcb 100644 --- a/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/project.info +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInterfaceFunctionQualifiers/project.info @@ -8,10 +8,10 @@ STEP 2: dirty js: lib1, lib2 STEP 3: libs: lib1, lib2, main - dirty js: lib1 + dirty js: lib1, lib2 STEP 4: libs: lib1, lib2, main - dirty js: lib1, lib2, main + dirty js: lib2, main STEP 5: libs: lib1, lib2, main dirty js: lib1 @@ -20,7 +20,7 @@ STEP 6: dirty js: lib1, lib2, main STEP 7: libs: lib1, lib2, main - dirty js: lib1 + dirty js: lib1, lib2 STEP 8: libs: lib1, lib2, main - dirty js: lib1, lib2, main + dirty js: lib2, main diff --git a/js/js.translator/testData/incremental/invalidation/interfaceSuperUsage/lib1/module.info b/js/js.translator/testData/incremental/invalidation/interfaceSuperUsage/lib1/module.info index 93e2a7b5b75..3aca11c33d0 100644 --- a/js/js.translator/testData/incremental/invalidation/interfaceSuperUsage/lib1/module.info +++ b/js/js.translator/testData/incremental/invalidation/interfaceSuperUsage/lib1/module.info @@ -19,8 +19,10 @@ STEP 4: modifications: U : Interface.4.kt -> Interface.kt modified ir: Interface.kt + updated exports: Interface.kt + updated imports: ClassB.kt, ClassA.kt STEP 5: - updated exports: Interface.kt, ClassB.kt + updated exports: ClassB.kt STEP 6: modifications: U : ClassB.6.kt -> ClassB.kt diff --git a/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/lib1/classA.0.kt b/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/lib1/classA.0.kt new file mode 100644 index 00000000000..c93967d2175 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/lib1/classA.0.kt @@ -0,0 +1,6 @@ +class ClassA { + fun leakObject(): Interface { + val obj = object : Interface {} + return obj + } +} diff --git a/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/lib1/classA.1.kt b/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/lib1/classA.1.kt new file mode 100644 index 00000000000..0f3ebcf3574 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/lib1/classA.1.kt @@ -0,0 +1,8 @@ +class ClassA { + fun leakObject(): Interface { + val obj = object : Interface { + override fun getNumber() = 1 + } + return obj + } +} diff --git a/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/lib1/interface.0.kt b/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/lib1/interface.0.kt new file mode 100644 index 00000000000..c9b6292efab --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/lib1/interface.0.kt @@ -0,0 +1,5 @@ +interface Interface { + val extraNumber get() = 0 + + fun getNumber() = 0 +} diff --git a/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/lib1/interface.2.kt b/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/lib1/interface.2.kt new file mode 100644 index 00000000000..bfb4b288404 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/lib1/interface.2.kt @@ -0,0 +1,7 @@ +interface Interface { + val extraNumber get() = 1 + + fun getNumber() = 0 + + fun getOtherNumber() = 1 +} diff --git a/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/lib1/interface.4.kt b/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/lib1/interface.4.kt new file mode 100644 index 00000000000..eee7fd40593 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/lib1/interface.4.kt @@ -0,0 +1,9 @@ +interface Interface { + val extraNumber get() = 2 + + fun getNumber() = 0 + + fun getOtherNumber() = 1 + + val otherExtraNumber get() = 1 +} diff --git a/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/lib1/module.info b/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/lib1/module.info new file mode 100644 index 00000000000..3199897c0cc --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/lib1/module.info @@ -0,0 +1,24 @@ +STEP 0: + modifications: + U : classA.0.kt -> classA.kt + U : interface.0.kt -> interface.kt + added file: classA.kt, interface.kt +STEP 1: + modifications: + U : classA.1.kt -> classA.kt + modified ir: classA.kt +STEP 2: + modifications: + U : interface.2.kt -> interface.kt + modified ir: interface.kt + updated exports: interface.kt + updated imports: classA.kt +STEP 3: +STEP 4: + modifications: + U : interface.4.kt -> interface.kt + modified ir: interface.kt + updated exports: interface.kt + updated imports: classA.kt +STEP 5: + updated exports: interface.kt diff --git a/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/main/m.kt b/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/main/m.kt new file mode 100644 index 00000000000..4616dd6437c --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/main/m.kt @@ -0,0 +1,7 @@ +fun box(stepId: Int): String { + val x = test() + if (x != stepId) { + return "Fail $x != $stepId" + } + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/main/module.info b/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/main/module.info new file mode 100644 index 00000000000..5b42b9fc0ce --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/main/module.info @@ -0,0 +1,23 @@ +STEP 0: + dependencies: lib1 + modifications: + U : test.0.kt -> test.kt + added file: m.kt, test.kt +STEP 1: + dependencies: lib1 +STEP 2: + dependencies: lib1 + updated imports: test.kt +STEP 3: + dependencies: lib1 + modifications: + U : test.3.kt -> test.kt + modified ir: test.kt +STEP 4: + dependencies: lib1 + updated imports: test.kt +STEP 5: + dependencies: lib1 + modifications: + U : test.5.kt -> test.kt + modified ir: test.kt diff --git a/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/main/test.0.kt b/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/main/test.0.kt new file mode 100644 index 00000000000..050ccf5d19c --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/main/test.0.kt @@ -0,0 +1,5 @@ +fun test(): Int { + val a = ClassA() + val obj = a.leakObject() + return obj.getNumber() + obj.extraNumber +} diff --git a/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/main/test.3.kt b/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/main/test.3.kt new file mode 100644 index 00000000000..328dad6e085 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/main/test.3.kt @@ -0,0 +1,5 @@ +fun test(): Int { + val a = ClassA() + val obj = a.leakObject() + return obj.getNumber() + obj.extraNumber + obj.getOtherNumber() +} diff --git a/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/main/test.5.kt b/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/main/test.5.kt new file mode 100644 index 00000000000..3449676fbf8 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/main/test.5.kt @@ -0,0 +1,5 @@ +fun test(): Int { + val a = ClassA() + val obj = a.leakObject() + return obj.getNumber() + obj.extraNumber + obj.getOtherNumber() + obj.otherExtraNumber +} diff --git a/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/project.info b/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/project.info new file mode 100644 index 00000000000..10474564688 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/localObjectsLeakThroughInterface/project.info @@ -0,0 +1,17 @@ +MODULES: lib1, main + +STEP 0: + libs: lib1, main + dirty js: lib1, main +STEP 1: + libs: lib1, main + dirty js: lib1 +STEP 2: + libs: lib1, main + dirty js: lib1, main +STEP 3: + libs: lib1, main + dirty js: main +STEP 4..5: + libs: lib1, main + dirty js: lib1, main diff --git a/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/lib1/classA.0.kt b/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/lib1/classA.0.kt new file mode 100644 index 00000000000..94094b7e9fe --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/lib1/classA.0.kt @@ -0,0 +1,5 @@ +class ClassA { + val leakedObject: SealedInterface get() = PrivateObject +} + +private object PrivateObject : SealedInterface diff --git a/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/lib1/classA.1.kt b/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/lib1/classA.1.kt new file mode 100644 index 00000000000..144b7925b2b --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/lib1/classA.1.kt @@ -0,0 +1,7 @@ +class ClassA { + val leakedObject: SealedInterface get() = PrivateObject +} + +private object PrivateObject : SealedInterface { + override fun getNumber() = 1 +} diff --git a/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/lib1/interface.0.kt b/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/lib1/interface.0.kt new file mode 100644 index 00000000000..b4f714d03e5 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/lib1/interface.0.kt @@ -0,0 +1,5 @@ +sealed interface SealedInterface { + val extraNumber get() = 0 + + fun getNumber() = 0 +} diff --git a/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/lib1/interface.2.kt b/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/lib1/interface.2.kt new file mode 100644 index 00000000000..4b6e81a0b2c --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/lib1/interface.2.kt @@ -0,0 +1,7 @@ +sealed interface SealedInterface { + val extraNumber get() = 1 + + fun getNumber() = 0 + + fun getOtherNumber() = 1 +} diff --git a/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/lib1/interface.4.kt b/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/lib1/interface.4.kt new file mode 100644 index 00000000000..3ab66c0c430 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/lib1/interface.4.kt @@ -0,0 +1,9 @@ +sealed interface SealedInterface { + val extraNumber get() = 2 + + fun getNumber() = 0 + + fun getOtherNumber() = 1 + + val otherExtraNumber get() = 1 +} diff --git a/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/lib1/module.info b/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/lib1/module.info new file mode 100644 index 00000000000..57efbfeafdc --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/lib1/module.info @@ -0,0 +1,24 @@ +STEP 0: + modifications: + U : classA.0.kt -> classA.kt + U : interface.0.kt -> interface.kt + added file: classA.kt, interface.kt +STEP 1: + modifications: + U : classA.1.kt -> classA.kt + modified ir: classA.kt +STEP 2: + modifications: + U : interface.2.kt -> interface.kt + modified ir: interface.kt + updated exports: interface.kt + updated imports: classA.kt +STEP 3: +STEP 4: + modifications: + U : interface.4.kt -> interface.kt + modified ir: interface.kt + updated exports: interface.kt + updated imports: classA.kt +STEP 5: + updated exports: interface.kt \ No newline at end of file diff --git a/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/main/m.kt b/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/main/m.kt new file mode 100644 index 00000000000..4616dd6437c --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/main/m.kt @@ -0,0 +1,7 @@ +fun box(stepId: Int): String { + val x = test() + if (x != stepId) { + return "Fail $x != $stepId" + } + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/main/module.info b/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/main/module.info new file mode 100644 index 00000000000..5b42b9fc0ce --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/main/module.info @@ -0,0 +1,23 @@ +STEP 0: + dependencies: lib1 + modifications: + U : test.0.kt -> test.kt + added file: m.kt, test.kt +STEP 1: + dependencies: lib1 +STEP 2: + dependencies: lib1 + updated imports: test.kt +STEP 3: + dependencies: lib1 + modifications: + U : test.3.kt -> test.kt + modified ir: test.kt +STEP 4: + dependencies: lib1 + updated imports: test.kt +STEP 5: + dependencies: lib1 + modifications: + U : test.5.kt -> test.kt + modified ir: test.kt diff --git a/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/main/test.0.kt b/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/main/test.0.kt new file mode 100644 index 00000000000..728da51fa0d --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/main/test.0.kt @@ -0,0 +1,5 @@ +fun test(): Int { + val a = ClassA() + val obj = a.leakedObject + return obj.getNumber() + obj.extraNumber +} diff --git a/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/main/test.3.kt b/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/main/test.3.kt new file mode 100644 index 00000000000..5e09cf360a0 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/main/test.3.kt @@ -0,0 +1,5 @@ +fun test(): Int { + val a = ClassA() + val obj = a.leakedObject + return obj.getNumber() + obj.extraNumber + obj.getOtherNumber() +} diff --git a/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/main/test.5.kt b/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/main/test.5.kt new file mode 100644 index 00000000000..9ae4bde26b6 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/main/test.5.kt @@ -0,0 +1,5 @@ +fun test(): Int { + val a = ClassA() + val obj = a.leakedObject + return obj.getNumber() + obj.extraNumber + obj.getOtherNumber() + obj.otherExtraNumber +} diff --git a/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/project.info b/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/project.info new file mode 100644 index 00000000000..10474564688 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/privateObjectsLeakThroughSealedInterface/project.info @@ -0,0 +1,17 @@ +MODULES: lib1, main + +STEP 0: + libs: lib1, main + dirty js: lib1, main +STEP 1: + libs: lib1, main + dirty js: lib1 +STEP 2: + libs: lib1, main + dirty js: lib1, main +STEP 3: + libs: lib1, main + dirty js: main +STEP 4..5: + libs: lib1, main + dirty js: lib1, main