Skip to content

Commit d2eea13

Browse files
committed
Address compatibility issues in scala2-library-bootstrapped
1 parent bfd0b4f commit d2eea13

File tree

9 files changed

+5776
-0
lines changed

9 files changed

+5776
-0
lines changed

scala2-library-bootstrapped/src/scala/Array.scala

Lines changed: 690 additions & 0 deletions
Large diffs are not rendered by default.

scala2-library-bootstrapped/src/scala/collection/ArrayOps.scala

Lines changed: 1664 additions & 0 deletions
Large diffs are not rendered by default.

scala2-library-bootstrapped/src/scala/collection/Factory.scala

Lines changed: 784 additions & 0 deletions
Large diffs are not rendered by default.

scala2-library-bootstrapped/src/scala/collection/Iterable.scala

Lines changed: 1043 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
/*
2+
* Scala (https://www.scala-lang.org)
3+
*
4+
* Copyright EPFL and Lightbend, Inc.
5+
*
6+
* Licensed under Apache License 2.0
7+
* (http://www.apache.org/licenses/LICENSE-2.0).
8+
*
9+
* See the NOTICE file distributed with this work for
10+
* additional information regarding copyright ownership.
11+
*/
12+
13+
package scala
14+
package collection
15+
16+
import scala.annotation.{implicitNotFound, nowarn}
17+
18+
/** A Map whose keys are sorted according to a [[scala.math.Ordering]]*/
19+
trait SortedMap[K, +V]
20+
extends Map[K, V]
21+
with SortedMapOps[K, V, SortedMap, SortedMap[K, V]]
22+
with SortedMapFactoryDefaults[K, V, SortedMap, Iterable, Map]{
23+
24+
def unsorted: Map[K, V] = this
25+
26+
def sortedMapFactory: SortedMapFactory[SortedMap] = SortedMap
27+
28+
@nowarn("""cat=deprecation&origin=scala\.collection\.Iterable\.stringPrefix""")
29+
override protected[this] def stringPrefix: String = "SortedMap"
30+
31+
override def equals(that: Any): Boolean = that match {
32+
case _ if this eq that.asInstanceOf[AnyRef] => true
33+
case sm: SortedMap[K @unchecked, _] if sm.ordering == this.ordering =>
34+
(sm canEqual this) &&
35+
(this.size == sm.size) && {
36+
val i1 = this.iterator
37+
val i2 = sm.iterator
38+
var allEqual = true
39+
while (allEqual && i1.hasNext) {
40+
val kv1 = i1.next()
41+
val kv2 = i2.next()
42+
allEqual = ordering.equiv(kv1._1, kv2._1) && kv1._2 == kv2._2
43+
}
44+
allEqual
45+
}
46+
case _ => super.equals(that)
47+
}
48+
}
49+
50+
trait SortedMapOps[K, +V, +CC[X, Y] <: Map[X, Y] with SortedMapOps[X, Y, CC, _], +C <: SortedMapOps[K, V, CC, C]]
51+
extends MapOps[K, V, Map, C]
52+
with SortedOps[K, C] {
53+
54+
/** The companion object of this sorted map, providing various factory methods.
55+
*
56+
* @note When implementing a custom collection type and refining `CC` to the new type, this
57+
* method needs to be overridden to return a factory for the new type (the compiler will
58+
* issue an error otherwise).
59+
*/
60+
def sortedMapFactory: SortedMapFactory[CC]
61+
62+
/** Similar to `mapFromIterable`, but returns a SortedMap collection type.
63+
* Note that the return type is now `CC[K2, V2]`.
64+
*/
65+
@`inline` protected final def sortedMapFromIterable[K2, V2](it: Iterable[(K2, V2)])(implicit ordering: Ordering[K2]): CC[K2, V2] = sortedMapFactory.from(it)
66+
67+
def unsorted: Map[K, V]
68+
69+
/**
70+
* Creates an iterator over all the key/value pairs
71+
* contained in this map having a key greater than or
72+
* equal to `start` according to the ordering of
73+
* this map. x.iteratorFrom(y) is equivalent
74+
* to but often more efficient than x.from(y).iterator.
75+
*
76+
* @param start The lower bound (inclusive)
77+
* on the keys to be returned
78+
*/
79+
def iteratorFrom(start: K): Iterator[(K, V)]
80+
81+
/**
82+
* Creates an iterator over all the keys(or elements) contained in this
83+
* collection greater than or equal to `start`
84+
* according to the ordering of this collection. x.keysIteratorFrom(y)
85+
* is equivalent to but often more efficient than
86+
* x.from(y).keysIterator.
87+
*
88+
* @param start The lower bound (inclusive)
89+
* on the keys to be returned
90+
*/
91+
def keysIteratorFrom(start: K): Iterator[K]
92+
93+
/**
94+
* Creates an iterator over all the values contained in this
95+
* map that are associated with a key greater than or equal to `start`
96+
* according to the ordering of this map. x.valuesIteratorFrom(y) is
97+
* equivalent to but often more efficient than
98+
* x.from(y).valuesIterator.
99+
*
100+
* @param start The lower bound (inclusive)
101+
* on the keys to be returned
102+
*/
103+
def valuesIteratorFrom(start: K): Iterator[V] = iteratorFrom(start).map(_._2)
104+
105+
def firstKey: K = head._1
106+
def lastKey: K = last._1
107+
108+
/** Find the element with smallest key larger than or equal to a given key.
109+
* @param key The given key.
110+
* @return `None` if there is no such node.
111+
*/
112+
def minAfter(key: K): Option[(K, V)] = rangeFrom(key).headOption
113+
114+
/** Find the element with largest key less than a given key.
115+
* @param key The given key.
116+
* @return `None` if there is no such node.
117+
*/
118+
def maxBefore(key: K): Option[(K, V)] = rangeUntil(key).lastOption
119+
120+
def rangeTo(to: K): C = {
121+
val i = keySet.rangeFrom(to).iterator
122+
if (i.isEmpty) return coll
123+
val next = i.next()
124+
if (ordering.compare(next, to) == 0)
125+
if (i.isEmpty) coll
126+
else rangeUntil(i.next())
127+
else
128+
rangeUntil(next)
129+
}
130+
131+
override def keySet: SortedSet[K] = new KeySortedSet
132+
133+
/** The implementation class of the set returned by `keySet` */
134+
protected class KeySortedSet extends SortedSet[K] with GenKeySet with GenKeySortedSet {
135+
def diff(that: Set[K]): SortedSet[K] = fromSpecific(view.filterNot(that))
136+
def rangeImpl(from: Option[K], until: Option[K]): SortedSet[K] = {
137+
val map = SortedMapOps.this.rangeImpl(from, until)
138+
new map.KeySortedSet
139+
}
140+
}
141+
142+
/** A generic trait that is reused by sorted keyset implementations */
143+
protected trait GenKeySortedSet extends GenKeySet { this: SortedSet[K] =>
144+
implicit def ordering: Ordering[K] = SortedMapOps.this.ordering
145+
def iteratorFrom(start: K): Iterator[K] = SortedMapOps.this.keysIteratorFrom(start)
146+
}
147+
148+
// And finally, we add new overloads taking an ordering
149+
/** Builds a new sorted map by applying a function to all elements of this $coll.
150+
*
151+
* @param f the function to apply to each element.
152+
* @return a new $coll resulting from applying the given function
153+
* `f` to each element of this $coll and collecting the results.
154+
*/
155+
def map[K2, V2](f: ((K, V)) => (K2, V2))(implicit @implicitNotFound(SortedMapOps.ordMsg) ordering: Ordering[K2]): CC[K2, V2] =
156+
sortedMapFactory.from(new View.Map[(K, V), (K2, V2)](this, f))
157+
158+
/** Builds a new sorted map by applying a function to all elements of this $coll
159+
* and using the elements of the resulting collections.
160+
*
161+
* @param f the function to apply to each element.
162+
* @return a new $coll resulting from applying the given collection-valued function
163+
* `f` to each element of this $coll and concatenating the results.
164+
*/
165+
def flatMap[K2, V2](f: ((K, V)) => IterableOnce[(K2, V2)])(implicit @implicitNotFound(SortedMapOps.ordMsg) ordering: Ordering[K2]): CC[K2, V2] =
166+
sortedMapFactory.from(new View.FlatMap(this, f))
167+
168+
/** Builds a new sorted map by applying a partial function to all elements of this $coll
169+
* on which the function is defined.
170+
*
171+
* @param pf the partial function which filters and maps the $coll.
172+
* @return a new $coll resulting from applying the given partial function
173+
* `pf` to each element on which it is defined and collecting the results.
174+
* The order of the elements is preserved.
175+
*/
176+
def collect[K2, V2](pf: PartialFunction[(K, V), (K2, V2)])(implicit @implicitNotFound(SortedMapOps.ordMsg) ordering: Ordering[K2]): CC[K2, V2] =
177+
sortedMapFactory.from(new View.Collect(this, pf))
178+
179+
override def concat[V2 >: V](suffix: IterableOnce[(K, V2)]): CC[K, V2] = sortedMapFactory.from(suffix match {
180+
case it: Iterable[(K, V2)] => new View.Concat(this, it)
181+
case _ => iterator.concat(suffix.iterator)
182+
})(using ordering)
183+
184+
/** Alias for `concat` */
185+
@`inline` override final def ++ [V2 >: V](xs: IterableOnce[(K, V2)]): CC[K, V2] = concat(xs)
186+
187+
@deprecated("Consider requiring an immutable Map or fall back to Map.concat", "2.13.0")
188+
override def + [V1 >: V](kv: (K, V1)): CC[K, V1] = sortedMapFactory.from(new View.Appended(this, kv))(using ordering)
189+
190+
@deprecated("Use ++ with an explicit collection argument instead of + with varargs", "2.13.0")
191+
override def + [V1 >: V](elem1: (K, V1), elem2: (K, V1), elems: (K, V1)*): CC[K, V1] = sortedMapFactory.from(new View.Concat(new View.Appended(new View.Appended(this, elem1), elem2), elems))(using ordering)
192+
}
193+
194+
object SortedMapOps {
195+
private[collection] final val ordMsg = "No implicit Ordering[${K2}] found to build a SortedMap[${K2}, ${V2}]. You may want to upcast to a Map[${K}, ${V}] first by calling `unsorted`."
196+
197+
/** Specializes `MapWithFilter` for sorted Map collections
198+
*
199+
* @define coll sorted map collection
200+
*/
201+
class WithFilter[K, +V, +IterableCC[_], +MapCC[X, Y] <: Map[X, Y], +CC[X, Y] <: Map[X, Y] with SortedMapOps[X, Y, CC, _]](
202+
self: SortedMapOps[K, V, CC, _] with MapOps[K, V, MapCC, _] with IterableOps[(K, V), IterableCC, _],
203+
p: ((K, V)) => Boolean
204+
) extends MapOps.WithFilter[K, V, IterableCC, MapCC](self, p) {
205+
206+
def map[K2 : Ordering, V2](f: ((K, V)) => (K2, V2)): CC[K2, V2] =
207+
self.sortedMapFactory.from(new View.Map(filtered, f))
208+
209+
def flatMap[K2 : Ordering, V2](f: ((K, V)) => IterableOnce[(K2, V2)]): CC[K2, V2] =
210+
self.sortedMapFactory.from(new View.FlatMap(filtered, f))
211+
212+
override def withFilter(q: ((K, V)) => Boolean): WithFilter[K, V, IterableCC, MapCC, CC] =
213+
new WithFilter[K, V, IterableCC, MapCC, CC](self, (kv: (K, V)) => p(kv) && q(kv))
214+
215+
}
216+
217+
}
218+
219+
@SerialVersionUID(3L)
220+
object SortedMap extends SortedMapFactory.Delegate[SortedMap](immutable.SortedMap)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Scala (https://www.scala-lang.org)
3+
*
4+
* Copyright EPFL and Lightbend, Inc.
5+
*
6+
* Licensed under Apache License 2.0
7+
* (http://www.apache.org/licenses/LICENSE-2.0).
8+
*
9+
* See the NOTICE file distributed with this work for
10+
* additional information regarding copyright ownership.
11+
*/
12+
13+
package scala.collection
14+
15+
import scala.annotation.implicitNotFound
16+
17+
/**
18+
* Trait that overrides sorted map operations to take advantage of strict builders.
19+
*
20+
* @tparam K Type of keys
21+
* @tparam V Type of values
22+
* @tparam CC Collection type constructor
23+
* @tparam C Collection type
24+
*/
25+
trait StrictOptimizedSortedMapOps[K, +V, +CC[X, Y] <: Map[X, Y] with SortedMapOps[X, Y, CC, _], +C <: SortedMapOps[K, V, CC, C]]
26+
extends SortedMapOps[K, V, CC, C]
27+
with StrictOptimizedMapOps[K, V, Map, C] {
28+
29+
override def map[K2, V2](f: ((K, V)) => (K2, V2))(implicit @implicitNotFound(SortedMapOps.ordMsg) ordering: Ordering[K2]): CC[K2, V2] =
30+
strictOptimizedMap(sortedMapFactory.newBuilder, f)
31+
32+
override def flatMap[K2, V2](f: ((K, V)) => IterableOnce[(K2, V2)])(implicit @implicitNotFound(SortedMapOps.ordMsg) ordering: Ordering[K2]): CC[K2, V2] =
33+
strictOptimizedFlatMap(sortedMapFactory.newBuilder, f)
34+
35+
override def concat[V2 >: V](xs: IterableOnce[(K, V2)]): CC[K, V2] =
36+
strictOptimizedConcat(xs, sortedMapFactory.newBuilder(using ordering))
37+
38+
override def collect[K2, V2](pf: PartialFunction[(K, V), (K2, V2)])(implicit @implicitNotFound(SortedMapOps.ordMsg) ordering: Ordering[K2]): CC[K2, V2] =
39+
strictOptimizedCollect(sortedMapFactory.newBuilder, pf)
40+
41+
@deprecated("Use ++ with an explicit collection argument instead of + with varargs", "2.13.0")
42+
override def + [V1 >: V](elem1: (K, V1), elem2: (K, V1), elems: (K, V1)*): CC[K, V1] = {
43+
val m = ((this + elem1).asInstanceOf[Map[K, V]] + elem2).asInstanceOf[CC[K, V1]]
44+
if(elems.isEmpty) m else m.concat(elems).asInstanceOf[CC[K, V1]]
45+
}
46+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* Scala (https://www.scala-lang.org)
3+
*
4+
* Copyright EPFL and Lightbend, Inc.
5+
*
6+
* Licensed under Apache License 2.0
7+
* (http://www.apache.org/licenses/LICENSE-2.0).
8+
*
9+
* See the NOTICE file distributed with this work for
10+
* additional information regarding copyright ownership.
11+
*/
12+
13+
package scala.collection.generic
14+
15+
import java.io.{ObjectInputStream, ObjectOutputStream}
16+
17+
import scala.collection.{Factory, Iterable}
18+
import scala.collection.mutable.Builder
19+
20+
/** The default serialization proxy for collection implementations.
21+
*
22+
* This class is `final` and requires an extra `Factory` object rather than leaving the details of creating a `Builder`
23+
* to an abstract method that could be implemented by a subclass. This is necessary because the factory is needed
24+
* for deserializing this class's private state, which happens before any subclass fields would be deserialized. Any
25+
* additional state required to create the proper `Builder` needs to be captured by the `factory`.
26+
*/
27+
@SerialVersionUID(3L)
28+
final class DefaultSerializationProxy[A](factory: Factory[A, Any], @transient private[this] val coll: Iterable[A]) extends Serializable {
29+
30+
@transient protected var builder: Builder[A, Any] = _
31+
32+
private[this] def writeObject(out: ObjectOutputStream): Unit = {
33+
out.defaultWriteObject()
34+
val k = coll.knownSize
35+
out.writeInt(k)
36+
var count = 0
37+
coll.foreach { x =>
38+
out.writeObject(x)
39+
count += 1
40+
}
41+
if(k >= 0) {
42+
if(count != k) throw new IllegalStateException(s"Illegal size $count of collection, expected $k")
43+
} else out.writeObject(SerializeEnd)
44+
}
45+
46+
private[this] def readObject(in: ObjectInputStream): Unit = {
47+
in.defaultReadObject()
48+
builder = factory.newBuilder
49+
val k = in.readInt()
50+
if(k >= 0) {
51+
builder.sizeHint(k)
52+
var count = 0
53+
while(count < k) {
54+
builder += in.readObject().asInstanceOf[A]
55+
count += 1
56+
}
57+
} else {
58+
while (true) in.readObject match {
59+
case SerializeEnd => return
60+
case a => builder += a.asInstanceOf[A]
61+
}
62+
}
63+
}
64+
65+
protected[this] def readResolve(): Any = builder.result()
66+
}
67+
68+
@SerialVersionUID(3L)
69+
private[collection] case object SerializeEnd
70+
71+
/** Mix-in trait to enable DefaultSerializationProxy for the standard collection types. Depending on the type
72+
* it is mixed into, it will dynamically choose `iterableFactory`, `mapFactory`, `sortedIterableFactory` or
73+
* `sortedMapFactory` for deserialization into the respective `CC` type. Override `writeReplace` or implement
74+
* it directly without using this trait if you need a non-standard factory or if you want to use a different
75+
* serialization scheme.
76+
*/
77+
trait DefaultSerializable extends Serializable { this: scala.collection.Iterable[_] =>
78+
protected[this] def writeReplace(): AnyRef = {
79+
val f: Factory[Any, Any] = this match {
80+
case it: scala.collection.SortedMap[_, _] => it.sortedMapFactory.sortedMapFactory[Any, Any](using it.ordering.asInstanceOf[Ordering[Any]]).asInstanceOf[Factory[Any, Any]]
81+
case it: scala.collection.Map[_, _] => it.mapFactory.mapFactory[Any, Any].asInstanceOf[Factory[Any, Any]]
82+
case it: scala.collection.SortedSet[_] => it.sortedIterableFactory.evidenceIterableFactory[Any](using it.ordering.asInstanceOf[Ordering[Any]])
83+
case it => it.iterableFactory.iterableFactory
84+
}
85+
new DefaultSerializationProxy(f, this)
86+
}
87+
}

0 commit comments

Comments
 (0)