From 9952d43252cea7ae238ef196a8dde7e6e2186e4c Mon Sep 17 00:00:00 2001 From: Alexander Korepanov Date: Wed, 30 Mar 2022 18:19:28 +0300 Subject: [PATCH] [JS IR] IC improvements - Reuse a built fragment - Use cache for saving built JS code --- .../jetbrains/kotlin/cli/js/K2JsIrCompiler.kt | 23 +- .../kotlin/ir/backend/js/compilerWithIC.kt | 49 +-- .../kotlin/ir/backend/js/ic/ArtifactCache.kt | 47 ++- .../ir/backend/js/ic/HashCalculatorForIC.kt | 21 + .../ir/backend/js/ic/IncrementalCache.kt | 14 +- .../ir/backend/js/ic/InlineGraphTracker.kt | 54 ++- .../ir/backend/js/ic/JsExecutableProducer.kt | 83 ++++ .../ir/backend/js/ic/JsMultiModuleCache.kt | 118 ++++++ .../kotlin/ir/backend/js/ic/fileUtils.kt | 2 +- .../kotlin/ir/backend/js/ic/invalidation.kt | 6 +- .../irToJs/IrModuleToJsTransformerTmp.kt | 18 +- .../irToJs/JsIrProgramFragment.kt | 157 +++++--- .../backend/js/transformers/irToJs/Merger.kt | 4 +- .../org/jetbrains/kotlin/codegen/TestModel.kt | 39 +- js/js.tests/build.gradle.kts | 1 + .../incremental/AbstractInvalidationTest.kt | 361 ++++++++++-------- .../js/test/converters/JsIrBackendFacade.kt | 20 +- .../test/utils/JsIrIncrementalDataProvider.kt | 29 +- .../kotlin/js/testOld/JsTestChecker.kt | 23 +- .../InvalidationTestGenerated.java | 5 + .../incremental/invalidation/class/main/m.kt | 9 +- .../invalidation/class/main/module.info | 6 +- .../invalidation/class/project.info | 8 +- .../classFunctionsAndFields/main/m.kt | 40 +- .../classFunctionsAndFields/main/module.info | 24 +- .../classFunctionsAndFields/project.info | 25 +- .../invalidation/constVals/lib2/module.info | 1 - .../invalidation/constVals/main/m.kt | 15 +- .../invalidation/constVals/main/module.info | 1 - .../invalidation/constVals/project.info | 5 +- .../crossModuleReferences/lib1/l1.kt | 6 + .../crossModuleReferences/lib1/module.info | 6 + .../crossModuleReferences/lib2/l2.kt | 2 + .../crossModuleReferences/lib2/l2.kt.1.txt | 2 + .../crossModuleReferences/lib2/l2.kt.2.txt | 2 + .../crossModuleReferences/lib2/l2.kt.3.txt | 2 + .../crossModuleReferences/lib2/l2.kt.4.txt | 2 + .../crossModuleReferences/lib2/l2.kt.6.txt | 2 + .../crossModuleReferences/lib2/module.info | 31 ++ .../crossModuleReferences/main/m.kt | 12 + .../crossModuleReferences/main/m.kt.5.txt | 11 + .../crossModuleReferences/main/module.info | 12 + .../crossModuleReferences/project.info | 14 + .../invalidation/fastPath1/lib1/module.info | 1 - .../invalidation/fastPath1/lib2/module.info | 3 +- .../invalidation/fastPath1/main/m.kt | 9 +- .../invalidation/fastPath1/main/module.info | 3 +- .../invalidation/fastPath1/project.info | 5 +- .../invalidation/fastPath2/lib1/module.info | 1 - .../invalidation/fastPath2/lib2/module.info | 3 +- .../invalidation/fastPath2/main/m.kt | 2 +- .../invalidation/fastPath2/main/module.info | 3 +- .../invalidation/fastPath2/project.info | 4 +- .../functionDefaultParams/main/m.kt | 11 +- .../functionDefaultParams/project.info | 4 + .../invalidation/functionSignature/main/m.kt | 23 +- .../functionSignature/main/module.info | 50 +-- .../functionSignature/project.info | 36 +- .../invalidation/genericFunctions/main/m.kt | 2 +- .../genericFunctions/main/module.info | 14 +- .../genericFunctions/project.info | 10 +- .../libProxy/module.info | 60 +-- .../genericInlineFunctions/main/m.kt | 14 +- .../main/m.proxy.kt.txt | 14 +- .../genericInlineFunctions/main/module.info | 67 +--- .../genericInlineFunctions/project.info | 53 +-- .../inlineBecomeNonInline/main/m.kt | 9 +- .../inlineBecomeNonInline/main/module.info | 5 +- .../inlineBecomeNonInline/project.info | 6 +- .../inlineFunctionAsParam/main/m.kt | 49 ++- .../inlineFunctionAsParam/main/module.info | 24 +- .../inlineFunctionAsParam/project.info | 18 +- .../inlineFunctionDefaultParams/main/m.kt | 9 +- .../main/module.info | 11 +- .../inlineFunctionDefaultParams/project.info | 8 +- .../invalidation/jsCode/lib1/l1.kt.1.txt | 2 +- .../invalidation/jsCode/lib1/l1.kt.2.txt | 2 +- .../incremental/invalidation/jsCode/main/m.kt | 11 +- .../invalidation/jsCode/main/module.info | 12 +- .../invalidation/jsCode/project.info | 8 +- .../invalidation/jsExport/main/m.kt | 6 +- .../invalidation/jsExport/main/module.info | 17 +- .../invalidation/jsExport/project.info | 15 +- .../mainModuleInvalidation/main/m.kt | 5 +- .../mainModuleInvalidation/main/m.kt.1.txt | 5 +- .../mainModuleInvalidation/main/module.info | 1 - .../mainModuleInvalidation/project.info | 3 +- .../moveFilesBetweenModules/lib1/module.info | 2 - .../moveFilesBetweenModules/lib2/module.info | 4 +- .../moveFilesBetweenModules/lib3/module.info | 10 +- .../moveFilesBetweenModules/main/m.kt | 10 +- .../moveFilesBetweenModules/main/module.info | 10 +- .../moveFilesBetweenModules/project.info | 8 +- .../lib2/module.info | 3 +- .../lib3/module.info | 6 +- .../main/m.kt | 9 +- .../main/module.info | 6 +- .../project.info | 5 +- .../nonInlineBecomeInline/main/m.kt | 10 +- .../nonInlineBecomeInline/main/module.info | 4 +- .../nonInlineBecomeInline/project.info | 6 +- .../privateInlineFunction1/lib2/module.info | 2 - .../privateInlineFunction1/main/m.kt | 9 +- .../privateInlineFunction1/main/module.info | 2 - .../privateInlineFunction1/project.info | 5 +- .../invalidation/removeFile/lib2/module.info | 3 +- .../invalidation/removeFile/main/m.kt | 6 +- .../invalidation/removeFile/main/m.kt.new | 5 +- .../invalidation/removeFile/main/module.info | 3 +- .../invalidation/removeFile/project.info | 5 +- .../removeModule/lib1/module.info | 3 +- .../removeModule/lib2/module.info | 3 +- .../invalidation/removeModule/main/m.kt | 9 +- .../removeModule/main/module.info | 1 - .../invalidation/removeModule/project.info | 5 +- .../invalidation/removeUnusedFile/main/m.kt | 5 +- .../removeUnusedFile/project.info | 4 +- .../invalidation/renameFile/main/m.kt | 5 +- .../invalidation/renameFile/main/module.info | 3 +- .../invalidation/renameFile/project.info | 5 +- .../invalidation/simple/lib1/l1.kt | 2 +- .../invalidation/simple/lib1/l1.kt.1 | 1 - .../invalidation/simple/lib1/l1.kt.1.txt | 1 + .../invalidation/simple/lib1/module.info | 2 +- .../invalidation/simple/lib2/module.info | 2 - .../incremental/invalidation/simple/main/m.kt | 9 +- .../invalidation/simple/main/module.info | 3 +- .../invalidation/simple/project.info | 5 +- .../invalidation/suspendFunctions/main/m.kt | 4 +- .../suspendFunctions/project.info | 3 + .../transitiveInlineFunction/lib2/module.info | 6 +- .../transitiveInlineFunction/main/m.kt | 9 +- .../transitiveInlineFunction/main/module.info | 6 +- .../transitiveInlineFunction/project.info | 5 +- .../invalidation/variance/main/m.kt | 5 +- .../invalidation/variance/main/module.info | 4 +- .../invalidation/variance/project.info | 6 +- 137 files changed, 1280 insertions(+), 899 deletions(-) create mode 100644 compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/JsExecutableProducer.kt create mode 100644 compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/JsMultiModuleCache.kt create mode 100644 js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib1/l1.kt create mode 100644 js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib1/module.info create mode 100644 js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib2/l2.kt create mode 100644 js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib2/l2.kt.1.txt create mode 100644 js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib2/l2.kt.2.txt create mode 100644 js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib2/l2.kt.3.txt create mode 100644 js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib2/l2.kt.4.txt create mode 100644 js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib2/l2.kt.6.txt create mode 100644 js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib2/module.info create mode 100644 js/js.translator/testData/incremental/invalidation/crossModuleReferences/main/m.kt create mode 100644 js/js.translator/testData/incremental/invalidation/crossModuleReferences/main/m.kt.5.txt create mode 100644 js/js.translator/testData/incremental/invalidation/crossModuleReferences/main/module.info create mode 100644 js/js.translator/testData/incremental/invalidation/crossModuleReferences/project.info delete mode 100644 js/js.translator/testData/incremental/invalidation/simple/lib1/l1.kt.1 create mode 100644 js/js.translator/testData/incremental/invalidation/simple/lib1/l1.kt.1.txt diff --git a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt index 27743d43994..4b265597e04 100644 --- a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt +++ b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt @@ -286,23 +286,22 @@ class K2JsIrCompiler : CLICompiler() { messageCollector.report(INFO, arguments.cacheDirectories ?: "") if (icCaches.isNotEmpty()) { - val beforeIc2Js = System.currentTimeMillis() - val moduleKind = configurationJs[JSConfigurationKeys.MODULE_KIND]!! - - val translationMode = TranslationMode.fromFlags(false, arguments.irPerModule, false) - - val compiledModule = generateJsFromAst( - moduleName, - moduleKind, - SourceMapsInfo.from(configurationJs), - setOf(translationMode), - icCaches, + val jsExecutableProducer = JsExecutableProducer( + mainModuleName = moduleName, + moduleKind = configurationJs[JSConfigurationKeys.MODULE_KIND]!!, + sourceMapsInfo = SourceMapsInfo.from(configurationJs), + caches = icCaches, relativeRequirePath = true ) - val outputs = compiledModule.outputs.values.single() + val outputs = jsExecutableProducer.buildExecutable( + multiModule = arguments.irPerModule, + rebuildCallback = { rebuiltModule -> + messageCollector.report(INFO, "IC module builder rebuilt module [${File(rebuiltModule).name}]") + } + ) outputFile.write(outputs) outputs.dependencies.forEach { (name, content) -> diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compilerWithIC.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compilerWithIC.kt index 7188563dce0..049ae90aac5 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compilerWithIC.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compilerWithIC.kt @@ -10,14 +10,13 @@ import org.jetbrains.kotlin.backend.common.phaser.PhaserState import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.backend.js.ic.ArtifactCache -import org.jetbrains.kotlin.ir.backend.js.ic.KLibArtifact +import org.jetbrains.kotlin.ir.backend.js.ic.JsMultiModuleCache +import org.jetbrains.kotlin.ir.backend.js.ic.ModuleArtifact import org.jetbrains.kotlin.ir.backend.js.lower.collectNativeImplementations import org.jetbrains.kotlin.ir.backend.js.lower.generateJsTests import org.jetbrains.kotlin.ir.backend.js.lower.moveBodilessDeclarationsToSeparatePlace import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.* -import org.jetbrains.kotlin.ir.backend.js.utils.sanitizeName -import org.jetbrains.kotlin.ir.backend.js.utils.serialization.JsIrAstDeserializer import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.descriptors.IrBuiltInsOverDescriptors import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator @@ -25,7 +24,6 @@ import org.jetbrains.kotlin.ir.util.noUnboundLeft import org.jetbrains.kotlin.js.config.RuntimeDiagnostic import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.serialization.js.ModuleKind -import java.io.ByteArrayInputStream @Suppress("UNUSED_PARAMETER") @OptIn(ObsoleteDescriptorBasedAPI::class) @@ -99,9 +97,11 @@ fun compileWithIC( module.files.filter { it.fileEntry.name in dirties } } ?: module.files - val ast = transformer.generateBinaryAst(dirtyFiles, allModules) - - ast.entries.forEach { (path, bytes) -> artifactCache.saveBinaryAst(path, bytes) } + val astAndFragments = transformer.generateBinaryAst(dirtyFiles, allModules) + astAndFragments.forEach { + artifactCache.saveFragment(it.srcPath, it.fragment) + artifactCache.saveBinaryAst(it.srcPath, it.binaryAst) + } } fun lowerPreservingTags(modules: Iterable, context: JsIrBackendContext, phaseConfig: PhaseConfig, controller: WholeWorldStageController) { @@ -117,38 +117,3 @@ fun lowerPreservingTags(modules: Iterable, context: JsIrBacken controller.currentStage = pirLowerings.size + 1 } - - -@Suppress("UNUSED_PARAMETER") -fun generateJsFromAst( - mainModuleName: String, - moduleKind: ModuleKind, - sourceMapsInfo: SourceMapsInfo?, - translationModes: Set, - caches: List, - relativeRequirePath: Boolean = false, -): CompilerResult { - fun compilationOutput(multiModule: Boolean): CompilationOutputs { - val deserializer = JsIrAstDeserializer() - val jsIrProgram = JsIrProgram(caches.map { cacheArtifact -> - JsIrModule( - cacheArtifact.moduleName.safeModuleName, - sanitizeName(cacheArtifact.moduleName.safeModuleName), - cacheArtifact.fileArtifacts.sortedBy { it.srcFilePath }.mapNotNull { srcFileArtifact -> - srcFileArtifact.astFileArtifact.fetchBinaryAst()?.let { deserializer.deserialize(ByteArrayInputStream(it)) } - }) - }) - - return generateWrappedModuleBody( - multiModule = multiModule, - mainModuleName = mainModuleName, - moduleKind = moduleKind, - jsIrProgram, - sourceMapsInfo = sourceMapsInfo, - relativeRequirePath = relativeRequirePath, - generateScriptModule = false, - ) - } - - return CompilerResult(translationModes.associate { it to compilationOutput(it.perModule) }, null) -} diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/ArtifactCache.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/ArtifactCache.kt index 90bb4f5d646..0a056247a85 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/ArtifactCache.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/ArtifactCache.kt @@ -5,29 +5,52 @@ package org.jetbrains.kotlin.ir.backend.js.ic +import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsIrModule +import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsIrProgramFragment +import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.safeModuleName +import org.jetbrains.kotlin.ir.backend.js.utils.serialization.JsIrAstDeserializer +import java.io.ByteArrayInputStream import java.io.File -class SrcFileArtifact(val srcFilePath: String, astArtifactFilePath: String, astBinaryData: ByteArray?) { - class Artifact(private val artifactFilePath: String, private var binaryData: ByteArray?) { - fun fetchBinaryAst(): ByteArray? { - if (binaryData == null) { - binaryData = File(artifactFilePath).ifExists { readBytes() } - } - return binaryData +class SrcFileArtifact(val srcFilePath: String, private val fragment: JsIrProgramFragment?, private val astArtifact: File? = null) { + fun loadJsIrFragment(deserializer: JsIrAstDeserializer): JsIrProgramFragment? { + if (fragment != null) { + return fragment + } + return astArtifact?.ifExists { readBytes() }?.let { + deserializer.deserialize(ByteArrayInputStream(it)) } } - val astFileArtifact = Artifact(astArtifactFilePath, astBinaryData) + fun isModified() = fragment != null } -class KLibArtifact(val moduleName: String, val fileArtifacts: List) +class ModuleArtifact( + moduleName: String, + val fileArtifacts: List, + val artifactsDir: File? = null, + val forceRebuildJs: Boolean = false +) { + val moduleSafeName = moduleName.safeModuleName + + fun loadJsIrModule(): JsIrModule { + val deserializer = JsIrAstDeserializer() + val fragments = fileArtifacts.sortedBy { it.srcFilePath }.mapNotNull { it.loadJsIrFragment(deserializer) } + return JsIrModule(moduleSafeName, moduleSafeName, fragments) + } +} abstract class ArtifactCache { protected val binaryAsts = mutableMapOf() + protected val fragments = mutableMapOf() - fun saveBinaryAst(srcPath: String, astData: ByteArray) { - binaryAsts[srcPath] = astData + fun saveBinaryAst(srcPath: String, binaryAst: ByteArray) { + binaryAsts[srcPath] = binaryAst } - abstract fun fetchArtifacts(): KLibArtifact + fun saveFragment(srcPath: String, fragment: JsIrProgramFragment) { + fragments[srcPath] = fragment + } + + abstract fun fetchArtifacts(): ModuleArtifact } 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 f12967c91fe..a8a15e4e0b4 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 @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.ir.backend.js.ic import org.jetbrains.kotlin.config.CompilerConfiguration +import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.CrossModuleReferences import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.util.DumpIrTreeVisitor import org.jetbrains.kotlin.js.config.JSConfigurationKeys @@ -99,3 +100,23 @@ internal fun KotlinLibrary.fingerprint(fileIndex: Int) = HashCalculatorForIC().a update(declarations(fileIndex)) update(bodies(fileIndex)) }.finalize() + +internal fun CrossModuleReferences.crossModuleReferencesHashForIC() = HashCalculatorForIC().apply { + for (importedModule in importedModules) { + update(importedModule.externalName) + update(importedModule.internalName.toString()) + } + for (exportFrom in transitiveJsExportFrom) { + update(exportFrom.toString()) + } + for (tag in exports.keys.sorted()) { + update(tag) + update(exports[tag]!!) + } + for (tag in imports.keys.sorted()) { + val import = imports[tag]!! + update(tag) + update(import.exportedAs) + update(import.moduleExporter.toString()) + } +}.finalize() 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 3f22554dc3d..a3ed3248643 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 @@ -36,6 +36,7 @@ class IncrementalCache(private val library: KotlinLibrary, cachePath: String) : private enum class CacheState { NON_LOADED, FETCHED_FOR_DEPENDENCY, FETCHED_FULL } private var state = CacheState.NON_LOADED + private var forceRebuildJs = false private val cacheDir = File(cachePath) private val signatureToIdMapping = mutableMapOf>() @@ -232,10 +233,12 @@ class IncrementalCache(private val library: KotlinLibrary, cachePath: String) : private fun clearCacheAfterCommit() { state = CacheState.FETCHED_FOR_DEPENDENCY + forceRebuildJs = deletedSrcFiles.isNotEmpty() signatureToIdMapping.clear() usedInlineFunctions.clear() srcFilesInOrderFromKLib = emptyList() deletedSrcFiles = emptySet() + binaryAsts.clear() } fun commitCacheForRemovedSrcFiles() { @@ -255,11 +258,14 @@ class IncrementalCache(private val library: KotlinLibrary, cachePath: String) : clearCacheAfterCommit() } - override fun fetchArtifacts() = KLibArtifact( + override fun fetchArtifacts() = ModuleArtifact( moduleName = cacheFastInfo.moduleName ?: error("Internal error: missing module name"), fileArtifacts = fingerprints.keys.map { - SrcFileArtifact(it, getBinaryAstPath(it).absolutePath, binaryAsts[it]) - }) + SrcFileArtifact(it, fragments[it], getBinaryAstPath(it)) + }, + artifactsDir = cacheDir, + forceRebuildJs = forceRebuildJs + ) fun invalidate() { cacheDir.deleteRecursively() @@ -268,6 +274,7 @@ class IncrementalCache(private val library: KotlinLibrary, cachePath: String) : usedInlineFunctions.clear() fingerprints.clear() binaryAsts.clear() + fragments.clear() cacheFastInfo = CacheFastInfo() srcFilesInOrderFromKLib = emptyList() deletedSrcFiles = emptySet() @@ -280,6 +287,7 @@ class IncrementalCache(private val library: KotlinLibrary, cachePath: String) : usedInlineFunctions.remove(srcPath) fingerprints.remove(srcPath) binaryAsts.remove(srcPath) + fragments.remove(srcPath) } private fun KotlinLibrary.filesAndSigReaders(): List> { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/InlineGraphTracker.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/InlineGraphTracker.kt index 4dca8a68146..c743d63243e 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/InlineGraphTracker.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/InlineGraphTracker.kt @@ -7,10 +7,13 @@ package org.jetbrains.kotlin.ir.backend.js.ic import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrFile +import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.expressions.IrCall +import org.jetbrains.kotlin.ir.expressions.IrFunctionReference import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.ir.util.file +import org.jetbrains.kotlin.ir.util.isFakeOverride import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid @@ -29,50 +32,63 @@ class InlineFunctionFlatHashBuilder : IrElementVisitorVoid { declaration.acceptChildren(this, null) } - private val flatHashes = mutableMapOf() + private val flatHashes = mutableMapOf() fun getFlatHashes() = flatHashes } interface InlineFunctionHashProvider { - fun hashForExternalFunction(declaration: IrSimpleFunction): ICHash? + fun hashForExternalFunction(declaration: IrFunction): ICHash? } class InlineFunctionHashBuilder( private val hashProvider: InlineFunctionHashProvider, - private val flatHashes: Map + private val flatHashes: Map ) { - private val inlineFunctionCallGraph: MutableMap> = mutableMapOf() + private val inlineFunctionCallGraph: MutableMap> = mutableMapOf() - private inner class GraphBuilder : IrElementVisitor> { + private inner class GraphBuilder : IrElementVisitor> { + var inlineFunctionCallDepth: Int = 0 - override fun visitElement(element: IrElement, data: MutableSet) { + override fun visitElement(element: IrElement, data: MutableSet) { element.acceptChildren(this, data) } - override fun visitSimpleFunction(declaration: IrSimpleFunction, data: MutableSet) { - val newGraph = mutableSetOf() + override fun visitSimpleFunction(declaration: IrSimpleFunction, data: MutableSet) { + val newGraph = mutableSetOf() inlineFunctionCallGraph[declaration] = newGraph declaration.acceptChildren(this, newGraph) } - - override fun visitCall(expression: IrCall, data: MutableSet) { + override fun visitCall(expression: IrCall, data: MutableSet) { val callee = expression.symbol.owner - if (callee.isInline) { - data.add(callee) + data += callee + inlineFunctionCallDepth += 1 } + expression.acceptChildren(this, data) + if (callee.isInline) { + inlineFunctionCallDepth -= 1 + if (inlineFunctionCallDepth < 0) { + error("Internal error: inline function calls depth inconsistency") + } + } + } + override fun visitFunctionReference(expression: IrFunctionReference, data: MutableSet) { + val reference = expression.symbol.owner + if (inlineFunctionCallDepth > 0 && reference.isInline) { + data += reference + } expression.acceptChildren(this, data) } } private inner class InlineFunctionHashProcessor { - private val computedHashes = mutableMapOf() - private val processingFunctions = mutableSetOf() + private val computedHashes = mutableMapOf() + private val processingFunctions = mutableSetOf() - private fun processInlineFunction(f: IrSimpleFunction): ICHash = computedHashes.getOrPut(f) { + private fun processInlineFunction(f: IrFunction): ICHash = computedHashes.getOrPut(f) { if (!processingFunctions.add(f)) { error("Inline circle through function ${f.render()} detected") } @@ -86,14 +102,14 @@ class InlineFunctionHashBuilder( functionInlineHash } - private fun processCallee(callee: IrSimpleFunction): ICHash { + private fun processCallee(callee: IrFunction): ICHash { if (callee in flatHashes) { return processInlineFunction(callee) } return hashProvider.hashForExternalFunction(callee) ?: error("Internal error: No hash found for ${callee.render()}") } - fun process(): Map { + fun process(): Map { for ((f, callees) in inlineFunctionCallGraph.entries) { if (f.isInline) { processInlineFunction(f) @@ -105,12 +121,12 @@ class InlineFunctionHashBuilder( } } - fun buildHashes(dirtyFiles: Collection): Map { + fun buildHashes(dirtyFiles: Collection): Map { dirtyFiles.forEach { it.acceptChildren(GraphBuilder(), mutableSetOf()) } return InlineFunctionHashProcessor().process() } - fun buildInlineGraph(computedHashed: Map): Map> { + fun buildInlineGraph(computedHashed: Map): Map> { val perFileInlineGraph = inlineFunctionCallGraph.entries.groupBy({ it.key.file }) { it.value } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/JsExecutableProducer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/JsExecutableProducer.kt new file mode 100644 index 00000000000..1426ad7d1b8 --- /dev/null +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/JsExecutableProducer.kt @@ -0,0 +1,83 @@ +/* + * 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.backend.js.CompilationOutputs +import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.* +import org.jetbrains.kotlin.serialization.js.ModuleKind + +class JsExecutableProducer( + private val mainModuleName: String, + private val moduleKind: ModuleKind, + private val sourceMapsInfo: SourceMapsInfo?, + private val caches: List, + private val relativeRequirePath: Boolean +) { + fun buildExecutable(multiModule: Boolean, rebuildCallback: (String) -> Unit = {}) = if (multiModule) { + buildMultiModuleExecutable(rebuildCallback) + } else { + buildSingleModuleExecutable(rebuildCallback) + } + + private fun buildSingleModuleExecutable(rebuildCallback: (String) -> Unit): CompilationOutputs { + val program = JsIrProgram(caches.map { cacheArtifact -> cacheArtifact.loadJsIrModule() }) + val out = generateSingleWrappedModuleBody( + moduleName = mainModuleName, + moduleKind = moduleKind, + fragments = program.modules.flatMap { it.fragments }, + sourceMapsInfo = sourceMapsInfo, + generateScriptModule = false, + generateCallToMain = true + ) + rebuildCallback(mainModuleName) + return out + } + + private fun buildMultiModuleExecutable(rebuildCallback: (String) -> Unit): CompilationOutputs { + val jsMultiModuleCache = JsMultiModuleCache(caches) + val cachedProgram = jsMultiModuleCache.loadProgramHeadersFromCache() + + val resolver = CrossModuleDependenciesResolver(cachedProgram.map { it.jsIrHeader }) + val crossModuleReferences = resolver.resolveCrossModuleDependencies(relativeRequirePath) + + jsMultiModuleCache.loadRequiredJsIrModules(crossModuleReferences) + + fun JsMultiModuleCache.CachedModuleInfo.compileModule(moduleName: String, generateCallToMain: Boolean): CompilationOutputs { + if (jsIrHeader.associatedModule == null) { + val compilationOutputs = jsMultiModuleCache.fetchCompiledJsCode(artifact) + if (compilationOutputs != null) { + return compilationOutputs + } + jsIrHeader.associatedModule = artifact.loadJsIrModule() + } + val associatedModule = jsIrHeader.associatedModule ?: error("Internal error: cannot load module $moduleName") + val crossRef = crossModuleReferences[jsIrHeader] ?: error("Internal error: cannot find cross references for module $moduleName") + crossRef.initJsImportsForModule(associatedModule) + + val compiledModule = generateSingleWrappedModuleBody( + moduleName = moduleName, + moduleKind = moduleKind, + associatedModule.fragments, + sourceMapsInfo = sourceMapsInfo, + generateScriptModule = false, + generateCallToMain = generateCallToMain, + crossModuleReferences = crossRef + ) + jsMultiModuleCache.commitCompiledJsCode(artifact, compiledModule) + rebuildCallback(moduleName) + return compiledModule + } + + val cachedMainModule = cachedProgram.last() + val mainModule = cachedMainModule.compileModule(mainModuleName, true) + + val cachedOtherModules = cachedProgram.dropLast(1) + val dependencies = cachedOtherModules.map { + it.jsIrHeader.externalModuleName to it.compileModule(it.jsIrHeader.externalModuleName, false) + } + return CompilationOutputs(mainModule.jsCode, mainModule.jsProgram, mainModule.sourceMap, dependencies) + } +} diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/JsMultiModuleCache.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/JsMultiModuleCache.kt new file mode 100644 index 00000000000..3e5c62a9ffd --- /dev/null +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/JsMultiModuleCache.kt @@ -0,0 +1,118 @@ +/* + * 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.backend.js.CompilationOutputs +import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.CrossModuleReferences +import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsIrModuleHeader +import java.io.File + +class JsMultiModuleCache(private val moduleArtifacts: List) { + companion object { + private const val cacheModuleHeader = "cache.module.header.info" + private const val cacheJsModuleFile = "cache.module.js" + private const val cacheJsMapModuleFile = "cache.module.js.map" + } + + private enum class NameType(val typeMask: Int) { + DEFINITIONS(0b01), NAME_BINDINGS(0b10) + } + + class CachedModuleInfo(val artifact: ModuleArtifact, val jsIrHeader: JsIrModuleHeader, var crossModuleReferencesHash: ICHash = ICHash()) + + private val headerToCachedInfo = mutableMapOf() + + private fun ModuleArtifact.fetchModuleInfo() = File(artifactsDir, cacheModuleHeader).useCodedInputIfExists { + val definitions = mutableSetOf() + val nameBindings = mutableMapOf() + + val crossModuleReferencesHash = ICHash.fromProtoStream(this) + val hasJsExports = readBool() + repeat(readInt32()) { + val tag = readString() + val mask = readInt32() + if (mask and NameType.DEFINITIONS.typeMask != 0) { + definitions += tag + } + if (mask and NameType.NAME_BINDINGS.typeMask != 0) { + nameBindings[tag] = readString() + } + } + CachedModuleInfo( + artifact = this@fetchModuleInfo, + jsIrHeader = JsIrModuleHeader(moduleSafeName, moduleSafeName, definitions, nameBindings, hasJsExports, null), + crossModuleReferencesHash = crossModuleReferencesHash + ) + } + + private fun CachedModuleInfo.commitModuleInfo() = artifact.artifactsDir?.let { cacheDir -> + File(cacheDir, cacheModuleHeader).useCodedOutput { + val names = mutableMapOf>() + for ((tag, name) in jsIrHeader.nameBindings) { + names[tag] = NameType.NAME_BINDINGS.typeMask to name + } + for (tag in jsIrHeader.definitions) { + val maskAndName = names[tag] + names[tag] = ((maskAndName?.first ?: 0) or NameType.DEFINITIONS.typeMask) to maskAndName?.second + } + crossModuleReferencesHash.toProtoStream(this) + writeBoolNoTag(jsIrHeader.hasJsExports) + writeInt32NoTag(names.size) + for ((tag, maskAndName) in names) { + writeStringNoTag(tag) + writeInt32NoTag(maskAndName.first) + if (maskAndName.second != null) { + writeStringNoTag(maskAndName.second) + } + } + } + } + + fun fetchCompiledJsCode(artifact: ModuleArtifact) = artifact.artifactsDir?.let { cacheDir -> + val jsCode = File(cacheDir, cacheJsModuleFile).ifExists { readText() } + val sourceMap = File(cacheDir, cacheJsMapModuleFile).ifExists { readText() } + jsCode?.let { CompilationOutputs(it, null, sourceMap) } + } + + fun commitCompiledJsCode(artifact: ModuleArtifact, compilationOutputs: CompilationOutputs) = artifact.artifactsDir?.let { cacheDir -> + val jsCodeCache = File(cacheDir, cacheJsModuleFile).apply { recreate() } + jsCodeCache.writeText(compilationOutputs.jsCode) + val jsMapCache = File(cacheDir, cacheJsMapModuleFile) + if (compilationOutputs.sourceMap != null) { + jsMapCache.recreate() + jsMapCache.writeText(compilationOutputs.sourceMap) + } else { + jsMapCache.ifExists { delete() } + } + } + + fun loadProgramHeadersFromCache(): List { + return moduleArtifacts.map { artifact -> + fun loadModuleInfo() = CachedModuleInfo(artifact, artifact.loadJsIrModule().makeModuleHeader()) + val actualInfo = when { + artifact.forceRebuildJs -> loadModuleInfo() + artifact.fileArtifacts.any { it.isModified() } -> loadModuleInfo() + else -> artifact.fetchModuleInfo() ?: loadModuleInfo() + } + headerToCachedInfo[actualInfo.jsIrHeader] = actualInfo + actualInfo + } + } + + fun loadRequiredJsIrModules(crossModuleReferences: Map) { + for ((header, references) in crossModuleReferences) { + val cachedInfo = headerToCachedInfo[header] ?: error("Internal error: cannot find artifact for module ${header.moduleName}") + val actualCrossModuleHash = references.crossModuleReferencesHashForIC() + if (header.associatedModule == null && cachedInfo.crossModuleReferencesHash != actualCrossModuleHash) { + header.associatedModule = cachedInfo.artifact.loadJsIrModule() + } + header.associatedModule?.let { + cachedInfo.crossModuleReferencesHash = actualCrossModuleHash + cachedInfo.commitModuleInfo() + } + } + } +} diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/fileUtils.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/fileUtils.kt index 9b8f7316268..866dd771e04 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/fileUtils.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/fileUtils.kt @@ -20,7 +20,7 @@ internal fun File.recreate() { createNewFile() } -internal inline fun File.useCodedInputIfExists(f: CodedInputStream.() -> Unit) = ifExists { +internal inline fun File.useCodedInputIfExists(f: CodedInputStream.() -> T) = ifExists { CodedInputStream.newInstance(FileInputStream(this)).f() } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/invalidation.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/invalidation.kt index fe51c86f574..0e72bf7ff06 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/invalidation.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/invalidation.kt @@ -9,8 +9,8 @@ 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.declarations.IrFactory +import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrModuleFragment -import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.js.config.JSConfigurationKeys @@ -144,7 +144,7 @@ class CacheUpdater( }.getFlatHashes() val hashProvider = object : InlineFunctionHashProvider { - override fun hashForExternalFunction(declaration: IrSimpleFunction): ICHash? { + override fun hashForExternalFunction(declaration: IrFunction): ICHash? { return declaration.symbol.signature?.let { cleanInlineHashes[it] } } } @@ -254,7 +254,7 @@ class CacheUpdater( } } - fun actualizeCaches(callback: (CacheUpdateStatus, String) -> Unit): List { + fun actualizeCaches(callback: (CacheUpdateStatus, String) -> Unit): List { val libraries = loadLibraries() val dependencyGraph = buildDependenciesGraph(libraries) val configHash = compilerConfiguration.configHashForIC() diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrModuleToJsTransformerTmp.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrModuleToJsTransformerTmp.kt index 0c35df44c60..7e454cf410b 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrModuleToJsTransformerTmp.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrModuleToJsTransformerTmp.kt @@ -125,7 +125,9 @@ class IrModuleToJsTransformerTmp( return CompilerResult(result, dts) } - fun generateBinaryAst(files: Iterable, allModules: Iterable): Map { + class SrcFileFragmentAndBinaryAst(val srcPath: String, val fragment: JsIrProgramFragment, val binaryAst: ByteArray) + + fun generateBinaryAst(files: Iterable, allModules: Iterable): List { val exportModelGenerator = ExportModelGenerator(backendContext, generateNamespacesForPackages = true) val exportData = files.associate { file -> @@ -139,18 +141,14 @@ class IrModuleToJsTransformerTmp( } val serializer = JsIrAstSerializer() - - val result = mutableMapOf() - files.forEach { f -> + return files.map { f -> val exports = exportData[f]!! // TODO val fragment = generateProgramFragment(f, exports, minimizedMemberNames = false) val output = ByteArrayOutputStream() serializer.serialize(fragment, output) val binaryAst = output.toByteArray() - result[f.fileEntry.name] = binaryAst + SrcFileFragmentAndBinaryAst(f.fileEntry.name, fragment, binaryAst) } - - return result } private fun ExportModelGenerator.generateExportWithExternals(irFile: IrFile): List { @@ -330,7 +328,7 @@ class IrModuleToJsTransformerTmp( } } -fun generateWrappedModuleBody( +private fun generateWrappedModuleBody( multiModule: Boolean, mainModuleName: String, moduleKind: ModuleKind, @@ -383,7 +381,7 @@ fun generateWrappedModuleBody( } } -private fun generateSingleWrappedModuleBody( +fun generateSingleWrappedModuleBody( moduleName: String, moduleKind: ModuleKind, fragments: List, @@ -458,4 +456,4 @@ class SourceMapsInfo( ) } } -} \ No newline at end of file +} diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIrProgramFragment.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIrProgramFragment.kt index 9eec7e47b85..412eb723c19 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIrProgramFragment.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIrProgramFragment.kt @@ -27,111 +27,148 @@ class JsIrProgramFragment(val packageFqn: String) { class JsIrModule( val moduleName: String, val externalModuleName: String, - val fragments: List, -) + val fragments: List +) { + fun makeModuleHeader(): JsIrModuleHeader { + val nameBindings = mutableMapOf() + val definitions = mutableSetOf() + var hasJsExports = false + for (fragment in fragments) { + hasJsExports = hasJsExports || !fragment.exports.isEmpty + for ((tag, name) in fragment.nameBindings.entries) { + nameBindings[tag] = name.toString() + } + definitions += fragment.definitions + } + return JsIrModuleHeader(moduleName, externalModuleName, definitions, nameBindings, hasJsExports, this) + } +} + +class JsIrModuleHeader( + val moduleName: String, + val externalModuleName: String, + val definitions: Set, + val nameBindings: Map, + val hasJsExports: Boolean, + var associatedModule: JsIrModule? +) { + val externalNames: Set by lazy { nameBindings.keys - definitions } +} class JsIrProgram(val modules: List) { val mainModule = modules.last() val otherModules = modules.dropLast(1) fun crossModuleDependencies(relativeRequirePath: Boolean): Map { - val moduleToBuilder = modules.associateWith { JsIrModuleCrossModuleReferecenceBuilder(it, relativeRequirePath) } + val resolver = CrossModuleDependenciesResolver(modules.map { it.makeModuleHeader() }) + val crossModuleReferences = resolver.resolveCrossModuleDependencies(relativeRequirePath) + return crossModuleReferences.entries.associate { + val module = it.key.associatedModule ?: error("Internal error: module ${it.key.moduleName} is not loaded") + it.value.initJsImportsForModule(module) + module to it.value + } + } +} + +class CrossModuleDependenciesResolver(private val headers: List) { + fun resolveCrossModuleDependencies(relativeRequirePath: Boolean): Map { + val headerToBuilder = headers.associateWith { JsIrModuleCrossModuleReferecenceBuilder(it, relativeRequirePath) } val definitionModule = mutableMapOf() - moduleToBuilder[mainModule]!!.transitiveJsExportFrom = otherModules - for (module in modules) { - val moduleBuilder = moduleToBuilder[module]!! - for (fragment in module.fragments) { - for (definition in fragment.definitions) { - require(definition !in definitionModule) { "Duplicate definition: $definition" } - definitionModule[definition] = moduleBuilder - } + val mainModuleHeader = headers.last() + val otherModuleHeaders = headers.dropLast(1) + headerToBuilder[mainModuleHeader]!!.transitiveJsExportFrom = otherModuleHeaders + + for (header in headers) { + val builder = headerToBuilder[header]!! + for (definition in header.definitions) { + require(definition !in definitionModule) { "Duplicate definition: $definition" } + definitionModule[definition] = builder } } - for (module in modules) { - val moduleBuilder = moduleToBuilder[module]!! - for (fragment in module.fragments) { - for (tag in fragment.nameBindings.keys) { - val fromModuleBuilder = definitionModule[tag] ?: continue // TODO error? - if (fromModuleBuilder == moduleBuilder) continue + for (header in headers) { + val builder = headerToBuilder[header]!! + for (tag in header.externalNames) { + val fromModuleBuilder = definitionModule[tag] ?: continue // TODO error? - moduleBuilder.imports += CrossModuleRef(fromModuleBuilder, tag) - fromModuleBuilder.exports += tag - } + builder.imports += CrossModuleRef(fromModuleBuilder, tag) + fromModuleBuilder.exports += tag } } - return modules.associateWith { moduleToBuilder[it]!!.buildCrossModuleRefs() } + return headers.associateWith { headerToBuilder[it]!!.buildCrossModuleRefs() } } - } +private fun String.prettyTag() = takeWhile { c -> c != '|' } + private class CrossModuleRef(val module: JsIrModuleCrossModuleReferecenceBuilder, val tag: String) - -private class JsIrModuleCrossModuleReferecenceBuilder(val module: JsIrModule, val relativeRequirePath: Boolean) { +private class JsIrModuleCrossModuleReferecenceBuilder(val header: JsIrModuleHeader, val relativeRequirePath: Boolean) { val imports = mutableListOf() val exports = mutableSetOf() - var transitiveJsExportFrom = emptyList() + var transitiveJsExportFrom = emptyList() private lateinit var exportNames: Map // tag -> index - private fun buildUniqueNames() { - val result = mutableMapOf() - + private fun buildExportNames() { var index = 0 - - exports.sorted().forEach { tag -> - result[tag] = index++.toJsIdentifier() - } - - exportNames = result + exportNames = exports.sorted().associateWith { index++.toJsIdentifier() } } fun buildCrossModuleRefs(): CrossModuleReferences { - buildUniqueNames() + buildExportNames() + val importedModules = mutableMapOf() - val importedModules = mutableMapOf() - - fun JsIrModule.import(): JsName { - return importedModules.getOrPut(this) { - val moduleName = JsName(moduleName, false) - JsImportedModule(externalModuleName, moduleName, null, relativeRequirePath) + fun import(moduleHeader: JsIrModuleHeader): JsName { + return importedModules.getOrPut(moduleHeader) { + val jsModuleName = JsName(moduleHeader.moduleName, false) + JsImportedModule(moduleHeader.externalModuleName, jsModuleName, null, relativeRequirePath) }.internalName } - val tagToName = module.fragments.flatMap { it.nameBindings.entries }.associate { it.key to it.value } - - val resultImports = imports.associate { - val tag = it.tag - require(it.module::exportNames.isInitialized) { + val resultImports = imports.associate { crossModuleRef -> + val tag = crossModuleRef.tag + require(crossModuleRef.module::exportNames.isInitialized) { // This situation appears in case of a dependent module redefine a symbol (function) from their dependency - "Cross module dependency resolution failed due to symbol '${tag.takeWhile { c -> c != '|' }}' redefinition" + "Cross module dependency resolution failed due to symbol '${tag.prettyTag()}' redefinition" } - val exportedAs = it.module.exportNames[tag]!! - val importedAs = tagToName[tag]!! - val moduleName = it.module.module.import() + val exportedAs = crossModuleRef.module.exportNames[tag]!! + val moduleName = import(crossModuleRef.module.header) - val importStatement = JsVars.JsVar(importedAs, JsNameRef(exportedAs, ReservedJsNames.makeCrossModuleNameRef(moduleName))) - - tag to importStatement + tag to CrossModuleImport(exportedAs, moduleName) } val transitiveExport = transitiveJsExportFrom.mapNotNull { - it.fragments.find { f -> !f.exports.isEmpty }?.run { it.import() } + if (it.hasJsExports) import(it) else null } - return CrossModuleReferences(importedModules.values.toList(), resultImports, exportNames, transitiveExport) + return CrossModuleReferences(importedModules.values.toList(), transitiveExport, exportNames, resultImports) } } +class CrossModuleImport(val exportedAs: String, val moduleExporter: JsName) + class CrossModuleReferences( val importedModules: List, // additional Kotlin imported modules - val imports: Map, // tag -> import statement + val transitiveJsExportFrom: List, // the list of modules which provide their js exports for transitive export val exports: Map, // tag -> index - val transitiveJsExportFrom: List // the list of modules which provide their js exports for transitive export + val imports: Map, // tag -> import statement ) { - companion object { - val Empty = CrossModuleReferences(listOf(), emptyMap(), emptyMap(), emptyList()) + // built from imports + var jsImports = emptyMap() // tag -> import statement + private set + + fun initJsImportsForModule(module: JsIrModule) { + val tagToName = module.fragments.flatMap { it.nameBindings.entries }.associate { it.key to it.value } + jsImports = imports.entries.associate { + val importedAs = tagToName[it.key] ?: error("Internal error: cannot find imported name for symbol ${it.key.prettyTag()}") + val exportRef = JsNameRef(it.value.exportedAs, ReservedJsNames.makeCrossModuleNameRef(it.value.moduleExporter)) + it.key to JsVars.JsVar(importedAs, exportRef) + } } -} \ No newline at end of file + + companion object { + val Empty = CrossModuleReferences(listOf(), emptyList(), emptyMap(), emptyMap()) + } +} diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/Merger.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/Merger.kt index a9fefae296c..b4c536bee32 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/Merger.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/Merger.kt @@ -56,7 +56,7 @@ class Merger( } } - for ((tag, jsVar) in crossModuleReferences.imports) { + for ((tag, jsVar) in crossModuleReferences.jsImports) { val importName = nameMap[tag] ?: error("Missing name for declaration '$tag'") importStatements.putIfAbsent(tag, JsVars(JsVars.JsVar(importName, jsVar.initExpression))) @@ -302,4 +302,4 @@ class Merger( this += statements endRegion() } -} \ No newline at end of file +} diff --git a/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/TestModel.kt b/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/TestModel.kt index 9be20f7f4ac..4036a557492 100644 --- a/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/TestModel.kt +++ b/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/TestModel.kt @@ -10,7 +10,7 @@ import java.util.regex.Pattern class ProjectInfo(val name: String, val modules: List, val steps: List, val muted: Boolean) { - class ProjectBuildStep(val id: Int, val order: List) + class ProjectBuildStep(val id: Int, val order: List, val dirtyJS: List) } class ModuleInfo(val moduleName: String) { @@ -52,14 +52,15 @@ class ModuleInfo(val moduleName: String) { } enum class StepDirectives(val mnemonic: String) { - FAST_PATH_UPDATE("FP") + FAST_PATH_UPDATE("FP"), + UNUSED_MODULE("UNUSED") } const val MODULES_LIST = "MODULES" const val PROJECT_INFO_FILE = "project.info" const val MODULE_INFO_FILE = "module.info" -private val STEP_PATTERN = Pattern.compile("^\\s*STEP\\s+(\\d+)\\s*:?$") +private val STEP_PATTERN = Pattern.compile("^\\s*STEP\\s+(\\d+)\\.*(\\d+)?\\s*:?$") private val MODIFICATION_PATTERN = Pattern.compile("^([UD])\\s*:(.+)$") @@ -94,11 +95,14 @@ abstract class InfoParser(protected val infoFile: File) { } +private fun String.splitAndTrim() = split(",").map { it.trim() }.filter { it.isNotBlank() } + class ProjectInfoParser(infoFile: File) : InfoParser(infoFile) { - private fun parseStep(stepId: Int): ProjectInfo.ProjectBuildStep { + private fun parseSteps(firstId: Int, lastId: Int): List { val order = mutableListOf() + val dirtyJS = mutableListOf() loop { line -> val splitIndex = line.indexOf(':') @@ -113,10 +117,13 @@ class ProjectInfoParser(infoFile: File) : InfoParser(infoFile) { ++lineCounter + when (op) { "libs" -> { - val args = splitted[1] - args.split(",").filter { it.isNotBlank() }.forEach { order.add(it.trim()) } + order += splitted[1].splitAndTrim() + } + "dirty js" -> { + dirtyJS += splitted[1].splitAndTrim() } else -> println(diagnosticMessage("Unknown op $op", line)) } @@ -124,7 +131,7 @@ class ProjectInfoParser(infoFile: File) : InfoParser(infoFile) { false } - return ProjectInfo.ProjectBuildStep(stepId, order) + return (firstId..lastId).map { ProjectInfo.ProjectBuildStep(it, order, dirtyJS) } } override fun parse(entryName: String): ProjectInfo { @@ -148,14 +155,15 @@ class ProjectInfoParser(infoFile: File) : InfoParser(infoFile) { when { op == MODULES_LIST -> { - val arguments = splitted[1] - arguments.split(",").filter { it.isNotBlank() }.forEach { libraries.add(it.trim()) } + libraries += splitted[1].splitAndTrim() } op.matches(STEP_PATTERN.toRegex()) -> { val m = STEP_PATTERN.matcher(op) if (!m.matches()) throwSyntaxError(line) - val stepId = Integer.parseInt(m.group(1)) - steps.add(parseStep(stepId)) + + val firstId = Integer.parseInt(m.group(1)) + val lastId = m.group(2)?.let { Integer.parseInt(it) } ?: firstId + steps += parseSteps(firstId, lastId) } else -> println(diagnosticMessage("Unknown op $op", line)) } @@ -202,7 +210,7 @@ class ModuleInfoParser(infoFile: File) : InfoParser(infoFile) { } } - private fun parseStep(stepId: Int): ModuleInfo.ModuleStep { + private fun parseSteps(firstId: Int, lastId: Int): List { val dependencies = mutableSetOf() val dirtyFiles = mutableSetOf() val modifications = mutableListOf() @@ -227,7 +235,7 @@ class ModuleInfoParser(infoFile: File) : InfoParser(infoFile) { false } - return ModuleInfo.ModuleStep(stepId, dependencies, dirtyFiles, modifications, directives) + return (firstId..lastId).map { ModuleInfo.ModuleStep(it, dependencies, dirtyFiles, modifications, directives) } } override fun parse(entryName: String): ModuleInfo { @@ -237,8 +245,9 @@ class ModuleInfoParser(infoFile: File) : InfoParser(infoFile) { lineCounter++ val stepMatcher = STEP_PATTERN.matcher(line) if (stepMatcher.matches()) { - val id = Integer.parseInt(stepMatcher.group(1)) - result.steps.add(parseStep(id)) + val firstId = Integer.parseInt(stepMatcher.group(1)) + val lastId = stepMatcher.group(2)?.let { Integer.parseInt(it) } ?: firstId + result.steps += parseSteps(firstId, lastId) } false } diff --git a/js/js.tests/build.gradle.kts b/js/js.tests/build.gradle.kts index f459018c782..5a8c1fc437e 100644 --- a/js/js.tests/build.gradle.kts +++ b/js/js.tests/build.gradle.kts @@ -366,6 +366,7 @@ projectTest("wasmTest", true) { } projectTest("invalidationTest", jUnitMode = JUnitMode.JUnit4) { + setupV8() workingDir = rootDir include("org/jetbrains/kotlin/incremental/*") diff --git a/js/js.tests/test/org/jetbrains/kotlin/incremental/AbstractInvalidationTest.kt b/js/js.tests/test/org/jetbrains/kotlin/incremental/AbstractInvalidationTest.kt index f95d3d3f1bf..b211f6a2998 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/incremental/AbstractInvalidationTest.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/incremental/AbstractInvalidationTest.kt @@ -16,25 +16,37 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.codegen.* import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.CompilerConfiguration -import org.jetbrains.kotlin.ir.backend.js.WholeWorldStageController -import org.jetbrains.kotlin.ir.backend.js.generateKLib +import org.jetbrains.kotlin.ir.backend.js.* import org.jetbrains.kotlin.ir.backend.js.ic.* import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker -import org.jetbrains.kotlin.ir.backend.js.prepareAnalyzedSourceModule -import org.jetbrains.kotlin.ir.declarations.IrFactory +import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.SourceMapsInfo +import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.safeModuleName import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImplForJsIC +import org.jetbrains.kotlin.js.config.JSConfigurationKeys +import org.jetbrains.kotlin.js.testOld.V8IrJsTestChecker import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.serialization.js.ModuleKind import org.jetbrains.kotlin.test.KotlinTestWithEnvironment import org.jetbrains.kotlin.test.util.JUnit4Assertions +import org.junit.ComparisonFailure import java.io.File import kotlin.io.path.createTempDirectory -private var stdlibCacheDir: File? = null - abstract class AbstractInvalidationTest : KotlinTestWithEnvironment() { + companion object { + private const val TEST_DATA_DIR_PATH = "js/js.translator/testData/" + + private const val stdlibAlias = "stdlib" + private const val stdlibModuleName = "kotlin" + private val stdlibKlibPath = File(System.getProperty("kotlin.js.stdlib.klib.path") ?: error("Please set stdlib path")).canonicalPath + private var stdlibCacheDir: File? = null + + private const val boxFunctionName = "box" + } + override fun createEnvironment(): KotlinCoreEnvironment { return KotlinCoreEnvironment.createForTests(TestDisposable(), CompilerConfiguration(), EnvironmentConfigFiles.JS_CONFIG_FILES) } @@ -47,36 +59,24 @@ abstract class AbstractInvalidationTest : KotlinTestWithEnvironment() { return ModuleInfoParser(infoFile).parse(moduleName) } - @Suppress("UNUSED_PARAMETER") - private fun emptyChecker( - currentModule: IrModuleFragment, - dependencies: Collection, - deserializer: JsIrLinker, - configuration: CompilerConfiguration, - dirtyFiles: Collection?, // if null consider the whole module dirty - artifactCache: ArtifactCache, - exportedDeclarations: Set, - mainArguments: List?, - ) { - } - private fun initializeStdlibCache() { if (stdlibCacheDir != null) return val cacheDir = createTempDirectory().toFile() cacheDir.deleteOnExit() - val configuration = createConfiguration("stdlib") - - actualizeCacheForModuleWithPrepare( + val cacheUpdater = CacheUpdater( stdlibKlibPath, - cacheDir.canonicalPath, - configuration, listOf(stdlibKlibPath), - emptyList(), - IrFactoryImpl, - null, // TODO: mainArguments - ::emptyChecker + createConfiguration(stdlibAlias), + listOf(cacheDir.canonicalPath), + { IrFactoryImplForJsIC(WholeWorldStageController()) }, + null, + ::buildCacheForModuleFiles ) + cacheUpdater.actualizeCaches { updateStatus, updatedModule -> + JUnit4Assertions.assertEquals(stdlibKlibPath, updatedModule) { "incorrect std klib path" } + JUnit4Assertions.assertTrue(updateStatus is CacheUpdateStatus.Dirty) { "std klib should be rebuilt" } + } stdlibCacheDir = cacheDir } @@ -104,70 +104,213 @@ abstract class AbstractInvalidationTest : KotlinTestWithEnvironment() { initializeWorkingDir(projectInfo, testDirectory, sourceDir, buildDir) - executeProjectSteps(projectInfo, modulesInfos, testDirectory, sourceDir, buildDir) + ProjectStepsExecutor(projectInfo, modulesInfos, testDirectory, sourceDir, buildDir).execute() } - private val stdlibKlibPath = System.getProperty("kotlin.js.stdlib.klib.path") ?: error("Please set stdlib path") - - private val String.artifactName: String get() = "$this.klib" - private fun resolveModuleArtifact(moduleName: String, buildDir: File): File { - if (moduleName == "stdlib") return File(stdlibKlibPath) - return File(File(buildDir, moduleName), moduleName.artifactName) + if (moduleName == stdlibAlias) return File(stdlibKlibPath) + return File(File(buildDir, moduleName), "$moduleName.klib") } private fun resolveModuleCache(moduleName: String, buildDir: File): File { - if (moduleName == "stdlib") return stdlibCacheDir ?: error("stdlib cache corruption") + if (moduleName == stdlibAlias) return stdlibCacheDir ?: error("stdlib cache corruption") return File(File(buildDir, moduleName), "cache") } private fun createConfiguration(moduleName: String): CompilerConfiguration { val copy = environment.configuration.copy() copy.put(CommonConfigurationKeys.MODULE_NAME, moduleName) + copy.put(JSConfigurationKeys.MODULE_KIND, ModuleKind.PLAIN) return copy } - private fun executeProjectSteps( - projectInfo: ProjectInfo, - moduleInfos: Map, - testDir: File, - sourceDir: File, - buildDir: File + private inner class ProjectStepsExecutor( + private val projectInfo: ProjectInfo, + private val moduleInfos: Map, + private val testDir: File, + private val sourceDir: File, + private val buildDir: File ) { - for (projStep in projectInfo.steps) { - for (module in projStep.order) { - val moduleTestDir = File(testDir, module) - val moduleSourceDir = File(sourceDir, module) - val moduleInfo = moduleInfos[module] ?: error("No module info found for $module") - val moduleStep = moduleInfo.steps[projStep.id] - val deletedFiles = mutableListOf() - for (modification in moduleStep.modifications) { - modification.execute(moduleTestDir, moduleSourceDir) { deletedFiles.add(it) } + private inner class TestStepInfo( + val moduleName: String, + val modulePath: String, + val icCacheDir: String, + val directives: Set, + val dirtyFiles: List = emptyList(), + val deletedFiles: List = emptyList() + ) + + private fun setupTestStep(projStepId: Int, module: String): TestStepInfo { + val moduleTestDir = File(testDir, module) + val moduleSourceDir = File(sourceDir, module) + val moduleInfo = moduleInfos[module] ?: error("No module info found for $module") + val moduleStep = moduleInfo.steps[projStepId] + val deletedFiles = mutableListOf() + for (modification in moduleStep.modifications) { + modification.execute(moduleTestDir, moduleSourceDir) { deletedFiles.add(it) } + } + + val dependencies = moduleStep.dependencies.map { resolveModuleArtifact(it, buildDir) } + val outputKlibFile = resolveModuleArtifact(module, buildDir) + val configuration = createConfiguration(module) + buildArtifact(configuration, module, moduleSourceDir, dependencies, outputKlibFile) + + return TestStepInfo( + module.safeModuleName, + outputKlibFile.canonicalPath, + resolveModuleCache(module, buildDir).canonicalPath, + moduleStep.directives, + moduleStep.dirtyFiles.map { File(moduleSourceDir, it).canonicalPath }, + deletedFiles.map { it.canonicalPath } + ) + } + + private fun verifyCacheUpdateStatus(stepId: Int, statuses: Map, testInfo: List) { + val expectedInfo = testInfo.filter { StepDirectives.UNUSED_MODULE !in it.directives } + + JUnit4Assertions.assertEquals(statuses.size, expectedInfo.size) { + "Mismatched updated modules count at step $stepId" + } + + for (info in expectedInfo) { + JUnit4Assertions.assertTrue(info.modulePath in statuses) { + "Status is missed for ${info.modulePath} at step $stepId" + } + val updateStatus = statuses[info.modulePath]!! + if (StepDirectives.FAST_PATH_UPDATE in info.directives) { + JUnit4Assertions.assertEquals(CacheUpdateStatus.FastPath, updateStatus) { + "Cache has to be checked by fast path, instead it $updateStatus at step $stepId" + } + } else { + JUnit4Assertions.assertNotEquals(CacheUpdateStatus.FastPath, updateStatus) { + "Cache has not to be checked by fast path, but it is at step $stepId" + } } - val dependencies = moduleStep.dependencies.map { resolveModuleArtifact(it, buildDir) } + val (updated, removed) = when (updateStatus) { + is CacheUpdateStatus.FastPath -> emptySet() to emptySet() + is CacheUpdateStatus.NoDirtyFiles -> emptySet() to updateStatus.removed + is CacheUpdateStatus.Dirty -> updateStatus.updated to updateStatus.removed + } - val outputKlibFile = resolveModuleArtifact(module, buildDir) + JUnit4Assertions.assertSameElements(info.dirtyFiles, updated.map { File(it).canonicalPath }) { + "Mismatched DIRTY files for module ${info.moduleName} at step $stepId" + } - val configuration = createConfiguration(module) + JUnit4Assertions.assertSameElements(info.deletedFiles, removed.map { File(it).canonicalPath }) { + "Mismatched DELETED files for module ${info.moduleName} at step $stepId" + } + } + } - buildArtifact(configuration, module, moduleSourceDir, dependencies, outputKlibFile) + private fun verifyJsExecutableProducerBuildModules(stepId: Int, gotRebuilt: Set, expectedRebuilt: List) { + val expected = expectedRebuilt.map { if (it == stdlibAlias) stdlibModuleName.safeModuleName else it.safeModuleName } + JUnit4Assertions.assertSameElements(expected, gotRebuilt) { + "Mismatched rebuilt modules at step $stepId" + } + } - val dirtyFiles = moduleStep.dirtyFiles.map { File(moduleSourceDir, it) } - val icCaches = moduleStep.dependencies.map { resolveModuleCache(it, buildDir) } + fun writeJsFile(name: String, text: String): String { + val file = File(buildDir, "$name.js") + if (file.exists()) { + file.delete() + } + file.writeText(text) + return file.canonicalPath + } - val moduleCacheDir = resolveModuleCache(module, buildDir) - - buildCachesAndCheck( - moduleStep, - configuration, - outputKlibFile, - moduleCacheDir, - dependencies, - icCaches, - dirtyFiles, - deletedFiles + private fun verifyJsCode(stepId: Int, mainModuleName: String, jsOutput: CompilationOutputs) { + val files = jsOutput.dependencies.map { writeJsFile(it.first, it.second.jsCode) } + writeJsFile(mainModuleName, jsOutput.jsCode) + try { + V8IrJsTestChecker.checkWithTestFunctionArgs( + files = files, + testModuleName = mainModuleName, + testPackageName = null, + testFunctionName = boxFunctionName, + testFunctionArgs = "$stepId", + expectedResult = "OK", + withModuleSystem = false ) + } catch (e: ComparisonFailure) { + throw ComparisonFailure("Mismatched box out at step $stepId", e.expected, e.actual) + } catch (e: IllegalStateException) { + throw IllegalStateException("Something goes wrong (bad JS code?) at step $stepId\n${e.message}") + } + } + + fun executorWithBoxExport( + currentModule: IrModuleFragment, + dependencies: Collection, + deserializer: JsIrLinker, + configuration: CompilerConfiguration, + dirtyFiles: Collection?, + artifactCache: ArtifactCache, + exportedDeclarations: Set, + mainArguments: List? + ) { + buildCacheForModuleFiles( + currentModule = currentModule, + dependencies = dependencies, + deserializer = deserializer, + configuration = configuration, + dirtyFiles = dirtyFiles, + artifactCache = artifactCache, + exportedDeclarations = exportedDeclarations + FqName(boxFunctionName), + mainArguments = mainArguments, + ) + } + + fun execute() { + val stdlibInfo = TestStepInfo( + moduleName = stdlibModuleName.safeModuleName, + modulePath = stdlibKlibPath, + icCacheDir = stdlibCacheDir!!.canonicalPath, + directives = setOf(StepDirectives.FAST_PATH_UPDATE) + ) + for (projStep in projectInfo.steps) { + val testInfo = projStep.order.mapTo(mutableListOf(stdlibInfo)) { setupTestStep(projStep.id, it) } + + val configuration = createConfiguration(projStep.order.last()) + val cacheUpdater = CacheUpdater( + rootModule = testInfo.last().modulePath, + testInfo.map { it.modulePath }, + configuration, + testInfo.map { it.icCacheDir }, + { IrFactoryImplForJsIC(WholeWorldStageController()) }, + null, + ::executorWithBoxExport + ) + + val updateStatuses = mutableMapOf() + var icCaches = cacheUpdater.actualizeCaches { updateStatus, updatedModule -> updateStatuses[updatedModule] = updateStatus } + verifyCacheUpdateStatus(projStep.id, updateStatuses, testInfo) + + val mainModuleCacheDir = icCaches.last().artifactsDir!! + // tests use one stdlib artifact for all cases, patching stdlib cache path here: + // - enable using cached js (stdlib) file through all steps in a test case + // - disable using cached js (stdlib) file through test cases + icCaches = icCaches.map { + when (it.moduleSafeName) { + stdlibModuleName.safeModuleName -> { + val stdlibDir = File(mainModuleCacheDir, stdlibAlias).apply { mkdirs() } + ModuleArtifact(stdlibModuleName, it.fileArtifacts, stdlibDir, it.forceRebuildJs) + } + else -> it + } + } + + val jsExecutableProducer = JsExecutableProducer( + mainModuleName = testInfo.last().moduleName, + moduleKind = configuration[JSConfigurationKeys.MODULE_KIND]!!, + sourceMapsInfo = SourceMapsInfo.from(configuration), + caches = icCaches, + relativeRequirePath = true + ) + + val rebuiltModules = mutableSetOf() + val jsOutput = jsExecutableProducer.buildExecutable(true) { rebuiltModules += it } + verifyJsExecutableProducerBuildModules(projStep.id, rebuiltModules, projStep.dirtyJS) + verifyJsCode(projStep.id, testInfo.last().moduleName, jsOutput) } } } @@ -177,83 +320,6 @@ abstract class AbstractInvalidationTest : KotlinTestWithEnvironment() { return listFiles { _, name -> name.endsWith(".kt") }!!.toList() } - private fun buildCachesAndCheck( - moduleStep: ModuleInfo.ModuleStep, - configuration: CompilerConfiguration, - moduleKlibFile: File, - moduleCacheDir: File, - dependencies: List, - icCaches: List, - expectedDirtyFiles: List, - expectedDeletedFiles: List - ) { - val dependenciesPaths = mutableListOf() - dependencies.mapTo(dependenciesPaths) { it.canonicalPath } - dependenciesPaths.add(moduleKlibFile.canonicalPath) - - val updateStatus = actualizeCacheForModuleWithPrepare( - moduleKlibFile.canonicalPath, - moduleCacheDir.canonicalPath, - configuration, - dependenciesPaths, - icCaches.map { it.canonicalPath },// + moduleCacheDir.canonicalPath, - IrFactoryImpl, - null, // TODO: mainArguments - ::emptyChecker - ) - - if (StepDirectives.FAST_PATH_UPDATE in moduleStep.directives) { - JUnit4Assertions.assertEquals(CacheUpdateStatus.FastPath, updateStatus) { - "Cache has to be checked by fast path, instead it $updateStatus" - } - } - - val (updated, removed) = when (updateStatus) { - is CacheUpdateStatus.FastPath -> emptySet() to emptySet() - is CacheUpdateStatus.NoDirtyFiles -> emptySet() to updateStatus.removed - is CacheUpdateStatus.Dirty -> updateStatus.updated to updateStatus.removed - } - - val actualDirtyFiles = updated.map { File(it).canonicalPath } - val expectedDirtyFilesCanonical = expectedDirtyFiles.map { it.canonicalPath } - JUnit4Assertions.assertSameElements(expectedDirtyFilesCanonical, actualDirtyFiles) { - "Mismatched DIRTY files for module $moduleKlibFile at step ${moduleStep.id}" - } - - val actualDeletedFiles = removed.map { File(it).canonicalPath } - val expectedDeletedFilesCanonical = expectedDeletedFiles.map { it.canonicalPath } - JUnit4Assertions.assertSameElements(expectedDeletedFilesCanonical, actualDeletedFiles) { - "Mismatched DELETED files for module $moduleKlibFile at step ${moduleStep.id}" - } - } - - private fun actualizeCacheForModuleWithPrepare( - moduleName: String, - cachePath: String, - compilerConfiguration: CompilerConfiguration, - dependencies: Collection, - icCachePaths: Collection, - irFactory: IrFactory, - mainArguments: List?, - executor: CacheExecutor - ): CacheUpdateStatus { - val modulePath = File(moduleName).canonicalPath - val statuses = mutableMapOf() - val cacheUpdater = CacheUpdater( - modulePath, - dependencies, - compilerConfiguration, - icCachePaths + cachePath, - { irFactory }, - mainArguments, - executor - ) - cacheUpdater.actualizeCaches { updateStatus, updatedModule -> - statuses[updatedModule] = updateStatus - } - return statuses[modulePath] ?: error("Status is missed for $modulePath") - } - private fun KotlinCoreEnvironment.createPsiFile(file: File): KtFile { val psiManager = PsiManager.getInstance(project) val fileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL) as CoreLocalFileSystem @@ -317,9 +383,4 @@ abstract class AbstractInvalidationTest : KotlinTestWithEnvironment() { return dir } - - companion object { - const val TEST_DATA_DIR_PATH = "js/js.translator/testData/" - } - } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/converters/JsIrBackendFacade.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/converters/JsIrBackendFacade.kt index 64124829d7c..da5602bba0e 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/converters/JsIrBackendFacade.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/converters/JsIrBackendFacade.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationGranularity import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationOptions import org.jetbrains.kotlin.ir.backend.js.codegen.generateEsModules import org.jetbrains.kotlin.ir.backend.js.dce.eliminateDeadDeclarations +import org.jetbrains.kotlin.ir.backend.js.ic.JsExecutableProducer import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerDesc import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrModuleToJsTransformer import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrModuleToJsTransformerTmp @@ -98,11 +99,20 @@ class JsIrBackendFacade( } else { File(JsEnvironmentConfigurator.getRecompiledJsModuleArtifactPath(testServices, module.name) + ".js") } - val moduleName = configuration.getNotNull(CommonConfigurationKeys.MODULE_NAME) - val moduleKind = configuration.get(JSConfigurationKeys.MODULE_KIND, ModuleKind.PLAIN) - val sourceMapsInfo = SourceMapsInfo.from(configuration) - val translationModes = setOf(TranslationMode.FULL, TranslationMode.PER_MODULE) - val compiledModule = generateJsFromAst(moduleName, moduleKind, sourceMapsInfo, translationModes, testServices.jsIrIncrementalDataProvider.getCaches()) + + val compiledModule = CompilerResult( + outputs = listOf(TranslationMode.FULL, TranslationMode.PER_MODULE).associateWith { + val jsExecutableProducer = JsExecutableProducer( + mainModuleName = configuration.getNotNull(CommonConfigurationKeys.MODULE_NAME), + moduleKind = configuration.get(JSConfigurationKeys.MODULE_KIND, ModuleKind.PLAIN), + sourceMapsInfo = SourceMapsInfo.from(configuration), + caches = testServices.jsIrIncrementalDataProvider.getCaches(), + relativeRequirePath = false + ) + jsExecutableProducer.buildExecutable(it.perModule) + }, + tsDefinitions = null + ) return BinaryArtifacts.Js.JsIrArtifact( outputFile, compiledModule, testServices.jsIrIncrementalDataProvider.getCacheForModule(module) ).dump(module, firstTimeCompilation) diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/utils/JsIrIncrementalDataProvider.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/utils/JsIrIncrementalDataProvider.kt index eb3c3d49872..9a47fc08b82 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/utils/JsIrIncrementalDataProvider.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/utils/JsIrIncrementalDataProvider.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.ir.backend.js.WholeWorldStageController import org.jetbrains.kotlin.ir.backend.js.ic.* import org.jetbrains.kotlin.ir.backend.js.moduleName +import org.jetbrains.kotlin.ir.backend.js.utils.serialization.JsIrAstDeserializer import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImplForJsIC import org.jetbrains.kotlin.js.test.handlers.JsBoxRunner import org.jetbrains.kotlin.konan.properties.propertyList @@ -22,17 +23,31 @@ import org.jetbrains.kotlin.test.services.TestServices import org.jetbrains.kotlin.test.services.compilerConfigurationProvider import org.jetbrains.kotlin.test.services.configuration.JsEnvironmentConfigurator import org.jetbrains.kotlin.test.services.jsLibraryProvider +import java.io.ByteArrayInputStream import java.io.File private class TestArtifactCache(var moduleName: String? = null) : ArtifactCache() { - override fun fetchArtifacts() = KLibArtifact( - moduleName = moduleName ?: error("Module name is not set"), - fileArtifacts = binaryAsts.entries.map { - SrcFileArtifact(it.key, "", it.value) - } - ) + override fun fetchArtifacts(): ModuleArtifact { + val deserializer = JsIrAstDeserializer() + return ModuleArtifact( + moduleName = moduleName ?: error("Module name is not set"), + fileArtifacts = binaryAsts.entries.map { + SrcFileArtifact( + srcFilePath = it.key, + // TODO: It will be better to use saved fragments (this.fragments), but it doesn't work + // Merger.merge() + JsNode.resolveTemporaryNames() modify fragments, + // therefore the sequential calls produce different results + fragment = deserializer.deserialize(ByteArrayInputStream(it.value)) + ) + } + ) + } + + fun invalidateForFile(srcPath: String) { + binaryAsts.remove(srcPath) + fragments.remove(srcPath) + } - fun invalidateForFile(srcPath: String) = binaryAsts.remove(srcPath) fun getAst(srcPath: String) = binaryAsts[srcPath] } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/testOld/JsTestChecker.kt b/js/js.tests/test/org/jetbrains/kotlin/js/testOld/JsTestChecker.kt index 916a308bfaf..bc956876efe 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/testOld/JsTestChecker.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/testOld/JsTestChecker.kt @@ -26,7 +26,8 @@ fun ScriptEngine.runTestFunction( testModuleName: String?, testPackageName: String?, testFunctionName: String, - withModuleSystem: Boolean + withModuleSystem: Boolean, + testFunctionArgs: String = "", ): String { var script = when { withModuleSystem -> "\$kotlin_test_internal\$.require('" + testModuleName!! + "')" @@ -38,7 +39,7 @@ fun ScriptEngine.runTestFunction( script += ".$testPackageName" } - script += ".$testFunctionName()" + script += ".$testFunctionName($testFunctionArgs)" return eval(script) } @@ -52,7 +53,20 @@ abstract class AbstractJsTestChecker { expectedResult: String, withModuleSystem: Boolean ) { - val actualResult = run(files, testModuleName, testPackageName, testFunctionName, withModuleSystem) + val actualResult = run(files, testModuleName, testPackageName, testFunctionName, "", withModuleSystem) + Assert.assertEquals(expectedResult, actualResult.normalize()) + } + + fun checkWithTestFunctionArgs( + files: List, + testModuleName: String?, + testPackageName: String?, + testFunctionName: String, + testFunctionArgs: String, + expectedResult: String, + withModuleSystem: Boolean + ) { + val actualResult = run(files, testModuleName, testPackageName, testFunctionName, testFunctionArgs, withModuleSystem) Assert.assertEquals(expectedResult, actualResult.normalize()) } @@ -61,9 +75,10 @@ abstract class AbstractJsTestChecker { testModuleName: String?, testPackageName: String?, testFunctionName: String, + testFunctionArgs: String, withModuleSystem: Boolean ) = run(files) { - runTestFunction(testModuleName, testPackageName, testFunctionName, withModuleSystem) + runTestFunction(testModuleName, testPackageName, testFunctionName, withModuleSystem, testFunctionArgs) } 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 1ea3f071736..8c0fc829e52 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 @@ -45,6 +45,11 @@ public class InvalidationTestGenerated extends AbstractInvalidationTest { runTest("js/js.translator/testData/incremental/invalidation/constVals/"); } + @TestMetadata("crossModuleReferences") + public void testCrossModuleReferences() throws Exception { + runTest("js/js.translator/testData/incremental/invalidation/crossModuleReferences/"); + } + @TestMetadata("fastPath1") public void testFastPath1() throws Exception { runTest("js/js.translator/testData/incremental/invalidation/fastPath1/"); diff --git a/js/js.translator/testData/incremental/invalidation/class/main/m.kt b/js/js.translator/testData/incremental/invalidation/class/main/m.kt index 98f59450431..e21ce7b27b4 100644 --- a/js/js.translator/testData/incremental/invalidation/class/main/m.kt +++ b/js/js.translator/testData/incremental/invalidation/class/main/m.kt @@ -1,2 +1,9 @@ -fun box() = Demo(100500) == Demo(15) +fun box(stepId: Int): String { + when (stepId) { + 0, 2 -> if (Demo(15) == Demo(15)) return "Fail" + 1, 3 -> if (Demo(15) != Demo(15)) return "Fail" + else -> return "Unknown" + } + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/class/main/module.info b/js/js.translator/testData/incremental/invalidation/class/main/module.info index e484b78a009..161216424f1 100644 --- a/js/js.translator/testData/incremental/invalidation/class/main/module.info +++ b/js/js.translator/testData/incremental/invalidation/class/main/module.info @@ -1,9 +1,5 @@ STEP 0: dependencies: stdlib, lib1 dirty: m.kt -STEP 1: - dependencies: stdlib, lib1 -STEP 2: - dependencies: stdlib, lib1 -STEP 3: +STEP 1..3: dependencies: stdlib, lib1 diff --git a/js/js.translator/testData/incremental/invalidation/class/project.info b/js/js.translator/testData/incremental/invalidation/class/project.info index a572bb611ba..e640d924b4f 100644 --- a/js/js.translator/testData/incremental/invalidation/class/project.info +++ b/js/js.translator/testData/incremental/invalidation/class/project.info @@ -2,9 +2,7 @@ MODULES: lib1, main STEP 0: libs: lib1, main -STEP 1: - libs: lib1, main -STEP 2: - libs: lib1, main -STEP 3: + dirty js: stdlib, lib1, main +STEP 1..3: libs: lib1, main + dirty js: stdlib, lib1 diff --git a/js/js.translator/testData/incremental/invalidation/classFunctionsAndFields/main/m.kt b/js/js.translator/testData/incremental/invalidation/classFunctionsAndFields/main/m.kt index f3284a53cfc..878d717417a 100644 --- a/js/js.translator/testData/incremental/invalidation/classFunctionsAndFields/main/m.kt +++ b/js/js.translator/testData/incremental/invalidation/classFunctionsAndFields/main/m.kt @@ -1 +1,39 @@ -fun box() = Demo("test1").foo() + Demo("test2").foo_inline() + "${Demo("test3").field1}" + +fun isEqual(l: Any?, r: Any?) = if (l == r) true else null + +fun box(stepId: Int): String { + when (stepId) { + 0 -> { + isEqual(Demo("test1").foo(), "foo test1") ?: return "Fail function" + isEqual(Demo("test2").foo_inline(), "inline foo test2") ?: return "Fail inline function" + isEqual(Demo("test3").field1, "field1") ?: return "Fail field" + } + 1 -> { + isEqual(Demo("test1").foo(), "foo test1 update") ?: return "Fail function" + isEqual(Demo("test2").foo_inline(), "inline foo test2") ?: return "Fail inline function" + isEqual(Demo("test3").field1, "field1") ?: return "Fail field" + } + 2, 3, 4 -> { + isEqual(Demo("test1").foo(), "foo test1 update") ?: return "Fail function" + isEqual(Demo("test2").foo_inline(), "inline foo test2 update") ?: return "Fail inline function" + isEqual(Demo("test3").field1, "field1") ?: return "Fail field" + } + 5, 6, 7, 8, 9 -> { + isEqual(Demo("test1").foo(), "foo test1 update") ?: return "Fail function" + isEqual(Demo("test2").foo_inline(), "inline foo test2 update") ?: return "Fail inline function" + isEqual(Demo("test3").field1, "field1 update") ?: return "Fail field" + } + 10 -> { + isEqual(Demo("test1").foo(), "foo test1 update") ?: return "Fail function" + isEqual(Demo("test2").foo_inline(), "inline foo test2 update") ?: return "Fail inline function" + isEqual(Demo("test3").field1, 77) ?: return "Fail field" + } + 11 -> { + isEqual(Demo("test1").foo(), "foo test1 update") ?: return "Fail function" + isEqual(Demo("test2").foo_inline(), "inline foo test2 update") ?: return "Fail inline function" + isEqual(Demo("test3").field1, null) ?: return "Fail field" + } + else -> return "Unkown" + } + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/classFunctionsAndFields/main/module.info b/js/js.translator/testData/incremental/invalidation/classFunctionsAndFields/main/module.info index 78b3b5b6040..c0857570346 100644 --- a/js/js.translator/testData/incremental/invalidation/classFunctionsAndFields/main/module.info +++ b/js/js.translator/testData/incremental/invalidation/classFunctionsAndFields/main/module.info @@ -3,27 +3,11 @@ STEP 0: dirty: m.kt STEP 1: dependencies: stdlib, lib1 -STEP 2: +STEP 2..3: dependencies: stdlib, lib1 dirty: m.kt -STEP 3: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 4: - dependencies: stdlib, lib1 -STEP 5: - dependencies: stdlib, lib1 -STEP 6: - dependencies: stdlib, lib1 -STEP 7: - dependencies: stdlib, lib1 -STEP 8: - dependencies: stdlib, lib1 -STEP 9: - dependencies: stdlib, lib1 -STEP 10: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 11: +STEP 4..9: + dependencies: stdlib, lib1 +STEP 10..11: dependencies: stdlib, lib1 dirty: m.kt diff --git a/js/js.translator/testData/incremental/invalidation/classFunctionsAndFields/project.info b/js/js.translator/testData/incremental/invalidation/classFunctionsAndFields/project.info index daff75c9467..08a53dfd524 100644 --- a/js/js.translator/testData/incremental/invalidation/classFunctionsAndFields/project.info +++ b/js/js.translator/testData/incremental/invalidation/classFunctionsAndFields/project.info @@ -2,25 +2,22 @@ MODULES: lib1, main STEP 0: libs: lib1, main + dirty js: stdlib, lib1, main STEP 1: libs: lib1, main -STEP 2: + dirty js: lib1 +STEP 2..3: libs: lib1, main -STEP 3: - libs: lib1, main -STEP 4: - libs: lib1, main -STEP 5: - libs: lib1, main -STEP 6: + dirty js: lib1, main +STEP 4..6: libs: lib1, main + dirty js: lib1 STEP 7: libs: lib1, main -STEP 8: + dirty js: stdlib, lib1 +STEP 8..9: libs: lib1, main -STEP 9: - libs: lib1, main -STEP 10: - libs: lib1, main -STEP 11: + dirty js: lib1 +STEP 10..11: libs: lib1, main + dirty js: lib1, main 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 63d0291c121..c1c7c4b5a69 100644 --- a/js/js.translator/testData/incremental/invalidation/constVals/lib2/module.info +++ b/js/js.translator/testData/incremental/invalidation/constVals/lib2/module.info @@ -1,6 +1,5 @@ STEP 0: dependencies: stdlib, lib1 dirty: l2.kt - STEP 1: dependencies: stdlib, lib1 diff --git a/js/js.translator/testData/incremental/invalidation/constVals/main/m.kt b/js/js.translator/testData/incremental/invalidation/constVals/main/m.kt index 2db1710a284..dd74a3d1a3f 100644 --- a/js/js.translator/testData/incremental/invalidation/constVals/main/m.kt +++ b/js/js.translator/testData/incremental/invalidation/constVals/main/m.kt @@ -1,2 +1,15 @@ -fun box() = qux() == bar() +fun box(stepId: Int): String { + when (stepId) { + 0 -> { + if (qux() != "FOO") return "Fail qux" + if (bar() != "FOO") return "Fail bar" + } + 1 -> { + if (qux() != "BAR") return "Fail qux" + if (bar() != "BAR") return "Fail bar" + } + else -> return "Unknown" + } + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/constVals/main/module.info b/js/js.translator/testData/incremental/invalidation/constVals/main/module.info index 92da0d12fc9..a2d4e3c24e6 100644 --- a/js/js.translator/testData/incremental/invalidation/constVals/main/module.info +++ b/js/js.translator/testData/incremental/invalidation/constVals/main/module.info @@ -1,6 +1,5 @@ STEP 0: dependencies: stdlib, lib1, lib2 dirty: m.kt - STEP 1: dependencies: stdlib, lib1, lib2 diff --git a/js/js.translator/testData/incremental/invalidation/constVals/project.info b/js/js.translator/testData/incremental/invalidation/constVals/project.info index 710e8567360..ca17baa143e 100644 --- a/js/js.translator/testData/incremental/invalidation/constVals/project.info +++ b/js/js.translator/testData/incremental/invalidation/constVals/project.info @@ -2,6 +2,7 @@ MODULES: lib1, lib2, main STEP 0: libs: lib1, lib2, main - + dirty js: stdlib, lib1, lib2, main STEP 1: - libs: lib1, lib2, main \ No newline at end of file + libs: lib1, lib2, main + dirty js: lib1 diff --git a/js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib1/l1.kt b/js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib1/l1.kt new file mode 100644 index 00000000000..42073132f5e --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib1/l1.kt @@ -0,0 +1,6 @@ +fun foo() = 42 +fun bar() = 24 + +fun baz(s: String) = s.length +fun baz(i: Int) = i + 2 +fun baz(b: Boolean) = if (b) 10 else 1 diff --git a/js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib1/module.info b/js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib1/module.info new file mode 100644 index 00000000000..5ed945b9908 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib1/module.info @@ -0,0 +1,6 @@ +STEP 0: + dependencies: stdlib + dirty: l1.kt +STEP 1..6: + dependencies: stdlib + flags: FP diff --git a/js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib2/l2.kt b/js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib2/l2.kt new file mode 100644 index 00000000000..534fdd6be64 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib2/l2.kt @@ -0,0 +1,2 @@ + +fun qux() = foo() + 2 diff --git a/js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib2/l2.kt.1.txt b/js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib2/l2.kt.1.txt new file mode 100644 index 00000000000..232ffb94add --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib2/l2.kt.1.txt @@ -0,0 +1,2 @@ + +fun qux() = foo() + bar() diff --git a/js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib2/l2.kt.2.txt b/js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib2/l2.kt.2.txt new file mode 100644 index 00000000000..f667b9c9e8d --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib2/l2.kt.2.txt @@ -0,0 +1,2 @@ + +fun qux() = foo() - 2 diff --git a/js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib2/l2.kt.3.txt b/js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib2/l2.kt.3.txt new file mode 100644 index 00000000000..063d3566c94 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib2/l2.kt.3.txt @@ -0,0 +1,2 @@ + +fun qux() = baz(2) + baz("test") + baz(true) diff --git a/js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib2/l2.kt.4.txt b/js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib2/l2.kt.4.txt new file mode 100644 index 00000000000..7501f18d5a6 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib2/l2.kt.4.txt @@ -0,0 +1,2 @@ + +fun qux() = baz("test") + baz(true) diff --git a/js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib2/l2.kt.6.txt b/js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib2/l2.kt.6.txt new file mode 100644 index 00000000000..555a0ce8658 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib2/l2.kt.6.txt @@ -0,0 +1,2 @@ + +fun qux() = baz("test") + 100 diff --git a/js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib2/module.info b/js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib2/module.info new file mode 100644 index 00000000000..0841185099f --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/crossModuleReferences/lib2/module.info @@ -0,0 +1,31 @@ +STEP 0: + dependencies: stdlib, lib1 + dirty: l2.kt +STEP 1: + dependencies: stdlib, lib1 + modifications: + U : l2.kt.1.txt -> l2.kt + dirty: l2.kt +STEP 2: + dependencies: stdlib, lib1 + modifications: + U : l2.kt.2.txt -> l2.kt + dirty: l2.kt +STEP 3: + dependencies: stdlib, lib1 + modifications: + U : l2.kt.3.txt -> l2.kt + dirty: l2.kt +STEP 4: + dependencies: stdlib, lib1 + modifications: + U : l2.kt.4.txt -> l2.kt + dirty: l2.kt +STEP 5: + dependencies: stdlib, lib1 + flags: FP +STEP 6: + dependencies: stdlib, lib1 + modifications: + U : l2.kt.6.txt -> l2.kt + dirty: l2.kt diff --git a/js/js.translator/testData/incremental/invalidation/crossModuleReferences/main/m.kt b/js/js.translator/testData/incremental/invalidation/crossModuleReferences/main/m.kt new file mode 100644 index 00000000000..9b55d4ffa5d --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/crossModuleReferences/main/m.kt @@ -0,0 +1,12 @@ + +fun box(stepId: Int): String { + when (stepId) { + 0 -> if (qux() != 44) return "Fail" + 1 -> if (qux() != 66) return "Fail" + 2 -> if (qux() != 40) return "Fail" + 3 -> if (qux() != 18) return "Fail" + 4 -> if (qux() != 14) return "Fail" + else -> return "Unknown" + } + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/crossModuleReferences/main/m.kt.5.txt b/js/js.translator/testData/incremental/invalidation/crossModuleReferences/main/m.kt.5.txt new file mode 100644 index 00000000000..44714ea1f9f --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/crossModuleReferences/main/m.kt.5.txt @@ -0,0 +1,11 @@ + +fun box(stepId: Int): String { + when (stepId) { + 5 -> if (qux() != 14) return "Fail" + 6 -> if (qux() != 104) return "Fail" + else -> return "Unknown" + } + if (baz(77) != 79) return "Fail" + if (baz("test") != 4) return "Fail" + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/crossModuleReferences/main/module.info b/js/js.translator/testData/incremental/invalidation/crossModuleReferences/main/module.info new file mode 100644 index 00000000000..96afcf54ec7 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/crossModuleReferences/main/module.info @@ -0,0 +1,12 @@ +STEP 0: + dependencies: stdlib, lib1, lib2 + dirty: m.kt +STEP 1..4: + dependencies: stdlib, lib1, lib2 +STEP 5: + dependencies: stdlib, lib1, lib2 + modifications: + U : m.kt.5.txt -> m.kt + dirty: m.kt +STEP 6: + dependencies: stdlib, lib1, lib2 diff --git a/js/js.translator/testData/incremental/invalidation/crossModuleReferences/project.info b/js/js.translator/testData/incremental/invalidation/crossModuleReferences/project.info new file mode 100644 index 00000000000..be7d9c3ce73 --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/crossModuleReferences/project.info @@ -0,0 +1,14 @@ +MODULES: lib1, lib2, main + +STEP 0: + libs: lib1, lib2, main + dirty js: stdlib, lib1, lib2, main +STEP 1..4: + libs: lib1, lib2, main + dirty js: lib1, lib2 +STEP 5: + libs: lib1, lib2, main + dirty js: lib1, main +STEP 6: + libs: lib1, lib2, main + dirty js: lib1, lib2, main diff --git a/js/js.translator/testData/incremental/invalidation/fastPath1/lib1/module.info b/js/js.translator/testData/incremental/invalidation/fastPath1/lib1/module.info index aadb891979d..f500435de26 100644 --- a/js/js.translator/testData/incremental/invalidation/fastPath1/lib1/module.info +++ b/js/js.translator/testData/incremental/invalidation/fastPath1/lib1/module.info @@ -3,5 +3,4 @@ STEP 0: dirty: l1.kt STEP 1: dependencies: stdlib - dirty: flags: FP diff --git a/js/js.translator/testData/incremental/invalidation/fastPath1/lib2/module.info b/js/js.translator/testData/incremental/invalidation/fastPath1/lib2/module.info index 64726957d38..34b5a84bf72 100644 --- a/js/js.translator/testData/incremental/invalidation/fastPath1/lib2/module.info +++ b/js/js.translator/testData/incremental/invalidation/fastPath1/lib2/module.info @@ -1,9 +1,8 @@ STEP 0: dependencies: stdlib, lib1 dirty: l2.kt - STEP 1: dependencies: stdlib, lib1 modifications: U : l2.kt.1 -> l2.kt - dirty: l2.kt \ No newline at end of file + dirty: l2.kt diff --git a/js/js.translator/testData/incremental/invalidation/fastPath1/main/m.kt b/js/js.translator/testData/incremental/invalidation/fastPath1/main/m.kt index 3ed427f027a..d55814a4cd9 100644 --- a/js/js.translator/testData/incremental/invalidation/fastPath1/main/m.kt +++ b/js/js.translator/testData/incremental/invalidation/fastPath1/main/m.kt @@ -1,2 +1,9 @@ -fun box() = qux() \ No newline at end of file +fun box(stepId: Int): String { + when (stepId) { + 0 -> if (qux() != 42) return "Fail" + 1 -> if (qux() != 44) return "Fail" + else -> return "Unknown" + } + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/fastPath1/main/module.info b/js/js.translator/testData/incremental/invalidation/fastPath1/main/module.info index d2047496476..a2d4e3c24e6 100644 --- a/js/js.translator/testData/incremental/invalidation/fastPath1/main/module.info +++ b/js/js.translator/testData/incremental/invalidation/fastPath1/main/module.info @@ -1,6 +1,5 @@ STEP 0: dependencies: stdlib, lib1, lib2 dirty: m.kt - STEP 1: - dependencies: stdlib, lib1, lib2 \ No newline at end of file + dependencies: stdlib, lib1, lib2 diff --git a/js/js.translator/testData/incremental/invalidation/fastPath1/project.info b/js/js.translator/testData/incremental/invalidation/fastPath1/project.info index 710e8567360..9ddce48f7c0 100644 --- a/js/js.translator/testData/incremental/invalidation/fastPath1/project.info +++ b/js/js.translator/testData/incremental/invalidation/fastPath1/project.info @@ -2,6 +2,7 @@ MODULES: lib1, lib2, main STEP 0: libs: lib1, lib2, main - + dirty js: stdlib, lib1, lib2, main STEP 1: - libs: lib1, lib2, main \ No newline at end of file + libs: lib1, lib2, main + dirty js: lib2 diff --git a/js/js.translator/testData/incremental/invalidation/fastPath2/lib1/module.info b/js/js.translator/testData/incremental/invalidation/fastPath2/lib1/module.info index aadb891979d..f500435de26 100644 --- a/js/js.translator/testData/incremental/invalidation/fastPath2/lib1/module.info +++ b/js/js.translator/testData/incremental/invalidation/fastPath2/lib1/module.info @@ -3,5 +3,4 @@ STEP 0: dirty: l1.kt STEP 1: dependencies: stdlib - dirty: flags: FP diff --git a/js/js.translator/testData/incremental/invalidation/fastPath2/lib2/module.info b/js/js.translator/testData/incremental/invalidation/fastPath2/lib2/module.info index 1b6a559ca71..a6323a2b98f 100644 --- a/js/js.translator/testData/incremental/invalidation/fastPath2/lib2/module.info +++ b/js/js.translator/testData/incremental/invalidation/fastPath2/lib2/module.info @@ -1,7 +1,6 @@ STEP 0: dependencies: stdlib, lib1 dirty: l2.kt - STEP 1: dependencies: stdlib, lib1 - flags: FP \ No newline at end of file + flags: FP diff --git a/js/js.translator/testData/incremental/invalidation/fastPath2/main/m.kt b/js/js.translator/testData/incremental/invalidation/fastPath2/main/m.kt index 3ed427f027a..dd7574e87da 100644 --- a/js/js.translator/testData/incremental/invalidation/fastPath2/main/m.kt +++ b/js/js.translator/testData/incremental/invalidation/fastPath2/main/m.kt @@ -1,2 +1,2 @@ -fun box() = qux() \ No newline at end of file +fun box() = if (qux() == 42) "OK" else "Fail" diff --git a/js/js.translator/testData/incremental/invalidation/fastPath2/main/module.info b/js/js.translator/testData/incremental/invalidation/fastPath2/main/module.info index 2791be3075a..cad654e4af7 100644 --- a/js/js.translator/testData/incremental/invalidation/fastPath2/main/module.info +++ b/js/js.translator/testData/incremental/invalidation/fastPath2/main/module.info @@ -1,7 +1,6 @@ STEP 0: dependencies: stdlib, lib1, lib2 dirty: m.kt - STEP 1: dependencies: stdlib, lib1, lib2 - flags: FP \ No newline at end of file + flags: FP diff --git a/js/js.translator/testData/incremental/invalidation/fastPath2/project.info b/js/js.translator/testData/incremental/invalidation/fastPath2/project.info index 710e8567360..ffc4ef83f29 100644 --- a/js/js.translator/testData/incremental/invalidation/fastPath2/project.info +++ b/js/js.translator/testData/incremental/invalidation/fastPath2/project.info @@ -2,6 +2,6 @@ MODULES: lib1, lib2, main STEP 0: libs: lib1, lib2, main - + dirty js: stdlib, lib1, lib2, main STEP 1: - libs: lib1, lib2, main \ No newline at end of file + libs: lib1, lib2, main diff --git a/js/js.translator/testData/incremental/invalidation/functionDefaultParams/main/m.kt b/js/js.translator/testData/incremental/invalidation/functionDefaultParams/main/m.kt index 62e2ca15940..23ef41f6090 100644 --- a/js/js.translator/testData/incremental/invalidation/functionDefaultParams/main/m.kt +++ b/js/js.translator/testData/incremental/invalidation/functionDefaultParams/main/m.kt @@ -1,2 +1,11 @@ -fun box() = foo() +fun box(stepId: Int): String { + when (stepId) { + 0 -> if (foo() != (42 + 77)) return "Fail" + 1 -> if (foo() != (42 + 88)) return "Fail" + 2 -> if (foo() != (42 + 88 + 11)) return "Fail" + 3 -> if (foo() != (42 + 88 + 22)) return "Fail" + else -> return "Unknown" + } + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/functionDefaultParams/project.info b/js/js.translator/testData/incremental/invalidation/functionDefaultParams/project.info index a572bb611ba..0c19fd8a2e7 100644 --- a/js/js.translator/testData/incremental/invalidation/functionDefaultParams/project.info +++ b/js/js.translator/testData/incremental/invalidation/functionDefaultParams/project.info @@ -2,9 +2,13 @@ MODULES: lib1, main STEP 0: libs: lib1, main + dirty js: stdlib, 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: lib1 diff --git a/js/js.translator/testData/incremental/invalidation/functionSignature/main/m.kt b/js/js.translator/testData/incremental/invalidation/functionSignature/main/m.kt index 62e2ca15940..ec53e2d1bb7 100644 --- a/js/js.translator/testData/incremental/invalidation/functionSignature/main/m.kt +++ b/js/js.translator/testData/incremental/invalidation/functionSignature/main/m.kt @@ -1,2 +1,23 @@ -fun box() = foo() +fun isEqual(l: Any?, r: Any?) = if (l == r) true else null + +fun box(stepId: Int): String { + when (stepId) { + 0, 8, 15, 16 -> isEqual(foo(), 42) ?: return "Fail" + 1 -> isEqual(foo(), false) ?: return "Fail" + 2 -> isEqual(foo(), 3.14) ?: return "Fail" + 3, 5, 6, 12 -> isEqual(foo(), "string") ?: return "Fail" + 4 -> isEqual(foo(), null) ?: return "Fail" + 7 -> { + foo() // Unit + return "OK" + } + 9 -> isEqual(foo(), 42 + 77) ?: return "Fail" + 10 -> isEqual(foo(), 42 + 98 + 1) ?: return "Fail" + 11 -> isEqual(foo(), 42 + 91) ?: return "Fail" + 13 -> isEqual(foo(), 99) ?: return "Fail" + 14 -> isEqual(foo(), 1L) ?: return "Fail" + else -> return "Unknown" + } + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/functionSignature/main/module.info b/js/js.translator/testData/incremental/invalidation/functionSignature/main/module.info index e441682b7f6..8bed6a33ca2 100644 --- a/js/js.translator/testData/incremental/invalidation/functionSignature/main/module.info +++ b/js/js.translator/testData/incremental/invalidation/functionSignature/main/module.info @@ -1,51 +1,3 @@ -STEP 0: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 1: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 2: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 3: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 4: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 5: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 6: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 7: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 8: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 9: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 10: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 11: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 12: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 13: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 14: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 15: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 16: +STEP 0..16: dependencies: stdlib, lib1 dirty: m.kt diff --git a/js/js.translator/testData/incremental/invalidation/functionSignature/project.info b/js/js.translator/testData/incremental/invalidation/functionSignature/project.info index 8e227812715..2ed43c2129b 100644 --- a/js/js.translator/testData/incremental/invalidation/functionSignature/project.info +++ b/js/js.translator/testData/incremental/invalidation/functionSignature/project.info @@ -2,35 +2,13 @@ MODULES: lib1, main STEP 0: libs: lib1, main -STEP 1: + dirty js: stdlib, lib1, main +STEP 1..6: libs: lib1, main -STEP 2: + dirty js: lib1, main +STEP 7..8: libs: lib1, main -STEP 3: - libs: lib1, main -STEP 4: - libs: lib1, main -STEP 5: - libs: lib1, main -STEP 6: - libs: lib1, main -STEP 7: - libs: lib1, main -STEP 8: - libs: lib1, main -STEP 9: - libs: lib1, main -STEP 10: - libs: lib1, main -STEP 11: - libs: lib1, main -STEP 12: - libs: lib1, main -STEP 13: - libs: lib1, main -STEP 14: - libs: lib1, main -STEP 15: - libs: lib1, main -STEP 16: + dirty js: stdlib, lib1, main +STEP 9..16: libs: lib1, main + dirty js: lib1, main diff --git a/js/js.translator/testData/incremental/invalidation/genericFunctions/main/m.kt b/js/js.translator/testData/incremental/invalidation/genericFunctions/main/m.kt index 14fe80ff9b6..c505af058d9 100644 --- a/js/js.translator/testData/incremental/invalidation/genericFunctions/main/m.kt +++ b/js/js.translator/testData/incremental/invalidation/genericFunctions/main/m.kt @@ -1,2 +1,2 @@ -fun box() = foo("demo") +fun box() = foo("OK") diff --git a/js/js.translator/testData/incremental/invalidation/genericFunctions/main/module.info b/js/js.translator/testData/incremental/invalidation/genericFunctions/main/module.info index 2a53e9ebea5..e1041e7b7f8 100644 --- a/js/js.translator/testData/incremental/invalidation/genericFunctions/main/module.info +++ b/js/js.translator/testData/incremental/invalidation/genericFunctions/main/module.info @@ -1,15 +1,3 @@ -STEP 0: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 1: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 2: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 3: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 4: +STEP 0..4: dependencies: stdlib, lib1 dirty: m.kt diff --git a/js/js.translator/testData/incremental/invalidation/genericFunctions/project.info b/js/js.translator/testData/incremental/invalidation/genericFunctions/project.info index 630f1a9dd95..7910d40726d 100644 --- a/js/js.translator/testData/incremental/invalidation/genericFunctions/project.info +++ b/js/js.translator/testData/incremental/invalidation/genericFunctions/project.info @@ -2,11 +2,7 @@ MODULES: lib1, main STEP 0: libs: lib1, main -STEP 1: - libs: lib1, main -STEP 2: - libs: lib1, main -STEP 3: - libs: lib1, main -STEP 4: + dirty js: stdlib, lib1, main +STEP 1..4: libs: lib1, main + dirty js: lib1, main diff --git a/js/js.translator/testData/incremental/invalidation/genericInlineFunctions/libProxy/module.info b/js/js.translator/testData/incremental/invalidation/genericInlineFunctions/libProxy/module.info index 3325ad63c26..9cf39fde8b3 100644 --- a/js/js.translator/testData/incremental/invalidation/genericInlineFunctions/libProxy/module.info +++ b/js/js.translator/testData/incremental/invalidation/genericInlineFunctions/libProxy/module.info @@ -3,25 +3,7 @@ STEP 0: modifications: U : proxy.kt.0.txt -> proxy.kt dirty: proxy.kt -STEP 1: - dependencies: stdlib - flags: FP -STEP 2: - dependencies: stdlib - flags: FP -STEP 3: - dependencies: stdlib - flags: FP -STEP 4: - dependencies: stdlib - flags: FP -STEP 5: - dependencies: stdlib - flags: FP -STEP 6: - dependencies: stdlib - flags: FP -STEP 7: +STEP 1..7: dependencies: stdlib flags: FP STEP 8: @@ -29,25 +11,7 @@ STEP 8: modifications: U : proxy.kt.1.txt -> proxy.kt dirty: proxy.kt -STEP 9: - dependencies: stdlib, lib1 - dirty: proxy.kt -STEP 10: - dependencies: stdlib, lib1 - dirty: proxy.kt -STEP 11: - dependencies: stdlib, lib1 - dirty: proxy.kt -STEP 12: - dependencies: stdlib, lib1 - dirty: proxy.kt -STEP 13: - dependencies: stdlib, lib1 - dirty: proxy.kt -STEP 14: - dependencies: stdlib, lib1 - dirty: proxy.kt -STEP 15: +STEP 9..15: dependencies: stdlib, lib1 dirty: proxy.kt STEP 16: @@ -55,24 +19,6 @@ STEP 16: modifications: U : proxy.kt.2.txt -> proxy.kt dirty: proxy.kt -STEP 17: - dependencies: stdlib, lib1 - dirty: proxy.kt -STEP 18: - dependencies: stdlib, lib1 - dirty: proxy.kt -STEP 19: - dependencies: stdlib, lib1 - dirty: proxy.kt -STEP 20: - dependencies: stdlib, lib1 - dirty: proxy.kt -STEP 21: - dependencies: stdlib, lib1 - dirty: proxy.kt -STEP 22: - dependencies: stdlib, lib1 - dirty: proxy.kt -STEP 23: +STEP 17..23: dependencies: stdlib, lib1 dirty: proxy.kt diff --git a/js/js.translator/testData/incremental/invalidation/genericInlineFunctions/main/m.kt b/js/js.translator/testData/incremental/invalidation/genericInlineFunctions/main/m.kt index 14fe80ff9b6..0379a8048cf 100644 --- a/js/js.translator/testData/incremental/invalidation/genericInlineFunctions/main/m.kt +++ b/js/js.translator/testData/incremental/invalidation/genericInlineFunctions/main/m.kt @@ -1,2 +1,14 @@ -fun box() = foo("demo") +fun isEqual(l: Any?, r: Any?) = if (l == r) true else null + +fun box(stepId: Int): String { + when (stepId) { + in 0..5 -> isEqual(foo("test"), 123) ?: return "Fail" + in 8..13 -> isEqual(foo("test"), 123) ?: return "Fail" + in 16..21 -> isEqual(foo("test"), 123) ?: return "Fail" + 6, 14, 22 -> isEqual(foo("test"), 99) ?: return "Fail" + 7, 15, 23 -> isEqual(foo("test"), "test") ?: return "Fail" + else -> return "Unknown" + } + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/genericInlineFunctions/main/m.proxy.kt.txt b/js/js.translator/testData/incremental/invalidation/genericInlineFunctions/main/m.proxy.kt.txt index c9fd204d2ab..034e10ee879 100644 --- a/js/js.translator/testData/incremental/invalidation/genericInlineFunctions/main/m.proxy.kt.txt +++ b/js/js.translator/testData/incremental/invalidation/genericInlineFunctions/main/m.proxy.kt.txt @@ -1,2 +1,14 @@ -fun box() = foo_proxy("demo") +fun isEqual(l: Any?, r: Any?) = if (l == r) true else null + +fun box(stepId: Int): String { + when (stepId) { + in 0..5 -> isEqual(foo_proxy("test"), 123) ?: return "Fail" + in 8..13 -> isEqual(foo_proxy("test"), 123) ?: return "Fail" + in 16..21 -> isEqual(foo_proxy("test"), 123) ?: return "Fail" + 6, 14, 22 -> isEqual(foo_proxy("test"), 99) ?: return "Fail" + 7, 15, 23 -> isEqual(foo_proxy("test"), "test") ?: return "Fail" + else -> return "Unknown" + } + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/genericInlineFunctions/main/module.info b/js/js.translator/testData/incremental/invalidation/genericInlineFunctions/main/module.info index 065039391ed..e8127ccfeb8 100644 --- a/js/js.translator/testData/incremental/invalidation/genericInlineFunctions/main/module.info +++ b/js/js.translator/testData/incremental/invalidation/genericInlineFunctions/main/module.info @@ -1,25 +1,4 @@ -STEP 0: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 1: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 2: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 3: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 4: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 5: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 6: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 7: +STEP 0..7: dependencies: stdlib, lib1 dirty: m.kt STEP 8: @@ -27,48 +6,6 @@ STEP 8: modifications: U : m.proxy.kt.txt -> m.kt dirty: m.kt -STEP 9: - dependencies: stdlib, lib1, libProxy - dirty: m.kt -STEP 10: - dependencies: stdlib, lib1, libProxy - dirty: m.kt -STEP 11: - dependencies: stdlib, lib1, libProxy - dirty: m.kt -STEP 12: - dependencies: stdlib, lib1, libProxy - dirty: m.kt -STEP 13: - dependencies: stdlib, lib1, libProxy - dirty: m.kt -STEP 14: - dependencies: stdlib, lib1, libProxy - dirty: m.kt -STEP 15: - dependencies: stdlib, lib1, libProxy - dirty: m.kt -STEP 16: - dependencies: stdlib, lib1, libProxy - dirty: m.kt -STEP 17: - dependencies: stdlib, lib1, libProxy - dirty: m.kt -STEP 18: - dependencies: stdlib, lib1, libProxy - dirty: m.kt -STEP 19: - dependencies: stdlib, lib1, libProxy - dirty: m.kt -STEP 20: - dependencies: stdlib, lib1, libProxy - dirty: m.kt -STEP 21: - dependencies: stdlib, lib1, libProxy - dirty: m.kt -STEP 22: - dependencies: stdlib, lib1, libProxy - dirty: m.kt -STEP 23: +STEP 9..23: dependencies: stdlib, lib1, libProxy dirty: m.kt diff --git a/js/js.translator/testData/incremental/invalidation/genericInlineFunctions/project.info b/js/js.translator/testData/incremental/invalidation/genericInlineFunctions/project.info index a22183ca767..345bfe6ad4f 100644 --- a/js/js.translator/testData/incremental/invalidation/genericInlineFunctions/project.info +++ b/js/js.translator/testData/incremental/invalidation/genericInlineFunctions/project.info @@ -2,49 +2,22 @@ MODULES: lib1, main, libProxy STEP 0: libs: lib1, main -STEP 1: + dirty js: stdlib, lib1, main +STEP 1..5: libs: lib1, main -STEP 2: + dirty js: lib1, main +STEP 6..7: libs: lib1, main -STEP 3: - libs: lib1, main -STEP 4: - libs: lib1, main -STEP 5: - libs: lib1, main -STEP 6: - libs: lib1, main -STEP 7: - libs: lib1, main -STEP 8: + dirty js: stdlib, lib1, main +STEP 8..13: libs: lib1, libProxy, main -STEP 9: + dirty js: lib1, libProxy, main +STEP 14..16: libs: lib1, libProxy, main -STEP 10: + dirty js: stdlib, lib1, libProxy, main +STEP 17..21: libs: lib1, libProxy, main -STEP 11: - libs: lib1, libProxy, main -STEP 12: - libs: lib1, libProxy, main -STEP 13: - libs: lib1, libProxy, main -STEP 14: - libs: lib1, libProxy, main -STEP 15: - libs: lib1, libProxy, main -STEP 16: - libs: lib1, libProxy, main -STEP 17: - libs: lib1, libProxy, main -STEP 18: - libs: lib1, libProxy, main -STEP 19: - libs: lib1, libProxy, main -STEP 20: - libs: lib1, libProxy, main -STEP 21: - libs: lib1, libProxy, main -STEP 22: - libs: lib1, libProxy, main -STEP 23: + dirty js: lib1, libProxy, main +STEP 22..23: libs: lib1, libProxy, main + dirty js: stdlib, lib1, libProxy, main diff --git a/js/js.translator/testData/incremental/invalidation/inlineBecomeNonInline/main/m.kt b/js/js.translator/testData/incremental/invalidation/inlineBecomeNonInline/main/m.kt index 62e2ca15940..49f9547009b 100644 --- a/js/js.translator/testData/incremental/invalidation/inlineBecomeNonInline/main/m.kt +++ b/js/js.translator/testData/incremental/invalidation/inlineBecomeNonInline/main/m.kt @@ -1,2 +1,9 @@ -fun box() = foo() +fun box(stepId: Int): String { + when(stepId) { + 0, 1 -> if (foo() != 42) return "Fail" + 2 -> if (foo() != 77) return "Fail" + else -> return "Unknown" + } + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/inlineBecomeNonInline/main/module.info b/js/js.translator/testData/incremental/invalidation/inlineBecomeNonInline/main/module.info index fe384b96acb..b19c6e2819d 100644 --- a/js/js.translator/testData/incremental/invalidation/inlineBecomeNonInline/main/module.info +++ b/js/js.translator/testData/incremental/invalidation/inlineBecomeNonInline/main/module.info @@ -1,7 +1,4 @@ -STEP 0: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 1: +STEP 0..1: dependencies: stdlib, lib1 dirty: m.kt STEP 2: diff --git a/js/js.translator/testData/incremental/invalidation/inlineBecomeNonInline/project.info b/js/js.translator/testData/incremental/invalidation/inlineBecomeNonInline/project.info index 08e19f88401..46365fc78a2 100644 --- a/js/js.translator/testData/incremental/invalidation/inlineBecomeNonInline/project.info +++ b/js/js.translator/testData/incremental/invalidation/inlineBecomeNonInline/project.info @@ -1,8 +1,8 @@ MODULES: lib1, main -STEP 0: - libs: lib1, main -STEP 1: +STEP 0..1: libs: lib1, main + dirty js: stdlib, lib1, main STEP 2: libs: lib1, main + dirty js: lib1 diff --git a/js/js.translator/testData/incremental/invalidation/inlineFunctionAsParam/main/m.kt b/js/js.translator/testData/incremental/invalidation/inlineFunctionAsParam/main/m.kt index 8d693ea832a..464db1f7f2f 100644 --- a/js/js.translator/testData/incremental/invalidation/inlineFunctionAsParam/main/m.kt +++ b/js/js.translator/testData/incremental/invalidation/inlineFunctionAsParam/main/m.kt @@ -1,6 +1,53 @@ +fun isEqual(l: Any?, r: Any?) = if (l == r) true else null + inline fun test1(x: () -> Any) = x() fun test2(x: () -> Any) = x() inline fun test3(x: () -> Any) = x() -fun box() = test1(::foo1).toString() + test2(::foo2).toString() + test3 { foo3() }.toString() +fun box(stepId: Int): String { + when (stepId) { + 0 -> { + isEqual(test1(::foo1), "foo1") ?: return "Fail foo1" + isEqual(test2(::foo2), "foo2") ?: return "Fail foo2" + isEqual(test3 { foo3() }, "foo3") ?: return "Fail foo3" + } + 1 -> { + isEqual(test1(::foo1), "foo1 update") ?: return "Fail foo1" + isEqual(test2(::foo2), "foo2") ?: return "Fail foo2" + isEqual(test3 { foo3() }, "foo3") ?: return "Fail foo3" + } + 2 -> { + isEqual(test1(::foo1), "foo1 update") ?: return "Fail foo1" + isEqual(test2(::foo2), "foo2 update") ?: return "Fail foo2" + isEqual(test3 { foo3() }, "foo3") ?: return "Fail foo3" + } + 3 -> { + isEqual(test1(::foo1), 77) ?: return "Fail foo1" + isEqual(test2(::foo2), "foo2 update") ?: return "Fail foo2" + isEqual(test3 { foo3() }, "foo3") ?: return "Fail foo3" + } + 4 -> { + isEqual(test1(::foo1), 77) ?: return "Fail foo1" + isEqual(test2(::foo2), 88) ?: return "Fail foo2" + isEqual(test3 { foo3() }, "foo3") ?: return "Fail foo3" + } + 5, 6 -> { + isEqual(test1(::foo1), 77) ?: return "Fail foo1" + isEqual(test2(::foo2), 88) ?: return "Fail foo2" + isEqual(test3 { foo3() }, "foo3 update") ?: return "Fail foo3" + } + 7, 8 -> { + isEqual(test1(::foo1), 99) ?: return "Fail foo1" + isEqual(test2(::foo2), 88) ?: return "Fail foo2" + isEqual(test3 { foo3() }, "foo3 update") ?: return "Fail foo3" + } + 9 -> { + isEqual(test1(::foo1), 88) ?: return "Fail foo1" + isEqual(test2(::foo2), 88) ?: return "Fail foo2" + isEqual(test3 { foo3() }, "foo3 update") ?: return "Fail foo3" + } + else -> return "Unknown" + } + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/inlineFunctionAsParam/main/module.info b/js/js.translator/testData/incremental/invalidation/inlineFunctionAsParam/main/module.info index a76fcc02081..ae53c73c164 100644 --- a/js/js.translator/testData/incremental/invalidation/inlineFunctionAsParam/main/module.info +++ b/js/js.translator/testData/incremental/invalidation/inlineFunctionAsParam/main/module.info @@ -1,28 +1,8 @@ -STEP 0: +STEP 0..1: dependencies: stdlib, lib1 dirty: m.kt -STEP 1: - dependencies: stdlib, lib1 STEP 2: dependencies: stdlib, lib1 -STEP 3: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 4: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 5: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 6: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 7: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 8: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 9: +STEP 3..9: dependencies: stdlib, lib1 dirty: m.kt diff --git a/js/js.translator/testData/incremental/invalidation/inlineFunctionAsParam/project.info b/js/js.translator/testData/incremental/invalidation/inlineFunctionAsParam/project.info index 8249af14c86..b59592e5040 100644 --- a/js/js.translator/testData/incremental/invalidation/inlineFunctionAsParam/project.info +++ b/js/js.translator/testData/incremental/invalidation/inlineFunctionAsParam/project.info @@ -2,21 +2,13 @@ MODULES: lib1, main STEP 0: libs: lib1, main + dirty js: stdlib, lib1, main STEP 1: libs: lib1, main + dirty js: lib1, main STEP 2: libs: lib1, main -STEP 3: - libs: lib1, main -STEP 4: - libs: lib1, main -STEP 5: - libs: lib1, main -STEP 6: - libs: lib1, main -STEP 7: - libs: lib1, main -STEP 8: - libs: lib1, main -STEP 9: + dirty js: lib1 +STEP 3..9: libs: lib1, main + dirty js: lib1, main diff --git a/js/js.translator/testData/incremental/invalidation/inlineFunctionDefaultParams/main/m.kt b/js/js.translator/testData/incremental/invalidation/inlineFunctionDefaultParams/main/m.kt index 62e2ca15940..beb64c009e5 100644 --- a/js/js.translator/testData/incremental/invalidation/inlineFunctionDefaultParams/main/m.kt +++ b/js/js.translator/testData/incremental/invalidation/inlineFunctionDefaultParams/main/m.kt @@ -1,2 +1,9 @@ -fun box() = foo() +fun box(stepId: Int): String { + when (stepId) { + 0 -> if (foo() != (42 + 77)) return "Fail" + 1, 2, 3 -> if (foo() != (42 + 88)) return "Fail" + else -> return "Unknown" + } + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/inlineFunctionDefaultParams/main/module.info b/js/js.translator/testData/incremental/invalidation/inlineFunctionDefaultParams/main/module.info index dbcc4510f38..157458fc2d5 100644 --- a/js/js.translator/testData/incremental/invalidation/inlineFunctionDefaultParams/main/module.info +++ b/js/js.translator/testData/incremental/invalidation/inlineFunctionDefaultParams/main/module.info @@ -1,12 +1,3 @@ -STEP 0: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 1: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 2: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 3: +STEP 0..3: dependencies: stdlib, lib1 dirty: m.kt diff --git a/js/js.translator/testData/incremental/invalidation/inlineFunctionDefaultParams/project.info b/js/js.translator/testData/incremental/invalidation/inlineFunctionDefaultParams/project.info index a572bb611ba..797d907ee4a 100644 --- a/js/js.translator/testData/incremental/invalidation/inlineFunctionDefaultParams/project.info +++ b/js/js.translator/testData/incremental/invalidation/inlineFunctionDefaultParams/project.info @@ -2,9 +2,7 @@ MODULES: lib1, main STEP 0: libs: lib1, main -STEP 1: - libs: lib1, main -STEP 2: - libs: lib1, main -STEP 3: + dirty js: stdlib, lib1, main +STEP 1..3: libs: lib1, main + dirty js: lib1, main diff --git a/js/js.translator/testData/incremental/invalidation/jsCode/lib1/l1.kt.1.txt b/js/js.translator/testData/incremental/invalidation/jsCode/lib1/l1.kt.1.txt index a7658997405..da492544483 100644 --- a/js/js.translator/testData/incremental/invalidation/jsCode/lib1/l1.kt.1.txt +++ b/js/js.translator/testData/incremental/invalidation/jsCode/lib1/l1.kt.1.txt @@ -1 +1 @@ -inline fun foo() = js("40 + 2") +inline fun foo() = js("42 + 1") diff --git a/js/js.translator/testData/incremental/invalidation/jsCode/lib1/l1.kt.2.txt b/js/js.translator/testData/incremental/invalidation/jsCode/lib1/l1.kt.2.txt index d658d3e820b..3d1c4055b3a 100644 --- a/js/js.translator/testData/incremental/invalidation/jsCode/lib1/l1.kt.2.txt +++ b/js/js.translator/testData/incremental/invalidation/jsCode/lib1/l1.kt.2.txt @@ -1 +1 @@ -inline fun foo() = js("'42'") +inline fun foo() = js("'44'") diff --git a/js/js.translator/testData/incremental/invalidation/jsCode/main/m.kt b/js/js.translator/testData/incremental/invalidation/jsCode/main/m.kt index 62e2ca15940..a2579cf9ac0 100644 --- a/js/js.translator/testData/incremental/invalidation/jsCode/main/m.kt +++ b/js/js.translator/testData/incremental/invalidation/jsCode/main/m.kt @@ -1,2 +1,11 @@ -fun box() = foo() +fun box(stepId: Int): String { + when (stepId) { + 0 -> if (foo() != 42) return "Fail" + 1 -> if (foo() != 43) return "Fail" + 2 -> if (foo() != "44") return "Fail" + 3 -> if (foo() != "hello") return "Fail" + else -> return "Unknown" + } + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/jsCode/main/module.info b/js/js.translator/testData/incremental/invalidation/jsCode/main/module.info index b82aa7fff26..157458fc2d5 100644 --- a/js/js.translator/testData/incremental/invalidation/jsCode/main/module.info +++ b/js/js.translator/testData/incremental/invalidation/jsCode/main/module.info @@ -1,13 +1,3 @@ -STEP 0: +STEP 0..3: dependencies: stdlib, lib1 dirty: m.kt -STEP 1: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 2: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 3: - dependencies: stdlib, lib1 - dirty: m.kt - diff --git a/js/js.translator/testData/incremental/invalidation/jsCode/project.info b/js/js.translator/testData/incremental/invalidation/jsCode/project.info index a572bb611ba..797d907ee4a 100644 --- a/js/js.translator/testData/incremental/invalidation/jsCode/project.info +++ b/js/js.translator/testData/incremental/invalidation/jsCode/project.info @@ -2,9 +2,7 @@ MODULES: lib1, main STEP 0: libs: lib1, main -STEP 1: - libs: lib1, main -STEP 2: - libs: lib1, main -STEP 3: + dirty js: stdlib, lib1, main +STEP 1..3: libs: lib1, main + dirty js: lib1, main diff --git a/js/js.translator/testData/incremental/invalidation/jsExport/main/m.kt b/js/js.translator/testData/incremental/invalidation/jsExport/main/m.kt index 7731f12b414..987163500ec 100644 --- a/js/js.translator/testData/incremental/invalidation/jsExport/main/m.kt +++ b/js/js.translator/testData/incremental/invalidation/jsExport/main/m.kt @@ -1,2 +1,6 @@ -fun box() = foo() + gaz() +fun box(): String { + if (foo() != 77) return "Fail foo" + if (gaz() != 99) return "Fail gaz" + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/jsExport/main/module.info b/js/js.translator/testData/incremental/invalidation/jsExport/main/module.info index 4ff12076b7b..eb6ad02059d 100644 --- a/js/js.translator/testData/incremental/invalidation/jsExport/main/module.info +++ b/js/js.translator/testData/incremental/invalidation/jsExport/main/module.info @@ -1,18 +1,5 @@ -STEP 0: +STEP 0..3: dependencies: stdlib, lib1 dirty: m.kt -STEP 1: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 2: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 3: - dependencies: stdlib, lib1 - dirty: m.kt -STEP 4: - dependencies: stdlib, lib1 -STEP 5: - dependencies: stdlib, lib1 -STEP 6: +STEP 4..6: dependencies: stdlib, lib1 diff --git a/js/js.translator/testData/incremental/invalidation/jsExport/project.info b/js/js.translator/testData/incremental/invalidation/jsExport/project.info index 63aeb972074..ce0e42b37cf 100644 --- a/js/js.translator/testData/incremental/invalidation/jsExport/project.info +++ b/js/js.translator/testData/incremental/invalidation/jsExport/project.info @@ -2,15 +2,10 @@ MODULES: lib1, main STEP 0: libs: lib1, main -STEP 1: + dirty js: stdlib, lib1, main +STEP 1..3: libs: lib1, main -STEP 2: - libs: lib1, main -STEP 3: - libs: lib1, main -STEP 4: - libs: lib1, main -STEP 5: - libs: lib1, main -STEP 6: + dirty js: lib1, main +STEP 4..6: libs: lib1, main + dirty js: lib1 diff --git a/js/js.translator/testData/incremental/invalidation/mainModuleInvalidation/main/m.kt b/js/js.translator/testData/incremental/invalidation/mainModuleInvalidation/main/m.kt index 3ed427f027a..c87f1720e2a 100644 --- a/js/js.translator/testData/incremental/invalidation/mainModuleInvalidation/main/m.kt +++ b/js/js.translator/testData/incremental/invalidation/mainModuleInvalidation/main/m.kt @@ -1,2 +1,5 @@ -fun box() = qux() \ No newline at end of file +fun box(): String { + if (qux() != 42) return "Fail" + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/mainModuleInvalidation/main/m.kt.1.txt b/js/js.translator/testData/incremental/invalidation/mainModuleInvalidation/main/m.kt.1.txt index 9a4e0081659..f5b6a11ce80 100644 --- a/js/js.translator/testData/incremental/invalidation/mainModuleInvalidation/main/m.kt.1.txt +++ b/js/js.translator/testData/incremental/invalidation/mainModuleInvalidation/main/m.kt.1.txt @@ -1,2 +1,5 @@ -fun box() = qux() + 88 +fun box(): String { + if (qux() != 42) return "Fail qux" + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/mainModuleInvalidation/main/module.info b/js/js.translator/testData/incremental/invalidation/mainModuleInvalidation/main/module.info index 6d880d391ff..05e0b6e092a 100644 --- a/js/js.translator/testData/incremental/invalidation/mainModuleInvalidation/main/module.info +++ b/js/js.translator/testData/incremental/invalidation/mainModuleInvalidation/main/module.info @@ -1,7 +1,6 @@ STEP 0: dependencies: stdlib, lib1 dirty: m.kt, m0.kt, m1.kt - STEP 1: dependencies: stdlib, lib1 modifications: diff --git a/js/js.translator/testData/incremental/invalidation/mainModuleInvalidation/project.info b/js/js.translator/testData/incremental/invalidation/mainModuleInvalidation/project.info index 3a4c1b58fea..00f537587ac 100644 --- a/js/js.translator/testData/incremental/invalidation/mainModuleInvalidation/project.info +++ b/js/js.translator/testData/incremental/invalidation/mainModuleInvalidation/project.info @@ -2,6 +2,7 @@ MODULES: lib1, main STEP 0: libs: lib1, main - + dirty js: stdlib, lib1, main STEP 1: libs: lib1, main + dirty js: main diff --git a/js/js.translator/testData/incremental/invalidation/moveFilesBetweenModules/lib1/module.info b/js/js.translator/testData/incremental/invalidation/moveFilesBetweenModules/lib1/module.info index 94f8915d2fe..2f11be99f45 100644 --- a/js/js.translator/testData/incremental/invalidation/moveFilesBetweenModules/lib1/module.info +++ b/js/js.translator/testData/incremental/invalidation/moveFilesBetweenModules/lib1/module.info @@ -5,8 +5,6 @@ STEP 1: dependencies: stdlib modifications: D : l12.kt - dirty: - STEP 2: dependencies: stdlib modifications: diff --git a/js/js.translator/testData/incremental/invalidation/moveFilesBetweenModules/lib2/module.info b/js/js.translator/testData/incremental/invalidation/moveFilesBetweenModules/lib2/module.info index 478999a0666..8466549fe50 100644 --- a/js/js.translator/testData/incremental/invalidation/moveFilesBetweenModules/lib2/module.info +++ b/js/js.translator/testData/incremental/invalidation/moveFilesBetweenModules/lib2/module.info @@ -1,15 +1,13 @@ STEP 0: dependencies: stdlib, lib1 dirty: l21.kt - STEP 1: dependencies: stdlib, lib1 modifications: U : l22.kt.1 -> l22.kt dirty: l21.kt, l22.kt - STEP 2: dependencies: stdlib, lib1 modifications: D : l22.kt - dirty: l21.kt \ No newline at end of file + dirty: l21.kt diff --git a/js/js.translator/testData/incremental/invalidation/moveFilesBetweenModules/lib3/module.info b/js/js.translator/testData/incremental/invalidation/moveFilesBetweenModules/lib3/module.info index 95a6e01fe56..9c530561fe8 100644 --- a/js/js.translator/testData/incremental/invalidation/moveFilesBetweenModules/lib3/module.info +++ b/js/js.translator/testData/incremental/invalidation/moveFilesBetweenModules/lib3/module.info @@ -1,11 +1,3 @@ -STEP 0: +STEP 0..2: dependencies: stdlib, lib1, lib2 dirty: l3.kt - -STEP 1: - dependencies: stdlib, lib1, lib2 - dirty: l3.kt - -STEP 2: - dependencies: stdlib, lib1, lib2 - dirty: l3.kt \ No newline at end of file diff --git a/js/js.translator/testData/incremental/invalidation/moveFilesBetweenModules/main/m.kt b/js/js.translator/testData/incremental/invalidation/moveFilesBetweenModules/main/m.kt index 9e4affdeab7..fc86ce1af14 100644 --- a/js/js.translator/testData/incremental/invalidation/moveFilesBetweenModules/main/m.kt +++ b/js/js.translator/testData/incremental/invalidation/moveFilesBetweenModules/main/m.kt @@ -1,2 +1,10 @@ -fun box() = dex(4, 2) \ No newline at end of file +fun box(stepId: Int): String { + when (stepId) { + 0 -> if (dex(4, 2) != 11) return "Fail" + 1 -> if (dex(4, 2) != 10) return "Fail" + 2 -> if (dex(4, 2) != 9) return "Fail" + else -> return "Unknown" + } + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/moveFilesBetweenModules/main/module.info b/js/js.translator/testData/incremental/invalidation/moveFilesBetweenModules/main/module.info index 22de8fc144c..0aa6e1d3601 100644 --- a/js/js.translator/testData/incremental/invalidation/moveFilesBetweenModules/main/module.info +++ b/js/js.translator/testData/incremental/invalidation/moveFilesBetweenModules/main/module.info @@ -1,11 +1,3 @@ -STEP 0: +STEP 0..2: dependencies: stdlib, lib1, lib2, lib3 dirty: m.kt - -STEP 1: - dependencies: stdlib, lib1, lib2, lib3 - dirty: m.kt - -STEP 2: - dependencies: stdlib, lib1, lib2, lib3 - dirty: m.kt \ No newline at end of file diff --git a/js/js.translator/testData/incremental/invalidation/moveFilesBetweenModules/project.info b/js/js.translator/testData/incremental/invalidation/moveFilesBetweenModules/project.info index 74641ec7008..0b9247734a4 100644 --- a/js/js.translator/testData/incremental/invalidation/moveFilesBetweenModules/project.info +++ b/js/js.translator/testData/incremental/invalidation/moveFilesBetweenModules/project.info @@ -2,9 +2,7 @@ MODULES: lib1, lib2, lib3, main STEP 0: libs: lib1, lib2, lib3, main - -STEP 1: + dirty js: stdlib, lib1, lib2, lib3, main +STEP 1..2: libs: lib1, lib2, lib3, main - -STEP 2: - libs: lib1, lib2, lib3, main \ No newline at end of file + dirty js: lib1, lib2, lib3, main diff --git a/js/js.translator/testData/incremental/invalidation/moveInlineFunctionBetweenModules/lib2/module.info b/js/js.translator/testData/incremental/invalidation/moveInlineFunctionBetweenModules/lib2/module.info index be5b21e1a99..a82f8cfa072 100644 --- a/js/js.translator/testData/incremental/invalidation/moveInlineFunctionBetweenModules/lib2/module.info +++ b/js/js.translator/testData/incremental/invalidation/moveInlineFunctionBetweenModules/lib2/module.info @@ -1,9 +1,8 @@ STEP 0: dependencies: stdlib, lib1 dirty: l2.kt - STEP 1: dependencies: stdlib, lib1 modifications: U : l22.kt.1 -> l22.kt - dirty: l2.kt, l22.kt \ No newline at end of file + dirty: l2.kt, l22.kt diff --git a/js/js.translator/testData/incremental/invalidation/moveInlineFunctionBetweenModules/lib3/module.info b/js/js.translator/testData/incremental/invalidation/moveInlineFunctionBetweenModules/lib3/module.info index 629ace95d91..c0e16b77a1f 100644 --- a/js/js.translator/testData/incremental/invalidation/moveInlineFunctionBetweenModules/lib3/module.info +++ b/js/js.translator/testData/incremental/invalidation/moveInlineFunctionBetweenModules/lib3/module.info @@ -1,7 +1,3 @@ -STEP 0: +STEP 0..1: dependencies: stdlib, lib1, lib2 dirty: l3.kt - -STEP 1: - dependencies: stdlib, lib1, lib2 - dirty: l3.kt \ No newline at end of file diff --git a/js/js.translator/testData/incremental/invalidation/moveInlineFunctionBetweenModules/main/m.kt b/js/js.translator/testData/incremental/invalidation/moveInlineFunctionBetweenModules/main/m.kt index 9e4affdeab7..9c493a1e3a7 100644 --- a/js/js.translator/testData/incremental/invalidation/moveInlineFunctionBetweenModules/main/m.kt +++ b/js/js.translator/testData/incremental/invalidation/moveInlineFunctionBetweenModules/main/m.kt @@ -1,2 +1,9 @@ -fun box() = dex(4, 2) \ No newline at end of file +fun box(stepId: Int): String { + when (stepId) { + 0 -> if (dex(4, 2) != 11) return "Fail" + 1 -> if (dex(4, 2) != 18) return "Fail" + else -> return "Unknown" + } + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/moveInlineFunctionBetweenModules/main/module.info b/js/js.translator/testData/incremental/invalidation/moveInlineFunctionBetweenModules/main/module.info index bcb9ac62070..0a863e696d5 100644 --- a/js/js.translator/testData/incremental/invalidation/moveInlineFunctionBetweenModules/main/module.info +++ b/js/js.translator/testData/incremental/invalidation/moveInlineFunctionBetweenModules/main/module.info @@ -1,7 +1,3 @@ -STEP 0: +STEP 0..1: dependencies: stdlib, lib1, lib2, lib3 dirty: m.kt - -STEP 1: - dependencies: stdlib, lib1, lib2, lib3 - dirty: m.kt \ No newline at end of file diff --git a/js/js.translator/testData/incremental/invalidation/moveInlineFunctionBetweenModules/project.info b/js/js.translator/testData/incremental/invalidation/moveInlineFunctionBetweenModules/project.info index 2ce90f668ad..194818478f6 100644 --- a/js/js.translator/testData/incremental/invalidation/moveInlineFunctionBetweenModules/project.info +++ b/js/js.translator/testData/incremental/invalidation/moveInlineFunctionBetweenModules/project.info @@ -2,6 +2,7 @@ MODULES: lib1, lib2, lib3, main STEP 0: libs: lib1, lib2, lib3, main - + dirty js: stdlib, lib1, lib2, lib3, main STEP 1: - libs: lib1, lib2, lib3, main \ No newline at end of file + libs: lib1, lib2, lib3, main + dirty js: lib1, lib2, lib3, main diff --git a/js/js.translator/testData/incremental/invalidation/nonInlineBecomeInline/main/m.kt b/js/js.translator/testData/incremental/invalidation/nonInlineBecomeInline/main/m.kt index 62e2ca15940..9f53a0f22d1 100644 --- a/js/js.translator/testData/incremental/invalidation/nonInlineBecomeInline/main/m.kt +++ b/js/js.translator/testData/incremental/invalidation/nonInlineBecomeInline/main/m.kt @@ -1,2 +1,10 @@ -fun box() = foo() +fun box(stepId: Int): String { + when (stepId) { + 0 -> if (foo() != 42) return "Fail" + 1 -> if (foo() != 33) return "Fail" + 2 -> if (foo() != 77) return "Fail" + else -> return "Unknown" + } + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/nonInlineBecomeInline/main/module.info b/js/js.translator/testData/incremental/invalidation/nonInlineBecomeInline/main/module.info index a4b307c7621..63fcbf11b28 100644 --- a/js/js.translator/testData/incremental/invalidation/nonInlineBecomeInline/main/module.info +++ b/js/js.translator/testData/incremental/invalidation/nonInlineBecomeInline/main/module.info @@ -1,7 +1,5 @@ STEP 0: dependencies: stdlib, lib1 dirty: m.kt -STEP 1: - dependencies: stdlib, lib1 -STEP 2: +STEP 1..2: dependencies: stdlib, lib1 diff --git a/js/js.translator/testData/incremental/invalidation/nonInlineBecomeInline/project.info b/js/js.translator/testData/incremental/invalidation/nonInlineBecomeInline/project.info index 08e19f88401..4c2690d8461 100644 --- a/js/js.translator/testData/incremental/invalidation/nonInlineBecomeInline/project.info +++ b/js/js.translator/testData/incremental/invalidation/nonInlineBecomeInline/project.info @@ -2,7 +2,7 @@ MODULES: lib1, main STEP 0: libs: lib1, main -STEP 1: - libs: lib1, main -STEP 2: + dirty js: stdlib, lib1, main +STEP 1..2: libs: lib1, main + dirty js: lib1 diff --git a/js/js.translator/testData/incremental/invalidation/privateInlineFunction1/lib2/module.info b/js/js.translator/testData/incremental/invalidation/privateInlineFunction1/lib2/module.info index c7b30818f27..c1c7c4b5a69 100644 --- a/js/js.translator/testData/incremental/invalidation/privateInlineFunction1/lib2/module.info +++ b/js/js.translator/testData/incremental/invalidation/privateInlineFunction1/lib2/module.info @@ -1,7 +1,5 @@ STEP 0: dependencies: stdlib, lib1 dirty: l2.kt - STEP 1: dependencies: stdlib, lib1 - dirty: \ No newline at end of file diff --git a/js/js.translator/testData/incremental/invalidation/privateInlineFunction1/main/m.kt b/js/js.translator/testData/incremental/invalidation/privateInlineFunction1/main/m.kt index fc2cbe78044..ab906368e18 100644 --- a/js/js.translator/testData/incremental/invalidation/privateInlineFunction1/main/m.kt +++ b/js/js.translator/testData/incremental/invalidation/privateInlineFunction1/main/m.kt @@ -1,2 +1,9 @@ -fun box() = qux(4, 2) \ No newline at end of file +fun box(stepId: Int): String { + when (stepId) { + 0 -> if (qux(4, 2) != -8) return "Fail" + 1 -> if (qux(4, 2) != -4) return "Fail" + else -> return "Unknown" + } + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/privateInlineFunction1/main/module.info b/js/js.translator/testData/incremental/invalidation/privateInlineFunction1/main/module.info index 53828bd4a60..a2d4e3c24e6 100644 --- a/js/js.translator/testData/incremental/invalidation/privateInlineFunction1/main/module.info +++ b/js/js.translator/testData/incremental/invalidation/privateInlineFunction1/main/module.info @@ -1,7 +1,5 @@ STEP 0: dependencies: stdlib, lib1, lib2 dirty: m.kt - STEP 1: dependencies: stdlib, lib1, lib2 - dirty: \ No newline at end of file diff --git a/js/js.translator/testData/incremental/invalidation/privateInlineFunction1/project.info b/js/js.translator/testData/incremental/invalidation/privateInlineFunction1/project.info index 710e8567360..ca17baa143e 100644 --- a/js/js.translator/testData/incremental/invalidation/privateInlineFunction1/project.info +++ b/js/js.translator/testData/incremental/invalidation/privateInlineFunction1/project.info @@ -2,6 +2,7 @@ MODULES: lib1, lib2, main STEP 0: libs: lib1, lib2, main - + dirty js: stdlib, lib1, lib2, main STEP 1: - libs: lib1, lib2, main \ No newline at end of file + libs: lib1, lib2, main + dirty js: lib1 diff --git a/js/js.translator/testData/incremental/invalidation/removeFile/lib2/module.info b/js/js.translator/testData/incremental/invalidation/removeFile/lib2/module.info index 9d947715e69..eadd9138e8f 100644 --- a/js/js.translator/testData/incremental/invalidation/removeFile/lib2/module.info +++ b/js/js.translator/testData/incremental/invalidation/removeFile/lib2/module.info @@ -1,8 +1,7 @@ STEP 0: dependencies: stdlib, lib1 dirty: l2_0.kt, l2_1.kt - STEP 1: dependencies: stdlib, lib1 modifications: - D : l2_1.kt \ No newline at end of file + D : l2_1.kt diff --git a/js/js.translator/testData/incremental/invalidation/removeFile/main/m.kt b/js/js.translator/testData/incremental/invalidation/removeFile/main/m.kt index 8f05d7bb9a9..824d10871af 100644 --- a/js/js.translator/testData/incremental/invalidation/removeFile/main/m.kt +++ b/js/js.translator/testData/incremental/invalidation/removeFile/main/m.kt @@ -1,2 +1,6 @@ -fun box() = qux0() + qux1() \ No newline at end of file +fun box(): String { + if (qux0() != 42) return "Fail" + if (qux1() != 24) return "Fail" + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/removeFile/main/m.kt.new b/js/js.translator/testData/incremental/invalidation/removeFile/main/m.kt.new index 74ee94fe379..84f8a228a26 100644 --- a/js/js.translator/testData/incremental/invalidation/removeFile/main/m.kt.new +++ b/js/js.translator/testData/incremental/invalidation/removeFile/main/m.kt.new @@ -1,2 +1,5 @@ -fun box() = qux0() \ No newline at end of file +fun box(): String { + if (qux0() != 42) return "Fail" + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/removeFile/main/module.info b/js/js.translator/testData/incremental/invalidation/removeFile/main/module.info index ceeb0dac9c9..aaf8b820e03 100644 --- a/js/js.translator/testData/incremental/invalidation/removeFile/main/module.info +++ b/js/js.translator/testData/incremental/invalidation/removeFile/main/module.info @@ -1,9 +1,8 @@ STEP 0: dependencies: stdlib, lib1, lib2 dirty: m.kt - STEP 1: dependencies: stdlib, lib1, lib2 modifications: U : m.kt.new -> m.kt - dirty: m.kt \ No newline at end of file + dirty: m.kt diff --git a/js/js.translator/testData/incremental/invalidation/removeFile/project.info b/js/js.translator/testData/incremental/invalidation/removeFile/project.info index 710e8567360..2b4d78d81dc 100644 --- a/js/js.translator/testData/incremental/invalidation/removeFile/project.info +++ b/js/js.translator/testData/incremental/invalidation/removeFile/project.info @@ -2,6 +2,7 @@ MODULES: lib1, lib2, main STEP 0: libs: lib1, lib2, main - + dirty js: stdlib, lib1, lib2, main STEP 1: - libs: lib1, lib2, main \ No newline at end of file + libs: lib1, lib2, main + dirty js: lib1, lib2, main diff --git a/js/js.translator/testData/incremental/invalidation/removeModule/lib1/module.info b/js/js.translator/testData/incremental/invalidation/removeModule/lib1/module.info index 071b9e69b1c..d66ee7e368c 100644 --- a/js/js.translator/testData/incremental/invalidation/removeModule/lib1/module.info +++ b/js/js.translator/testData/incremental/invalidation/removeModule/lib1/module.info @@ -1,7 +1,6 @@ STEP 0: dependencies: stdlib dirty: l1.kt - STEP 1: dependencies: stdlib - flags: FP \ No newline at end of file + flags: FP UNUSED diff --git a/js/js.translator/testData/incremental/invalidation/removeModule/lib2/module.info b/js/js.translator/testData/incremental/invalidation/removeModule/lib2/module.info index 7d3a8416412..5f5d59240bd 100644 --- a/js/js.translator/testData/incremental/invalidation/removeModule/lib2/module.info +++ b/js/js.translator/testData/incremental/invalidation/removeModule/lib2/module.info @@ -1,9 +1,8 @@ STEP 0: dependencies: stdlib, lib1 dirty: l2.kt - STEP 1: dependencies: stdlib modifications: U : l2.kt.1 -> l2.kt - dirty: l2.kt \ No newline at end of file + dirty: l2.kt diff --git a/js/js.translator/testData/incremental/invalidation/removeModule/main/m.kt b/js/js.translator/testData/incremental/invalidation/removeModule/main/m.kt index 3ed427f027a..10481919e36 100644 --- a/js/js.translator/testData/incremental/invalidation/removeModule/main/m.kt +++ b/js/js.translator/testData/incremental/invalidation/removeModule/main/m.kt @@ -1,2 +1,9 @@ -fun box() = qux() \ No newline at end of file +fun box(stepId: Int): String { + when (stepId) { + 0 -> if (qux() != 42) return "Fail" + 1 -> if (qux() != 99) return "Fail" + else -> "Unknown" + } + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/removeModule/main/module.info b/js/js.translator/testData/incremental/invalidation/removeModule/main/module.info index 83c64540faa..507ff56ba8f 100644 --- a/js/js.translator/testData/incremental/invalidation/removeModule/main/module.info +++ b/js/js.translator/testData/incremental/invalidation/removeModule/main/module.info @@ -1,6 +1,5 @@ STEP 0: dependencies: stdlib, lib1, lib2 dirty: m.kt - STEP 1: dependencies: stdlib, lib2 diff --git a/js/js.translator/testData/incremental/invalidation/removeModule/project.info b/js/js.translator/testData/incremental/invalidation/removeModule/project.info index 710e8567360..9ddce48f7c0 100644 --- a/js/js.translator/testData/incremental/invalidation/removeModule/project.info +++ b/js/js.translator/testData/incremental/invalidation/removeModule/project.info @@ -2,6 +2,7 @@ MODULES: lib1, lib2, main STEP 0: libs: lib1, lib2, main - + dirty js: stdlib, lib1, lib2, main STEP 1: - libs: lib1, lib2, main \ No newline at end of file + libs: lib1, lib2, main + dirty js: lib2 diff --git a/js/js.translator/testData/incremental/invalidation/removeUnusedFile/main/m.kt b/js/js.translator/testData/incremental/invalidation/removeUnusedFile/main/m.kt index b5f49971b4b..ac2fd73c575 100644 --- a/js/js.translator/testData/incremental/invalidation/removeUnusedFile/main/m.kt +++ b/js/js.translator/testData/incremental/invalidation/removeUnusedFile/main/m.kt @@ -1,2 +1,5 @@ -fun box() = foo0() \ No newline at end of file +fun box(): String { + if (foo0() != 42) return "Fail" + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/removeUnusedFile/project.info b/js/js.translator/testData/incremental/invalidation/removeUnusedFile/project.info index 928fb4c8855..3d92db19a6f 100644 --- a/js/js.translator/testData/incremental/invalidation/removeUnusedFile/project.info +++ b/js/js.translator/testData/incremental/invalidation/removeUnusedFile/project.info @@ -2,9 +2,9 @@ MODULES: lib1, main STEP 0: libs: lib1, main - + dirty js: stdlib, lib1, main STEP 1: libs: lib1, main - + dirty js: lib1 STEP 2: libs: lib1, main diff --git a/js/js.translator/testData/incremental/invalidation/renameFile/main/m.kt b/js/js.translator/testData/incremental/invalidation/renameFile/main/m.kt index d9aa30c4152..e7b5ed244a5 100644 --- a/js/js.translator/testData/incremental/invalidation/renameFile/main/m.kt +++ b/js/js.translator/testData/incremental/invalidation/renameFile/main/m.kt @@ -1,2 +1,5 @@ -fun box() = foo() \ No newline at end of file +fun box(): String { + if (foo() != 42) return "Fail" + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/renameFile/main/module.info b/js/js.translator/testData/incremental/invalidation/renameFile/main/module.info index 39fd2a6ea15..1548fa8071c 100644 --- a/js/js.translator/testData/incremental/invalidation/renameFile/main/module.info +++ b/js/js.translator/testData/incremental/invalidation/renameFile/main/module.info @@ -1,6 +1,5 @@ STEP 0: dependencies: stdlib, lib1 dirty: m.kt - STEP 1: - dependencies: stdlib, lib1 \ No newline at end of file + dependencies: stdlib, lib1 diff --git a/js/js.translator/testData/incremental/invalidation/renameFile/project.info b/js/js.translator/testData/incremental/invalidation/renameFile/project.info index e43922d5598..d5bc61c3174 100644 --- a/js/js.translator/testData/incremental/invalidation/renameFile/project.info +++ b/js/js.translator/testData/incremental/invalidation/renameFile/project.info @@ -2,6 +2,7 @@ MODULES: lib1, main STEP 0: libs: lib1, main - + dirty js: stdlib, lib1, main STEP 1: - libs: lib1, main \ No newline at end of file + libs: lib1, main + dirty js: lib1 diff --git a/js/js.translator/testData/incremental/invalidation/simple/lib1/l1.kt b/js/js.translator/testData/incremental/invalidation/simple/lib1/l1.kt index 859b384ad7f..9d198400fd7 100644 --- a/js/js.translator/testData/incremental/invalidation/simple/lib1/l1.kt +++ b/js/js.translator/testData/incremental/invalidation/simple/lib1/l1.kt @@ -1 +1 @@ -fun foo() = 42 \ No newline at end of file +fun foo() = 42 diff --git a/js/js.translator/testData/incremental/invalidation/simple/lib1/l1.kt.1 b/js/js.translator/testData/incremental/invalidation/simple/lib1/l1.kt.1 deleted file mode 100644 index 8e3c1332e9e..00000000000 --- a/js/js.translator/testData/incremental/invalidation/simple/lib1/l1.kt.1 +++ /dev/null @@ -1 +0,0 @@ -fun foo() = 33 \ No newline at end of file diff --git a/js/js.translator/testData/incremental/invalidation/simple/lib1/l1.kt.1.txt b/js/js.translator/testData/incremental/invalidation/simple/lib1/l1.kt.1.txt new file mode 100644 index 00000000000..0030f51273b --- /dev/null +++ b/js/js.translator/testData/incremental/invalidation/simple/lib1/l1.kt.1.txt @@ -0,0 +1 @@ +fun foo() = 33 diff --git a/js/js.translator/testData/incremental/invalidation/simple/lib1/module.info b/js/js.translator/testData/incremental/invalidation/simple/lib1/module.info index 5963605a540..a9dea2597b7 100644 --- a/js/js.translator/testData/incremental/invalidation/simple/lib1/module.info +++ b/js/js.translator/testData/incremental/invalidation/simple/lib1/module.info @@ -4,5 +4,5 @@ STEP 0: STEP 1: dependencies: stdlib modifications: - U : l1.kt.1 -> l1.kt + U : l1.kt.1.txt -> l1.kt dirty: l1.kt diff --git a/js/js.translator/testData/incremental/invalidation/simple/lib2/module.info b/js/js.translator/testData/incremental/invalidation/simple/lib2/module.info index c7b30818f27..c1c7c4b5a69 100644 --- a/js/js.translator/testData/incremental/invalidation/simple/lib2/module.info +++ b/js/js.translator/testData/incremental/invalidation/simple/lib2/module.info @@ -1,7 +1,5 @@ STEP 0: dependencies: stdlib, lib1 dirty: l2.kt - STEP 1: dependencies: stdlib, lib1 - dirty: \ No newline at end of file diff --git a/js/js.translator/testData/incremental/invalidation/simple/main/m.kt b/js/js.translator/testData/incremental/invalidation/simple/main/m.kt index 3ed427f027a..88654f7e0cd 100644 --- a/js/js.translator/testData/incremental/invalidation/simple/main/m.kt +++ b/js/js.translator/testData/incremental/invalidation/simple/main/m.kt @@ -1,2 +1,9 @@ -fun box() = qux() \ No newline at end of file +fun box(stepId: Int): String { + when (stepId) { + 0 -> if (qux() != 42) return "Fail" + 1 -> if (qux() != 33) return "Fail" + else -> return "Unknown" + } + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/simple/main/module.info b/js/js.translator/testData/incremental/invalidation/simple/main/module.info index d2047496476..a2d4e3c24e6 100644 --- a/js/js.translator/testData/incremental/invalidation/simple/main/module.info +++ b/js/js.translator/testData/incremental/invalidation/simple/main/module.info @@ -1,6 +1,5 @@ STEP 0: dependencies: stdlib, lib1, lib2 dirty: m.kt - STEP 1: - dependencies: stdlib, lib1, lib2 \ No newline at end of file + dependencies: stdlib, lib1, lib2 diff --git a/js/js.translator/testData/incremental/invalidation/simple/project.info b/js/js.translator/testData/incremental/invalidation/simple/project.info index 710e8567360..ca17baa143e 100644 --- a/js/js.translator/testData/incremental/invalidation/simple/project.info +++ b/js/js.translator/testData/incremental/invalidation/simple/project.info @@ -2,6 +2,7 @@ MODULES: lib1, lib2, main STEP 0: libs: lib1, lib2, main - + dirty js: stdlib, lib1, lib2, main STEP 1: - libs: lib1, lib2, main \ No newline at end of file + libs: lib1, lib2, main + dirty js: lib1 diff --git a/js/js.translator/testData/incremental/invalidation/suspendFunctions/main/m.kt b/js/js.translator/testData/incremental/invalidation/suspendFunctions/main/m.kt index b410afb9155..74852df8d5b 100644 --- a/js/js.translator/testData/incremental/invalidation/suspendFunctions/main/m.kt +++ b/js/js.translator/testData/incremental/invalidation/suspendFunctions/main/m.kt @@ -1,6 +1,8 @@ -suspend fun box(): Int { +suspend fun suspendBox(): Int { val x = fooX() val y = fooY() return x + y } + +fun box() = "OK" diff --git a/js/js.translator/testData/incremental/invalidation/suspendFunctions/project.info b/js/js.translator/testData/incremental/invalidation/suspendFunctions/project.info index 08e19f88401..739d806ed37 100644 --- a/js/js.translator/testData/incremental/invalidation/suspendFunctions/project.info +++ b/js/js.translator/testData/incremental/invalidation/suspendFunctions/project.info @@ -2,7 +2,10 @@ MODULES: lib1, main STEP 0: libs: lib1, main + dirty js: stdlib, lib1, main STEP 1: libs: lib1, main + dirty js: lib1, main STEP 2: libs: lib1, main + dirty js: stdlib, lib1, main diff --git a/js/js.translator/testData/incremental/invalidation/transitiveInlineFunction/lib2/module.info b/js/js.translator/testData/incremental/invalidation/transitiveInlineFunction/lib2/module.info index acda14b6069..f73e46361ac 100644 --- a/js/js.translator/testData/incremental/invalidation/transitiveInlineFunction/lib2/module.info +++ b/js/js.translator/testData/incremental/invalidation/transitiveInlineFunction/lib2/module.info @@ -1,7 +1,3 @@ -STEP 0: +STEP 0..1: dependencies: stdlib, lib1 dirty: l2.kt - -STEP 1: - dependencies: stdlib, lib1 - dirty: l2.kt \ No newline at end of file diff --git a/js/js.translator/testData/incremental/invalidation/transitiveInlineFunction/main/m.kt b/js/js.translator/testData/incremental/invalidation/transitiveInlineFunction/main/m.kt index 3ed427f027a..88654f7e0cd 100644 --- a/js/js.translator/testData/incremental/invalidation/transitiveInlineFunction/main/m.kt +++ b/js/js.translator/testData/incremental/invalidation/transitiveInlineFunction/main/m.kt @@ -1,2 +1,9 @@ -fun box() = qux() \ No newline at end of file +fun box(stepId: Int): String { + when (stepId) { + 0 -> if (qux() != 42) return "Fail" + 1 -> if (qux() != 33) return "Fail" + else -> return "Unknown" + } + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/transitiveInlineFunction/main/module.info b/js/js.translator/testData/incremental/invalidation/transitiveInlineFunction/main/module.info index df595acd9eb..bf31ce71736 100644 --- a/js/js.translator/testData/incremental/invalidation/transitiveInlineFunction/main/module.info +++ b/js/js.translator/testData/incremental/invalidation/transitiveInlineFunction/main/module.info @@ -1,7 +1,3 @@ -STEP 0: +STEP 0..1: dependencies: stdlib, lib1, lib2 dirty: m.kt - -STEP 1: - dependencies: stdlib, lib1, lib2 - dirty: m.kt \ No newline at end of file diff --git a/js/js.translator/testData/incremental/invalidation/transitiveInlineFunction/project.info b/js/js.translator/testData/incremental/invalidation/transitiveInlineFunction/project.info index 710e8567360..2b4d78d81dc 100644 --- a/js/js.translator/testData/incremental/invalidation/transitiveInlineFunction/project.info +++ b/js/js.translator/testData/incremental/invalidation/transitiveInlineFunction/project.info @@ -2,6 +2,7 @@ MODULES: lib1, lib2, main STEP 0: libs: lib1, lib2, main - + dirty js: stdlib, lib1, lib2, main STEP 1: - libs: lib1, lib2, main \ No newline at end of file + libs: lib1, lib2, main + dirty js: lib1, lib2, main diff --git a/js/js.translator/testData/incremental/invalidation/variance/main/m.kt b/js/js.translator/testData/incremental/invalidation/variance/main/m.kt index 5aababd1566..4e73634d321 100644 --- a/js/js.translator/testData/incremental/invalidation/variance/main/m.kt +++ b/js/js.translator/testData/incremental/invalidation/variance/main/m.kt @@ -8,4 +8,7 @@ class BoxConsumer: Consumer { fun test(producer: Producer, consumer: Consumer) = consumer.consume(producer.produce()) -fun box() = test(BoxProducer(), BoxConsumer()) +fun box(): String { + if (test(BoxProducer(), BoxConsumer()) != 4) return "Fail" + return "OK" +} diff --git a/js/js.translator/testData/incremental/invalidation/variance/main/module.info b/js/js.translator/testData/incremental/invalidation/variance/main/module.info index a4b307c7621..63fcbf11b28 100644 --- a/js/js.translator/testData/incremental/invalidation/variance/main/module.info +++ b/js/js.translator/testData/incremental/invalidation/variance/main/module.info @@ -1,7 +1,5 @@ STEP 0: dependencies: stdlib, lib1 dirty: m.kt -STEP 1: - dependencies: stdlib, lib1 -STEP 2: +STEP 1..2: dependencies: stdlib, lib1 diff --git a/js/js.translator/testData/incremental/invalidation/variance/project.info b/js/js.translator/testData/incremental/invalidation/variance/project.info index 08e19f88401..4c2690d8461 100644 --- a/js/js.translator/testData/incremental/invalidation/variance/project.info +++ b/js/js.translator/testData/incremental/invalidation/variance/project.info @@ -2,7 +2,7 @@ MODULES: lib1, main STEP 0: libs: lib1, main -STEP 1: - libs: lib1, main -STEP 2: + dirty js: stdlib, lib1, main +STEP 1..2: libs: lib1, main + dirty js: lib1