diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kapt3IT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kapt3IT.kt index b0f07f58576..e24abb3680f 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kapt3IT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kapt3IT.kt @@ -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") + } + } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/annotation-processor/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/annotation-processor/build.gradle new file mode 100644 index 00000000000..b1e6d0bae10 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/annotation-processor/build.gradle @@ -0,0 +1,6 @@ +apply plugin: 'kotlin' + +dependencies { + compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + compile 'com.github.yanex:takenoko:0.1' +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/annotation-processor/src/main/java/TestAnnotationProcessor.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/annotation-processor/src/main/java/TestAnnotationProcessor.kt new file mode 100644 index 00000000000..2b143c78138 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/annotation-processor/src/main/java/TestAnnotationProcessor.kt @@ -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?, 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 + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/annotation-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/annotation-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor new file mode 100644 index 00000000000..f18297ebb0f --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/annotation-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor @@ -0,0 +1 @@ +org.kotlin.annotationProcessor.TestAnnotationProcessor \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/build.gradle new file mode 100644 index 00000000000..dd647166215 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/build.gradle @@ -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' } + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/example/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/example/build.gradle new file mode 100644 index 00000000000..ed0bb8750a4 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/example/build.gradle @@ -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') + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/example/src/main/java/Example.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/example/src/main/java/Example.kt new file mode 100644 index 00000000000..2daa2b86333 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/example/src/main/java/Example.kt @@ -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 + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/example/src/test/java/test.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/example/src/test/java/test.kt new file mode 100644 index 00000000000..33854ef9a48 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/example/src/test/java/test.kt @@ -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) + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/gradle.properties b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/gradle.properties new file mode 100644 index 00000000000..dc3793168f1 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/gradle.properties @@ -0,0 +1 @@ +kapt.verbose=true \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/settings.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/settings.gradle new file mode 100644 index 00000000000..046135aeaf1 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/settings.gradle @@ -0,0 +1 @@ +include ':annotation-processor', ':example' \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/src/main/java/Library.java b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/src/main/java/Library.java new file mode 100644 index 00000000000..fa1b41a2634 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/src/main/java/Library.java @@ -0,0 +1,8 @@ +/* + * This Java source file was generated by the Gradle 'init' task. + */ +public class Library { + public boolean someLibraryMethod() { + return true; + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/src/test/java/LibraryTest.java b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/src/test/java/LibraryTest.java new file mode 100644 index 00000000000..645740d0301 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/localAnnotationProcessor/src/test/java/LibraryTest.java @@ -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()); + } +} diff --git a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/Kapt3Extension.kt b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/Kapt3Extension.kt index e814db4f627..d99a3192397 100644 --- a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/Kapt3Extension.kt +++ b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/Kapt3Extension.kt @@ -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 { + ClassUtilCore.clearJarURLCache() + val classpath = annotationProcessingClasspath + compileClasspath val classLoader = URLClassLoader(classpath.map { it.toURI().toURL() }.toTypedArray()) this.annotationProcessingClassLoader = classLoader