Resolve compiler plugin classpath using 'kotlinCompilerPluginClasspath' configuration

#KT-24653 fixed
        #KT-24676 fixed
This commit is contained in:
Alexey Tsvetkov
2018-05-28 23:18:30 +03:00
parent 0c21b21a88
commit 873de17056
16 changed files with 94 additions and 225 deletions
@@ -20,6 +20,8 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin
import org.gradle.api.Project
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.compile.AbstractCompile
import org.jetbrains.kotlin.gradle.plugin.JetBrainsSubpluginArtifact
import org.jetbrains.kotlin.gradle.plugin.SubpluginArtifact
import org.jetbrains.kotlin.gradle.plugin.SubpluginOption
class ExampleSubplugin : KotlinGradleSubplugin<AbstractCompile> {
@@ -44,11 +46,6 @@ class ExampleSubplugin : KotlinGradleSubplugin<AbstractCompile> {
return "example.plugin"
}
override fun getGroupName(): String {
return "org.jetbrains.kotlin"
}
override fun getArtifactName(): String {
return "kotlin-gradle-subplugin-example"
}
override fun getPluginArtifact(): SubpluginArtifact =
JetBrainsSubpluginArtifact("kotlin-gradle-subplugin-example")
}
@@ -22,7 +22,9 @@ import org.gradle.api.artifacts.ResolvedArtifact
import org.gradle.api.internal.AbstractTask
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.compile.AbstractCompile
import org.jetbrains.kotlin.gradle.plugin.JetBrainsSubpluginArtifact
import org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin
import org.jetbrains.kotlin.gradle.plugin.SubpluginArtifact
import org.jetbrains.kotlin.gradle.plugin.SubpluginOption
class AllOpenGradleSubplugin : Plugin<Project> {
@@ -34,39 +36,14 @@ class AllOpenGradleSubplugin : Plugin<Project> {
}
}
fun Project.getBuildscriptArtifacts(): Set<ResolvedArtifact> =
buildscript.configurations.findByName("classpath")?.resolvedConfiguration?.resolvedArtifacts ?: emptySet()
override fun apply(project: Project) {
val allOpenExtension = project.extensions.create("allOpen", AllOpenExtension::class.java)
project.afterEvaluate {
val fqNamesAsString = allOpenExtension.myAnnotations.joinToString(",")
val presetsAsString = allOpenExtension.myPresets.joinToString(",")
project.extensions.extraProperties.set("kotlinAllOpenAnnotations", fqNamesAsString)
val allBuildscriptArtifacts = project.getBuildscriptArtifacts() + project.rootProject.getBuildscriptArtifacts()
val allOpenCompilerPluginFile = allBuildscriptArtifacts.filter {
val id = it.moduleVersion.id
id.group == AllOpenKotlinGradleSubplugin.ALLOPEN_GROUP_NAME
&& id.name == AllOpenKotlinGradleSubplugin.ALLOPEN_ARTIFACT_NAME
}.firstOrNull()?.file?.absolutePath ?: ""
open class TaskForAllOpen : AbstractTask()
project.tasks.add(project.tasks.create("allOpenDataStorageTask", TaskForAllOpen::class.java).apply {
isEnabled = false
description = "Supported annotations: $fqNamesAsString" +
"; Presets: $presetsAsString" +
"; Compiler plugin classpath: $allOpenCompilerPluginFile"
})
}
project.extensions.create("allOpen", AllOpenExtension::class.java)
}
}
class AllOpenKotlinGradleSubplugin : KotlinGradleSubplugin<AbstractCompile> {
companion object {
val ALLOPEN_GROUP_NAME = "org.jetbrains.kotlin"
val ALLOPEN_ARTIFACT_NAME = "kotlin-allopen"
const val ALLOPEN_ARTIFACT_NAME = "kotlin-allopen"
private val ANNOTATION_ARG_NAME = "annotation"
private val PRESET_ARG_NAME = "preset"
@@ -99,7 +76,7 @@ class AllOpenKotlinGradleSubplugin : KotlinGradleSubplugin<AbstractCompile> {
return options
}
override fun getGroupName() = ALLOPEN_GROUP_NAME
override fun getArtifactName() = ALLOPEN_ARTIFACT_NAME
override fun getCompilerPluginId() = "org.jetbrains.kotlin.allopen"
override fun getPluginArtifact(): SubpluginArtifact =
JetBrainsSubpluginArtifact(artifactId = ALLOPEN_ARTIFACT_NAME)
}
@@ -63,6 +63,10 @@ interface KotlinGradleSubplugin<in KotlinCompile : AbstractCompile> {
): List<AbstractCompile> = emptyList()
fun getCompilerPluginId(): String
fun getGroupName(): String
fun getArtifactName(): String
fun getPluginArtifact(): SubpluginArtifact
}
open class SubpluginArtifact(val groupId: String, val artifactId: String)
class JetBrainsSubpluginArtifact(artifactId: String) : SubpluginArtifact(groupId = "org.jetbrains.kotlin", artifactId = artifactId)
@@ -54,7 +54,8 @@ test.dependsOn(":kotlin-allopen:install",
":kotlin-stdlib-jre8:install",
":examples:annotation-processor-example:install",
":kotlin-scripting-common:install",
":kotlin-scripting-jvm:install")
":kotlin-scripting-jvm:install",
":kotlin-scripting-gradle:install")
// Validate that all dependencies 'install' tasks are added to 'test' dependencies
@@ -260,9 +260,8 @@ class AndroidSubplugin : KotlinGradleSubplugin<KotlinCompile> {
override fun getCompilerPluginId() = "org.jetbrains.kotlin.android"
override fun getGroupName() = "org.jetbrains.kotlin"
override fun getArtifactName() = "kotlin-android-extensions"
override fun getPluginArtifact(): SubpluginArtifact =
JetBrainsSubpluginArtifact(artifactId = "kotlin-android-extensions")
private fun File.parseXml(): Document {
val factory = DocumentBuilderFactory.newInstance()
@@ -74,8 +74,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
val MAIN_KAPT_CONFIGURATION_NAME = "kapt"
val KAPT_GROUP_NAME = "org.jetbrains.kotlin"
val KAPT_ARTIFACT_NAME = "kotlin-annotation-processing-gradle"
const val KAPT_ARTIFACT_NAME = "kotlin-annotation-processing-gradle"
val KAPT_SUBPLUGIN_ID = "org.jetbrains.kotlin.kapt3"
fun getKaptConfigurationName(sourceSetName: String): String {
@@ -136,10 +135,6 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
val sourcesOutputDir = getKaptGeneratedSourcesDir(project, sourceSetName)
val kotlinSourcesOutputDir = getKaptGeneratedKotlinSourcesDir(project, sourceSetName)
val classesOutputDir = getKaptGeneratedClassesDir(project, sourceSetName)
val kaptClasspathArtifacts = project
.resolveSubpluginArtifacts(listOf(this@Kapt3KotlinGradleSubplugin))
.flatMap { it.value }
}
override fun apply(
@@ -180,9 +175,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
val kaptExtension = project.extensions.getByType(KaptExtension::class.java)
val nonEmptyKaptConfigurations = kaptConfigurations.filter { configuration ->
configuration.dependencies.any { it.group != getGroupName() || it.name != getArtifactName() }
}
val nonEmptyKaptConfigurations = kaptConfigurations.filter { it.dependencies.isNotEmpty() }
val context = Kapt3SubpluginContext(
project, kotlinCompile, javaCompile,
@@ -319,8 +312,6 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
kaptTask.kotlinCompileTask = kotlinCompile
kaptClasspathArtifacts.forEach { kaptTask.pluginOptions.addClasspathEntry(it) }
kaptTask.stubsDir = getKaptStubsDir()
kaptTask.destinationDir = sourcesOutputDir
kaptTask.kotlinSourcesDestinationDir = kotlinSourcesOutputDir
@@ -360,8 +351,6 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
kaptTask.kotlinCompileTask = kotlinCompile
kotlinToKaptGenerateStubsTasksMap[kotlinCompile] = kaptTask
kaptClasspathArtifacts.forEach { kaptTask.pluginOptions.addClasspathEntry(it) }
kaptTask.stubsDir = getKaptStubsDir()
kaptTask.destinationDir = getKaptIncrementalDataDir()
kaptTask.mapClasspath { kotlinCompile.classpath }
@@ -406,8 +395,9 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
}
override fun getCompilerPluginId() = KAPT_SUBPLUGIN_ID
override fun getGroupName() = KAPT_GROUP_NAME
override fun getArtifactName() = KAPT_ARTIFACT_NAME
override fun getPluginArtifact(): SubpluginArtifact =
JetBrainsSubpluginArtifact(artifactId = KAPT_ARTIFACT_NAME)
}
internal fun registerGeneratedJavaSource(kaptTask: KaptTask, javaTask: AbstractCompile) {
@@ -75,8 +75,6 @@ open class KaptGenerateStubsTask : KotlinCompile() {
override fun setupCompilerArgs(args: K2JVMCompilerArguments, defaultsOnly: Boolean) {
kotlinCompileTask.setupCompilerArgs(args)
args.pluginClasspaths = (pluginClasspath + args.pluginClasspaths!!).toSet().toTypedArray()
val pluginOptionsWithKapt = pluginOptions.withWrappedKaptOptions(withApClasspath = kaptClasspath)
args.pluginOptions = (pluginOptionsWithKapt.arguments + args.pluginOptions!!).toTypedArray()
@@ -11,8 +11,10 @@ import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.compilerRunner.GradleCompilerEnvironment
import org.jetbrains.kotlin.compilerRunner.GradleCompilerRunner
import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl
import org.jetbrains.kotlin.gradle.plugin.PLUGIN_CLASSPATH_CONFIGURATION_NAME
import org.jetbrains.kotlin.gradle.tasks.*
import org.jetbrains.kotlin.incremental.isJavaFile
import org.jetbrains.kotlin.incremental.toSortedPathsArray
import java.io.File
@CacheableTask
@@ -64,7 +66,7 @@ open class KaptTask : ConventionTask(), CompilerArgumentAwareWithInput<K2JVMComp
override fun setupCompilerArgs(args: K2JVMCompilerArguments, defaultsOnly: Boolean) {
kotlinCompileTask.setupCompilerArgs(args)
args.pluginClasspaths = (pluginClasspath + args.pluginClasspaths!!).toSet().toTypedArray()
args.pluginClasspaths = pluginClasspath.toSortedPathsArray()
val pluginOptionsWithKapt: CompilerPluginOptions = pluginOptions.withWrappedKaptOptions(withApClasspath = kaptClasspath)
args.pluginOptions = (pluginOptionsWithKapt.arguments + args.pluginOptions!!).toTypedArray()
@@ -79,11 +81,10 @@ open class KaptTask : ConventionTask(), CompilerArgumentAwareWithInput<K2JVMComp
@get:Internal
var useBuildCache: Boolean = false
@get:Classpath @get:InputFiles @Suppress("unused")
internal val kotlinTaskPluginClasspaths get() = kotlinCompileTask.pluginClasspath
@get:Classpath @get:InputFiles
internal val pluginClasspath get() = pluginOptions.classpath
@get:Classpath
@get:InputFiles
val pluginClasspath: FileCollection
get() = project.configurations.getByName(PLUGIN_CLASSPATH_CONFIGURATION_NAME)
@get:InputFiles @get:PathSensitive(PathSensitivity.RELATIVE)
val source: Collection<File>
@@ -55,7 +55,6 @@ internal fun CompilerPluginOptions.withWrappedKaptOptions(withApClasspath: Itera
}
val result = CompilerPluginOptions()
classpath.forEach { result.addClasspathEntry(File(it)) }
resultOptionsByPluginId.forEach { pluginId, options ->
options.forEach { option -> result.addPluginArgument(pluginId, option) }
}
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.gradle.internal.*
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.getKaptGeneratedClassesDir
import org.jetbrains.kotlin.gradle.tasks.*
import org.jetbrains.kotlin.gradle.utils.*
import org.jetbrains.kotlin.incremental.stackTraceStr
import org.jetbrains.kotlin.scripting.gradle.ScriptingGradleSubplugin
import java.io.File
import java.net.URL
@@ -36,6 +37,7 @@ import java.util.*
import java.util.concurrent.Callable
import java.util.jar.Manifest
internal const val PLUGIN_CLASSPATH_CONFIGURATION_NAME = "kotlinCompilerPluginClasspath"
val KOTLIN_DSL_NAME = "kotlin"
val KOTLIN_JS_DSL_NAME = "kotlin2js"
val KOTLIN_OPTIONS_DSL_NAME = "kotlinOptions"
@@ -150,12 +152,10 @@ internal class Kotlin2JvmSourceSetProcessor(
if (project != null) {
val javaTask = project.tasks.findByName(sourceSet.compileJavaTaskName)
val subpluginEnvironment = loadSubplugins(project)
val subpluginEnvironment = loadSubplugins(project, kotlinPluginVersion)
val appliedPlugins = subpluginEnvironment.addSubpluginOptions(
project, kotlinTask, javaTask as JavaCompile, null, null, sourceSet)
removeAnnotationProcessingPluginClasspathEntry(kotlinTask)
// KotlinCompile.source(kotlinDirSet) should be called only after all java roots are added to kotlinDirSet
// otherwise some java roots can be ignored
kotlinTask.source(kotlinSourceSet.kotlin)
@@ -235,7 +235,8 @@ internal class Kotlin2JsSourceSetProcessor(
javaBasePlugin: JavaBasePlugin,
sourceSet: SourceSet,
tasksProvider: KotlinTasksProvider,
kotlinSourceSetProvider: KotlinSourceSetProvider
kotlinSourceSetProvider: KotlinSourceSetProvider,
private val kotlinPluginVersion: String
) : KotlinSourceSetProcessor<Kotlin2JsCompile>(
project, javaBasePlugin, sourceSet, tasksProvider, kotlinSourceSetProvider,
dslExtensionName = KOTLIN_JS_DSL_NAME,
@@ -254,7 +255,7 @@ internal class Kotlin2JsSourceSetProcessor(
// outputFile can be set later during the configuration phase, get it only after the phase:
project.afterEvaluate { project ->
val subpluginEnvironment: SubpluginEnvironment = loadSubplugins(project)
val subpluginEnvironment: SubpluginEnvironment = loadSubplugins(project, kotlinPluginVersion)
val appliedPlugins = subpluginEnvironment.addSubpluginOptions(
project, kotlinTask, kotlinTask, null, null, sourceSet)
@@ -296,7 +297,8 @@ internal class KotlinCommonSourceSetProcessor(
javaBasePlugin: JavaBasePlugin,
sourceSet: SourceSet,
tasksProvider: KotlinTasksProvider,
kotlinSourceSetProvider: KotlinSourceSetProvider
kotlinSourceSetProvider: KotlinSourceSetProvider,
private val kotlinPluginVersion: String
) : KotlinSourceSetProcessor<KotlinCompileCommon>(
project, javaBasePlugin, sourceSet, tasksProvider, kotlinSourceSetProvider,
dslExtensionName = KOTLIN_DSL_NAME,
@@ -309,7 +311,7 @@ internal class KotlinCommonSourceSetProcessor(
project.afterEvaluate { project ->
kotlinTask.source(kotlinSourceSet.kotlin)
val subpluginEnvironment: SubpluginEnvironment = loadSubplugins(project)
val subpluginEnvironment: SubpluginEnvironment = loadSubplugins(project, kotlinPluginVersion)
val appliedPlugins = subpluginEnvironment.addSubpluginOptions(
project, kotlinTask, kotlinTask, null, null, sourceSet)
@@ -327,6 +329,7 @@ internal class KotlinCommonSourceSetProcessor(
tasksProvider.createKotlinCommonTask(project, taskName, sourceSet.name)
}
internal abstract class AbstractKotlinPlugin(
val tasksProvider: KotlinTasksProvider,
val kotlinSourceSetProvider: KotlinSourceSetProvider,
@@ -335,6 +338,8 @@ internal abstract class AbstractKotlinPlugin(
internal abstract fun buildSourceSetProcessor(project: Project, javaBasePlugin: JavaBasePlugin, sourceSet: SourceSet, kotlinPluginVersion: String): KotlinSourceSetProcessor<*>
override fun apply(project: Project) {
project.configurations.create(PLUGIN_CLASSPATH_CONFIGURATION_NAME)
val javaBasePlugin = project.plugins.apply(JavaBasePlugin::class.java)
val javaPluginConvention = project.convention.getPlugin(JavaPluginConvention::class.java)
@@ -415,7 +420,7 @@ internal open class KotlinCommonPlugin(
kotlinPluginVersion: String
) : AbstractKotlinPlugin(tasksProvider, kotlinSourceSetProvider, kotlinPluginVersion) {
override fun buildSourceSetProcessor(project: Project, javaBasePlugin: JavaBasePlugin, sourceSet: SourceSet, kotlinPluginVersion: String) =
KotlinCommonSourceSetProcessor(project, javaBasePlugin, sourceSet, tasksProvider, kotlinSourceSetProvider)
KotlinCommonSourceSetProcessor(project, javaBasePlugin, sourceSet, tasksProvider, kotlinSourceSetProvider, kotlinPluginVersion)
}
internal open class Kotlin2JsPlugin(
@@ -424,7 +429,7 @@ internal open class Kotlin2JsPlugin(
kotlinPluginVersion: String
) : AbstractKotlinPlugin(tasksProvider, kotlinSourceSetProvider, kotlinPluginVersion) {
override fun buildSourceSetProcessor(project: Project, javaBasePlugin: JavaBasePlugin, sourceSet: SourceSet, kotlinPluginVersion: String) =
Kotlin2JsSourceSetProcessor(project, javaBasePlugin, sourceSet, tasksProvider, kotlinSourceSetProvider)
Kotlin2JsSourceSetProcessor(project, javaBasePlugin, sourceSet, tasksProvider, kotlinSourceSetProvider, kotlinPluginVersion)
}
internal open class KotlinAndroidPlugin(
@@ -522,7 +527,7 @@ abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationT
"plugins to be applied to the project:\n\t" +
androidPluginIds.joinToString("\n\t") { "* $it" })
val subpluginEnvironment = loadSubplugins(project)
val subpluginEnvironment = loadSubplugins(project, kotlinConfigurationTools.kotlinPluginVersion)
checkAndroidAnnotationProcessorDependencyUsage(project)
@@ -540,7 +545,8 @@ abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationT
androidPlugin: BasePlugin,
aptConfigurations: Map<String, Configuration>,
rootKotlinOptions: KotlinJvmOptionsImpl,
tasksProvider: KotlinTasksProvider, subpluginEnvironment: SubpluginEnvironment) {
tasksProvider: KotlinTasksProvider,
subpluginEnvironment: SubpluginEnvironment) {
checkVariantIsValid(variantData)
@@ -563,8 +569,6 @@ abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationT
kotlinTask.destinationDir = File(project.buildDir, "tmp/kotlin-classes/$variantDataName")
kotlinTask.description = "Compiles the $variantDataName kotlin."
removeAnnotationProcessingPluginClasspathEntry(kotlinTask)
configureSources(kotlinTask, variantData)
wireKotlinTasks(project, androidPlugin, androidExt, variantData, javaTask, kotlinTask)
@@ -662,64 +666,23 @@ private fun SourceSet.clearJavaSrcDirs() {
java.setSrcDirs(emptyList<File>())
}
private val KOTLIN_ANNOTATION_PROCESSING_FILE_REGEX = "kotlin-annotation-processing-[\\-0-9A-Za-z.]+\\.jar".toRegex()
private fun removeAnnotationProcessingPluginClasspathEntry(kotlinCompile: KotlinCompile) {
kotlinCompile.pluginOptions.classpath
.map(::File)
.filter { it.name.matches(KOTLIN_ANNOTATION_PROCESSING_FILE_REGEX) }
.forEach {
kotlinCompile.logger.kotlinDebug("Removing plugin classpath dependency $it")
kotlinCompile.pluginOptions.removeClasspathEntry(it)
}
}
private fun loadSubplugins(project: Project): SubpluginEnvironment {
private fun loadSubplugins(project: Project, kotlinPluginVersion: String): SubpluginEnvironment =
try {
val subplugins = ServiceLoader.load(KotlinGradleSubplugin::class.java, project.buildscript.classLoader)
.map { @Suppress("UNCHECKED_CAST") (it as KotlinGradleSubplugin<AbstractCompile>) }
.map { @Suppress("UNCHECKED_CAST") (it as KotlinGradleSubplugin<AbstractCompile>) }
return SubpluginEnvironment(project.resolveSubpluginArtifacts(subplugins), subplugins)
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.
return SubpluginEnvironment(mapOf(), listOf())
project.logger.error("Could not load subplugins", e)
SubpluginEnvironment(listOf(), kotlinPluginVersion)
}
}
internal fun <T: AbstractCompile> Project.resolveSubpluginArtifacts(
subplugins: List<KotlinGradleSubplugin<T>>
): Map<KotlinGradleSubplugin<T>, List<File>> {
fun Project.getResolvedArtifacts() = buildscript.configurations.getByName("classpath")
.resolvedConfiguration.resolvedArtifacts
val resolvedClasspathArtifacts = getResolvedArtifacts().toMutableList()
val rootProject = rootProject
if (rootProject != this) {
resolvedClasspathArtifacts += rootProject.getResolvedArtifacts()
}
val subpluginClasspaths = hashMapOf<KotlinGradleSubplugin<T>, List<File>>()
for (subplugin in subplugins) {
val file = resolvedClasspathArtifacts
.firstOrNull {
val id = it.moduleVersion.id
subplugin.getGroupName() == id.group && subplugin.getArtifactName() == id.name
}?.file
if (file != null) {
subpluginClasspaths.put(subplugin, listOf(file))
}
}
return subpluginClasspaths
}
internal class SubpluginEnvironment(
val subpluginClasspaths: Map<KotlinGradleSubplugin<AbstractCompile>, List<File>>,
val subplugins: List<KotlinGradleSubplugin<AbstractCompile>>
private val subplugins: List<KotlinGradleSubplugin<AbstractCompile>>,
private val kotlinPluginVersion: String
) {
fun <C: CommonCompilerArguments> addSubpluginOptions(
project: Project,
kotlinTask: AbstractKotlinCompile<C>,
@@ -734,12 +697,13 @@ internal class SubpluginEnvironment(
for (subplugin in appliedSubplugins) {
if (!subplugin.isApplicable(project, kotlinTask)) continue
with(subplugin) {
project.logger.kotlinDebug("Subplugin ${getCompilerPluginId()} (${getGroupName()}:${getArtifactName()}) loaded.")
}
val pluginId = subplugin.getCompilerPluginId()
project.logger.kotlinDebug { "Loading subplugin $pluginId" }
val subpluginClasspath = subpluginClasspaths[subplugin] ?: continue
subpluginClasspath.forEach { pluginOptions.addClasspathEntry(it) }
val artifact = subplugin.getPluginArtifact()
val mavenCoordinate = "${artifact.groupId}:${artifact.artifactId}:$kotlinPluginVersion"
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, javaSourceSet)
val subpluginId = subplugin.getCompilerPluginId()
@@ -748,6 +712,7 @@ internal class SubpluginEnvironment(
for (option in subpluginOptions) {
pluginOptions.addPluginArgument(subpluginId, option)
}
project.logger.kotlinDebug("Subplugin $pluginId loaded")
}
return appliedSubplugins
@@ -20,28 +20,14 @@ import org.jetbrains.kotlin.gradle.plugin.SubpluginOption
import java.io.File
internal class CompilerPluginOptions {
private val mutableClasspath = arrayListOf<String>()
private val mutableArguments = arrayListOf<String>()
internal val subpluginOptionsByPluginId =
mutableMapOf<String, MutableList<SubpluginOption>>()
val classpath: List<String>
get() = mutableClasspath
mutableMapOf<String, MutableList<SubpluginOption>>()
val arguments: List<String>
get() = mutableArguments
// used in kotlin-gradle-plugin
@Suppress("unused")
fun addClasspathEntry(file: File) {
mutableClasspath.add(file.canonicalPath)
}
internal fun removeClasspathEntry(file: File) {
mutableClasspath.remove(file.canonicalPath)
}
fun addPluginArgument(pluginId: String, option: SubpluginOption) {
mutableArguments.add("plugin:$pluginId:${option.key}=${option.value}")
subpluginOptionsByPluginId.getOrPut(pluginId) { mutableListOf() }.add(option)
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.tasks
import com.intellij.openapi.util.io.FileUtil
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.file.FileCollection
import org.gradle.api.logging.Logger
import org.gradle.api.plugins.BasePluginConvention
import org.gradle.api.tasks.*
@@ -36,7 +37,6 @@ import java.io.File
import java.util.*
import kotlin.properties.Delegates
const val ANNOTATIONS_PLUGIN_NAME = "org.jetbrains.kotlin.kapt"
const val KOTLIN_BUILD_DIR_NAME = "kotlin"
const val USING_INCREMENTAL_COMPILATION_MESSAGE = "Using Kotlin incremental compilation"
const val USING_EXPERIMENTAL_JS_INCREMENTAL_COMPILATION_MESSAGE = "Using experimental Kotlin/JS incremental compilation"
@@ -96,6 +96,11 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractKo
protected val multiModuleICSettings: MultiModuleICSettings
get() = MultiModuleICSettings(buildHistoryFile, useModuleDetection)
@get:Classpath
@get:InputFiles
val pluginClasspath: FileCollection
get() = project.configurations.getByName(PLUGIN_CLASSPATH_CONFIGURATION_NAME)
@get:Internal
internal val pluginOptions = CompilerPluginOptions()
@@ -107,9 +112,6 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractKo
get() = (classpath + additionalClasspath)
.filterTo(LinkedHashSet(), File::exists)
@get:Classpath @get:InputFiles
internal val pluginClasspath get() = pluginOptions.classpath
private val kotlinExt: KotlinProjectExtension
get() = project.extensions.findByType(KotlinProjectExtension::class.java)!!
@@ -243,8 +245,8 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractKo
setupPlugins(args)
}
open fun setupPlugins(compilerArgs: T) {
compilerArgs.pluginClasspaths = pluginClasspath.toTypedArray()
fun setupPlugins(compilerArgs: T) {
compilerArgs.pluginClasspaths = pluginClasspath.toSortedPathsArray()
compilerArgs.pluginOptions = pluginOptions.arguments.toTypedArray()
}
@@ -292,11 +294,6 @@ open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), Kotl
override fun createCompilerArgs(): K2JVMCompilerArguments =
K2JVMCompilerArguments()
override fun setupPlugins(compilerArgs: K2JVMCompilerArguments) {
compilerArgs.pluginClasspaths = pluginClasspath.toTypedArray()
compilerArgs.pluginOptions = pluginOptions.arguments.toTypedArray()
}
override fun setupCompilerArgs(args: K2JVMCompilerArguments, defaultsOnly: Boolean) {
args.apply { fillDefaultValues() }
super.setupCompilerArgs(args, defaultsOnly)
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.incremental
import org.gradle.api.Project
import java.io.File
import java.util.*
// todo: Move all files under org.jetbrains.kotlin.gradle package to avoid class clash (KT-18621, KT-20516)
@@ -43,4 +44,7 @@ internal fun Iterable<File>.pathsAsStringRelativeTo(base: File): String =
map { it.relativeOrCanonical(base) }.sorted().joinToString()
internal fun File.relativeToRoot(project: Project): String =
relativeOrCanonical(project.rootProject.rootDir)
relativeOrCanonical(project.rootProject.rootDir)
internal fun Iterable<File>.toSortedPathsArray(): Array<String> =
map { it.canonicalPath }.toTypedArray().also { Arrays.sort(it) }
@@ -23,7 +23,9 @@ import org.gradle.api.artifacts.ResolvedArtifact
import org.gradle.api.internal.ConventionTask
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.compile.AbstractCompile
import org.jetbrains.kotlin.gradle.plugin.JetBrainsSubpluginArtifact
import org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin
import org.jetbrains.kotlin.gradle.plugin.SubpluginArtifact
import org.jetbrains.kotlin.gradle.plugin.SubpluginOption
class NoArgGradleSubplugin : Plugin<Project> {
@@ -35,39 +37,14 @@ class NoArgGradleSubplugin : Plugin<Project> {
}
}
fun Project.getBuildscriptArtifacts(): Set<ResolvedArtifact> =
buildscript.configurations.findByName("classpath")?.resolvedConfiguration?.resolvedArtifacts ?: emptySet()
override fun apply(project: Project) {
val noArgExtension = project.extensions.create("noArg", NoArgExtension::class.java)
project.afterEvaluate {
val fqNamesAsString = noArgExtension.myAnnotations.joinToString(",")
val presetsAsString = noArgExtension.myPresets.joinToString(",")
project.extensions.extraProperties.set("kotlinNoArgAnnotations", fqNamesAsString)
val allBuildscriptArtifacts = project.getBuildscriptArtifacts() + project.rootProject.getBuildscriptArtifacts()
val noArgCompilerPluginFile = allBuildscriptArtifacts.filter {
val id = it.moduleVersion.id
id.group == NoArgKotlinGradleSubplugin.NOARG_GROUP_NAME
&& id.name == NoArgKotlinGradleSubplugin.NOARG_ARTIFACT_NAME
}.firstOrNull()?.file?.absolutePath ?: ""
open class TaskForNoArg : AbstractTask()
project.tasks.add(project.tasks.create("noArgDataStorageTask", TaskForNoArg::class.java).apply {
isEnabled = false
description = "Supported annotations: " + fqNamesAsString +
"; Presets: $presetsAsString" +
"; Compiler plugin classpath: $noArgCompilerPluginFile"
})
}
project.extensions.create("noArg", NoArgExtension::class.java)
}
}
class NoArgKotlinGradleSubplugin : KotlinGradleSubplugin<AbstractCompile> {
companion object {
val NOARG_GROUP_NAME = "org.jetbrains.kotlin"
val NOARG_ARTIFACT_NAME = "kotlin-noarg"
const val NOARG_ARTIFACT_NAME = "kotlin-noarg"
private val ANNOTATION_ARG_NAME = "annotation"
private val PRESET_ARG_NAME = "preset"
@@ -105,7 +82,7 @@ class NoArgKotlinGradleSubplugin : KotlinGradleSubplugin<AbstractCompile> {
return options
}
override fun getArtifactName() = "kotlin-noarg"
override fun getGroupName() = "org.jetbrains.kotlin"
override fun getCompilerPluginId() = "org.jetbrains.kotlin.noarg"
override fun getPluginArtifact(): SubpluginArtifact =
JetBrainsSubpluginArtifact(artifactId = NOARG_ARTIFACT_NAME)
}
@@ -23,51 +23,24 @@ import org.gradle.api.artifacts.ResolvedArtifact
import org.gradle.api.internal.ConventionTask
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.compile.AbstractCompile
import org.jetbrains.kotlin.gradle.plugin.JetBrainsSubpluginArtifact
import org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin
import org.jetbrains.kotlin.gradle.plugin.SubpluginArtifact
import org.jetbrains.kotlin.gradle.plugin.SubpluginOption
class SamWithReceiverGradleSubplugin : Plugin<Project> {
companion object {
fun isEnabled(project: Project) = project.plugins.findPlugin(SamWithReceiverGradleSubplugin::class.java) != null
fun getSamWithReceiverExtension(project: Project): SamWithReceiverExtension {
return project.extensions.getByType(SamWithReceiverExtension::class.java)
}
}
fun Project.getBuildscriptArtifacts(): Set<ResolvedArtifact> =
buildscript.configurations.findByName("classpath")?.resolvedConfiguration?.resolvedArtifacts ?: emptySet()
override fun apply(project: Project) {
val samWithReceiverExtension = project.extensions.create("samWithReceiver", SamWithReceiverExtension::class.java)
project.afterEvaluate {
val fqNamesAsString = samWithReceiverExtension.myAnnotations.joinToString(",")
val presetsAsString = samWithReceiverExtension.myPresets.joinToString(",")
project.extensions.extraProperties.set("kotlinSamWithReceiverAnnotations", fqNamesAsString)
val allBuildscriptArtifacts = project.getBuildscriptArtifacts() + project.rootProject.getBuildscriptArtifacts()
val samWithReceiverCompilerPluginFile = allBuildscriptArtifacts.filter {
val id = it.moduleVersion.id
id.group == SamWithReceiverKotlinGradleSubplugin.SAM_WITH_RECEIVER_GROUP_NAME
&& id.name == SamWithReceiverKotlinGradleSubplugin.SAM_WITH_RECEIVER_ARTIFACT_NAME
}.firstOrNull()?.file?.absolutePath ?: ""
open class TaskForSamWithReceiver : AbstractTask()
project.tasks.add(project.tasks.create("samWithReceiverDataStorageTask", TaskForSamWithReceiver::class.java).apply {
isEnabled = false
description = "Supported annotations: " + fqNamesAsString +
"; Presets: $presetsAsString" +
"; Compiler plugin classpath: $samWithReceiverCompilerPluginFile"
})
}
project.extensions.create("samWithReceiver", SamWithReceiverExtension::class.java)
}
}
class SamWithReceiverKotlinGradleSubplugin : KotlinGradleSubplugin<AbstractCompile> {
companion object {
val SAM_WITH_RECEIVER_GROUP_NAME = "org.jetbrains.kotlin"
val SAM_WITH_RECEIVER_ARTIFACT_NAME = "kotlin-sam-with-receiver"
const val SAM_WITH_RECEIVER_ARTIFACT_NAME = "kotlin-sam-with-receiver"
private val ANNOTATION_ARG_NAME = "annotation"
private val PRESET_ARG_NAME = "preset"
@@ -100,7 +73,7 @@ class SamWithReceiverKotlinGradleSubplugin : KotlinGradleSubplugin<AbstractCompi
return options
}
override fun getArtifactName() = "kotlin-sam-with-receiver"
override fun getGroupName() = "org.jetbrains.kotlin"
override fun getCompilerPluginId() = "org.jetbrains.kotlin.samWithReceiver"
override fun getPluginArtifact(): SubpluginArtifact =
JetBrainsSubpluginArtifact(artifactId = SAM_WITH_RECEIVER_ARTIFACT_NAME)
}
@@ -9,7 +9,9 @@ import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.compile.AbstractCompile
import org.jetbrains.kotlin.gradle.plugin.JetBrainsSubpluginArtifact
import org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin
import org.jetbrains.kotlin.gradle.plugin.SubpluginArtifact
import org.jetbrains.kotlin.gradle.plugin.SubpluginOption
class ScriptingGradleSubplugin : Plugin<Project>
@@ -23,8 +25,7 @@ class ScriptingGradleSubplugin : Plugin<Project>
class ScriptingKotlinGradleSubplugin : KotlinGradleSubplugin<AbstractCompile> {
companion object {
val SCRIPTING_GROUP_NAME = "org.jetbrains.kotlin"
val SCRIPTING_ARTIFACT_NAME = "kotlin-scripting"
const val SCRIPTING_ARTIFACT_NAME = "kotlin-scripting"
val SCRIPT_DEFINITIONS_OPTION = "script-definitions"
val SCRIPT_DEFINITIONS_CLASSPATH_OPTION = "script-definitions-classpath"
@@ -65,7 +66,7 @@ class ScriptingKotlinGradleSubplugin : KotlinGradleSubplugin<AbstractCompile> {
return options
}
override fun getArtifactName() = "kotlin-scripting-gradle"
override fun getGroupName() = "org.jetbrains.kotlin"
override fun getCompilerPluginId() = "kotlin.scripting"
override fun getPluginArtifact(): SubpluginArtifact =
JetBrainsSubpluginArtifact(artifactId = SCRIPTING_ARTIFACT_NAME)
}