Fix annotation processors outputting to classes dir with kapt 3
#KT-15915 fixed Annotation processor can access a classes directory provided by AP environment. Previously kapt 3 was using kotlin-classes directory as a a classes directory. However compileKotlin task does not expect this. Also having multiple tasks with the same output dir is a bad practise in Gradle. This change introduces a separate directory for classes generated by kapt 3. Its output is copied to a resulting classes dir (just as a kotlin-classes dir).
This commit is contained in:
-6
@@ -60,12 +60,6 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
|
||||
): ExitCode {
|
||||
val outputDir = args.destinationAsFile
|
||||
|
||||
if (environment !is GradleIncrementalCompilerEnvironment) {
|
||||
log.debug("Removing all kotlin classes in $outputDir")
|
||||
// we're free to delete all classes since only we know about that directory
|
||||
outputDir.deleteRecursively()
|
||||
}
|
||||
|
||||
val moduleFile = makeModuleFile(
|
||||
args.moduleName,
|
||||
isTest = false,
|
||||
|
||||
+7
-1
@@ -29,6 +29,7 @@ import org.gradle.api.tasks.compile.JavaCompile
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.android.AndroidGradleWrapper
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.SyncOutputTask
|
||||
import java.io.File
|
||||
|
||||
// apply plugin: 'kotlin-kapt'
|
||||
@@ -59,6 +60,9 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
||||
}
|
||||
|
||||
fun findMainKaptConfiguration(project: Project) = project.findKaptConfiguration(MAIN_KAPT_CONFIGURATION_NAME)
|
||||
|
||||
fun getKaptClasssesDir(project: Project, sourceSetName: String): File =
|
||||
File(project.project.buildDir, "tmp/kapt3/classes/$sourceSetName")
|
||||
}
|
||||
|
||||
private val kotlinToKaptTasksMap = mutableMapOf<KotlinCompile, KaptTask>()
|
||||
@@ -156,7 +160,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
||||
javaCompile.source(generatedFilesDir)
|
||||
|
||||
pluginOptions += SubpluginOption("sources", generatedFilesDir.canonicalPath)
|
||||
pluginOptions += SubpluginOption("classes", kotlinCompile.destinationDir.canonicalPath)
|
||||
pluginOptions += SubpluginOption("classes", getKaptClasssesDir(project, sourceSetName).canonicalPath)
|
||||
|
||||
val androidPlugin = variantData?.let {
|
||||
project.extensions.findByName("android") as? BaseExtension
|
||||
@@ -193,6 +197,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
||||
|
||||
private fun Kapt3SubpluginContext.createKaptKotlinTask() {
|
||||
val sourcesOutputDir = getKaptGeneratedDir(project, sourceSetName)
|
||||
val classesOutputDir = getKaptClasssesDir(project, sourceSetName)
|
||||
|
||||
// Replace compile*Kotlin to kapt*Kotlin
|
||||
assert(kotlinCompile.name.startsWith("compile"))
|
||||
@@ -207,6 +212,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
||||
|
||||
kaptTask.mapClasspath { kotlinCompile.classpath }
|
||||
kaptTask.destinationDir = sourcesOutputDir
|
||||
kaptTask.classesDir = classesOutputDir
|
||||
kaptTask.dependsOn(*(javaCompile.dependsOn.filter { it !== kotlinCompile }.toTypedArray()))
|
||||
kotlinCompile.dependsOn(kaptTask)
|
||||
|
||||
|
||||
+5
@@ -39,12 +39,17 @@ open class KaptTask : AbstractCompile() {
|
||||
return FileUtil.isAncestor(destinationDir, this, /* strict = */ false)
|
||||
}
|
||||
|
||||
lateinit var classesDir: File
|
||||
|
||||
@TaskAction
|
||||
override fun compile() {
|
||||
/** Delete everything inside the [destinationDir] */
|
||||
destinationDir.deleteRecursively()
|
||||
destinationDir.mkdirs()
|
||||
|
||||
classesDir.deleteRecursively()
|
||||
classesDir.mkdirs()
|
||||
|
||||
val sourceRoots = SourceRoots.ForJvm.create(getSource(), rawSourceRoots)
|
||||
val compileClasspath = classpath.toList().filter(File::exists)
|
||||
|
||||
|
||||
+5
-4
@@ -21,15 +21,15 @@ import org.gradle.api.tasks.bundling.Zip
|
||||
import org.gradle.api.tasks.compile.AbstractCompile
|
||||
import org.gradle.api.tasks.compile.JavaCompile
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl
|
||||
import org.jetbrains.kotlin.gradle.internal.AnnotationProcessingManager
|
||||
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin
|
||||
import org.jetbrains.kotlin.gradle.internal.Kapt3KotlinGradleSubplugin
|
||||
import org.jetbrains.kotlin.gradle.internal.initKapt
|
||||
import org.jetbrains.kotlin.gradle.internal.*
|
||||
import org.jetbrains.kotlin.gradle.internal.Kapt3KotlinGradleSubplugin.Companion.getKaptClasssesDir
|
||||
import org.jetbrains.kotlin.gradle.plugin.android.AndroidGradleWrapper
|
||||
import org.jetbrains.kotlin.gradle.plugin.android.KotlinJillTask
|
||||
import org.jetbrains.kotlin.gradle.tasks.*
|
||||
import org.jetbrains.kotlin.incremental.configureMultiProjectIncrementalCompilation
|
||||
import org.jetbrains.kotlin.incremental.multiproject.ArtifactDifferenceRegistryProviderAndroidWrapper
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
import java.io.File
|
||||
import java.net.URL
|
||||
import java.util.*
|
||||
@@ -540,6 +540,7 @@ private fun createSyncOutputTask(
|
||||
syncTask.kotlinTask = kotlinCompile
|
||||
kotlinTask.javaOutputDir = javaDir
|
||||
kotlinAfterJavaTask?.javaOutputDir = javaDir
|
||||
syncTask.kaptClassesDir = getKaptClasssesDir(project, variantName)
|
||||
|
||||
// copying should be executed after a latter task
|
||||
val previousTask = kotlinAfterJavaTask ?: javaTask
|
||||
|
||||
+21
-7
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.tasks
|
||||
|
||||
import ch.qos.logback.core.util.FileUtil
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.tasks.InputFiles
|
||||
import org.gradle.api.tasks.OutputDirectory
|
||||
@@ -23,6 +24,7 @@ import org.gradle.api.tasks.OutputFiles
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.api.tasks.incremental.IncrementalTaskInputs
|
||||
import org.gradle.api.tasks.incremental.InputFileDetails
|
||||
import org.jetbrains.kotlin.com.intellij.openapi.util.io.FileUtil.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.kotlinDebug
|
||||
import java.io.File
|
||||
import java.io.ObjectInputStream
|
||||
@@ -55,6 +57,13 @@ import kotlin.properties.Delegates
|
||||
internal open class SyncOutputTask : DefaultTask() {
|
||||
@get:InputFiles
|
||||
var kotlinOutputDir: File by Delegates.notNull()
|
||||
|
||||
@get:InputFiles
|
||||
var kaptClassesDir: File by Delegates.notNull()
|
||||
|
||||
private val classesDirs: List<File>
|
||||
get() = listOf(kotlinOutputDir, kaptClassesDir).filter(File::exists)
|
||||
|
||||
var javaOutputDir: File by Delegates.notNull()
|
||||
var kotlinTask: KotlinCompile by Delegates.notNull()
|
||||
|
||||
@@ -78,13 +87,14 @@ internal open class SyncOutputTask : DefaultTask() {
|
||||
@Suppress("unused")
|
||||
@TaskAction
|
||||
fun execute(inputs: IncrementalTaskInputs): Unit {
|
||||
val sourceDirs = classesDirs.joinToString()
|
||||
if (inputs.isIncremental) {
|
||||
logger.kotlinDebug { "Incremental copying files from $kotlinOutputDir to $javaOutputDir" }
|
||||
logger.kotlinDebug { "Incremental copying files from $sourceDirs to $javaOutputDir" }
|
||||
inputs.outOfDate { processIncrementally(it) }
|
||||
inputs.removed { processIncrementally(it) }
|
||||
}
|
||||
else {
|
||||
logger.kotlinDebug { "Non-incremental copying files from $kotlinOutputDir to $javaOutputDir" }
|
||||
logger.kotlinDebug { "Non-incremental copying files from $sourceDirs to $javaOutputDir" }
|
||||
processNonIncrementally()
|
||||
}
|
||||
|
||||
@@ -103,14 +113,16 @@ internal open class SyncOutputTask : DefaultTask() {
|
||||
timestampsFile.delete()
|
||||
timestamps.clear()
|
||||
|
||||
kotlinOutputDir.walkTopDown().forEach {
|
||||
copy(it, it.siblingInJavaDir)
|
||||
for (dir in classesDirs) {
|
||||
dir.walkTopDown().forEach {
|
||||
copy(it, it.siblingInJavaDir(baseDir = dir))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun processIncrementally(input: InputFileDetails) {
|
||||
val fileInKotlinDir = input.file
|
||||
val fileInJavaDir = fileInKotlinDir.siblingInJavaDir
|
||||
val fileInJavaDir = fileInKotlinDir.siblingInJavaDir()
|
||||
|
||||
if (input.isRemoved) {
|
||||
// file was removed in kotlin dir, remove from java as well
|
||||
@@ -146,8 +158,10 @@ internal open class SyncOutputTask : DefaultTask() {
|
||||
}
|
||||
}
|
||||
|
||||
private val File.siblingInJavaDir: File
|
||||
get() = File(javaOutputDir, this.relativeTo(kotlinOutputDir).path)
|
||||
private fun File.siblingInJavaDir(baseDir: File? = null): File {
|
||||
val base = baseDir ?: classesDirs.find { isAncestor(it, this, true) }!!
|
||||
return File(javaOutputDir, this.relativeTo(base).path)
|
||||
}
|
||||
}
|
||||
|
||||
private val TIMESTAMP_FILE_NAME = "kotlin-files-in-java-timestamps.bin"
|
||||
|
||||
+6
@@ -231,6 +231,12 @@ open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), Kotl
|
||||
}
|
||||
}
|
||||
|
||||
if (!incremental) {
|
||||
logger.kotlinDebug { "Removing all kotlin classes in $destinationDir" }
|
||||
destinationDir.deleteRecursively()
|
||||
destinationDir.mkdirs()
|
||||
}
|
||||
|
||||
try {
|
||||
val exitCode = compilerRunner.runJvmCompiler(sourceRoots.kotlinSourceFiles, sourceRoots.javaSourceRoots, args, environment)
|
||||
processCompilerExitCode(exitCode)
|
||||
|
||||
Reference in New Issue
Block a user