From 1cc94f92e28ccacd30d6f4decc16f1d5af15dab0 Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Sat, 11 Jul 2015 00:46:52 +0300 Subject: [PATCH] Also generate contains for meaningless combinations of types to prevent mistakenly using contains from an Iterable. #KT-6361 --- libraries/stdlib/src/generated/_Ranges.kt | 60 +++++++++++++++++++ .../kotlin-stdlib-gen/src/templates/Engine.kt | 1 + .../kotlin-stdlib-gen/src/templates/Ranges.kt | 18 ++++-- 3 files changed, 75 insertions(+), 4 deletions(-) diff --git a/libraries/stdlib/src/generated/_Ranges.kt b/libraries/stdlib/src/generated/_Ranges.kt index 1507bfce3b9..2271752701d 100644 --- a/libraries/stdlib/src/generated/_Ranges.kt +++ b/libraries/stdlib/src/generated/_Ranges.kt @@ -45,6 +45,41 @@ public fun FloatRange.contains(item: Byte): Boolean { return start <= item && item <= end } +deprecated("The 'contains' operation for a range of Char and Byte item is not supported and should not be used.") +public fun CharRange.contains(item: Byte): Nothing { + throw UnsupportedOperationException() +} + +deprecated("The 'contains' operation for a range of Int and Char item is not supported and should not be used.") +public fun IntRange.contains(item: Char): Nothing { + throw UnsupportedOperationException() +} + +deprecated("The 'contains' operation for a range of Long and Char item is not supported and should not be used.") +public fun LongRange.contains(item: Char): Nothing { + throw UnsupportedOperationException() +} + +deprecated("The 'contains' operation for a range of Byte and Char item is not supported and should not be used.") +public fun ByteRange.contains(item: Char): Nothing { + throw UnsupportedOperationException() +} + +deprecated("The 'contains' operation for a range of Short and Char item is not supported and should not be used.") +public fun ShortRange.contains(item: Char): Nothing { + throw UnsupportedOperationException() +} + +deprecated("The 'contains' operation for a range of Double and Char item is not supported and should not be used.") +public fun DoubleRange.contains(item: Char): Nothing { + throw UnsupportedOperationException() +} + +deprecated("The 'contains' operation for a range of Float and Char item is not supported and should not be used.") +public fun FloatRange.contains(item: Char): Nothing { + throw UnsupportedOperationException() +} + /** * Checks if the specified [item] belongs to this range. */ @@ -80,6 +115,11 @@ public fun FloatRange.contains(item: Double): Boolean { return start <= item && item <= end } +deprecated("The 'contains' operation for a range of Char and Double item is not supported and should not be used.") +public fun CharRange.contains(item: Double): Nothing { + throw UnsupportedOperationException() +} + /** * Checks if the specified [item] belongs to this range. */ @@ -115,6 +155,11 @@ public fun DoubleRange.contains(item: Float): Boolean { return start <= item && item <= end } +deprecated("The 'contains' operation for a range of Char and Float item is not supported and should not be used.") +public fun CharRange.contains(item: Float): Nothing { + throw UnsupportedOperationException() +} + /** * Checks if the specified [item] belongs to this range. */ @@ -150,6 +195,11 @@ public fun FloatRange.contains(item: Int): Boolean { return start <= item && item <= end } +deprecated("The 'contains' operation for a range of Char and Int item is not supported and should not be used.") +public fun CharRange.contains(item: Int): Nothing { + throw UnsupportedOperationException() +} + /** * Checks if the specified [item] belongs to this range. */ @@ -185,6 +235,11 @@ public fun FloatRange.contains(item: Long): Boolean { return start <= item && item <= end } +deprecated("The 'contains' operation for a range of Char and Long item is not supported and should not be used.") +public fun CharRange.contains(item: Long): Nothing { + throw UnsupportedOperationException() +} + /** * Checks if the specified [item] belongs to this range. */ @@ -220,6 +275,11 @@ public fun FloatRange.contains(item: Short): Boolean { return start <= item && item <= end } +deprecated("The 'contains' operation for a range of Char and Short item is not supported and should not be used.") +public fun CharRange.contains(item: Short): Nothing { + throw UnsupportedOperationException() +} + /** * 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. diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Engine.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Engine.kt index f5bd5bddb64..f275334e765 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Engine.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Engine.kt @@ -54,6 +54,7 @@ enum class PrimitiveType { } fun PrimitiveType.isIntegral(): Boolean = this in PrimitiveType.integralPrimitives +fun PrimitiveType.isNumeric(): Boolean = this in PrimitiveType.numericPrimitives class GenericFunction(val signature: String, val keyword: String = "fun") : Comparable { diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Ranges.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Ranges.kt index 41f2e354c6a..f731cfe254e 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Ranges.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Ranges.kt @@ -120,12 +120,22 @@ fun ranges(): List { fun contains(rangeType: PrimitiveType, itemType: PrimitiveType) = f("contains(item: $itemType)") { only(RangesOfPrimitives) only(rangeType) - returns("Boolean") - doc { "Checks if the specified [item] belongs to this range." } - body { "return start <= item && item <= end" } + val meaningless = (rangeType.isNumeric() != itemType.isNumeric()) + if (!meaningless) { + returns("Boolean") + doc { "Checks if the specified [item] belongs to this range." } + body { "return start <= item && item <= end" } + } + else { + returns("Nothing") + annotations("""deprecated("The 'contains' operation for a range of $rangeType and $itemType item is not supported and should not be used.")""") + body { """throw UnsupportedOperationException()""" } + } } - templates addAll numericPermutations.filter { it.first != it.second }.map { contains(it.first, it.second) } + val allPermutations = (numericPrimitives + PrimitiveType.Char).let { it.flatMap { from -> it.map { to -> from to to } }} + + templates addAll allPermutations.filter { it.first != it.second }.map { contains(it.first, it.second) } return templates } \ No newline at end of file