From 98f561bbed4da3e4ac4d9029171954b32094bd4e Mon Sep 17 00:00:00 2001 From: Alexey Tsvetkov Date: Thu, 27 Feb 2020 12:13:15 +0300 Subject: [PATCH] Add separate flag to control JS KLIB IC in Gradle --- .../jetbrains/kotlin/gradle/BaseGradleIT.kt | 2 ++ .../kotlin/gradle/Kotlin2JsGradlePluginIT.kt | 27 +++++++++++----- .../kotlin/gradle/plugin/KotlinProperties.kt | 4 +++ .../jetbrains/kotlin/gradle/tasks/Tasks.kt | 31 ++++++++++++++----- 4 files changed, 50 insertions(+), 14 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseGradleIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseGradleIT.kt index e75cb4350f2..089f73e963e 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseGradleIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseGradleIT.kt @@ -199,6 +199,7 @@ abstract class BaseGradleIT { val daemonOptionSupported: Boolean = true, val incremental: Boolean? = null, val incrementalJs: Boolean? = null, + val incrementalJsKlib: Boolean? = null, val jsIrBackend: Boolean? = null, val androidHome: File? = null, val javaHome: File? = null, @@ -736,6 +737,7 @@ Finished executing task ':$taskName'| add("-Pkotlin.incremental=$it") } options.incrementalJs?.let { add("-Pkotlin.incremental.js=$it") } + options.incrementalJsKlib?.let { add("-Pkotlin.incremental.js.klib=$it") } options.jsIrBackend?.let { add("-Pkotlin.js.useIrBackend=$it") } options.usePreciseJavaTracking?.let { add("-Pkotlin.incremental.usePreciseJavaTracking=$it") } options.androidGradlePluginVersion?.let { add("-Pandroid_tools_version=$it") } 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 d02777286cc..65c77109a4b 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 @@ -7,6 +7,7 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProjectModules import org.jetbrains.kotlin.gradle.targets.js.npm.fromSrcPackageJson import org.jetbrains.kotlin.gradle.tasks.USING_JS_INCREMENTAL_COMPILATION_MESSAGE import org.jetbrains.kotlin.gradle.tasks.USING_JS_IR_BACKEND_MESSAGE +import org.jetbrains.kotlin.gradle.util.allKotlinFiles import org.jetbrains.kotlin.gradle.util.getFileByName import org.jetbrains.kotlin.gradle.util.getFilesByNames import org.jetbrains.kotlin.gradle.util.jsCompilerType @@ -460,11 +461,19 @@ abstract class AbstractKotlin2JsGradlePluginIT(private val irBackend: Boolean) : @Test fun testIncrementalCompilation() = Project("kotlin2JsICProject").run { + setupWorkingDir() + val modules = listOf("app", "lib") + val mainFiles = modules.flatMapTo(LinkedHashSet()) { + projectDir.resolve("$it/src/main").allKotlinFiles() + } + build("build") { assertSuccessful() checkIrCompilationMessage() - if (!irBackend) { // TODO: Support incremental compilation - assertContains(USING_JS_INCREMENTAL_COMPILATION_MESSAGE) + assertContains(USING_JS_INCREMENTAL_COMPILATION_MESSAGE) + if (irBackend) { + assertCompiledKotlinSources(project.relativize(mainFiles)) + } else { assertCompiledKotlinSources(project.relativize(allKotlinFiles)) } } @@ -480,10 +489,12 @@ abstract class AbstractKotlin2JsGradlePluginIT(private val irBackend: Boolean) : build("build") { assertSuccessful() checkIrCompilationMessage() - // TODO: Support incremental compilation in IR backend - if (!irBackend) { - assertContains(USING_JS_INCREMENTAL_COMPILATION_MESSAGE) - val affectedFiles = project.projectDir.getFilesByNames("A.kt", "useAInLibMain.kt", "useAInAppMain.kt", "useAInAppTest.kt") + assertContains(USING_JS_INCREMENTAL_COMPILATION_MESSAGE) + val affectedFiles = project.projectDir.getFilesByNames("A.kt", "useAInLibMain.kt", "useAInAppMain.kt", "useAInAppTest.kt") + if (irBackend) { + // only klib ic is supported for now, so tests are generated non-incrementally with ir backend + assertCompiledKotlinSources(project.relativize(affectedFiles.filter { it in mainFiles })) + } else { assertCompiledKotlinSources(project.relativize(affectedFiles)) } } @@ -491,7 +502,9 @@ abstract class AbstractKotlin2JsGradlePluginIT(private val irBackend: Boolean) : @Test fun testIncrementalCompilationDisabled() = Project("kotlin2JsICProject").run { - val options = defaultBuildOptions().copy(incrementalJs = false) + val options = defaultBuildOptions().run { + if (irBackend) copy(incrementalJsKlib = false) else copy(incrementalJs = false) + } build("build", options = options) { assertSuccessful() diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinProperties.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinProperties.kt index 949c6079702..aa7800d314e 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinProperties.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinProperties.kt @@ -43,6 +43,7 @@ internal fun PropertiesProvider.mapKotlinTaskProperties(task: AbstractKotlinComp if (task is Kotlin2JsCompile) { incrementalJs?.let { task.incremental = it } + incrementalJsKlib?.let { task.incrementalJsKlib = it } } } @@ -76,6 +77,9 @@ internal class PropertiesProvider private constructor(private val project: Proje val incrementalJs: Boolean? get() = booleanProperty("kotlin.incremental.js") + val incrementalJsKlib: Boolean? + get() = booleanProperty("kotlin.incremental.js.klib") + val incrementalMultiplatform: Boolean? get() = booleanProperty("kotlin.incremental.multiplatform") diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt index 0ebdc3040ae..c4b5e09a207 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt @@ -128,7 +128,9 @@ abstract class AbstractKotlinCompile() : AbstractKo // indicates that task should compile kotlin incrementally if possible // it's not possible when IncrementalTaskInputs#isIncremental returns false (i.e first build) - @get:Input + // todo: deprecate and remove (we may need to design api for configuring IC) + // don't rely on it to check if IC is enabled, use isIncrementalCompilationEnabled instead + @get:Internal var incremental: Boolean = false get() = field set(value) { @@ -136,6 +138,10 @@ abstract class AbstractKotlinCompile() : AbstractKo logger.kotlinDebug { "Set $this.incremental=$value" } } + @Input + internal open fun isIncrementalCompilationEnabled(): Boolean = + incremental + @get:Internal internal var buildReportMode: BuildReportMode? = null @@ -263,13 +269,13 @@ abstract class AbstractKotlinCompile() : AbstractKo // then Gradle forces next build to be non-incremental (see Gradle's DefaultTaskArtifactStateRepository#persistNewOutputs) // To prevent this, we backup outputs before incremental build and restore when exception is thrown val outputsBackup: TaskOutputsBackup? = - if (incremental && inputs.isIncremental) + if (isIncrementalCompilationEnabled() && inputs.isIncremental) kotlinLogger.logTime("Backing up outputs for incremental build") { TaskOutputsBackup(allOutputFiles()) } else null - if (!incremental) { + if (!isIncrementalCompilationEnabled()) { clearLocalState("IC is disabled") } @@ -405,7 +411,7 @@ open class KotlinCompile : AbstractKotlinCompile(), Kotl val outputItemCollector = OutputItemsCollectorImpl() val compilerRunner = compilerRunner() - val icEnv = if (incremental) { + val icEnv = if (isIncrementalCompilationEnabled()) { logger.info(USING_JVM_INCREMENTAL_COMPILATION_MESSAGE) IncrementalCompilationEnvironment( if (hasFilesInTaskBuildDirectory()) changedFiles else ChangedFiles.Unknown(), @@ -434,7 +440,7 @@ open class KotlinCompile : AbstractKotlinCompile(), Kotl } private fun disableMultiModuleIC(): Boolean { - if (!incremental || javaOutputDir == null) return false + if (!isIncrementalCompilationEnabled() || javaOutputDir == null) return false fun forEachTask(fn: (Task) -> Unit) { if (isGradleVersionAtLeast(4, 10)) { @@ -518,6 +524,17 @@ open class Kotlin2JsCompile : AbstractKotlinCompile(), Ko protected val defaultOutputFile: File get() = File(destinationDir, "${taskData.compilation.ownModuleName}.js") + @get:Input + internal var incrementalJsKlib: Boolean = true + + override fun isIncrementalCompilationEnabled(): Boolean = + when { + "-Xir-produce-js" in kotlinOptions.freeCompilerArgs -> false + "-Xir-produce-klib-dir" in kotlinOptions.freeCompilerArgs -> incrementalJsKlib + "-Xir-produce-klib-file" in kotlinOptions.freeCompilerArgs -> incrementalJsKlib + else -> incremental + } + @Suppress("unused") @get:OutputFile val outputFile: File @@ -571,6 +588,7 @@ open class Kotlin2JsCompile : AbstractKotlinCompile(), Ko "-Xir-produce-klib-file" ).any(freeCompilerArgs::contains) + // see also isIncrementalCompilationEnabled private fun KotlinJsOptions.isIrBackendEnabled(): Boolean = listOf( "-Xir-produce-klib-dir", @@ -601,7 +619,6 @@ open class Kotlin2JsCompile : AbstractKotlinCompile(), Ko if (kotlinOptions.isIrBackendEnabled()) { logger.info(USING_JS_IR_BACKEND_MESSAGE) - incremental = false } val dependencies = compileClasspath @@ -626,7 +643,7 @@ open class Kotlin2JsCompile : AbstractKotlinCompile(), Ko val outputItemCollector = OutputItemsCollectorImpl() val compilerRunner = compilerRunner() - val icEnv = if (incremental) { + val icEnv = if (isIncrementalCompilationEnabled()) { logger.info(USING_JS_INCREMENTAL_COMPILATION_MESSAGE) IncrementalCompilationEnvironment( if (hasFilesInTaskBuildDirectory()) changedFiles else ChangedFiles.Unknown(),