diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/CacheUpdater.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/CacheUpdater.kt index 865dda2b36aa5..cd2e32a086df3 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/CacheUpdater.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/CacheUpdater.kt @@ -684,7 +684,7 @@ class CacheUpdater( ) } - fun actualizeCaches(eventCallback: (String) -> Unit = {}): List { + private fun actualizeCachesImpl(eventCallback: (String) -> Unit = {}): List { dirtyFileStats.clear() val modifiedFiles = loadModifiedFiles() @@ -732,6 +732,15 @@ class CacheUpdater( return artifacts } + + fun actualizeCaches(eventCallback: (String) -> Unit = {}): List { + try { + return actualizeCachesImpl(eventCallback) + } catch (e: Exception) { + cacheMap.values.forEach { cacheDir -> File(cacheDir).deleteRecursively() } + throw e + } + } } // Used for tests only diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt index fabb48cc50fc4..03907285dc24f 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt @@ -219,6 +219,23 @@ class Kotlin2JsIrGradlePluginIT : AbstractKotlin2JsGradlePluginIT(true) { } } + @DisplayName("JS IR incremental recompilation after an error") + @GradleTest + fun testJsIrIncrementalRebuildAfterError(gradleVersion: GradleVersion) { + project("kotlin-js-ir-ic-rebuild-after-error", gradleVersion) { + for (i in 0..1) { + buildAndFail("compileDevelopmentExecutableKotlinJs") { + assertTasksFailed(":app:compileDevelopmentExecutableKotlinJs") + + projectPath.resolve("app/build/klib/cache/").toFile().walk().forEach { cachedFile -> + // could be empty directories + assertTrue("Cache should be empty") { cachedFile.isDirectory } + } + } + } + } + } + @DisplayName("Remove unused dependency from klib") @GradleTest fun testJsIrIncrementalKlibRemoveUnusedDependency(gradleVersion: GradleVersion) { diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-ir-ic-rebuild-after-error/app/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-ir-ic-rebuild-after-error/app/build.gradle.kts new file mode 100644 index 0000000000000..7797d2d5e09c8 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-ir-ic-rebuild-after-error/app/build.gradle.kts @@ -0,0 +1,15 @@ +plugins { + kotlin("js") +} + +kotlin { + js { + browser { + } + binaries.executable() + } +} + +configurations["compileClasspath"].apply { + attributes.attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage::class.java, "kotlin-runtime")) +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-ir-ic-rebuild-after-error/app/src/main/kotlin/App.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-ir-ic-rebuild-after-error/app/src/main/kotlin/App.kt new file mode 100644 index 0000000000000..c73b2093b89ef --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-ir-ic-rebuild-after-error/app/src/main/kotlin/App.kt @@ -0,0 +1,17 @@ +/* + * Copyright 2010-2023 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 com.example + +private fun someFunction(x: Any? = null) {} + +fun getSomething(x: dynamic) = with(x) { + someFunction(::unkownFunction) + "Hello!" +} + +fun main() { + println(getSomething(null)) +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-ir-ic-rebuild-after-error/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-ir-ic-rebuild-after-error/build.gradle.kts new file mode 100644 index 0000000000000..877c415742c9f --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-ir-ic-rebuild-after-error/build.gradle.kts @@ -0,0 +1,13 @@ +plugins { + kotlin("js").apply(false) +} + +group = "com.example" +version = "1.0" + +allprojects { + repositories { + mavenLocal() + mavenCentral() + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-ir-ic-rebuild-after-error/gradle.properties b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-ir-ic-rebuild-after-error/gradle.properties new file mode 100644 index 0000000000000..5de000d1dda84 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-ir-ic-rebuild-after-error/gradle.properties @@ -0,0 +1,2 @@ +kotlin.incremental.js.klib=true +kotlin.incremental.js.ir=true \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-ir-ic-rebuild-after-error/settings.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-ir-ic-rebuild-after-error/settings.gradle new file mode 100644 index 0000000000000..fbba8326f0562 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-ir-ic-rebuild-after-error/settings.gradle @@ -0,0 +1,3 @@ +rootProject.name = "kotlin-js-ir-ic-rebuild-after-error" + +include("app")