Kapt: Do not use AbstractCompile as a supertype for KaptTask (KT-19179)
Gradle sometimes tells that kaptCompile is UP-TO-DATE even when it's not true, so the annotation processing step is silently skipped.
Looks like replacing `mapSource {}` with an explicit getter or with manual `source()` invocation does not fix the problem.
This looks like a bug in Gradle appeared since 3.0. The test from this commit works with Gradle 2.14.1.
This commit is contained in:
+44
@@ -1,8 +1,10 @@
|
||||
package org.jetbrains.kotlin.gradle
|
||||
|
||||
import org.jetbrains.kotlin.gradle.util.getFileByName
|
||||
import org.jetbrains.kotlin.gradle.util.modify
|
||||
import org.junit.Test
|
||||
import java.io.File
|
||||
import java.util.zip.ZipFile
|
||||
|
||||
class KotlinGradlePluginMultiVersionIT : BaseMultiGradleVersionIT() {
|
||||
@Test
|
||||
@@ -18,6 +20,48 @@ class KotlinGradlePluginMultiVersionIT : BaseMultiGradleVersionIT() {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testKt19179() {
|
||||
val project = Project("kt19179", gradleVersion, directoryPrefix = "kapt2")
|
||||
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
assertFileExists("processor/build/tmp/kapt3/classes/main/META-INF/services/javax.annotation.processing.Processor")
|
||||
|
||||
val processorJar = fileInWorkingDir("processor/build/libs/processor.jar")
|
||||
assert(processorJar.exists())
|
||||
|
||||
ZipFile(processorJar).use { zip ->
|
||||
assert(zip.getEntry("META-INF/services/javax.annotation.processing.Processor") != null)
|
||||
}
|
||||
|
||||
assertTasksExecuted(listOf(
|
||||
":processor:kaptGenerateStubsKotlin", ":processor:kaptKotlin",
|
||||
":app:kaptGenerateStubsKotlin", ":app:kaptKotlin"))
|
||||
}
|
||||
|
||||
project.projectDir.getFileByName("Test.kt").modify { text ->
|
||||
assert("SomeClass()" in text)
|
||||
text.replace("SomeClass()", "SomeClass(); val a = 5")
|
||||
}
|
||||
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
assertTasksUpToDate(listOf(":processor:kaptGenerateStubsKotlin", ":processor:kaptKotlin", ":app:kaptKotlin"))
|
||||
assertTasksExecuted(listOf(":app:kaptGenerateStubsKotlin"))
|
||||
}
|
||||
|
||||
project.projectDir.getFileByName("Test.kt").modify { text ->
|
||||
text + "\n\nfun t() {}"
|
||||
}
|
||||
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
assertTasksUpToDate(listOf(":processor:kaptGenerateStubsKotlin", ":processor:kaptKotlin"))
|
||||
assertTasksExecuted(listOf(":app:kaptGenerateStubsKotlin", ":app:kaptKotlin"))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testJavaIcCompatibility() {
|
||||
val version = gradleVersion.split(".").map(String::toInt)
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
apply plugin: 'kotlin'
|
||||
|
||||
dependencies {
|
||||
compile "org.jetbrains.kotlin:kotlin-runtime:$kotlin_version"
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package com.example
|
||||
|
||||
import kotlin.annotation.AnnotationTarget.CLASS
|
||||
|
||||
@Target(CLASS)
|
||||
annotation class SomeAnnotation
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
apply plugin: 'kotlin'
|
||||
apply plugin: 'kotlin-kapt'
|
||||
|
||||
dependencies {
|
||||
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
compile project(':api')
|
||||
kapt project(':processor')
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package com.example
|
||||
|
||||
@SomeAnnotation class SomeClass
|
||||
|
||||
fun main(vararg args: String) {
|
||||
SomeClass()
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
||||
subprojects {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
apply plugin: 'kotlin'
|
||||
apply plugin: 'kotlin-kapt'
|
||||
|
||||
dependencies {
|
||||
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
compile 'com.google.auto.service:auto-service:1.0-rc3'
|
||||
kapt 'com.google.auto.service:auto-service:1.0-rc3'
|
||||
compile project(':api')
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.example
|
||||
|
||||
import com.google.auto.service.AutoService
|
||||
import javax.annotation.processing.AbstractProcessor
|
||||
import javax.annotation.processing.Processor
|
||||
import javax.annotation.processing.RoundEnvironment
|
||||
import javax.lang.model.element.TypeElement
|
||||
import javax.tools.Diagnostic.Kind.MANDATORY_WARNING
|
||||
|
||||
@AutoService(Processor::class)
|
||||
class Processor : AbstractProcessor() {
|
||||
|
||||
override fun getSupportedAnnotationTypes() = setOf(SomeAnnotation::class.java.canonicalName)
|
||||
|
||||
override fun process(annotations: Set<TypeElement>, roundEnv: RoundEnvironment): Boolean {
|
||||
processingEnv.messager.printMessage(MANDATORY_WARNING, "*** AP RUNNING ***' ")
|
||||
return true
|
||||
}
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
rootProject.name = 'kapt3-issues'
|
||||
include ':app'
|
||||
include ':api'
|
||||
include ':processor'
|
||||
-11
@@ -281,19 +281,8 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
||||
|
||||
kaptTask.stubsDir = getKaptStubsDir()
|
||||
kaptTask.destinationDir = sourcesOutputDir
|
||||
kaptTask.mapClasspath { kotlinCompile.classpath }
|
||||
kaptTask.classesDir = classesOutputDir
|
||||
|
||||
kaptTask.mapSource {
|
||||
val sourcesFromKotlinTask = kotlinCompile.source
|
||||
.filter { it.extension == "java" && !kaptTask.isInsideDestinationDirs(it) }
|
||||
.asFileTree
|
||||
|
||||
val stubSources = project.fileTree(kaptTask.stubsDir)
|
||||
|
||||
sourcesFromKotlinTask + stubSources
|
||||
}
|
||||
|
||||
kotlinCompile.source(sourcesOutputDir, kotlinSourcesOutputDir)
|
||||
|
||||
if (kaptVariantData != null) {
|
||||
|
||||
+26
-8
@@ -1,8 +1,9 @@
|
||||
package org.jetbrains.kotlin.gradle.internal
|
||||
|
||||
import org.gradle.api.GradleException
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.api.tasks.compile.AbstractCompile
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.internal.ConventionTask
|
||||
import org.gradle.api.tasks.*
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
||||
import org.jetbrains.kotlin.com.intellij.openapi.util.io.FileUtil
|
||||
import org.jetbrains.kotlin.compilerRunner.GradleCompilerEnvironment
|
||||
@@ -11,20 +12,37 @@ import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl
|
||||
import org.jetbrains.kotlin.gradle.tasks.*
|
||||
import java.io.File
|
||||
|
||||
open class KaptTask : AbstractCompile() {
|
||||
open class KaptTask : ConventionTask() {
|
||||
internal val pluginOptions = CompilerPluginOptions()
|
||||
internal lateinit var kotlinCompileTask: KotlinCompile
|
||||
|
||||
fun isInsideDestinationDirs(file: File): Boolean {
|
||||
internal lateinit var kotlinCompileTask: KotlinCompile
|
||||
internal lateinit var stubsDir: File
|
||||
|
||||
private fun isInsideDestinationDirs(file: File): Boolean {
|
||||
return FileUtil.isAncestor(destinationDir, file, /* strict = */ false)
|
||||
|| FileUtil.isAncestor(classesDir, file, /* strict = */ false)
|
||||
}
|
||||
|
||||
lateinit var classesDir: File
|
||||
lateinit var stubsDir: File
|
||||
@OutputDirectory
|
||||
internal lateinit var classesDir: File
|
||||
|
||||
@OutputDirectory
|
||||
lateinit var destinationDir: File
|
||||
|
||||
val classpath: FileCollection
|
||||
@InputFiles get() = kotlinCompileTask.classpath
|
||||
|
||||
val source: FileCollection
|
||||
@InputFiles get() {
|
||||
val sourcesFromKotlinTask = kotlinCompileTask.source
|
||||
.filter { it.extension == "java" && !isInsideDestinationDirs(it) }
|
||||
|
||||
val stubSources = project.fileTree(stubsDir)
|
||||
return sourcesFromKotlinTask + stubSources
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
override fun compile() {
|
||||
fun compile() {
|
||||
/** Delete everything inside generated sources and classes output directory
|
||||
* (annotation processing is not incremental) */
|
||||
destinationDir.clearDirectory()
|
||||
|
||||
-4
@@ -51,10 +51,6 @@ fun AbstractCompile.mapClasspath(fn: () -> FileCollection) {
|
||||
conventionMapping.map("classpath", fn)
|
||||
}
|
||||
|
||||
internal fun AbstractCompile.mapSource(fn: () -> FileTree) {
|
||||
conventionMapping.map("source", fn)
|
||||
}
|
||||
|
||||
internal inline fun <reified T : Any> Any.addConvention(name: String, plugin: T) {
|
||||
(this as HasConvention).convention.plugins[name] = plugin
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user