From 749a5742343830d7aaafdd6d22a0df493dd1dd97 Mon Sep 17 00:00:00 2001 From: Leonid Startsev Date: Thu, 24 Aug 2017 17:26:01 +0300 Subject: [PATCH] Support for gradle subplugins in Kotlin2JS compilation Because ServiceLoader can't check generic argument of KotlinGradleSubplugin in runtime, we have to manually check the type in `isApplicable`. --- .../gradle/plugin/KotlinGradleSubplugin.kt | 6 ++-- .../gradle/internal/AndroidSubplugin.kt | 5 +-- .../internal/Kapt3KotlinGradleSubplugin.kt | 4 +-- .../kotlin/gradle/plugin/KotlinPlugin.kt | 31 ++++++++++++------- .../jetbrains/kotlin/gradle/tasks/Tasks.kt | 22 +++++++++---- 5 files changed, 44 insertions(+), 24 deletions(-) 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 f0894b98132..6147d9f01bd 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 @@ -23,10 +23,10 @@ import org.gradle.api.tasks.compile.AbstractCompile class SubpluginOption(val key: String, val value: String) interface KotlinGradleSubplugin { - fun isApplicable(project: Project, task: KotlinCompile): Boolean - + fun isApplicable(project: Project, task: AbstractCompile): Boolean + fun apply( - project: Project, + project: Project, kotlinCompile: KotlinCompile, javaCompile: AbstractCompile, variantData: Any?, 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 e1a71089f76..dc908ebb158 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 @@ -74,7 +74,8 @@ class AndroidExtensionsSubpluginIndicator : Plugin { } class AndroidSubplugin : KotlinGradleSubplugin { - override fun isApplicable(project: Project, task: KotlinCompile): Boolean { + override fun isApplicable(project: Project, task: AbstractCompile): Boolean { + if (task !is KotlinCompile) return false try { project.extensions.getByName("android") as? BaseExtension ?: return false } catch (e: UnknownDomainObjectException) { @@ -89,7 +90,7 @@ class AndroidSubplugin : KotlinGradleSubplugin { override fun apply( project: Project, kotlinCompile: KotlinCompile, - javaCompile: AbstractCompile, + javaCompile: AbstractCompile, variantData: Any?, androidProjectHandler: Any?, javaSourceSet: SourceSet? diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/Kapt3KotlinGradleSubplugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/Kapt3KotlinGradleSubplugin.kt index 1d3c96b1dab..0502f635d75 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/Kapt3KotlinGradleSubplugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/Kapt3KotlinGradleSubplugin.kt @@ -84,7 +84,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin { private val kotlinToKaptGenerateStubsTasksMap = mutableMapOf() - override fun isApplicable(project: Project, task: KotlinCompile) = Kapt3GradleSubplugin.isEnabled(project) + override fun isApplicable(project: Project, task: AbstractCompile) = task is KotlinCompile && Kapt3GradleSubplugin.isEnabled(project) fun getKaptGeneratedDir(project: Project, sourceSetName: String): File { return File(project.project.buildDir, "generated/source/kapt/$sourceSetName") @@ -123,7 +123,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin { } override fun apply( - project: Project, + project: Project, kotlinCompile: KotlinCompile, javaCompile: AbstractCompile, variantData: Any?, 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 dcb2bfdad46..f635306632f 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,7 @@ import org.gradle.api.tasks.SourceSet import org.gradle.api.tasks.SourceSetOutput import org.gradle.api.tasks.compile.AbstractCompile import org.gradle.api.tasks.compile.JavaCompile +import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments import org.jetbrains.kotlin.com.intellij.openapi.util.io.FileUtil import org.jetbrains.kotlin.com.intellij.openapi.util.text.StringUtil.compareVersionNumbers import org.jetbrains.kotlin.com.intellij.util.ReflectionUtil @@ -269,7 +270,11 @@ internal class Kotlin2JsSourceSetProcessor( createCleanSourceMapTask() // outputFile can be set later during the configuration phase, get it only after the phase: - project.afterEvaluate { + project.afterEvaluate { project -> + val subpluginEnvironment: SubpluginEnvironment = loadSubplugins(project) + val appliedPlugins = subpluginEnvironment.addSubpluginOptions( + project, kotlinTask, kotlinTask, null, null, sourceSet) + kotlinTask.kotlinOptions.outputFile = File(kotlinTask.outputFile).absolutePath val outputDir = File(kotlinTask.outputFile).parentFile @@ -285,6 +290,10 @@ internal class Kotlin2JsSourceSetProcessor( if (!isSeparateClassesDirSupported) { sourceSet.output.setClassesDir(kotlinTask.destinationDir) } + + appliedPlugins + .flatMap { it.getSubpluginKotlinTasks(project, kotlinTask) } + .forEach { it.source(kotlinSourceSet.kotlin) } } } @@ -694,7 +703,7 @@ private fun removeAnnotationProcessingPluginClasspathEntry(kotlinCompile: Kotlin private fun loadSubplugins(project: Project): SubpluginEnvironment { try { val subplugins = ServiceLoader.load(KotlinGradleSubplugin::class.java, project.buildscript.classLoader) - .map { @Suppress("UNCHECKED_CAST") (it as KotlinGradleSubplugin) } + .map { @Suppress("UNCHECKED_CAST") (it as KotlinGradleSubplugin) } return SubpluginEnvironment(project.resolveSubpluginArtifacts(subplugins), subplugins) } catch (e: NoClassDefFoundError) { @@ -704,9 +713,9 @@ private fun loadSubplugins(project: Project): SubpluginEnvironment { } } -internal fun Project.resolveSubpluginArtifacts( - subplugins: List> -): Map, List> { +internal fun Project.resolveSubpluginArtifacts( + subplugins: List> +): Map, List> { fun Project.getResolvedArtifacts() = buildscript.configurations.getByName("classpath") .resolvedConfiguration.resolvedArtifacts @@ -716,7 +725,7 @@ internal fun Project.resolveSubpluginArtifacts( resolvedClasspathArtifacts += rootProject.getResolvedArtifacts() } - val subpluginClasspaths = hashMapOf, List>() + val subpluginClasspaths = hashMapOf, List>() for (subplugin in subplugins) { val file = resolvedClasspathArtifacts @@ -733,18 +742,18 @@ internal fun Project.resolveSubpluginArtifacts( } internal class SubpluginEnvironment( - val subpluginClasspaths: Map, List>, - val subplugins: List> + val subpluginClasspaths: Map, List>, + val subplugins: List> ) { - fun addSubpluginOptions( + fun addSubpluginOptions( project: Project, - kotlinTask: KotlinCompile, + kotlinTask: AbstractKotlinCompile, javaTask: AbstractCompile, variantData: Any?, androidProjectHandler: AbstractAndroidProjectHandler?, javaSourceSet: SourceSet? - ): List> { + ): List>> { val pluginOptions = kotlinTask.pluginOptions val appliedSubplugins = subplugins.filter { it.isApplicable(project, kotlinTask) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt index d3da4230096..69832aa6386 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt @@ -65,6 +65,8 @@ abstract class AbstractKotlinCompileTool() : AbstractCo abstract class AbstractKotlinCompile() : AbstractKotlinCompileTool(), CompilerArgumentAware { abstract protected fun createCompilerArgs(): T + internal val pluginOptions = CompilerPluginOptions() + protected val additionalClasspath = arrayListOf() protected val compileClasspath: Iterable get() = (classpath + additionalClasspath) @@ -204,6 +206,13 @@ abstract class AbstractKotlinCompile() : AbstractKo if (project.logger.isDebugEnabled) { args.verbose = true } + + setupPlugins(args) + } + + open fun setupPlugins(compilerArgs: T) { + compilerArgs.pluginClasspaths = pluginOptions.classpath.toTypedArray() + compilerArgs.pluginOptions = pluginOptions.arguments.toTypedArray() } } @@ -241,7 +250,6 @@ open class KotlinCompile : AbstractKotlinCompile(), Kotl @get:Input internal val javaPackagePrefixInputString get() = javaPackagePrefix ?: "" - internal val pluginOptions = CompilerPluginOptions() internal var artifactDifferenceRegistryProvider: ArtifactDifferenceRegistryProvider? = null internal var artifactFile: File? = null @@ -251,15 +259,17 @@ open class KotlinCompile : AbstractKotlinCompile(), Kotl override fun createCompilerArgs(): K2JVMCompilerArguments = K2JVMCompilerArguments() + override fun setupPlugins(compilerArgs: K2JVMCompilerArguments) { + compilerArgs.pluginClasspaths = pluginOptions.classpath.toTypedArray() + + val kaptPluginOptions = getKaptPluginOptions() + compilerArgs.pluginOptions = (pluginOptions.arguments + kaptPluginOptions.arguments).toTypedArray() + } + override fun setupCompilerArgs(args: K2JVMCompilerArguments, defaultsOnly: Boolean) { super.setupCompilerArgs(args, defaultsOnly) args.apply { fillDefaultValues() } - args.pluginClasspaths = pluginOptions.classpath.toTypedArray() - - val kaptPluginOptions = getKaptPluginOptions() - args.pluginOptions = (pluginOptions.arguments + kaptPluginOptions.arguments).toTypedArray() - args.addCompilerBuiltIns = true val gradleVersion = getGradleVersion()