diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/CacheUpdater.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/CacheUpdater.kt index 64531be943b..18ab7182ceb 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/CacheUpdater.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/CacheUpdater.kt @@ -8,10 +8,10 @@ import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.ir.backend.js.* import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsIrFragmentAndBinaryAst -import org.jetbrains.kotlin.ir.declarations.IrFactory -import org.jetbrains.kotlin.ir.declarations.IrFile -import org.jetbrains.kotlin.ir.declarations.IrModuleFragment +import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.util.* +import org.jetbrains.kotlin.ir.util.resolveFakeOverride import org.jetbrains.kotlin.js.config.JSConfigurationKeys import org.jetbrains.kotlin.konan.properties.propertyList import org.jetbrains.kotlin.library.KLIB_PROPERTY_DEPENDS @@ -238,6 +238,16 @@ class CacheUpdater( return exportedSymbols } + private fun resolveFakeOverrideInlineFunction(symbol: IrSymbol): IdSignature? { + return (symbol.owner as? IrSimpleFunction)?.let { overridable -> + if (overridable.isFakeOverride && overridable.isInline) { + overridable.resolveFakeOverride()?.symbol?.signature + } else { + null + } + } + } + private fun rebuildDirtySourceMetadata( jsIrLinker: JsIrLinker, loadedFragments: Map, @@ -253,12 +263,15 @@ class CacheUpdater( val libSrcFile = KotlinSourceFile(fileDeserializer.file) val reachableSignatures = fileDeserializer.symbolDeserializer.signatureDeserializer.signatureToIndexMapping() - val allImplementedSignatures = fileDeserializer.symbolDeserializer.deserializedSymbols.keys + val allImplementedSymbols = fileDeserializer.symbolDeserializer.deserializedSymbols val maybeImportedSignatures = reachableSignatures.keys.toMutableSet() - for (signature in allImplementedSignatures) { + for ((signature, symbol) in allImplementedSymbols) { if (signature in reachableSignatures) { idSignatureToFile[signature] = lib to libSrcFile maybeImportedSignatures.remove(signature) + + val resolvedSignature = resolveFakeOverrideInlineFunction(symbol) ?: continue + maybeImportedSignatures.add(resolvedSignature) } } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/ICUtils.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/ICUtils.kt index f1d4add8601..8f08ad8df3f 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/ICUtils.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/ICUtils.kt @@ -38,12 +38,14 @@ internal inline fun File.useCodedOutput(f: CodedOutputStream.() -> Unit) { } } -internal fun icError(msg: String): Nothing = error("IC internal error: $msg") - -internal fun notFoundIcError(what: String, libFile: KotlinLibraryFile? = null, srcFile: KotlinSourceFile? = null): Nothing { +internal fun icError(what: String, libFile: KotlinLibraryFile? = null, srcFile: KotlinSourceFile? = null): Nothing { val filePath = listOfNotNull(libFile?.path, srcFile?.path).joinToString(":") { File(it).name } val msg = if (filePath.isEmpty()) what else "$what for $filePath" - icError("can not find $msg") + error("IC internal error: $msg") +} + +internal fun notFoundIcError(what: String, libFile: KotlinLibraryFile? = null, srcFile: KotlinSourceFile? = null): Nothing { + icError("can not find $what", libFile, srcFile) } internal inline fun buildListUntil(to: Int, builderAction: MutableList.(Int) -> Unit): List { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IdSignatureSerialization.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IdSignatureSerialization.kt new file mode 100644 index 00000000000..7aad2a91eca --- /dev/null +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IdSignatureSerialization.kt @@ -0,0 +1,117 @@ +/* + * 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.ir.backend.js.ic + +import org.jetbrains.kotlin.ir.util.IdSignature +import org.jetbrains.kotlin.protobuf.CodedInputStream +import org.jetbrains.kotlin.protobuf.CodedOutputStream + +private enum class IdSignatureProtoType(val id: Int) { + DECLARED_SIGNATURE(0), + COMMON_SIGNATURE(1), + COMPOSITE_SIGNATURE(2), + ACCESSOR_SIGNATURE(3); +} + +internal fun CodedOutputStream.writeIdSignature(signature: IdSignature, signatureToIndexMapper: (IdSignature) -> Int?) { + val index = signatureToIndexMapper(signature) + if (index != null) { + writeInt32NoTag(IdSignatureProtoType.DECLARED_SIGNATURE.id) + writeInt32NoTag(index) + return + } + + when (signature) { + is IdSignature.CommonSignature -> { + writeInt32NoTag(IdSignatureProtoType.COMMON_SIGNATURE.id) + writeStringNoTag(signature.packageFqName) + writeStringNoTag(signature.declarationFqName) + val id = signature.id + if (id != null) { + writeBoolNoTag(true) + writeFixed64NoTag(id) + } else { + writeBoolNoTag(false) + } + writeInt64NoTag(signature.mask) + } + is IdSignature.CompositeSignature -> { + writeInt32NoTag(IdSignatureProtoType.COMPOSITE_SIGNATURE.id) + writeIdSignature(signature.container, signatureToIndexMapper) + writeIdSignature(signature.inner, signatureToIndexMapper) + } + is IdSignature.AccessorSignature -> { + writeInt32NoTag(IdSignatureProtoType.ACCESSOR_SIGNATURE.id) + writeIdSignature(signature.propertySignature, signatureToIndexMapper) + writeIdSignature(signature.accessorSignature, signatureToIndexMapper) + } + else -> { + icError("can not write $signature signature") + } + } +} + +internal fun CodedInputStream.readIdSignature(indexToSignatureMapper: (Int) -> IdSignature): IdSignature { + when (val signatureType = readInt32()) { + IdSignatureProtoType.DECLARED_SIGNATURE.id -> { + return indexToSignatureMapper(readInt32()) + } + IdSignatureProtoType.COMMON_SIGNATURE.id -> { + val packageFqName = readString() + val declarationFqName = readString() + val id = if (readBool()) { + readFixed64() + } else { + null + } + val mask = readInt64() + return IdSignature.CommonSignature(packageFqName, declarationFqName, id, mask) + } + IdSignatureProtoType.COMPOSITE_SIGNATURE.id -> { + val containerSignature = readIdSignature(indexToSignatureMapper) + val innerSignature = readIdSignature(indexToSignatureMapper) + return IdSignature.CompositeSignature(containerSignature, innerSignature) + } + IdSignatureProtoType.ACCESSOR_SIGNATURE.id -> { + val propertySignature = readIdSignature(indexToSignatureMapper) + val accessorSignature = readIdSignature(indexToSignatureMapper) + if (accessorSignature !is IdSignature.CommonSignature) { + icError("can not read accessor signature") + } + return IdSignature.AccessorSignature(propertySignature, accessorSignature) + } + else -> { + icError("can not read signature type $signatureType") + } + } +} + +internal fun CodedInputStream.skipIdSignature() { + when (val signatureType = readInt32()) { + IdSignatureProtoType.DECLARED_SIGNATURE.id -> { + readInt32() + } + IdSignatureProtoType.COMMON_SIGNATURE.id -> { + readString() + readString() + if (readBool()) { + readFixed64() + } + readInt64() + } + IdSignatureProtoType.COMPOSITE_SIGNATURE.id -> { + skipIdSignature() + skipIdSignature() + } + IdSignatureProtoType.ACCESSOR_SIGNATURE.id -> { + skipIdSignature() + skipIdSignature() + } + else -> { + icError("can not skip signature type $signatureType") + } + } +} diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IncrementalCache.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IncrementalCache.kt index f678d2f4fc5..fef479e47b1 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IncrementalCache.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IncrementalCache.kt @@ -165,10 +165,10 @@ class IncrementalCache(private val library: KotlinLibrary, cachePath: String) { private fun fetchSourceFileMetadata(srcFile: KotlinSourceFile, loadSignatures: Boolean) = kotlinLibrarySourceFileMetadata.getOrPut(srcFile) { val signatureToIndexMapping = signatureToIndexMappingFromMetadata.getOrPut(srcFile) { mutableMapOf() } - fun IdSignatureDeserializer.deserializeIdSignatureAndSave(index: Int): IdSignature { - val signature = deserializeIdSignature(index) + fun CodedInputStream.deserializeIdSignatureAndSave(deserializer: IdSignatureDeserializer) = readIdSignature { index -> + val signature = deserializer.deserializeIdSignature(index) signatureToIndexMapping[signature] = index - return signature + signature } val deserializer: IdSignatureDeserializer by lazy { @@ -181,9 +181,9 @@ class IncrementalCache(private val library: KotlinLibrary, cachePath: String) { val depends = buildMapUntil(readInt32()) { val dependencySrcFile = KotlinSourceFile.fromProtoStream(this@useCodedInputIfExists) val dependencySignatures = if (loadSignatures) { - buildSetUntil(readInt32()) { add(deserializer.deserializeIdSignatureAndSave(readInt32())) } + buildSetUntil(readInt32()) { add(deserializeIdSignatureAndSave(deserializer)) } } else { - repeat(readInt32()) { readInt32() } + repeat(readInt32()) { skipIdSignature() } emptySet() } put(dependencySrcFile, dependencySignatures) @@ -196,7 +196,7 @@ class IncrementalCache(private val library: KotlinLibrary, cachePath: String) { val importedInlineFunctions = if (loadSignatures) { buildMapUntil(readInt32()) { - val signature = deserializer.deserializeIdSignatureAndSave(readInt32()) + val signature = deserializeIdSignatureAndSave(deserializer) val transitiveHash = ICHash.fromProtoStream(this@useCodedInputIfExists) put(signature, transitiveHash) } @@ -220,10 +220,8 @@ class IncrementalCache(private val library: KotlinLibrary, cachePath: String) { } val signatureToIndexMappingSaved = signatureToIndexMappingFromMetadata[srcFile] ?: emptyMap() - fun serializeSignature(signature: IdSignature): Int { - val index = signatureToIndexMapping[signature] ?: signatureToIndexMappingSaved[signature] - return index ?: notFoundIcError("signature $signature", libraryFile, srcFile) - } + fun CodedOutputStream.serializeIdSignature(signature: IdSignature) = + writeIdSignature(signature) { signatureToIndexMapping[it] ?: signatureToIndexMappingSaved[it] } headerCacheFile.useCodedOutput { fun writeDepends(depends: KotlinSourceFileMap>) { @@ -235,7 +233,7 @@ class IncrementalCache(private val library: KotlinLibrary, cachePath: String) { dependencySrcFile.toProtoStream(this) writeInt32NoTag(signatures.size) for (signature in signatures) { - writeInt32NoTag(serializeSignature(signature)) + serializeIdSignature(signature) } } } @@ -246,7 +244,7 @@ class IncrementalCache(private val library: KotlinLibrary, cachePath: String) { writeInt32NoTag(sourceFileMetadata.importedInlineFunctions.size) for ((signature, transitiveHash) in sourceFileMetadata.importedInlineFunctions) { - writeInt32NoTag(serializeSignature(signature)) + serializeIdSignature(signature) transitiveHash.toProtoStream(this) } } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/InlineFunctionTransitiveHashCalculator.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/InlineFunctionTransitiveHashCalculator.kt index c50296fc7ed..6c240903304 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/InlineFunctionTransitiveHashCalculator.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/InlineFunctionTransitiveHashCalculator.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.ir.expressions.IrFunctionReference import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.ir.util.isFakeOverride import org.jetbrains.kotlin.ir.util.render +import org.jetbrains.kotlin.ir.util.resolveFakeOverride import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid @@ -37,7 +38,13 @@ class InlineFunctionTransitiveHashCalculator { if (declaration in flatHashes) { return } - flatHashes[declaration] = declaration.irElementHashForIC() + + flatHashes[declaration] = if (declaration.isFakeOverride) { + declaration.resolveFakeOverride()?.irElementHashForIC() + ?: icError("can not resolve fake override for ${declaration.render()}") + } else { + declaration.irElementHashForIC() + } } // go deeper since local inline special declarations (like a reference adaptor) may appear declaration.acceptChildren(this, null) @@ -61,10 +68,7 @@ class InlineFunctionTransitiveHashCalculator { override fun visitCall(expression: IrCall, data: MutableSet) { val callee = expression.symbol.owner if (callee.isInline) { - // TODO: do not ignore fake overrides after KT-51896 - if (!callee.isFakeOverride) { - data += callee - } + data += callee inlineFunctionCallDepth += 1 } expression.acceptChildren(this, data) 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 459ea4aa6ef..7248ece8d7b 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 @@ -80,9 +80,24 @@ public class InvalidationTestGenerated extends AbstractInvalidationTest { runTest("js/js.translator/testData/incremental/invalidation/exportsThroughInlineFunction/"); } - @TestMetadata("fakeOverride") - public void testFakeOverride() throws Exception { - runTest("js/js.translator/testData/incremental/invalidation/fakeOverride/"); + @TestMetadata("fakeOverrideInheritance") + public void testFakeOverrideInheritance() throws Exception { + runTest("js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/"); + } + + @TestMetadata("fakeOverrideInlineExtension") + public void testFakeOverrideInlineExtension() throws Exception { + runTest("js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/"); + } + + @TestMetadata("fakeOverrideInlineFunction") + public void testFakeOverrideInlineFunction() throws Exception { + runTest("js/js.translator/testData/incremental/invalidation/fakeOverrideInlineFunction/"); + } + + @TestMetadata("fakeOverrideInlineProperty") + public void testFakeOverrideInlineProperty() throws Exception { + runTest("js/js.translator/testData/incremental/invalidation/fakeOverrideInlineProperty/"); } @TestMetadata("fastPath1") diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/lib1/A.0.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/lib1/A.0.kt new file mode 100644 index 00000000000..8592ef19f7d --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/lib1/A.0.kt @@ -0,0 +1,3 @@ +abstract class AbstractClassA { + inline fun funA() = "a-0" +} diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/lib1/A.1.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/lib1/A.1.kt new file mode 100644 index 00000000000..a15eb6aaa73 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/lib1/A.1.kt @@ -0,0 +1,3 @@ +abstract class AbstractClassA { + inline fun funA() = "a-1" +} diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/lib1/B.0.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/lib1/B.0.kt new file mode 100644 index 00000000000..28e3da803ef --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/lib1/B.0.kt @@ -0,0 +1,3 @@ +abstract class AbstractClassB : AbstractClassA() { + inline fun funB() = "b-0 ${funA()}" +} diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/lib1/B.2.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/lib1/B.2.kt new file mode 100644 index 00000000000..31b2d04b57d --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/lib1/B.2.kt @@ -0,0 +1,3 @@ +abstract class AbstractClassB : AbstractClassA() { + inline fun funB() = "b-2" +} diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/lib1/C.0.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/lib1/C.0.kt new file mode 100644 index 00000000000..d571c58b47b --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/lib1/C.0.kt @@ -0,0 +1,3 @@ +abstract class AbstractClassC : AbstractClassB() { + inline fun funC() = "c-0 ${funB()}" +} diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/lib1/module.info b/js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/lib1/module.info new file mode 100644 index 00000000000..1e1fb2caf45 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/lib1/module.info @@ -0,0 +1,30 @@ +STEP 0: + modifications: + U : A.0.kt -> A.kt + U : B.0.kt -> B.kt + U : C.0.kt -> C.kt + added file: A.kt, B.kt, C.kt +STEP 1: + modifications: + U : A.1.kt -> A.kt + modified ir: A.kt + updated inline imports: B.kt, C.kt +STEP 2: + modifications: + U : B.2.kt -> B.kt + modified ir: B.kt + updated inline imports: C.kt +STEP 3: + modifications: + U : A.0.kt -> A.kt + modified ir: A.kt +STEP 4: + modifications: + U : B.0.kt -> B.kt + modified ir: B.kt + updated inline imports: C.kt +STEP 5: + modifications: + U : A.1.kt -> A.kt + modified ir: A.kt + updated inline imports: B.kt, C.kt diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/main/classABC.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/main/classABC.kt new file mode 100644 index 00000000000..5c1964cb5b5 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/main/classABC.kt @@ -0,0 +1,5 @@ +class ClassABC: AbstractClassC() { + inline fun testA() = funA() + inline fun testB() = funB() + inline fun testC() = funC() +} diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/main/m.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/main/m.kt new file mode 100644 index 00000000000..782118bf581 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/main/m.kt @@ -0,0 +1,27 @@ +fun box(stepId: Int): String { + val a = ClassABC() + when (stepId) { + 0, 4 -> { + if (a.testA() != "a-0") return "Fail testA()" + if (a.testB() != "b-0 a-0") return "Fail testB()" + if (a.testC() != "c-0 b-0 a-0") return "Fail testC()" + } + 1, 5 -> { + if (a.testA() != "a-1") return "Fail testA()" + if (a.testB() != "b-0 a-1") return "Fail testB()" + if (a.testC() != "c-0 b-0 a-1") return "Fail testC()" + } + 2 -> { + if (a.testA() != "a-1") return "Fail testA()" + if (a.testB() != "b-2") return "Fail testB()" + if (a.testC() != "c-0 b-2") return "Fail testC()" + } + 3 -> { + if (a.testA() != "a-0") return "Fail testA()" + if (a.testB() != "b-2") return "Fail testB()" + if (a.testC() != "c-0 b-2") return "Fail testC()" + } + else -> return "Unknown" + } + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/main/module.info b/js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/main/module.info new file mode 100644 index 00000000000..19768e93727 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/main/module.info @@ -0,0 +1,6 @@ +STEP 0: + dependencies: lib1 + added file: m.kt, classABC.kt +STEP 1..5: + dependencies: lib1 + updated inline imports: m.kt, classABC.kt diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/project.info b/js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/project.info new file mode 100644 index 00000000000..95044474783 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInheritance/project.info @@ -0,0 +1,8 @@ +MODULES: lib1, main + +STEP 0: + libs: lib1, main + dirty js: lib1, main +STEP 1..5: + libs: lib1, main + dirty js: lib1, main diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/lib1/l1.0.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/lib1/l1.0.kt new file mode 100644 index 00000000000..bc9358fdb95 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/lib1/l1.0.kt @@ -0,0 +1,14 @@ +abstract class AbstractClassA { + inline fun String.fakeOverrideExtension() = "${this} fakeOverrideExtension 0" + + inline val String.fakeOverrideGetProperty + get() = "${this} fakeOverrideGetProperty 0" + + inline var String.fakeOverrideSetProperty: String + get() = "${savedString} fakeOverrideSetProperty getter 0" + set(str) { + savedString = "${str} fakeOverrideSetProperty setter 0" + } + + var savedString = "" +} diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/lib1/l1.1.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/lib1/l1.1.kt new file mode 100644 index 00000000000..775c61386ba --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/lib1/l1.1.kt @@ -0,0 +1,14 @@ +abstract class AbstractClassA { + inline fun String.fakeOverrideExtension() = "${this} fakeOverrideExtension 1" + + inline val String.fakeOverrideGetProperty + get() = "${this} fakeOverrideGetProperty 0" + + inline var String.fakeOverrideSetProperty: String + get() = "${savedString} fakeOverrideSetProperty getter 0" + set(str) { + savedString = "${str} fakeOverrideSetProperty setter 0" + } + + var savedString = "" +} diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/lib1/l1.2.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/lib1/l1.2.kt new file mode 100644 index 00000000000..e4b00c37432 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/lib1/l1.2.kt @@ -0,0 +1,14 @@ +abstract class AbstractClassA { + inline fun String.fakeOverrideExtension() = "${this} fakeOverrideExtension 1" + + inline val String.fakeOverrideGetProperty + get() = "${this} fakeOverrideGetProperty 2" + + inline var String.fakeOverrideSetProperty: String + get() = "${savedString} fakeOverrideSetProperty getter 0" + set(str) { + savedString = "${str} fakeOverrideSetProperty setter 0" + } + + var savedString = "" +} diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/lib1/l1.3.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/lib1/l1.3.kt new file mode 100644 index 00000000000..843032d516f --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/lib1/l1.3.kt @@ -0,0 +1,14 @@ +abstract class AbstractClassA { + inline fun String.fakeOverrideExtension() = "${this} fakeOverrideExtension 1" + + inline val String.fakeOverrideGetProperty + get() = "${this} fakeOverrideGetProperty 2" + + inline var String.fakeOverrideSetProperty: String + get() = "${savedString} fakeOverrideSetProperty getter 0" + set(str) { + savedString = "${str} fakeOverrideSetProperty setter 3" + } + + var savedString = "empty" +} diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/lib1/l1.4.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/lib1/l1.4.kt new file mode 100644 index 00000000000..65c2b22d2c6 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/lib1/l1.4.kt @@ -0,0 +1,14 @@ +abstract class AbstractClassA { + inline fun String.fakeOverrideExtension() = "${this} fakeOverrideExtension 1" + + inline val String.fakeOverrideGetProperty + get() = "${this} fakeOverrideGetProperty 2" + + inline var String.fakeOverrideSetProperty: String + get() = "${savedString} fakeOverrideSetProperty getter 4" + set(str) { + savedString = "${str} fakeOverrideSetProperty setter 3" + } + + var savedString = "" +} diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/lib1/module.info b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/lib1/module.info new file mode 100644 index 00000000000..e7cd35d3035 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/lib1/module.info @@ -0,0 +1,20 @@ +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: + modifications: + U : l1.3.kt -> l1.kt + modified ir: l1.kt +STEP 4: + modifications: + U : l1.4.kt -> l1.kt + modified ir: l1.kt diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/main/classA.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/main/classA.kt new file mode 100644 index 00000000000..ad61ff0b469 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/main/classA.kt @@ -0,0 +1,11 @@ +class ClassA: AbstractClassA() { + inline fun testExtension() = "testExtension".fakeOverrideExtension() + inline fun testGetProperty() = "testGetProperty".fakeOverrideGetProperty + + inline fun testSetPropertySetter(): String { + "test".fakeOverrideSetProperty = "testSetPropertySetter" + return savedString; + } + + inline fun testSetPropertyGetter() = "test".fakeOverrideSetProperty +} diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/main/m.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/main/m.kt new file mode 100644 index 00000000000..cbf36c6f64e --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/main/m.kt @@ -0,0 +1,37 @@ +fun box(stepId: Int): String { + val a = ClassA() + when (stepId) { + 0 -> { + if (a.testExtension() != "testExtension fakeOverrideExtension 0") return "Fail extension" + if (a.testGetProperty() != "testGetProperty fakeOverrideGetProperty 0") return "Fail getProperty" + if (a.testSetPropertySetter() != "testSetPropertySetter fakeOverrideSetProperty setter 0") return "Fail setPropertySetter" + if (a.testSetPropertyGetter() != "testSetPropertySetter fakeOverrideSetProperty setter 0 fakeOverrideSetProperty getter 0") return a.testSetPropertyGetter() + } + 1 -> { + if (a.testExtension() != "testExtension fakeOverrideExtension 1") return "Fail extension" + if (a.testGetProperty() != "testGetProperty fakeOverrideGetProperty 0") return "Fail getProperty" + if (a.testSetPropertySetter() != "testSetPropertySetter fakeOverrideSetProperty setter 0") return "Fail setPropertySetter" + if (a.testSetPropertyGetter() != "testSetPropertySetter fakeOverrideSetProperty setter 0 fakeOverrideSetProperty getter 0") return a.testSetPropertyGetter() + } + 2 -> { + if (a.testExtension() != "testExtension fakeOverrideExtension 1") return "Fail extension" + if (a.testGetProperty() != "testGetProperty fakeOverrideGetProperty 2") return "Fail getProperty" + if (a.testSetPropertySetter() != "testSetPropertySetter fakeOverrideSetProperty setter 0") return "Fail setPropertySetter" + if (a.testSetPropertyGetter() != "testSetPropertySetter fakeOverrideSetProperty setter 0 fakeOverrideSetProperty getter 0") return a.testSetPropertyGetter() + } + 3 -> { + if (a.testExtension() != "testExtension fakeOverrideExtension 1") return "Fail extension" + if (a.testGetProperty() != "testGetProperty fakeOverrideGetProperty 2") return "Fail getProperty" + if (a.testSetPropertySetter() != "testSetPropertySetter fakeOverrideSetProperty setter 3") return "Fail setPropertySetter" + if (a.testSetPropertyGetter() != "testSetPropertySetter fakeOverrideSetProperty setter 3 fakeOverrideSetProperty getter 0") return a.testSetPropertyGetter() + } + 4 -> { + if (a.testExtension() != "testExtension fakeOverrideExtension 1") return "Fail extension" + if (a.testGetProperty() != "testGetProperty fakeOverrideGetProperty 2") return "Fail getProperty" + if (a.testSetPropertySetter() != "testSetPropertySetter fakeOverrideSetProperty setter 3") return "Fail setPropertySetter" + if (a.testSetPropertyGetter() != "testSetPropertySetter fakeOverrideSetProperty setter 3 fakeOverrideSetProperty getter 4") return a.testSetPropertyGetter() + } + else -> return "Unknown" + } + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/main/module.info b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/main/module.info new file mode 100644 index 00000000000..1d40cc4469e --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/main/module.info @@ -0,0 +1,6 @@ +STEP 0: + dependencies: lib1 + added file: m.kt, classA.kt +STEP 1..4: + dependencies: lib1 + updated inline imports: m.kt, classA.kt diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/project.info b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/project.info new file mode 100644 index 00000000000..1733e265b51 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineExtension/project.info @@ -0,0 +1,8 @@ +MODULES: lib1, main + +STEP 0: + libs: lib1, main + dirty js: lib1, main +STEP 1..4: + libs: lib1, main + dirty js: lib1, main diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverride/lib1/l1.1.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineFunction/lib1/l1.1.kt similarity index 100% rename from js/js.translator/testData/incremental/invalidation/fakeOverride/lib1/l1.1.kt rename to js/js.translator/testData/incremental/invalidation/fakeOverrideInlineFunction/lib1/l1.1.kt diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverride/lib1/l1.2.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineFunction/lib1/l1.2.kt similarity index 100% rename from js/js.translator/testData/incremental/invalidation/fakeOverride/lib1/l1.2.kt rename to js/js.translator/testData/incremental/invalidation/fakeOverrideInlineFunction/lib1/l1.2.kt diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverride/lib1/l1.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineFunction/lib1/l1.kt similarity index 100% rename from js/js.translator/testData/incremental/invalidation/fakeOverride/lib1/l1.kt rename to js/js.translator/testData/incremental/invalidation/fakeOverrideInlineFunction/lib1/l1.kt diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverride/lib1/module.info b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineFunction/lib1/module.info similarity index 100% rename from js/js.translator/testData/incremental/invalidation/fakeOverride/lib1/module.info rename to js/js.translator/testData/incremental/invalidation/fakeOverrideInlineFunction/lib1/module.info diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverride/lib2/l2.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineFunction/lib2/l2.kt similarity index 100% rename from js/js.translator/testData/incremental/invalidation/fakeOverride/lib2/l2.kt rename to js/js.translator/testData/incremental/invalidation/fakeOverrideInlineFunction/lib2/l2.kt diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverride/lib2/module.info b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineFunction/lib2/module.info similarity index 51% rename from js/js.translator/testData/incremental/invalidation/fakeOverride/lib2/module.info rename to js/js.translator/testData/incremental/invalidation/fakeOverrideInlineFunction/lib2/module.info index b6251b6e3d7..bf6598795b8 100644 --- a/js/js.translator/testData/incremental/invalidation/fakeOverride/lib2/module.info +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineFunction/lib2/module.info @@ -1,5 +1,8 @@ STEP 0: dependencies: lib1 added file: l2.kt -STEP 1..2: +STEP 1: + dependencies: lib1 + updated inline imports: l2.kt +STEP 2: dependencies: lib1 diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverride/main/m.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineFunction/main/m.kt similarity index 66% rename from js/js.translator/testData/incremental/invalidation/fakeOverride/main/m.kt rename to js/js.translator/testData/incremental/invalidation/fakeOverrideInlineFunction/main/m.kt index db615f2beb3..3d39cbc6c89 100644 --- a/js/js.translator/testData/incremental/invalidation/fakeOverride/main/m.kt +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineFunction/main/m.kt @@ -23,12 +23,12 @@ fun box(stepId: Int): String { if (callIt(b::fakeOverrideFunction) != 0) return "Fail 0-6" } 1 -> { - if (a.test2() != null) return "Fail 1-1" // TODO: test2() must return "OTHER 2", should be fixed in KT-51896 - if (b.test2() != null) return "Fail 1-2" // TODO: test2() must return "OTHER 1", should be fixed in KT-51896 + if (a.test2() != "OTHER 2") return "Fail 1-1" + if (b.test2() != "OTHER 1") return "Fail 1-2" } 2 -> { - if (a.fakeOverrideFunction() != 0) return "Fail 2-1" // TODO: fakeOverrideFunction() must return 2, should be fixed in KT-51896 - if (b.fakeOverrideFunction() != 0) return "Fail 2-2" // TODO: fakeOverrideFunction() must return 2, should be fixed in KT-51896 + if (a.fakeOverrideFunction() != 2) return "Fail 2-1" + if (b.fakeOverrideFunction() != 2) return "Fail 2-2" if (callIt(a::fakeOverrideFunction) != 2) return "Fail 2-3" if (callIt(b::fakeOverrideFunction) != 2) return "Fail 2-4" diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverride/main/module.info b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineFunction/main/module.info similarity index 74% rename from js/js.translator/testData/incremental/invalidation/fakeOverride/main/module.info rename to js/js.translator/testData/incremental/invalidation/fakeOverrideInlineFunction/main/module.info index 9fbc8ef145a..d0b85963a6b 100644 --- a/js/js.translator/testData/incremental/invalidation/fakeOverride/main/module.info +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineFunction/main/module.info @@ -3,3 +3,4 @@ STEP 0: added file: m.kt STEP 1..2: dependencies: lib1, lib2 + updated inline imports: m.kt diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverride/project.info b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineFunction/project.info similarity index 54% rename from js/js.translator/testData/incremental/invalidation/fakeOverride/project.info rename to js/js.translator/testData/incremental/invalidation/fakeOverrideInlineFunction/project.info index 2b1cc8467ee..7829bf96009 100644 --- a/js/js.translator/testData/incremental/invalidation/fakeOverride/project.info +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineFunction/project.info @@ -3,6 +3,9 @@ MODULES: lib1, lib2, main STEP 0: libs: lib1, lib2, main dirty js: lib1, lib2, main -STEP 1..2: +STEP 1: libs: lib1, lib2, main - dirty js: lib1 + dirty js: lib1, lib2, main +STEP 2: + libs: lib1, lib2, main + dirty js: lib1, main diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineProperty/lib1/l1.0.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineProperty/lib1/l1.0.kt new file mode 100644 index 00000000000..36dd991779f --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineProperty/lib1/l1.0.kt @@ -0,0 +1,12 @@ +abstract class AbstractClassA { + inline val propertyWithGetter: String + get() = "0" + + inline var propertyWithSetter: String + get() = savedStr + set(str) { + savedStr = "$str 0" + } + + var savedStr = "empty" +} diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineProperty/lib1/l1.1.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineProperty/lib1/l1.1.kt new file mode 100644 index 00000000000..c8b3d313f54 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineProperty/lib1/l1.1.kt @@ -0,0 +1,12 @@ +abstract class AbstractClassA { + inline val propertyWithGetter: String + get() = "1" + + inline var propertyWithSetter: String + get() = savedStr + set(str) { + savedStr = "$str 0" + } + + var savedStr = "empty" +} diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineProperty/lib1/l1.2.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineProperty/lib1/l1.2.kt new file mode 100644 index 00000000000..58cc74f87a5 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineProperty/lib1/l1.2.kt @@ -0,0 +1,12 @@ +abstract class AbstractClassA { + inline val propertyWithGetter: String + get() = "1" + + inline var propertyWithSetter: String + get() = savedStr + set(str) { + savedStr = "$str 2" + } + + var savedStr = "empty" +} diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineProperty/lib1/module.info b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineProperty/lib1/module.info new file mode 100644 index 00000000000..4ae641e95be --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineProperty/lib1/module.info @@ -0,0 +1,12 @@ +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 diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineProperty/main/classA.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineProperty/main/classA.kt new file mode 100644 index 00000000000..27832bb602a --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineProperty/main/classA.kt @@ -0,0 +1,8 @@ +class ClassA: AbstractClassA() { + inline fun testPropertyWithGetter() = propertyWithGetter + + inline fun testPropertyWithSetter(): String { + propertyWithSetter = "test" + return savedStr + } +} diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineProperty/main/m.kt b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineProperty/main/m.kt new file mode 100644 index 00000000000..08762efb53b --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineProperty/main/m.kt @@ -0,0 +1,19 @@ +fun box(stepId: Int): String { + val a = ClassA() + when (stepId) { + 0 -> { + if (a.testPropertyWithGetter() != "0") return "Fail testPropertyWithGetter()" + if (a.testPropertyWithSetter() != "test 0") return "Fail testPropertyWithSetter()" + } + 1 -> { + if (a.testPropertyWithGetter() != "1") return "Fail testPropertyWithGetter()" + if (a.testPropertyWithSetter() != "test 0") return "Fail testPropertyWithSetter()" + } + 2 -> { + if (a.testPropertyWithGetter() != "1") return "Fail testPropertyWithGetter()" + if (a.testPropertyWithSetter() != "test 2") return "Fail testPropertyWithSetter()" + } + else -> return "Unknown" + } + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineProperty/main/module.info b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineProperty/main/module.info new file mode 100644 index 00000000000..7fdd4b26739 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineProperty/main/module.info @@ -0,0 +1,6 @@ +STEP 0: + dependencies: lib1 + added file: m.kt, classA.kt +STEP 1..2: + dependencies: lib1 + updated inline imports: m.kt, classA.kt diff --git a/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineProperty/project.info b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineProperty/project.info new file mode 100644 index 00000000000..74a808765e7 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/fakeOverrideInlineProperty/project.info @@ -0,0 +1,8 @@ +MODULES: lib1, main + +STEP 0: + libs: lib1, main + dirty js: lib1, main +STEP 1..2: + libs: lib1, main + dirty js: lib1, main