KAPT: add tests for processed types, remove dead code, simplify logic
Add integration test which checks if only types can be reprocessed in an incremental round. Also, remove unused `invalidateTypesForFiles` method. Furthermore, clarify that types that are reprocessed (i.e types from .class files) are not necessarily aggregating types, but simply types that should be reprocessed. Test: KaptIncrementalWithIsolatingApt.testClasspathChangesCauseTypesToBeReprocessed
This commit is contained in:
committed by
Mikhael Bogdanov
parent
08a2b47c77
commit
11673bd09c
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.gradle.incapt;
|
||||
|
||||
import javax.annotation.processing.AbstractProcessor;
|
||||
import javax.annotation.processing.RoundEnvironment;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
public class IncrementalAggregatingReferencingClasspathProcessor extends AbstractProcessor {
|
||||
|
||||
// Type that the generated source will extend.
|
||||
public static final String CLASSPATH_TYPE = "com.example.FromClasspath";
|
||||
|
||||
private Set<String> values = new TreeSet<String>();
|
||||
|
||||
@Override
|
||||
public Set<String> getSupportedAnnotationTypes() {
|
||||
return Collections.singleton("example.KotlinFilerGenerated");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||
for (TypeElement annotation : annotations) {
|
||||
for (Element element : roundEnv.getElementsAnnotatedWith(annotation)) {
|
||||
if (element instanceof TypeElement || element instanceof ExecutableElement || element instanceof VariableElement) {
|
||||
values.add(element.getSimpleName().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (roundEnv.processingOver() && !values.isEmpty()) {
|
||||
|
||||
try (Writer writer = processingEnv.getFiler().createSourceFile("com.example.AggGenerated").openWriter()) {
|
||||
writer.append("package ").append("com.example").append(";");
|
||||
writer.append("\npublic class ").append("AggGenerated").append(" extends ").append(CLASSPATH_TYPE).append(" {}");
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
values.clear();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+97
@@ -5,11 +5,14 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle
|
||||
|
||||
import org.jetbrains.kotlin.gradle.incapt.IncrementalAggregatingReferencingClasspathProcessor
|
||||
import org.jetbrains.kotlin.gradle.incapt.IncrementalBinaryIsolatingProcessor
|
||||
import org.jetbrains.kotlin.gradle.incapt.IncrementalProcessor
|
||||
import org.jetbrains.kotlin.gradle.incapt.IncrementalProcessorReferencingClasspath
|
||||
import org.jetbrains.kotlin.gradle.util.AGPVersion
|
||||
import org.jetbrains.kotlin.gradle.util.modify
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Assume
|
||||
import org.junit.Test
|
||||
import test.kt33617.MyClass
|
||||
@@ -275,6 +278,92 @@ class KaptIncrementalWithIsolatingApt : KaptIncrementalIT() {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure that changes to classpath can cause types to be reprocessed (i.e types in generated .class files that contain annotations
|
||||
* claimed by annotation processors).
|
||||
*/
|
||||
@Test
|
||||
fun testClasspathChangesCauseTypesToBeReprocessed() {
|
||||
val project = Project(
|
||||
"kaptIncrementalCompilationProject",
|
||||
GradleVersionRequired.None
|
||||
).apply {
|
||||
setupIncrementalAptProject(
|
||||
Pair("ISOLATING", IncrementalBinaryIsolatingProcessor::class.java),
|
||||
Pair("AGGREGATING", IncrementalAggregatingReferencingClasspathProcessor::class.java),
|
||||
)
|
||||
}
|
||||
project.gradleSettingsScript().writeText("include ':', ':lib'")
|
||||
val classpathTypeSource = project.projectDir.resolve("lib").run {
|
||||
mkdirs()
|
||||
resolve("build.gradle").writeText("apply plugin: 'java'")
|
||||
val source =
|
||||
resolve("src/main/java/" + IncrementalAggregatingReferencingClasspathProcessor.CLASSPATH_TYPE.replace(".", "/") + ".java")
|
||||
source.parentFile.mkdirs()
|
||||
|
||||
source.writeText(
|
||||
"""
|
||||
package ${IncrementalAggregatingReferencingClasspathProcessor.CLASSPATH_TYPE.substringBeforeLast(".")};
|
||||
public class ${IncrementalAggregatingReferencingClasspathProcessor.CLASSPATH_TYPE.substringAfterLast(".")} {}
|
||||
""".trimIndent()
|
||||
)
|
||||
return@run source
|
||||
}
|
||||
project.gradleBuildScript().appendText(
|
||||
"""
|
||||
|
||||
dependencies {
|
||||
implementation project(':lib')
|
||||
}
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
// Remove all sources, and add only 1 source file
|
||||
project.projectDir.resolve("src").let {
|
||||
it.deleteRecursively()
|
||||
with(it.resolve("main/java/example/A.kt")) {
|
||||
parentFile.mkdirs()
|
||||
writeText(
|
||||
"""
|
||||
package example
|
||||
|
||||
annotation class ExampleAnnotation
|
||||
@ExampleAnnotation
|
||||
class A
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val allKotlinStubs = setOf(
|
||||
project.projectDir.resolve("build/tmp/kapt3/stubs/main/example/ExampleAnnotation.java").canonicalPath,
|
||||
project.projectDir.resolve("build/tmp/kapt3/stubs/main/example/A.java").canonicalPath,
|
||||
project.projectDir.resolve("build/tmp/kapt3/stubs/main/error/NonExistentClass.java").canonicalPath
|
||||
)
|
||||
|
||||
project.build("clean", "build") {
|
||||
assertSuccessful()
|
||||
assertEquals(allKotlinStubs, getProcessedSources(output))
|
||||
|
||||
assertTrue(
|
||||
"Aggregating sources exists",
|
||||
fileInWorkingDir("build/generated/source/kapt/main/com/example/AggGenerated.java").exists()
|
||||
)
|
||||
}
|
||||
|
||||
// change type that the aggregated generated source reference
|
||||
classpathTypeSource.writeText(classpathTypeSource.readText().replace("}", "int i = 10;\n}"))
|
||||
project.build("build") {
|
||||
assertSuccessful()
|
||||
assertEquals(emptySet<String>(), getProcessedSources(output))
|
||||
assertEquals(setOf("example.AGenerated"), getProcessedTypes(output))
|
||||
assertTrue(
|
||||
"Aggregating sources exists",
|
||||
fileInWorkingDir("build/generated/source/kapt/main/com/example/AggGenerated.java").exists()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private const val patternApt = "Processing java sources with annotation processors:"
|
||||
@@ -285,6 +374,14 @@ fun getProcessedSources(output: String): Set<String> {
|
||||
}
|
||||
}
|
||||
|
||||
private const val patternClassesApt = "Processing types with annotation processors: "
|
||||
fun getProcessedTypes(output: String): Set<String> {
|
||||
return output.lines().filter { it.contains(patternClassesApt) }.flatMapTo(HashSet()) { logging ->
|
||||
val indexOf = logging.indexOf(patternClassesApt) + patternClassesApt.length
|
||||
logging.drop(indexOf).split(",").map { it.trim() }.filter { !it.isEmpty() }.toSet()
|
||||
}
|
||||
}
|
||||
|
||||
fun BaseGradleIT.Project.setupIncrementalAptProject(
|
||||
procType: String,
|
||||
buildFile: File = projectDir.resolve("build.gradle"),
|
||||
|
||||
+4
@@ -15,11 +15,15 @@ apply plugin: "kotlin-kapt"
|
||||
repositories {
|
||||
jcenter()
|
||||
mavenLocal()
|
||||
maven {
|
||||
url "https://jetbrains.bintray.com/intellij-third-party-dependencies/"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
implementation "org.jetbrains.kotlin:annotation-processor-example:$kotlin_version"
|
||||
kapt "org.jetbrains.kotlin:annotation-processor-example:$kotlin_version"
|
||||
kapt "org.jetbrains.intellij.deps:asm-all:9.0"
|
||||
testImplementation 'junit:junit:4.12'
|
||||
}
|
||||
Reference in New Issue
Block a user