Kapt: Clear URL cache after changing annotation processor JAR

This commit is contained in:
Yan Zhulanow
2017-11-30 01:03:41 +09:00
parent 84a766de24
commit ef6be206d0
13 changed files with 188 additions and 0 deletions
@@ -300,4 +300,28 @@ open class Kapt3IT : Kapt3BaseIT() {
assertFileExists("build/classes/main/example/TestClassCustomized.class")
}
}
@Test
fun testChangesInLocalAnnotationProcessor() {
val project = Project("localAnnotationProcessor", GRADLE_VERSION, directoryPrefix = "kapt2")
project.build("build") {
assertSuccessful()
}
val testAnnotationProcessor = project.projectDir.getFileByName("TestAnnotationProcessor.kt")
testAnnotationProcessor.modify { text ->
val commentText = "// print warning "
assert(text.contains(commentText))
text.replace(commentText, "")
}
project.build("build") {
assertSuccessful()
assertNotContains(":example:kaptKotlin UP-TO-DATE",
":example:kaptGenerateStubsKotlin UP-TO-DATE")
assertContains("Additional warning message from AP")
}
}
}
@@ -0,0 +1,6 @@
apply plugin: 'kotlin'
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
compile 'com.github.yanex:takenoko:0.1'
}
@@ -0,0 +1,68 @@
package org.kotlin.annotationProcessor
import org.yanex.takenoko.*
import java.io.File
import javax.annotation.processing.*
import javax.lang.model.SourceVersion
import javax.lang.model.element.Element
import javax.lang.model.element.TypeElement
import javax.tools.Diagnostic.Kind.*
import javax.tools.StandardLocation
@Target(AnnotationTarget.CLASS)
annotation class TestAnnotation
@SupportedSourceVersion(SourceVersion.RELEASE_8)
@SupportedAnnotationTypes("org.kotlin.annotationProcessor.TestAnnotation")
@SupportedOptions(TestAnnotationProcessor.KAPT_KOTLIN_GENERATED_OPTION_NAME)
class TestAnnotationProcessor : AbstractProcessor() {
companion object {
const val KAPT_KOTLIN_GENERATED_OPTION_NAME = "kapt.kotlin.generated"
}
override fun process(annotations: MutableSet<out TypeElement>?, roundEnv: RoundEnvironment): Boolean {
val annotatedElements = roundEnv.getElementsAnnotatedWith(TestAnnotation::class.java)
if (annotatedElements.isEmpty()) return false
val kaptKotlinGeneratedDir = processingEnv.options[KAPT_KOTLIN_GENERATED_OPTION_NAME] ?: run {
processingEnv.messager.printMessage(ERROR, "Can't find the target directory for generated Kotlin files.")
return false
}
val generatedKtFile = kotlinFile("test.generated") {
for (element in annotatedElements) {
val typeElement = element.toTypeElementOrNull() ?: continue
property("simpleClassName") {
receiverType(typeElement.qualifiedName.toString())
getterExpression("this::class.java.simpleName")
}
}
}
File(kaptKotlinGeneratedDir, "testGenerated.kt").apply {
parentFile.mkdirs()
writeText(generatedKtFile.accept(PrettyPrinter(PrettyPrinterConfiguration())))
}
// print warning processingEnv.messager.printMessage(WARNING, "Additional warning message from AP")
processingEnv.filer
.createResource(StandardLocation.CLASS_OUTPUT, "abc", "helloWorld.txt")
.openWriter()
.use {
it.write("Hello, world!")
}
return true
}
fun Element.toTypeElementOrNull(): TypeElement? {
if (this !is TypeElement) {
processingEnv.messager.printMessage(ERROR, "Invalid element type, class expected", this)
return null
}
return this
}
}
@@ -0,0 +1,17 @@
buildscript {
repositories {
jcenter()
mavenLocal()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
jcenter()
mavenLocal()
maven { url 'https://jitpack.io' }
}
}
@@ -0,0 +1,22 @@
apply plugin: 'kotlin'
apply plugin: 'kotlin-kapt'
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
compile project(":annotation-processor")
kapt project(":annotation-processor")
compile files("a")
testCompile 'junit:junit:4.12'
}
apply plugin: 'idea'
idea {
module {
sourceDirs += files('build/generated/source/kapt/main', 'build/generated/source/kaptKotlin/main')
generatedSourceDirs += files('build/generated/source/kapt/main', 'build/generated/source/kaptKotlin/main')
}
}
@@ -0,0 +1,13 @@
package org.kotlin.test
import org.kotlin.annotationProcessor.TestAnnotation
import java.awt.Color
@TestAnnotation
class SimpleClass
class Test(val a: String) {
companion object {
val a = Color.PINK
}
}
@@ -0,0 +1,11 @@
package org.kotlin.test
import org.junit.Test
import org.junit.Assert.*
import test.generated.simpleClassName
class AnnotationTest {
@Test fun testSimple() {
assertEquals("SimpleClass", SimpleClass().simpleClassName)
}
}
@@ -0,0 +1,8 @@
/*
* This Java source file was generated by the Gradle 'init' task.
*/
public class Library {
public boolean someLibraryMethod() {
return true;
}
}
@@ -0,0 +1,12 @@
/*
* This Java source file was generated by the Gradle 'init' task.
*/
import org.junit.Test;
import static org.junit.Assert.*;
public class LibraryTest {
@Test public void testSomeLibraryMethod() {
Library classUnderTest = new Library();
assertTrue("someLibraryMethod should return 'true'", classUnderTest.someLibraryMethod());
}
}
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.kapt3
import com.intellij.ide.ClassUtilCore
import com.intellij.openapi.project.Project
import com.sun.tools.javac.tree.JCTree
import org.jetbrains.kotlin.analyzer.AnalysisResult
@@ -83,10 +84,13 @@ class ClasspathBasedKapt3Extension(
return super.analysisCompleted(project, module, bindingTrace, files)
} finally {
annotationProcessingClassLoader?.close()
ClassUtilCore.clearJarURLCache()
}
}
override fun loadProcessors(): List<Processor> {
ClassUtilCore.clearJarURLCache()
val classpath = annotationProcessingClasspath + compileClasspath
val classLoader = URLClassLoader(classpath.map { it.toURI().toURL() }.toTypedArray())
this.annotationProcessingClassLoader = classLoader