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.jvm.tasks.Jar
|
||||
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.KotlinSingleJavaTargetExtension
|
||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||
@@ -42,7 +41,7 @@ import java.util.*
|
||||
import java.util.concurrent.Callable
|
||||
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"
|
||||
val KOTLIN_DSL_NAME = "kotlin"
|
||||
val KOTLIN_JS_DSL_NAME = "kotlin2js"
|
||||
@@ -172,7 +171,7 @@ internal class Kotlin2JvmSourceSetProcessor(
|
||||
project.afterEvaluate { project ->
|
||||
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(
|
||||
project, kotlinTask, javaTask, null, null, kotlinCompilation
|
||||
)
|
||||
@@ -270,7 +269,7 @@ internal class Kotlin2JsSourceSetProcessor(
|
||||
kotlinTask.kotlinOptions.outputFile = kotlinTask.outputFile.absolutePath
|
||||
val outputDir = kotlinTask.outputFile.parentFile
|
||||
|
||||
val subpluginEnvironment: SubpluginEnvironment = loadSubplugins(project, kotlinPluginVersion)
|
||||
val subpluginEnvironment: SubpluginEnvironment = SubpluginEnvironment.loadSubplugins(project, kotlinPluginVersion)
|
||||
val appliedPlugins = subpluginEnvironment.addSubpluginOptions(
|
||||
project, kotlinTask, null, null, null, kotlinCompilation)
|
||||
|
||||
@@ -321,7 +320,7 @@ internal class KotlinCommonSourceSetProcessor(
|
||||
}
|
||||
|
||||
project.afterEvaluate { project ->
|
||||
val subpluginEnvironment: SubpluginEnvironment = loadSubplugins(project, kotlinPluginVersion)
|
||||
val subpluginEnvironment: SubpluginEnvironment = SubpluginEnvironment.loadSubplugins(project, kotlinPluginVersion)
|
||||
val appliedPlugins = subpluginEnvironment.addSubpluginOptions(
|
||||
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 ->
|
||||
val compilation = kotlinAndroidTarget.compilations.getByName(getVariantName(variant))
|
||||
@@ -827,74 +826,6 @@ private fun SourceSet.clearJavaSrcDirs() {
|
||||
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>) {
|
||||
// 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:
|
||||
|
||||
+1
-1
@@ -148,7 +148,7 @@ open class KotlinMultiplatformPluginWrapper @Inject constructor(
|
||||
fun Project.getKotlinPluginVersion(): String? =
|
||||
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")
|
||||
val props = 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 java.io.File
|
||||
|
||||
internal class CompilerPluginOptions {
|
||||
class CompilerPluginOptions {
|
||||
private val mutableArguments = arrayListOf<String>()
|
||||
|
||||
internal val subpluginOptionsByPluginId =
|
||||
|
||||
Reference in New Issue
Block a user