Reorder Gradle -Xplugin=... so that serialization goes first (KT-47921)
Ensure that the serialization plugin's artifact (and, possibly, some other prioritized plugin artifacts) are put first to the -Xplugin=... classpath passed to the compiler. This fixes the conflict of the serialization plugin with some other plugins altering the IR in unexpected ways. Issue #KT-47921
This commit is contained in:
+25
-1
@@ -275,6 +275,30 @@ class SubpluginsIT : BaseGradleIT() {
|
||||
Project("lombokProject").build("build") {
|
||||
assertSuccessful()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test // KT-47921
|
||||
fun testSerializationPluginOrderedFirst() = with(Project("allOpenSimple")) {
|
||||
setupWorkingDir()
|
||||
// Ensure that there are also allopen, noarg, and serialization plugins applied:
|
||||
gradleBuildScript().appendText(
|
||||
"""
|
||||
buildscript {
|
||||
dependencies {
|
||||
classpath("org.jetbrains.kotlin:kotlin-noarg:${defaultBuildOptions().kotlinVersion}")
|
||||
classpath("org.jetbrains.kotlin:kotlin-serialization:${defaultBuildOptions().kotlinVersion}")
|
||||
}
|
||||
}
|
||||
apply plugin: "org.jetbrains.kotlin.plugin.noarg"
|
||||
apply plugin: "org.jetbrains.kotlin.plugin.serialization"
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
build("compileKotlin") {
|
||||
assertSuccessful()
|
||||
val xPlugin = output.split(" ").single { it.startsWith("-Xplugin") }.substringAfter("-Xplugin").split(",")
|
||||
assertTrue("Expected serialization plugin to go first; actual order: $xPlugin") { xPlugin.first().contains("serialization") }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.gradle.logging.kotlinDebug
|
||||
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompileArgumentsProvider
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompilerArgumentsProvider
|
||||
import org.jetbrains.kotlin.gradle.utils.toSortedPathsArray
|
||||
import org.jetbrains.kotlin.gradle.utils.toPathsArray
|
||||
import org.jetbrains.kotlin.incremental.classpathAsList
|
||||
import org.jetbrains.kotlin.incremental.destinationAsFile
|
||||
|
||||
@@ -63,7 +63,7 @@ internal open class AbstractKotlinCompileArgumentsContributor<T : CommonCompiler
|
||||
}
|
||||
|
||||
internal fun setupPlugins(compilerArgs: T) {
|
||||
compilerArgs.pluginClasspaths = pluginClasspath.toSortedPathsArray()
|
||||
compilerArgs.pluginClasspaths = pluginClasspath.toPathsArray()
|
||||
compilerArgs.pluginOptions = pluginOptions.arguments.toTypedArray()
|
||||
}
|
||||
}
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.gradle.internal
|
||||
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.artifacts.Dependency
|
||||
import org.gradle.api.artifacts.ModuleDependency
|
||||
|
||||
/**
|
||||
* Reorder the compiler plugin dependencies in this [Configuration] so that dependencies on the
|
||||
* modules under [prioritizedPluginArtifactCoordinates] appear first.
|
||||
*
|
||||
* In particular, the serialization plugin needs to appear first on the -Xplugin classpath in order to avoid conflicts with other compiler
|
||||
* plugins producing unexpected IR.
|
||||
*
|
||||
* KT-47921
|
||||
*/
|
||||
internal fun Configuration.reorderPluginClasspathDependencies() {
|
||||
withDependencies { dependencySet ->
|
||||
val orderedDependencies = dependencySet.toList().partition(Dependency::isPrioritized).toList().flatten()
|
||||
dependencySet.clear()
|
||||
dependencySet.addAll(orderedDependencies)
|
||||
}
|
||||
}
|
||||
|
||||
private val Dependency.isPrioritized: Boolean
|
||||
get() = this is ModuleDependency && (group to name) in prioritizedPluginArtifactCoordinates
|
||||
|
||||
private val prioritizedPluginArtifactCoordinates = setOf(
|
||||
"org.jetbrains.kotlin" to "kotlin-serialization",
|
||||
"org.jetbrains.kotlin" to "kotlin-serialization-unshaded"
|
||||
)
|
||||
+2
-2
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.gradle.report.ReportingSettings
|
||||
import org.jetbrains.kotlin.gradle.tasks.*
|
||||
import org.jetbrains.kotlin.gradle.utils.newInstance
|
||||
import org.jetbrains.kotlin.gradle.utils.property
|
||||
import org.jetbrains.kotlin.gradle.utils.toSortedPathsArray
|
||||
import org.jetbrains.kotlin.gradle.utils.toPathsArray
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -71,7 +71,7 @@ abstract class KaptWithKotlincTask @Inject constructor(
|
||||
ignoreClasspathResolutionErrors
|
||||
))
|
||||
|
||||
args.pluginClasspaths = pluginClasspath.toSortedPathsArray()
|
||||
args.pluginClasspaths = pluginClasspath.toPathsArray()
|
||||
|
||||
val pluginOptionsWithKapt: CompilerPluginOptions = pluginOptions.withWrappedKaptOptions(
|
||||
withApClasspath = kaptClasspath,
|
||||
|
||||
+2
@@ -27,6 +27,7 @@ import org.gradle.language.base.plugins.LifecycleBasePlugin
|
||||
import org.gradle.language.jvm.tasks.ProcessResources
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
|
||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||
import org.jetbrains.kotlin.gradle.internal.reorderPluginClasspathDependencies
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsCompilerAttribute
|
||||
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget
|
||||
@@ -286,6 +287,7 @@ abstract class AbstractKotlinTargetConfigurator<KotlinTargetType : KotlinTarget>
|
||||
isVisible = false
|
||||
isCanBeConsumed = false
|
||||
description = "Kotlin compiler plugins for $compilation"
|
||||
reorderPluginClasspathDependencies()
|
||||
}
|
||||
|
||||
val compileConfiguration = configurations.findByName(compilation.deprecatedCompileConfigurationName)?.apply {
|
||||
|
||||
+2
-1
@@ -7,9 +7,9 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.pm20
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.jetbrains.kotlin.gradle.internal.reorderPluginClasspathDependencies
|
||||
import org.jetbrains.kotlin.gradle.plugin.FilesSubpluginOption
|
||||
import org.jetbrains.kotlin.gradle.plugin.SubpluginOption
|
||||
import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion
|
||||
import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilerPluginData
|
||||
import org.jetbrains.kotlin.gradle.utils.newProperty
|
||||
@@ -93,6 +93,7 @@ internal class CompilerPluginOptionsBuilder(
|
||||
isCanBeConsumed = false
|
||||
isCanBeResolved = true
|
||||
isVisible = false
|
||||
reorderPluginClasspathDependencies()
|
||||
}
|
||||
artifacts.forEach { project.dependencies.add(configurationName, it) }
|
||||
|
||||
|
||||
+1
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.tasks
|
||||
import org.gradle.api.GradleException
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.file.*
|
||||
import org.gradle.api.invocation.Gradle
|
||||
import org.gradle.api.attributes.Attribute
|
||||
|
||||
+2
-2
@@ -26,8 +26,8 @@ internal fun Iterable<File>.pathsAsStringRelativeTo(base: File): String =
|
||||
internal fun File.relativeToRoot(project: Project): String =
|
||||
relativeOrCanonical(project.rootProject.rootDir)
|
||||
|
||||
internal fun Iterable<File>.toSortedPathsArray(): Array<String> =
|
||||
map { it.canonicalPath }.toTypedArray().also { Arrays.sort(it) }
|
||||
internal fun Iterable<File>.toPathsArray(): Array<String> =
|
||||
map { it.canonicalPath }.toTypedArray()
|
||||
|
||||
internal fun newTmpFile(prefix: String, suffix: String? = null, directory: File? = null, deleteOnExit: Boolean = true): File =
|
||||
(if (directory == null) Files.createTempFile(prefix, suffix) else Files.createTempFile(directory.toPath(), prefix, suffix))
|
||||
|
||||
Reference in New Issue
Block a user