Introduce new API for Kotlin compiler support Gradle plugins

The old API was too specific for the Kotlin internal use cases and
leaked some abstractions due to the missing target-compilation project
model. One of such leaking abstractions was the Gradle tasks being
exposed to the subplugin, which required the tasks to instantiate
in order for the subplugin to apply. This violated task configuration
avoidance, so the old API could never work in compliance with TCA.

Introduce the new KotlinCompilerPluginSupportPlugin API that uses the
compilations instead of the tasks and is TCA-compliant.
This commit is contained in:
Sergey Igushkin
2020-06-06 00:20:21 +03:00
parent 0b2d96c1ef
commit 96ed30a449
4 changed files with 194 additions and 127 deletions
@@ -16,7 +16,10 @@
package org.jetbrains.kotlin.gradle.plugin
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.compile.AbstractCompile
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
import java.io.File
@@ -62,6 +65,12 @@ enum class FilesOptionKind {
/** Defines a subplugin option that should be excluded from Gradle input/output checks */
open class InternalSubpluginOption(key: String, value: String) : SubpluginOption(key, value)
// Deprecated because most calls require the tasks to be instantiated, which is not compatible with Gradle task configuration avoidance.
@Deprecated(
message = "This interface will be removed due to performance considerations. " +
"Please use the KotlinCompilerPluginSupportPlugin interface instead.",
replaceWith = ReplaceWith("KotlinCompilerPluginSupportPlugin")
)
interface KotlinGradleSubplugin<in KotlinCompile : AbstractCompile> {
fun isApplicable(project: Project, task: AbstractCompile): Boolean
@@ -75,8 +84,8 @@ interface KotlinGradleSubplugin<in KotlinCompile : AbstractCompile> {
): List<SubpluginOption>
fun getSubpluginKotlinTasks(
project: Project,
kotlinCompile: KotlinCompile
project: Project,
kotlinCompile: KotlinCompile
): List<AbstractCompile> = emptyList()
fun getCompilerPluginId(): String
@@ -85,6 +94,37 @@ interface KotlinGradleSubplugin<in KotlinCompile : AbstractCompile> {
fun getNativeCompilerPluginArtifact(): SubpluginArtifact? = null
}
/**
* Gradle plugin implementing support for a Kotlin compiler plugin.
*
* In order to be discovered, it should be applied to the project as an ordinary Gradle [Plugin] before the
* Kotlin plugin inspects the project model in an afterEvaluate handler.
*
* The default implementation of [apply]
* doesn't do anything, but it can be overridden.
*
* Then its [isApplicable] is checked against compilations of the project, and if it returns true,
* then [applyToCompilation] may be called later.
*/
interface KotlinCompilerPluginSupportPlugin : Plugin<Project> {
override fun apply(target: Project) = Unit
fun isApplicable(kotlinCompilation: KotlinCompilation<*>): Boolean
/**
* Configures the compiler plugin to be incorporated into a specific [kotlinCompilation].
* This function is only called on [kotlinCompilation]s approved by [isApplicable].
* The [Provider] returned from this function may never get queried if the compilation is avoided in the current build.
*/
fun applyToCompilation(
kotlinCompilation: KotlinCompilation<*>
): Provider<List<SubpluginOption>>
fun getCompilerPluginId(): String
fun getPluginArtifact(): SubpluginArtifact
fun getNativeCompilerPluginArtifact(): SubpluginArtifact? = null
}
open class SubpluginArtifact(val groupId: String, val artifactId: String, val version: String? = null)
class JetBrainsSubpluginArtifact(artifactId: String) : SubpluginArtifact(groupId = "org.jetbrains.kotlin", artifactId = artifactId)