diff --git a/core/builtins/native/kotlin/Primitives.kt b/core/builtins/native/kotlin/Primitives.kt index fc3fbe14281..99a14d03f45 100644 --- a/core/builtins/native/kotlin/Primitives.kt +++ b/core/builtins/native/kotlin/Primitives.kt @@ -137,9 +137,9 @@ public class Byte private () : Number, Comparable { public operator fun unaryMinus(): Int /** Creates a range from this value to the specified [other] value. */ - public operator fun rangeTo(other: Byte): ByteRange + public operator fun rangeTo(other: Byte): IntRange /** Creates a range from this value to the specified [other] value. */ - public operator fun rangeTo(other: Short): ShortRange + public operator fun rangeTo(other: Short): IntRange /** Creates a range from this value to the specified [other] value. */ public operator fun rangeTo(other: Int): IntRange /** Creates a range from this value to the specified [other] value. */ @@ -277,9 +277,9 @@ public class Short private () : Number, Comparable { public operator fun unaryMinus(): Int /** Creates a range from this value to the specified [other] value. */ - public operator fun rangeTo(other: Byte): ShortRange + public operator fun rangeTo(other: Byte): IntRange /** Creates a range from this value to the specified [other] value. */ - public operator fun rangeTo(other: Short): ShortRange + public operator fun rangeTo(other: Short): IntRange /** Creates a range from this value to the specified [other] value. */ public operator fun rangeTo(other: Int): IntRange /** Creates a range from this value to the specified [other] value. */ diff --git a/generators/src/org/jetbrains/kotlin/generators/builtins/primitives.kt b/generators/src/org/jetbrains/kotlin/generators/builtins/primitives.kt index b3ea30b3e72..2befbe3525b 100644 --- a/generators/src/org/jetbrains/kotlin/generators/builtins/primitives.kt +++ b/generators/src/org/jetbrains/kotlin/generators/builtins/primitives.kt @@ -113,14 +113,16 @@ class GeneratePrimitives(out: PrintWriter) : BuiltInsSourceGenerator(out) { for (otherKind in PrimitiveType.onlyNumeric) { val returnType = getOperatorReturnType(thisKind, otherKind) out.println(" /** $doc */") - out.println(" public operator fun $name(other: ${otherKind.capitalized}): $returnType") + out.println(" public operator fun $name(other: ${otherKind.capitalized}): ${returnType.capitalized}") } out.println() } private fun generateRangeTo(thisKind: PrimitiveType) { for (otherKind in PrimitiveType.onlyNumeric) { - val returnType = if (otherKind.ordinal() > thisKind.ordinal()) otherKind else thisKind + val returnType = + maxByDomainCapacity(thisKind, otherKind) + .let { if (it == PrimitiveType.CHAR) it else maxByDomainCapacity(it, PrimitiveType.INT) } out.println(" /** Creates a range from this value to the specified [other] value. */") out.println(" public operator fun rangeTo(other: ${otherKind.capitalized}): ${returnType.capitalized}Range") } @@ -159,10 +161,12 @@ class GeneratePrimitives(out: PrintWriter) : BuiltInsSourceGenerator(out) { } } - private fun getOperatorReturnType(kind1: PrimitiveType, kind2: PrimitiveType): String { - if (kind1 == PrimitiveType.DOUBLE || kind2 == PrimitiveType.DOUBLE) return "Double" - if (kind1 == PrimitiveType.FLOAT || kind2 == PrimitiveType.FLOAT) return "Float" - if (kind1 == PrimitiveType.LONG || kind2 == PrimitiveType.LONG) return "Long" - return "Int" + private fun maxByDomainCapacity(type1: PrimitiveType, type2: PrimitiveType): PrimitiveType + = if (type1.ordinal > type2.ordinal) type1 else type2 + + private fun getOperatorReturnType(kind1: PrimitiveType, kind2: PrimitiveType): PrimitiveType { + require(kind1 != PrimitiveType.BOOLEAN) { "kind1 must not be BOOLEAN" } + require(kind2 != PrimitiveType.BOOLEAN) { "kind2 must not be BOOLEAN" } + return maxByDomainCapacity(maxByDomainCapacity(kind1, kind2), PrimitiveType.INT) } } diff --git a/libraries/stdlib/src/generated/_Ranges.kt b/libraries/stdlib/src/generated/_Ranges.kt index 4f9bbdf9a40..4ddf2f7ef9b 100644 --- a/libraries/stdlib/src/generated/_Ranges.kt +++ b/libraries/stdlib/src/generated/_Ranges.kt @@ -31,6 +31,7 @@ public operator fun Range.contains(item: Byte): Boolean { /** * Checks if the specified [item] belongs to this range. */ +@Deprecated("This range will be removed soon.") @kotlin.jvm.JvmName("shortRangeContains") public operator fun Range.contains(item: Byte): Boolean { return start <= item && item <= end @@ -75,6 +76,7 @@ public operator fun Range.contains(item: Double): Boolean { /** * Checks if the specified [item] belongs to this range. */ +@Deprecated("This range will be removed soon.") @kotlin.jvm.JvmName("byteRangeContains") public operator fun Range.contains(item: Double): Boolean { return start <= item && item <= end @@ -83,6 +85,7 @@ public operator fun Range.contains(item: Double): Boolean { /** * Checks if the specified [item] belongs to this range. */ +@Deprecated("This range will be removed soon.") @kotlin.jvm.JvmName("shortRangeContains") public operator fun Range.contains(item: Double): Boolean { return start <= item && item <= end @@ -117,6 +120,7 @@ public operator fun Range.contains(item: Float): Boolean { /** * Checks if the specified [item] belongs to this range. */ +@Deprecated("This range will be removed soon.") @kotlin.jvm.JvmName("byteRangeContains") public operator fun Range.contains(item: Float): Boolean { return start <= item && item <= end @@ -125,6 +129,7 @@ public operator fun Range.contains(item: Float): Boolean { /** * Checks if the specified [item] belongs to this range. */ +@Deprecated("This range will be removed soon.") @kotlin.jvm.JvmName("shortRangeContains") public operator fun Range.contains(item: Float): Boolean { return start <= item && item <= end @@ -151,6 +156,7 @@ public operator fun Range.contains(item: Int): Boolean { /** * Checks if the specified [item] belongs to this range. */ +@Deprecated("This range will be removed soon.") @kotlin.jvm.JvmName("byteRangeContains") public operator fun Range.contains(item: Int): Boolean { return start <= item && item <= end @@ -159,6 +165,7 @@ public operator fun Range.contains(item: Int): Boolean { /** * Checks if the specified [item] belongs to this range. */ +@Deprecated("This range will be removed soon.") @kotlin.jvm.JvmName("shortRangeContains") public operator fun Range.contains(item: Int): Boolean { return start <= item && item <= end @@ -195,6 +202,7 @@ public operator fun Range.contains(item: Long): Boolean { /** * Checks if the specified [item] belongs to this range. */ +@Deprecated("This range will be removed soon.") @kotlin.jvm.JvmName("byteRangeContains") public operator fun Range.contains(item: Long): Boolean { return start <= item && item <= end @@ -203,6 +211,7 @@ public operator fun Range.contains(item: Long): Boolean { /** * Checks if the specified [item] belongs to this range. */ +@Deprecated("This range will be removed soon.") @kotlin.jvm.JvmName("shortRangeContains") public operator fun Range.contains(item: Long): Boolean { return start <= item && item <= end @@ -247,6 +256,7 @@ public operator fun Range.contains(item: Short): Boolean { /** * Checks if the specified [item] belongs to this range. */ +@Deprecated("This range will be removed soon.") @kotlin.jvm.JvmName("byteRangeContains") public operator fun Range.contains(item: Short): Boolean { return start <= item && item <= end @@ -292,16 +302,16 @@ public infix fun Long.downTo(to: Byte): 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. */ -public infix fun Byte.downTo(to: Byte): ByteProgression { - return ByteProgression(this, to, -1) +public infix fun Byte.downTo(to: Byte): IntProgression { + return IntProgression(this.toInt(), to.toInt(), -1) } /** * 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. */ -public infix fun Short.downTo(to: Byte): ShortProgression { - return ShortProgression(this, to.toShort(), -1) +public infix fun Short.downTo(to: Byte): IntProgression { + return IntProgression(this.toInt(), to.toInt(), -1) } /** @@ -576,16 +586,16 @@ public infix fun Long.downTo(to: Short): 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. */ -public infix fun Byte.downTo(to: Short): ShortProgression { - return ShortProgression(this.toShort(), to, -1) +public infix fun Byte.downTo(to: Short): IntProgression { + return IntProgression(this.toInt(), to.toInt(), -1) } /** * 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. */ -public infix fun Short.downTo(to: Short): ShortProgression { - return ShortProgression(this, to, -1) +public infix fun Short.downTo(to: Short): IntProgression { + return IntProgression(this.toInt(), to.toInt(), -1) } /** @@ -608,13 +618,6 @@ public infix fun Float.downTo(to: Short): FloatProgression { return FloatProgression(this, to.toFloat(), -1.0F) } -/** - * Returns a progression that goes over the same range in the opposite direction with the same step. - */ -public fun ByteProgression.reversed(): ByteProgression { - return ByteProgression(end, start, -increment) -} - /** * Returns a progression that goes over the same range in the opposite direction with the same step. */ @@ -636,20 +639,6 @@ public fun LongProgression.reversed(): LongProgression { return LongProgression(end, start, -increment) } -/** - * Returns a progression that goes over the same range in the opposite direction with the same step. - */ -public fun ShortProgression.reversed(): ShortProgression { - return ShortProgression(end, start, -increment) -} - -/** - * Returns a progression that goes over this range in reverse direction. - */ -public fun ByteRange.reversed(): ByteProgression { - return ByteProgression(end, start, -1) -} - /** * Returns a progression that goes over this range in reverse direction. */ @@ -672,10 +661,12 @@ public fun LongRange.reversed(): LongProgression { } /** - * Returns a progression that goes over this range in reverse direction. + * Returns a progression that goes over the same range in the opposite direction with the same step. */ -public fun ShortRange.reversed(): ShortProgression { - return ShortProgression(end, start, -1) +@Deprecated("This range implementation has unclear semantics and will be removed soon.") +@Suppress("DEPRECATION_ERROR") +public fun ByteProgression.reversed(): ByteProgression { + return ByteProgression(end, start, -increment) } /** @@ -696,6 +687,24 @@ 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. + */ +@Deprecated("This range implementation has unclear semantics and will be removed soon.") +@Suppress("DEPRECATION_ERROR") +public fun ShortProgression.reversed(): ShortProgression { + return ShortProgression(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.") +@Suppress("DEPRECATION_ERROR") +public fun ByteRange.reversed(): ByteProgression { + return ByteProgression(end, start, -1) +} + /** * Returns a progression that goes over this range in reverse direction. */ @@ -715,11 +724,12 @@ public fun FloatRange.reversed(): FloatProgression { } /** - * Returns a progression that goes over the same range with the given step. + * Returns a progression that goes over this range in reverse direction. */ -public infix fun ByteProgression.step(step: Int): ByteProgression { - checkStepIsPositive(step > 0, step) - return ByteProgression(start, end, if (increment > 0) step else -step) +@Deprecated("This range implementation has unclear semantics and will be removed soon.") +@Suppress("DEPRECATION_ERROR") +public fun ShortRange.reversed(): ShortProgression { + return ShortProgression(end, start, -1) } /** @@ -746,22 +756,6 @@ public infix fun LongProgression.step(step: Long): LongProgression { return LongProgression(start, end, if (increment > 0) step else -step) } -/** - * Returns a progression that goes over the same range with the given step. - */ -public infix fun ShortProgression.step(step: Int): ShortProgression { - checkStepIsPositive(step > 0, step) - return ShortProgression(start, end, if (increment > 0) step else -step) -} - -/** - * Returns a progression that goes over this range with given step. - */ -public infix fun ByteRange.step(step: Int): ByteProgression { - checkStepIsPositive(step > 0, step) - return ByteProgression(start, end, step) -} - /** * Returns a progression that goes over this range with given step. */ @@ -787,11 +781,13 @@ public infix fun LongRange.step(step: Long): LongProgression { } /** - * Returns a progression that goes over this range with given step. + * Returns a progression that goes over the same range with the given step. */ -public infix fun ShortRange.step(step: Int): ShortProgression { +@Deprecated("This range implementation has unclear semantics and will be removed soon.") +@Suppress("DEPRECATION_ERROR") +public infix fun ByteProgression.step(step: Int): ByteProgression { checkStepIsPositive(step > 0, step) - return ShortProgression(start, end, step) + return ByteProgression(start, end, if (increment > 0) step else -step) } /** @@ -814,6 +810,26 @@ public infix fun FloatProgression.step(step: Float): FloatProgression { return FloatProgression(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.") +@Suppress("DEPRECATION_ERROR") +public infix fun ShortProgression.step(step: Int): ShortProgression { + checkStepIsPositive(step > 0, step) + return ShortProgression(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.") +@Suppress("DEPRECATION_ERROR") +public infix fun ByteRange.step(step: Int): ByteProgression { + checkStepIsPositive(step > 0, step) + return ByteProgression(start, end, step) +} + /** * Returns a progression that goes over this range with given step. */ @@ -836,6 +852,16 @@ public infix fun FloatRange.step(step: Float): FloatProgression { return FloatProgression(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.") +@Suppress("DEPRECATION_ERROR") +public infix fun ShortRange.step(step: Int): ShortProgression { + checkStepIsPositive(step > 0, step) + return ShortProgression(start, end, step) +} + /** * Returns a range from this value up to but excluding the specified [to] value. */ @@ -852,19 +878,16 @@ public infix fun Long.until(to: Byte): LongRange { /** * Returns a range from this value up to but excluding the specified [to] value. - * The [to] value must be greater than [Byte.MIN_VALUE]. */ -public infix fun Byte.until(to: Byte): ByteRange { - val to_ = (to - 1).toByte() - if (to_ > to) throw IllegalArgumentException("The to argument value '$to' was too small.") - return this .. to_ +public infix fun Byte.until(to: Byte): IntRange { + return this.toInt() .. (to.toInt() - 1).toInt() } /** * Returns a range from this value up to but excluding the specified [to] value. */ -public infix fun Short.until(to: Byte): ShortRange { - return this .. (to.toShort() - 1).toShort() +public infix fun Short.until(to: Byte): IntRange { + return this.toInt() .. (to.toInt() - 1).toInt() } /** @@ -970,22 +993,16 @@ public infix fun Long.until(to: Short): LongRange { /** * Returns a range from this value up to but excluding the specified [to] value. - * The [to] value must be greater than [Short.MIN_VALUE]. */ -public infix fun Byte.until(to: Short): ShortRange { - val to_ = (to - 1).toShort() - if (to_ > to) throw IllegalArgumentException("The to argument value '$to' was too small.") - return this.toShort() .. to_ +public infix fun Byte.until(to: Short): IntRange { + return this.toInt() .. (to.toInt() - 1).toInt() } /** * Returns a range from this value up to but excluding the specified [to] value. - * The [to] value must be greater than [Short.MIN_VALUE]. */ -public infix fun Short.until(to: Short): ShortRange { - val to_ = (to - 1).toShort() - if (to_ > to) throw IllegalArgumentException("The to argument value '$to' was too small.") - return this .. to_ +public infix fun Short.until(to: Short): IntRange { + return this.toInt() .. (to.toInt() - 1).toInt() } /** diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Ranges.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Ranges.kt index d9eb9c474c3..21e28a897fa 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Ranges.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Ranges.kt @@ -1,13 +1,19 @@ package templates import templates.Family.* +import templates.PrimitiveType.Companion.maxByCapacity fun ranges(): List { val templates = arrayListOf() + val rangePrimitives = listOf(PrimitiveType.Int, PrimitiveType.Long, PrimitiveType.Char) + fun rangeElementType(fromType: PrimitiveType, toType: PrimitiveType) + = maxByCapacity(fromType, toType).let { if (it == PrimitiveType.Char) it else maxByCapacity(it, PrimitiveType.Int) } + + templates add f("reversed()") { only(RangesOfPrimitives, ProgressionsOfPrimitives) - only(PrimitiveType.integralPrimitives) + only(rangePrimitives) 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") @@ -21,7 +27,7 @@ fun ranges(): List { templates add f("reversed()") { only(RangesOfPrimitives, ProgressionsOfPrimitives) - only(defaultPrimitives - PrimitiveType.Boolean - PrimitiveType.integralPrimitives) + only(defaultPrimitives - PrimitiveType.Boolean - rangePrimitives) 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") @@ -39,7 +45,7 @@ fun ranges(): List { infix(true) only(RangesOfPrimitives, ProgressionsOfPrimitives) - only(PrimitiveType.integralPrimitives) + only(rangePrimitives) 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") @@ -61,7 +67,7 @@ fun ranges(): List { infix(true) only(RangesOfPrimitives, ProgressionsOfPrimitives) - only(defaultPrimitives - PrimitiveType.Boolean - PrimitiveType.integralPrimitives) + only(defaultPrimitives - PrimitiveType.Boolean - rangePrimitives) 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") @@ -88,13 +94,14 @@ fun ranges(): List { } } + fun downTo(fromType: PrimitiveType, toType: PrimitiveType) = f("downTo(to: $toType)") { infix(true) sourceFile(SourceFile.Ranges) only(Primitives) only(fromType) - val elementType = PrimitiveType.maxByCapacity(fromType, toType) + val elementType = rangeElementType(fromType, toType) val progressionType = elementType.name + "Progression" returns(progressionType) @@ -134,7 +141,7 @@ fun ranges(): List { sourceFile(SourceFile.Ranges) only(Primitives) only(fromType) - val elementType = PrimitiveType.maxByCapacity(fromType, toType) + val elementType = rangeElementType(fromType, toType) val progressionType = elementType.name + "Range" returns(progressionType) @@ -182,8 +189,11 @@ fun ranges(): List { deprecate(Deprecation("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.WARNING)) annotations("""@Suppress("DEPRECATION_ERROR")""") } + else if (rangeType !in rangePrimitives) { + deprecate(Deprecation("This range will be removed soon.", level = DeprecationLevel.WARNING)) + } - check(rangeType.isNumeric() == itemType.isNumeric()) { "Require rangeType and itemType both be numeric or both not, got: $rangeType, $itemType" } + check(rangeType.isNumeric() == itemType.isNumeric()) { "Required rangeType and itemType both to be numeric or both not, got: $rangeType, $itemType" } only(Ranges) onlyPrimitives(Ranges, rangeType) platformName("${rangeType.name.decapitalize()}RangeContains")