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 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 } } }
}
@@ -304,11 +310,35 @@ abstract class BaseGradleIT {
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)
assertContainFiles(sources, compiledKotlinSources.projectRelativePaths(this.project), "Compiled Kotlin files differ:\n ")
assertContainFiles(sources, getCompiledKotlinSources(output).projectRelativePaths(this.project), "Compiled Kotlin files differ:\n ")
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 =
if (weakTesting)
@@ -113,6 +113,8 @@ class Kapt3IT : BaseGradleIT() {
project.build("build", options = options) {
assertSuccessful()
assertContains(":compileKotlin UP-TO-DATE")
assertContains(":kaptGenerateStubsKotlin UP-TO-DATE")
assertContains(":kaptKotlin UP-TO-DATE")
assertFileExists("build/classes/main/example/TestClass.class")
assertClassFilesNotContain(classesDir, "ExampleSourceAnnotation")
}
@@ -277,6 +279,7 @@ class Kapt3IT : BaseGradleIT() {
project.build("classes", options = options) {
assertSuccessful()
assertFileExists("build/generated/source/kapt/main/foo/InternalDummyGenerated.java")
}
// remove annotation
@@ -286,6 +289,7 @@ class Kapt3IT : BaseGradleIT() {
assertSuccessful()
val allMainKotlinSrc = File(project.projectDir, "src/main").allKotlinFiles()
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 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 {
private const val GRADLE_VERSION = "2.10"
private val EXAMPLE_ANNOTATION_REGEX = "@(field:)?example.ExampleAnnotation".toRegex()
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() =
Project("kaptIncrementalCompilationProject", GRADLE_VERSION).apply {
Project(projectName, GRADLE_VERSION).apply {
setupWorkingDir()
val buildGradle = projectDir.parentFile.getFileByName("build.gradle")
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 =
@@ -47,6 +63,11 @@ abstract class KaptIncrementalBaseIT(val shouldUseStubs: Boolean): BaseGradleIT(
assertContains(":compileKotlin UP-TO-DATE",
":compileJava UP-TO-DATE")
if (useKapt3) {
assertContains(":kaptKotlin UP-TO-DATE",
":kaptGenerateStubsKotlin UP-TO-DATE")
}
if (shouldUseStubs) {
assertContains(":compileKotlinAfterJava UP-TO-DATE")
}
@@ -70,8 +91,10 @@ abstract class KaptIncrementalBaseIT(val shouldUseStubs: Boolean): BaseGradleIT(
project.build("build") {
assertSuccessful()
assertKapt3FullyExecuted()
// todo: for kapt with stubs check compileKotlin and compileKotlinAfterJava separately
assertCompiledKotlinSources(project.relativize(utilKt))
assertCompiledKotlinSourcesHandleKapt3(project.relativize(utilKt))
checkGenerated(*(annotatedElements + arrayOf("newUtilFun")))
}
}
@@ -88,6 +111,7 @@ abstract class KaptIncrementalBaseIT(val shouldUseStubs: Boolean): BaseGradleIT(
project.build("build") {
assertSuccessful()
assertKapt3FullyExecuted()
assertCompiledKotlinSources(project.relativize(utilKt))
checkGenerated(*(annotatedElements + arrayOf("notAnnotatedFun")))
}
@@ -113,7 +137,8 @@ abstract class KaptIncrementalBaseIT(val shouldUseStubs: Boolean): BaseGradleIT(
project.build("build") {
assertSuccessful()
assertCompiledKotlinSources(project.relativize(project.projectDir.allKotlinFiles()))
assertKapt3FullyExecuted()
assertCompiledKotlinSourcesHandleKapt3(project.relativize(project.projectDir.allKotlinFiles()))
val affectedElements = arrayOf("B", "funB", "valB", "useB")
checkGenerated(*(annotatedElements.toSet() - affectedElements).toTypedArray())
checkNotGenerated(*affectedElements)
@@ -133,7 +158,19 @@ abstract class KaptIncrementalBaseIT(val shouldUseStubs: Boolean): BaseGradleIT(
project.build("build") {
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
assertCompiledKotlinSources(project.relativize(project.projectDir.allKotlinFiles()))
}
@@ -159,11 +196,31 @@ abstract class KaptIncrementalBaseIT(val shouldUseStubs: Boolean): BaseGradleIT(
project.build("build") {
assertSuccessful()
assertCompiledKotlinSources(project.relativize(bKt, useBKt))
assertKapt3FullyExecuted()
assertCompiledKotlinSourcesHandleKapt3(project.relativize(bKt, useBKt))
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) {
getGeneratedFileNames(*annotatedElementNames).forEach {
val file = project.projectDir.getFileByName(it)
@@ -9,6 +9,7 @@ buildscript {
apply plugin: "java"
apply plugin: "kotlin"
// APPLY_KAPT_PLUGIN
repositories {
mavenLocal()
@@ -7,7 +7,7 @@ import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.gradle.tasks.GradleMessageCollector
import org.jetbrains.kotlin.gradle.tasks.findToolsJar
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 java.io.File
import java.net.URL
@@ -30,7 +30,7 @@ internal open class GradleCompilerEnvironment(
internal class GradleIncrementalCompilerEnvironment(
compilerJar: File,
val changedFiles: ChangedFiles,
val reporter: GradleICReporter,
val reporter: ICReporter,
val workingDir: File,
messageCollector: GradleMessageCollector,
outputItemsCollector: OutputItemsCollector,
@@ -18,11 +18,14 @@ package org.jetbrains.kotlin.gradle.internal
import org.gradle.api.tasks.SourceTask
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.gradle.plugin.kotlinDebug
import org.jetbrains.kotlin.gradle.tasks.FilteringSourceRootsContainer
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
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 java.io.File