Replace usages of IncrementalTaskInputs with InputChanges.
Gradle IncrementalTaskInputs was long time ago deprecated and not so flexible as a new proposed way - InputChanges. ^KT-47867 Fixed
This commit is contained in:
+11
-1
@@ -818,6 +818,7 @@ fun getSomething() = 10
|
||||
|
||||
project.build("assembleDebug", options = options) {
|
||||
assertSuccessful()
|
||||
output
|
||||
}
|
||||
|
||||
val androidModuleKt = project.projectDir.getFileByName("AndroidModule.kt")
|
||||
@@ -830,13 +831,22 @@ fun getSomething() = 10
|
||||
|
||||
project.build(":app:assembleDebug", options = options) {
|
||||
assertSuccessful()
|
||||
assertCompiledKotlinSources(project.relativize(androidModuleKt))
|
||||
assertTasksExecuted(
|
||||
":app:kaptGenerateStubsDebugKotlin",
|
||||
":app:kaptDebugKotlin",
|
||||
":app:compileDebugKotlin",
|
||||
":app:compileDebugJavaWithJavac"
|
||||
)
|
||||
|
||||
// Output is combined with previous build, but we are only interested in the compilation
|
||||
// from second build to avoid false positive test failure
|
||||
val filteredOutput = output
|
||||
.lineSequence()
|
||||
.filter { it.contains("[KOTLIN] compile iteration:") }
|
||||
.drop(1)
|
||||
.joinToString(separator = "/n")
|
||||
val actualSources = getCompiledKotlinSources(filteredOutput).projectRelativePaths(project)
|
||||
assertSameFiles(project.relativize(androidModuleKt), actualSources, "Compiled Kotlin files differ:\n ")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -567,7 +567,7 @@ abstract class BaseGradleIT {
|
||||
return this
|
||||
}
|
||||
|
||||
private fun Iterable<File>.projectRelativePaths(project: Project): Iterable<String> {
|
||||
internal fun Iterable<File>.projectRelativePaths(project: Project): Iterable<String> {
|
||||
return map { it.canonicalFile.toRelativeString(project.projectDir) }
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -96,7 +96,7 @@ class KaptIncrementalWithIsolatingApt : KaptIncrementalIT() {
|
||||
)
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
assertContains("Unable to use existing data, re-initializing classpath information for KAPT.")
|
||||
assertContains("The input changes require a full rebuild for incremental task ':kaptKotlin'.")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ class KaptIncrementalWithIsolatingApt : KaptIncrementalIT() {
|
||||
}
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
assertContains("Unable to use existing data, re-initializing classpath information for KAPT.")
|
||||
assertContains("The input changes require a full rebuild for incremental task ':kaptKotlin'.")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.gradle.incremental
|
||||
|
||||
import org.jetbrains.kotlin.incremental.ChangedFiles
|
||||
import java.io.File
|
||||
|
||||
internal fun ChangedFiles(
|
||||
@Suppress("DEPRECATION") taskInputs: org.gradle.api.tasks.incremental.IncrementalTaskInputs
|
||||
): ChangedFiles {
|
||||
if (!taskInputs.isIncremental) return ChangedFiles.Unknown()
|
||||
|
||||
val modified = ArrayList<File>()
|
||||
val removed = ArrayList<File>()
|
||||
|
||||
taskInputs.outOfDate { modified.add(it.file) }
|
||||
taskInputs.removed { removed.add(it.file) }
|
||||
|
||||
return ChangedFiles.Known(modified, removed)
|
||||
}
|
||||
+2
-2
@@ -519,7 +519,7 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
|
||||
kaptTask.destinationDir = sourcesOutputDir
|
||||
kaptTask.kotlinSourcesDestinationDir = kotlinSourcesOutputDir
|
||||
kaptTask.classesDir = classesOutputDir
|
||||
kaptTask.includeCompileClasspath = includeCompileClasspath
|
||||
kaptTask.includeCompileClasspath.set(includeCompileClasspath)
|
||||
|
||||
kaptTask.isIncremental = project.isIncrementalKapt()
|
||||
|
||||
@@ -618,7 +618,7 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
|
||||
kaptTaskProvider.configure { task ->
|
||||
task.onlyIf {
|
||||
it as KaptTask
|
||||
it.includeCompileClasspath || !it.kaptClasspath.isEmpty()
|
||||
it.includeCompileClasspath.get() || !it.kaptClasspath.isEmpty
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+99
-72
@@ -10,7 +10,8 @@ import org.gradle.api.provider.ListProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.tasks.*
|
||||
import org.gradle.api.tasks.incremental.IncrementalTaskInputs
|
||||
import org.gradle.work.Incremental
|
||||
import org.gradle.work.InputChanges
|
||||
import org.jetbrains.kotlin.build.report.metrics.BuildMetricsReporter
|
||||
import org.jetbrains.kotlin.build.report.metrics.BuildMetricsReporterImpl
|
||||
import org.jetbrains.kotlin.gradle.internal.kapt.incremental.ClasspathSnapshot
|
||||
@@ -22,9 +23,10 @@ import org.jetbrains.kotlin.gradle.internal.tasks.TaskWithLocalState
|
||||
import org.jetbrains.kotlin.gradle.tasks.*
|
||||
import org.jetbrains.kotlin.gradle.tasks.cacheOnlyIfEnabledForKotlin
|
||||
import org.jetbrains.kotlin.gradle.tasks.clearLocalState
|
||||
import org.jetbrains.kotlin.gradle.utils.getValue
|
||||
import org.jetbrains.kotlin.gradle.utils.*
|
||||
import org.jetbrains.kotlin.gradle.utils.isConfigurationCacheAvailable
|
||||
import org.jetbrains.kotlin.gradle.utils.property
|
||||
import org.jetbrains.kotlin.gradle.utils.propertyWithConvention
|
||||
import org.jetbrains.kotlin.gradle.utils.propertyWithNewInstance
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
import java.io.File
|
||||
@@ -88,8 +90,8 @@ abstract class KaptTask @Inject constructor(
|
||||
@get:Internal
|
||||
internal abstract val kaptClasspathConfigurationNames: ListProperty<String>
|
||||
|
||||
|
||||
@get:PathSensitive(PathSensitivity.NONE)
|
||||
@get:Incremental
|
||||
@get:IgnoreEmptyDirectories
|
||||
@get:Optional
|
||||
@get:InputFiles
|
||||
@@ -114,7 +116,9 @@ abstract class KaptTask @Inject constructor(
|
||||
internal val annotationProcessorOptionProviders: MutableList<Any> = mutableListOf()
|
||||
|
||||
@get:Input
|
||||
internal var includeCompileClasspath: Boolean = true
|
||||
internal val includeCompileClasspath: Property<Boolean> = objectFactory
|
||||
.propertyWithConvention(true)
|
||||
.chainedFinalizeValueOnRead()
|
||||
|
||||
@get:Input
|
||||
internal var isIncremental = true
|
||||
@@ -137,10 +141,11 @@ abstract class KaptTask @Inject constructor(
|
||||
message = "Don't use directly. Used only for up-to-date checks",
|
||||
level = DeprecationLevel.ERROR
|
||||
)
|
||||
@get:Incremental
|
||||
@get:CompileClasspath
|
||||
internal val internalAbiClasspath: FileCollection by project.provider {
|
||||
if (includeCompileClasspath) project.files() else classpath
|
||||
}
|
||||
internal val internalAbiClasspath: FileCollection = project.objects.fileCollection().from(
|
||||
{ if (includeCompileClasspath.get()) null else classpath }
|
||||
)
|
||||
|
||||
|
||||
@Suppress("unused", "DeprecatedCallableAddReplaceWith")
|
||||
@@ -148,10 +153,11 @@ abstract class KaptTask @Inject constructor(
|
||||
message = "Don't use directly. Used only for up-to-date checks",
|
||||
level = DeprecationLevel.ERROR
|
||||
)
|
||||
@get:Incremental
|
||||
@get:Classpath
|
||||
internal val internalNonAbiClasspath: FileCollection by project.provider {
|
||||
if (includeCompileClasspath) classpath else project.files()
|
||||
}
|
||||
internal val internalNonAbiClasspath: FileCollection = project.objects.fileCollection().from(
|
||||
{ if (includeCompileClasspath.get()) classpath else null }
|
||||
)
|
||||
|
||||
@get:Internal
|
||||
var useBuildCache: Boolean = false
|
||||
@@ -165,6 +171,7 @@ abstract class KaptTask @Inject constructor(
|
||||
|
||||
@get:InputFiles
|
||||
@get:IgnoreEmptyDirectories
|
||||
@get:Incremental
|
||||
@get:PathSensitive(PathSensitivity.RELATIVE)
|
||||
abstract val source: ConfigurableFileCollection
|
||||
|
||||
@@ -208,7 +215,7 @@ abstract class KaptTask @Inject constructor(
|
||||
}
|
||||
|
||||
protected fun checkAnnotationProcessorClasspath() {
|
||||
if (!includeCompileClasspath) return
|
||||
if (!includeCompileClasspath.get()) return
|
||||
|
||||
val kaptClasspath = kaptClasspath.toSet()
|
||||
val processorsFromCompileClasspath = classpath.files.filterTo(LinkedHashSet()) {
|
||||
@@ -240,86 +247,106 @@ abstract class KaptTask @Inject constructor(
|
||||
@get:Internal
|
||||
internal abstract val compiledSources: ConfigurableFileCollection
|
||||
|
||||
protected fun getIncrementalChanges(inputs: IncrementalTaskInputs): KaptIncrementalChanges {
|
||||
protected fun getIncrementalChanges(inputChanges: InputChanges): KaptIncrementalChanges {
|
||||
return if (isIncremental) {
|
||||
findClasspathChanges(inputs)
|
||||
findClasspathChanges(inputChanges)
|
||||
} else {
|
||||
clearLocalState()
|
||||
KaptIncrementalChanges.Unknown
|
||||
}
|
||||
}
|
||||
|
||||
private fun findClasspathChanges(inputs: IncrementalTaskInputs): KaptIncrementalChanges {
|
||||
private fun findClasspathChanges(inputChanges: InputChanges): KaptIncrementalChanges {
|
||||
val incAptCacheDir = incAptCache.asFile.get()
|
||||
incAptCacheDir.mkdirs()
|
||||
|
||||
val allDataFiles = classpathStructure.files
|
||||
val changedFiles = if (inputs.isIncremental) {
|
||||
with(mutableSetOf<File>()) {
|
||||
inputs.outOfDate { this.add(it.file) }
|
||||
inputs.removed { this.add(it.file) }
|
||||
return@with this
|
||||
|
||||
return if (inputChanges.isIncremental) {
|
||||
val startTime = System.currentTimeMillis()
|
||||
|
||||
@Suppress("DEPRECATION_ERROR")
|
||||
val changedFiles = listOf(
|
||||
source,
|
||||
internalNonAbiClasspath,
|
||||
internalAbiClasspath,
|
||||
classpathStructure
|
||||
).fold(mutableSetOf<File>()) { acc, prop ->
|
||||
inputChanges.getFileChanges(prop).forEach { acc.add(it.file) }
|
||||
acc
|
||||
}
|
||||
|
||||
val previousSnapshot = loadPreviousSnapshot(incAptCacheDir, allDataFiles, changedFiles)
|
||||
val currentSnapshot = ClasspathSnapshot.ClasspathSnapshotFactory
|
||||
.createCurrent(
|
||||
incAptCacheDir,
|
||||
classpath.files.toList(),
|
||||
kaptClasspath.files.toList(),
|
||||
allDataFiles
|
||||
)
|
||||
val classpathChanges = currentSnapshot.diff(previousSnapshot, changedFiles)
|
||||
if (classpathChanges == KaptClasspathChanges.Unknown) {
|
||||
// We are unable to determine classpath changes, so clean the local state as we will run non-incrementally
|
||||
clearLocalState()
|
||||
}
|
||||
currentSnapshot.writeToCache()
|
||||
|
||||
if (logger.isInfoEnabled) {
|
||||
val time = "Took ${System.currentTimeMillis() - startTime}ms."
|
||||
when {
|
||||
previousSnapshot == UnknownSnapshot ->
|
||||
logger.info("Initializing classpath information for KAPT. $time")
|
||||
classpathChanges == KaptClasspathChanges.Unknown ->
|
||||
logger.info("Unable to use existing data, re-initializing classpath information for KAPT. $time")
|
||||
else -> {
|
||||
classpathChanges as KaptClasspathChanges.Known
|
||||
logger.info("Full list of impacted classpath names: ${classpathChanges.names}. $time")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return when (classpathChanges) {
|
||||
is KaptClasspathChanges.Unknown -> KaptIncrementalChanges.Unknown
|
||||
is KaptClasspathChanges.Known -> KaptIncrementalChanges.Known(
|
||||
changedFiles.filter { it.extension == "java" }.toSet(), classpathChanges.names
|
||||
)
|
||||
}
|
||||
} else {
|
||||
allDataFiles
|
||||
clearLocalState("Kapt is running non-incrementally")
|
||||
|
||||
ClasspathSnapshot.ClasspathSnapshotFactory
|
||||
.createCurrent(
|
||||
incAptCacheDir,
|
||||
classpath.files.toList(),
|
||||
kaptClasspath.files.toList(),
|
||||
allDataFiles
|
||||
)
|
||||
.writeToCache()
|
||||
|
||||
KaptIncrementalChanges.Unknown
|
||||
}
|
||||
}
|
||||
|
||||
val startTime = System.currentTimeMillis()
|
||||
private fun loadPreviousSnapshot(
|
||||
cacheDir: File,
|
||||
allDataFiles: MutableSet<File>,
|
||||
changedFiles: MutableSet<File>
|
||||
): ClasspathSnapshot {
|
||||
val loadedPrevious = ClasspathSnapshot.ClasspathSnapshotFactory.loadFrom(cacheDir)
|
||||
|
||||
val previousSnapshot = if (inputs.isIncremental) {
|
||||
val loadedPrevious = ClasspathSnapshot.ClasspathSnapshotFactory.loadFrom(incAptCacheDir)
|
||||
|
||||
val previousAndCurrentDataFiles = lazy { loadedPrevious.getAllDataFiles() + allDataFiles }
|
||||
val allChangesRecognized = changedFiles.all {
|
||||
val extension = it.extension
|
||||
if (extension.isEmpty() || extension == "java" || extension == "jar" || extension == "class") {
|
||||
return@all true
|
||||
}
|
||||
// if not a directory, Java source file, jar, or class, it has to be a structure file, in order to understand changes
|
||||
it in previousAndCurrentDataFiles.value
|
||||
}
|
||||
if (allChangesRecognized) {
|
||||
loadedPrevious
|
||||
} else {
|
||||
ClasspathSnapshot.ClasspathSnapshotFactory.getEmptySnapshot()
|
||||
val previousAndCurrentDataFiles = lazy { loadedPrevious.getAllDataFiles() + allDataFiles }
|
||||
val allChangesRecognized = changedFiles.all {
|
||||
val extension = it.extension
|
||||
if (extension.isEmpty() || extension == "java" || extension == "jar" || extension == "class") {
|
||||
return@all true
|
||||
}
|
||||
// if not a directory, Java source file, jar, or class, it has to be a structure file, in order to understand changes
|
||||
it in previousAndCurrentDataFiles.value
|
||||
}
|
||||
return if (allChangesRecognized) {
|
||||
loadedPrevious
|
||||
} else {
|
||||
ClasspathSnapshot.ClasspathSnapshotFactory.getEmptySnapshot()
|
||||
}
|
||||
val currentSnapshot =
|
||||
ClasspathSnapshot.ClasspathSnapshotFactory.createCurrent(
|
||||
incAptCacheDir,
|
||||
classpath.files.toList(),
|
||||
kaptClasspath.files.toList(),
|
||||
allDataFiles
|
||||
)
|
||||
|
||||
val classpathChanges = currentSnapshot.diff(previousSnapshot, changedFiles)
|
||||
if (classpathChanges == KaptClasspathChanges.Unknown) {
|
||||
// We are unable to determine classpath changes, so clean the local state as we will run non-incrementally
|
||||
clearLocalState()
|
||||
}
|
||||
currentSnapshot.writeToCache()
|
||||
|
||||
if (logger.isInfoEnabled) {
|
||||
val time = "Took ${System.currentTimeMillis() - startTime}ms."
|
||||
when {
|
||||
previousSnapshot == UnknownSnapshot ->
|
||||
logger.info("Initializing classpath information for KAPT. $time")
|
||||
classpathChanges == KaptClasspathChanges.Unknown ->
|
||||
logger.info("Unable to use existing data, re-initializing classpath information for KAPT. $time")
|
||||
else -> {
|
||||
classpathChanges as KaptClasspathChanges.Known
|
||||
logger.info("Full list of impacted classpath names: ${classpathChanges.names}. $time")
|
||||
}
|
||||
}
|
||||
}
|
||||
return when (classpathChanges) {
|
||||
is KaptClasspathChanges.Unknown -> KaptIncrementalChanges.Unknown
|
||||
is KaptClasspathChanges.Known -> KaptIncrementalChanges.Known(
|
||||
changedFiles.filter { it.extension == "java" }.toSet(), classpathChanges.names
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun hasAnnotationProcessors(file: File): Boolean {
|
||||
|
||||
+3
-2
@@ -12,6 +12,7 @@ import org.gradle.api.provider.Property
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.tasks.*
|
||||
import org.gradle.api.tasks.incremental.IncrementalTaskInputs
|
||||
import org.gradle.work.InputChanges
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
||||
import org.jetbrains.kotlin.compilerRunner.GradleCompilerEnvironment
|
||||
import org.jetbrains.kotlin.compilerRunner.GradleCompilerRunner
|
||||
@@ -97,11 +98,11 @@ abstract class KaptWithKotlincTask @Inject constructor(
|
||||
private val reportingSettings = objectFactory.property(ReportingSettings::class.java)
|
||||
|
||||
@TaskAction
|
||||
fun compile(inputs: IncrementalTaskInputs) {
|
||||
fun compile(inputChanges: InputChanges) {
|
||||
logger.debug("Running kapt annotation processing using the Kotlin compiler")
|
||||
checkAnnotationProcessorClasspath()
|
||||
|
||||
val incrementalChanges = getIncrementalChanges(inputs)
|
||||
val incrementalChanges = getIncrementalChanges(inputChanges)
|
||||
if (incrementalChanges is KaptIncrementalChanges.Known) {
|
||||
changedFiles = incrementalChanges.changedSources.toList()
|
||||
classpathChanges = incrementalChanges.changedClasspathJvmNames.toList()
|
||||
|
||||
+4
-3
@@ -12,6 +12,7 @@ import org.gradle.api.provider.ProviderFactory
|
||||
import org.gradle.api.tasks.*
|
||||
import org.gradle.api.tasks.incremental.IncrementalTaskInputs
|
||||
import org.gradle.process.CommandLineArgumentProvider
|
||||
import org.gradle.work.InputChanges
|
||||
import org.gradle.workers.IsolationMode
|
||||
import org.gradle.workers.WorkAction
|
||||
import org.gradle.workers.WorkParameters
|
||||
@@ -99,11 +100,11 @@ abstract class KaptWithoutKotlincTask @Inject constructor(
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun compile(inputs: IncrementalTaskInputs) {
|
||||
fun compile(inputChanges: InputChanges) {
|
||||
logger.info("Running kapt annotation processing using the Gradle Worker API")
|
||||
checkAnnotationProcessorClasspath()
|
||||
|
||||
val incrementalChanges = getIncrementalChanges(inputs)
|
||||
val incrementalChanges = getIncrementalChanges(inputChanges)
|
||||
val (changedFiles, classpathChanges) = when (incrementalChanges) {
|
||||
is KaptIncrementalChanges.Unknown -> Pair(emptyList<File>(), emptyList<String>())
|
||||
is KaptIncrementalChanges.Known -> Pair(incrementalChanges.changedSources.toList(), incrementalChanges.changedClasspathJvmNames)
|
||||
@@ -117,7 +118,7 @@ abstract class KaptWithoutKotlincTask @Inject constructor(
|
||||
val kaptFlagsForWorker = mutableSetOf<String>().apply {
|
||||
if (verbose.get()) add("VERBOSE")
|
||||
if (mapDiagnosticLocations) add("MAP_DIAGNOSTIC_LOCATIONS")
|
||||
if (includeCompileClasspath) add("INCLUDE_COMPILE_CLASSPATH")
|
||||
if (includeCompileClasspath.get()) add("INCLUDE_COMPILE_CLASSPATH")
|
||||
if (incrementalChanges is KaptIncrementalChanges.Known) add("INCREMENTAL_APT")
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -59,7 +59,9 @@ class Android25ProjectHandler(
|
||||
|
||||
val preJavaClasspathKey = variantData.registerPreJavacGeneratedBytecode(preJavaKotlinOutput)
|
||||
kotlinTask.configure { kotlinTaskInstance ->
|
||||
kotlinTaskInstance.inputs.files(variantData.getSourceFolders(SourceKind.JAVA)).withPathSensitivity(PathSensitivity.RELATIVE)
|
||||
kotlinTaskInstance.source(
|
||||
variantData.getSourceFolders(SourceKind.JAVA)
|
||||
)
|
||||
|
||||
kotlinTaskInstance.classpath = project.files()
|
||||
.from(variantData.getCompileClasspath(preJavaClasspathKey))
|
||||
|
||||
+1
-1
@@ -135,7 +135,7 @@ class AndroidSubplugin :
|
||||
)
|
||||
)
|
||||
kotlinCompilation.compileKotlinTaskProvider.configure {
|
||||
it.inputs.files(getLayoutDirectories(project, sourceSet.res.srcDirs)).withPathSensitivity(PathSensitivity.RELATIVE)
|
||||
it.source(getLayoutDirectories(project, sourceSet.res.srcDirs))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+68
-11
@@ -14,6 +14,7 @@ import org.gradle.api.invocation.Gradle
|
||||
import org.gradle.api.attributes.Attribute
|
||||
import org.gradle.api.logging.Logger
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.api.model.ReplacedBy
|
||||
import org.gradle.api.provider.ListProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.provider.Provider
|
||||
@@ -22,7 +23,9 @@ import org.gradle.api.services.BuildServiceParameters
|
||||
import org.gradle.api.tasks.*
|
||||
import org.gradle.api.tasks.compile.AbstractCompile
|
||||
import org.gradle.api.tasks.compile.JavaCompile
|
||||
import org.gradle.api.tasks.incremental.IncrementalTaskInputs
|
||||
import org.gradle.work.ChangeType
|
||||
import org.gradle.work.Incremental
|
||||
import org.gradle.work.InputChanges
|
||||
import org.gradle.workers.WorkerExecutor
|
||||
import org.jetbrains.kotlin.build.DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS
|
||||
import org.jetbrains.kotlin.build.report.metrics.*
|
||||
@@ -36,7 +39,6 @@ import org.jetbrains.kotlin.compilerRunner.GradleCompilerRunner.Companion.normal
|
||||
import org.jetbrains.kotlin.daemon.common.MultiModuleICSettings
|
||||
import org.jetbrains.kotlin.gradle.dsl.*
|
||||
import org.jetbrains.kotlin.gradle.incremental.*
|
||||
import org.jetbrains.kotlin.gradle.incremental.ChangedFiles
|
||||
import org.jetbrains.kotlin.gradle.internal.*
|
||||
import org.jetbrains.kotlin.gradle.internal.tasks.TaskConfigurator
|
||||
import org.jetbrains.kotlin.gradle.internal.tasks.TaskWithLocalState
|
||||
@@ -74,10 +76,22 @@ abstract class AbstractKotlinCompileTool<T : CommonToolArguments>
|
||||
CompilerArgumentAwareWithInput<T>,
|
||||
TaskWithLocalState {
|
||||
|
||||
@InputFiles
|
||||
@PathSensitive(PathSensitivity.RELATIVE)
|
||||
@ReplacedBy("stableSources")
|
||||
override fun getSource() = super.getSource()
|
||||
|
||||
@get:InputFiles
|
||||
@get:SkipWhenEmpty
|
||||
@get:IgnoreEmptyDirectories
|
||||
@get:PathSensitive(PathSensitivity.RELATIVE)
|
||||
internal val stableSources: FileCollection = project.files(
|
||||
{ source }
|
||||
)
|
||||
|
||||
@Incremental
|
||||
override fun getClasspath(): FileCollection {
|
||||
return super.getClasspath()
|
||||
}
|
||||
|
||||
@get:Input
|
||||
internal var useFallbackCompilerSearch: Boolean = false
|
||||
|
||||
@@ -278,6 +292,7 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> : AbstractKotl
|
||||
|
||||
@get:InputFiles
|
||||
@get:IgnoreEmptyDirectories
|
||||
@get:Incremental
|
||||
@get:PathSensitive(PathSensitivity.RELATIVE)
|
||||
internal val commonSourceSet: ConfigurableFileCollection = objects.fileCollection()
|
||||
|
||||
@@ -321,7 +336,7 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> : AbstractKotl
|
||||
private val systemPropertiesService = CompilerSystemPropertiesService.registerIfAbsent(project.gradle)
|
||||
|
||||
@TaskAction
|
||||
fun execute(inputs: IncrementalTaskInputs) {
|
||||
fun execute(inputChanges: InputChanges) {
|
||||
metrics.measure(BuildTime.GRADLE_TASK_ACTION) {
|
||||
systemPropertiesService.get().startIntercept()
|
||||
CompilerSystemProperties.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY.value = "true"
|
||||
@@ -330,7 +345,7 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> : AbstractKotl
|
||||
// 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 (isIncrementalCompilationEnabled() && inputs.isIncremental)
|
||||
if (isIncrementalCompilationEnabled() && inputChanges.isIncremental)
|
||||
metrics.measure(BuildTime.BACKUP_OUTPUT) {
|
||||
TaskOutputsBackup(allOutputFiles())
|
||||
}
|
||||
@@ -338,12 +353,12 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> : AbstractKotl
|
||||
|
||||
if (!isIncrementalCompilationEnabled()) {
|
||||
clearLocalState("IC is disabled")
|
||||
} else if (!inputs.isIncremental) {
|
||||
} else if (!inputChanges.isIncremental) {
|
||||
clearLocalState("Task cannot run incrementally")
|
||||
}
|
||||
|
||||
try {
|
||||
executeImpl(inputs)
|
||||
executeImpl(inputChanges)
|
||||
} catch (t: Throwable) {
|
||||
if (outputsBackup != null) {
|
||||
metrics.measure(BuildTime.RESTORE_OUTPUT_FROM_BACKUP) {
|
||||
@@ -360,13 +375,21 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> : AbstractKotl
|
||||
|
||||
private val projectDir = project.rootProject.projectDir
|
||||
|
||||
private fun executeImpl(inputs: IncrementalTaskInputs) {
|
||||
@get:Internal
|
||||
protected open val incrementalProps: List<FileCollection>
|
||||
get() = listOfNotNull(
|
||||
stableSources,
|
||||
classpath,
|
||||
commonSourceSet
|
||||
)
|
||||
|
||||
private fun executeImpl(inputChanges: InputChanges) {
|
||||
val sourceRoots = getSourceRoots()
|
||||
val allKotlinSources = sourceRoots.kotlinSourceFiles
|
||||
|
||||
logger.kotlinDebug { "All kotlin sources: ${allKotlinSources.pathsAsStringRelativeTo(projectDir)}" }
|
||||
|
||||
if (!inputs.isIncremental && skipCondition()) {
|
||||
if (!inputChanges.isIncremental && skipCondition()) {
|
||||
// Skip running only if non-incremental run. Otherwise, we may need to do some cleanup.
|
||||
logger.kotlinDebug { "No Kotlin files found, skipping Kotlin compiler task" }
|
||||
return
|
||||
@@ -375,7 +398,33 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> : AbstractKotl
|
||||
sourceRoots.log(this.name, logger)
|
||||
val args = prepareCompilerArguments()
|
||||
taskBuildDirectory.get().asFile.mkdirs()
|
||||
callCompilerAsync(args, sourceRoots, ChangedFiles(inputs))
|
||||
callCompilerAsync(
|
||||
args,
|
||||
sourceRoots,
|
||||
getChangedFiles(inputChanges, incrementalProps)
|
||||
)
|
||||
}
|
||||
|
||||
protected fun getChangedFiles(
|
||||
inputChanges: InputChanges,
|
||||
incrementalProps: List<FileCollection>
|
||||
) = if (!inputChanges.isIncremental) {
|
||||
ChangedFiles.Unknown()
|
||||
} else {
|
||||
incrementalProps
|
||||
.fold(mutableListOf<File>() to mutableListOf<File>()) { (modified, removed), prop ->
|
||||
inputChanges.getFileChanges(prop).forEach {
|
||||
when (it.changeType) {
|
||||
ChangeType.ADDED, ChangeType.MODIFIED -> modified.add(it.file)
|
||||
ChangeType.REMOVED -> removed.add(it.file)
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
modified to removed
|
||||
}
|
||||
.run {
|
||||
ChangedFiles.Known(first, second)
|
||||
}
|
||||
}
|
||||
|
||||
@Internal
|
||||
@@ -550,6 +599,7 @@ abstract class KotlinCompile @Inject constructor(
|
||||
abstract val useClasspathSnapshot: Property<Boolean>
|
||||
|
||||
@get:Classpath
|
||||
@get:Incremental
|
||||
@get:Optional // Set if useClasspathSnapshot == true
|
||||
abstract val classpathSnapshot: ConfigurableFileCollection
|
||||
|
||||
@@ -614,6 +664,9 @@ abstract class KotlinCompile @Inject constructor(
|
||||
KotlinJvmCompilerArgumentsContributor(KotlinJvmCompilerArgumentsProvider(this))
|
||||
}
|
||||
|
||||
override val incrementalProps: List<FileCollection>
|
||||
get() = super.incrementalProps + listOf(classpathSnapshotProperties.classpathSnapshot)
|
||||
|
||||
override fun getSourceRoots(): SourceRoots.ForJvm = jvmSourceRoots
|
||||
|
||||
override fun callCompilerAsync(args: K2JVMCompilerArguments, sourceRoots: SourceRoots, changedFiles: ChangedFiles) {
|
||||
@@ -941,6 +994,7 @@ abstract class Kotlin2JsCompile @Inject constructor(
|
||||
|
||||
@get:InputFiles
|
||||
@get:IgnoreEmptyDirectories
|
||||
@get:Incremental
|
||||
@get:Optional
|
||||
@get:PathSensitive(PathSensitivity.RELATIVE)
|
||||
internal val friendDependencies: FileCollection = objectFactory
|
||||
@@ -1015,6 +1069,9 @@ abstract class Kotlin2JsCompile @Inject constructor(
|
||||
@get:Internal
|
||||
internal val absolutePathProvider = project.projectDir.absolutePath
|
||||
|
||||
override val incrementalProps: List<FileCollection>
|
||||
get() = super.incrementalProps + listOf(friendDependencies)
|
||||
|
||||
override fun callCompilerAsync(args: K2JSCompilerArguments, sourceRoots: SourceRoots, changedFiles: ChangedFiles) {
|
||||
sourceRoots as SourceRoots.KotlinOnly
|
||||
|
||||
|
||||
-27
@@ -18,15 +18,12 @@ package org.jetbrains.kotlin.gradle.utils
|
||||
|
||||
import org.gradle.api.GradleException
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.file.ArchiveOperations
|
||||
import org.gradle.api.file.CopySpec
|
||||
import org.gradle.api.file.FileSystemOperations
|
||||
import org.gradle.api.file.FileTree
|
||||
import org.gradle.api.internal.project.ProjectInternal
|
||||
import org.gradle.api.internal.tasks.testing.TestDescriptorInternal
|
||||
import org.gradle.api.tasks.TaskInputs
|
||||
import org.gradle.api.tasks.TaskOutputs
|
||||
import org.gradle.api.tasks.WorkResult
|
||||
import org.gradle.api.tasks.bundling.AbstractArchiveTask
|
||||
import org.gradle.api.tasks.testing.TestDescriptor
|
||||
@@ -36,30 +33,6 @@ import java.io.Serializable
|
||||
|
||||
const val minSupportedGradleVersion = "6.1.1"
|
||||
|
||||
internal val Task.inputsCompatible: TaskInputs get() = inputs
|
||||
|
||||
internal val Task.outputsCompatible: TaskOutputs get() = outputs
|
||||
|
||||
private val propertyMethod by lazy {
|
||||
TaskInputs::class.java.methods.first {
|
||||
it.name == "property" && it.parameterTypes.contentEquals(arrayOf(String::class.java, Any::class.java))
|
||||
}
|
||||
}
|
||||
|
||||
internal fun TaskInputs.propertyCompatible(name: String, value: Any) {
|
||||
propertyMethod(this, name, value)
|
||||
}
|
||||
|
||||
private val inputsDirMethod by lazy {
|
||||
TaskInputs::class.java.methods.first {
|
||||
it.name == "dir" && it.parameterTypes.contentEquals(arrayOf(Any::class.java))
|
||||
}
|
||||
}
|
||||
|
||||
internal fun TaskInputs.dirCompatible(dirPath: Any) {
|
||||
inputsDirMethod(this, dirPath)
|
||||
}
|
||||
|
||||
internal fun checkGradleCompatibility(
|
||||
withComponent: String = "the Kotlin Gradle plugin",
|
||||
minSupportedVersion: GradleVersion = GradleVersion.version(minSupportedGradleVersion)
|
||||
|
||||
Reference in New Issue
Block a user