Skip to content

Commit 4b11b79

Browse files
committed
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.
1 parent 4953550 commit 4b11b79

File tree

12 files changed

+147
-22
lines changed

12 files changed

+147
-22
lines changed

libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginMultiVersionIT.kt

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package org.jetbrains.kotlin.gradle
22

3+
import org.jetbrains.kotlin.gradle.util.getFileByName
34
import org.jetbrains.kotlin.gradle.util.modify
45
import org.junit.Test
56
import java.io.File
7+
import java.util.zip.ZipFile
68

79
class KotlinGradlePluginMultiVersionIT : BaseMultiGradleVersionIT() {
810
@Test
@@ -18,6 +20,48 @@ class KotlinGradlePluginMultiVersionIT : BaseMultiGradleVersionIT() {
1820
}
1921
}
2022

23+
@Test
24+
fun testKt19179() {
25+
val project = Project("kt19179", gradleVersion, directoryPrefix = "kapt2")
26+
27+
project.build("build") {
28+
assertSuccessful()
29+
assertFileExists("processor/build/tmp/kapt3/classes/main/META-INF/services/javax.annotation.processing.Processor")
30+
31+
val processorJar = fileInWorkingDir("processor/build/libs/processor.jar")
32+
assert(processorJar.exists())
33+
34+
ZipFile(processorJar).use { zip ->
35+
assert(zip.getEntry("META-INF/services/javax.annotation.processing.Processor") != null)
36+
}
37+
38+
assertTasksExecuted(listOf(
39+
":processor:kaptGenerateStubsKotlin", ":processor:kaptKotlin",
40+
":app:kaptGenerateStubsKotlin", ":app:kaptKotlin"))
41+
}
42+
43+
project.projectDir.getFileByName("Test.kt").modify { text ->
44+
assert("SomeClass()" in text)
45+
text.replace("SomeClass()", "SomeClass(); val a = 5")
46+
}
47+
48+
project.build("build") {
49+
assertSuccessful()
50+
assertTasksUpToDate(listOf(":processor:kaptGenerateStubsKotlin", ":processor:kaptKotlin", ":app:kaptKotlin"))
51+
assertTasksExecuted(listOf(":app:kaptGenerateStubsKotlin"))
52+
}
53+
54+
project.projectDir.getFileByName("Test.kt").modify { text ->
55+
text + "\n\nfun t() {}"
56+
}
57+
58+
project.build("build") {
59+
assertSuccessful()
60+
assertTasksUpToDate(listOf(":processor:kaptGenerateStubsKotlin", ":processor:kaptKotlin"))
61+
assertTasksExecuted(listOf(":app:kaptGenerateStubsKotlin", ":app:kaptKotlin"))
62+
}
63+
}
64+
2165
@Test
2266
fun testJavaIcCompatibility() {
2367
val version = gradleVersion.split(".").map(String::toInt)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
apply plugin: 'kotlin'
2+
3+
dependencies {
4+
compile "org.jetbrains.kotlin:kotlin-runtime:$kotlin_version"
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.example
2+
3+
import kotlin.annotation.AnnotationTarget.CLASS
4+
5+
@Target(CLASS)
6+
annotation class SomeAnnotation
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
apply plugin: 'kotlin'
2+
apply plugin: 'kotlin-kapt'
3+
4+
dependencies {
5+
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
6+
compile project(':api')
7+
kapt project(':processor')
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.example
2+
3+
@SomeAnnotation class SomeClass
4+
5+
fun main(vararg args: String) {
6+
SomeClass()
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
buildscript {
2+
repositories {
3+
mavenLocal()
4+
}
5+
6+
dependencies {
7+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
8+
}
9+
}
10+
11+
subprojects {
12+
repositories {
13+
mavenLocal()
14+
jcenter()
15+
}
16+
}
17+
18+
task clean(type: Delete) {
19+
delete rootProject.buildDir
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
apply plugin: 'kotlin'
2+
apply plugin: 'kotlin-kapt'
3+
4+
dependencies {
5+
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
6+
compile 'com.google.auto.service:auto-service:1.0-rc3'
7+
kapt 'com.google.auto.service:auto-service:1.0-rc3'
8+
compile project(':api')
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.example
2+
3+
import com.google.auto.service.AutoService
4+
import javax.annotation.processing.AbstractProcessor
5+
import javax.annotation.processing.Processor
6+
import javax.annotation.processing.RoundEnvironment
7+
import javax.lang.model.element.TypeElement
8+
import javax.tools.Diagnostic.Kind.MANDATORY_WARNING
9+
10+
@AutoService(Processor::class)
11+
class Processor : AbstractProcessor() {
12+
13+
override fun getSupportedAnnotationTypes() = setOf(SomeAnnotation::class.java.canonicalName)
14+
15+
override fun process(annotations: Set<TypeElement>, roundEnv: RoundEnvironment): Boolean {
16+
processingEnv.messager.printMessage(MANDATORY_WARNING, "*** AP RUNNING ***' ")
17+
return true
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
rootProject.name = 'kapt3-issues'
2+
include ':app'
3+
include ':api'
4+
include ':processor'

libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/Kapt3KotlinGradleSubplugin.kt

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -281,19 +281,8 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
281281

282282
kaptTask.stubsDir = getKaptStubsDir()
283283
kaptTask.destinationDir = sourcesOutputDir
284-
kaptTask.mapClasspath { kotlinCompile.classpath }
285284
kaptTask.classesDir = classesOutputDir
286285

287-
kaptTask.mapSource {
288-
val sourcesFromKotlinTask = kotlinCompile.source
289-
.filter { it.extension == "java" && !kaptTask.isInsideDestinationDirs(it) }
290-
.asFileTree
291-
292-
val stubSources = project.fileTree(kaptTask.stubsDir)
293-
294-
sourcesFromKotlinTask + stubSources
295-
}
296-
297286
kotlinCompile.source(sourcesOutputDir, kotlinSourcesOutputDir)
298287

299288
if (kaptVariantData != null) {

libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/KaptTask.kt

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package org.jetbrains.kotlin.gradle.internal
22

33
import org.gradle.api.GradleException
4-
import org.gradle.api.tasks.TaskAction
5-
import org.gradle.api.tasks.compile.AbstractCompile
4+
import org.gradle.api.file.FileCollection
5+
import org.gradle.api.internal.ConventionTask
6+
import org.gradle.api.tasks.*
67
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
78
import org.jetbrains.kotlin.com.intellij.openapi.util.io.FileUtil
89
import org.jetbrains.kotlin.compilerRunner.GradleCompilerEnvironment
@@ -11,20 +12,37 @@ import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl
1112
import org.jetbrains.kotlin.gradle.tasks.*
1213
import java.io.File
1314

14-
open class KaptTask : AbstractCompile() {
15+
open class KaptTask : ConventionTask() {
1516
internal val pluginOptions = CompilerPluginOptions()
17+
1618
internal lateinit var kotlinCompileTask: KotlinCompile
19+
internal lateinit var stubsDir: File
1720

18-
fun isInsideDestinationDirs(file: File): Boolean {
21+
private fun isInsideDestinationDirs(file: File): Boolean {
1922
return FileUtil.isAncestor(destinationDir, file, /* strict = */ false)
2023
|| FileUtil.isAncestor(classesDir, file, /* strict = */ false)
2124
}
2225

23-
lateinit var classesDir: File
24-
lateinit var stubsDir: File
26+
@OutputDirectory
27+
internal lateinit var classesDir: File
28+
29+
@OutputDirectory
30+
lateinit var destinationDir: File
31+
32+
val classpath: FileCollection
33+
@InputFiles get() = kotlinCompileTask.classpath
34+
35+
val source: FileCollection
36+
@InputFiles get() {
37+
val sourcesFromKotlinTask = kotlinCompileTask.source
38+
.filter { it.extension == "java" && !isInsideDestinationDirs(it) }
39+
40+
val stubSources = project.fileTree(stubsDir)
41+
return sourcesFromKotlinTask + stubSources
42+
}
2543

2644
@TaskAction
27-
override fun compile() {
45+
fun compile() {
2846
/** Delete everything inside generated sources and classes output directory
2947
* (annotation processing is not incremental) */
3048
destinationDir.clearDirectory()

libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/gradleUtils.kt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,6 @@ fun AbstractCompile.mapClasspath(fn: () -> FileCollection) {
5151
conventionMapping.map("classpath", fn)
5252
}
5353

54-
internal fun AbstractCompile.mapSource(fn: () -> FileTree) {
55-
conventionMapping.map("source", fn)
56-
}
57-
5854
internal inline fun <reified T : Any> Any.addConvention(name: String, plugin: T) {
5955
(this as HasConvention).convention.plugins[name] = plugin
6056
}

0 commit comments

Comments
 (0)