Kapt3: Modify kapt incremental tests in order to support kapt3

This commit is contained in:
Yan Zhulanow
2017-04-13 19:39:16 +03:00
parent c18bf5088d
commit c8d7c339cf
6 changed files with 107 additions and 12 deletions
@@ -153,7 +153,13 @@ abstract class BaseGradleIT {
val javaSourcesListRegex = Regex("\\[DEBUG\\] \\[[^\\]]*JavaCompiler\\] Compiler arguments: ([^\\r\\n]*)") val javaSourcesListRegex = Regex("\\[DEBUG\\] \\[[^\\]]*JavaCompiler\\] Compiler arguments: ([^\\r\\n]*)")
} }
val compiledKotlinSources: Iterable<File> by lazy { kotlinSourcesListRegex.findAll(output).asIterable().flatMap { it.groups[1]!!.value.split(", ").map { File(project.projectDir, it).canonicalFile } } } private fun getCompiledFiles(regex: Regex, output: String) = regex.findAll(output)
.asIterable()
.flatMap { it.groups[1]!!.value.split(", ")
.map { File(project.projectDir, it).canonicalFile } }
fun getCompiledKotlinSources(output: String) = getCompiledFiles(kotlinSourcesListRegex, output)
val compiledJavaSources: Iterable<File> by lazy { javaSourcesListRegex.findAll(output).asIterable().flatMap { it.groups[1]!!.value.split(" ").filter { it.endsWith(".java", ignoreCase = true) }.map { File(it).canonicalFile } } } val compiledJavaSources: Iterable<File> by lazy { javaSourcesListRegex.findAll(output).asIterable().flatMap { it.groups[1]!!.value.split(" ").filter { it.endsWith(".java", ignoreCase = true) }.map { File(it).canonicalFile } } }
} }
@@ -304,11 +310,35 @@ abstract class BaseGradleIT {
return this return this
} }
fun CompiledProject.assertCompiledKotlinSources(sources: Iterable<String>, weakTesting: Boolean = false): CompiledProject = fun CompiledProject.getOutputForTask(taskName: String): String {
fun String.substringAfter(delimiter: String, missingDelimiterValue: () -> String): String {
val index = indexOf(delimiter)
return if (index == -1) missingDelimiterValue() else substring(index + delimiter.length, length)
}
fun String.substringBefore(delimiter: String, missingDelimiterValue: () -> String): String {
val index = indexOf(delimiter)
return if (index == -1) missingDelimiterValue() else substring(0, index)
}
return output.substringAfter("[LIFECYCLE] [class org.gradle.TaskExecutionLogger] :$taskName") { error("Can't find start for task $taskName") }
.substringBefore("Finished executing task ':$taskName'") { error("Can't find completion for task $taskName") }
}
fun CompiledProject.assertCompiledKotlinSources(
sources: Iterable<String>,
weakTesting: Boolean = false,
tasks: List<String>) {
for (task in tasks) {
assertCompiledKotlinSources(sources, weakTesting, getOutputForTask(task))
}
}
fun CompiledProject.assertCompiledKotlinSources(sources: Iterable<String>, weakTesting: Boolean = false, output: String = this.output): CompiledProject =
if (weakTesting) if (weakTesting)
assertContainFiles(sources, compiledKotlinSources.projectRelativePaths(this.project), "Compiled Kotlin files differ:\n ") assertContainFiles(sources, getCompiledKotlinSources(output).projectRelativePaths(this.project), "Compiled Kotlin files differ:\n ")
else else
assertSameFiles(sources, compiledKotlinSources.projectRelativePaths(this.project), "Compiled Kotlin files differ:\n ") assertSameFiles(sources, getCompiledKotlinSources(output).projectRelativePaths(this.project), "Compiled Kotlin files differ:\n ")
fun CompiledProject.assertCompiledJavaSources(sources: Iterable<String>, weakTesting: Boolean = false): CompiledProject = fun CompiledProject.assertCompiledJavaSources(sources: Iterable<String>, weakTesting: Boolean = false): CompiledProject =
if (weakTesting) if (weakTesting)
@@ -113,6 +113,8 @@ class Kapt3IT : BaseGradleIT() {
project.build("build", options = options) { project.build("build", options = options) {
assertSuccessful() assertSuccessful()
assertContains(":compileKotlin UP-TO-DATE") assertContains(":compileKotlin UP-TO-DATE")
assertContains(":kaptGenerateStubsKotlin UP-TO-DATE")
assertContains(":kaptKotlin UP-TO-DATE")
assertFileExists("build/classes/main/example/TestClass.class") assertFileExists("build/classes/main/example/TestClass.class")
assertClassFilesNotContain(classesDir, "ExampleSourceAnnotation") assertClassFilesNotContain(classesDir, "ExampleSourceAnnotation")
} }
@@ -277,6 +279,7 @@ class Kapt3IT : BaseGradleIT() {
project.build("classes", options = options) { project.build("classes", options = options) {
assertSuccessful() assertSuccessful()
assertFileExists("build/generated/source/kapt/main/foo/InternalDummyGenerated.java")
} }
// remove annotation // remove annotation
@@ -286,6 +289,7 @@ class Kapt3IT : BaseGradleIT() {
assertSuccessful() assertSuccessful()
val allMainKotlinSrc = File(project.projectDir, "src/main").allKotlinFiles() val allMainKotlinSrc = File(project.projectDir, "src/main").allKotlinFiles()
assertCompiledKotlinSources(project.relativize(allMainKotlinSrc)) assertCompiledKotlinSources(project.relativize(allMainKotlinSrc))
assertNoSuchFile("build/generated/source/kapt/main/foo/InternalDummyGenerated.java")
} }
} }
@@ -9,19 +9,35 @@ import org.junit.Test
class KaptIncrementalNoStubsIT : KaptIncrementalBaseIT(shouldUseStubs = false) class KaptIncrementalNoStubsIT : KaptIncrementalBaseIT(shouldUseStubs = false)
class KaptIncrementalWithStubsIT : KaptIncrementalBaseIT(shouldUseStubs = true) class KaptIncrementalWithStubsIT : KaptIncrementalBaseIT(shouldUseStubs = true)
abstract class KaptIncrementalBaseIT(val shouldUseStubs: Boolean): BaseGradleIT() { class Kapt3Incremental : KaptIncrementalBaseIT(shouldUseStubs = false, useKapt3 = true)
abstract class KaptIncrementalBaseIT(val shouldUseStubs: Boolean, val useKapt3: Boolean = false): BaseGradleIT() {
init {
if (useKapt3) {
assert(!shouldUseStubs)
}
}
companion object { companion object {
private const val GRADLE_VERSION = "2.10" private const val GRADLE_VERSION = "2.10"
private val EXAMPLE_ANNOTATION_REGEX = "@(field:)?example.ExampleAnnotation".toRegex() private val EXAMPLE_ANNOTATION_REGEX = "@(field:)?example.ExampleAnnotation".toRegex()
private const val GENERATE_STUBS_PLACEHOLDER = "GENERATE_STUBS_PLACEHOLDER" private const val GENERATE_STUBS_PLACEHOLDER = "GENERATE_STUBS_PLACEHOLDER"
private const val APPLY_KAPT3_PLUGIN_PLACEHOLDER = "// APPLY_KAPT_PLUGIN"
private const val APPLY_KAPT3_PLUGIN = "apply plugin: \"kotlin-kapt\""
} }
protected open val projectName = "kaptIncrementalCompilationProject"
private fun getProject() = private fun getProject() =
Project("kaptIncrementalCompilationProject", GRADLE_VERSION).apply { Project(projectName, GRADLE_VERSION).apply {
setupWorkingDir() setupWorkingDir()
val buildGradle = projectDir.parentFile.getFileByName("build.gradle") val buildGradle = projectDir.parentFile.getFileByName("build.gradle")
buildGradle.modify { it.replace(GENERATE_STUBS_PLACEHOLDER, shouldUseStubs.toString()) } buildGradle.modify { it.replace(GENERATE_STUBS_PLACEHOLDER, shouldUseStubs.toString()) }
if (useKapt3) {
buildGradle.modify { it.replace(APPLY_KAPT3_PLUGIN_PLACEHOLDER, APPLY_KAPT3_PLUGIN) }
}
} }
private val annotatedElements = private val annotatedElements =
@@ -47,6 +63,11 @@ abstract class KaptIncrementalBaseIT(val shouldUseStubs: Boolean): BaseGradleIT(
assertContains(":compileKotlin UP-TO-DATE", assertContains(":compileKotlin UP-TO-DATE",
":compileJava UP-TO-DATE") ":compileJava UP-TO-DATE")
if (useKapt3) {
assertContains(":kaptKotlin UP-TO-DATE",
":kaptGenerateStubsKotlin UP-TO-DATE")
}
if (shouldUseStubs) { if (shouldUseStubs) {
assertContains(":compileKotlinAfterJava UP-TO-DATE") assertContains(":compileKotlinAfterJava UP-TO-DATE")
} }
@@ -70,8 +91,10 @@ abstract class KaptIncrementalBaseIT(val shouldUseStubs: Boolean): BaseGradleIT(
project.build("build") { project.build("build") {
assertSuccessful() assertSuccessful()
assertKapt3FullyExecuted()
// todo: for kapt with stubs check compileKotlin and compileKotlinAfterJava separately // todo: for kapt with stubs check compileKotlin and compileKotlinAfterJava separately
assertCompiledKotlinSources(project.relativize(utilKt)) assertCompiledKotlinSourcesHandleKapt3(project.relativize(utilKt))
checkGenerated(*(annotatedElements + arrayOf("newUtilFun"))) checkGenerated(*(annotatedElements + arrayOf("newUtilFun")))
} }
} }
@@ -88,6 +111,7 @@ abstract class KaptIncrementalBaseIT(val shouldUseStubs: Boolean): BaseGradleIT(
project.build("build") { project.build("build") {
assertSuccessful() assertSuccessful()
assertKapt3FullyExecuted()
assertCompiledKotlinSources(project.relativize(utilKt)) assertCompiledKotlinSources(project.relativize(utilKt))
checkGenerated(*(annotatedElements + arrayOf("notAnnotatedFun"))) checkGenerated(*(annotatedElements + arrayOf("notAnnotatedFun")))
} }
@@ -113,7 +137,8 @@ abstract class KaptIncrementalBaseIT(val shouldUseStubs: Boolean): BaseGradleIT(
project.build("build") { project.build("build") {
assertSuccessful() assertSuccessful()
assertCompiledKotlinSources(project.relativize(project.projectDir.allKotlinFiles())) assertKapt3FullyExecuted()
assertCompiledKotlinSourcesHandleKapt3(project.relativize(project.projectDir.allKotlinFiles()))
val affectedElements = arrayOf("B", "funB", "valB", "useB") val affectedElements = arrayOf("B", "funB", "valB", "useB")
checkGenerated(*(annotatedElements.toSet() - affectedElements).toTypedArray()) checkGenerated(*(annotatedElements.toSet() - affectedElements).toTypedArray())
checkNotGenerated(*affectedElements) checkNotGenerated(*affectedElements)
@@ -133,7 +158,19 @@ abstract class KaptIncrementalBaseIT(val shouldUseStubs: Boolean): BaseGradleIT(
project.build("build") { project.build("build") {
assertSuccessful() assertSuccessful()
if (shouldUseStubs) {
if (useKapt3) {
assertKapt3FullyExecuted()
val useBKt = project.projectDir.getFileByName("useB.kt")
assertCompiledKotlinSources(project.relativize(bKt, useBKt),
output = getOutputForTask("kaptGenerateStubsKotlin"))
// java removal is detected
assertCompiledKotlinSources(project.relativize(project.projectDir.allKotlinFiles()),
output = getOutputForTask("compileKotlin"))
}
else if (shouldUseStubs) {
// java removal is detected // java removal is detected
assertCompiledKotlinSources(project.relativize(project.projectDir.allKotlinFiles())) assertCompiledKotlinSources(project.relativize(project.projectDir.allKotlinFiles()))
} }
@@ -159,11 +196,31 @@ abstract class KaptIncrementalBaseIT(val shouldUseStubs: Boolean): BaseGradleIT(
project.build("build") { project.build("build") {
assertSuccessful() assertSuccessful()
assertCompiledKotlinSources(project.relativize(bKt, useBKt)) assertKapt3FullyExecuted()
assertCompiledKotlinSourcesHandleKapt3(project.relativize(bKt, useBKt))
checkGenerated(*annotatedElements) checkGenerated(*annotatedElements)
} }
} }
private fun CompiledProject.assertCompiledKotlinSourcesHandleKapt3(
sources: Iterable<String>,
weakTesting: Boolean = false
) {
if (useKapt3) {
assertCompiledKotlinSources(sources, weakTesting,
tasks = listOf("compileKotlin", "kaptGenerateStubsKotlin"))
} else {
assertCompiledKotlinSources(sources, weakTesting)
}
}
private fun CompiledProject.assertKapt3FullyExecuted() {
if (useKapt3) {
assertNotContains(":kaptKotlin UP-TO-DATE",
":kaptGenerateStubsKotlin UP-TO-DATE")
}
}
private fun CompiledProject.checkGenerated(vararg annotatedElementNames: String) { private fun CompiledProject.checkGenerated(vararg annotatedElementNames: String) {
getGeneratedFileNames(*annotatedElementNames).forEach { getGeneratedFileNames(*annotatedElementNames).forEach {
val file = project.projectDir.getFileByName(it) val file = project.projectDir.getFileByName(it)
@@ -9,6 +9,7 @@ buildscript {
apply plugin: "java" apply plugin: "java"
apply plugin: "kotlin" apply plugin: "kotlin"
// APPLY_KAPT_PLUGIN
repositories { repositories {
mavenLocal() mavenLocal()
@@ -7,7 +7,7 @@ import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.gradle.tasks.GradleMessageCollector import org.jetbrains.kotlin.gradle.tasks.GradleMessageCollector
import org.jetbrains.kotlin.gradle.tasks.findToolsJar import org.jetbrains.kotlin.gradle.tasks.findToolsJar
import org.jetbrains.kotlin.incremental.ChangedFiles import org.jetbrains.kotlin.incremental.ChangedFiles
import org.jetbrains.kotlin.incremental.GradleICReporter import org.jetbrains.kotlin.incremental.ICReporter
import org.jetbrains.kotlin.incremental.multiproject.ArtifactDifferenceRegistryProvider import org.jetbrains.kotlin.incremental.multiproject.ArtifactDifferenceRegistryProvider
import java.io.File import java.io.File
import java.net.URL import java.net.URL
@@ -30,7 +30,7 @@ internal open class GradleCompilerEnvironment(
internal class GradleIncrementalCompilerEnvironment( internal class GradleIncrementalCompilerEnvironment(
compilerJar: File, compilerJar: File,
val changedFiles: ChangedFiles, val changedFiles: ChangedFiles,
val reporter: GradleICReporter, val reporter: ICReporter,
val workingDir: File, val workingDir: File,
messageCollector: GradleMessageCollector, messageCollector: GradleMessageCollector,
outputItemsCollector: OutputItemsCollector, outputItemsCollector: OutputItemsCollector,
@@ -18,11 +18,14 @@ package org.jetbrains.kotlin.gradle.internal
import org.gradle.api.tasks.SourceTask import org.gradle.api.tasks.SourceTask
import org.gradle.api.tasks.incremental.IncrementalTaskInputs import org.gradle.api.tasks.incremental.IncrementalTaskInputs
import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.com.intellij.openapi.util.io.FileUtil import org.jetbrains.kotlin.com.intellij.openapi.util.io.FileUtil
import org.jetbrains.kotlin.gradle.plugin.kotlinDebug import org.jetbrains.kotlin.gradle.plugin.kotlinDebug
import org.jetbrains.kotlin.gradle.tasks.FilteringSourceRootsContainer import org.jetbrains.kotlin.gradle.tasks.FilteringSourceRootsContainer
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.incremental.ChangedFiles import org.jetbrains.kotlin.incremental.ChangedFiles
import org.jetbrains.kotlin.incremental.GradleICReporter
import org.jetbrains.kotlin.incremental.ICReporter
import org.jetbrains.kotlin.incremental.pathsAsStringRelativeTo import org.jetbrains.kotlin.incremental.pathsAsStringRelativeTo
import java.io.File import java.io.File