Implement Gradle JS IC support

#KT-19956 fixed

To try the experimental JS IC add
'kotlin.incremental.js = true' to a 'local.properties'
or 'gradle.properties' file in Gradle project's root.
This commit is contained in:
Alexey Tsvetkov
2017-06-13 22:30:42 +03:00
parent eeb90656dc
commit b54414d628
13 changed files with 280 additions and 95 deletions
@@ -24,10 +24,7 @@ import org.jetbrains.kotlin.build.JvmSourceRoot
import org.jetbrains.kotlin.cli.common.CLICompiler import org.jetbrains.kotlin.cli.common.CLICompiler
import org.jetbrains.kotlin.cli.common.ExitCode import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.cli.common.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY import org.jetbrains.kotlin.cli.common.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.*
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.parseCommandLineArguments
import org.jetbrains.kotlin.cli.common.arguments.validateArguments
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.common.messages.MessageRenderer import org.jetbrains.kotlin.cli.common.messages.MessageRenderer
@@ -390,26 +387,73 @@ class CompileServiceImpl(
} }
} }
CompilerMode.INCREMENTAL_COMPILER -> { CompilerMode.INCREMENTAL_COMPILER -> {
if (targetPlatform != CompileService.TargetPlatform.JVM) {
throw IllegalStateException("Incremental compilation is not supported for target platform: $targetPlatform")
}
val k2jvmArgs = k2PlatformArgs as K2JVMCompilerArguments
val gradleIncrementalArgs = compilationOptions as IncrementalCompilationOptions val gradleIncrementalArgs = compilationOptions as IncrementalCompilationOptions
val gradleIncrementalServicesFacade = servicesFacade as IncrementalCompilerServicesFacade val gradleIncrementalServicesFacade = servicesFacade as IncrementalCompilerServicesFacade
withIC { when (targetPlatform) {
doCompile(sessionId, daemonReporter, tracer = null) { _, _ -> CompileService.TargetPlatform.JVM -> {
execIncrementalCompiler(k2jvmArgs, gradleIncrementalArgs, gradleIncrementalServicesFacade, compilationResults!!, val k2jvmArgs = k2PlatformArgs as K2JVMCompilerArguments
messageCollector, daemonReporter)
}
}
withIC {
doCompile(sessionId, daemonReporter, tracer = null) { _, _ ->
execIncrementalCompiler(k2jvmArgs, gradleIncrementalArgs, gradleIncrementalServicesFacade, compilationResults!!,
messageCollector, daemonReporter)
}
}
}
CompileService.TargetPlatform.JS -> {
val k2jsArgs = k2PlatformArgs as K2JSCompilerArguments
withJsIC {
doCompile(sessionId, daemonReporter, tracer = null) { _, _ ->
execJsIncrementalCompiler(k2jsArgs, gradleIncrementalArgs, gradleIncrementalServicesFacade, compilationResults!!, messageCollector)
}
}
}
else -> throw IllegalStateException("Incremental compilation is not supported for target platform: $targetPlatform")
}
} }
else -> throw IllegalStateException("Unknown compilation mode ${compilationOptions.compilerMode}") else -> throw IllegalStateException("Unknown compilation mode ${compilationOptions.compilerMode}")
} }
} }
private fun execJsIncrementalCompiler(
args: K2JSCompilerArguments,
incrementalCompilationOptions: IncrementalCompilationOptions,
servicesFacade: IncrementalCompilerServicesFacade,
compilationResults: CompilationResults,
compilerMessageCollector: MessageCollector
): ExitCode {
val allKotlinFiles = arrayListOf<File>()
val freeArgsWithoutKotlinFiles = arrayListOf<String>()
args.freeArgs.forEach {
if (it.endsWith(".kt") && File(it).exists()) {
allKotlinFiles.add(File(it))
}
else {
freeArgsWithoutKotlinFiles.add(it)
}
}
args.freeArgs = freeArgsWithoutKotlinFiles
val reporter = RemoteICReporter(servicesFacade, compilationResults, incrementalCompilationOptions)
val changedFiles = if (incrementalCompilationOptions.areFileChangesKnown) {
ChangedFiles.Known(incrementalCompilationOptions.modifiedFiles!!, incrementalCompilationOptions.deletedFiles!!)
}
else {
ChangedFiles.Unknown()
}
val workingDir = incrementalCompilationOptions.workingDir
val versions = commonCacheVersions(workingDir) +
customCacheVersion(incrementalCompilationOptions.customCacheVersion, incrementalCompilationOptions.customCacheVersionFileName, workingDir, forceEnable = true)
return IncrementalJsCompilerRunner(workingDir, versions, reporter)
.compile(allKotlinFiles, args, compilerMessageCollector, { changedFiles })
}
private fun execIncrementalCompiler( private fun execIncrementalCompiler(
k2jvmArgs: K2JVMCompilerArguments, k2jvmArgs: K2JVMCompilerArguments,
incrementalCompilationOptions: IncrementalCompilationOptions, incrementalCompilationOptions: IncrementalCompilationOptions,
@@ -1,6 +1,8 @@
package org.jetbrains.kotlin.gradle package org.jetbrains.kotlin.gradle
import org.gradle.api.logging.LogLevel import org.gradle.api.logging.LogLevel
import org.jetbrains.kotlin.gradle.tasks.USING_EXPERIMENTAL_JS_INCREMENTAL_COMPILATION_MESSAGE
import org.jetbrains.kotlin.gradle.util.allKotlinFiles
import org.jetbrains.kotlin.gradle.util.getFileByName import org.jetbrains.kotlin.gradle.util.getFileByName
import org.jetbrains.kotlin.gradle.util.modify import org.jetbrains.kotlin.gradle.util.modify
import org.junit.Test import org.junit.Test
@@ -235,4 +237,24 @@ class Kotlin2JsGradlePluginIT : BaseGradleIT() {
assertNotContains("this build assumes a single directory for all classes from a source set") assertNotContains("this build assumes a single directory for all classes from a source set")
} }
} }
@Test
fun testIncrementalCompilation() {
val project = Project("kotlin2JsICProject", "4.0")
project.build("build") {
assertSuccessful()
assertContains(USING_EXPERIMENTAL_JS_INCREMENTAL_COMPILATION_MESSAGE)
assertCompiledKotlinSources(project.relativize(project.projectDir.allKotlinFiles()))
}
val aKt = project.projectDir.getFileByName("A.kt").apply {
modify { it.replace("val x: String", "val x: Int") }
}
val useAKt = project.projectDir.getFileByName("useA.kt")
project.build("build") {
assertSuccessful()
assertContains(USING_EXPERIMENTAL_JS_INCREMENTAL_COMPILATION_MESSAGE)
assertCompiledKotlinSources(project.relativize(aKt, useAKt))
}
}
} }
@@ -0,0 +1,47 @@
buildscript {
repositories {
mavenLocal()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'kotlin2js'
repositories {
mavenLocal()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version"
}
task jarSources(type: Jar) {
from sourceSets.main.allSource
classifier = 'source'
}
artifacts {
compile jarSources
}
def outDir = "${buildDir}/kotlin2js/main/"
compileKotlin2Js.kotlinOptions.outputFile = outDir + "test-library.js"
jar {
from sourceSets.main.allSource
include "**/*.kt"
from outDir
include "**/*.js"
manifest {
attributes(
"Specification-Title": "Kotlin JavaScript Lib",
"Kotlin-JS-Module-Name": "test-library"
)
}
}
jar.dependsOn(compileKotlin2Js)
@@ -0,0 +1,19 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package foo
class A(val x: String)
@@ -0,0 +1,19 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package foo
fun dummy() {}
@@ -0,0 +1,19 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package foo
fun useA(a: A) = a.x
@@ -34,8 +34,8 @@ internal class GradleIncrementalCompilerEnvironment(
val workingDir: File, val workingDir: File,
messageCollector: GradleMessageCollector, messageCollector: GradleMessageCollector,
outputItemsCollector: OutputItemsCollector, outputItemsCollector: OutputItemsCollector,
val kaptAnnotationsFileUpdater: AnnotationFileUpdater?, compilerArgs: CommonCompilerArguments,
val artifactDifferenceRegistryProvider: ArtifactDifferenceRegistryProvider?, val kaptAnnotationsFileUpdater: AnnotationFileUpdater? = null,
val artifactFile: File?, val artifactDifferenceRegistryProvider: ArtifactDifferenceRegistryProvider? = null,
compilerArgs: CommonCompilerArguments val artifactFile: File? = null
) : GradleCompilerEnvironment(compilerJar, messageCollector, outputItemsCollector, compilerArgs) ) : GradleCompilerEnvironment(compilerJar, messageCollector, outputItemsCollector, compilerArgs)
@@ -193,11 +193,17 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
} }
val (daemon, sessionId) = connection val (daemon, sessionId) = connection
val targetPlatform = when (compilerClassName) {
K2JVM_COMPILER -> CompileService.TargetPlatform.JVM
K2JS_COMPILER -> CompileService.TargetPlatform.JS
K2METADATA_COMPILER -> CompileService.TargetPlatform.METADATA
else -> throw IllegalArgumentException("Unknown compiler type $compilerClassName")
}
val exitCode = try { val exitCode = try {
val res = if (environment is GradleIncrementalCompilerEnvironment) { val res = if (environment is GradleIncrementalCompilerEnvironment) {
incrementalCompilationWithDaemon(daemon, sessionId, environment) incrementalCompilationWithDaemon(daemon, sessionId, targetPlatform, environment)
} else { } else {
nonIncrementalCompilationWithDaemon(daemon, sessionId, compilerClassName, environment) nonIncrementalCompilationWithDaemon(daemon, sessionId, targetPlatform, environment)
} }
exitCodeFromProcessExitCode(res.get()) exitCodeFromProcessExitCode(res.get())
} }
@@ -215,16 +221,9 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
private fun nonIncrementalCompilationWithDaemon( private fun nonIncrementalCompilationWithDaemon(
daemon: CompileService, daemon: CompileService,
sessionId: Int, sessionId: Int,
compilerClassName: String, targetPlatform: CompileService.TargetPlatform,
environment: GradleCompilerEnvironment environment: GradleCompilerEnvironment
): CompileService.CallResult<Int> { ): CompileService.CallResult<Int> {
val targetPlatform = when (compilerClassName) {
K2JVM_COMPILER -> CompileService.TargetPlatform.JVM
K2JS_COMPILER -> CompileService.TargetPlatform.JS
K2METADATA_COMPILER -> CompileService.TargetPlatform.METADATA
else -> throw IllegalArgumentException("Unknown compiler type $compilerClassName")
}
val verbose = environment.compilerArgs.verbose val verbose = environment.compilerArgs.verbose
val compilationOptions = CompilationOptions( val compilationOptions = CompilationOptions(
compilerMode = CompilerMode.NON_INCREMENTAL_COMPILER, compilerMode = CompilerMode.NON_INCREMENTAL_COMPILER,
@@ -240,6 +239,7 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
private fun incrementalCompilationWithDaemon( private fun incrementalCompilationWithDaemon(
daemon: CompileService, daemon: CompileService,
sessionId: Int, sessionId: Int,
targetPlatform: CompileService.TargetPlatform,
environment: GradleIncrementalCompilerEnvironment environment: GradleIncrementalCompilerEnvironment
): CompileService.CallResult<Int> { ): CompileService.CallResult<Int> {
val knownChangedFiles = environment.changedFiles as? ChangedFiles.Known val knownChangedFiles = environment.changedFiles as? ChangedFiles.Known
@@ -256,7 +256,7 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
reportSeverity = reportSeverity(verbose), reportSeverity = reportSeverity(verbose),
requestedCompilationResults = arrayOf(CompilationResultCategory.IC_COMPILE_ITERATION.code), requestedCompilationResults = arrayOf(CompilationResultCategory.IC_COMPILE_ITERATION.code),
compilerMode = CompilerMode.INCREMENTAL_COMPILER, compilerMode = CompilerMode.INCREMENTAL_COMPILER,
targetPlatform = CompileService.TargetPlatform.JVM targetPlatform = targetPlatform
) )
val servicesFacade = GradleIncrementalCompilerServicesFacadeImpl(project, environment) val servicesFacade = GradleIncrementalCompilerServicesFacadeImpl(project, environment)
val argsArray = ArgumentUtils.convertArgumentsToStringList(environment.compilerArgs).toTypedArray() val argsArray = ArgumentUtils.convertArgumentsToStringList(environment.compilerArgs).toTypedArray()
@@ -19,47 +19,48 @@ package org.jetbrains.kotlin.gradle.plugin
import org.gradle.api.Project import org.gradle.api.Project
import org.jetbrains.kotlin.gradle.dsl.Coroutines import org.jetbrains.kotlin.gradle.dsl.Coroutines
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import java.util.* import java.util.*
import kotlin.reflect.KMutableProperty1 import kotlin.reflect.KMutableProperty1
fun mapKotlinTaskProperties(project: Project, task: AbstractKotlinCompile<*>) { fun mapKotlinTaskProperties(project: Project, task: AbstractKotlinCompile<*>) {
propertyMappings.forEach { it.apply(project, task) } val properties = PropertiesProvider(project)
val localPropertiesFile = project.rootProject.file("local.properties") properties["kotlin.coroutines"]?.let {
if (localPropertiesFile.isFile) { task.coroutinesFromGradleProperties = Coroutines.byCompilerArgument(it)
val properties = Properties() }
localPropertiesFile.inputStream().use {
properties.load(it) if (task is KotlinCompile) {
properties["kotlin.incremental"]?.let {
task.incremental = it.toBoolean()
}
}
if (task is Kotlin2JsCompile) {
properties["kotlin.incremental.js"]?.let {
task.incremental = it.toBoolean()
} }
propertyMappings.forEach { it.apply(properties, task) }
} }
} }
private val propertyMappings = listOf( private class PropertiesProvider(private val project: Project) {
KotlinPropertyMapping("kotlin.incremental", AbstractKotlinCompile<*>::incremental, String::toBoolean), val localProperties = Properties()
KotlinPropertyMapping("kotlin.coroutines", AbstractKotlinCompile<*>::coroutinesFromGradleProperties) { Coroutines.byCompilerArgument(it) }
)
private class KotlinPropertyMapping<T>( init {
private val projectPropName: String, val localPropertiesFile = project.rootProject.file("local.properties")
private val taskProperty: KMutableProperty1<AbstractKotlinCompile<*>, T>, if (localPropertiesFile.isFile) {
private val transform: (String) -> T localPropertiesFile.inputStream().use {
) { localProperties.load(it)
fun apply(project: Project, task: AbstractKotlinCompile<*>) { }
if (!project.hasProperty(projectPropName)) return }
setPropertyValue(task, project.property(projectPropName))
} }
fun apply(properties: Properties, task: AbstractKotlinCompile<*>) { operator fun get(propName: String): String? =
setPropertyValue(task, properties.getProperty(projectPropName)) if (project.hasProperty(propName)) {
} project.property(propName) as? String
}
private fun setPropertyValue(task: AbstractKotlinCompile<*>, value: Any?) { else {
if (value !is String) return localProperties.getProperty(propName)
}
val transformedValue = transform(value) ?: return
taskProperty.set(task, transformedValue)
}
} }
@@ -51,7 +51,8 @@ import kotlin.properties.Delegates
const val ANNOTATIONS_PLUGIN_NAME = "org.jetbrains.kotlin.kapt" const val ANNOTATIONS_PLUGIN_NAME = "org.jetbrains.kotlin.kapt"
const val KOTLIN_BUILD_DIR_NAME = "kotlin" const val KOTLIN_BUILD_DIR_NAME = "kotlin"
const val USING_INCREMENTAL_COMPILATION_MESSAGE = "Using kotlin incremental compilation" const val USING_INCREMENTAL_COMPILATION_MESSAGE = "Using Kotlin incremental compilation"
const val USING_EXPERIMENTAL_JS_INCREMENTAL_COMPILATION_MESSAGE = "Using experimental Kotlin/JS incremental compilation"
abstract class AbstractKotlinCompileTool<T : CommonToolArguments>() : AbstractCompile() { abstract class AbstractKotlinCompileTool<T : CommonToolArguments>() : AbstractCompile() {
var compilerJarFile: File? = null var compilerJarFile: File? = null
@@ -63,6 +64,30 @@ abstract class AbstractKotlinCompileTool<T : CommonToolArguments>() : AbstractCo
} }
abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractKotlinCompileTool<T>(), CompilerArgumentAware { abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractKotlinCompileTool<T>(), CompilerArgumentAware {
internal val taskBuildDirectory: File
get() = File(File(project.buildDir, KOTLIN_BUILD_DIR_NAME), name).apply { mkdirs() }
private val cacheVersions: List<CacheVersion> =
listOf(normalCacheVersion(taskBuildDirectory),
dataContainerCacheVersion(taskBuildDirectory),
gradleCacheVersion(taskBuildDirectory))
// indicates that task should compile kotlin incrementally if possible
// it's not possible when IncrementalTaskInputs#isIncremental returns false (i.e first build)
var incremental: Boolean = false
get() = field
set(value) {
field = value
logger.kotlinDebug { "Set $this.incremental=$value" }
}
internal val isCacheFormatUpToDate: Boolean
get() {
if (!incremental) return true
return cacheVersions.all { it.checkVersion() == CacheVersion.Action.DO_NOTHING }
}
abstract protected fun createCompilerArgs(): T abstract protected fun createCompilerArgs(): T
protected val additionalClasspath = arrayListOf<File>() protected val additionalClasspath = arrayListOf<File>()
@@ -87,16 +112,6 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractKo
private val kotlinExt: KotlinProjectExtension private val kotlinExt: KotlinProjectExtension
get() = project.extensions.findByType(KotlinProjectExtension::class.java)!! get() = project.extensions.findByType(KotlinProjectExtension::class.java)!!
// indicates that task should compile kotlin incrementally if possible
// it's not possible when IncrementalTaskInputs#isIncremental returns false (i.e first build)
var incremental: Boolean = false
get() = field
set(value) {
field = value
logger.kotlinDebug { "Set $this.incremental=$value" }
System.setProperty("kotlin.incremental.compilation", value.toString())
}
private lateinit var destinationDirProvider: Lazy<File> private lateinit var destinationDirProvider: Lazy<File>
override fun getDestinationDir(): File { override fun getDestinationDir(): File {
@@ -111,10 +126,6 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractKo
destinationDirProvider = lazyOf(destinationDir) destinationDirProvider = lazyOf(destinationDir)
} }
init {
incremental = true //to execute the setter as well
}
internal var coroutinesFromGradleProperties: Coroutines? = null internal var coroutinesFromGradleProperties: Coroutines? = null
// Input is needed to force rebuild even if source files are not changed // Input is needed to force rebuild even if source files are not changed
@get:Input @get:Input
@@ -214,20 +225,6 @@ open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), Kotl
get() = kotlinOptionsImpl get() = kotlinOptionsImpl
internal open val sourceRootsContainer = FilteringSourceRootsContainer() internal open val sourceRootsContainer = FilteringSourceRootsContainer()
internal val taskBuildDirectory: File
get() = File(File(project.buildDir, KOTLIN_BUILD_DIR_NAME), name).apply { mkdirs() }
private val cacheVersions by lazy {
listOf(normalCacheVersion(taskBuildDirectory),
dataContainerCacheVersion(taskBuildDirectory),
gradleCacheVersion(taskBuildDirectory))
}
internal val isCacheFormatUpToDate: Boolean
get() {
if (!incremental) return true
return cacheVersions.all { it.checkVersion() == CacheVersion.Action.DO_NOTHING }
}
private var kaptAnnotationsFileUpdater: AnnotationFileUpdater? = null private var kaptAnnotationsFileUpdater: AnnotationFileUpdater? = null
val kaptOptions = KaptOptions() val kaptOptions = KaptOptions()
@@ -245,6 +242,10 @@ open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), Kotl
internal var artifactDifferenceRegistryProvider: ArtifactDifferenceRegistryProvider? = null internal var artifactDifferenceRegistryProvider: ArtifactDifferenceRegistryProvider? = null
internal var artifactFile: File? = null internal var artifactFile: File? = null
init {
incremental = true
}
override fun findKotlinCompilerJar(project: Project): File? = override fun findKotlinCompilerJar(project: Project): File? =
findKotlinJvmCompilerJar(project) findKotlinJvmCompilerJar(project)
@@ -298,9 +299,9 @@ open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), Kotl
else -> { else -> {
logger.warn(USING_INCREMENTAL_COMPILATION_MESSAGE) logger.warn(USING_INCREMENTAL_COMPILATION_MESSAGE)
GradleIncrementalCompilerEnvironment(compilerJar, changedFiles, reporter, taskBuildDirectory, GradleIncrementalCompilerEnvironment(compilerJar, changedFiles, reporter, taskBuildDirectory,
messageCollector, outputItemCollector, kaptAnnotationsFileUpdater, messageCollector, outputItemCollector, args, kaptAnnotationsFileUpdater,
artifactDifferenceRegistryProvider, artifactDifferenceRegistryProvider,
artifactFile, args) artifactFile)
} }
} }
@@ -444,9 +445,21 @@ open class Kotlin2JsCompile() : AbstractKotlinCompile<K2JSCompilerArguments>(),
val messageCollector = GradleMessageCollector(logger) val messageCollector = GradleMessageCollector(logger)
val outputItemCollector = OutputItemsCollectorImpl() val outputItemCollector = OutputItemsCollectorImpl()
val compilerRunner = GradleCompilerRunner(project) val compilerRunner = GradleCompilerRunner(project)
val environment = GradleCompilerEnvironment(compilerJar, messageCollector, outputItemCollector, args) val reporter = GradleICReporter(project.rootProject.projectDir)
val environment = when {
incremental -> {
logger.warn(USING_EXPERIMENTAL_JS_INCREMENTAL_COMPILATION_MESSAGE)
GradleIncrementalCompilerEnvironment(
compilerJar, changedFiles, reporter, taskBuildDirectory,
messageCollector, outputItemCollector, args)
}
else -> {
GradleCompilerEnvironment(compilerJar, messageCollector, outputItemCollector, args)
}
}
val exitCode = compilerRunner.runJsCompiler(sourceRoots.kotlinSourceFiles, args, environment) val exitCode = compilerRunner.runJsCompiler(sourceRoots.kotlinSourceFiles, args, environment)
throwGradleExceptionIfError(exitCode) throwGradleExceptionIfError(exitCode)
} }
@@ -25,7 +25,6 @@ internal open class KotlinTasksProvider {
fun createKotlinJVMTask(project: Project, name: String, sourceSetName: String): KotlinCompile = fun createKotlinJVMTask(project: Project, name: String, sourceSetName: String): KotlinCompile =
project.tasks.create(name, KotlinCompile::class.java).apply { project.tasks.create(name, KotlinCompile::class.java).apply {
configure(project, sourceSetName) configure(project, sourceSetName)
outputs.upToDateWhen { isCacheFormatUpToDate }
} }
fun createKotlinJSTask(project: Project, name: String, sourceSetName: String): Kotlin2JsCompile = fun createKotlinJSTask(project: Project, name: String, sourceSetName: String): Kotlin2JsCompile =
@@ -42,6 +41,7 @@ internal open class KotlinTasksProvider {
this.sourceSetName = sourceSetName this.sourceSetName = sourceSetName
this.friendTaskName = taskToFriendTaskMapper[this] this.friendTaskName = taskToFriendTaskMapper[this]
mapKotlinTaskProperties(project, this) mapKotlinTaskProperties(project, this)
outputs.upToDateWhen { isCacheFormatUpToDate }
} }
protected open val taskToFriendTaskMapper: TaskToFriendTaskMapper = protected open val taskToFriendTaskMapper: TaskToFriendTaskMapper =
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.incremental
import java.io.File import java.io.File
internal const val GRADLE_CACHE_VERSION = 3 internal const val GRADLE_CACHE_VERSION = 4
internal const val GRADLE_CACHE_VERSION_FILE_NAME = "gradle-format-version.txt" internal const val GRADLE_CACHE_VERSION_FILE_NAME = "gradle-format-version.txt"
internal fun gradleCacheVersion(dataRoot: File): CacheVersion = internal fun gradleCacheVersion(dataRoot: File): CacheVersion =