From 8de67d039bf50712cd2c732c45bf48c4b6124ba9 Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Fri, 7 Oct 2016 04:52:53 +0300 Subject: [PATCH] Expose maximum version component value as a constant, increase it to 255. Add tests for KotlinVersion, document remaining parts of API. #KT-14789 --- .../stdlib/src/kotlin/util/KotlinVersion.kt | 38 ++++++++++++++----- .../stdlib/test/utils/KotlinVersionTest.kt | 37 ++++++++++++++++++ .../reference-public-api/kotlin-stdlib.txt | 2 +- 3 files changed, 67 insertions(+), 10 deletions(-) create mode 100644 libraries/stdlib/test/utils/KotlinVersionTest.kt diff --git a/libraries/stdlib/src/kotlin/util/KotlinVersion.kt b/libraries/stdlib/src/kotlin/util/KotlinVersion.kt index daf3330964f..7a3944f9eb5 100644 --- a/libraries/stdlib/src/kotlin/util/KotlinVersion.kt +++ b/libraries/stdlib/src/kotlin/util/KotlinVersion.kt @@ -1,16 +1,27 @@ package kotlin /** - * Represents a version of the Kotlin standard library + * Represents a version of the Kotlin standard library. + * + * [major], [minor] and [patch] are integer components of a version, + * they must be non-negative and not greater than 255 ([MAX_COMPONENT_VALUE]). + * + * @constructor Creates a version from all three components. */ +@SinceKotlin("1.1") public class KotlinVersion(val major: Int, val minor: Int, val patch: Int) : Comparable { + /** + * Creates a version from [major] and [minor] components, leaving [patch] component zero. + */ public constructor(major: Int, minor: Int) : this(major, minor, 0) private val version = versionOf(major, minor, patch) private fun versionOf(major: Int, minor: Int, patch: Int): Int { - require(major in 0..99 && minor in 0..99 && patch in 0..99) { "Version components are out of range: $major.$minor.$patch" } - return major * 100 * 100 + minor * 100 + patch + require(major in 0..MAX_COMPONENT_VALUE && minor in 0..MAX_COMPONENT_VALUE && patch in 0..MAX_COMPONENT_VALUE) { + "Version components are out of range: $major.$minor.$patch" + } + return major shl 16 + minor shl 8 + patch } /** @@ -38,28 +49,37 @@ public class KotlinVersion(val major: Int, val minor: Int, val patch: Int) : Com override fun compareTo(other: KotlinVersion): Int = version - other.version + /** + * Returns `true` if this version is not less than the version specified + * with the provided [major] and [minor] components. + */ public fun isAtLeast(major: Int, minor: Int): Boolean = // or this.version >= versionOf(major, minor, 0) this.major > major || (this.major == major && this.minor >= minor) + /** + * Returns `true` if this version is not less than the version specified + * with the provided [major], [minor] and [patch] components. + */ public fun isAtLeast(major: Int, minor: Int, patch: Int): Boolean = // or this.version >= versionOf(major, minor, patch) this.major > major || (this.major == major && (this.minor > minor || this.minor == minor && this.patch >= patch)) - public fun isAtLeast(version: KotlinVersion): Boolean = this >= version - companion object { /** - * Returns the current version of the Kotlin standard library + * Maximum value a version component can have, a constant value 255. + */ + // NOTE: Must be placed before CURRENT because its initialization requires this field being initialized in JS + public const val MAX_COMPONENT_VALUE = 255 + + /** + * Returns the current version of the Kotlin standard library. */ // TODO: get from metadata or hardcode automatically during build @kotlin.jvm.JvmField public val CURRENT: KotlinVersion = KotlinVersion(1, 1, 0) - - // should we have 'parse'? - } } \ No newline at end of file diff --git a/libraries/stdlib/test/utils/KotlinVersionTest.kt b/libraries/stdlib/test/utils/KotlinVersionTest.kt new file mode 100644 index 00000000000..941b81c2cb8 --- /dev/null +++ b/libraries/stdlib/test/utils/KotlinVersionTest.kt @@ -0,0 +1,37 @@ +package test.utils + +import org.junit.Test +import kotlin.test.* + + +class KotlinVersionTest { + + @Test fun currentVersion() { + assertTrue(KotlinVersion.CURRENT.isAtLeast(1, 1)) + assertTrue(KotlinVersion.CURRENT.isAtLeast(1, 1, 0)) + assertTrue(KotlinVersion.CURRENT >= KotlinVersion(1, 1)) + assertTrue(KotlinVersion(1, 1) <= KotlinVersion.CURRENT) + + val anotherCurrent = KotlinVersion.CURRENT.run { KotlinVersion(major, minor, patch) } + assertEquals(KotlinVersion.CURRENT, anotherCurrent) + assertEquals(KotlinVersion.CURRENT.hashCode(), anotherCurrent.hashCode()) + assertEquals(0, KotlinVersion.CURRENT.compareTo(anotherCurrent)) + } + + @Test fun componentValidation() { + for (component in listOf(Int.MIN_VALUE, -1, 0, KotlinVersion.MAX_COMPONENT_VALUE, KotlinVersion.MAX_COMPONENT_VALUE + 1, Int.MAX_VALUE)) { + for (place in 0..2) { + val (major, minor, patch) = IntArray(3) { index -> if (index == place) component else 0 } + if (component in 0..KotlinVersion.MAX_COMPONENT_VALUE) { + KotlinVersion(major, minor, patch) + } + else { + assertFailsWith("Expected $major.$minor.$patch to be invalid version") { + KotlinVersion(major, minor, patch) + } + } + } + } + } +} + diff --git a/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib.txt b/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib.txt index 317c2bee790..460e1c27459 100644 --- a/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib.txt +++ b/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib.txt @@ -5,6 +5,7 @@ public final class kotlin/ExceptionsKt { public final class kotlin/KotlinVersion : java/lang/Comparable { public static final field CURRENT Lkotlin/KotlinVersion; public static final field Companion Lkotlin/KotlinVersion$Companion; + public static final field MAX_COMPONENT_VALUE I public fun (II)V public fun (III)V public synthetic fun compareTo (Ljava/lang/Object;)I @@ -16,7 +17,6 @@ public final class kotlin/KotlinVersion : java/lang/Comparable { public fun hashCode ()I public final fun isAtLeast (II)Z public final fun isAtLeast (III)Z - public final fun isAtLeast (Lkotlin/KotlinVersion;)Z public final fun toInt ()I public fun toString ()Ljava/lang/String; }