From 873de17056fd97e395d2a79297e7538022f2d4c1 Mon Sep 17 00:00:00 2001 From: Alexey Tsvetkov Date: Mon, 28 May 2018 23:18:30 +0300 Subject: [PATCH] Resolve compiler plugin classpath using 'kotlinCompilerPluginClasspath' configuration #KT-24653 fixed #KT-24676 fixed --- .../main/kotlin/example/ExampleSubplugin.kt | 11 +-- .../kotlin/allopen/gradle/AllOpenSubplugin.kt | 35 ++----- .../gradle/plugin/KotlinGradleSubplugin.kt | 8 +- .../build.gradle | 3 +- .../gradle/internal/AndroidSubplugin.kt | 5 +- .../internal/Kapt3KotlinGradleSubplugin.kt | 20 +--- .../gradle/internal/KaptGenerateStubsTask.kt | 2 - .../kotlin/gradle/internal/KaptTask.kt | 13 +-- .../kotlin/gradle/internal/subpluginUtils.kt | 1 - .../kotlin/gradle/plugin/KotlinPlugin.kt | 97 ++++++------------- .../gradle/tasks/CompilerPluginOptions.kt | 16 +-- .../jetbrains/kotlin/gradle/tasks/Tasks.kt | 19 ++-- .../jetbrains/kotlin/incremental/fileUtils.kt | 6 +- .../kotlin/noarg/gradle/NoArgSubplugin.kt | 35 ++----- .../noarg/gradle/SamWithReceiverSubplugin.kt | 39 ++------ .../gradle/ScriptingGradleSubplugin.kt | 9 +- 16 files changed, 94 insertions(+), 225 deletions(-) diff --git a/libraries/examples/kotlin-gradle-subplugin-example/src/main/kotlin/example/ExampleSubplugin.kt b/libraries/examples/kotlin-gradle-subplugin-example/src/main/kotlin/example/ExampleSubplugin.kt index 2c555ad2775..7c980c0d1ef 100644 --- a/libraries/examples/kotlin-gradle-subplugin-example/src/main/kotlin/example/ExampleSubplugin.kt +++ b/libraries/examples/kotlin-gradle-subplugin-example/src/main/kotlin/example/ExampleSubplugin.kt @@ -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 { @@ -44,11 +46,6 @@ class ExampleSubplugin : KotlinGradleSubplugin { 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") } \ No newline at end of file diff --git a/libraries/tools/kotlin-allopen/src/main/kotlin/org/jetbrains/kotlin/allopen/gradle/AllOpenSubplugin.kt b/libraries/tools/kotlin-allopen/src/main/kotlin/org/jetbrains/kotlin/allopen/gradle/AllOpenSubplugin.kt index 03375c2a011..e31a6c38588 100644 --- a/libraries/tools/kotlin-allopen/src/main/kotlin/org/jetbrains/kotlin/allopen/gradle/AllOpenSubplugin.kt +++ b/libraries/tools/kotlin-allopen/src/main/kotlin/org/jetbrains/kotlin/allopen/gradle/AllOpenSubplugin.kt @@ -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 { @@ -34,39 +36,14 @@ class AllOpenGradleSubplugin : Plugin { } } - fun Project.getBuildscriptArtifacts(): Set = - 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 { 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 { 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) } \ No newline at end of file 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 64907fb18b6..75f462ee3c2 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 @@ -63,6 +63,10 @@ interface KotlinGradleSubplugin { ): List = 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) diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle index 3b884a513c3..5f8d759e7d2 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle @@ -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 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 0c2eb668705..34b0ae363af 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 @@ -260,9 +260,8 @@ class AndroidSubplugin : KotlinGradleSubplugin { 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() 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 dd9c0a93c8b..90b90e40b54 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 @@ -74,8 +74,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin { 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 { 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 { 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 { 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 { 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 { } 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) { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/KaptGenerateStubsTask.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/KaptGenerateStubsTask.kt index 4b8e70a7dbe..c4ef3a6ce50 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/KaptGenerateStubsTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/KaptGenerateStubsTask.kt @@ -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() diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/KaptTask.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/KaptTask.kt index dcf08af9929..537e450f630 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/KaptTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/KaptTask.kt @@ -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 diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/subpluginUtils.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/subpluginUtils.kt index 30f98243eef..1ea3ec2b5e4 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/subpluginUtils.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/subpluginUtils.kt @@ -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) } } 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 cf466b54050..53223d68305 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 @@ -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( 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( 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(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(private val kotlinConfigurationT androidPlugin: BasePlugin, aptConfigurations: Map, rootKotlinOptions: KotlinJvmOptionsImpl, - tasksProvider: KotlinTasksProvider, subpluginEnvironment: SubpluginEnvironment) { + tasksProvider: KotlinTasksProvider, + subpluginEnvironment: SubpluginEnvironment) { checkVariantIsValid(variantData) @@ -563,8 +569,6 @@ abstract class AbstractAndroidProjectHandler(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()) } -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) } + .map { @Suppress("UNCHECKED_CAST") (it as KotlinGradleSubplugin) } - 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 Project.resolveSubpluginArtifacts( - subplugins: List> -): Map, List> { - 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, List>() - - 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, List>, - val subplugins: List> + private val subplugins: List>, + private val kotlinPluginVersion: String ) { - fun addSubpluginOptions( project: Project, kotlinTask: AbstractKotlinCompile, @@ -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 diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/CompilerPluginOptions.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/CompilerPluginOptions.kt index 4bc6b660a65..00ff85897a9 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/CompilerPluginOptions.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/CompilerPluginOptions.kt @@ -20,28 +20,14 @@ import org.jetbrains.kotlin.gradle.plugin.SubpluginOption import java.io.File internal class CompilerPluginOptions { - private val mutableClasspath = arrayListOf() private val mutableArguments = arrayListOf() internal val subpluginOptionsByPluginId = - mutableMapOf>() - - val classpath: List - get() = mutableClasspath + mutableMapOf>() val arguments: List 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) 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 8745e2b0556..f3ccfd5444a 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 @@ -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() : 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() : 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() : 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(), 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) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/incremental/fileUtils.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/incremental/fileUtils.kt index f1c7efab6b4..532ec6d2d42 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/incremental/fileUtils.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/incremental/fileUtils.kt @@ -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.pathsAsStringRelativeTo(base: File): String = map { it.relativeOrCanonical(base) }.sorted().joinToString() internal fun File.relativeToRoot(project: Project): String = - relativeOrCanonical(project.rootProject.rootDir) \ No newline at end of file + relativeOrCanonical(project.rootProject.rootDir) + +internal fun Iterable.toSortedPathsArray(): Array = + map { it.canonicalPath }.toTypedArray().also { Arrays.sort(it) } \ No newline at end of file diff --git a/libraries/tools/kotlin-noarg/src/main/kotlin/org/jetbrains/kotlin/noarg/gradle/NoArgSubplugin.kt b/libraries/tools/kotlin-noarg/src/main/kotlin/org/jetbrains/kotlin/noarg/gradle/NoArgSubplugin.kt index 1478ef15494..0edffc60b9b 100644 --- a/libraries/tools/kotlin-noarg/src/main/kotlin/org/jetbrains/kotlin/noarg/gradle/NoArgSubplugin.kt +++ b/libraries/tools/kotlin-noarg/src/main/kotlin/org/jetbrains/kotlin/noarg/gradle/NoArgSubplugin.kt @@ -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 { @@ -35,39 +37,14 @@ class NoArgGradleSubplugin : Plugin { } } - fun Project.getBuildscriptArtifacts(): Set = - 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 { 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 { 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) } \ No newline at end of file diff --git a/libraries/tools/kotlin-sam-with-receiver/src/main/kotlin/org/jetbrains/kotlin/noarg/gradle/SamWithReceiverSubplugin.kt b/libraries/tools/kotlin-sam-with-receiver/src/main/kotlin/org/jetbrains/kotlin/noarg/gradle/SamWithReceiverSubplugin.kt index 0e5585548d1..9e1b35bd083 100644 --- a/libraries/tools/kotlin-sam-with-receiver/src/main/kotlin/org/jetbrains/kotlin/noarg/gradle/SamWithReceiverSubplugin.kt +++ b/libraries/tools/kotlin-sam-with-receiver/src/main/kotlin/org/jetbrains/kotlin/noarg/gradle/SamWithReceiverSubplugin.kt @@ -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 { 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 = - 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 { 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 @@ -23,8 +25,7 @@ class ScriptingGradleSubplugin : Plugin class ScriptingKotlinGradleSubplugin : KotlinGradleSubplugin { 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 { 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) }