From 407af3a0e53f4646d9170eb3f6d297c498c478f1 Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Tue, 21 Jun 2016 21:09:45 +0300 Subject: [PATCH] Kapt: Gradle plugin for the new kapt (cherry picked from commit f4fc8f1) --- build.xml | 52 +++++- compiler/compiler.pro | 4 + .../main/kotlin/example/ExampleSubplugin.kt | 11 +- .../kotlin-annotation-processing/pom.xml | 89 ++++++++++- .../gradle/plugin/KotlinGradleSubplugin.kt | 25 ++- .../gradle/internal/AndroidSubplugin.kt | 9 +- .../internal/AnnotationProcessingManager.kt | 2 +- .../internal/Kapt2KotlinGradleSubplugin.kt | 150 ++++++++++++++++++ .../kotlin/gradle/plugin/KotlinPlugin.kt | 19 ++- .../gradle-plugins/kotlin-kapt2.properties | 1 + ...kotlin.gradle.plugin.KotlinGradleSubplugin | 3 +- ...otlin.compiler.plugin.CommandLineProcessor | 1 + ....kotlin.compiler.plugin.ComponentRegistrar | 1 + 13 files changed, 344 insertions(+), 23 deletions(-) mode change 100644 => 100755 libraries/tools/kotlin-annotation-processing/pom.xml create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/Kapt2KotlinGradleSubplugin.kt mode change 100644 => 100755 libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/kotlin-kapt2.properties create mode 100644 plugins/annotation-processing/src/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor create mode 100644 plugins/annotation-processing/src/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar diff --git a/build.xml b/build.xml index d57b4de722a..40787f04057 100644 --- a/build.xml +++ b/build.xml @@ -765,6 +765,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1093,11 +1141,11 @@ depends="builtins,stdlib,kotlin-test,core,reflection,pack-runtime,pack-runtime-sources,mock-runtime-for-test"/> { + override fun apply( + project: Project, + kotlinCompile: AbstractCompile, + javaCompile: AbstractCompile?, + variantData: Any?, + javaSourceSet: SourceSet? + ): List { println("ExampleSubplugin loaded") return listOf(SubpluginOption("exampleKey", "exampleValue")) } diff --git a/libraries/tools/kotlin-annotation-processing/pom.xml b/libraries/tools/kotlin-annotation-processing/pom.xml old mode 100644 new mode 100755 index 38c70ae487c..9cc89dfbbd8 --- a/libraries/tools/kotlin-annotation-processing/pom.xml +++ b/libraries/tools/kotlin-annotation-processing/pom.xml @@ -6,6 +6,12 @@ 4.0.0 3.0.4 + ${basedir}/src/main/kotlin + ${basedir}/../../../plugins/annotation-processing/src + ${basedir}/../../../plugins/java-model-wrappers/src + ${basedir}/target/src/main/kotlin + ${basedir}/target/src/test/kotlin + ${basedir}/target/resource @@ -33,6 +39,12 @@ kotlin-stdlib ${project.version} + + org.jetbrains.kotlin + kotlin-compiler-embeddable + ${project.version} + provided + org.jetbrains.kotlin gradle-api @@ -48,15 +60,79 @@ - ${project.basedir}/src/main/kotlin - ${project.basedir}/src/test/kotlin + ${annotation-processing.target-src} + ${annotation-processing.target-src-test} + + + ${annotation-processing.target-resource} + + + + maven-resources-plugin + 3.0.0 + + + copy-sources + validate + + copy-resources + + + ${annotation-processing.target-src} + + ${annotation-processing.src} + ${java-model-wrappers.src} + ${old-kapt.src} + + + + + copy-resources + validate + + copy-resources + + + ${annotation-processing.target-resource}/META-INF + + ${annotation-processing.src}/META-INF + + + + + + + com.google.code.maven-replacer-plugin + replacer + 1.5.3 + + + generate-sources + + replace + + + + + + ${annotation-processing.target-src}/** + + + + com\.intellij + org.jetbrains.kotlin.com.intellij + + + + kotlin-maven-plugin org.jetbrains.kotlin ${project.version} + ${env.JDK_18} ${basedir}/kotlinAnnotation @@ -67,6 +143,11 @@ compile compile compile + + + ${annotation-processing.target-src} + + @@ -76,6 +157,10 @@ + + org.apache.maven.plugins + maven-compiler-plugin + maven-failsafe-plugin 2.6 diff --git a/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinGradleSubplugin.kt b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinGradleSubplugin.kt index d70679f7c43..b6e411cd748 100644 --- a/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinGradleSubplugin.kt +++ b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinGradleSubplugin.kt @@ -17,14 +17,23 @@ package org.jetbrains.kotlin.gradle.plugin import org.gradle.api.Project +import org.gradle.api.tasks.SourceSet import org.gradle.api.tasks.compile.AbstractCompile -public class SubpluginOption(val key: String, val value: String) +class SubpluginOption(val key: String, val value: String) -public interface KotlinGradleSubplugin { - public fun isApplicable(project: Project, task: AbstractCompile): Boolean - public fun getExtraArguments(project: Project, task: AbstractCompile): List - public fun getPluginName(): String - public fun getGroupName(): String - public fun getArtifactName(): String -} \ No newline at end of file +interface KotlinGradleSubplugin { + fun isApplicable(project: Project, task: AbstractCompile): Boolean + + fun apply( + project: Project, + kotlinCompile: AbstractCompile, + javaCompile: AbstractCompile?, + variantData: Any?, + javaSourceSet: SourceSet? + ): List + + fun getPluginName(): String + fun getGroupName(): String + fun getArtifactName(): String +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/AndroidSubplugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/AndroidSubplugin.kt index b7350df55c7..1d723161e12 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/AndroidSubplugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/AndroidSubplugin.kt @@ -21,6 +21,7 @@ import com.android.build.gradle.api.AndroidSourceSet import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.UnknownDomainObjectException +import org.gradle.api.tasks.SourceSet import org.gradle.api.tasks.compile.AbstractCompile import org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin import org.jetbrains.kotlin.gradle.plugin.SubpluginOption @@ -58,7 +59,13 @@ class AndroidSubplugin : KotlinGradleSubplugin { return true } - override fun getExtraArguments(project: Project, task: AbstractCompile): List { + override fun apply( + project: Project, + kotlinCompile: AbstractCompile, + javaCompile: AbstractCompile?, + variantData: Any?, + javaSourceSet: SourceSet? + ): List { val androidExtension = project.extensions.getByName("android") as? BaseExtension ?: return emptyList() val sourceSets = androidExtension.sourceSets 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 a55dd4005fa..1dc187d1250 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 @@ -63,7 +63,7 @@ fun Project.initKapt( kotlinAfterJavaTask.source(kaptManager.generatedKotlinSourceDir) kotlinAfterJavaTask.source(kaptManager.aptOutputDir) - subpluginEnvironment.addSubpluginArguments(this, kotlinAfterJavaTask) + subpluginEnvironment.addSubpluginArguments(this, kotlinAfterJavaTask, javaTask, null, null) javaTask.doLast { moveGeneratedJavaFilesToCorrespondingDirectories(kaptManager.aptOutputDir) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/Kapt2KotlinGradleSubplugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/Kapt2KotlinGradleSubplugin.kt new file mode 100644 index 00000000000..acfc1e9e70a --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/Kapt2KotlinGradleSubplugin.kt @@ -0,0 +1,150 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.gradle.internal + +import com.android.build.gradle.BaseExtension +import com.android.build.gradle.api.AndroidSourceSet +import com.android.build.gradle.internal.variant.BaseVariantData +import com.android.builder.model.SourceProvider +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.UnknownDomainObjectException +import org.gradle.api.artifacts.Configuration +import org.gradle.api.internal.HasConvention +import org.gradle.api.plugins.JavaPluginConvention +import org.gradle.api.tasks.SourceSet +import org.gradle.api.tasks.compile.AbstractCompile +import org.gradle.api.tasks.compile.JavaCompile +import org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin +import org.jetbrains.kotlin.gradle.plugin.SubpluginOption +import java.io.File + +// apply plugin: 'kotlin-kapt2' +class Kapt2GradleSubplugin : Plugin { + private val kapt2Configurations = mutableMapOf>() + + fun getConfigurations(project: Project): Map = kapt2Configurations[project] ?: emptyMap() + + override fun apply(project: Project) { + val androidExt = project.extensions.findByName("android") as? BaseExtension + if (androidExt != null) { + androidExt.sourceSets.all { sourceSet -> + addKapt2Configuration(project, sourceSet.name) + } + } + else { + val javaPluginConvention = project.convention.getPlugin(JavaPluginConvention::class.java) + javaPluginConvention.sourceSets.all { sourceSet -> + addKapt2Configuration(project, sourceSet.name) + } + } + } + + private fun addKapt2Configuration(project: Project, sourceSetName: String) { + val aptConfigurationName = if (sourceSetName != "main") "kapt2${sourceSetName.capitalize()}" else "kapt2" + val configuration = project.configurations.create(aptConfigurationName) + kapt2Configurations.getOrPut(project, { mutableMapOf() }).put(sourceSetName, configuration) + } +} + +// Subplugin for the Kotlin Gradle plugin +class Kapt2KotlinGradleSubplugin : KotlinGradleSubplugin { + private companion object { + val VERBOSE_OPTION_NAME = "kapt2.verbose" + } + + override fun isApplicable(project: Project, task: AbstractCompile): Boolean { + return project.plugins.findPlugin(Kapt2GradleSubplugin::class.java) != null + } + + fun getKaptGeneratedDir(project: Project, sourceSetName: String): File { + return File(project.project.buildDir, "generated/source/kapt2/$sourceSetName") + } + + override fun apply( + project: Project, + kotlinCompile: AbstractCompile, + javaCompile: AbstractCompile?, + variantData: Any?, + javaSourceSet: SourceSet? + ): List { + //assertion only one variantData / javaSourceSet + + // delete + if (javaCompile == null) error("Java compile task should exist") + + val kapt2Configurations = project.plugins.findPlugin(Kapt2GradleSubplugin::class.java).getConfigurations(project) + + val pluginOptions = mutableListOf() + val kaptClasspath = arrayListOf() + + val generatedFilesDir = if (variantData != null) { + variantData as BaseVariantData<*> + + for (provider in variantData.sourceProviders) { + val kapt2Configuration = kapt2Configurations[(provider as AndroidSourceSet).name] + // extract & java + if (kapt2Configuration != null && kapt2Configuration.dependencies.size > 0) { + javaCompile.dependsOn(kapt2Configuration.buildDependencies) + kaptClasspath.addAll(kapt2Configuration.resolve()) + } + } + + getKaptGeneratedDir(project, variantData.name).apply { variantData.addJavaSourceFoldersToModel(this) } + } + else if (javaSourceSet != null) { + val kapt2Configuration = kapt2Configurations[javaSourceSet.name] + if (kapt2Configuration != null && kapt2Configuration.dependencies.size > 0) { + javaCompile.dependsOn(kapt2Configuration.buildDependencies) + kaptClasspath.addAll(kapt2Configuration.resolve()) + } + + getKaptGeneratedDir(project, javaSourceSet.name) + } + else { + throw IllegalArgumentException("variantData or javaSourceSet should be provided") + } + + // Skip annotation processing in kotlinc if no kapt dependencies were provided + if (kaptClasspath.isEmpty()) return emptyList() + kaptClasspath.forEach { pluginOptions += SubpluginOption("apclasspath", it.absolutePath) } + + javaCompile.source(generatedFilesDir) + + // Completely disable annotation processing in Java + (javaCompile as? JavaCompile)?.let { javaCompile -> + val options = javaCompile.options + options.compilerArgs = options.compilerArgs.filter { !it.startsWith("-proc:") } + "-proc:none" + } + + pluginOptions += SubpluginOption("generated", generatedFilesDir.canonicalPath) + pluginOptions += SubpluginOption("classes", kotlinCompile.destinationDir.canonicalPath) + + if (project.hasProperty(VERBOSE_OPTION_NAME) && project.property(VERBOSE_OPTION_NAME) == "true") { + pluginOptions += SubpluginOption("verbose", "true") + } + + return pluginOptions + } + + private val BaseVariantData<*>.sourceProviders: List + get() = variantConfiguration.sortedSourceProviders + + override fun getPluginName() = "org.jetbrains.kotlin.kapt2" + override fun getGroupName() = "org.jetbrains.kotlin" + override fun getArtifactName() = "kotlin-annotation-processing" +} \ No newline at end of file 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 old mode 100644 new mode 100755 index 0c830ec9c45..c57fa1ebae5 --- 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 @@ -125,10 +125,12 @@ class Kotlin2JvmSourceSetProcessor( project.afterEvaluate { project -> if (project != null) { - val subpluginEnvironment = loadSubplugins(project) - subpluginEnvironment.addSubpluginArguments(project, kotlinTask) - val javaTask = project.tasks.findByName(sourceSet.compileJavaTaskName) + + val subpluginEnvironment = loadSubplugins(project) + subpluginEnvironment.addSubpluginArguments(project, kotlinTask, + javaTask as? AbstractCompile, null, sourceSet) + if (javaTask !is JavaCompile) return@afterEvaluate var kotlinAfterJavaTask: KotlinCompile? = null @@ -340,7 +342,7 @@ open class KotlinAndroidPlugin( } } - subpluginEnvironment.addSubpluginArguments(project, kotlinTask) + subpluginEnvironment.addSubpluginArguments(project, kotlinTask, javaTask, variantData, null) kotlinTask.mapClasspath { javaTask.classpath + project.files(AndroidGradleWrapper.getRuntimeJars(androidPlugin, androidExt)) } val (aptOutputDir, aptWorkingDir) = project.getAptDirsForSourceSet(variantDataName) variantData.addJavaSourceFoldersToModel(aptOutputDir) @@ -471,7 +473,12 @@ class SubpluginEnvironment( val subplugins: List ) { - fun addSubpluginArguments(project: Project, kotlinTask: KotlinCompile) { + fun addSubpluginArguments( + project: Project, + kotlinTask: KotlinCompile, + javaTask: AbstractCompile?, + variantData: Any?, + javaSourceSet: SourceSet?) { val pluginOptions = kotlinTask.pluginOptions for (subplugin in subplugins) { @@ -484,7 +491,7 @@ class SubpluginEnvironment( val subpluginClasspath = subpluginClasspaths[subplugin] ?: continue subpluginClasspath.forEach { pluginOptions.addClasspathEntry(it) } - for (arg in subplugin.getExtraArguments(project, kotlinTask)) { + for (arg in subplugin.apply(project, kotlinTask, javaTask, variantData, javaSourceSet)) { pluginOptions.addPluginArgument(subplugin.getPluginName(), arg.key, arg.value) } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/kotlin-kapt2.properties b/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/kotlin-kapt2.properties new file mode 100644 index 00000000000..750daf39fac --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/kotlin-kapt2.properties @@ -0,0 +1 @@ +implementation-class=org.jetbrains.kotlin.gradle.internal.Kapt2GradleSubplugin \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/services/org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin b/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/services/org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin index c4858027308..70f073c8d95 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/services/org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin +++ b/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/services/org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin @@ -1 +1,2 @@ -org.jetbrains.kotlin.gradle.internal.AndroidSubplugin \ No newline at end of file +org.jetbrains.kotlin.gradle.internal.AndroidSubplugin +org.jetbrains.kotlin.gradle.internal.Kapt2KotlinGradleSubplugin \ No newline at end of file diff --git a/plugins/annotation-processing/src/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor b/plugins/annotation-processing/src/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor new file mode 100644 index 00000000000..769c1967d51 --- /dev/null +++ b/plugins/annotation-processing/src/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor @@ -0,0 +1 @@ +org.jetbrains.kotlin.annotation.processing.AnnotationProcessingCommandLineProcessor \ No newline at end of file diff --git a/plugins/annotation-processing/src/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar b/plugins/annotation-processing/src/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar new file mode 100644 index 00000000000..4af1a3bcc17 --- /dev/null +++ b/plugins/annotation-processing/src/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar @@ -0,0 +1 @@ +org.jetbrains.kotlin.annotation.processing.AnnotationProcessingComponentRegistrar \ No newline at end of file