Drop Progression<T> and its deprecated properties: start, end, increment.

Drop deprecated range extensions.
Make progression constructors private.
This commit is contained in:
Ilya Gorbunov
2016-01-14 20:19:52 +03:00
parent 6dd8470835
commit 91f4cf0ebc
15 changed files with 45 additions and 257 deletions
@@ -1065,7 +1065,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
Type asmLoopRangeType = asmType(loopRangeType);
Collection<PropertyDescriptor> incrementProp =
loopRangeType.getMemberScope().getContributedVariables(Name.identifier("increment"), NoLookupLocation.FROM_BACKEND);
loopRangeType.getMemberScope().getContributedVariables(Name.identifier("step"), NoLookupLocation.FROM_BACKEND);
assert incrementProp.size() == 1 : loopRangeType + " " + incrementProp.size();
incrementType = asmType(incrementProp.iterator().next().getType());
-41
View File
@@ -1,41 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package kotlin
/**
* Represents a sequence of numbers or characters with a given start value, end value and step.
* This class is intended to be used in 'for' loops, and the JVM backend suggests efficient
* bytecode generation for it. Progressions with a step of -1 can be created through the
* `downTo` method on classes representing primitive types.
*/
@Deprecated("This generic progression interface is not of much use and will be removed soon. Use concrete progression implementation instead: IntProgression, LongProgression or CharProgression.")
public interface Progression<out N : Any> : Iterable<N> {
/**
* The start value of the progression.
*/
public val start: N
/**
* The end value of the progression (inclusive).
*/
public val end: N
/**
* The step of the progression.
*/
public val increment: Number
}
+6 -48
View File
@@ -24,13 +24,12 @@ import kotlin.internal.getProgressionLastElement
* A progression of values of type `Char`.
*/
public open class CharProgression
@Deprecated("This constructor will become private soon. Use CharProgression.fromClosedRange() instead.", ReplaceWith("CharProgression.fromClosedRange(start, endInclusive, step)"))
public constructor
internal constructor
(
start: Char,
endInclusive: Char,
step: Int
) : Progression<Char> /*, Iterable<Char> */ {
) : Iterable<Char> {
init {
if (step == 0) throw IllegalArgumentException("Step must be non-zero")
}
@@ -50,19 +49,6 @@ public open class CharProgression
*/
public val step: Int = step
@Deprecated("Use 'first' property instead.", ReplaceWith("first"))
public override val start: Char get() = first
/**
* The end value of the progression (inclusive).
*/
@Deprecated("Use 'last' property instead.")
public override val end: Char = endInclusive
@Deprecated("Use 'step' property instead.", ReplaceWith("step"))
public override val increment: Int get() = step
override fun iterator(): CharIterator = CharProgressionIterator(first, last, step)
/** Checks if the progression is empty. */
@@ -92,13 +78,12 @@ public open class CharProgression
* A progression of values of type `Int`.
*/
public open class IntProgression
@Deprecated("This constructor will become private soon. Use IntProgression.fromClosedRange() instead.", ReplaceWith("IntProgression.fromClosedRange(start, endInclusive, step)"))
public constructor
internal constructor
(
start: Int,
endInclusive: Int,
step: Int
) : Progression<Int> /*, Iterable<Int> */ {
) : Iterable<Int> {
init {
if (step == 0) throw IllegalArgumentException("Step must be non-zero")
}
@@ -118,19 +103,6 @@ public open class IntProgression
*/
public val step: Int = step
@Deprecated("Use 'first' property instead.", ReplaceWith("first"))
public override val start: Int get() = first
/**
* The end value of the progression (inclusive).
*/
@Deprecated("Use 'last' property instead.")
public override val end: Int = endInclusive
@Deprecated("Use 'step' property instead.", ReplaceWith("step"))
public override val increment: Int get() = step
override fun iterator(): IntIterator = IntProgressionIterator(first, last, step)
/** Checks if the progression is empty. */
@@ -160,13 +132,12 @@ public open class IntProgression
* A progression of values of type `Long`.
*/
public open class LongProgression
@Deprecated("This constructor will become private soon. Use LongProgression.fromClosedRange() instead.", ReplaceWith("LongProgression.fromClosedRange(start, endInclusive, step)"))
public constructor
internal constructor
(
start: Long,
endInclusive: Long,
step: Long
) : Progression<Long> /*, Iterable<Long> */ {
) : Iterable<Long> {
init {
if (step == 0L) throw IllegalArgumentException("Step must be non-zero")
}
@@ -186,19 +157,6 @@ public open class LongProgression
*/
public val step: Long = step
@Deprecated("Use 'first' property instead.", ReplaceWith("first"))
public override val start: Long get() = first
/**
* The end value of the progression (inclusive).
*/
@Deprecated("Use 'last' property instead.")
public override val end: Long = endInclusive
@Deprecated("Use 'step' property instead.", ReplaceWith("step"))
public override val increment: Long get() = step
override fun iterator(): LongIterator = LongProgressionIterator(first, last, step)
/** Checks if the progression is empty. */
+15 -24
View File
@@ -22,24 +22,21 @@ package kotlin.ranges
* A range of values of type `Char`.
*/
public class CharRange(start: Char, endInclusive: Char) : CharProgression(start, endInclusive, 1), ClosedRange<Char> {
@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(value: Char): Boolean = start <= value && value <= endInclusive
override fun contains(value: Char): Boolean = first <= value && value <= last
override fun isEmpty(): Boolean = start > endInclusive
override fun isEmpty(): Boolean = first > last
override fun equals(other: Any?): Boolean =
other is CharRange && (isEmpty() && other.isEmpty() ||
start == other.start && endInclusive == other.endInclusive)
first == other.first && last == other.last)
override fun hashCode(): Int =
if (isEmpty()) -1 else (31 * start.toInt() + endInclusive.toInt())
if (isEmpty()) -1 else (31 * first.toInt() + last.toInt())
override fun toString(): String = "$start..$endInclusive"
override fun toString(): String = "$first..$last"
companion object {
/** An empty range of values of type Char. */
@@ -51,24 +48,21 @@ public class CharRange(start: Char, endInclusive: Char) : CharProgression(start,
* A range of values of type `Int`.
*/
public class IntRange(start: Int, endInclusive: Int) : IntProgression(start, endInclusive, 1), ClosedRange<Int> {
@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(value: Int): Boolean = start <= value && value <= endInclusive
override fun contains(value: Int): Boolean = first <= value && value <= last
override fun isEmpty(): Boolean = start > endInclusive
override fun isEmpty(): Boolean = first > last
override fun equals(other: Any?): Boolean =
other is IntRange && (isEmpty() && other.isEmpty() ||
start == other.start && endInclusive == other.endInclusive)
first == other.first && last == other.last)
override fun hashCode(): Int =
if (isEmpty()) -1 else (31 * start + endInclusive)
if (isEmpty()) -1 else (31 * first + last)
override fun toString(): String = "$start..$endInclusive"
override fun toString(): String = "$first..$last"
companion object {
/** An empty range of values of type Int. */
@@ -80,24 +74,21 @@ public class IntRange(start: Int, endInclusive: Int) : IntProgression(start, end
* A range of values of type `Long`.
*/
public class LongRange(start: Long, endInclusive: Long) : LongProgression(start, endInclusive, 1), ClosedRange<Long> {
@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(value: Long): Boolean = start <= value && value <= endInclusive
override fun contains(value: Long): Boolean = first <= value && value <= last
override fun isEmpty(): Boolean = start > endInclusive
override fun isEmpty(): Boolean = first > last
override fun equals(other: Any?): Boolean =
other is LongRange && (isEmpty() && other.isEmpty() ||
start == other.start && endInclusive == other.endInclusive)
first == other.first && last == other.last)
override fun hashCode(): Int =
if (isEmpty()) -1 else (31 * (start xor (start ushr 32)) + (endInclusive xor (endInclusive ushr 32))).toInt()
if (isEmpty()) -1 else (31 * (first xor (first ushr 32)) + (last xor (last ushr 32))).toInt()
override fun toString(): String = "$start..$endInclusive"
override fun toString(): String = "$first..$last"
companion object {
/** An empty range of values of type Long. */
@@ -52,13 +52,12 @@ class GenerateProgressions(out: PrintWriter) : BuiltInsSourceGenerator(out) {
* 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, endInclusive, step)"))
public constructor
internal constructor
(
start: $t,
endInclusive: $t,
step: $incrementType
) : Progression<$t> /*, Iterable<$t> */ {
) : Iterable<$t> {
init {
$checkZero
}
@@ -78,19 +77,6 @@ public open class $progression
*/
public val step: $incrementType = step
@Deprecated("Use 'first' property 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
@Deprecated("Use 'step' property instead.", ReplaceWith("step"))
public override val increment: $incrementType get() = step
override fun iterator(): ${t}Iterator = ${t}ProgressionIterator(first, last, step)
/** Checks if the progression is empty. */
@@ -39,33 +39,30 @@ class GenerateRanges(out: PrintWriter) : BuiltInsSourceGenerator(out) {
val hashCode = when (kind) {
CHAR -> "=\n" +
" if (isEmpty()) -1 else (31 * start.toInt() + endInclusive.toInt())"
" if (isEmpty()) -1 else (31 * first.toInt() + last.toInt())"
INT -> "=\n" +
" if (isEmpty()) -1 else (31 * start + endInclusive)"
" if (isEmpty()) -1 else (31 * first + last)"
LONG -> "=\n" +
" if (isEmpty()) -1 else (31 * ${hashLong("start")} + ${hashLong("endInclusive")}).toInt()"
" if (isEmpty()) -1 else (31 * ${hashLong("first")} + ${hashLong("last")}).toInt()"
}
val toString = "\"\$start..\$endInclusive\""
val toString = "\"\$first..\$last\""
out.println(
"""/**
* A range of values of type `$t`.
*/
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
override val start: $t get() = first
override val endInclusive: $t get() = last
override fun contains(value: $t): Boolean = start <= value && value <= endInclusive
override fun contains(value: $t): Boolean = first <= value && value <= last
override fun isEmpty(): Boolean = start > endInclusive
override fun isEmpty(): Boolean = first > last
override fun equals(other: Any?): Boolean =
other is $range && (isEmpty() && other.isEmpty() ||
${compare("start")} && ${compare("endInclusive")})
${compare("first")} && ${compare("last")})
override fun hashCode(): Int $hashCode
+3 -3
View File
@@ -120,7 +120,7 @@ public class Regex(pattern: String, options: Set<RegexOption>) {
val foundMatch = match!!
sb.append(input, lastStart, foundMatch.range.start)
sb.append(transform(foundMatch))
lastStart = foundMatch.range.end + 1
lastStart = foundMatch.range.endInclusive + 1
match = foundMatch.next()
} while (lastStart < length && match != null)
@@ -154,7 +154,7 @@ public class Regex(pattern: String, options: Set<RegexOption>) {
for (match in matches) {
result.add(input.subSequence(lastStart, match.range.start).toString())
lastStart = match.range.end + 1
lastStart = match.range.endInclusive + 1
}
result.add(input.subSequence(lastStart, input.length()).toString())
return result
@@ -223,7 +223,7 @@ private fun RegExp.findNext(input: String, from: Int): MatchResult? {
return groupValues_!!
}
override fun next(): MatchResult? = this@findNext.findNext(input, if (range.isEmpty()) range.start + 1 else range.end + 1)
override fun next(): MatchResult? = this@findNext.findNext(input, if (range.isEmpty()) range.start + 1 else range.endInclusive + 1)
}
}
@@ -183,9 +183,9 @@ fun translateForExpression(expression: KtForExpression, context: TranslationCont
fun getProperty(funName: String): JsExpression = JsNameRef(funName, rangeExpression.reference())
val start = context.declareTemporary(getProperty("start"))
val end = context.declareTemporary(getProperty("end"))
val increment = context.declareTemporary(getProperty("increment"))
val start = context.declareTemporary(getProperty("first"))
val end = context.declareTemporary(getProperty("last"))
val increment = context.declareTemporary(getProperty("step"))
val body = translateBody(null)
val initExpression = newVar(parameterName, start.reference())
+1 -28
View File
@@ -859,18 +859,12 @@
return [Kotlin.modules['builtins'].kotlin.collections.Iterable];
},
function (start, end, step) {
this.start = start;
this.endInclusive = end;
this.first = start;
this.last = getProgressionFinalElement(start, end, step);
this.step = step;
this.increment = step;
if (this.step === 0)
throw new Kotlin.IllegalArgumentException('Step must be non-zero');
}, {
end: { get: function () {
return this.endInclusive;
}},
iterator: function () {
return new Kotlin.RangeIterator(this.first, this.last, this.step);
},
@@ -895,9 +889,6 @@
this.start = start;
this.endInclusive = endInclusive;
}, {
end: { get: function () {
return this.endInclusive;
}},
contains_htax2k$: function (item) {
return this.start <= item && item <= this.endInclusive;
},
@@ -947,18 +938,12 @@
return [Kotlin.modules['builtins'].kotlin.collections.Iterable];
},
function (start, end, step) {
this.start = start;
this.endInclusive = end;
this.first = start;
this.last = getProgressionFinalElementLong(start, end, step);
this.step = step;
this.increment = step;
if (this.step.isZero())
throw new Kotlin.IllegalArgumentException('Step must be non-zero');
}, {
end: { get: function () {
return this.endInclusive;
}},
iterator: function () {
return new Kotlin.LongRangeIterator(this.first, this.last, this.step);
},
@@ -983,9 +968,6 @@
this.start = start;
this.endInclusive = endInclusive;
}, {
end: { get: function () {
return this.endInclusive;
}},
contains_htax2k$: function (item) {
return this.start.compareTo_za3rmp$(item) <= 0 && item.compareTo_za3rmp$(this.endInclusive) <= 0;
},
@@ -1026,20 +1008,14 @@
return [Kotlin.modules['builtins'].kotlin.collections.Iterable];
},
function (start, end, step) {
this.start = start;
this.endInclusive = end;
this.first = start;
this.startCode = start.charCodeAt(0);
this.endCode = getProgressionFinalElement(this.startCode, end.charCodeAt(0), step);
this.last = String.fromCharCode(this.endCode);
this.step = step;
this.increment = step;
if (this.increment === 0)
if (this.step === 0)
throw new Kotlin.IllegalArgumentException('Increment must be non-zero');
}, {
end: { get: function () {
return this.endInclusive;
}},
iterator: function () {
return new Kotlin.CharRangeIterator(this.startCode, this.endCode, this.step);
},
@@ -1065,9 +1041,6 @@
this.start = start;
this.endInclusive = endInclusive;
}, {
end: { get: function () {
return this.endInclusive;
}},
contains_htax2k$: function (item) {
return this.start <= item && item <= this.endInclusive;
},
-51
View File
@@ -410,30 +410,6 @@ public fun LongProgression.reversed(): LongProgression {
return LongProgression.fromClosedRange(last, first, -step)
}
/**
* Returns a progression that goes over this range in reverse direction.
*/
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
public fun CharRange.reversed(): CharProgression {
return CharProgression.fromClosedRange(last, first, -1)
}
/**
* Returns a progression that goes over this range in reverse direction.
*/
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
public fun IntRange.reversed(): IntProgression {
return IntProgression.fromClosedRange(last, first, -1)
}
/**
* Returns a progression that goes over this range in reverse direction.
*/
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
public fun LongRange.reversed(): LongProgression {
return LongProgression.fromClosedRange(last, first, -1L)
}
/**
* Returns a progression that goes over the same range with the given step.
*/
@@ -458,33 +434,6 @@ public infix fun LongProgression.step(step: Long): LongProgression {
return LongProgression.fromClosedRange(first, last, if (this.step > 0) step else -step)
}
/**
* Returns a progression that goes over this range with given step.
*/
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
public infix fun CharRange.step(step: Int): CharProgression {
checkStepIsPositive(step > 0, step)
return CharProgression.fromClosedRange(first, last, step)
}
/**
* Returns a progression that goes over this range with given step.
*/
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
public infix fun IntRange.step(step: Int): IntProgression {
checkStepIsPositive(step > 0, step)
return IntProgression.fromClosedRange(first, last, step)
}
/**
* Returns a progression that goes over this range with given step.
*/
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
public infix fun LongRange.step(step: Long): LongProgression {
checkStepIsPositive(step > 0, step)
return LongProgression.fromClosedRange(first, last, step)
}
/**
* Returns a range from this value up to but excluding the specified [to] value.
*/
@@ -27,14 +27,6 @@ public fun<T> Enumeration<T>.asSequence(): Sequence<T> = this.iterator().asSeque
*/
public fun <T> sequenceOf(vararg elements: T): Sequence<T> = if (elements.isEmpty()) emptySequence() else elements.asSequence()
/**
* Creates a sequence that returns all values in the specified [progression].
*/
@Deprecated("Use progression.asSequence() instead.", ReplaceWith("progression.asSequence()"))
public fun <T : Any> sequenceOf(progression: Progression<T>): Sequence<T> = object : Sequence<T> {
override fun iterator(): Iterator<T> = progression.iterator()
}
/**
* Returns an empty sequence.
*/
@@ -223,6 +223,7 @@ public fun String.replaceRange(firstIndex: Int, lastIndex: Int, replacement: Str
public fun String.replaceRange(range: IntRange, replacement: String): String
= replaceRange(range.start, range.end + 1, replacement)
private val IntRange.end: Int get() = endInclusive
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
public fun String.removePrefix(prefix: String): String = removePrefix(prefix)
@@ -31,12 +31,6 @@ public open class RangeIterationTestBase {
last = sequence.last
increment = sequence.step
}
// TODO: Drop this branch
is Progression -> {
first = sequence.start
last = sequence.end
increment = sequence.increment
}
else -> throw IllegalArgumentException("Unsupported sequence type: $sequence")
}
@@ -1,6 +1,7 @@
@file: Suppress("DEPRECATION_ERROR")
package language
import kotlin.ranges.LongProgression.Companion
import java.lang.Double as jDouble
import java.lang.Float as jFloat
import org.junit.Test as test
@@ -26,9 +27,9 @@ public class RangeJVMTest {
@test fun illegalProgressionCreation() {
fun assertFailsWithIllegalArgument(f: () -> Unit) = assertFailsWith(IllegalArgumentException::class, block = f)
// create Progression explicitly with increment = 0
assertFailsWithIllegalArgument { IntProgression(0, 5, 0) }
assertFailsWithIllegalArgument { LongProgression(0, 5, 0) }
assertFailsWithIllegalArgument { CharProgression('a', 'z', 0) }
assertFailsWithIllegalArgument { IntProgression.fromClosedRange(0, 5, 0) }
assertFailsWithIllegalArgument { LongProgression.fromClosedRange(0, 5, 0) }
assertFailsWithIllegalArgument { CharProgression.fromClosedRange('a', 'z', 0) }
assertFailsWithIllegalArgument { 0..5 step 0 }
@@ -13,15 +13,10 @@ fun ranges(): List<GenericFunction> {
fun <T> Collection<T>.permutations(): List<Pair<T, T>> = flatMap { a -> map { b -> a to b } }
templates add f("reversed()") {
only(RangesOfPrimitives, ProgressionsOfPrimitives)
only(ProgressionsOfPrimitives)
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")
deprecate(RangesOfPrimitives) { forBinaryCompatibility }
body(RangesOfPrimitives) {
"return TProgression.fromClosedRange(last, first, -ONE)"
}
body(ProgressionsOfPrimitives) {
"return TProgression.fromClosedRange(last, first, -step)"
}
@@ -30,18 +25,10 @@ fun ranges(): List<GenericFunction> {
templates add f("step(step: SUM)") {
infix(true)
only(RangesOfPrimitives, ProgressionsOfPrimitives)
only(ProgressionsOfPrimitives)
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")
deprecate(RangesOfPrimitives) { forBinaryCompatibility }
body(RangesOfPrimitives) {
"""
checkStepIsPositive(step > 0, step)
return TProgression.fromClosedRange(first, last, step)
"""
}
body(ProgressionsOfPrimitives) {
"""
checkStepIsPositive(step > 0, step)