From 69dc6701cc43af3523961735ed9fb039f634d01f Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Tue, 13 Oct 2015 20:38:15 +0300 Subject: [PATCH] Deprecate Double, Float and Comparable range implementations. --- .../src/kotlin/ProgressionIterators.kt | 2 + core/builtins/src/kotlin/Progressions.kt | 4 + core/builtins/src/kotlin/Ranges.kt | 4 + .../builtins/progressionIterators.kt | 2 +- .../generators/builtins/progressions.kt | 5 + .../kotlin/generators/builtins/ranges.kt | 5 + libraries/stdlib/src/generated/_Ranges.kt | 257 ++++++++++++------ libraries/stdlib/src/kotlin/util/Ranges.kt | 4 + .../test/language/RangeIterationJVMTest.kt | 1 + .../test/language/RangeIterationTest.kt | 1 + .../stdlib/test/language/RangeJVMTest.kt | 1 + libraries/stdlib/test/language/RangeTest.kt | 1 + libraries/stdlib/test/numbers/CoercionTest.kt | 2 + .../src/templates/Comparables.kt | 23 +- .../kotlin-stdlib-gen/src/templates/Ranges.kt | 61 ++++- 15 files changed, 279 insertions(+), 94 deletions(-) diff --git a/core/builtins/src/kotlin/ProgressionIterators.kt b/core/builtins/src/kotlin/ProgressionIterators.kt index 471e9fcb50f..659cb9fad2a 100644 --- a/core/builtins/src/kotlin/ProgressionIterators.kt +++ b/core/builtins/src/kotlin/ProgressionIterators.kt @@ -139,6 +139,7 @@ class LongProgressionIterator(start: Long, end: Long, val increment: Long) : Lon * An iterator over a progression of values of type `Float`. * @property increment the number by which the value is incremented on each step. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) class FloatProgressionIterator(start: Float, val end: Float, val increment: Float) : FloatIterator() { private var next = start @@ -155,6 +156,7 @@ class FloatProgressionIterator(start: Float, val end: Float, val increment: Floa * An iterator over a progression of values of type `Double`. * @property increment the number by which the value is incremented on each step. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) class DoubleProgressionIterator(start: Double, val end: Double, val increment: Double) : DoubleIterator() { private var next = start diff --git a/core/builtins/src/kotlin/Progressions.kt b/core/builtins/src/kotlin/Progressions.kt index 15b45025bd7..0161b6ddd7e 100644 --- a/core/builtins/src/kotlin/Progressions.kt +++ b/core/builtins/src/kotlin/Progressions.kt @@ -153,6 +153,8 @@ public class LongProgression( override fun toString(): String = if (increment > 0) "$start..$end step $increment" else "$start downTo $end step ${-increment}" } +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") /** * A progression of values of type `Float`. */ @@ -181,6 +183,8 @@ public class FloatProgression( override fun toString(): String = if (increment > 0) "$start..$end step $increment" else "$start downTo $end step ${-increment}" } +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") /** * A progression of values of type `Double`. */ diff --git a/core/builtins/src/kotlin/Ranges.kt b/core/builtins/src/kotlin/Ranges.kt index 1d2c16818ce..8e61350214f 100644 --- a/core/builtins/src/kotlin/Ranges.kt +++ b/core/builtins/src/kotlin/Ranges.kt @@ -158,6 +158,8 @@ public class LongRange(override val start: Long, override val end: Long) : Range } } +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") /** * A range of values of type `Float`. */ @@ -186,6 +188,8 @@ public class FloatRange(override val start: Float, override val end: Float) : Ra } } +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") /** * A range of values of type `Double`. */ diff --git a/generators/src/org/jetbrains/kotlin/generators/builtins/progressionIterators.kt b/generators/src/org/jetbrains/kotlin/generators/builtins/progressionIterators.kt index ea91197d5e4..fdb040f17b9 100644 --- a/generators/src/org/jetbrains/kotlin/generators/builtins/progressionIterators.kt +++ b/generators/src/org/jetbrains/kotlin/generators/builtins/progressionIterators.kt @@ -57,11 +57,11 @@ class ${t}ProgressionIterator(start: $t, end: $t, val increment: $incrementType) fun floatingPointProgressionIterator(kind: ProgressionKind): String { val t = kind.capitalized - return """/** * An iterator over a progression of values of type `$t`. * @property increment the number by which the value is incremented on each step. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) class ${t}ProgressionIterator(start: $t, val end: $t, val increment: $t) : ${t}Iterator() { private var next = start diff --git a/generators/src/org/jetbrains/kotlin/generators/builtins/progressions.kt b/generators/src/org/jetbrains/kotlin/generators/builtins/progressions.kt index 2674cfe06dd..50e1994283c 100644 --- a/generators/src/org/jetbrains/kotlin/generators/builtins/progressions.kt +++ b/generators/src/org/jetbrains/kotlin/generators/builtins/progressions.kt @@ -64,6 +64,11 @@ class GenerateProgressions(out: PrintWriter) : BuiltInsSourceGenerator(out) { " }" } + if (kind == FLOAT || kind == DOUBLE) { + out.println("""@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR)""") + out.println("""@Suppress("DEPRECATION_ERROR")""") + } + out.println( """/** * A progression of values of type `$t`. diff --git a/generators/src/org/jetbrains/kotlin/generators/builtins/ranges.kt b/generators/src/org/jetbrains/kotlin/generators/builtins/ranges.kt index ff344707d4e..1fe3d2c3db7 100644 --- a/generators/src/org/jetbrains/kotlin/generators/builtins/ranges.kt +++ b/generators/src/org/jetbrains/kotlin/generators/builtins/ranges.kt @@ -64,6 +64,11 @@ class GenerateRanges(out: PrintWriter) : BuiltInsSourceGenerator(out) { val toString = "\"\$start..\$end\"" + if (kind == FLOAT || kind == DOUBLE) { + out.println("""@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR)""") + out.println("""@Suppress("DEPRECATION_ERROR")""") + } + out.println( """/** * A range of values of type `$t`. diff --git a/libraries/stdlib/src/generated/_Ranges.kt b/libraries/stdlib/src/generated/_Ranges.kt index e17ee8c68ed..bca57a513b0 100644 --- a/libraries/stdlib/src/generated/_Ranges.kt +++ b/libraries/stdlib/src/generated/_Ranges.kt @@ -39,7 +39,9 @@ public operator fun Range.contains(item: Byte): Boolean { /** * Checks if the specified [item] belongs to this range. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) @kotlin.jvm.JvmName("doubleRangeContains") +@Suppress("DEPRECATION_ERROR") public operator fun Range.contains(item: Byte): Boolean { return start <= item && item <= end } @@ -47,7 +49,9 @@ public operator fun Range.contains(item: Byte): Boolean { /** * Checks if the specified [item] belongs to this range. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) @kotlin.jvm.JvmName("floatRangeContains") +@Suppress("DEPRECATION_ERROR") public operator fun Range.contains(item: Byte): Boolean { return start <= item && item <= end } @@ -87,7 +91,9 @@ public operator fun Range.contains(item: Double): Boolean { /** * Checks if the specified [item] belongs to this range. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) @kotlin.jvm.JvmName("floatRangeContains") +@Suppress("DEPRECATION_ERROR") public operator fun Range.contains(item: Double): Boolean { return start <= item && item <= end } @@ -127,7 +133,9 @@ public operator fun Range.contains(item: Float): Boolean { /** * Checks if the specified [item] belongs to this range. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) @kotlin.jvm.JvmName("doubleRangeContains") +@Suppress("DEPRECATION_ERROR") public operator fun Range.contains(item: Float): Boolean { return start <= item && item <= end } @@ -159,7 +167,9 @@ public operator fun Range.contains(item: Int): Boolean { /** * Checks if the specified [item] belongs to this range. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) @kotlin.jvm.JvmName("doubleRangeContains") +@Suppress("DEPRECATION_ERROR") public operator fun Range.contains(item: Int): Boolean { return start <= item && item <= end } @@ -167,7 +177,9 @@ public operator fun Range.contains(item: Int): Boolean { /** * Checks if the specified [item] belongs to this range. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) @kotlin.jvm.JvmName("floatRangeContains") +@Suppress("DEPRECATION_ERROR") public operator fun Range.contains(item: Int): Boolean { return start <= item && item <= end } @@ -199,7 +211,9 @@ public operator fun Range.contains(item: Long): Boolean { /** * Checks if the specified [item] belongs to this range. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) @kotlin.jvm.JvmName("doubleRangeContains") +@Suppress("DEPRECATION_ERROR") public operator fun Range.contains(item: Long): Boolean { return start <= item && item <= end } @@ -207,7 +221,9 @@ public operator fun Range.contains(item: Long): Boolean { /** * Checks if the specified [item] belongs to this range. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) @kotlin.jvm.JvmName("floatRangeContains") +@Suppress("DEPRECATION_ERROR") public operator fun Range.contains(item: Long): Boolean { return start <= item && item <= end } @@ -239,7 +255,9 @@ public operator fun Range.contains(item: Short): Boolean { /** * Checks if the specified [item] belongs to this range. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) @kotlin.jvm.JvmName("doubleRangeContains") +@Suppress("DEPRECATION_ERROR") public operator fun Range.contains(item: Short): Boolean { return start <= item && item <= end } @@ -247,7 +265,9 @@ public operator fun Range.contains(item: Short): Boolean { /** * Checks if the specified [item] belongs to this range. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) @kotlin.jvm.JvmName("floatRangeContains") +@Suppress("DEPRECATION_ERROR") public operator fun Range.contains(item: Short): Boolean { return start <= item && item <= end } @@ -288,6 +308,8 @@ public infix fun Short.downTo(to: Byte): ShortProgression { * Returns a progression from this value down to the specified [to] value with the increment -1. * The [to] value has to be less than this value. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") public infix fun Double.downTo(to: Byte): DoubleProgression { return DoubleProgression(this, to.toDouble(), -1.0) } @@ -296,6 +318,8 @@ public infix fun Double.downTo(to: Byte): DoubleProgression { * Returns a progression from this value down to the specified [to] value with the increment -1. * The [to] value has to be less than this value. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") public infix fun Float.downTo(to: Byte): FloatProgression { return FloatProgression(this, to.toFloat(), -1.0F) } @@ -312,6 +336,8 @@ public infix fun Char.downTo(to: Char): CharProgression { * Returns a progression from this value down to the specified [to] value with the increment -1. * The [to] value has to be less than this value. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") public infix fun Int.downTo(to: Double): DoubleProgression { return DoubleProgression(this.toDouble(), to, -1.0) } @@ -320,6 +346,8 @@ public infix fun Int.downTo(to: Double): DoubleProgression { * Returns a progression from this value down to the specified [to] value with the increment -1. * The [to] value has to be less than this value. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") public infix fun Long.downTo(to: Double): DoubleProgression { return DoubleProgression(this.toDouble(), to, -1.0) } @@ -328,6 +356,8 @@ public infix fun Long.downTo(to: Double): DoubleProgression { * Returns a progression from this value down to the specified [to] value with the increment -1. * The [to] value has to be less than this value. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") public infix fun Byte.downTo(to: Double): DoubleProgression { return DoubleProgression(this.toDouble(), to, -1.0) } @@ -336,6 +366,8 @@ public infix fun Byte.downTo(to: Double): DoubleProgression { * Returns a progression from this value down to the specified [to] value with the increment -1. * The [to] value has to be less than this value. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") public infix fun Short.downTo(to: Double): DoubleProgression { return DoubleProgression(this.toDouble(), to, -1.0) } @@ -344,6 +376,8 @@ public infix fun Short.downTo(to: Double): DoubleProgression { * Returns a progression from this value down to the specified [to] value with the increment -1. * The [to] value has to be less than this value. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") public infix fun Double.downTo(to: Double): DoubleProgression { return DoubleProgression(this, to, -1.0) } @@ -352,6 +386,8 @@ public infix fun Double.downTo(to: Double): DoubleProgression { * Returns a progression from this value down to the specified [to] value with the increment -1. * The [to] value has to be less than this value. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") public infix fun Float.downTo(to: Double): DoubleProgression { return DoubleProgression(this.toDouble(), to, -1.0) } @@ -360,6 +396,8 @@ public infix fun Float.downTo(to: Double): DoubleProgression { * Returns a progression from this value down to the specified [to] value with the increment -1. * The [to] value has to be less than this value. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") public infix fun Int.downTo(to: Float): FloatProgression { return FloatProgression(this.toFloat(), to, -1.0F) } @@ -368,6 +406,8 @@ public infix fun Int.downTo(to: Float): FloatProgression { * Returns a progression from this value down to the specified [to] value with the increment -1. * The [to] value has to be less than this value. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") public infix fun Long.downTo(to: Float): FloatProgression { return FloatProgression(this.toFloat(), to, -1.0F) } @@ -376,6 +416,8 @@ public infix fun Long.downTo(to: Float): FloatProgression { * Returns a progression from this value down to the specified [to] value with the increment -1. * The [to] value has to be less than this value. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") public infix fun Byte.downTo(to: Float): FloatProgression { return FloatProgression(this.toFloat(), to, -1.0F) } @@ -384,6 +426,8 @@ public infix fun Byte.downTo(to: Float): FloatProgression { * Returns a progression from this value down to the specified [to] value with the increment -1. * The [to] value has to be less than this value. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") public infix fun Short.downTo(to: Float): FloatProgression { return FloatProgression(this.toFloat(), to, -1.0F) } @@ -392,6 +436,8 @@ public infix fun Short.downTo(to: Float): FloatProgression { * Returns a progression from this value down to the specified [to] value with the increment -1. * The [to] value has to be less than this value. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") public infix fun Double.downTo(to: Float): DoubleProgression { return DoubleProgression(this, to.toDouble(), -1.0) } @@ -400,6 +446,8 @@ public infix fun Double.downTo(to: Float): DoubleProgression { * Returns a progression from this value down to the specified [to] value with the increment -1. * The [to] value has to be less than this value. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") public infix fun Float.downTo(to: Float): FloatProgression { return FloatProgression(this, to, -1.0F) } @@ -440,6 +488,8 @@ public infix fun Short.downTo(to: Int): IntProgression { * Returns a progression from this value down to the specified [to] value with the increment -1. * The [to] value has to be less than this value. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") public infix fun Double.downTo(to: Int): DoubleProgression { return DoubleProgression(this, to.toDouble(), -1.0) } @@ -448,6 +498,8 @@ public infix fun Double.downTo(to: Int): DoubleProgression { * Returns a progression from this value down to the specified [to] value with the increment -1. * The [to] value has to be less than this value. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") public infix fun Float.downTo(to: Int): FloatProgression { return FloatProgression(this, to.toFloat(), -1.0F) } @@ -488,6 +540,8 @@ public infix fun Short.downTo(to: Long): LongProgression { * Returns a progression from this value down to the specified [to] value with the increment -1. * The [to] value has to be less than this value. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") public infix fun Double.downTo(to: Long): DoubleProgression { return DoubleProgression(this, to.toDouble(), -1.0) } @@ -496,6 +550,8 @@ public infix fun Double.downTo(to: Long): DoubleProgression { * Returns a progression from this value down to the specified [to] value with the increment -1. * The [to] value has to be less than this value. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") public infix fun Float.downTo(to: Long): FloatProgression { return FloatProgression(this, to.toFloat(), -1.0F) } @@ -536,6 +592,8 @@ public infix fun Short.downTo(to: Short): ShortProgression { * Returns a progression from this value down to the specified [to] value with the increment -1. * The [to] value has to be less than this value. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") public infix fun Double.downTo(to: Short): DoubleProgression { return DoubleProgression(this, to.toDouble(), -1.0) } @@ -544,6 +602,8 @@ public infix fun Double.downTo(to: Short): DoubleProgression { * Returns a progression from this value down to the specified [to] value with the increment -1. * The [to] value has to be less than this value. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") public infix fun Float.downTo(to: Short): FloatProgression { return FloatProgression(this, to.toFloat(), -1.0F) } @@ -562,20 +622,6 @@ public fun CharProgression.reversed(): CharProgression { return CharProgression(end, start, -increment) } -/** - * Returns a progression that goes over the same range in the opposite direction with the same step. - */ -public fun DoubleProgression.reversed(): DoubleProgression { - return DoubleProgression(end, start, -increment) -} - -/** - * Returns a progression that goes over the same range in the opposite direction with the same step. - */ -public fun FloatProgression.reversed(): FloatProgression { - return FloatProgression(end, start, -increment) -} - /** * Returns a progression that goes over the same range in the opposite direction with the same step. */ @@ -611,20 +657,6 @@ public fun CharRange.reversed(): CharProgression { return CharProgression(end, start, -1) } -/** - * Returns a progression that goes over this range in reverse direction. - */ -public fun DoubleRange.reversed(): DoubleProgression { - return DoubleProgression(end, start, -1.0) -} - -/** - * Returns a progression that goes over this range in reverse direction. - */ -public fun FloatRange.reversed(): FloatProgression { - return FloatProgression(end, start, -1.0f) -} - /** * Returns a progression that goes over this range in reverse direction. */ @@ -646,6 +678,42 @@ public fun ShortRange.reversed(): ShortProgression { return ShortProgression(end, start, -1) } +/** + * Returns a progression that goes over the same range in the opposite direction with the same step. + */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") +public fun DoubleProgression.reversed(): DoubleProgression { + return DoubleProgression(end, start, -increment) +} + +/** + * Returns a progression that goes over the same range in the opposite direction with the same step. + */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") +public fun FloatProgression.reversed(): FloatProgression { + return FloatProgression(end, start, -increment) +} + +/** + * Returns a progression that goes over this range in reverse direction. + */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") +public fun DoubleRange.reversed(): DoubleProgression { + return DoubleProgression(end, start, -1.0) +} + +/** + * Returns a progression that goes over this range in reverse direction. + */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") +public fun FloatRange.reversed(): FloatProgression { + return FloatProgression(end, start, -1.0f) +} + /** * Returns a progression that goes over the same range with the given step. */ @@ -662,22 +730,6 @@ public infix fun CharProgression.step(step: Int): CharProgression { return CharProgression(start, end, if (increment > 0) step else -step) } -/** - * Returns a progression that goes over the same range with the given step. - */ -public infix fun DoubleProgression.step(step: Double): DoubleProgression { - checkStepIsPositive(step > 0, step) - return DoubleProgression(start, end, if (increment > 0) step else -step) -} - -/** - * Returns a progression that goes over the same range with the given step. - */ -public infix fun FloatProgression.step(step: Float): FloatProgression { - checkStepIsPositive(step > 0, step) - return FloatProgression(start, end, if (increment > 0) step else -step) -} - /** * Returns a progression that goes over the same range with the given step. */ @@ -718,24 +770,6 @@ public infix fun CharRange.step(step: Int): CharProgression { return CharProgression(start, end, step) } -/** - * Returns a progression that goes over this range with given step. - */ -public infix fun DoubleRange.step(step: Double): DoubleProgression { - if (step.isNaN()) throw IllegalArgumentException("Step must not be NaN.") - checkStepIsPositive(step > 0, step) - return DoubleProgression(start, end, step) -} - -/** - * Returns a progression that goes over this range with given step. - */ -public infix fun FloatRange.step(step: Float): FloatProgression { - if (step.isNaN()) throw IllegalArgumentException("Step must not be NaN.") - checkStepIsPositive(step > 0, step) - return FloatProgression(start, end, step) -} - /** * Returns a progression that goes over this range with given step. */ @@ -760,6 +794,48 @@ public infix fun ShortRange.step(step: Int): ShortProgression { return ShortProgression(start, end, step) } +/** + * Returns a progression that goes over the same range with the given step. + */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") +public infix fun DoubleProgression.step(step: Double): DoubleProgression { + checkStepIsPositive(step > 0, step) + return DoubleProgression(start, end, if (increment > 0) step else -step) +} + +/** + * Returns a progression that goes over the same range with the given step. + */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") +public infix fun FloatProgression.step(step: Float): FloatProgression { + checkStepIsPositive(step > 0, step) + return FloatProgression(start, end, if (increment > 0) step else -step) +} + +/** + * Returns a progression that goes over this range with given step. + */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") +public infix fun DoubleRange.step(step: Double): DoubleProgression { + if (step.isNaN()) throw IllegalArgumentException("Step must not be NaN.") + checkStepIsPositive(step > 0, step) + return DoubleProgression(start, end, step) +} + +/** + * Returns a progression that goes over this range with given step. + */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") +public infix fun FloatRange.step(step: Float): FloatProgression { + if (step.isNaN()) throw IllegalArgumentException("Step must not be NaN.") + checkStepIsPositive(step > 0, step) + return FloatProgression(start, end, step) +} + /** * Returns a range from this value up to but excluding the specified [to] value. */ @@ -1143,15 +1219,6 @@ public fun Short.coerceIn(minimumValue: Short?, maximumValue: Short?): Short { return this } -/** - * Ensures that this value lies in the specified [range]. - * @return this value if it's in the [range], or range.start if this value is less than range.start, or range.end if this value is greater than range.end. - */ -public fun > T.coerceIn(range: Range): T { - if (range.isEmpty()) throw IllegalArgumentException("Cannot coerce value to an empty range: $range.") - return if (this < range.start) range.start else if (this > range.end) range.end else this -} - /** * Ensures that this value lies in the specified [range]. * @return this value if it's in the [range], or range.start if this value is less than range.start, or range.end if this value is greater than range.end. @@ -1161,24 +1228,6 @@ public fun Byte.coerceIn(range: Range): Byte { return if (this < range.start) range.start else if (this > range.end) range.end else this } -/** - * Ensures that this value lies in the specified [range]. - * @return this value if it's in the [range], or range.start if this value is less than range.start, or range.end if this value is greater than range.end. - */ -public fun Double.coerceIn(range: Range): Double { - if (range.isEmpty()) throw IllegalArgumentException("Cannot coerce value to an empty range: $range.") - return if (this < range.start) range.start else if (this > range.end) range.end else this -} - -/** - * Ensures that this value lies in the specified [range]. - * @return this value if it's in the [range], or range.start if this value is less than range.start, or range.end if this value is greater than range.end. - */ -public fun Float.coerceIn(range: Range): Float { - if (range.isEmpty()) throw IllegalArgumentException("Cannot coerce value to an empty range: $range.") - return if (this < range.start) range.start else if (this > range.end) range.end else this -} - /** * Ensures that this value lies in the specified [range]. * @return this value if it's in the [range], or range.start if this value is less than range.start, or range.end if this value is greater than range.end. @@ -1206,3 +1255,33 @@ public fun Short.coerceIn(range: Range): Short { return if (this < range.start) range.start else if (this > range.end) range.end else this } +/** + * Ensures that this value lies in the specified [range]. + * @return this value if it's in the [range], or range.start if this value is less than range.start, or range.end if this value is greater than range.end. + */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +public fun > T.coerceIn(range: Range): T { + if (range.isEmpty()) throw IllegalArgumentException("Cannot coerce value to an empty range: $range.") + return if (this < range.start) range.start else if (this > range.end) range.end else this +} + +/** + * Ensures that this value lies in the specified [range]. + * @return this value if it's in the [range], or range.start if this value is less than range.start, or range.end if this value is greater than range.end. + */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +public fun Double.coerceIn(range: Range): Double { + if (range.isEmpty()) throw IllegalArgumentException("Cannot coerce value to an empty range: $range.") + return if (this < range.start) range.start else if (this > range.end) range.end else this +} + +/** + * Ensures that this value lies in the specified [range]. + * @return this value if it's in the [range], or range.start if this value is less than range.start, or range.end if this value is greater than range.end. + */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +public fun Float.coerceIn(range: Range): Float { + if (range.isEmpty()) throw IllegalArgumentException("Cannot coerce value to an empty range: $range.") + return if (this < range.start) range.start else if (this > range.end) range.end else this +} + diff --git a/libraries/stdlib/src/kotlin/util/Ranges.kt b/libraries/stdlib/src/kotlin/util/Ranges.kt index df955f6c5d5..0bd814d22a9 100644 --- a/libraries/stdlib/src/kotlin/util/Ranges.kt +++ b/libraries/stdlib/src/kotlin/util/Ranges.kt @@ -5,6 +5,7 @@ package kotlin /** * Represents a range of [Comparable] values. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) public class ComparableRange> ( override val start: T, override val end: T @@ -13,6 +14,7 @@ public class ComparableRange> ( return start <= item && item <= end } + @Suppress("DEPRECATION_ERROR") override fun equals(other: Any?): Boolean { return other is ComparableRange<*> && (isEmpty() && other.isEmpty() || start == other.start && end == other.end) @@ -29,6 +31,8 @@ public class ComparableRange> ( * Creates a range from this [Comparable] value to the specified [that] value. This value * needs to be smaller than [that] value, otherwise the returned range will be empty. */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR) +@Suppress("DEPRECATION_ERROR") public operator fun > T.rangeTo(that: T): ComparableRange { return ComparableRange(this, that) } diff --git a/libraries/stdlib/test/language/RangeIterationJVMTest.kt b/libraries/stdlib/test/language/RangeIterationJVMTest.kt index 506954168f3..b8d02d3159a 100644 --- a/libraries/stdlib/test/language/RangeIterationJVMTest.kt +++ b/libraries/stdlib/test/language/RangeIterationJVMTest.kt @@ -1,3 +1,4 @@ +@file: Suppress("DEPRECATION_ERROR") package language import java.lang.Integer.MAX_VALUE as MaxI diff --git a/libraries/stdlib/test/language/RangeIterationTest.kt b/libraries/stdlib/test/language/RangeIterationTest.kt index 875f7d0a2c2..223a8b71f85 100644 --- a/libraries/stdlib/test/language/RangeIterationTest.kt +++ b/libraries/stdlib/test/language/RangeIterationTest.kt @@ -1,3 +1,4 @@ +@file: Suppress("DEPRECATION_ERROR") package language import org.junit.Test as test diff --git a/libraries/stdlib/test/language/RangeJVMTest.kt b/libraries/stdlib/test/language/RangeJVMTest.kt index 287ab6612af..e17e596a1ab 100644 --- a/libraries/stdlib/test/language/RangeJVMTest.kt +++ b/libraries/stdlib/test/language/RangeJVMTest.kt @@ -1,3 +1,4 @@ +@file: Suppress("DEPRECATION_ERROR") package language import java.lang.Double as jDouble diff --git a/libraries/stdlib/test/language/RangeTest.kt b/libraries/stdlib/test/language/RangeTest.kt index 1f40847f11b..85da2472048 100644 --- a/libraries/stdlib/test/language/RangeTest.kt +++ b/libraries/stdlib/test/language/RangeTest.kt @@ -1,3 +1,4 @@ +@file: Suppress("DEPRECATION_ERROR") package language import kotlin.test.* diff --git a/libraries/stdlib/test/numbers/CoercionTest.kt b/libraries/stdlib/test/numbers/CoercionTest.kt index 1ea7d0db96d..6730ca3509c 100644 --- a/libraries/stdlib/test/numbers/CoercionTest.kt +++ b/libraries/stdlib/test/numbers/CoercionTest.kt @@ -65,6 +65,7 @@ class CoercionTest { } @Test + @Suppress("DEPRECATION_ERROR") fun coercionsDouble() { expect(5.0) { 5.0.coerceAtLeast(1.0) } expect(5.0) { 1.0.coerceAtLeast(5.0) } @@ -88,6 +89,7 @@ class CoercionTest { } @Test + @Suppress("DEPRECATION_ERROR") fun coercionsComparable() { val v = 0..10 map { ComparableNumber(it) } diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Comparables.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Comparables.kt index abf719694ab..39117466692 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Comparables.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Comparables.kt @@ -47,10 +47,30 @@ fun comparables(): List { } } + templates add f("coerceIn(range: Range)") { + sourceFile(SourceFile.Ranges) + only(Primitives) + only(numericPrimitives.filter { it.isIntegral() }) + returns("SELF") + doc { + """ + Ensures that this value lies in the specified [range]. + + @return this value if it's in the [range], or range.start if this value is less than range.start, or range.end if this value is greater than range.end. + """ + } + body { + """ + if (range.isEmpty()) throw IllegalArgumentException("Cannot coerce value to an empty range: ${'$'}range.") + return if (this < range.start) range.start else if (this > range.end) range.end else this + """ + } + } + templates add f("coerceIn(range: Range)") { sourceFile(SourceFile.Ranges) only(Primitives, Generic) - only(numericPrimitives) + only(numericPrimitives.filterNot { it.isIntegral() }) returns("SELF") typeParam("T: Comparable") doc { @@ -60,6 +80,7 @@ fun comparables(): List { @return this value if it's in the [range], or range.start if this value is less than range.start, or range.end if this value is greater than range.end. """ } + deprecate(Deprecation("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR)) body { """ if (range.isEmpty()) throw IllegalArgumentException("Cannot coerce value to an empty range: ${'$'}range.") diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Ranges.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Ranges.kt index cf075815806..19cc620d7ba 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Ranges.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Ranges.kt @@ -8,7 +8,7 @@ fun ranges(): List { templates add f("reversed()") { only(RangesOfPrimitives, ProgressionsOfPrimitives) - exclude(PrimitiveType.Boolean) + only(PrimitiveType.integralPrimitives) doc(ProgressionsOfPrimitives) { "Returns a progression that goes over the same range in the opposite direction with the same step." } doc(RangesOfPrimitives) { "Returns a progression that goes over this range in reverse direction." } returns("TProgression") @@ -20,11 +20,27 @@ fun ranges(): List { } } + templates add f("reversed()") { + only(RangesOfPrimitives, ProgressionsOfPrimitives) + only(defaultPrimitives - PrimitiveType.Boolean - PrimitiveType.integralPrimitives) + doc(ProgressionsOfPrimitives) { "Returns a progression that goes over the same range in the opposite direction with the same step." } + doc(RangesOfPrimitives) { "Returns a progression that goes over this range in reverse direction." } + returns("TProgression") + deprecate(Deprecation("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR)) + annotations("""@Suppress("DEPRECATION_ERROR")""") + body(RangesOfPrimitives) { + "return TProgression(end, start, -ONE)" + } + body(ProgressionsOfPrimitives) { + "return TProgression(end, start, -increment)" + } + } + templates add f("step(step: SUM)") { infix(true) only(RangesOfPrimitives, ProgressionsOfPrimitives) - exclude(PrimitiveType.Boolean) + only(PrimitiveType.integralPrimitives) doc(ProgressionsOfPrimitives) { "Returns a progression that goes over the same range with the given step." } doc(RangesOfPrimitives) { "Returns a progression that goes over this range with given step." } returns("TProgression") @@ -34,6 +50,30 @@ fun ranges(): List { return TProgression(start, end, step) """ } + body(ProgressionsOfPrimitives) { + """ + checkStepIsPositive(step > 0, step) + return TProgression(start, end, if (increment > 0) step else -step) + """ + } + } + + templates add f("step(step: SUM)") { + infix(true) + + only(RangesOfPrimitives, ProgressionsOfPrimitives) + only(defaultPrimitives - PrimitiveType.Boolean - PrimitiveType.integralPrimitives) + doc(ProgressionsOfPrimitives) { "Returns a progression that goes over the same range with the given step." } + doc(RangesOfPrimitives) { "Returns a progression that goes over this range with given step." } + returns("TProgression") + deprecate(Deprecation("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR)) + annotations("""@Suppress("DEPRECATION_ERROR")""") + body(RangesOfPrimitives) { + """ + checkStepIsPositive(step > 0, step) + return TProgression(start, end, step) + """ + } bodyForTypes(RangesOfPrimitives, PrimitiveType.Float, PrimitiveType.Double) { """ if (step.isNaN()) throw IllegalArgumentException("Step must not be NaN.") @@ -66,6 +106,11 @@ fun ranges(): List { """ } + if (!fromType.isIntegral() || !toType.isIntegral()) { + deprecate(Deprecation("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR)) + annotations("""@Suppress("DEPRECATION_ERROR")""") + } + val fromExpr = if (elementType == fromType) "this" else "this.to$elementType()" val toExpr = if (elementType == toType) "to" else "to.to$elementType()" val incrementExpr = when (elementType) { @@ -101,6 +146,11 @@ fun ranges(): List { """ } + if (!fromType.isIntegral() || !toType.isIntegral()) { + deprecate(Deprecation("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR)) + annotations("""@Suppress("DEPRECATION_ERROR")""") + } + val fromExpr = if (elementType == fromType) "this" else "this.to$elementType()" if (elementType == toType) { @@ -129,7 +179,12 @@ fun ranges(): List { fun contains(rangeType: PrimitiveType, itemType: PrimitiveType) = f("contains(item: $itemType)") { operator(true) - assert(rangeType.isNumeric() != itemType.isNumeric()) + if (!rangeType.isIntegral()) { + deprecate(Deprecation("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.ERROR)) + annotations("""@Suppress("DEPRECATION_ERROR")""") + } + + check(rangeType.isNumeric() == itemType.isNumeric()) { "Require rangeType and itemType both be numeric or both not, got: $rangeType, $itemType" } only(Ranges) onlyPrimitives(Ranges, rangeType) platformName("${rangeType.name.decapitalize()}RangeContains")