diff --git a/core/builtins/src/kotlin/Progressions.kt b/core/builtins/src/kotlin/Progressions.kt index 05ed6bca3bd..da05ccaed58 100644 --- a/core/builtins/src/kotlin/Progressions.kt +++ b/core/builtins/src/kotlin/Progressions.kt @@ -22,174 +22,298 @@ package kotlin /** * A progression of values of type `Byte`. */ -public open class ByteProgression( - override val start: Byte, - val endInclusive: Byte, - override val increment: Int -) : Progression /*, Iterable */ { +public open class ByteProgression + @Deprecated("This constructor will become private soon. Use ByteProgression.fromClosedRange() instead.", ReplaceWith("ByteProgression.fromClosedRange(start, end, increment)")) + public constructor + ( + start: Byte, + endInclusive: Byte, + override val increment: Int + ) : Progression /*, Iterable */ { init { if (increment == 0) throw IllegalArgumentException("Increment must be non-zero") } + /** + * The first element in the progression. + */ + public val first: Byte = start + /** + * The last element in the progression. + */ + public val last: Byte = kotlin.internal.getProgressionFinalElement(start.toInt(), endInclusive.toInt(), increment).toByte() + + @Deprecated("Use first instead.", ReplaceWith("first")) + public override val start: Byte get() = first + /** * The end value of the progression (inclusive). */ - @Deprecated("Use endInclusive instead.", ReplaceWith("endInclusive")) - public override val end: Byte get() = endInclusive + @Deprecated("Use 'last' property instead.") + public override val end: Byte = endInclusive - override fun iterator(): ByteIterator = ByteProgressionIterator(start, endInclusive, increment) + override fun iterator(): ByteIterator = ByteProgressionIterator(first, last, increment) /** Checks if the progression is empty. */ - public open fun isEmpty(): Boolean = if (increment > 0) start > endInclusive else start < endInclusive + public open fun isEmpty(): Boolean = if (increment > 0) first > last else first < last override fun equals(other: Any?): Boolean = other is ByteProgression && (isEmpty() && other.isEmpty() || - start == other.start && endInclusive == other.endInclusive && increment == other.increment) + first == other.first && last == other.last && increment == other.increment) override fun hashCode(): Int = - if (isEmpty()) -1 else (31 * (31 * start.toInt() + endInclusive.toInt()) + increment) + if (isEmpty()) -1 else (31 * (31 * first.toInt() + last.toInt()) + increment) - override fun toString(): String = if (increment > 0) "$start..$endInclusive step $increment" else "$start downTo $endInclusive step ${-increment}" + override fun toString(): String = if (increment > 0) "$first..$last step $increment" else "$first downTo $last step ${-increment}" + + companion object { + /** + * Creates ByteProgression within the specified bounds of a closed range. + + * The progression starts with the [rangeStart] value and goes toward the [rangeEnd] value not excluding it, with the specified [step]. + * In order to go backwards the [step] must be negative. + */ + public fun fromClosedRange(rangeStart: Byte, rangeEnd: Byte, step: Int): ByteProgression = ByteProgression(rangeStart, rangeEnd, step) + } } /** * A progression of values of type `Char`. */ -public open class CharProgression( - override val start: Char, - val endInclusive: Char, - override val increment: Int -) : Progression /*, Iterable */ { +public open class CharProgression + @Deprecated("This constructor will become private soon. Use CharProgression.fromClosedRange() instead.", ReplaceWith("CharProgression.fromClosedRange(start, end, increment)")) + public constructor + ( + start: Char, + endInclusive: Char, + override val increment: Int + ) : Progression /*, Iterable */ { init { if (increment == 0) throw IllegalArgumentException("Increment must be non-zero") } + /** + * The first element in the progression. + */ + public val first: Char = start + /** + * The last element in the progression. + */ + public val last: Char = kotlin.internal.getProgressionFinalElement(start.toInt(), endInclusive.toInt(), increment).toChar() + + @Deprecated("Use first instead.", ReplaceWith("first")) + public override val start: Char get() = first + /** * The end value of the progression (inclusive). */ - @Deprecated("Use endInclusive instead.", ReplaceWith("endInclusive")) - public override val end: Char get() = endInclusive + @Deprecated("Use 'last' property instead.") + public override val end: Char = endInclusive - override fun iterator(): CharIterator = CharProgressionIterator(start, endInclusive, increment) + override fun iterator(): CharIterator = CharProgressionIterator(first, last, increment) /** Checks if the progression is empty. */ - public open fun isEmpty(): Boolean = if (increment > 0) start > endInclusive else start < endInclusive + public open fun isEmpty(): Boolean = if (increment > 0) first > last else first < last override fun equals(other: Any?): Boolean = other is CharProgression && (isEmpty() && other.isEmpty() || - start == other.start && endInclusive == other.endInclusive && increment == other.increment) + first == other.first && last == other.last && increment == other.increment) override fun hashCode(): Int = - if (isEmpty()) -1 else (31 * (31 * start.toInt() + endInclusive.toInt()) + increment) + if (isEmpty()) -1 else (31 * (31 * first.toInt() + last.toInt()) + increment) - override fun toString(): String = if (increment > 0) "$start..$endInclusive step $increment" else "$start downTo $endInclusive step ${-increment}" + override fun toString(): String = if (increment > 0) "$first..$last step $increment" else "$first downTo $last step ${-increment}" + + companion object { + /** + * Creates CharProgression within the specified bounds of a closed range. + + * The progression starts with the [rangeStart] value and goes toward the [rangeEnd] value not excluding it, with the specified [step]. + * In order to go backwards the [step] must be negative. + */ + public fun fromClosedRange(rangeStart: Char, rangeEnd: Char, step: Int): CharProgression = CharProgression(rangeStart, rangeEnd, step) + } } @Deprecated("Use IntProgression instead.", ReplaceWith("IntProgression"), level = DeprecationLevel.WARNING) /** * A progression of values of type `Short`. */ -public open class ShortProgression( - override val start: Short, - val endInclusive: Short, - override val increment: Int -) : Progression /*, Iterable */ { +public open class ShortProgression + @Deprecated("This constructor will become private soon. Use ShortProgression.fromClosedRange() instead.", ReplaceWith("ShortProgression.fromClosedRange(start, end, increment)")) + public constructor + ( + start: Short, + endInclusive: Short, + override val increment: Int + ) : Progression /*, Iterable */ { init { if (increment == 0) throw IllegalArgumentException("Increment must be non-zero") } + /** + * The first element in the progression. + */ + public val first: Short = start + /** + * The last element in the progression. + */ + public val last: Short = kotlin.internal.getProgressionFinalElement(start.toInt(), endInclusive.toInt(), increment).toShort() + + @Deprecated("Use first instead.", ReplaceWith("first")) + public override val start: Short get() = first + /** * The end value of the progression (inclusive). */ - @Deprecated("Use endInclusive instead.", ReplaceWith("endInclusive")) - public override val end: Short get() = endInclusive + @Deprecated("Use 'last' property instead.") + public override val end: Short = endInclusive - override fun iterator(): ShortIterator = ShortProgressionIterator(start, endInclusive, increment) + override fun iterator(): ShortIterator = ShortProgressionIterator(first, last, increment) /** Checks if the progression is empty. */ - public open fun isEmpty(): Boolean = if (increment > 0) start > endInclusive else start < endInclusive + public open fun isEmpty(): Boolean = if (increment > 0) first > last else first < last override fun equals(other: Any?): Boolean = other is ShortProgression && (isEmpty() && other.isEmpty() || - start == other.start && endInclusive == other.endInclusive && increment == other.increment) + first == other.first && last == other.last && increment == other.increment) override fun hashCode(): Int = - if (isEmpty()) -1 else (31 * (31 * start.toInt() + endInclusive.toInt()) + increment) + if (isEmpty()) -1 else (31 * (31 * first.toInt() + last.toInt()) + increment) - override fun toString(): String = if (increment > 0) "$start..$endInclusive step $increment" else "$start downTo $endInclusive step ${-increment}" + override fun toString(): String = if (increment > 0) "$first..$last step $increment" else "$first downTo $last step ${-increment}" + + companion object { + /** + * Creates ShortProgression within the specified bounds of a closed range. + + * The progression starts with the [rangeStart] value and goes toward the [rangeEnd] value not excluding it, with the specified [step]. + * In order to go backwards the [step] must be negative. + */ + public fun fromClosedRange(rangeStart: Short, rangeEnd: Short, step: Int): ShortProgression = ShortProgression(rangeStart, rangeEnd, step) + } } /** * A progression of values of type `Int`. */ -public open class IntProgression( - override val start: Int, - val endInclusive: Int, - override val increment: Int -) : Progression /*, Iterable */ { +public open class IntProgression + @Deprecated("This constructor will become private soon. Use IntProgression.fromClosedRange() instead.", ReplaceWith("IntProgression.fromClosedRange(start, end, increment)")) + public constructor + ( + start: Int, + endInclusive: Int, + override val increment: Int + ) : Progression /*, Iterable */ { init { if (increment == 0) throw IllegalArgumentException("Increment must be non-zero") } + /** + * The first element in the progression. + */ + public val first: Int = start + /** + * The last element in the progression. + */ + public val last: Int = kotlin.internal.getProgressionFinalElement(start.toInt(), endInclusive.toInt(), increment).toInt() + + @Deprecated("Use first instead.", ReplaceWith("first")) + public override val start: Int get() = first + /** * The end value of the progression (inclusive). */ - @Deprecated("Use endInclusive instead.", ReplaceWith("endInclusive")) - public override val end: Int get() = endInclusive + @Deprecated("Use 'last' property instead.") + public override val end: Int = endInclusive - override fun iterator(): IntIterator = IntProgressionIterator(start, endInclusive, increment) + override fun iterator(): IntIterator = IntProgressionIterator(first, last, increment) /** Checks if the progression is empty. */ - public open fun isEmpty(): Boolean = if (increment > 0) start > endInclusive else start < endInclusive + public open fun isEmpty(): Boolean = if (increment > 0) first > last else first < last override fun equals(other: Any?): Boolean = other is IntProgression && (isEmpty() && other.isEmpty() || - start == other.start && endInclusive == other.endInclusive && increment == other.increment) + first == other.first && last == other.last && increment == other.increment) override fun hashCode(): Int = - if (isEmpty()) -1 else (31 * (31 * start + endInclusive) + increment) + if (isEmpty()) -1 else (31 * (31 * first + last) + increment) - override fun toString(): String = if (increment > 0) "$start..$endInclusive step $increment" else "$start downTo $endInclusive step ${-increment}" + override fun toString(): String = if (increment > 0) "$first..$last step $increment" else "$first downTo $last step ${-increment}" + + companion object { + /** + * Creates IntProgression within the specified bounds of a closed range. + + * The progression starts with the [rangeStart] value and goes toward the [rangeEnd] value not excluding it, with the specified [step]. + * In order to go backwards the [step] must be negative. + */ + public fun fromClosedRange(rangeStart: Int, rangeEnd: Int, step: Int): IntProgression = IntProgression(rangeStart, rangeEnd, step) + } } /** * A progression of values of type `Long`. */ -public open class LongProgression( - override val start: Long, - val endInclusive: Long, - override val increment: Long -) : Progression /*, Iterable */ { +public open class LongProgression + @Deprecated("This constructor will become private soon. Use LongProgression.fromClosedRange() instead.", ReplaceWith("LongProgression.fromClosedRange(start, end, increment)")) + public constructor + ( + start: Long, + endInclusive: Long, + override val increment: Long + ) : Progression /*, Iterable */ { init { if (increment == 0L) throw IllegalArgumentException("Increment must be non-zero") } + /** + * The first element in the progression. + */ + public val first: Long = start + /** + * The last element in the progression. + */ + public val last: Long = kotlin.internal.getProgressionFinalElement(start.toLong(), endInclusive.toLong(), increment).toLong() + + @Deprecated("Use first instead.", ReplaceWith("first")) + public override val start: Long get() = first + /** * The end value of the progression (inclusive). */ - @Deprecated("Use endInclusive instead.", ReplaceWith("endInclusive")) - public override val end: Long get() = endInclusive + @Deprecated("Use 'last' property instead.") + public override val end: Long = endInclusive - override fun iterator(): LongIterator = LongProgressionIterator(start, endInclusive, increment) + override fun iterator(): LongIterator = LongProgressionIterator(first, last, increment) /** Checks if the progression is empty. */ - public open fun isEmpty(): Boolean = if (increment > 0) start > endInclusive else start < endInclusive + public open fun isEmpty(): Boolean = if (increment > 0) first > last else first < last override fun equals(other: Any?): Boolean = other is LongProgression && (isEmpty() && other.isEmpty() || - start == other.start && endInclusive == other.endInclusive && increment == other.increment) + first == other.first && last == other.last && increment == other.increment) override fun hashCode(): Int = - if (isEmpty()) -1 else (31 * (31 * (start xor (start ushr 32)) + (endInclusive xor (endInclusive ushr 32))) + (increment xor (increment ushr 32))).toInt() + if (isEmpty()) -1 else (31 * (31 * (first xor (first ushr 32)) + (last xor (last ushr 32))) + (increment xor (increment ushr 32))).toInt() - override fun toString(): String = if (increment > 0) "$start..$endInclusive step $increment" else "$start downTo $endInclusive step ${-increment}" + override fun toString(): String = if (increment > 0) "$first..$last step $increment" else "$first downTo $last step ${-increment}" + + companion object { + /** + * Creates LongProgression within the specified bounds of a closed range. + + * The progression starts with the [rangeStart] value and goes toward the [rangeEnd] value not excluding it, with the specified [step]. + * In order to go backwards the [step] must be negative. + */ + public fun fromClosedRange(rangeStart: Long, rangeEnd: Long, step: Long): LongProgression = LongProgression(rangeStart, rangeEnd, step) + } } -@Deprecated("This progression implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.WARNING) -@Suppress("DEPRECATION_ERROR") /** * A progression of values of type `Float`. */ +@Deprecated("This progression implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.WARNING) public open class FloatProgression( override val start: Float, val endInclusive: Float, @@ -221,11 +345,10 @@ public open class FloatProgression( override fun toString(): String = if (increment > 0) "$start..$endInclusive step $increment" else "$start downTo $endInclusive step ${-increment}" } -@Deprecated("This progression implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.WARNING) -@Suppress("DEPRECATION_ERROR") /** * A progression of values of type `Double`. */ +@Deprecated("This progression implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.WARNING) public open class DoubleProgression( override val start: Double, val endInclusive: Double, diff --git a/core/builtins/src/kotlin/Ranges.kt b/core/builtins/src/kotlin/Ranges.kt index d9db265cfdc..5cd0e37e169 100644 --- a/core/builtins/src/kotlin/Ranges.kt +++ b/core/builtins/src/kotlin/Ranges.kt @@ -26,6 +26,9 @@ public class ByteRange(start: Byte, endInclusive: Byte) : ByteProgression(start, @Deprecated("Use endInclusive instead.", ReplaceWith("endInclusive")) override val end: Byte get() = endInclusive + override val start: Byte get() = first + override val endInclusive: Byte get() = last + override fun contains(item: Byte): Boolean = start <= item && item <= endInclusive override fun isEmpty(): Boolean = start > endInclusive @@ -52,6 +55,9 @@ public class CharRange(start: Char, endInclusive: Char) : CharProgression(start, @Deprecated("Use endInclusive instead.", ReplaceWith("endInclusive")) override val end: Char get() = endInclusive + override val start: Char get() = first + override val endInclusive: Char get() = last + override fun contains(item: Char): Boolean = start <= item && item <= endInclusive override fun isEmpty(): Boolean = start > endInclusive @@ -79,6 +85,9 @@ public class ShortRange(start: Short, endInclusive: Short) : ShortProgression(st @Deprecated("Use endInclusive instead.", ReplaceWith("endInclusive")) override val end: Short get() = endInclusive + override val start: Short get() = first + override val endInclusive: Short get() = last + override fun contains(item: Short): Boolean = start <= item && item <= endInclusive override fun isEmpty(): Boolean = start > endInclusive @@ -105,6 +114,9 @@ public class IntRange(start: Int, endInclusive: Int) : IntProgression(start, end @Deprecated("Use endInclusive instead.", ReplaceWith("endInclusive")) override val end: Int get() = endInclusive + override val start: Int get() = first + override val endInclusive: Int get() = last + override fun contains(item: Int): Boolean = start <= item && item <= endInclusive override fun isEmpty(): Boolean = start > endInclusive @@ -131,6 +143,9 @@ public class LongRange(start: Long, endInclusive: Long) : LongProgression(start, @Deprecated("Use endInclusive instead.", ReplaceWith("endInclusive")) override val end: Long get() = endInclusive + override val start: Long get() = first + override val endInclusive: Long get() = last + override fun contains(item: Long): Boolean = start <= item && item <= endInclusive override fun isEmpty(): Boolean = start > endInclusive diff --git a/generators/src/org/jetbrains/kotlin/generators/builtins/progressions.kt b/generators/src/org/jetbrains/kotlin/generators/builtins/progressions.kt index b39922af2d8..df9e930e6e8 100644 --- a/generators/src/org/jetbrains/kotlin/generators/builtins/progressions.kt +++ b/generators/src/org/jetbrains/kotlin/generators/builtins/progressions.kt @@ -22,61 +22,133 @@ import org.jetbrains.kotlin.generators.builtins.ProgressionKind.* import java.io.PrintWriter class GenerateProgressions(out: PrintWriter) : BuiltInsSourceGenerator(out) { - override fun generateBody() { - for (kind in ProgressionKind.values()) { - val t = kind.capitalized - val progression = "${t}Progression" - val incrementType = progressionIncrementType(kind) + private fun generateDiscreteBody(kind: ProgressionKind) { + require(kind != FLOAT && kind != DOUBLE) - fun compare(v: String) = areEqualNumbers(kind, v) + val t = kind.capitalized + val progression = "${t}Progression" - val zero = when (kind) { - FLOAT -> "0.0f" - DOUBLE -> "0.0" - LONG -> "0L" - else -> "0" - } - val checkNaN = - if (kind == FLOAT || kind == DOUBLE) - "if (java.lang.$t.isNaN(increment)) throw IllegalArgumentException(\"Increment must be not NaN\")\n " - else "" - val checkZero = "if (increment == $zero) throw IllegalArgumentException(\"Increment must be non-zero\")" - val constructor = checkNaN + checkZero + val incrementType = progressionIncrementType(kind) + fun compare(v: String) = areEqualNumbers(kind, v) - val hashCode = when (kind) { - BYTE, CHAR, SHORT -> "=\n" + - " if (isEmpty()) -1 else (31 * (31 * start.toInt() + endInclusive.toInt()) + increment)" - INT -> "=\n" + - " if (isEmpty()) -1 else (31 * (31 * start + endInclusive) + increment)" - LONG -> "=\n" + - " if (isEmpty()) -1 else (31 * (31 * ${hashLong("start")} + ${hashLong("endInclusive")}) + ${hashLong("increment")}).toInt()" - FLOAT -> "=\n" + - " if (isEmpty()) -1 else (31 * (31 * ${floatToIntBits("start")} + ${floatToIntBits("endInclusive")}) + ${floatToIntBits("increment")})" - DOUBLE -> "{\n" + - " if (isEmpty()) return -1\n" + - " var temp = ${doubleToLongBits("start")}\n" + - " var result = ${hashLong("temp")}\n" + - " temp = ${doubleToLongBits("endInclusive")}\n" + - " result = 31 * result + ${hashLong("temp")}\n" + - " temp = ${doubleToLongBits("increment")}\n" + - " return (31 * result + ${hashLong("temp")}).toInt()\n" + - " }" - } + val zero = when (kind) { + LONG -> "0L" + else -> "0" + } + val checkZero = "if (increment == $zero) throw IllegalArgumentException(\"Increment must be non-zero\")" - if (kind == FLOAT || kind == DOUBLE) { - out.println("""@Deprecated("This progression implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.WARNING)""") - out.println("""@Suppress("DEPRECATION_ERROR")""") - } + val hashCode = "=\n" + when (kind) { + BYTE, CHAR, SHORT -> + " if (isEmpty()) -1 else (31 * (31 * first.toInt() + last.toInt()) + increment)" + INT -> + " if (isEmpty()) -1 else (31 * (31 * first + last) + increment)" + LONG -> + " if (isEmpty()) -1 else (31 * (31 * ${hashLong("first")} + ${hashLong("last")}) + ${hashLong("increment")}).toInt()" + else -> throw IllegalArgumentException() + } - if (kind == SHORT || kind == BYTE) { - out.println("""@Deprecated("Use IntProgression instead.", ReplaceWith("IntProgression"), level = DeprecationLevel.WARNING)""") - } - - out.println( -"""/** + if (kind == SHORT || kind == BYTE) { + out.println("""@Deprecated("Use IntProgression instead.", ReplaceWith("IntProgression"), level = DeprecationLevel.WARNING)""") + } + out.println( + """/** * A progression of values of type `$t`. */ +public open class $progression + @Deprecated("This constructor will become private soon. Use $progression.fromClosedRange() instead.", ReplaceWith("$progression.fromClosedRange(start, end, increment)")) + public constructor + ( + start: $t, + endInclusive: $t, + override val increment: $incrementType + ) : Progression<$t> /*, Iterable<$t> */ { + init { + $checkZero + } + + /** + * The first element in the progression. + */ + public val first: $t = start + /** + * The last element in the progression. + */ + public val last: $t = kotlin.internal.getProgressionFinalElement(start.to$incrementType(), endInclusive.to$incrementType(), increment).to$t() + + @Deprecated("Use first instead.", ReplaceWith("first")) + public override val start: $t get() = first + + /** + * The end value of the progression (inclusive). + */ + @Deprecated("Use 'last' property instead.") + public override val end: $t = endInclusive + + override fun iterator(): ${t}Iterator = ${t}ProgressionIterator(first, last, increment) + + /** Checks if the progression is empty. */ + public open fun isEmpty(): Boolean = if (increment > 0) first > last else first < last + + override fun equals(other: Any?): Boolean = + other is $progression && (isEmpty() && other.isEmpty() || + ${compare("first")} && ${compare("last")} && ${compare("increment")}) + + override fun hashCode(): Int $hashCode + + override fun toString(): String = ${"if (increment > 0) \"\$first..\$last step \$increment\" else \"\$first downTo \$last step \${-increment}\""} + + companion object { + /** + * Creates $progression within the specified bounds of a closed range. + + * The progression starts with the [rangeStart] value and goes toward the [rangeEnd] value not excluding it, with the specified [step]. + * In order to go backwards the [step] must be negative. + */ + public fun fromClosedRange(rangeStart: $t, rangeEnd: $t, step: $incrementType): $progression = $progression(rangeStart, rangeEnd, step) + } +}""") + out.println() + + } + + private fun generateFloatingPointBody(kind: ProgressionKind) { + require(kind == FLOAT || kind == DOUBLE) + + val t = kind.capitalized + val progression = "${t}Progression" + + val incrementType = progressionIncrementType(kind) + + fun compare(v: String) = areEqualNumbers(kind, v) + + val zero = when (kind) { + FLOAT -> "0.0f" + else -> "0.0" + } + val constructor = "if (java.lang.$t.isNaN(increment)) throw IllegalArgumentException(\"Increment must be not NaN\")\n" + + " if (increment == $zero) throw IllegalArgumentException(\"Increment must be non-zero\")" + + val hashCode = when (kind) { + FLOAT -> "=\n" + + " if (isEmpty()) -1 else (31 * (31 * ${floatToIntBits("start")} + ${floatToIntBits("endInclusive")}) + ${floatToIntBits("increment")})" + else -> "{\n" + + " if (isEmpty()) return -1\n" + + " var temp = ${doubleToLongBits("start")}\n" + + " var result = ${hashLong("temp")}\n" + + " temp = ${doubleToLongBits("endInclusive")}\n" + + " result = 31 * result + ${hashLong("temp")}\n" + + " temp = ${doubleToLongBits("increment")}\n" + + " return (31 * result + ${hashLong("temp")}).toInt()\n" + + " }" + } + + + out.println( + """/** + * A progression of values of type `$t`. + */ +@Deprecated("This progression implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.WARNING) public open class $progression( override val start: $t, val endInclusive: $t, @@ -105,7 +177,16 @@ public open class $progression( override fun toString(): String = ${"if (increment > 0) \"\$start..\$endInclusive step \$increment\" else \"\$start downTo \$endInclusive step \${-increment}\""} }""") - out.println() + out.println() + + } + + override fun generateBody() { + for (kind in ProgressionKind.values) { + if (kind == FLOAT || kind == DOUBLE) + generateFloatingPointBody(kind) + else + generateDiscreteBody(kind) } } } diff --git a/generators/src/org/jetbrains/kotlin/generators/builtins/ranges.kt b/generators/src/org/jetbrains/kotlin/generators/builtins/ranges.kt index d56151c9def..a307f468d73 100644 --- a/generators/src/org/jetbrains/kotlin/generators/builtins/ranges.kt +++ b/generators/src/org/jetbrains/kotlin/generators/builtins/ranges.kt @@ -79,7 +79,11 @@ class GenerateRanges(out: PrintWriter) : BuiltInsSourceGenerator(out) { public class $range(start: $t, endInclusive: $t) : ${t}Progression(start, endInclusive, $increment), ClosedRange<$t> { @Deprecated("Use endInclusive instead.", ReplaceWith("endInclusive")) override val end: $t get() = endInclusive - +""" + (if (kind != FLOAT && kind != DOUBLE) """ + override val start: $t get() = first + override val endInclusive: $t get() = last +""" else "") + +""" override fun contains(item: $t): Boolean = start <= item && item <= endInclusive override fun isEmpty(): Boolean = start > endInclusive diff --git a/libraries/stdlib/src/generated/_Ranges.kt b/libraries/stdlib/src/generated/_Ranges.kt index 4ddf2f7ef9b..b6d1dfbd1e8 100644 --- a/libraries/stdlib/src/generated/_Ranges.kt +++ b/libraries/stdlib/src/generated/_Ranges.kt @@ -287,7 +287,7 @@ public operator fun Range.contains(item: Short): Boolean { * The [to] value has to be less than this value. */ public infix fun Int.downTo(to: Byte): IntProgression { - return IntProgression(this, to.toInt(), -1) + return IntProgression.fromClosedRange(this, to.toInt(), -1) } /** @@ -295,7 +295,7 @@ public infix fun Int.downTo(to: Byte): IntProgression { * The [to] value has to be less than this value. */ public infix fun Long.downTo(to: Byte): LongProgression { - return LongProgression(this, to.toLong(), -1L) + return LongProgression.fromClosedRange(this, to.toLong(), -1L) } /** @@ -303,7 +303,7 @@ public infix fun Long.downTo(to: Byte): LongProgression { * The [to] value has to be less than this value. */ public infix fun Byte.downTo(to: Byte): IntProgression { - return IntProgression(this.toInt(), to.toInt(), -1) + return IntProgression.fromClosedRange(this.toInt(), to.toInt(), -1) } /** @@ -311,7 +311,7 @@ public infix fun Byte.downTo(to: Byte): IntProgression { * The [to] value has to be less than this value. */ public infix fun Short.downTo(to: Byte): IntProgression { - return IntProgression(this.toInt(), to.toInt(), -1) + return IntProgression.fromClosedRange(this.toInt(), to.toInt(), -1) } /** @@ -321,7 +321,7 @@ public infix fun Short.downTo(to: Byte): IntProgression { @Deprecated("This range implementation has unclear semantics and will be removed soon.") @Suppress("DEPRECATION_ERROR") public infix fun Double.downTo(to: Byte): DoubleProgression { - return DoubleProgression(this, to.toDouble(), -1.0) + return DoubleProgression.fromClosedRange(this, to.toDouble(), -1.0) } /** @@ -331,7 +331,7 @@ public infix fun Double.downTo(to: Byte): DoubleProgression { @Deprecated("This range implementation has unclear semantics and will be removed soon.") @Suppress("DEPRECATION_ERROR") public infix fun Float.downTo(to: Byte): FloatProgression { - return FloatProgression(this, to.toFloat(), -1.0F) + return FloatProgression.fromClosedRange(this, to.toFloat(), -1.0F) } /** @@ -339,7 +339,7 @@ public infix fun Float.downTo(to: Byte): FloatProgression { * The [to] value has to be less than this value. */ public infix fun Char.downTo(to: Char): CharProgression { - return CharProgression(this, to, -1) + return CharProgression.fromClosedRange(this, to, -1) } /** @@ -349,7 +349,7 @@ public infix fun Char.downTo(to: Char): CharProgression { @Deprecated("This range implementation has unclear semantics and will be removed soon.") @Suppress("DEPRECATION_ERROR") public infix fun Int.downTo(to: Double): DoubleProgression { - return DoubleProgression(this.toDouble(), to, -1.0) + return DoubleProgression.fromClosedRange(this.toDouble(), to, -1.0) } /** @@ -359,7 +359,7 @@ public infix fun Int.downTo(to: Double): DoubleProgression { @Deprecated("This range implementation has unclear semantics and will be removed soon.") @Suppress("DEPRECATION_ERROR") public infix fun Long.downTo(to: Double): DoubleProgression { - return DoubleProgression(this.toDouble(), to, -1.0) + return DoubleProgression.fromClosedRange(this.toDouble(), to, -1.0) } /** @@ -369,7 +369,7 @@ public infix fun Long.downTo(to: Double): DoubleProgression { @Deprecated("This range implementation has unclear semantics and will be removed soon.") @Suppress("DEPRECATION_ERROR") public infix fun Byte.downTo(to: Double): DoubleProgression { - return DoubleProgression(this.toDouble(), to, -1.0) + return DoubleProgression.fromClosedRange(this.toDouble(), to, -1.0) } /** @@ -379,7 +379,7 @@ public infix fun Byte.downTo(to: Double): DoubleProgression { @Deprecated("This range implementation has unclear semantics and will be removed soon.") @Suppress("DEPRECATION_ERROR") public infix fun Short.downTo(to: Double): DoubleProgression { - return DoubleProgression(this.toDouble(), to, -1.0) + return DoubleProgression.fromClosedRange(this.toDouble(), to, -1.0) } /** @@ -389,7 +389,7 @@ public infix fun Short.downTo(to: Double): DoubleProgression { @Deprecated("This range implementation has unclear semantics and will be removed soon.") @Suppress("DEPRECATION_ERROR") public infix fun Double.downTo(to: Double): DoubleProgression { - return DoubleProgression(this, to, -1.0) + return DoubleProgression.fromClosedRange(this, to, -1.0) } /** @@ -399,7 +399,7 @@ public infix fun Double.downTo(to: Double): DoubleProgression { @Deprecated("This range implementation has unclear semantics and will be removed soon.") @Suppress("DEPRECATION_ERROR") public infix fun Float.downTo(to: Double): DoubleProgression { - return DoubleProgression(this.toDouble(), to, -1.0) + return DoubleProgression.fromClosedRange(this.toDouble(), to, -1.0) } /** @@ -409,7 +409,7 @@ public infix fun Float.downTo(to: Double): DoubleProgression { @Deprecated("This range implementation has unclear semantics and will be removed soon.") @Suppress("DEPRECATION_ERROR") public infix fun Int.downTo(to: Float): FloatProgression { - return FloatProgression(this.toFloat(), to, -1.0F) + return FloatProgression.fromClosedRange(this.toFloat(), to, -1.0F) } /** @@ -419,7 +419,7 @@ public infix fun Int.downTo(to: Float): FloatProgression { @Deprecated("This range implementation has unclear semantics and will be removed soon.") @Suppress("DEPRECATION_ERROR") public infix fun Long.downTo(to: Float): FloatProgression { - return FloatProgression(this.toFloat(), to, -1.0F) + return FloatProgression.fromClosedRange(this.toFloat(), to, -1.0F) } /** @@ -429,7 +429,7 @@ public infix fun Long.downTo(to: Float): FloatProgression { @Deprecated("This range implementation has unclear semantics and will be removed soon.") @Suppress("DEPRECATION_ERROR") public infix fun Byte.downTo(to: Float): FloatProgression { - return FloatProgression(this.toFloat(), to, -1.0F) + return FloatProgression.fromClosedRange(this.toFloat(), to, -1.0F) } /** @@ -439,7 +439,7 @@ public infix fun Byte.downTo(to: Float): FloatProgression { @Deprecated("This range implementation has unclear semantics and will be removed soon.") @Suppress("DEPRECATION_ERROR") public infix fun Short.downTo(to: Float): FloatProgression { - return FloatProgression(this.toFloat(), to, -1.0F) + return FloatProgression.fromClosedRange(this.toFloat(), to, -1.0F) } /** @@ -449,7 +449,7 @@ public infix fun Short.downTo(to: Float): FloatProgression { @Deprecated("This range implementation has unclear semantics and will be removed soon.") @Suppress("DEPRECATION_ERROR") public infix fun Double.downTo(to: Float): DoubleProgression { - return DoubleProgression(this, to.toDouble(), -1.0) + return DoubleProgression.fromClosedRange(this, to.toDouble(), -1.0) } /** @@ -459,7 +459,7 @@ public infix fun Double.downTo(to: Float): DoubleProgression { @Deprecated("This range implementation has unclear semantics and will be removed soon.") @Suppress("DEPRECATION_ERROR") public infix fun Float.downTo(to: Float): FloatProgression { - return FloatProgression(this, to, -1.0F) + return FloatProgression.fromClosedRange(this, to, -1.0F) } /** @@ -467,7 +467,7 @@ public infix fun Float.downTo(to: Float): FloatProgression { * The [to] value has to be less than this value. */ public infix fun Int.downTo(to: Int): IntProgression { - return IntProgression(this, to, -1) + return IntProgression.fromClosedRange(this, to, -1) } /** @@ -475,7 +475,7 @@ public infix fun Int.downTo(to: Int): IntProgression { * The [to] value has to be less than this value. */ public infix fun Long.downTo(to: Int): LongProgression { - return LongProgression(this, to.toLong(), -1L) + return LongProgression.fromClosedRange(this, to.toLong(), -1L) } /** @@ -483,7 +483,7 @@ public infix fun Long.downTo(to: Int): LongProgression { * The [to] value has to be less than this value. */ public infix fun Byte.downTo(to: Int): IntProgression { - return IntProgression(this.toInt(), to, -1) + return IntProgression.fromClosedRange(this.toInt(), to, -1) } /** @@ -491,7 +491,7 @@ public infix fun Byte.downTo(to: Int): IntProgression { * The [to] value has to be less than this value. */ public infix fun Short.downTo(to: Int): IntProgression { - return IntProgression(this.toInt(), to, -1) + return IntProgression.fromClosedRange(this.toInt(), to, -1) } /** @@ -501,7 +501,7 @@ public infix fun Short.downTo(to: Int): IntProgression { @Deprecated("This range implementation has unclear semantics and will be removed soon.") @Suppress("DEPRECATION_ERROR") public infix fun Double.downTo(to: Int): DoubleProgression { - return DoubleProgression(this, to.toDouble(), -1.0) + return DoubleProgression.fromClosedRange(this, to.toDouble(), -1.0) } /** @@ -511,7 +511,7 @@ public infix fun Double.downTo(to: Int): DoubleProgression { @Deprecated("This range implementation has unclear semantics and will be removed soon.") @Suppress("DEPRECATION_ERROR") public infix fun Float.downTo(to: Int): FloatProgression { - return FloatProgression(this, to.toFloat(), -1.0F) + return FloatProgression.fromClosedRange(this, to.toFloat(), -1.0F) } /** @@ -519,7 +519,7 @@ public infix fun Float.downTo(to: Int): FloatProgression { * The [to] value has to be less than this value. */ public infix fun Int.downTo(to: Long): LongProgression { - return LongProgression(this.toLong(), to, -1L) + return LongProgression.fromClosedRange(this.toLong(), to, -1L) } /** @@ -527,7 +527,7 @@ public infix fun Int.downTo(to: Long): LongProgression { * The [to] value has to be less than this value. */ public infix fun Long.downTo(to: Long): LongProgression { - return LongProgression(this, to, -1L) + return LongProgression.fromClosedRange(this, to, -1L) } /** @@ -535,7 +535,7 @@ public infix fun Long.downTo(to: Long): LongProgression { * The [to] value has to be less than this value. */ public infix fun Byte.downTo(to: Long): LongProgression { - return LongProgression(this.toLong(), to, -1L) + return LongProgression.fromClosedRange(this.toLong(), to, -1L) } /** @@ -543,7 +543,7 @@ public infix fun Byte.downTo(to: Long): LongProgression { * The [to] value has to be less than this value. */ public infix fun Short.downTo(to: Long): LongProgression { - return LongProgression(this.toLong(), to, -1L) + return LongProgression.fromClosedRange(this.toLong(), to, -1L) } /** @@ -553,7 +553,7 @@ public infix fun Short.downTo(to: Long): LongProgression { @Deprecated("This range implementation has unclear semantics and will be removed soon.") @Suppress("DEPRECATION_ERROR") public infix fun Double.downTo(to: Long): DoubleProgression { - return DoubleProgression(this, to.toDouble(), -1.0) + return DoubleProgression.fromClosedRange(this, to.toDouble(), -1.0) } /** @@ -563,7 +563,7 @@ public infix fun Double.downTo(to: Long): DoubleProgression { @Deprecated("This range implementation has unclear semantics and will be removed soon.") @Suppress("DEPRECATION_ERROR") public infix fun Float.downTo(to: Long): FloatProgression { - return FloatProgression(this, to.toFloat(), -1.0F) + return FloatProgression.fromClosedRange(this, to.toFloat(), -1.0F) } /** @@ -571,7 +571,7 @@ public infix fun Float.downTo(to: Long): FloatProgression { * The [to] value has to be less than this value. */ public infix fun Int.downTo(to: Short): IntProgression { - return IntProgression(this, to.toInt(), -1) + return IntProgression.fromClosedRange(this, to.toInt(), -1) } /** @@ -579,7 +579,7 @@ public infix fun Int.downTo(to: Short): IntProgression { * The [to] value has to be less than this value. */ public infix fun Long.downTo(to: Short): LongProgression { - return LongProgression(this, to.toLong(), -1L) + return LongProgression.fromClosedRange(this, to.toLong(), -1L) } /** @@ -587,7 +587,7 @@ public infix fun Long.downTo(to: Short): LongProgression { * The [to] value has to be less than this value. */ public infix fun Byte.downTo(to: Short): IntProgression { - return IntProgression(this.toInt(), to.toInt(), -1) + return IntProgression.fromClosedRange(this.toInt(), to.toInt(), -1) } /** @@ -595,7 +595,7 @@ public infix fun Byte.downTo(to: Short): IntProgression { * The [to] value has to be less than this value. */ public infix fun Short.downTo(to: Short): IntProgression { - return IntProgression(this.toInt(), to.toInt(), -1) + return IntProgression.fromClosedRange(this.toInt(), to.toInt(), -1) } /** @@ -605,7 +605,7 @@ public infix fun Short.downTo(to: Short): IntProgression { @Deprecated("This range implementation has unclear semantics and will be removed soon.") @Suppress("DEPRECATION_ERROR") public infix fun Double.downTo(to: Short): DoubleProgression { - return DoubleProgression(this, to.toDouble(), -1.0) + return DoubleProgression.fromClosedRange(this, to.toDouble(), -1.0) } /** @@ -615,49 +615,49 @@ public infix fun Double.downTo(to: Short): DoubleProgression { @Deprecated("This range implementation has unclear semantics and will be removed soon.") @Suppress("DEPRECATION_ERROR") public infix fun Float.downTo(to: Short): FloatProgression { - return FloatProgression(this, to.toFloat(), -1.0F) + return FloatProgression.fromClosedRange(this, to.toFloat(), -1.0F) } /** * Returns a progression that goes over the same range in the opposite direction with the same step. */ public fun CharProgression.reversed(): CharProgression { - return CharProgression(end, start, -increment) + return CharProgression.fromClosedRange(last, first, -increment) } /** * Returns a progression that goes over the same range in the opposite direction with the same step. */ public fun IntProgression.reversed(): IntProgression { - return IntProgression(end, start, -increment) + return IntProgression.fromClosedRange(last, first, -increment) } /** * Returns a progression that goes over the same range in the opposite direction with the same step. */ public fun LongProgression.reversed(): LongProgression { - return LongProgression(end, start, -increment) + return LongProgression.fromClosedRange(last, first, -increment) } /** * Returns a progression that goes over this range in reverse direction. */ public fun CharRange.reversed(): CharProgression { - return CharProgression(end, start, -1) + return CharProgression.fromClosedRange(last, first, -1) } /** * Returns a progression that goes over this range in reverse direction. */ public fun IntRange.reversed(): IntProgression { - return IntProgression(end, start, -1) + return IntProgression.fromClosedRange(last, first, -1) } /** * Returns a progression that goes over this range in reverse direction. */ public fun LongRange.reversed(): LongProgression { - return LongProgression(end, start, -1L) + return LongProgression.fromClosedRange(last, first, -1L) } /** @@ -666,7 +666,7 @@ public fun LongRange.reversed(): LongProgression { @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) + return ByteProgression.fromClosedRange(last, first, -increment) } /** @@ -675,7 +675,7 @@ public fun ByteProgression.reversed(): ByteProgression { @Deprecated("This range implementation has unclear semantics and will be removed soon.") @Suppress("DEPRECATION_ERROR") public fun DoubleProgression.reversed(): DoubleProgression { - return DoubleProgression(end, start, -increment) + return DoubleProgression.fromClosedRange(last, first, -increment) } /** @@ -684,7 +684,7 @@ public fun DoubleProgression.reversed(): DoubleProgression { @Deprecated("This range implementation has unclear semantics and will be removed soon.") @Suppress("DEPRECATION_ERROR") public fun FloatProgression.reversed(): FloatProgression { - return FloatProgression(end, start, -increment) + return FloatProgression.fromClosedRange(last, first, -increment) } /** @@ -693,7 +693,7 @@ public fun FloatProgression.reversed(): FloatProgression { @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) + return ShortProgression.fromClosedRange(last, first, -increment) } /** @@ -702,7 +702,7 @@ public fun ShortProgression.reversed(): ShortProgression { @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) + return ByteProgression.fromClosedRange(last, first, -1) } /** @@ -711,7 +711,7 @@ public fun ByteRange.reversed(): ByteProgression { @Deprecated("This range implementation has unclear semantics and will be removed soon.") @Suppress("DEPRECATION_ERROR") public fun DoubleRange.reversed(): DoubleProgression { - return DoubleProgression(end, start, -1.0) + return DoubleProgression.fromClosedRange(last, first, -1.0) } /** @@ -720,7 +720,7 @@ public fun DoubleRange.reversed(): DoubleProgression { @Deprecated("This range implementation has unclear semantics and will be removed soon.") @Suppress("DEPRECATION_ERROR") public fun FloatRange.reversed(): FloatProgression { - return FloatProgression(end, start, -1.0f) + return FloatProgression.fromClosedRange(last, first, -1.0f) } /** @@ -729,7 +729,7 @@ public fun FloatRange.reversed(): FloatProgression { @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) + return ShortProgression.fromClosedRange(last, first, -1) } /** @@ -737,7 +737,7 @@ public fun ShortRange.reversed(): ShortProgression { */ public infix fun CharProgression.step(step: Int): CharProgression { checkStepIsPositive(step > 0, step) - return CharProgression(start, end, if (increment > 0) step else -step) + return CharProgression.fromClosedRange(first, last, if (increment > 0) step else -step) } /** @@ -745,7 +745,7 @@ public infix fun CharProgression.step(step: Int): CharProgression { */ public infix fun IntProgression.step(step: Int): IntProgression { checkStepIsPositive(step > 0, step) - return IntProgression(start, end, if (increment > 0) step else -step) + return IntProgression.fromClosedRange(first, last, if (increment > 0) step else -step) } /** @@ -753,7 +753,7 @@ public infix fun IntProgression.step(step: Int): IntProgression { */ public infix fun LongProgression.step(step: Long): LongProgression { checkStepIsPositive(step > 0, step) - return LongProgression(start, end, if (increment > 0) step else -step) + return LongProgression.fromClosedRange(first, last, if (increment > 0) step else -step) } /** @@ -761,7 +761,7 @@ public infix fun LongProgression.step(step: Long): LongProgression { */ public infix fun CharRange.step(step: Int): CharProgression { checkStepIsPositive(step > 0, step) - return CharProgression(start, end, step) + return CharProgression.fromClosedRange(first, last, step) } /** @@ -769,7 +769,7 @@ public infix fun CharRange.step(step: Int): CharProgression { */ public infix fun IntRange.step(step: Int): IntProgression { checkStepIsPositive(step > 0, step) - return IntProgression(start, end, step) + return IntProgression.fromClosedRange(first, last, step) } /** @@ -777,7 +777,7 @@ public infix fun IntRange.step(step: Int): IntProgression { */ public infix fun LongRange.step(step: Long): LongProgression { checkStepIsPositive(step > 0, step) - return LongProgression(start, end, step) + return LongProgression.fromClosedRange(first, last, step) } /** @@ -787,7 +787,7 @@ public infix fun LongRange.step(step: Long): LongProgression { @Suppress("DEPRECATION_ERROR") public infix fun ByteProgression.step(step: Int): ByteProgression { checkStepIsPositive(step > 0, step) - return ByteProgression(start, end, if (increment > 0) step else -step) + return ByteProgression.fromClosedRange(first, last, if (increment > 0) step else -step) } /** @@ -797,7 +797,7 @@ public infix fun ByteProgression.step(step: Int): ByteProgression { @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) + return DoubleProgression.fromClosedRange(first, last, if (increment > 0) step else -step) } /** @@ -807,7 +807,7 @@ public infix fun DoubleProgression.step(step: Double): DoubleProgression { @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) + return FloatProgression.fromClosedRange(first, last, if (increment > 0) step else -step) } /** @@ -817,7 +817,7 @@ public infix fun FloatProgression.step(step: Float): FloatProgression { @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) + return ShortProgression.fromClosedRange(first, last, if (increment > 0) step else -step) } /** @@ -827,7 +827,7 @@ public infix fun ShortProgression.step(step: Int): ShortProgression { @Suppress("DEPRECATION_ERROR") public infix fun ByteRange.step(step: Int): ByteProgression { checkStepIsPositive(step > 0, step) - return ByteProgression(start, end, step) + return ByteProgression.fromClosedRange(first, last, step) } /** @@ -838,7 +838,7 @@ public infix fun ByteRange.step(step: Int): ByteProgression { 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) + return DoubleProgression.fromClosedRange(start, end, step) } /** @@ -849,7 +849,7 @@ public infix fun DoubleRange.step(step: Double): DoubleProgression { 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) + return FloatProgression.fromClosedRange(start, end, step) } /** @@ -859,7 +859,7 @@ public infix fun FloatRange.step(step: Float): FloatProgression { @Suppress("DEPRECATION_ERROR") public infix fun ShortRange.step(step: Int): ShortProgression { checkStepIsPositive(step > 0, step) - return ShortProgression(start, end, step) + return ShortProgression.fromClosedRange(first, last, step) } /** diff --git a/libraries/stdlib/test/language/RangeIterationJVMTest.kt b/libraries/stdlib/test/language/RangeIterationJVMTest.kt index d4dc9702be9..b2640a5e1e6 100644 --- a/libraries/stdlib/test/language/RangeIterationJVMTest.kt +++ b/libraries/stdlib/test/language/RangeIterationJVMTest.kt @@ -17,17 +17,45 @@ import kotlin.test.* // Test data for codegen is generated from this class. If you change it, rerun GenerateTests public class RangeIterationJVMTest { private fun doTest( - sequence: Progression, - expectedStart: N, - expectedEnd: N, + sequence: Iterable, + expectedFirst: N, + expectedLast: N, expectedIncrement: Number, expectedElements: List - ) { - assertEquals(expectedStart, sequence.start) - assertEquals(expectedEnd, sequence.end) - assertEquals(expectedIncrement, sequence.increment) + ) { + val first: Any + val last: Any + val increment: Number + when (sequence) { + is IntProgression -> { + first = sequence.first + last = sequence.last + increment = sequence.increment + } + is LongProgression -> { + first = sequence.first + last = sequence.last + increment = sequence.increment + } + is CharProgression -> { + first = sequence.first + last = sequence.last + increment = sequence.increment + } + // TODO: Drop this branch + is Progression -> { + first = sequence.start + last = sequence.end + increment = sequence.increment + } + else -> throw IllegalArgumentException("Unsupported sequence type: $sequence") + } - if (expectedElements.none()) + assertEquals(expectedFirst, first) + assertEquals(expectedLast, last) + assertEquals(expectedIncrement, increment) + + if (expectedElements.isEmpty()) assertTrue(sequence.none()) else assertEquals(expectedElements, sequence.toList()) diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Ranges.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Ranges.kt index 21e28a897fa..80f34417b46 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Ranges.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Ranges.kt @@ -18,10 +18,10 @@ fun ranges(): List { doc(RangesOfPrimitives) { "Returns a progression that goes over this range in reverse direction." } returns("TProgression") body(RangesOfPrimitives) { - "return TProgression(end, start, -ONE)" + "return TProgression.fromClosedRange(last, first, -ONE)" } body(ProgressionsOfPrimitives) { - "return TProgression(end, start, -increment)" + "return TProgression.fromClosedRange(last, first, -increment)" } } @@ -34,10 +34,10 @@ fun ranges(): List { deprecate(Deprecation("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.WARNING)) annotations("""@Suppress("DEPRECATION_ERROR")""") body(RangesOfPrimitives) { - "return TProgression(end, start, -ONE)" + "return TProgression.fromClosedRange(last, first, -ONE)" } body(ProgressionsOfPrimitives) { - "return TProgression(end, start, -increment)" + "return TProgression.fromClosedRange(last, first, -increment)" } } @@ -52,13 +52,13 @@ fun ranges(): List { body(RangesOfPrimitives) { """ checkStepIsPositive(step > 0, step) - return TProgression(start, end, step) + return TProgression.fromClosedRange(first, last, step) """ } body(ProgressionsOfPrimitives) { """ checkStepIsPositive(step > 0, step) - return TProgression(start, end, if (increment > 0) step else -step) + return TProgression.fromClosedRange(first, last, if (increment > 0) step else -step) """ } } @@ -76,20 +76,20 @@ fun ranges(): List { body(RangesOfPrimitives) { """ checkStepIsPositive(step > 0, step) - return TProgression(start, end, step) + return TProgression.fromClosedRange(first, last, step) """ } bodyForTypes(RangesOfPrimitives, PrimitiveType.Float, PrimitiveType.Double) { """ if (step.isNaN()) throw IllegalArgumentException("Step must not be NaN.") checkStepIsPositive(step > 0, step) - return TProgression(start, end, step) + return TProgression.fromClosedRange(start, end, step) """ } body(ProgressionsOfPrimitives) { """ checkStepIsPositive(step > 0, step) - return TProgression(start, end, if (increment > 0) step else -step) + return TProgression.fromClosedRange(first, last, if (increment > 0) step else -step) """ } } @@ -126,7 +126,7 @@ fun ranges(): List { else -> "-1" } - body { "return $progressionType($fromExpr, $toExpr, $incrementExpr)" } + body { "return $progressionType.fromClosedRange($fromExpr, $toExpr, $incrementExpr)" } } val numericPrimitives = PrimitiveType.numericPrimitives