From c85e21d43b6b0d7498d1876bcbfb89b33d34a414 Mon Sep 17 00:00:00 2001 From: Ivan Gavrilovic Date: Tue, 26 Mar 2019 17:31:17 +0000 Subject: [PATCH] Incremental KAPT - pass changed classpath entries Pass computed list of changed classpath names to KAPT instead of relying on the history files to be computed by stub generation. Also, stop generating classpath history changes during the stub generation. This commit does not compute the actual changed classpath entries, and that will be done in the following commits. #KT-23880 --- .../daemon/common/CompilationOptions.kt | 2 - .../kotlin/daemon/CompileServiceImpl.kt | 8 +- .../incremental/IncrementalCompilerRunner.kt | 2 +- .../IncrementalJvmCompilerRunner.kt | 25 +----- .../KaptIncrementalWithAggregatingApt.kt | 12 --- .../gradle/KaptIncrementalWithIsolatingApt.kt | 12 --- .../GradleKotlinCompilerWork.kt | 1 - .../IncrementalCompilationEnvironment.kt | 3 +- .../kapt/Kapt3KotlinGradleSubplugin.kt | 11 +-- .../internal/kapt/KaptGenerateStubsTask.kt | 5 -- .../kotlin/gradle/internal/kapt/KaptTask.kt | 15 ++-- .../internal/kapt/KaptWithKotlincTask.kt | 27 ++++-- .../internal/kapt/KaptWithoutKotlincTask.kt | 19 +++-- .../kotlin/gradle/internal/subpluginUtils.kt | 15 +++- .../jetbrains/kotlin/gradle/tasks/Tasks.kt | 7 +- .../kotlin/kapt3/base/KaptContext.kt | 15 ++-- .../kotlin/kapt3/base/KaptOptions.kt | 11 ++- .../kotlin/kapt3/base/incremental/cache.kt | 85 +++++-------------- .../base/incremental/IncrementalKaptTest.kt | 25 ++---- .../incremental/InheritedAnnotationTest.kt | 2 +- .../incremental/JavaClassCacheManagerTest.kt | 54 ++---------- .../incremental/ReferencedContantsTest.kt | 4 +- .../TestComplexIncrementalAptCache.kt | 4 +- .../TestSimpleIncrementalAptCache.kt | 10 +-- plugins/kapt3/kapt3-cli/src/KaptCliOption.kt | 14 ++- .../org/jetbrains/kotlin/kapt3/Kapt3Plugin.kt | 3 +- 26 files changed, 136 insertions(+), 255 deletions(-) diff --git a/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/CompilationOptions.kt b/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/CompilationOptions.kt index 38505dbf5bc..22a05153ace 100644 --- a/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/CompilationOptions.kt +++ b/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/CompilationOptions.kt @@ -67,7 +67,6 @@ class IncrementalCompilationOptions( val outputFiles: List, val multiModuleICSettings: MultiModuleICSettings, val modulesInfo: IncrementalModuleInfo, - val classpathFqNamesHistory: File? = null, kotlinScriptExtensions: Array? = null ) : CompilationOptions( compilerMode, @@ -91,7 +90,6 @@ class IncrementalCompilationOptions( "multiModuleICSettings=$multiModuleICSettings, " + "usePreciseJavaTracking=$usePreciseJavaTracking" + "outputFiles=$outputFiles" + - "classpathFqNamesHistory=$classpathFqNamesHistory" + ")" } } diff --git a/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt b/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt index 01975583874..bc44d270e42 100644 --- a/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt +++ b/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt @@ -566,18 +566,14 @@ class CompileServiceImpl( } } - val outputFiles = incrementalCompilationOptions.outputFiles.toMutableList() - incrementalCompilationOptions.classpathFqNamesHistory?.let { outputFiles.add(it) } - val compiler = IncrementalJvmCompilerRunner( workingDir, reporter, buildHistoryFile = incrementalCompilationOptions.multiModuleICSettings.buildHistoryFile, - outputFiles = outputFiles, + outputFiles = incrementalCompilationOptions.outputFiles, usePreciseJavaTracking = incrementalCompilationOptions.usePreciseJavaTracking, modulesApiHistory = modulesApiHistory, - kotlinSourceFilesExtensions = allKotlinExtensions, - classpathFqNamesHistory = incrementalCompilationOptions.classpathFqNamesHistory + kotlinSourceFilesExtensions = allKotlinExtensions ) return try { compiler.compile(allKotlinFiles, k2jvmArgs, compilerMessageCollector, changedFiles) diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt index fff8690a757..844c890787f 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt @@ -313,7 +313,7 @@ abstract class IncrementalCompilerRunner< open fun runWithNoDirtyKotlinSources(caches: CacheManager): Boolean = false - protected open fun processChangesAfterBuild( + private fun processChangesAfterBuild( compilationMode: CompilationMode, currentBuildInfo: BuildInfo, dirtyData: DirtyData diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt index 5d7aa0a7825..3f8a5be6b81 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt @@ -109,8 +109,7 @@ class IncrementalJvmCompilerRunner( buildHistoryFile: File, outputFiles: Collection, private val modulesApiHistory: ModulesApiHistory, - override val kotlinSourceFilesExtensions: List = DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS, - private val classpathFqNamesHistory: File? = null + override val kotlinSourceFilesExtensions: List = DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS ) : IncrementalCompilerRunner( workingDir, "caches-jvm", @@ -257,28 +256,6 @@ class IncrementalJvmCompilerRunner( } } - override fun processChangesAfterBuild(compilationMode: CompilationMode, currentBuildInfo: BuildInfo, dirtyData: DirtyData) { - super.processChangesAfterBuild(compilationMode, currentBuildInfo, dirtyData) - - classpathFqNamesHistory ?: return - classpathFqNamesHistory.mkdirs() - - val historyFiles = classpathFqNamesHistory.listFiles() - if (dirtyClasspathChanges.isEmpty() && historyFiles.isNotEmpty()) { - // Don't write an empty file. We check there is at least one file so that downstream task can mark what it has processed. - return - } - - if (historyFiles.size > 10) { - historyFiles.minBy { it.lastModified() }!!.delete() - } - val newHistoryFile = classpathFqNamesHistory.resolve(System.currentTimeMillis().toString()) - ObjectOutputStream(newHistoryFile.outputStream().buffered()).use { - val listOfNames = dirtyClasspathChanges.map { it.toString() }.toList() - it.writeObject(listOfNames) - } - } - override fun postCompilationHook(exitCode: ExitCode) {} override fun updateCaches( diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KaptIncrementalWithAggregatingApt.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KaptIncrementalWithAggregatingApt.kt index dcf1383dfe9..c77a5691b6e 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KaptIncrementalWithAggregatingApt.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KaptIncrementalWithAggregatingApt.kt @@ -35,26 +35,14 @@ class KaptIncrementalWithAggregatingApt : KaptIncrementalIT() { fun testIncrementalChanges() { val project = getProject() - var aptTimestamp = 0L - project.build("clean", "build") { assertSuccessful() - - val classpathHistory = - fileInWorkingDir("build/kotlin/kaptGenerateStubsKotlin/classpath-fq-history").listFiles().asList().single() - val stubsTimestamp = classpathHistory.name.toLong() - - aptTimestamp = fileInWorkingDir("build/tmp/kapt3/incApCache/main/last-build-ts.bin").readText().toLong() - assertTrue(stubsTimestamp < aptTimestamp) } project.projectFile("useB.kt").modify { current -> "$current\nfun otherFunction() {}" } project.build("build") { assertSuccessful() - val newAptTimestamp = fileInWorkingDir("build/tmp/kapt3/incApCache/main/last-build-ts.bin").readText().toLong() - assertTrue(aptTimestamp < newAptTimestamp) - assertEquals( setOf( fileInWorkingDir("build/tmp/kapt3/stubs/main/bar/UseBKt.java").absolutePath, diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KaptIncrementalWithIsolatingApt.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KaptIncrementalWithIsolatingApt.kt index 5a2c29c2c06..4de5eb4d55b 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KaptIncrementalWithIsolatingApt.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KaptIncrementalWithIsolatingApt.kt @@ -38,26 +38,14 @@ class KaptIncrementalWithIsolatingApt : KaptIncrementalIT() { fun testIncrementalChanges() { val project = getProject() - var aptTimestamp = 0L - project.build("clean", "build") { assertSuccessful() - - val classpathHistory = - fileInWorkingDir("build/kotlin/kaptGenerateStubsKotlin/classpath-fq-history").listFiles().asList().single() - val stubsTimestamp = classpathHistory.name.toLong() - - aptTimestamp = fileInWorkingDir("build/tmp/kapt3/incApCache/main/last-build-ts.bin").readText().toLong() - assertTrue(stubsTimestamp < aptTimestamp) } project.projectFile("useB.kt").modify { current -> "$current\nfun otherFunction() {}" } project.build("build") { assertSuccessful() - val newAptTimestamp = fileInWorkingDir("build/tmp/kapt3/incApCache/main/last-build-ts.bin").readText().toLong() - assertTrue(aptTimestamp < newAptTimestamp) - assertEquals(setOf(fileInWorkingDir("build/tmp/kapt3/stubs/main/bar/UseBKt.java").absolutePath), getProcessedSources(output)) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt index faa377bc950..12f003d6ed7 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt @@ -268,7 +268,6 @@ internal class GradleKotlinCompilerWork @Inject constructor( outputFiles = outputFiles, multiModuleICSettings = icEnv.multiModuleICSettings, modulesInfo = incrementalModuleInfo!!, - classpathFqNamesHistory = icEnv.classpathFqNamesHistory, kotlinScriptExtensions = kotlinScriptExtensions ) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/IncrementalCompilationEnvironment.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/IncrementalCompilationEnvironment.kt index 525ff7e3ab1..c1a9df5a0e7 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/IncrementalCompilationEnvironment.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/IncrementalCompilationEnvironment.kt @@ -15,8 +15,7 @@ internal class IncrementalCompilationEnvironment( val workingDir: File, val usePreciseJavaTracking: Boolean = false, val disableMultiModuleIC: Boolean = false, - val multiModuleICSettings: MultiModuleICSettings, - val classpathFqNamesHistory: File? = null + val multiModuleICSettings: MultiModuleICSettings ) : Serializable { companion object { const val serialVersionUID: Long = 0 diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/Kapt3KotlinGradleSubplugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/Kapt3KotlinGradleSubplugin.kt index e466a9df50f..7d1bf84c6ad 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/Kapt3KotlinGradleSubplugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/Kapt3KotlinGradleSubplugin.kt @@ -234,9 +234,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin { ) val kaptGenerateStubsTask = context.createKaptGenerateStubsTask() - val kaptTask = context.createKaptKotlinTask( - useWorkerApi = project.isUseWorkerApi(), - classpathHistoryDir = kaptGenerateStubsTask.getClasspathFqNamesHistoryDir()) + val kaptTask = context.createKaptKotlinTask(useWorkerApi = project.isUseWorkerApi()) kaptGenerateStubsTask.source(*kaptConfigurations.toTypedArray()) @@ -374,7 +372,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin { } } - private fun Kapt3SubpluginContext.createKaptKotlinTask(useWorkerApi: Boolean, classpathHistoryDir: File? = null): KaptTask { + private fun Kapt3SubpluginContext.createKaptKotlinTask(useWorkerApi: Boolean): KaptTask { val taskClass = if (useWorkerApi) KaptWithoutKotlincTask::class.java else KaptWithKotlincTask::class.java val kaptTask = project.tasks.create(getKaptTaskName("kapt"), taskClass) @@ -391,7 +389,6 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin { kaptTask.isIncremental = project.isIncrementalKapt() if (kaptTask.isIncremental) { kaptTask.incAptCache = getKaptIncrementalAnnotationProcessingCache() - kaptTask.classpathDirtyFqNamesHistoryDir = project.files(classpathHistoryDir) } kotlinCompilation?.run { @@ -422,10 +419,6 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin { kaptTask.pluginOptions.addPluginArgument( getCompilerPluginId(), SubpluginOption("incrementalCache", kaptTask.incAptCache!!.absolutePath)) - - kaptTask.pluginOptions.addPluginArgument( - getCompilerPluginId(), - SubpluginOption("classpathFqNamesHistory", kaptTask.classpathDirtyFqNamesHistoryDir.singleFile!!.absolutePath)) } buildAndAddOptionsTo(kaptTask, kaptTask.pluginOptions, aptMode = "apt") diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptGenerateStubsTask.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptGenerateStubsTask.kt index 2b0dd2917fe..2d9ce8ebb09 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptGenerateStubsTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptGenerateStubsTask.kt @@ -74,11 +74,6 @@ open class KaptGenerateStubsTask : KotlinCompile() { super.setSource(sourceRootsContainer.set(sources)) } - @Internal - override fun getClasspathFqNamesHistoryDir(): File? { - return taskBuildDirectory.resolve("classpath-fq-history") - } - private fun isSourceRootAllowed(source: File): Boolean = !destinationDir.isParentOf(source) && !stubsDir.isParentOf(source) && diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptTask.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptTask.kt index 3ed7c9a35bc..51b4a67e3e6 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptTask.kt @@ -67,9 +67,6 @@ abstract class KaptTask : ConventionTask(), TaskWithLocalState { @get:Input internal var includeCompileClasspath: Boolean = true - @get:InputFiles - internal var classpathDirtyFqNamesHistoryDir: FileCollection = project.files() - @get:Input internal var isIncremental = true @@ -160,15 +157,21 @@ abstract class KaptTask : ConventionTask(), TaskWithLocalState { protected fun getCompiledSources() = listOfNotNull(kotlinCompileTask.destinationDir, kotlinCompileTask.javaOutputDir) protected fun getChangedFiles(inputs: IncrementalTaskInputs): List { - return if (!isIncremental || !inputs.isIncremental || !getCompiledSources().all { it.exists() }) { + if (!isIncremental || !inputs.isIncremental || !getCompiledSources().all { it.exists() }) { clearLocalState() - emptyList() + return emptyList() } else { - with(mutableSetOf()) { + val changes = with(mutableSetOf()) { inputs.outOfDate { this.add(it.file) } inputs.removed { this.add(it.file) } return@with this.toList() } + + return if (changes.all { it.extension == "java" }) { + changes + } else { + emptyList() + } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptWithKotlincTask.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptWithKotlincTask.kt index 705cf091e5e..a54c7716e8d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptWithKotlincTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptWithKotlincTask.kt @@ -16,17 +16,13 @@ import org.gradle.api.tasks.incremental.IncrementalTaskInputs import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments import org.jetbrains.kotlin.compilerRunner.GradleCompilerEnvironment import org.jetbrains.kotlin.compilerRunner.GradleCompilerRunner -import org.jetbrains.kotlin.compilerRunner.IncrementalCompilationEnvironment -import org.jetbrains.kotlin.gradle.logging.GradleKotlinLogger import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl -import org.jetbrains.kotlin.gradle.incremental.ChangedFiles import org.jetbrains.kotlin.gradle.internal.tasks.allOutputFiles +import org.jetbrains.kotlin.gradle.logging.GradleKotlinLogger +import org.jetbrains.kotlin.gradle.logging.GradlePrintingMessageCollector import org.jetbrains.kotlin.gradle.plugin.PLUGIN_CLASSPATH_CONFIGURATION_NAME import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions -import org.jetbrains.kotlin.gradle.logging.GradlePrintingMessageCollector -import org.jetbrains.kotlin.gradle.tasks.clearLocalState import org.jetbrains.kotlin.gradle.utils.toSortedPathsArray -import org.jetbrains.kotlin.incremental.ChangedFiles import java.io.File open class KaptWithKotlincTask : KaptTask(), CompilerArgumentAwareWithInput { @@ -54,7 +50,10 @@ open class KaptWithKotlincTask : KaptTask(), CompilerArgumentAwareWithInput = emptyList() + private var classpathChanges: List = emptyList() + private var processIncrementally = false @TaskAction fun compile(inputs: IncrementalTaskInputs) { logger.debug("Running kapt annotation processing using the Kotlin compiler") checkAnnotationProcessorClasspath() - changedFiles = getChangedFiles(inputs) + val incrementalChanges = getChangedFiles(inputs) + when { + incrementalChanges.isNotEmpty() -> { + changedFiles = incrementalChanges + classpathChanges = emptyList() + processIncrementally = true + } + else -> { + // do nothing + } + } val args = prepareCompilerArguments() diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptWithoutKotlincTask.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptWithoutKotlincTask.kt index 435f0e9fd57..4416ede8905 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptWithoutKotlincTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptWithoutKotlincTask.kt @@ -12,10 +12,8 @@ import org.gradle.api.tasks.TaskAction import org.gradle.api.tasks.incremental.IncrementalTaskInputs import org.gradle.workers.IsolationMode import org.gradle.workers.WorkerExecutor -import org.jetbrains.kotlin.gradle.incremental.ChangedFiles import org.jetbrains.kotlin.gradle.internal.Kapt3KotlinGradleSubplugin.Companion.KAPT_WORKER_DEPENDENCIES_CONFIGURATION_NAME import org.jetbrains.kotlin.gradle.plugin.KotlinAndroidPluginWrapper -import org.jetbrains.kotlin.gradle.tasks.clearLocalState import org.jetbrains.kotlin.gradle.tasks.findKotlinStdlibClasspath import org.jetbrains.kotlin.gradle.tasks.findToolsJar import org.jetbrains.kotlin.utils.PathUtil @@ -52,6 +50,8 @@ open class KaptWithoutKotlincTask @Inject constructor(private val workerExecutor logger.info("Running kapt annotation processing using the Gradle Worker API") checkAnnotationProcessorClasspath() + val incrementalChanges = getChangedFiles(inputs) + val compileClasspath = classpath.files.toMutableList() if (project.plugins.none { it is KotlinAndroidPluginWrapper }) { compileClasspath.addAll(0, PathUtil.getJdkClassesRootsFromCurrentJre()) @@ -68,10 +68,11 @@ open class KaptWithoutKotlincTask @Inject constructor(private val workerExecutor compileClasspath, javaSourceRoots.toList(), - getChangedFiles(inputs), + incrementalChanges, getCompiledSources(), incAptCache, - classpathDirtyFqNamesHistoryDir.singleOrNull(), + emptyList(), + incrementalChanges.isNotEmpty(), destinationDir, classesDir, @@ -94,7 +95,7 @@ open class KaptWithoutKotlincTask @Inject constructor(private val workerExecutor workerExecutor.submit(KaptExecution::class.java) { config -> val isolationModeStr = project.findProperty("kapt.workers.isolation") as String? ?: "none" - config.isolationMode = when(isolationModeStr.toLowerCase()) { + config.isolationMode = when (isolationModeStr.toLowerCase()) { "process" -> IsolationMode.PROCESS "none" -> IsolationMode.NONE else -> IsolationMode.NONE @@ -148,7 +149,7 @@ private class KaptExecution @Inject constructor( } } - private fun createKaptOptions(classLoader: ClassLoader) = with (optionsForWorker) { + private fun createKaptOptions(classLoader: ClassLoader) = with(optionsForWorker) { val flags = kaptClass(classLoader).declaredMethods.single { it.name == "kaptFlags" }.invoke(null, flags) val mode = Class.forName("org.jetbrains.kotlin.base.kapt3.AptMode", true, classLoader) @@ -165,7 +166,8 @@ private class KaptExecution @Inject constructor( changedFiles, compiledSources, incAptCache, - classpathFqNamesHistory, + classpathChanges, + processIncrementally, sourcesOutputDir, classesOutputDir, @@ -201,7 +203,8 @@ private data class KaptOptionsForWorker( val changedFiles: List, val compiledSources: List, val incAptCache: File?, - val classpathFqNamesHistory: File?, + val classpathChanges: List, + val processIncrementally: Boolean, val sourcesOutputDir: File, val classesOutputDir: File, diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/subpluginUtils.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/subpluginUtils.kt index d1fd3df9d2f..178b888117b 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/subpluginUtils.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/subpluginUtils.kt @@ -44,13 +44,22 @@ fun encodePluginOptions(options: Map>): String { } internal fun CompilerPluginOptions.withWrappedKaptOptions( - withApClasspath: Iterable, changedFiles: List = emptyList(), compiledSourcesDir: List = emptyList() + withApClasspath: Iterable, + changedFiles: List = emptyList(), + classpathChanges: List = emptyList(), + compiledSourcesDir: List = emptyList(), + processIncrementally: Boolean = false ): CompilerPluginOptions { val resultOptionsByPluginId: MutableMap> = subpluginOptionsByPluginId.toMutableMap() resultOptionsByPluginId.compute(Kapt3KotlinGradleSubplugin.KAPT_SUBPLUGIN_ID) { _, kaptOptions -> val changedFilesOption = FilesSubpluginOption("changedFile", changedFiles).takeIf { changedFiles.isNotEmpty() } + val classpathChangesOption = SubpluginOption( + "classpathChange", + classpathChanges.joinToString(separator = File.pathSeparator) + ).takeIf { classpathChanges.isNotEmpty() } + val processIncrementallyOption = SubpluginOption("processIncrementally", processIncrementally.toString()) val compiledSourcesOption = FilesSubpluginOption("compiledSourcesDir", compiledSourcesDir).takeIf { compiledSourcesDir.isNotEmpty() } @@ -58,7 +67,9 @@ internal fun CompilerPluginOptions.withWrappedKaptOptions( kaptOptions.orEmpty() + withApClasspath.map { FilesSubpluginOption("apclasspath", listOf(it)) } + changedFilesOption + - compiledSourcesOption + classpathChangesOption + + compiledSourcesOption + + processIncrementallyOption wrapPluginOptions(kaptOptionsWithClasspath.filterNotNull(), "configuration") } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt index a2c71356b88..4c11bd42703 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt @@ -435,8 +435,7 @@ open class KotlinCompile : AbstractKotlinCompile(), Kotl taskBuildDirectory, usePreciseJavaTracking = usePreciseJavaTracking, disableMultiModuleIC = disableMultiModuleIC(), - multiModuleICSettings = multiModuleICSettings, - classpathFqNamesHistory = getClasspathFqNamesHistoryDir() + multiModuleICSettings = multiModuleICSettings ) } else null @@ -479,10 +478,6 @@ open class KotlinCompile : AbstractKotlinCompile(), Kotl return false } - @Optional - @Internal - internal open fun getClasspathFqNamesHistoryDir(): File? = null - // override setSource to track source directory sets and files (for generated android folders) override fun setSource(sources: Any?) { sourceRootsContainer.set(sources) diff --git a/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/KaptContext.kt b/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/KaptContext.kt index 7d602713f86..12acf415acc 100644 --- a/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/KaptContext.kt +++ b/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/KaptContext.kt @@ -57,11 +57,16 @@ open class KaptContext(val options: KaptOptions, val withJdk: Boolean, val logge KaptJavaCompiler.preRegister(context) cacheManager = options.incrementalCache?.let { - JavaClassCacheManager(it, options.classpathFqNamesHistory!!) + JavaClassCacheManager(it) + } + if (options.processIncrementally) { + sourcesToReprocess = + cacheManager?.invalidateAndGetDirtyFiles( + options.changedFiles, options.classpathChanges + ) ?: SourcesToReprocess.FullRebuild + } else { + sourcesToReprocess = SourcesToReprocess.FullRebuild } - sourcesToReprocess = cacheManager?.invalidateAndGetDirtyFiles( - options.changedFiles.filter { it.extension == "java" } - ) ?: SourcesToReprocess.FullRebuild javacOptions = Options.instance(context).apply { for ((key, value) in options.processingOptions) { @@ -88,7 +93,7 @@ open class KaptContext(val options: KaptOptions, val withJdk: Boolean, val logge put("accessInternalAPI", "true") } - val compileClasspath = if (sourcesToReprocess is SourcesToReprocess.FullRebuild || options.changedFiles.isEmpty()) { + val compileClasspath = if (sourcesToReprocess is SourcesToReprocess.FullRebuild) { options.compileClasspath } else { options.compileClasspath + options.compiledSources diff --git a/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/KaptOptions.kt b/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/KaptOptions.kt index e12ce239527..d7427ce36b7 100644 --- a/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/KaptOptions.kt +++ b/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/KaptOptions.kt @@ -17,7 +17,8 @@ class KaptOptions( val changedFiles: List, val compiledSources: List, val incrementalCache: File?, - val classpathFqNamesHistory: File?, + val classpathChanges: List, + val processIncrementally: Boolean, val sourcesOutputDir: File, val classesOutputDir: File, @@ -45,12 +46,13 @@ class KaptOptions( val changedFiles: MutableList = mutableListOf() val compiledSources: MutableList = mutableListOf() var incrementalCache: File? = null - var classpathFqNamesHistory: File? = null + val classpathChanges: MutableList = mutableListOf() var sourcesOutputDir: File? = null var classesOutputDir: File? = null var stubsOutputDir: File? = null var incrementalDataOutputDir: File? = null + var processIncrementally: Boolean = false val processingClasspath: MutableList = mutableListOf() val processors: MutableList = mutableListOf() @@ -73,7 +75,7 @@ class KaptOptions( return KaptOptions( projectBaseDir, compileClasspath, javaSourceRoots, - changedFiles, compiledSources, incrementalCache, classpathFqNamesHistory, + changedFiles, compiledSources, incrementalCache, classpathChanges, processIncrementally, sourcesOutputDir, classesOutputDir, stubsOutputDir, incrementalDataOutputDir, processingClasspath, processors, processingOptions, javacOptions, KaptFlags.fromSet(flags), mode, detectMemoryLeaks @@ -169,5 +171,6 @@ fun KaptOptions.logString(additionalInfo: String = "") = buildString { appendln("[incremental apt] Changed files: $changedFiles") appendln("[incremental apt] Compiled sources directories: ${compiledSources.joinToString()}") appendln("[incremental apt] Cache directory for incremental compilation: $incrementalCache") - appendln("[incremental apt] Classpath fq names history dir: $classpathFqNamesHistory") + appendln("[incremental apt] Changes classpath names: ${classpathChanges.joinToString()}") + appendln("[incremental apt] If processing incrementally: $processIncrementally") } \ No newline at end of file diff --git a/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/incremental/cache.kt b/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/incremental/cache.kt index e427480e047..5885d9ae17e 100644 --- a/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/incremental/cache.kt +++ b/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/incremental/cache.kt @@ -8,7 +8,7 @@ package org.jetbrains.kotlin.kapt3.base.incremental import java.io.* // TODO(gavra): switch away from Java serialization -class JavaClassCacheManager(val file: File, private val classpathFqNamesHistory: File) : Closeable { +class JavaClassCacheManager(val file: File) : Closeable { private val javaCacheFile = file.resolve("java-cache.bin") internal val javaCache = maybeGetJavaCacheFromFile() @@ -16,38 +16,8 @@ class JavaClassCacheManager(val file: File, private val classpathFqNamesHistory: private val aptCacheFile = file.resolve("apt-cache.bin") private val aptCache = maybeGetAptCacheFromFile() - private val lastBuildTimestamp = file.resolve("last-build-ts.bin") - private var closed = false - private fun getDirtyFqNamesFromClasspath(): ClasspathChanged { - if (!lastBuildTimestamp.exists()) return ClasspathChanged.FullRebuild - - val lastTimestamp = lastBuildTimestamp.readText() - - val (before, after) = classpathFqNamesHistory.listFiles().partition { it.name < lastTimestamp } - - if (before.isEmpty()) { - return ClasspathChanged.FullRebuild - } - - val dirtyFqNames = mutableSetOf() - after.forEach { file -> - ObjectInputStream(file.inputStream().buffered()).use { - @Suppress("UNCHECKED_CAST") - dirtyFqNames.addAll(it.readObject() as Collection) - } - } - - return if (dirtyFqNames.isNotEmpty()) { - // TODO(gavra): We need to handle constants from classpath that might change between runs being incremental. One solution - // would be to fetch the changed symbols alongside changed fqNames, and to check if the symbol is a constant using ASM. - ClasspathChanged.FullRebuild - } else { - ClasspathChanged.Incremental(dirtyFqNames) - } - } - fun updateCache(processors: List) { if (!aptCache.updateCache(processors)) { javaCache.invalidateAll() @@ -58,39 +28,38 @@ class JavaClassCacheManager(val file: File, private val classpathFqNamesHistory: * From set of changed sources, get list of files to recompile using structural information and dependency information from * annotation processing. */ - fun invalidateAndGetDirtyFiles(changedSources: Collection): SourcesToReprocess { + fun invalidateAndGetDirtyFiles(changedSources: Collection, dirtyClasspathJvmNames: Collection): SourcesToReprocess { if (!aptCache.isIncremental) { return SourcesToReprocess.FullRebuild } - val dirtyFqNamesFromClasspath = getDirtyFqNamesFromClasspath() - return when (dirtyFqNamesFromClasspath) { - is ClasspathChanged.FullRebuild -> SourcesToReprocess.FullRebuild - is ClasspathChanged.Incremental -> { - val changes = Changes(changedSources, dirtyFqNamesFromClasspath.dirtyFqNames) - val filesToReprocess = javaCache.invalidateEntriesForChangedFiles(changes) + val dirtyClasspathFqNames = HashSet(dirtyClasspathJvmNames.size) + dirtyClasspathJvmNames.forEach { + dirtyClasspathFqNames.add(it.replace("$", ".").replace("/", ".")) + } - when (filesToReprocess) { - is SourcesToReprocess.FullRebuild -> SourcesToReprocess.FullRebuild - is SourcesToReprocess.Incremental -> { - val toReprocess = filesToReprocess.toReprocess.toMutableSet() + val changes = Changes(changedSources, dirtyClasspathFqNames.toSet()) + val filesToReprocess = javaCache.invalidateEntriesForChangedFiles(changes) - val isolatingGenerated = aptCache.invalidateIsolatingGenerated(toReprocess) - val generatedDirtyTypes = javaCache.invalidateGeneratedTypes(isolatingGenerated).toMutableSet() + return when (filesToReprocess) { + is SourcesToReprocess.FullRebuild -> SourcesToReprocess.FullRebuild + is SourcesToReprocess.Incremental -> { + val toReprocess = filesToReprocess.toReprocess.toMutableSet() - if (!toReprocess.isEmpty()) { - // only if there are some files to reprocess we should invalidate the aggregating ones - val aggregatingGenerated = aptCache.invalidateAggregating() - generatedDirtyTypes.addAll(javaCache.invalidateGeneratedTypes(aggregatingGenerated)) + val isolatingGenerated = aptCache.invalidateIsolatingGenerated(toReprocess) + val generatedDirtyTypes = javaCache.invalidateGeneratedTypes(isolatingGenerated).toMutableSet() - toReprocess.addAll( - javaCache.invalidateEntriesAnnotatedWith(aptCache.getAggregatingClaimedAnnotations()) - ) - } + if (!toReprocess.isEmpty()) { + // only if there are some files to reprocess we should invalidate the aggregating ones + val aggregatingGenerated = aptCache.invalidateAggregating() + generatedDirtyTypes.addAll(javaCache.invalidateGeneratedTypes(aggregatingGenerated)) - SourcesToReprocess.Incremental(toReprocess.toList(), generatedDirtyTypes) - } + toReprocess.addAll( + javaCache.invalidateEntriesAnnotatedWith(aptCache.getAggregatingClaimedAnnotations()) + ) } + + SourcesToReprocess.Incremental(toReprocess.toList(), generatedDirtyTypes) } } } @@ -144,9 +113,6 @@ class JavaClassCacheManager(val file: File, private val classpathFqNamesHistory: } } - with(lastBuildTimestamp) { - writeText(System.currentTimeMillis().toString()) - } closed = true } } @@ -154,9 +120,4 @@ class JavaClassCacheManager(val file: File, private val classpathFqNamesHistory: sealed class SourcesToReprocess { class Incremental(val toReprocess: List, val dirtyTypes: Set) : SourcesToReprocess() object FullRebuild : SourcesToReprocess() -} - -sealed class ClasspathChanged { - class Incremental(val dirtyFqNames: Set) : ClasspathChanged() - object FullRebuild : ClasspathChanged() } \ No newline at end of file diff --git a/plugins/kapt3/kapt3-base/test/org/jetbrains/kotlin/kapt3/base/incremental/IncrementalKaptTest.kt b/plugins/kapt3/kapt3-base/test/org/jetbrains/kotlin/kapt3/base/incremental/IncrementalKaptTest.kt index f9c4e44930d..106d6430d49 100644 --- a/plugins/kapt3/kapt3-base/test/org/jetbrains/kotlin/kapt3/base/incremental/IncrementalKaptTest.kt +++ b/plugins/kapt3/kapt3-base/test/org/jetbrains/kotlin/kapt3/base/incremental/IncrementalKaptTest.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.base.kapt3.KaptOptions import org.jetbrains.kotlin.base.kapt3.collectJavaSourceFiles import org.jetbrains.kotlin.kapt3.base.KaptContext import org.jetbrains.kotlin.kapt3.base.doAnnotationProcessing +import org.jetbrains.kotlin.kapt3.base.incremental.SourcesToReprocess import org.jetbrains.kotlin.kapt3.base.util.WriterBackedKaptLogger import org.junit.Assert.* import org.junit.Rule @@ -32,9 +33,6 @@ class IncrementalKaptTest { val outputDir = tmp.newFolder() val incrementalCacheDir = tmp.newFolder() - val classpathHistory = tmp.newFolder().also { - it.resolve("0").createNewFile() - } val options = KaptOptions.Builder().apply { projectBaseDir = tmp.newFolder() javaSourceRoots.add(sourcesDir) @@ -45,14 +43,12 @@ class IncrementalKaptTest { incrementalDataOutputDir = outputDir incrementalCache = incrementalCacheDir - classpathFqNamesHistory = classpathHistory }.build() val logger = WriterBackedKaptLogger(isVerbose = true) KaptContext(options, true, logger).use { - val toReprocess = it.cacheManager!!.invalidateAndGetDirtyFiles(options.changedFiles) it.doAnnotationProcessing( - options.collectJavaSourceFiles(toReprocess), listOf(SimpleProcessor().toIsolating()) + options.collectJavaSourceFiles(SourcesToReprocess.FullRebuild), listOf(SimpleProcessor().toIsolating()) ) } @@ -72,14 +68,14 @@ class IncrementalKaptTest { incrementalDataOutputDir = outputDir incrementalCache = incrementalCacheDir - classpathFqNamesHistory = classpathHistory compiledSources.add(classesOutput) changedFiles.add(sourcesDir.resolve("User.java")) + processIncrementally = true }.build() KaptContext(optionsForSecondRun, true, logger).use { val sourcesToReprocess = - it.cacheManager!!.invalidateAndGetDirtyFiles(optionsForSecondRun.changedFiles) + it.cacheManager!!.invalidateAndGetDirtyFiles(optionsForSecondRun.changedFiles, emptyList()) assertFalse(outputDir.resolve("test/UserGenerated.java").exists()) it.doAnnotationProcessing( @@ -92,7 +88,7 @@ class IncrementalKaptTest { sourcesDir.resolve("User.java").delete() KaptContext(optionsForSecondRun, true, logger).use { - val sourcesToReprocess = it.cacheManager!!.invalidateAndGetDirtyFiles(optionsForSecondRun.changedFiles) + val sourcesToReprocess = it.cacheManager!!.invalidateAndGetDirtyFiles(optionsForSecondRun.changedFiles, emptyList()) it.doAnnotationProcessing( optionsForSecondRun.collectJavaSourceFiles(sourcesToReprocess), listOf(SimpleProcessor().toIsolating()) @@ -114,9 +110,6 @@ class IncrementalKaptTest { val outputDir = tmp.newFolder() val incrementalCacheDir = tmp.newFolder() - val classpathHistory = tmp.newFolder().also { - it.resolve("0").createNewFile() - } val options = KaptOptions.Builder().apply { projectBaseDir = tmp.newFolder() javaSourceRoots.add(sourcesDir) @@ -127,14 +120,12 @@ class IncrementalKaptTest { incrementalDataOutputDir = outputDir incrementalCache = incrementalCacheDir - classpathFqNamesHistory = classpathHistory }.build() val logger = WriterBackedKaptLogger(isVerbose = true) KaptContext(options, true, logger).use { - val toReprocess = it.cacheManager!!.invalidateAndGetDirtyFiles(options.changedFiles) it.doAnnotationProcessing( - options.collectJavaSourceFiles(toReprocess), listOf(SimpleGeneratingIfTypeDoesNotExist().toIsolating()) + options.collectJavaSourceFiles(SourcesToReprocess.FullRebuild), listOf(SimpleGeneratingIfTypeDoesNotExist().toIsolating()) ) } @@ -151,14 +142,14 @@ class IncrementalKaptTest { incrementalDataOutputDir = outputDir incrementalCache = incrementalCacheDir - classpathFqNamesHistory = classpathHistory compiledSources.add(classesOutput) changedFiles.add(sourcesDir.resolve("User.java")) + processIncrementally = true }.build() KaptContext(optionsForSecondRun, true, logger).use { val sourcesToReprocess = - it.cacheManager!!.invalidateAndGetDirtyFiles(optionsForSecondRun.changedFiles) + it.cacheManager!!.invalidateAndGetDirtyFiles(optionsForSecondRun.changedFiles, emptyList()) assertFalse(outputDir.resolve("test/UserGenerated.java").exists()) it.doAnnotationProcessing( diff --git a/plugins/kapt3/kapt3-base/test/org/jetbrains/kotlin/kapt3/base/incremental/InheritedAnnotationTest.kt b/plugins/kapt3/kapt3-base/test/org/jetbrains/kotlin/kapt3/base/incremental/InheritedAnnotationTest.kt index 0676c901192..2db745e9a36 100644 --- a/plugins/kapt3/kapt3-base/test/org/jetbrains/kotlin/kapt3/base/incremental/InheritedAnnotationTest.kt +++ b/plugins/kapt3/kapt3-base/test/org/jetbrains/kotlin/kapt3/base/incremental/InheritedAnnotationTest.kt @@ -30,7 +30,7 @@ class TestInheritedAnnotation { @BeforeClass fun setUp() { val classpathHistory = tmp.newFolder() - cache = JavaClassCacheManager(tmp.newFolder(), classpathHistory) + cache = JavaClassCacheManager(tmp.newFolder()) generatedSources = tmp.newFolder() cache.close() classpathHistory.resolve("0").createNewFile() diff --git a/plugins/kapt3/kapt3-base/test/org/jetbrains/kotlin/kapt3/base/incremental/JavaClassCacheManagerTest.kt b/plugins/kapt3/kapt3-base/test/org/jetbrains/kotlin/kapt3/base/incremental/JavaClassCacheManagerTest.kt index b9e75828d99..3fa987dbb51 100644 --- a/plugins/kapt3/kapt3-base/test/org/jetbrains/kotlin/kapt3/base/incremental/JavaClassCacheManagerTest.kt +++ b/plugins/kapt3/kapt3-base/test/org/jetbrains/kotlin/kapt3/base/incremental/JavaClassCacheManagerTest.kt @@ -22,13 +22,11 @@ class JavaClassCacheManagerTest { private lateinit var cache: JavaClassCacheManager private lateinit var cacheDir: File - private lateinit var classpathHistory: File @Before fun setUp() { cacheDir = tmp.newFolder() - classpathHistory = tmp.newFolder() - cache = JavaClassCacheManager(cacheDir, classpathHistory) + cache = JavaClassCacheManager(cacheDir) } @@ -38,7 +36,6 @@ class JavaClassCacheManagerTest { assertTrue(cacheDir.resolve("java-cache.bin").exists()) assertTrue(cacheDir.resolve("apt-cache.bin").exists()) - assertTrue(cacheDir.resolve("last-build-ts.bin").exists()) } @Test @@ -59,7 +56,7 @@ class JavaClassCacheManagerTest { } prepareForIncremental() - val dirtyFiles = cache.invalidateAndGetDirtyFiles(listOf(File("Mentioned.java"))) as SourcesToReprocess.Incremental + val dirtyFiles = cache.invalidateAndGetDirtyFiles(listOf(File("Mentioned.java")), emptyList()) as SourcesToReprocess.Incremental assertEquals( listOf( File("Mentioned.java").absoluteFile, @@ -87,7 +84,7 @@ class JavaClassCacheManagerTest { } prepareForIncremental() - val dirtyFiles = cache.invalidateAndGetDirtyFiles(listOf(File("Mentioned.java"))) as SourcesToReprocess.Incremental + val dirtyFiles = cache.invalidateAndGetDirtyFiles(listOf(File("Mentioned.java")), emptyList()) as SourcesToReprocess.Incremental assertEquals( listOf( File("Mentioned.java").absoluteFile, @@ -115,7 +112,7 @@ class JavaClassCacheManagerTest { } prepareForIncremental() - val dirtyFiles = cache.invalidateAndGetDirtyFiles(listOf(File("TwoTypes.java"))) as SourcesToReprocess.Incremental + val dirtyFiles = cache.invalidateAndGetDirtyFiles(listOf(File("TwoTypes.java")), emptyList()) as SourcesToReprocess.Incremental assertEquals( listOf( File("TwoTypes.java").absoluteFile, @@ -126,48 +123,16 @@ class JavaClassCacheManagerTest { } @Test - fun testNoClasspathHistory() { - SourceFileStructure(File("Src.java").toURI()).also { - it.addDeclaredType("test.Src") - cache.javaCache.addSourceStructure(it) - } - cache.close() - classpathHistory.resolve(Long.MAX_VALUE.toString()).createNewFile() - - val dirtyFiles = cache.invalidateAndGetDirtyFiles(listOf()) - assertEquals(SourcesToReprocess.FullRebuild, dirtyFiles) - } - - @Test - fun testWithClasspathHistoryButNoNewChanges() { + fun testWithClasspathChanges() { SourceFileStructure(File("Src.java").toURI()).also { it.addDeclaredType("test.Src") it.addMentionedType("test.Mentioned") cache.javaCache.addSourceStructure(it) } prepareForIncremental() - ObjectOutputStream(classpathHistory.resolve("0").outputStream()).use { - it.writeObject(listOf("test.Mentioned")) - } - val dirtyFiles = cache.invalidateAndGetDirtyFiles(listOf()) as SourcesToReprocess.Incremental - assertEquals(emptyList(), dirtyFiles.toReprocess) - } - - @Test - fun testWithClasspathHistoryWithChanges() { - SourceFileStructure(File("Src.java").toURI()).also { - it.addDeclaredType("test.Src") - it.addMentionedType("test.Mentioned") - cache.javaCache.addSourceStructure(it) - } - prepareForIncremental() - ObjectOutputStream(classpathHistory.resolve(Long.MAX_VALUE.toString()).outputStream()).use { - it.writeObject(listOf("test.Mentioned")) - } - - val dirtyFiles = cache.invalidateAndGetDirtyFiles(listOf()) - assertEquals(SourcesToReprocess.FullRebuild, dirtyFiles) + val dirtyFiles = cache.invalidateAndGetDirtyFiles(listOf(), listOf("test/Mentioned")) as SourcesToReprocess.Incremental + assertEquals(listOf(File("Src.java").absoluteFile), dirtyFiles.toReprocess) } @Test @@ -187,7 +152,7 @@ class JavaClassCacheManagerTest { } prepareForIncremental() - val dirtyFiles = cache.invalidateAndGetDirtyFiles(listOf(File("Constants.java"))) + val dirtyFiles = cache.invalidateAndGetDirtyFiles(listOf(File("Constants.java")), emptyList()) assertEquals(SourcesToReprocess.FullRebuild, dirtyFiles) } @@ -217,7 +182,6 @@ class JavaClassCacheManagerTest { private fun prepareForIncremental() { cache.close() - classpathHistory.resolve("0").createNewFile() - cache = JavaClassCacheManager(cacheDir, classpathHistory) + cache = JavaClassCacheManager(cacheDir) } } diff --git a/plugins/kapt3/kapt3-base/test/org/jetbrains/kotlin/kapt3/base/incremental/ReferencedContantsTest.kt b/plugins/kapt3/kapt3-base/test/org/jetbrains/kotlin/kapt3/base/incremental/ReferencedContantsTest.kt index 418f52b8d42..494d09e612a 100644 --- a/plugins/kapt3/kapt3-base/test/org/jetbrains/kotlin/kapt3/base/incremental/ReferencedContantsTest.kt +++ b/plugins/kapt3/kapt3-base/test/org/jetbrains/kotlin/kapt3/base/incremental/ReferencedContantsTest.kt @@ -32,11 +32,9 @@ class ReferencedConstantsTest { val compiledClasses = tmp.newFolder() compileSources(listOf(MY_TEST_DIR.resolve("CKlass.java")), compiledClasses) - val classpathHistory = tmp.newFolder() - cache = JavaClassCacheManager(tmp.newFolder(), classpathHistory) + cache = JavaClassCacheManager(tmp.newFolder()) generatedSources = tmp.newFolder() cache.close() - classpathHistory.resolve("0").createNewFile() val processor = SimpleProcessor().toAggregating() val srcFiles = listOf( "A.java", diff --git a/plugins/kapt3/kapt3-base/test/org/jetbrains/kotlin/kapt3/base/incremental/TestComplexIncrementalAptCache.kt b/plugins/kapt3/kapt3-base/test/org/jetbrains/kotlin/kapt3/base/incremental/TestComplexIncrementalAptCache.kt index 9540b3d9308..c6142069ff1 100644 --- a/plugins/kapt3/kapt3-base/test/org/jetbrains/kotlin/kapt3/base/incremental/TestComplexIncrementalAptCache.kt +++ b/plugins/kapt3/kapt3-base/test/org/jetbrains/kotlin/kapt3/base/incremental/TestComplexIncrementalAptCache.kt @@ -29,11 +29,9 @@ class TestComplexIncrementalAptCache { @JvmStatic @BeforeClass fun setUp() { - val classpathHistory = tmp.newFolder() - cache = JavaClassCacheManager(tmp.newFolder(), classpathHistory) + cache = JavaClassCacheManager(tmp.newFolder()) generatedSources = tmp.newFolder() cache.close() - classpathHistory.resolve("0").createNewFile() val processor = SimpleProcessor().toAggregating() val srcFiles = listOf( "MyEnum.java", diff --git a/plugins/kapt3/kapt3-base/test/org/jetbrains/kotlin/kapt3/base/incremental/TestSimpleIncrementalAptCache.kt b/plugins/kapt3/kapt3-base/test/org/jetbrains/kotlin/kapt3/base/incremental/TestSimpleIncrementalAptCache.kt index 72acb9c0f8e..019470bd05f 100644 --- a/plugins/kapt3/kapt3-base/test/org/jetbrains/kotlin/kapt3/base/incremental/TestSimpleIncrementalAptCache.kt +++ b/plugins/kapt3/kapt3-base/test/org/jetbrains/kotlin/kapt3/base/incremental/TestSimpleIncrementalAptCache.kt @@ -27,18 +27,16 @@ class TestSimpleIncrementalAptCache { @Before fun setUp() { - val classpathHistory = tmp.newFolder() - cache = JavaClassCacheManager(tmp.newFolder(), classpathHistory) + cache = JavaClassCacheManager(tmp.newFolder()) generatedSources = tmp.newFolder() cache.close() - classpathHistory.resolve("0").createNewFile() } @Test fun testAggregatingAnnotations() { runProcessor(SimpleProcessor().toAggregating()) - val dirtyFiles = cache.invalidateAndGetDirtyFiles(listOf(TEST_DATA_DIR.resolve("User.java"))) as SourcesToReprocess.Incremental + val dirtyFiles = cache.invalidateAndGetDirtyFiles(listOf(TEST_DATA_DIR.resolve("User.java")), emptyList()) as SourcesToReprocess.Incremental assertEquals( listOf(TEST_DATA_DIR.resolve("User.java").absoluteFile, TEST_DATA_DIR.resolve("Address.java").absoluteFile), dirtyFiles.toReprocess @@ -51,7 +49,7 @@ class TestSimpleIncrementalAptCache { fun testIsolatingAnnotations() { runProcessor(SimpleProcessor().toIsolating()) - val dirtyFiles = cache.invalidateAndGetDirtyFiles(listOf(TEST_DATA_DIR.resolve("User.java"))) as SourcesToReprocess.Incremental + val dirtyFiles = cache.invalidateAndGetDirtyFiles(listOf(TEST_DATA_DIR.resolve("User.java")), emptyList()) as SourcesToReprocess.Incremental assertFalse(generatedSources.resolve("test/UserGenerated.java").exists()) assertEquals( listOf(TEST_DATA_DIR.resolve("User.java").absoluteFile), @@ -63,7 +61,7 @@ class TestSimpleIncrementalAptCache { fun testNonIncremental() { runProcessor(SimpleProcessor().toNonIncremental()) - val dirtyFiles = cache.invalidateAndGetDirtyFiles(listOf(TEST_DATA_DIR.resolve("User.java"))) + val dirtyFiles = cache.invalidateAndGetDirtyFiles(listOf(TEST_DATA_DIR.resolve("User.java")), emptyList()) assertTrue(dirtyFiles is SourcesToReprocess.FullRebuild) } diff --git a/plugins/kapt3/kapt3-cli/src/KaptCliOption.kt b/plugins/kapt3/kapt3-cli/src/KaptCliOption.kt index 628fb854421..9058a13d324 100644 --- a/plugins/kapt3/kapt3-cli/src/KaptCliOption.kt +++ b/plugins/kapt3/kapt3-cli/src/KaptCliOption.kt @@ -90,10 +90,16 @@ enum class KaptCliOption( "Use only in apt mode. Output directory for cache necessary to support incremental annotation processing." ), - CLASSPATH_FQ_NAMES_HISTORY( - "classpathFqNamesHistory", - "", - "Use only in apt mode. Directory containing history of classpath fq name changes." + CLASSPATH_CHANGES( + "classpathChange", + "", + "Use only in apt mode. Classpath jvm internal names that changed." + ), + + PROCESS_INCREMENTALLY( + "processIncrementally", + "boolean", + "Use only in apt mode. Enables incremental apt processing" ), ANNOTATION_PROCESSOR_CLASSPATH_OPTION( diff --git a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/Kapt3Plugin.kt b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/Kapt3Plugin.kt index 198c6e11337..e9c3f9e5cad 100644 --- a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/Kapt3Plugin.kt +++ b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/Kapt3Plugin.kt @@ -100,7 +100,8 @@ class Kapt3CommandLineProcessor : CommandLineProcessor { CHANGED_FILES -> changedFiles.addAll(value.split(File.pathSeparator).map { File(it) }) COMPILED_SOURCES_DIR -> compiledSources.addAll(value.split(File.pathSeparator).map { File(it) }) INCREMENTAL_CACHE -> incrementalCache = File(value) - CLASSPATH_FQ_NAMES_HISTORY -> classpathFqNamesHistory = File(value) + CLASSPATH_CHANGES -> classpathChanges.addAll(value.split(File.pathSeparator).map { it }) + PROCESS_INCREMENTALLY -> processIncrementally = value.toBoolean() ANNOTATION_PROCESSOR_CLASSPATH_OPTION -> processingClasspath += File(value) ANNOTATION_PROCESSORS_OPTION -> processors.addAll(value.split(',').map { it.trim() }.filter { it.isNotEmpty() })