[KAPT] Cache annotation processors' classloaders
Adds experimental feature to cache annotation processors' classloaders It should increase speed of KAPT for consecutive runs Works for gradle only (it stores cl in gradle daemon) #KT-28901 Fixed
This commit is contained in:
committed by
TeamCityServer
parent
e6b9935df9
commit
1093bffc62
+5
-1
@@ -258,7 +258,8 @@ abstract class BaseGradleIT {
|
||||
val verbose: Boolean,
|
||||
val useWorkers: Boolean,
|
||||
val incrementalKapt: Boolean = false,
|
||||
val includeCompileClasspath: Boolean = true
|
||||
val includeCompileClasspath: Boolean = true,
|
||||
val classLoadersCacheSize: Int? = null
|
||||
)
|
||||
|
||||
open inner class Project(
|
||||
@@ -913,6 +914,9 @@ Finished executing task ':$taskName'|
|
||||
add("-Pkapt.use.worker.api=${kaptOptions.useWorkers}")
|
||||
add("-Pkapt.incremental.apt=${kaptOptions.incrementalKapt}")
|
||||
add("-Pkapt.include.compile.classpath=${kaptOptions.includeCompileClasspath}")
|
||||
kaptOptions.classLoadersCacheSize?.also { cacheSize ->
|
||||
add("-Pkapt.classloaders.cache.size=$cacheSize")
|
||||
}
|
||||
}
|
||||
|
||||
options.parallelTasksInProject?.let {
|
||||
|
||||
+76
-6
@@ -21,11 +21,14 @@ import org.jetbrains.kotlin.gradle.tasks.USING_JVM_INCREMENTAL_COMPILATION_MESSA
|
||||
import org.jetbrains.kotlin.gradle.util.*
|
||||
import org.junit.Assert
|
||||
import org.junit.Assume
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import java.io.File
|
||||
import java.util.regex.Pattern
|
||||
import java.util.zip.ZipFile
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertNull
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
abstract class Kapt3BaseIT : BaseGradleIT() {
|
||||
companion object {
|
||||
@@ -43,7 +46,7 @@ abstract class Kapt3BaseIT : BaseGradleIT() {
|
||||
}
|
||||
}
|
||||
|
||||
class Kapt3WorkersIT : Kapt3IT() {
|
||||
open class Kapt3WorkersIT : Kapt3IT() {
|
||||
override fun kaptOptions(): KaptOptions =
|
||||
super.kaptOptions().copy(useWorkers = true)
|
||||
|
||||
@@ -53,7 +56,9 @@ class Kapt3WorkersIT : Kapt3IT() {
|
||||
Project("javacIsLoadedOnce", directoryPrefix = "kapt2")
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
assertSubstringCount("Loaded com.sun.tools.javac.util.Context from", 1)
|
||||
|
||||
val loadsCount = Pattern.quote("Loaded com.sun.tools.javac.util.Context from").toRegex().findAll(output).count()
|
||||
assertTrue(loadsCount <= 1, "javac is loaded more than once")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,9 +100,65 @@ class Kapt3WorkersIT : Kapt3IT() {
|
||||
}
|
||||
}
|
||||
|
||||
class Kapt3ClassLoadersCacheIT : Kapt3WorkersIT() {
|
||||
override fun kaptOptions(): KaptOptions =
|
||||
super.kaptOptions().copy(classLoadersCacheSize = 10, includeCompileClasspath = false)
|
||||
|
||||
@Ignore
|
||||
override fun testDisableDiscoveryInCompileClasspath() {
|
||||
//classloaders cache is incompatible with AP discovery in classpath
|
||||
}
|
||||
|
||||
@Test
|
||||
override fun testAnnotationProcessorAsFqName() {
|
||||
val project = Project("annotationProcessorAsFqName", directoryPrefix = "kapt2").also { it.setupWorkingDir() }
|
||||
|
||||
//classloaders caching is not compatible with includeCompileClasspath
|
||||
project.projectDir.getFileByName("build.gradle").modify {
|
||||
it.addBeforeSubstring(
|
||||
"kapt \"org.jetbrains.kotlin:annotation-processor-example:\$kotlin_version\"\n",
|
||||
"implementation \"org.jetbrains.kotlin:annotation-processor-example"
|
||||
)
|
||||
}
|
||||
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
assertKaptSuccessful()
|
||||
assertTasksExecuted(":compileKotlin", ":compileJava")
|
||||
assertFileExists("build/generated/source/kapt/main/example/TestClassGenerated.java")
|
||||
assertFileExists(kotlinClassesDir() + "example/TestClass.class")
|
||||
assertFileExists(javaClassesDir() + "example/TestClassGenerated.class")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAnnotationProcessorClassIsLoadedOnce() {
|
||||
val project = Project("javacIsLoadedOnce", directoryPrefix = "kapt2")
|
||||
|
||||
fun CompiledProject.classLoadingCount() =
|
||||
Pattern.quote("Loaded example.ExampleAnnotationProcessor from").toRegex().findAll(output).count()
|
||||
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
assertTasksExecuted(":module1:kaptKotlin", ":module2:kaptKotlin")
|
||||
assertTrue(classLoadingCount() <= 1, "AP class is loaded more than once")
|
||||
}
|
||||
|
||||
project.projectDir.getFilesByNames("Module1Class.kt", "Module2Class.kt").forEach {
|
||||
it.appendText("\n fun touch() = null")
|
||||
}
|
||||
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
assertTasksExecuted(":module1:kaptKotlin", ":module2:kaptKotlin")
|
||||
assertTrue(classLoadingCount() == 0, "AP class shouldn't be loaded on the second build")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open class Kapt3IT : Kapt3BaseIT() {
|
||||
@Test
|
||||
fun testAnnotationProcessorAsFqName() {
|
||||
open fun testAnnotationProcessorAsFqName() {
|
||||
val project = Project("annotationProcessorAsFqName", directoryPrefix = "kapt2")
|
||||
|
||||
project.build("build") {
|
||||
@@ -487,7 +548,7 @@ open class Kapt3IT : Kapt3BaseIT() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDisableDiscoveryInCompileClasspath() = with(Project("kaptAvoidance", directoryPrefix = "kapt2")) {
|
||||
open fun testDisableDiscoveryInCompileClasspath() = with(Project("kaptAvoidance", directoryPrefix = "kapt2")) {
|
||||
setupWorkingDir()
|
||||
val buildGradle = projectDir.resolve("app/build.gradle")
|
||||
buildGradle.modify {
|
||||
@@ -510,6 +571,12 @@ open class Kapt3IT : Kapt3BaseIT() {
|
||||
|
||||
@Test
|
||||
fun testKaptAvoidance() = with(Project("kaptAvoidance", directoryPrefix = "kapt2")) {
|
||||
setupWorkingDir()
|
||||
|
||||
projectDir.resolve("app/build.gradle").modify {
|
||||
"$it\n\nkapt.includeCompileClasspath = true"
|
||||
}
|
||||
|
||||
build("assemble") {
|
||||
assertSuccessful()
|
||||
assertTasksExecuted(
|
||||
@@ -538,7 +605,10 @@ open class Kapt3IT : Kapt3BaseIT() {
|
||||
|
||||
// enable discovery
|
||||
projectDir.resolve("app/build.gradle").modify {
|
||||
"$it\n\nkapt.includeCompileClasspath = false"
|
||||
it.replace(
|
||||
"kapt.includeCompileClasspath = true",
|
||||
"kapt.includeCompileClasspath = false"
|
||||
)
|
||||
}
|
||||
build("assemble") {
|
||||
assertSuccessful()
|
||||
@@ -710,7 +780,7 @@ open class Kapt3IT : Kapt3BaseIT() {
|
||||
assertSuccessful()
|
||||
assertKaptSuccessful()
|
||||
assertTasksExecuted(":compileKotlin", ":compileJava")
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-2
@@ -3,9 +3,12 @@ buildscript {
|
||||
'kotlin': [
|
||||
'stdlib': [
|
||||
'common': "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlin_version",
|
||||
'jdk': "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version",
|
||||
],
|
||||
'jdk': "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
]
|
||||
],
|
||||
'other' : [
|
||||
'ap_example': "org.jetbrains.kotlin:annotation-processor-example:$kotlin_version"
|
||||
]
|
||||
]
|
||||
|
||||
repositories {
|
||||
|
||||
+1
@@ -7,4 +7,5 @@ targetCompatibility = JavaVersion.VERSION_1_8
|
||||
dependencies {
|
||||
expectedBy project(':dac')
|
||||
implementation deps.kotlin.stdlib.jdk
|
||||
kapt deps.other.ap_example
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user