diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/annotation/AnnotationFileUpdater.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/annotation/AnnotationFileUpdater.kt index 5b5fb8bf5a2..b536e6f94ad 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/annotation/AnnotationFileUpdater.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/annotation/AnnotationFileUpdater.kt @@ -16,64 +16,10 @@ package org.jetbrains.kotlin.annotation -import org.gradle.api.logging.Logging -import org.jetbrains.kotlin.gradle.plugin.kotlinDebug import org.jetbrains.kotlin.resolve.jvm.JvmClassName -import java.io.File -import java.util.* -/** - * Annotation file is generated by collecting annotated elements of generated files. - * When compiling incrementally, the compiler generates only subset of all classes, - * so after compilation annotation file contains only a subset of annotated elements, - * which breaks the build. - * - * The workaround is to: - * 1. backup old file before incremental compilation; - * 2. after each iteration of IC: - * 2.1 remove classes corresponding to dirty source files - * 2.2 add annotations from newly generated annotations file - */ -internal class AnnotationFileUpdater(private val generatedAnnotationFile: File) { - private val logger = Logging.getLogger(this.javaClass) - private val lastSuccessfullyUpdatedFile = File.createTempFile("kapt-annotations-copy", "tmp") +interface AnnotationFileUpdater { + fun updateAnnotations(outdatedClasses: Iterable) + fun revert() +} - init { - if (generatedAnnotationFile.exists()) { - generatedAnnotationFile.copyTo(lastSuccessfullyUpdatedFile, overwrite = true) - } - else { - lastSuccessfullyUpdatedFile.writeText("") - } - } - - fun updateAnnotations(outdatedClasses: Iterable) { - val outdatedClassesFqNames = outdatedClasses.mapTo(HashSet()) { it.fqNameForClassNameWithoutDollars.asString() } - - val annotationsProvider = MutableKotlinAnnotationProvider().apply { - addAnnotationsFrom(lastSuccessfullyUpdatedFile) - removeClasses(outdatedClassesFqNames) - logger.kotlinDebug { "Removed annotation entries for fq-names [${outdatedClassesFqNames.joinToString()}]" } - - if (generatedAnnotationFile.exists()) { - addAnnotationsFrom(generatedAnnotationFile) - logger.kotlinDebug { "Added annotation entries from $generatedAnnotationFile" } - } - } - - generatedAnnotationFile.delete() - generatedAnnotationFile.bufferedWriter().use { writer -> - annotationsProvider.writeAnnotations(CompactAnnotationWriter(writer)) - logger.kotlinDebug { "Written updated annotations to $generatedAnnotationFile" } - } - generatedAnnotationFile.copyTo(lastSuccessfullyUpdatedFile, overwrite = true) - } - - fun revert() { - lastSuccessfullyUpdatedFile.copyTo(generatedAnnotationFile, overwrite = true) - } - - fun dispose() { - lastSuccessfullyUpdatedFile.delete() - } -} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/annotation/AnnotationFileUpdaterImpl.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/annotation/AnnotationFileUpdaterImpl.kt new file mode 100644 index 00000000000..2a8362e118b --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/annotation/AnnotationFileUpdaterImpl.kt @@ -0,0 +1,58 @@ +package org.jetbrains.kotlin.annotation + +import org.gradle.api.logging.Logging +import org.jetbrains.kotlin.gradle.plugin.kotlinDebug +import org.jetbrains.kotlin.resolve.jvm.JvmClassName +import java.io.File + +/** + * Annotation file is generated by collecting annotated elements of generated files. + * When compiling incrementally, the compiler generates only subset of all classes, + * so after compilation annotation file contains only a subset of annotated elements, + * which breaks the build. + * + * The workaround is to: + * 1. backup old file before incremental compilation; + * 2. after each iteration of IC: + * 2.1 remove classes corresponding to dirty source files + * 2.2 add annotations from newly generated annotations file + */ +internal class AnnotationFileUpdaterImpl(private val generatedAnnotationFile: File) : AnnotationFileUpdater { + private val logger = Logging.getLogger(this.javaClass) + private val lastSuccessfullyUpdatedFile = File.createTempFile("kapt-annotations-copy", "tmp") + + init { + if (generatedAnnotationFile.exists()) { + generatedAnnotationFile.copyTo(lastSuccessfullyUpdatedFile, overwrite = true) + } + else { + lastSuccessfullyUpdatedFile.writeText("") + } + } + + override fun updateAnnotations(outdatedClasses: Iterable) { + val outdatedClassesFqNames = outdatedClasses.mapTo(java.util.HashSet()) { it.fqNameForClassNameWithoutDollars.asString() } + + val annotationsProvider = MutableKotlinAnnotationProvider().apply { + addAnnotationsFrom(lastSuccessfullyUpdatedFile) + removeClasses(outdatedClassesFqNames) + logger.kotlinDebug { "Removed annotation entries for fq-names [${outdatedClassesFqNames.joinToString()}]" } + + if (generatedAnnotationFile.exists()) { + addAnnotationsFrom(generatedAnnotationFile) + logger.kotlinDebug { "Added annotation entries from $generatedAnnotationFile" } + } + } + + generatedAnnotationFile.delete() + generatedAnnotationFile.bufferedWriter().use { writer -> + annotationsProvider.writeAnnotations(CompactAnnotationWriter(writer)) + logger.kotlinDebug { "Written updated annotations to $generatedAnnotationFile" } + } + generatedAnnotationFile.copyTo(lastSuccessfullyUpdatedFile, overwrite = true) + } + + override fun revert() { + lastSuccessfullyUpdatedFile.copyTo(generatedAnnotationFile, overwrite = true) + } +} \ No newline at end of file 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 c52f6211825..c2435448c8d 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 @@ -27,6 +27,7 @@ import org.gradle.api.tasks.TaskAction import org.gradle.api.tasks.compile.AbstractCompile import org.gradle.api.tasks.incremental.IncrementalTaskInputs import org.jetbrains.kotlin.annotation.AnnotationFileUpdater +import org.jetbrains.kotlin.annotation.AnnotationFileUpdaterImpl import org.jetbrains.kotlin.cli.common.CLICompiler import org.jetbrains.kotlin.cli.common.ExitCode import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments @@ -40,7 +41,6 @@ import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler import org.jetbrains.kotlin.compilerRunner.ArgumentUtils import org.jetbrains.kotlin.compilerRunner.GradleCompilerRunner import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl -import org.jetbrains.kotlin.config.Services import org.jetbrains.kotlin.gradle.dsl.* import org.jetbrains.kotlin.gradle.plugin.CoroutineSupport import org.jetbrains.kotlin.gradle.plugin.kotlinDebug @@ -51,7 +51,6 @@ import org.jetbrains.kotlin.incremental.multiproject.ArtifactDifferenceRegistryP import org.jetbrains.kotlin.utils.LibraryUtils import java.io.File import java.util.* -import kotlin.concurrent.thread import kotlin.properties.Delegates const val ANNOTATIONS_PLUGIN_NAME = "org.jetbrains.kotlin.kapt" @@ -254,7 +253,7 @@ open class KotlinCompile : AbstractKotlinCompile(), Kotl private fun handleKaptProperties() { kaptOptions.annotationsFile?.let { kaptAnnotationsFile -> if (incremental) { - kaptAnnotationsFileUpdater = AnnotationFileUpdater(kaptAnnotationsFile) + kaptAnnotationsFileUpdater = AnnotationFileUpdaterImpl(kaptAnnotationsFile) } pluginOptions.addPluginArgument(ANNOTATIONS_PLUGIN_NAME, "output", kaptAnnotationsFile.canonicalPath)