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 index acfc1e9e70a..c1d5ac1f95e 100644 --- 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 @@ -16,65 +16,49 @@ 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.KaptExtension 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() + companion object { + fun isEnabled(project: Project) = project.plugins.findPlugin(Kapt2GradleSubplugin::class.java) != null + } - 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) - } + override fun apply(project: Project) {} } // Subplugin for the Kotlin Gradle plugin class Kapt2KotlinGradleSubplugin : KotlinGradleSubplugin { - private companion object { - val VERBOSE_OPTION_NAME = "kapt2.verbose" + companion object { + private val VERBOSE_OPTION_NAME = "kapt.verbose" + + fun getKaptConfigurationName(sourceSetName: String): String { + return if (sourceSetName != "main") "kapt${sourceSetName.capitalize()}" else "kapt" + } } - override fun isApplicable(project: Project, task: AbstractCompile): Boolean { - return project.plugins.findPlugin(Kapt2GradleSubplugin::class.java) != null - } + override fun isApplicable(project: Project, task: AbstractCompile) = Kapt2GradleSubplugin.isEnabled(project) fun getKaptGeneratedDir(project: Project, sourceSetName: String): File { return File(project.project.buildDir, "generated/source/kapt2/$sourceSetName") } + private fun Project.findKaptConfiguration(sourceSetName: String): Configuration? { + return project.configurations.findByName(getKaptConfigurationName(sourceSetName)) + } + override fun apply( project: Project, kotlinCompile: AbstractCompile, @@ -82,41 +66,31 @@ class Kapt2KotlinGradleSubplugin : KotlinGradleSubplugin { 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) + assert((variantData != null) xor (javaSourceSet != null)) 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] + fun handleSourceSet(sourceSetName: String) { + val kapt2Configuration = project.findKaptConfiguration(sourceSetName) if (kapt2Configuration != null && kapt2Configuration.dependencies.size > 0) { javaCompile.dependsOn(kapt2Configuration.buildDependencies) kaptClasspath.addAll(kapt2Configuration.resolve()) } + } - getKaptGeneratedDir(project, javaSourceSet.name) - } + val generatedFilesDir = if (variantData != null) { + for (provider in (variantData as BaseVariantData<*>).sourceProviders) { + handleSourceSet((provider as AndroidSourceSet).name) + } + + getKaptGeneratedDir(project, variantData.name).apply { variantData.addJavaSourceFoldersToModel(this) } + } else { - throw IllegalArgumentException("variantData or javaSourceSet should be provided") + if (javaSourceSet == null) error("Java source set should not be null") + + handleSourceSet(javaSourceSet.name) + getKaptGeneratedDir(project, javaSourceSet.name) } // Skip annotation processing in kotlinc if no kapt dependencies were provided @@ -133,6 +107,11 @@ class Kapt2KotlinGradleSubplugin : KotlinGradleSubplugin { pluginOptions += SubpluginOption("generated", generatedFilesDir.canonicalPath) pluginOptions += SubpluginOption("classes", kotlinCompile.destinationDir.canonicalPath) + + val kaptExtension = project.extensions.getByType(KaptExtension::class.java) + if (kaptExtension.generateStubs) { + project.logger.warn("'kapt.generateStubs' is not used by the 'kotlin-kapt' plugin") + } if (project.hasProperty(VERBOSE_OPTION_NAME) && project.property(VERBOSE_OPTION_NAME) == "true") { pluginOptions += SubpluginOption("verbose", "true") 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 c57fa1ebae5..a10e86deba3 100755 --- 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 @@ -21,6 +21,8 @@ import org.gradle.api.tasks.compile.AbstractCompile import org.gradle.api.tasks.compile.JavaCompile import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments import org.jetbrains.kotlin.gradle.internal.AnnotationProcessingManager +import org.jetbrains.kotlin.gradle.internal.Kapt2GradleSubplugin +import org.jetbrains.kotlin.gradle.internal.Kapt2KotlinGradleSubplugin import org.jetbrains.kotlin.gradle.internal.initKapt import org.jetbrains.kotlin.gradle.plugin.android.AndroidGradleWrapper import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile @@ -135,7 +137,7 @@ class Kotlin2JvmSourceSetProcessor( var kotlinAfterJavaTask: KotlinCompile? = null - if (aptConfiguration.dependencies.size > 1) { + if (aptConfiguration.dependencies.size > 1 && !Kapt2GradleSubplugin.isEnabled(project)) { javaTask.dependsOn(aptConfiguration.buildDependencies) val (aptOutputDir, aptWorkingDir) = project.getAptDirsForSourceSet(sourceSetName) @@ -151,7 +153,7 @@ class Kotlin2JvmSourceSetProcessor( // otherwise some java roots can be ignored kotlinTask.source(kotlinSourceSet.kotlin) kotlinAfterJavaTask?.let { it.source(kotlinSourceSet.kotlin) } - configureJavaTask(kotlinTask, javaTask, kotlinAfterJavaTask, logger) + configureJavaTask(kotlinTask, javaTask, logger) createSyncOutputTask(project, kotlinTask, javaTask, kotlinAfterJavaTask, sourceSetName) } } @@ -332,27 +334,39 @@ open class KotlinAndroidPlugin( kotlinTask.description = "Compiles the $variantDataName kotlin." kotlinTask.setDependsOn(javaTask.dependsOn) + val isKapt2Enabled = Kapt2GradleSubplugin.isEnabled(project) + val aptFiles = arrayListOf() - for (provider in variantData.sourceProviders) { - val aptConfiguration = aptConfigurations[(provider as AndroidSourceSet).name] - // Ignore if there's only an annotation processor wrapper in dependencies (added by default) - if (aptConfiguration != null && aptConfiguration.dependencies.size > 1) { - javaTask.dependsOn(aptConfiguration.buildDependencies) - aptFiles.addAll(aptConfiguration.resolve()) + + if (!isKapt2Enabled) { + for (provider in variantData.sourceProviders) { + val aptConfiguration = aptConfigurations[(provider as AndroidSourceSet).name] + // Ignore if there's only an annotation processor wrapper in dependencies (added by default) + if (aptConfiguration != null && aptConfiguration.dependencies.size > 1) { + javaTask.dependsOn(aptConfiguration.buildDependencies) + aptFiles.addAll(aptConfiguration.resolve()) + } } } 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) + + kotlinTask.mapClasspath { + javaTask.classpath + project.files(AndroidGradleWrapper.getRuntimeJars(androidPlugin, androidExt)) + } + var kotlinAfterJavaTask: KotlinCompile? = null - if (javaTask is JavaCompile && aptFiles.isNotEmpty()) { + if (javaTask is JavaCompile && aptFiles.isNotEmpty() && !isKapt2Enabled) { + val (aptOutputDir, aptWorkingDir) = project.getAptDirsForSourceSet(variantDataName) + + variantData.addJavaSourceFoldersToModel(aptOutputDir) + val kaptManager = AnnotationProcessingManager(kotlinTask, javaTask, variantDataName, aptFiles.toSet(), aptOutputDir, aptWorkingDir, variantData) - kotlinAfterJavaTask = project.initKapt(kotlinTask, javaTask, kaptManager, variantDataName, kotlinOptions, subpluginEnvironment, tasksProvider) + kotlinAfterJavaTask = project.initKapt(kotlinTask, javaTask, kaptManager, + variantDataName, kotlinOptions, subpluginEnvironment, tasksProvider) } configureSources(kotlinTask, variantData) @@ -360,7 +374,7 @@ open class KotlinAndroidPlugin( configureSources(kotlinAfterJavaTask, variantData) } - configureJavaTask(kotlinTask, javaTask, kotlinAfterJavaTask, logger) + configureJavaTask(kotlinTask, javaTask, logger) createSyncOutputTask(project, kotlinTask, javaTask, kotlinAfterJavaTask, variantDataName) } } @@ -383,7 +397,7 @@ open class KotlinAndroidPlugin( get() = variantConfiguration.sortedSourceProviders } -private fun configureJavaTask(kotlinTask: KotlinCompile, javaTask: AbstractCompile, kotlinAfterJavaTask: KotlinCompile?, logger: Logger) { +private fun configureJavaTask(kotlinTask: KotlinCompile, javaTask: AbstractCompile, logger: Logger) { // Since we cannot update classpath statically, java not able to detect changes in the classpath after kotlin compiler. // Therefore this (probably inefficient since java cannot decide "uptodateness" by the list of changed class files, but told // explicitly being out of date whenever any kotlin files are compiled @@ -509,7 +523,7 @@ private fun Project.getAptDirsForSourceSet(sourceSetName: String): Pair