Add kotlin-build-tools-enum-compat workaround
It acts as a workaround for the case when build tools or dependencies are compiled with latest 'kotlin-stdlib' version, but at a runtime older 'kotlin-stdlib' is provided, which does not know about new `EnumEntries`. ^KT-57317 Fixed
This commit is contained in:
committed by
Space Team
parent
1f649b698c
commit
eb4e96a113
@@ -0,0 +1,7 @@
|
||||
## Description
|
||||
|
||||
Backport of `EnumEntries` runtime support API ([KT-48872](https://youtrack.jetbrains.com/issue/KT-48872))
|
||||
|
||||
This should help with the case when code was compiled using newer `kotlin-stdlib` version as a `compileOnly` dependency, but at a runtime
|
||||
older version of `kotlin-stdlib` is provided ([KT-57317](https://youtrack.jetbrains.com/issue/KT-57317)). Mostly it is needed for Kotlin
|
||||
build tools artifacts.
|
||||
@@ -0,0 +1,17 @@
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
|
||||
|
||||
plugins {
|
||||
id("org.jetbrains.kotlin.jvm")
|
||||
id("jps-compatible")
|
||||
}
|
||||
|
||||
configureKotlinCompileTasksGradleCompatibility()
|
||||
extensions.extraProperties["kotlin.stdlib.default.dependency"] = "false"
|
||||
|
||||
dependencies {
|
||||
compileOnly(project(":kotlin-stdlib"))
|
||||
}
|
||||
|
||||
tasks.withType<KotlinJvmCompile>().configureEach {
|
||||
compilerOptions.freeCompilerArgs.add("-Xallow-kotlin-package")
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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 kotlin.enums
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* A specialized immutable implementation of [List] interface that
|
||||
* contains all enum entries of the specified enum type [E].
|
||||
* [EnumEntries] contains all enum entries in the order they are declared in the source code,
|
||||
* consistently with the corresponding [Enum.ordinal] values.
|
||||
*
|
||||
* An instance of this interface can only be obtained from `EnumClass.entries` property.
|
||||
*/
|
||||
@ExperimentalStdlibApi
|
||||
interface EnumEntries<E : Enum<E>> : List<E>
|
||||
|
||||
@Suppress("unused")
|
||||
@PublishedApi
|
||||
@ExperimentalStdlibApi
|
||||
internal fun <E : Enum<E>> enumEntries(entriesProvider: () -> Array<E>): EnumEntries<E> = EnumEntriesList(entriesProvider())
|
||||
|
||||
@PublishedApi
|
||||
@ExperimentalStdlibApi
|
||||
internal fun <E : Enum<E>> enumEntries(entries: Array<E>): EnumEntries<E> = EnumEntriesList(entries)
|
||||
|
||||
@ExperimentalStdlibApi
|
||||
private class EnumEntriesList<T : Enum<T>>(private val entries: Array<T>) : EnumEntries<T>, AbstractList<T>(), Serializable {
|
||||
// WA for JS IR bug:
|
||||
// class type parameter name MUST be different from E (AbstractList<E> type parameter),
|
||||
// otherwise the bridge names for contains() and indexOf() will be clashed with the original method names,
|
||||
// and produced JS code will not contain type checks and will not work correctly.
|
||||
|
||||
override val size: Int
|
||||
get() = entries.size
|
||||
|
||||
override fun get(index: Int): T {
|
||||
checkElementIndex(index, entries.size)
|
||||
return entries[index]
|
||||
}
|
||||
|
||||
// Ported from kotlin-stdlib-common AbstractList.kt
|
||||
private fun checkElementIndex(index: Int, size: Int) {
|
||||
if (index < 0 || index >= size) {
|
||||
throw IndexOutOfBoundsException("index: $index, size: $size")
|
||||
}
|
||||
}
|
||||
|
||||
// By definition, EnumEntries contains **all** enums in declaration order,
|
||||
// thus we are able to short-circuit the implementation here
|
||||
|
||||
override fun contains(element: T): Boolean {
|
||||
@Suppress("SENSELESS_COMPARISON")
|
||||
if (element === null) return false // WA for JS IR bug
|
||||
// Check identity due to UnsafeVariance
|
||||
val target = entries.getOrNull(element.ordinal)
|
||||
return target === element
|
||||
}
|
||||
|
||||
override fun indexOf(element: T): Int {
|
||||
@Suppress("SENSELESS_COMPARISON")
|
||||
if (element === null) return -1 // WA for JS IR bug
|
||||
// Check identity due to UnsafeVariance
|
||||
val ordinal = element.ordinal
|
||||
val target = entries.getOrNull(ordinal)
|
||||
return if (target === element) ordinal else -1
|
||||
}
|
||||
|
||||
override fun lastIndexOf(element: T): Int = indexOf(element)
|
||||
|
||||
@Suppress("unused")
|
||||
private fun writeReplace(): Any {
|
||||
// Used for Java serialization: EESP ensures that deserialized object **always** reflects the state of the enum on the target classpath
|
||||
return EnumEntriesSerializationProxy(entries)
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.
|
||||
*/
|
||||
|
||||
@file:Suppress("EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE") // for building kotlin-stdlib-jvm-minimal-for-test
|
||||
|
||||
package kotlin.enums
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
@Suppress("UNCHECKED_CAST", "unused")
|
||||
internal class EnumEntriesSerializationProxy<E : Enum<E>>(entries: Array<E>) : Serializable {
|
||||
private val c: Class<E> = entries.javaClass.componentType!! as Class<E>
|
||||
|
||||
private companion object {
|
||||
private const val serialVersionUID: Long = 0L
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
private fun readResolve(): Any {
|
||||
return enumEntries(c.enumConstants)
|
||||
}
|
||||
}
|
||||
@@ -89,6 +89,14 @@ dependencies {
|
||||
exclude(group = "*")
|
||||
}
|
||||
|
||||
// Adding workaround KT-57317 for Gradle versions where Kotlin runtime <1.8.0
|
||||
mainEmbedded(project(":kotlin-build-tools-enum-compat"))
|
||||
gradle70Embedded(project(":kotlin-build-tools-enum-compat"))
|
||||
gradle71Embedded(project(":kotlin-build-tools-enum-compat"))
|
||||
gradle74Embedded(project(":kotlin-build-tools-enum-compat"))
|
||||
gradle75Embedded(project(":kotlin-build-tools-enum-compat"))
|
||||
gradle76Embedded(project(":kotlin-build-tools-enum-compat"))
|
||||
|
||||
testCompileOnly(project(":compiler"))
|
||||
testCompileOnly(project(":kotlin-annotation-processing"))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user