Return EMPTY range [0, -1] when MIN_VALUE is specified as exclusive upper bound.

#KT-12762 Fixed
This commit is contained in:
Ilya Gorbunov
2016-08-19 17:50:15 +03:00
parent ca8b284805
commit 9c4221cda8
4 changed files with 39 additions and 41 deletions
+24 -32
View File
@@ -482,23 +482,21 @@ public infix fun Short.until(to: Byte): IntRange {
/**
* Returns a range from this value up to but excluding the specified [to] value.
*
* The [to] value must be greater than [Char.MIN_VALUE].
* If the [to] value is less than or equal to ['\u0000'] the returned range is empty.
*/
public infix fun Char.until(to: Char): CharRange {
val to_ = (to.toInt() - 1).toChar()
if (to_ > to) throw IllegalArgumentException("The to argument value '$to' was too small.")
return this .. to_
if (to <= '\u0000') return CharRange.EMPTY
return this .. (to - 1).toChar()
}
/**
* Returns a range from this value up to but excluding the specified [to] value.
*
* The [to] value must be greater than [Int.MIN_VALUE].
* If the [to] value is less than or equal to [Int.MIN_VALUE] the returned range is empty.
*/
public infix fun Int.until(to: Int): IntRange {
val to_ = (to.toLong() - 1).toInt()
if (to_ > to) throw IllegalArgumentException("The to argument value '$to' was too small.")
return this .. to_
if (to <= Int.MIN_VALUE) return IntRange.EMPTY
return this .. (to - 1).toInt()
}
/**
@@ -511,67 +509,61 @@ public infix fun Long.until(to: Int): LongRange {
/**
* Returns a range from this value up to but excluding the specified [to] value.
*
* The [to] value must be greater than [Int.MIN_VALUE].
* If the [to] value is less than or equal to [Int.MIN_VALUE] the returned range is empty.
*/
public infix fun Byte.until(to: Int): IntRange {
val to_ = (to.toLong() - 1).toInt()
if (to_ > to) throw IllegalArgumentException("The to argument value '$to' was too small.")
return this.toInt() .. to_
if (to <= Int.MIN_VALUE) return IntRange.EMPTY
return this.toInt() .. (to - 1).toInt()
}
/**
* Returns a range from this value up to but excluding the specified [to] value.
*
* The [to] value must be greater than [Int.MIN_VALUE].
* If the [to] value is less than or equal to [Int.MIN_VALUE] the returned range is empty.
*/
public infix fun Short.until(to: Int): IntRange {
val to_ = (to.toLong() - 1).toInt()
if (to_ > to) throw IllegalArgumentException("The to argument value '$to' was too small.")
return this.toInt() .. to_
if (to <= Int.MIN_VALUE) return IntRange.EMPTY
return this.toInt() .. (to - 1).toInt()
}
/**
* Returns a range from this value up to but excluding the specified [to] value.
*
* The [to] value must be greater than [Long.MIN_VALUE].
* If the [to] value is less than or equal to [Long.MIN_VALUE] the returned range is empty.
*/
public infix fun Int.until(to: Long): LongRange {
val to_ = (to - 1).toLong()
if (to_ > to) throw IllegalArgumentException("The to argument value '$to' was too small.")
return this.toLong() .. to_
if (to <= Long.MIN_VALUE) return LongRange.EMPTY
return this.toLong() .. (to - 1).toLong()
}
/**
* Returns a range from this value up to but excluding the specified [to] value.
*
* The [to] value must be greater than [Long.MIN_VALUE].
* If the [to] value is less than or equal to [Long.MIN_VALUE] the returned range is empty.
*/
public infix fun Long.until(to: Long): LongRange {
val to_ = (to - 1).toLong()
if (to_ > to) throw IllegalArgumentException("The to argument value '$to' was too small.")
return this .. to_
if (to <= Long.MIN_VALUE) return LongRange.EMPTY
return this .. (to - 1).toLong()
}
/**
* Returns a range from this value up to but excluding the specified [to] value.
*
* The [to] value must be greater than [Long.MIN_VALUE].
* If the [to] value is less than or equal to [Long.MIN_VALUE] the returned range is empty.
*/
public infix fun Byte.until(to: Long): LongRange {
val to_ = (to - 1).toLong()
if (to_ > to) throw IllegalArgumentException("The to argument value '$to' was too small.")
return this.toLong() .. to_
if (to <= Long.MIN_VALUE) return LongRange.EMPTY
return this.toLong() .. (to - 1).toLong()
}
/**
* Returns a range from this value up to but excluding the specified [to] value.
*
* The [to] value must be greater than [Long.MIN_VALUE].
* If the [to] value is less than or equal to [Long.MIN_VALUE] the returned range is empty.
*/
public infix fun Short.until(to: Long): LongRange {
val to_ = (to - 1).toLong()
if (to_ > to) throw IllegalArgumentException("The to argument value '$to' was too small.")
return this.toLong() .. to_
if (to <= Long.MIN_VALUE) return LongRange.EMPTY
return this.toLong() .. (to - 1).toLong()
}
/**
+6 -5
View File
@@ -36,8 +36,7 @@ public class RangeTest {
assertTrue(9 in openRange)
assertFalse(10 in openRange)
// fails to throw in JS
// assertTrue(assertFails { 1 until Int.MIN_VALUE } is IllegalArgumentException)
assertTrue((1 until Int.MIN_VALUE).isEmpty())
}
@test fun byteRange() {
@@ -72,7 +71,7 @@ public class RangeTest {
// byte arguments now construct IntRange so no overflow here
// assertTrue(assertFails { 0.toByte() until Byte.MIN_VALUE } is IllegalArgumentException)
assertTrue((0.toByte() until Int.MIN_VALUE).isEmpty())
}
@test fun shortRange() {
@@ -106,6 +105,7 @@ public class RangeTest {
// short arguments now construct IntRange so no overflow here
// assertTrue(assertFails { 0.toShort() until Short.MIN_VALUE } is IllegalArgumentException)
assertTrue((0.toShort() until Int.MIN_VALUE).isEmpty())
}
@test fun longRange() {
@@ -140,7 +140,8 @@ public class RangeTest {
assertTrue(9L in openRange)
assertFalse(10L in openRange)
assertFailsWith<IllegalArgumentException> { 0L until Long.MIN_VALUE }
assertTrue((0 until Long.MIN_VALUE).isEmpty())
assertTrue((0L until Long.MIN_VALUE).isEmpty())
}
@@ -168,7 +169,7 @@ public class RangeTest {
assertTrue('Y' in openRange)
assertFalse('Z' in openRange)
assertFailsWith<IllegalArgumentException> { 'A' until '\u0000' }
assertTrue(('A' until '\u0000').isEmpty())
}
@test fun doubleRange() {
@@ -83,12 +83,15 @@ fun ranges(): List<GenericFunction> {
val elementType = rangeElementType(fromType, toType)
val progressionType = elementType.name + "Range"
returns(progressionType)
val minValue = if (elementType == PrimitiveType.Char) "'\\u0000'" else "$elementType.MIN_VALUE"
doc {
"""
Returns a range from this value up to but excluding the specified [to] value.
${ if (elementType == toType) "The [to] value must be greater than [$elementType.MIN_VALUE]." else "" }
${textWhen(elementType == toType) {
"If the [to] value is less than or equal to [$minValue] the returned range is empty."
}}
"""
}
@@ -102,10 +105,10 @@ fun ranges(): List<GenericFunction> {
else -> "to"
}
body {
// <= instead of == for JS
"""
val to_ = ($toExpr - 1).to$elementType()
if (to_ > to) throw IllegalArgumentException("The to argument value '${'$'}to' was too small.")
return $fromExpr .. to_
if (to <= $minValue) return $progressionType.EMPTY
return $fromExpr .. (to - 1).to$elementType()
"""
}
} else {
@@ -38,6 +38,8 @@ object DocExtensions {
else -> "list"
}
fun textWhen(condition: Boolean, text: () -> String): String = if (condition) text() else ""
private fun String.singularize() = removeSuffix("s")
public fun String.pluralize() = when {