Attempt to make loading of compiler plugins from kotlin-platform-native Gradle plugin
Moved SubpluginEnviroment to separate file and made public some methods KotlinNativeCompile task now extends AbstractCompile so it could be passed to SubpluginEnviroment.loadSubplugins KotlinNativeBasePlugin now declares kotlinCompilerPluginClasspath configuration
This commit is contained in:
+5
-74
@@ -22,7 +22,6 @@ import org.gradle.api.tasks.compile.AbstractCompile
|
|||||||
import org.gradle.api.tasks.compile.JavaCompile
|
import org.gradle.api.tasks.compile.JavaCompile
|
||||||
import org.gradle.jvm.tasks.Jar
|
import org.gradle.jvm.tasks.Jar
|
||||||
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
|
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl
|
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinSingleJavaTargetExtension
|
import org.jetbrains.kotlin.gradle.dsl.KotlinSingleJavaTargetExtension
|
||||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||||
@@ -42,7 +41,7 @@ import java.util.*
|
|||||||
import java.util.concurrent.Callable
|
import java.util.concurrent.Callable
|
||||||
import java.util.jar.Manifest
|
import java.util.jar.Manifest
|
||||||
|
|
||||||
internal const val PLUGIN_CLASSPATH_CONFIGURATION_NAME = "kotlinCompilerPluginClasspath"
|
const val PLUGIN_CLASSPATH_CONFIGURATION_NAME = "kotlinCompilerPluginClasspath"
|
||||||
internal const val COMPILER_CLASSPATH_CONFIGURATION_NAME = "kotlinCompilerClasspath"
|
internal const val COMPILER_CLASSPATH_CONFIGURATION_NAME = "kotlinCompilerClasspath"
|
||||||
val KOTLIN_DSL_NAME = "kotlin"
|
val KOTLIN_DSL_NAME = "kotlin"
|
||||||
val KOTLIN_JS_DSL_NAME = "kotlin2js"
|
val KOTLIN_JS_DSL_NAME = "kotlin2js"
|
||||||
@@ -172,7 +171,7 @@ internal class Kotlin2JvmSourceSetProcessor(
|
|||||||
project.afterEvaluate { project ->
|
project.afterEvaluate { project ->
|
||||||
val javaTask = javaSourceSet?.let { project.tasks.findByName(it.compileJavaTaskName) as JavaCompile }
|
val javaTask = javaSourceSet?.let { project.tasks.findByName(it.compileJavaTaskName) as JavaCompile }
|
||||||
|
|
||||||
val subpluginEnvironment = loadSubplugins(project, kotlinPluginVersion)
|
val subpluginEnvironment = SubpluginEnvironment.loadSubplugins(project, kotlinPluginVersion)
|
||||||
val appliedPlugins = subpluginEnvironment.addSubpluginOptions(
|
val appliedPlugins = subpluginEnvironment.addSubpluginOptions(
|
||||||
project, kotlinTask, javaTask, null, null, kotlinCompilation
|
project, kotlinTask, javaTask, null, null, kotlinCompilation
|
||||||
)
|
)
|
||||||
@@ -270,7 +269,7 @@ internal class Kotlin2JsSourceSetProcessor(
|
|||||||
kotlinTask.kotlinOptions.outputFile = kotlinTask.outputFile.absolutePath
|
kotlinTask.kotlinOptions.outputFile = kotlinTask.outputFile.absolutePath
|
||||||
val outputDir = kotlinTask.outputFile.parentFile
|
val outputDir = kotlinTask.outputFile.parentFile
|
||||||
|
|
||||||
val subpluginEnvironment: SubpluginEnvironment = loadSubplugins(project, kotlinPluginVersion)
|
val subpluginEnvironment: SubpluginEnvironment = SubpluginEnvironment.loadSubplugins(project, kotlinPluginVersion)
|
||||||
val appliedPlugins = subpluginEnvironment.addSubpluginOptions(
|
val appliedPlugins = subpluginEnvironment.addSubpluginOptions(
|
||||||
project, kotlinTask, null, null, null, kotlinCompilation)
|
project, kotlinTask, null, null, null, kotlinCompilation)
|
||||||
|
|
||||||
@@ -321,7 +320,7 @@ internal class KotlinCommonSourceSetProcessor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
project.afterEvaluate { project ->
|
project.afterEvaluate { project ->
|
||||||
val subpluginEnvironment: SubpluginEnvironment = loadSubplugins(project, kotlinPluginVersion)
|
val subpluginEnvironment: SubpluginEnvironment = SubpluginEnvironment.loadSubplugins(project, kotlinPluginVersion)
|
||||||
val appliedPlugins = subpluginEnvironment.addSubpluginOptions(
|
val appliedPlugins = subpluginEnvironment.addSubpluginOptions(
|
||||||
project, kotlinTask, null, null, null, kotlinCompilation
|
project, kotlinTask, null, null, null, kotlinCompilation
|
||||||
)
|
)
|
||||||
@@ -678,7 +677,7 @@ abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationT
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val subpluginEnvironment = loadSubplugins(project, kotlinConfigurationTools.kotlinPluginVersion)
|
val subpluginEnvironment = SubpluginEnvironment.loadSubplugins(project, kotlinConfigurationTools.kotlinPluginVersion)
|
||||||
|
|
||||||
forEachVariant(project) { variant ->
|
forEachVariant(project) { variant ->
|
||||||
val compilation = kotlinAndroidTarget.compilations.getByName(getVariantName(variant))
|
val compilation = kotlinAndroidTarget.compilations.getByName(getVariantName(variant))
|
||||||
@@ -827,74 +826,6 @@ private fun SourceSet.clearJavaSrcDirs() {
|
|||||||
java.setSrcDirs(emptyList<File>())
|
java.setSrcDirs(emptyList<File>())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadSubplugins(project: Project, kotlinPluginVersion: String): SubpluginEnvironment =
|
|
||||||
try {
|
|
||||||
val klass = KotlinGradleSubplugin::class.java
|
|
||||||
val buildscriptClassloader = project.buildscript.classLoader
|
|
||||||
val klassFromBuildscript = try {
|
|
||||||
buildscriptClassloader.loadClass(klass.canonicalName)
|
|
||||||
} catch (e: ClassNotFoundException) {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
val classloader = if (klass == klassFromBuildscript) {
|
|
||||||
buildscriptClassloader
|
|
||||||
} else {
|
|
||||||
klass.classLoader
|
|
||||||
}
|
|
||||||
|
|
||||||
val subplugins = ServiceLoader.load(KotlinGradleSubplugin::class.java, classloader)
|
|
||||||
.map { @Suppress("UNCHECKED_CAST") (it as KotlinGradleSubplugin<AbstractCompile>) }
|
|
||||||
|
|
||||||
SubpluginEnvironment(subplugins, kotlinPluginVersion)
|
|
||||||
} catch (e: NoClassDefFoundError) {
|
|
||||||
// Skip plugin loading if KotlinGradleSubplugin is not defined.
|
|
||||||
// It is true now for tests in kotlin-gradle-plugin-core.
|
|
||||||
project.logger.error("Could not load subplugins", e)
|
|
||||||
SubpluginEnvironment(listOf(), kotlinPluginVersion)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class SubpluginEnvironment(
|
|
||||||
private val subplugins: List<KotlinGradleSubplugin<AbstractCompile>>,
|
|
||||||
private val kotlinPluginVersion: String
|
|
||||||
) {
|
|
||||||
fun <C: CommonCompilerArguments> addSubpluginOptions(
|
|
||||||
project: Project,
|
|
||||||
kotlinTask: AbstractKotlinCompile<C>,
|
|
||||||
javaTask: AbstractCompile?,
|
|
||||||
variantData: Any?,
|
|
||||||
androidProjectHandler: AbstractAndroidProjectHandler<out Any?>?,
|
|
||||||
kotlinCompilation: KotlinCompilation?
|
|
||||||
): List<KotlinGradleSubplugin<AbstractKotlinCompile<C>>> {
|
|
||||||
val pluginOptions = kotlinTask.pluginOptions
|
|
||||||
|
|
||||||
val appliedSubplugins = subplugins.filter { it.isApplicable(project, kotlinTask) }
|
|
||||||
for (subplugin in appliedSubplugins) {
|
|
||||||
if (!subplugin.isApplicable(project, kotlinTask)) continue
|
|
||||||
|
|
||||||
val pluginId = subplugin.getCompilerPluginId()
|
|
||||||
project.logger.kotlinDebug { "Loading subplugin $pluginId" }
|
|
||||||
|
|
||||||
val artifact = subplugin.getPluginArtifact()
|
|
||||||
val artifactVersion = artifact.version ?: kotlinPluginVersion
|
|
||||||
val mavenCoordinate = "${artifact.groupId}:${artifact.artifactId}:$artifactVersion"
|
|
||||||
project.logger.kotlinDebug { "Adding '$mavenCoordinate' to '$PLUGIN_CLASSPATH_CONFIGURATION_NAME' configuration" }
|
|
||||||
project.dependencies.add(PLUGIN_CLASSPATH_CONFIGURATION_NAME, mavenCoordinate)
|
|
||||||
|
|
||||||
val subpluginOptions = subplugin.apply(project, kotlinTask, javaTask, variantData, androidProjectHandler, kotlinCompilation)
|
|
||||||
val subpluginId = subplugin.getCompilerPluginId()
|
|
||||||
kotlinTask.registerSubpluginOptionsAsInputs(subpluginId, subpluginOptions)
|
|
||||||
|
|
||||||
for (option in subpluginOptions) {
|
|
||||||
pluginOptions.addPluginArgument(subpluginId, option)
|
|
||||||
}
|
|
||||||
project.logger.kotlinDebug("Subplugin $pluginId loaded")
|
|
||||||
}
|
|
||||||
|
|
||||||
return appliedSubplugins
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun Task.registerSubpluginOptionsAsInputs(subpluginId: String, subpluginOptions: List<SubpluginOption>) {
|
internal fun Task.registerSubpluginOptionsAsInputs(subpluginId: String, subpluginOptions: List<SubpluginOption>) {
|
||||||
// There might be several options with the same key. We group them together
|
// There might be several options with the same key. We group them together
|
||||||
// and add an index to the Gradle input property name to resolve possible duplication:
|
// and add an index to the Gradle input property name to resolve possible duplication:
|
||||||
|
|||||||
+1
-1
@@ -148,7 +148,7 @@ open class KotlinMultiplatformPluginWrapper @Inject constructor(
|
|||||||
fun Project.getKotlinPluginVersion(): String? =
|
fun Project.getKotlinPluginVersion(): String? =
|
||||||
plugins.asSequence().mapNotNull { (it as? KotlinBasePluginWrapper)?.kotlinPluginVersion }.firstOrNull()
|
plugins.asSequence().mapNotNull { (it as? KotlinBasePluginWrapper)?.kotlinPluginVersion }.firstOrNull()
|
||||||
|
|
||||||
private fun Any.loadKotlinVersionFromResource(log: Logger): String {
|
fun Plugin<*>.loadKotlinVersionFromResource(log: Logger): String {
|
||||||
log.kotlinDebug("Loading version information")
|
log.kotlinDebug("Loading version information")
|
||||||
val props = Properties()
|
val props = Properties()
|
||||||
val propFileName = "project.properties"
|
val propFileName = "project.properties"
|
||||||
|
|||||||
+95
@@ -0,0 +1,95 @@
|
|||||||
|
package org.jetbrains.kotlin.gradle.plugin
|
||||||
|
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.tasks.compile.AbstractCompile
|
||||||
|
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||||
|
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
|
||||||
|
import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class SubpluginEnvironment(
|
||||||
|
private val subplugins: List<KotlinGradleSubplugin<AbstractCompile>>,
|
||||||
|
private val kotlinPluginVersion: String
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
fun loadSubplugins(project: Project, kotlinPluginVersion: String): SubpluginEnvironment =
|
||||||
|
try {
|
||||||
|
val klass = KotlinGradleSubplugin::class.java
|
||||||
|
val buildscriptClassloader = project.buildscript.classLoader
|
||||||
|
val klassFromBuildscript = try {
|
||||||
|
buildscriptClassloader.loadClass(klass.canonicalName)
|
||||||
|
} catch (e: ClassNotFoundException) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
val classloader = if (klass == klassFromBuildscript) {
|
||||||
|
buildscriptClassloader
|
||||||
|
} else {
|
||||||
|
klass.classLoader
|
||||||
|
}
|
||||||
|
|
||||||
|
val subplugins = ServiceLoader.load(KotlinGradleSubplugin::class.java, classloader)
|
||||||
|
.map { @Suppress("UNCHECKED_CAST") (it as KotlinGradleSubplugin<AbstractCompile>) }
|
||||||
|
|
||||||
|
SubpluginEnvironment(subplugins, kotlinPluginVersion)
|
||||||
|
} catch (e: NoClassDefFoundError) {
|
||||||
|
// Skip plugin loading if KotlinGradleSubplugin is not defined.
|
||||||
|
// It is true now for tests in kotlin-gradle-plugin-core.
|
||||||
|
project.logger.error("Could not load subplugins", e)
|
||||||
|
SubpluginEnvironment(listOf(), kotlinPluginVersion)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <C : CommonCompilerArguments> addSubpluginOptions(
|
||||||
|
project: Project,
|
||||||
|
kotlinTask: AbstractKotlinCompile<C>,
|
||||||
|
javaTask: AbstractCompile? = null,
|
||||||
|
variantData: Any? = null,
|
||||||
|
androidProjectHandler: AbstractAndroidProjectHandler<out Any?>? = null,
|
||||||
|
kotlinCompilation: KotlinCompilation? = null
|
||||||
|
): List<KotlinGradleSubplugin<AbstractKotlinCompile<C>>> = addSubpluginOptions(
|
||||||
|
project,
|
||||||
|
kotlinTask,
|
||||||
|
kotlinTask.pluginOptions,
|
||||||
|
javaTask,
|
||||||
|
variantData,
|
||||||
|
androidProjectHandler,
|
||||||
|
kotlinCompilation
|
||||||
|
)
|
||||||
|
|
||||||
|
fun <C : CommonCompilerArguments> addSubpluginOptions(
|
||||||
|
project: Project,
|
||||||
|
kotlinTask: AbstractCompile,
|
||||||
|
pluginOptions: CompilerPluginOptions,
|
||||||
|
javaTask: AbstractCompile? = null,
|
||||||
|
variantData: Any? = null,
|
||||||
|
androidProjectHandler: AbstractAndroidProjectHandler<out Any?>? = null,
|
||||||
|
kotlinCompilation: KotlinCompilation? = null
|
||||||
|
): List<KotlinGradleSubplugin<AbstractKotlinCompile<C>>> {
|
||||||
|
val appliedSubplugins = subplugins.filter { it.isApplicable(project, kotlinTask) }
|
||||||
|
for (subplugin in appliedSubplugins) {
|
||||||
|
if (!subplugin.isApplicable(project, kotlinTask)) continue
|
||||||
|
|
||||||
|
val pluginId = subplugin.getCompilerPluginId()
|
||||||
|
project.logger.kotlinDebug { "Loading subplugin $pluginId" }
|
||||||
|
|
||||||
|
val artifact = subplugin.getPluginArtifact()
|
||||||
|
val artifactVersion = artifact.version ?: kotlinPluginVersion
|
||||||
|
val mavenCoordinate = "${artifact.groupId}:${artifact.artifactId}:$artifactVersion"
|
||||||
|
project.logger.kotlinDebug { "Adding '$mavenCoordinate' to '$PLUGIN_CLASSPATH_CONFIGURATION_NAME' configuration" }
|
||||||
|
project.dependencies.add(PLUGIN_CLASSPATH_CONFIGURATION_NAME, mavenCoordinate)
|
||||||
|
|
||||||
|
val subpluginOptions =
|
||||||
|
subplugin.apply(project, kotlinTask, javaTask, variantData, androidProjectHandler, kotlinCompilation)
|
||||||
|
val subpluginId = subplugin.getCompilerPluginId()
|
||||||
|
kotlinTask.registerSubpluginOptionsAsInputs(subpluginId, subpluginOptions)
|
||||||
|
|
||||||
|
for (option in subpluginOptions) {
|
||||||
|
pluginOptions.addPluginArgument(subpluginId, option)
|
||||||
|
}
|
||||||
|
project.logger.kotlinDebug("Subplugin $pluginId loaded")
|
||||||
|
}
|
||||||
|
|
||||||
|
return appliedSubplugins
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.gradle.tasks
|
|||||||
import org.jetbrains.kotlin.gradle.plugin.SubpluginOption
|
import org.jetbrains.kotlin.gradle.plugin.SubpluginOption
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
internal class CompilerPluginOptions {
|
class CompilerPluginOptions {
|
||||||
private val mutableArguments = arrayListOf<String>()
|
private val mutableArguments = arrayListOf<String>()
|
||||||
|
|
||||||
internal val subpluginOptionsByPluginId =
|
internal val subpluginOptionsByPluginId =
|
||||||
|
|||||||
Reference in New Issue
Block a user