diff --git a/libraries/examples/annotation-processor-example/src/main/kotlin/example/ExampleAnnotationProcessor.kt b/libraries/examples/annotation-processor-example/src/main/kotlin/example/ExampleAnnotationProcessor.kt index 02051d5a87c..0d12379f62a 100644 --- a/libraries/examples/annotation-processor-example/src/main/kotlin/example/ExampleAnnotationProcessor.kt +++ b/libraries/examples/annotation-processor-example/src/main/kotlin/example/ExampleAnnotationProcessor.kt @@ -1,5 +1,6 @@ package example +import java.io.File import javax.annotation.processing.AbstractProcessor import javax.annotation.processing.RoundEnvironment import javax.lang.model.SourceVersion @@ -12,6 +13,8 @@ public class ExampleAnnotationProcessor : AbstractProcessor() { private companion object { val ANNOTATION_FQ_NAME = javaClass().getCanonicalName() val SUFFIX_OPTION = "suffix" + val GENERATE_KOTLIN_CODE_OPTION = "generate.kotlin.code" + val KAPT_KOTLIN_GENERATED_OPTION = "kapt.kotlin.generated" } override fun process(annotations: MutableSet?, roundEnv: RoundEnvironment): Boolean { @@ -20,17 +23,27 @@ public class ExampleAnnotationProcessor : AbstractProcessor() { val elementUtils = processingEnv.getElementUtils() val filer = processingEnv.getFiler() - val generatedFileSuffix = processingEnv.getOptions().get(SUFFIX_OPTION) ?: "Generated" + val options = processingEnv.getOptions() + val generatedFileSuffix = options[SUFFIX_OPTION] ?: "Generated" + val generateKotlinCode = "true" == options[GENERATE_KOTLIN_CODE_OPTION] + val kotlinGenerated = options[KAPT_KOTLIN_GENERATED_OPTION] for (element in elements) { val packageName = elementUtils.getPackageOf(element).getQualifiedName().toString() - val className = element.getSimpleName().toString().capitalize() + generatedFileSuffix + val simpleName = element.getSimpleName() + val className = simpleName.toString().capitalize() + generatedFileSuffix filer.createSourceFile(className).openWriter().use { with(it) { appendln("package $packageName;") - appendln() appendln("public final class $className {}") }} + + if (generateKotlinCode && kotlinGenerated != null && element.getKind() == ElementKind.CLASS) { + File(kotlinGenerated, "$simpleName.kt").writer().buffered().use { + it.appendln("package $packageName") + it.appendln("fun $simpleName.customToString() = \"$simpleName: \" + toString()") + } + } } return true; diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/AnnotationProcessingManager.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/AnnotationProcessingManager.kt index 178f7a87fbb..220406ed193 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/AnnotationProcessingManager.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/AnnotationProcessingManager.kt @@ -54,6 +54,12 @@ public class AnnotationProcessingManager( return File(aptWorkingDir, "$WRAPPERS_DIRECTORY/annotations.$taskQualifier.txt") } + fun getGeneratedKotlinSourceDir(): File { + val kotlinGeneratedDir = File(aptWorkingDir, "kotlinGenerated") + if (!kotlinGeneratedDir.exists()) kotlinGeneratedDir.mkdirs() + return kotlinGeneratedDir + } + fun setupKapt() { if (aptFiles.isEmpty()) return @@ -72,7 +78,8 @@ public class AnnotationProcessingManager( addGeneratedSourcesOutputToCompilerArgs(javaTask, aptOutputDir) - appendAnnotationsFileLocationArgument() + + appendAnnotationsArguments() appendAdditionalComplerArgs() } @@ -102,9 +109,10 @@ public class AnnotationProcessingManager( } } - private fun appendAnnotationsFileLocationArgument() { + private fun appendAnnotationsArguments() { javaTask.modifyCompilerArguments { list -> list.add("-Akapt.annotations=" + getAnnotationFile()) + list.add("-Akapt.kotlin.generated=" + getGeneratedKotlinSourceDir()) } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt index 01a1e0ea879..5a824f4c9f3 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt @@ -609,11 +609,13 @@ private fun Project.initKapt( kotlinTask.doFirst { kaptManager.generateJavaHackFile() + kotlinAfterJavaTask?.source(kaptManager.getGeneratedKotlinSourceDir()) } javaTask.doFirst { kaptManager.setupKapt() kaptManager.generateJavaHackFile() + kotlinAfterJavaTask?.source(kaptManager.getGeneratedKotlinSourceDir()) } javaTask.doLast { diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt b/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt index fe7006d689d..8a0fac51061 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt @@ -158,4 +158,19 @@ class KotlinGradleIT: BaseGradleIT() { assertFileExists("build/classes/main/example/AncestorClassGenerated.class") } } + + Test fun testKaptOutputKotlinCode() { + Project("kaptOutputKotlinCode", "1.12").build("build") { + assertSuccessful() + assertContains("kapt: Using class file stubs") + assertContains(":compileKotlin") + assertContains(":compileJava") + assertFileExists("build/tmp/kapt/main/wrappers/annotations.main.txt") + assertFileExists("build/generated/source/kapt/main/TestClassCustomized.java") + assertFileExists("build/tmp/kapt/main/kotlinGenerated/TestClass.kt") + assertFileExists("build/classes/main/example/TestClass.class") + assertFileExists("build/classes/main/example/TestClassCustomized.class") + } + } + } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/kaptOutputKotlinCode/build.gradle b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/kaptOutputKotlinCode/build.gradle new file mode 100644 index 00000000000..ed19a15fd87 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/kaptOutputKotlinCode/build.gradle @@ -0,0 +1,43 @@ +buildscript { + repositories { + mavenCentral() + maven { + url 'file://' + pathToKotlinPlugin + } + } + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:0.1-SNAPSHOT" + } +} + +apply plugin: "java" +apply plugin: "kotlin" + +repositories { + maven { + url 'file://' + pathToKotlinPlugin + } + mavenCentral() +} + +dependencies { + compile "org.jetbrains.kotlin:kotlin-stdlib:0.1-SNAPSHOT" + compile "org.jetbrains.kotlin:annotation-processor-example:0.1-SNAPSHOT" + kapt "org.jetbrains.kotlin:annotation-processor-example:0.1-SNAPSHOT" +} + +task show << { + buildscript.configurations.classpath.each { println it } +} + +task wrapper(type: Wrapper) { + gradleVersion="1.12" +} + +kapt { + generateStubs = true + arguments { + arg("suffix", "Customized") + arg("generate.kotlin.code", "true") + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/kaptOutputKotlinCode/src/main/java/test.kt b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/kaptOutputKotlinCode/src/main/java/test.kt new file mode 100644 index 00000000000..a8d981a9cc3 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/kaptOutputKotlinCode/src/main/java/test.kt @@ -0,0 +1,10 @@ +package example + +@example.ExampleAnnotation +public class TestClass { + + fun test() { + println(this.customToString()) + } + +} \ No newline at end of file