Fix java build when kotlin is changed
See SimpleKotlinGradleIT#testSimpleCompile
#KT-11350 fixed
This commit is contained in:
@@ -37,6 +37,7 @@
|
|||||||
|
|
||||||
### Tools.Gradle
|
### Tools.Gradle
|
||||||
- Added project property 'kotlin.incremental'
|
- Added project property 'kotlin.incremental'
|
||||||
|
- Fixed a bug causing Java rebuild when both Java and Kotlin are up-to-date
|
||||||
|
|
||||||
## 1.0.1-2
|
## 1.0.1-2
|
||||||
|
|
||||||
|
|||||||
+35
-34
@@ -17,6 +17,7 @@ import org.gradle.api.file.SourceDirectorySet
|
|||||||
import org.gradle.api.initialization.dsl.ScriptHandler
|
import org.gradle.api.initialization.dsl.ScriptHandler
|
||||||
import org.gradle.api.internal.HasConvention
|
import org.gradle.api.internal.HasConvention
|
||||||
import org.gradle.api.internal.project.ProjectInternal
|
import org.gradle.api.internal.project.ProjectInternal
|
||||||
|
import org.gradle.api.logging.Logger
|
||||||
import org.gradle.api.logging.Logging
|
import org.gradle.api.logging.Logging
|
||||||
import org.gradle.api.plugins.ExtensionAware
|
import org.gradle.api.plugins.ExtensionAware
|
||||||
import org.gradle.api.plugins.JavaBasePlugin
|
import org.gradle.api.plugins.JavaBasePlugin
|
||||||
@@ -134,28 +135,8 @@ class Kotlin2JvmSourceSetProcessor(
|
|||||||
kotlinTask.setProperty("kotlinDestinationDir", kotlinDestinationDir)
|
kotlinTask.setProperty("kotlinDestinationDir", kotlinDestinationDir)
|
||||||
|
|
||||||
val javaTask = project.tasks.findByName(sourceSet.compileJavaTaskName) as AbstractCompile?
|
val javaTask = project.tasks.findByName(sourceSet.compileJavaTaskName) as AbstractCompile?
|
||||||
|
|
||||||
if (javaTask != null) {
|
if (javaTask != null) {
|
||||||
// Since we cannot update classpath statically, java not able to detect changes in the classpath after kotlin compiler.
|
setUpKotlinToJavaDependency(project, kotlinTask, javaTask, logger)
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val kotlinAnnotationProcessingDep = cachedKotlinAnnotationProcessingDep ?: run {
|
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)
|
val (aptOutputDir, aptWorkingDir) = project.getAptDirsForSourceSet(variantDataName)
|
||||||
variantData.addJavaSourceFoldersToModel(aptOutputDir)
|
variantData.addJavaSourceFoldersToModel(aptOutputDir)
|
||||||
|
|
||||||
@@ -457,17 +436,7 @@ open class KotlinAndroidPlugin @Inject constructor(val scriptHandler: ScriptHand
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
javaTask.doFirst {
|
setUpKotlinToJavaDependency(project, kotlinTask, javaTask, logger)
|
||||||
/*
|
|
||||||
* 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"))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -481,8 +450,40 @@ open class KotlinAndroidPlugin @Inject constructor(val scriptHandler: ScriptHand
|
|||||||
val result = (obj as HasConvention).convention.plugins[extensionName]
|
val result = (obj as HasConvention).convention.plugins[extensionName]
|
||||||
return result as T
|
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 {
|
private fun loadSubplugins(project: Project): SubpluginEnvironment {
|
||||||
|
|||||||
Reference in New Issue
Block a user