diff --git a/libraries/stdlib/src/kotlin/collections/AbstractCollection.kt b/libraries/stdlib/src/kotlin/collections/AbstractCollection.kt new file mode 100644 index 00000000000..5ff2a502bb5 --- /dev/null +++ b/libraries/stdlib/src/kotlin/collections/AbstractCollection.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2010-2016 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.collections + +public abstract class AbstractCollection : Collection { + abstract override val size: Int + abstract override fun iterator(): Iterator + + override fun contains(element: @UnsafeVariance E): Boolean = any { it == element } + + override fun containsAll(elements: Collection<@UnsafeVariance E>): Boolean = + elements.all(this::contains) + + override fun isEmpty(): Boolean = size == 0 + + abstract override fun hashCode(): Int + + abstract override fun equals(other: Any?): Boolean + + override fun toString(): String = joinToString(", ", "[", "]") { + if (it === this) "(this Collection)" else it.toString() + } + + +} + + diff --git a/libraries/stdlib/src/kotlin/collections/AbstractList.kt b/libraries/stdlib/src/kotlin/collections/AbstractList.kt new file mode 100644 index 00000000000..230449f0f2c --- /dev/null +++ b/libraries/stdlib/src/kotlin/collections/AbstractList.kt @@ -0,0 +1,151 @@ +/* + * Copyright 2010-2016 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. + */ +/* + * Based on GWT AbstractList + * Copyright 2007 Google Inc. +*/ + +package kotlin.collections + +public abstract class AbstractList : AbstractCollection(), List { + abstract override val size: Int + abstract override fun get(index: Int): E + + override fun iterator(): Iterator = IteratorImpl() + + override fun indexOf(element: @UnsafeVariance E): Int = indexOfFirst { it == element } + + override fun lastIndexOf(element: @UnsafeVariance E): Int = indexOfLast { it == element } + + override fun listIterator(): ListIterator = ListIteratorImpl(0) + + override fun listIterator(index: Int): ListIterator = ListIteratorImpl(index) + + override fun subList(fromIndex: Int, toIndex: Int): List = SubList(this, fromIndex, toIndex) + + internal open class SubList(private val list: AbstractList, private val fromIndex: Int, toIndex: Int) : AbstractList() { + private var _size: Int = 0 + + init { + checkRangeIndexes(fromIndex, toIndex, list.size) + this._size = toIndex - fromIndex + } + + override fun get(index: Int): E { + checkElementIndex(index, _size) + + return list[fromIndex + index] + } + + override val size: Int get() = _size + } + + override fun equals(other: Any?): Boolean { + if (other === this) return true + if (other !is List<*>) return false + + return orderedEquals(this, other) + } + + override fun hashCode(): Int = orderedHashCode(this) + + internal open inner class IteratorImpl : Iterator { + /** the index of the item that will be returned on the next call to [next]`()` */ + protected var index = 0 + /** the index of the item that was returned on the previous call to [next]`()` + * or [ListIterator.previous]`()` (for `ListIterator`), + * -1 if no such item exists + */ + protected var last = -1 + + override fun hasNext(): Boolean = index < size + + override fun next(): E { + if (!hasNext()) throw NoSuchElementException() + last = index++ + return get(last) + } + } + + /** + * Implementation of `MutableListIterator` for abstract lists. + */ + internal open inner class ListIteratorImpl(index: Int) : IteratorImpl(), ListIterator { + + init { + checkPositionIndex(index, this@AbstractList.size) + this.index = index + } + + override fun hasPrevious(): Boolean = index > 0 + + override fun nextIndex(): Int = index + + override fun previous(): E { + if (!hasPrevious()) throw NoSuchElementException() + + last = --index + return get(last) + } + + override fun previousIndex(): Int = index - 1 + } + + companion object { + internal fun checkElementIndex(index: Int, size: Int) { + if (index < 0 || index >= size) { + throw IndexOutOfBoundsException("index: $index, size: $size") + } + } + + internal fun checkPositionIndex(index: Int, size: Int) { + if (index < 0 || index > size) { + throw IndexOutOfBoundsException("index: $index, size: $size") + } + } + + internal fun checkRangeIndexes(start: Int, end: Int, size: Int) { + if (start < 0 || end > size) { + throw IndexOutOfBoundsException("fromIndex: $start, toIndex: $end, size: $size") + } + if (start > end) { + throw IllegalArgumentException("fromIndex: $start > toIndex: $end") + } + } + + internal fun orderedHashCode(c: Collection<*>): Int { + var hashCode = 1 + for (e in c) { + hashCode = 31 * hashCode + (e?.hashCode() ?: 0) + hashCode = hashCode or 0 // make sure we don't overflow + } + return hashCode + } + + internal fun orderedEquals(c: Collection<*>, other: Collection<*>): Boolean { + if (c.size != other.size) return false + + val otherIterator = other.iterator() + for (elem in c) { + val elemOther = otherIterator.next() + if (elem != elemOther) { + return false + } + } + return true + } + } +} \ No newline at end of file diff --git a/libraries/stdlib/src/kotlin/collections/AbstractSet.kt b/libraries/stdlib/src/kotlin/collections/AbstractSet.kt new file mode 100644 index 00000000000..5f91b809ffd --- /dev/null +++ b/libraries/stdlib/src/kotlin/collections/AbstractSet.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2010-2016 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.collections + +public abstract class AbstractSet protected constructor() : AbstractCollection(), Set { + + override fun equals(other: Any?): Boolean { + if (other === this) return true + if (other !is Set<*>) return false + if (other.size != size) return false + return containsAll(other) + } + + override fun hashCode(): Int { + var hashCode = 0 + for (element in this) { + hashCode = (hashCode + (element?.hashCode() ?: 0)) or 0 + } + return hashCode + } + +} \ No newline at end of file diff --git a/libraries/stdlib/src/kotlin/collections/ReversedViews.kt b/libraries/stdlib/src/kotlin/collections/ReversedViews.kt index 4bc8593dc22..dfec641cb21 100644 --- a/libraries/stdlib/src/kotlin/collections/ReversedViews.kt +++ b/libraries/stdlib/src/kotlin/collections/ReversedViews.kt @@ -18,25 +18,31 @@ package kotlin.collections -import java.util.* -private open class ReversedListReadOnly(protected open val delegate: List) : AbstractList() { +private open class ReversedListReadOnly(private val delegate: List) : AbstractList() { override val size: Int get() = delegate.size - override fun get(index: Int): T = delegate[index.flipIndex()] + override fun get(index: Int): T = delegate[reverseElementIndex(index)] - protected fun Int.flipIndex(): Int = if (this in 0..size - 1) size - this - 1 else throw IndexOutOfBoundsException("index $this should be in range [${0..size - 1}].") - protected fun Int.flipIndexForward(): Int = if (this in 0..size) size - this else throw IndexOutOfBoundsException("index $this should be in range [${0..size}].") } -private class ReversedList(protected override val delegate: MutableList) : ReversedListReadOnly(delegate) { - override fun clear() = delegate.clear() - override fun removeAt(index: Int): T = delegate.removeAt(index.flipIndex()) +private class ReversedList(private val delegate: MutableList) : AbstractMutableList() { + override val size: Int get() = delegate.size + override fun get(index: Int): T = delegate[reverseElementIndex(index)] - override fun set(index: Int, element: T): T = delegate.set(index.flipIndex(), element) + override fun clear() = delegate.clear() + override fun removeAt(index: Int): T = delegate.removeAt(reverseElementIndex(index)) + + override fun set(index: Int, element: T): T = delegate.set(reverseElementIndex(index), element) override fun add(index: Int, element: T) { - delegate.add(index.flipIndexForward(), element) + delegate.add(reversePositionIndex(index), element) } } +private fun List<*>.reverseElementIndex(index: Int) = // TODO: Use AbstractList.checkElementIndex: run { AbstractList.checkElementIndex(index, size); lastIndex - index } + if (index in 0..size - 1) size - index - 1 else throw IndexOutOfBoundsException("Index $index should be in range [${0..size - 1}].") + +private fun List<*>.reversePositionIndex(index: Int) = + if (index in 0..size) size - index else throw IndexOutOfBoundsException("Index $index should be in range [${0..size}].") + /** * Returns a reversed read-only view of the original List. diff --git a/libraries/stdlib/src/kotlin/collections/TypeAliases.kt b/libraries/stdlib/src/kotlin/collections/TypeAliases.kt new file mode 100644 index 00000000000..9bf6bbb1fd1 --- /dev/null +++ b/libraries/stdlib/src/kotlin/collections/TypeAliases.kt @@ -0,0 +1,6 @@ +@file:JvmVersion +package kotlin.collections + +public typealias AbstractMutableCollection = java.util.AbstractCollection +public typealias AbstractMutableList = java.util.AbstractList +public typealias AbstractMutableSet = java.util.AbstractSet \ No newline at end of file diff --git a/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib.txt b/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib.txt index 1e816d68dfd..cdf3228147c 100644 --- a/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib.txt +++ b/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib.txt @@ -66,6 +66,27 @@ public final class kotlin/_Assertions { public static final field INSTANCE Lkotlin/_Assertions; } +public abstract class kotlin/collections/AbstractCollection : java/util/Collection, kotlin/jvm/internal/markers/KMappedMarker { + public fun ()V + public fun add (Ljava/lang/Object;)Z + public fun addAll (Ljava/util/Collection;)Z + public fun clear ()V + public fun contains (Ljava/lang/Object;)Z + public fun containsAll (Ljava/util/Collection;)Z + public abstract fun equals (Ljava/lang/Object;)Z + public abstract fun getSize ()I + public abstract fun hashCode ()I + public fun isEmpty ()Z + public abstract fun iterator ()Ljava/util/Iterator; + public fun remove (Ljava/lang/Object;)Z + public fun removeAll (Ljava/util/Collection;)Z + public fun retainAll (Ljava/util/Collection;)Z + public final fun size ()I + public fun toArray ()[Ljava/lang/Object; + public fun toArray ([Ljava/lang/Object;)[Ljava/lang/Object; + public fun toString ()Ljava/lang/String; +} + public abstract class kotlin/collections/AbstractIterator : java/util/Iterator, kotlin/jvm/internal/markers/KMappedMarker { public fun ()V protected abstract fun computeNext ()V @@ -76,6 +97,53 @@ public abstract class kotlin/collections/AbstractIterator : java/util/Iterator, protected final fun setNext (Ljava/lang/Object;)V } +public abstract class kotlin/collections/AbstractList : kotlin/collections/AbstractCollection, java/util/List, kotlin/jvm/internal/markers/KMappedMarker { + public static final field Companion Lkotlin/collections/AbstractList$Companion; + public fun ()V + public fun add (ILjava/lang/Object;)V + public fun add (Ljava/lang/Object;)Z + public fun addAll (ILjava/util/Collection;)Z + public fun addAll (Ljava/util/Collection;)Z + public fun clear ()V + public fun equals (Ljava/lang/Object;)Z + public abstract fun get (I)Ljava/lang/Object; + public abstract fun getSize ()I + public fun hashCode ()I + public fun indexOf (Ljava/lang/Object;)I + public fun iterator ()Ljava/util/Iterator; + public fun lastIndexOf (Ljava/lang/Object;)I + public fun listIterator ()Ljava/util/ListIterator; + public fun listIterator (I)Ljava/util/ListIterator; + public fun remove (I)Ljava/lang/Object; + public fun remove (Ljava/lang/Object;)Z + public fun removeAll (Ljava/util/Collection;)Z + public fun removeAt (I)Ljava/lang/Object; + public fun retainAll (Ljava/util/Collection;)Z + public fun set (ILjava/lang/Object;)Ljava/lang/Object; + public fun subList (II)Ljava/util/List; + public fun toArray ()[Ljava/lang/Object; + public fun toArray ([Ljava/lang/Object;)[Ljava/lang/Object; +} + +public final class kotlin/collections/AbstractList$Companion { +} + +public abstract class kotlin/collections/AbstractSet : kotlin/collections/AbstractCollection, java/util/Set, kotlin/jvm/internal/markers/KMappedMarker { + protected fun ()V + public fun add (Ljava/lang/Object;)Z + public fun addAll (Ljava/util/Collection;)Z + public fun clear ()V + public fun equals (Ljava/lang/Object;)Z + public abstract fun getSize ()I + public fun hashCode ()I + public fun iterator ()Ljava/util/Iterator; + public fun remove (Ljava/lang/Object;)Z + public fun removeAll (Ljava/util/Collection;)Z + public fun retainAll (Ljava/util/Collection;)Z + public fun toArray ()[Ljava/lang/Object; + public fun toArray ([Ljava/lang/Object;)[Ljava/lang/Object; +} + public final class kotlin/collections/ArraysKt { public static final fun all ([BLkotlin/jvm/functions/Function1;)Z public static final fun all ([CLkotlin/jvm/functions/Function1;)Z