diff --git a/libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt b/libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt index f7c4e8223e6..1b6110bee70 100644 --- a/libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt +++ b/libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt @@ -59,6 +59,7 @@ abstract class AbstractKotlinCompile() : AbstractCo } abstract protected fun populateTargetSpecificArgs(args: T) + var experimentalIncremental: Boolean = false var kotlinOptions: T = createBlankArgs() var kotlinDestinationDir: File? = destinationDir var compilerCalled: Boolean = false @@ -220,10 +221,12 @@ open class KotlinCompile() : AbstractKotlinCompile() { override fun callCompiler(args: K2JVMCompilerArguments, sources: List, isIncrementalRequested: Boolean, modified: List, removed: List, cachesBaseDir: File) { - // TODO: consider other ways to pass incremental flag to compiler/builder - System.setProperty("kotlin.incremental.compilation", "true") - // TODO: experimental should be removed as soon as it becomes standard - System.setProperty("kotlin.incremental.compilation.experimental", "true") + if (experimentalIncremental) { + // TODO: consider other ways to pass incremental flag to compiler/builder + System.setProperty("kotlin.incremental.compilation", "true") + // TODO: experimental should be removed as soon as it becomes standard + System.setProperty("kotlin.incremental.compilation.experimental", "true") + } val targetType = "java-production" val moduleName = args.moduleName @@ -316,7 +319,8 @@ open class KotlinCompile() : AbstractKotlinCompile() { fun calculateSourcesToCompile(): Pair, Boolean> { - if (!isIncrementalRequested || + if (!experimentalIncremental || + !isIncrementalRequested || // TODO: more precise will be not to rebuild unconditionally on classpath changes, but retrieve lookup info and try to find out which sources are affected by cp changes isClassPathChanged() || // so far considering it not incremental TODO: store java files in the cache and extract removed symbols from it here @@ -384,9 +388,28 @@ open class KotlinCompile() : AbstractKotlinCompile() { generatedRelPaths.forEach { File(destinationDir, it).delete() } } + fun processCompilerExitCode(exitCode: ExitCode) { + if (exitCode != ExitCode.OK) { + cleanupOnError() + } + when (exitCode) { + ExitCode.COMPILATION_ERROR -> throw GradleException("Compilation error. See log for more details") + ExitCode.INTERNAL_ERROR -> throw GradleException("Internal compiler error. See log for more details") + ExitCode.SCRIPT_EXECUTION_ERROR -> throw GradleException("Script execution error. See log for more details") + ExitCode.OK -> logger.kotlinInfo("Compilation succeeded") + } + } + fun outputRelativePath(f: File) = f.toRelativeString(outputDir) + if (!experimentalIncremental) { + anyClassesCompiled = true + processCompilerExitCode(compileNotIncremental(sources, outputDir, args)) + return + } + logger.warn("Using experimental kotlin incremental compilation") + anyClassesCompiled = false // TODO: decide what to do if no files are considered dirty - rebuild or skip the module @@ -425,23 +448,7 @@ open class KotlinCompile() : AbstractKotlinCompile() { allCachesVersions().forEach { it.saveIfNeeded() } - when (exitCode) { - ExitCode.COMPILATION_ERROR -> { - cleanupOnError() - throw GradleException("Compilation error. See log for more details") - } - ExitCode.INTERNAL_ERROR -> { - cleanupOnError() - throw GradleException("Internal compiler error. See log for more details") - } - ExitCode.SCRIPT_EXECUTION_ERROR -> { - cleanupOnError() - throw GradleException("Script execution error. See log for more details") - } - ExitCode.OK -> { - logger.kotlinInfo("Compilation succeeded") - } - } + processCompilerExitCode(exitCode) if (!isIncrementalDecided) break; @@ -522,6 +529,20 @@ open class KotlinCompile() : AbstractKotlinCompile() { getOutputDir = { outputDir })) } + private fun compileNotIncremental(sourcesToCompile: List, + outputDir: File, + args: K2JVMCompilerArguments) + : ExitCode + { + // show kotlin compiler where to look for java source files + args.freeArgs = (sourcesToCompile.map { it.absolutePath } + getJavaSourceRoots().map { it.absolutePath }).distinct() + args.destination = outputDir.absolutePath + + logger.kotlinDebug("compiling with args ${ArgumentUtils.convertArgumentsToStringList(args)}") + + return compiler.exec(GradleMessageCollector(logger), Services.EMPTY, args) + } + private fun handleKaptProperties(extraProperties: ExtraPropertiesExtension, pluginOptions: MutableList) { val kaptAnnotationsFile = extraProperties.getOrNull("kaptAnnotationsFile") diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseIncrementalGradleIT.kt b/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseIncrementalGradleIT.kt index a20ce17a412..ac57ca7ed7e 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseIncrementalGradleIT.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseIncrementalGradleIT.kt @@ -50,6 +50,10 @@ sourceSets { } } +compileKotlin { + experimentalIncremental = true +} + repositories { maven { url 'file://' + pathToKotlinPlugin