Fix java build when kotlin is changed

See SimpleKotlinGradleIT#testSimpleCompile

    #KT-11350 fixed
This commit is contained in:
Alexey Tsvetkov
2016-03-25 08:22:18 +03:00
parent 4e64d46105
commit ae53183d72
2 changed files with 36 additions and 34 deletions
+1
View File
@@ -37,6 +37,7 @@
### Tools.Gradle
- Added project property 'kotlin.incremental'
- Fixed a bug causing Java rebuild when both Java and Kotlin are up-to-date
## 1.0.1-2
@@ -17,6 +17,7 @@ import org.gradle.api.file.SourceDirectorySet
import org.gradle.api.initialization.dsl.ScriptHandler
import org.gradle.api.internal.HasConvention
import org.gradle.api.internal.project.ProjectInternal
import org.gradle.api.logging.Logger
import org.gradle.api.logging.Logging
import org.gradle.api.plugins.ExtensionAware
import org.gradle.api.plugins.JavaBasePlugin
@@ -134,28 +135,8 @@ class Kotlin2JvmSourceSetProcessor(
kotlinTask.setProperty("kotlinDestinationDir", kotlinDestinationDir)
val javaTask = project.tasks.findByName(sourceSet.compileJavaTaskName) as AbstractCompile?
if (javaTask != null) {
// Since we cannot update classpath statically, java not able to detect changes in the classpath after kotlin compiler.
// Therefore this (probably inefficient since java cannot decide "uptodateness" by the list of changed class files, but told
// explicitly being out of date whenever any kotlin files are compiled
if (kotlinTask.hasProperty("anyClassesCompiled")) {
kotlinTask.property("anyClassesCompiled")?.let {
kotlinTask.setProperty("anyClassesCompiled", false)
javaTask.outputs.upToDateWhen { task ->
val kotlinClassesCompiled = kotlinTask.property("anyClassesCompiled") as? Boolean ?: false
if (kotlinClassesCompiled) {
logger.info("Marking $task out of date, because kotlin classes are changed")
}
!kotlinClassesCompiled
}
}
}
javaTask.dependsOn(kotlinTaskName)
javaTask.doFirst {
javaTask.classpath += project.files(kotlinDestinationDir)
}
setUpKotlinToJavaDependency(project, kotlinTask, javaTask, logger)
}
val kotlinAnnotationProcessingDep = cachedKotlinAnnotationProcessingDep ?: run {
@@ -440,8 +421,6 @@ open class KotlinAndroidPlugin @Inject constructor(val scriptHandler: ScriptHand
}
}
javaTask.dependsOn(kotlinTaskName)
val (aptOutputDir, aptWorkingDir) = project.getAptDirsForSourceSet(variantDataName)
variantData.addJavaSourceFoldersToModel(aptOutputDir)
@@ -457,17 +436,7 @@ open class KotlinAndroidPlugin @Inject constructor(val scriptHandler: ScriptHand
}
}
javaTask.doFirst {
/*
* It's important to modify javaTask.classpath only in doFirst,
* because Android plugin uses ConventionMapping to modify it too (see JavaCompileConfigAction.execute),
* and setting classpath explicitly prevents usage of Android mappings.
* Also classpath setted by Android can be modified after excecution of some tasks (see VarianConfiguration.getCompileClasspath)
* ex. it adds some support libraries jars after execution of prepareComAndroidSupportSupportV42311Library task,
* so it's only safe to modify javaTask.classpath right before its usage
*/
javaTask.classpath += project.files(kotlinTask.property("kotlinDestinationDir"))
}
setUpKotlinToJavaDependency(project, kotlinTask, javaTask, logger)
}
}
@@ -481,8 +450,40 @@ open class KotlinAndroidPlugin @Inject constructor(val scriptHandler: ScriptHand
val result = (obj as HasConvention).convention.plugins[extensionName]
return result as T
}
}
private fun setUpKotlinToJavaDependency(project: Project, kotlinTask: AbstractCompile, javaTask: AbstractCompile, logger: Logger) {
// Since we cannot update classpath statically, java not able to detect changes in the classpath after kotlin compiler.
// Therefore this (probably inefficient since java cannot decide "uptodateness" by the list of changed class files, but told
// explicitly being out of date whenever any kotlin files are compiled
if (kotlinTask.hasProperty("anyClassesCompiled")) {
kotlinTask.property("anyClassesCompiled")?.let {
kotlinTask.setProperty("anyClassesCompiled", false)
javaTask.outputs.upToDateWhen { task ->
val kotlinClassesCompiled = kotlinTask.property("anyClassesCompiled") as? Boolean ?: false
if (kotlinClassesCompiled) {
logger.info("Marking $task out of date, because kotlin classes are changed")
}
!kotlinClassesCompiled
}
}
}
javaTask.dependsOn(kotlinTask.name)
javaTask.doFirst {
/*
* It's important to modify javaTask.classpath only in doFirst,
* because Android plugin uses ConventionMapping to modify it too (see JavaCompileConfigAction.execute),
* and setting classpath explicitly prevents usage of Android mappings.
* Also classpath setted by Android can be modified after excecution of some tasks (see VarianConfiguration.getCompileClasspath)
* ex. it adds some support libraries jars after execution of prepareComAndroidSupportSupportV42311Library task,
* so it's only safe to modify javaTask.classpath right before its usage
*/
javaTask.classpath += project.files(kotlinTask.property("kotlinDestinationDir"))
}
javaTask.doLast {
javaTask.classpath -= project.files(kotlinTask.property("kotlinDestinationDir"))
}
}
private fun loadSubplugins(project: Project): SubpluginEnvironment {