Skip to content

Commit

Permalink
Cross-build
Browse files Browse the repository at this point in the history
  • Loading branch information
som-snytt committed Apr 8, 2024
1 parent 7dbb249 commit 4094ebe
Show file tree
Hide file tree
Showing 13 changed files with 66 additions and 69 deletions.
13 changes: 10 additions & 3 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ThisBuild / scalaVersion := "3.3.3"
ThisBuild / scalaVersion := "3.4.1"
ThisBuild / crossScalaVersions := Seq((ThisBuild / scalaVersion).value, "2.13.13")

lazy val root = project.in(file("."))
Expand All @@ -20,8 +20,15 @@ lazy val collectionContrib = crossProject(JVMPlatform, JSPlatform, NativePlatfor
scalaModuleAutomaticModuleName := Some("scala.collection.contrib"),
Compile / compile / scalacOptions ++= {
CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, _)) => Seq("-opt-warnings", "-Werror", "-Wconf:origin=scala.collection.IterableOps.toIterable:s")
case _ => Seq("-Xfatal-warnings", "-Wconf:cat=deprecation:s")
case Some((2, _)) => Seq(
"-Werror", "-Wconf:origin=scala.collection.IterableOps.toIterable:s",
"-Wopt", "-opt:inline:<sources>",
"-Wnonunit-statement",
"-Wvalue-discard",
"-Xlint",
"-Xsource:3-cross",
)
case _ => Seq("-Werror", "-Wconf:cat=deprecation:s")
}
},
Compile / doc / scalacOptions ++= {
Expand Down
16 changes: 7 additions & 9 deletions src/main/scala/scala/collection/MultiDict.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ trait MultiDict[K, V]
with MultiDictOps[K, V, MultiDict, MultiDict[K, V]]
with Equals {

override protected[this] def className: String = "MultiDict"
override protected def className: String = "MultiDict"

def multiDictFactory: MapFactory[MultiDict] = MultiDict
override protected def fromSpecific(coll: IterableOnce[(K, V)]): MultiDict[K, V] = multiDictFactory.from(coll)
Expand All @@ -26,14 +26,12 @@ trait MultiDict[K, V]
override def equals(o: Any): Boolean = o match {
case that: MultiDict[K @unchecked, _] =>
(this eq that) ||
(that canEqual this) &&
(this.size == that.size) && {
try {
sets forall { case (k, vs) => that.sets.get(k).contains(vs) }
} catch {
that.canEqual(this) &&
this.size == that.size && {
try sets.forall { case (k, vs) => that.sets.get(k).contains(vs) }
catch {
case _: ClassCastException => false
}
}
}}
case _ => false
}

Expand Down Expand Up @@ -205,7 +203,7 @@ trait MultiDictOps[K, V, +CC[X, Y] <: MultiDict[X, Y], +C <: MultiDict[K, V]]
object MultiDictOps {

class WithFilter[K, V, +IterableCC[_], +CC[X, Y] <: MultiDict[X, Y]](
`this`: MultiDictOps[K, V, CC, _] with IterableOps[(K, V), IterableCC, _],
`this`: MultiDictOps[K, V, CC, ?] & IterableOps[(K, V), IterableCC, ?],
p: ((K, V)) => Boolean
) extends IterableOps.WithFilter[(K, V), IterableCC](`this`, p) {

Expand Down
18 changes: 8 additions & 10 deletions src/main/scala/scala/collection/MultiSet.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ trait MultiSet[A]
with MultiSetOps[A, MultiSet, MultiSet[A]]
with Equals {

override protected[this] def className: String = "MultiSet"
override protected def className: String = "MultiSet"

override def iterableFactory: IterableFactory[MultiSet] = MultiSet
override protected def fromSpecific(coll: IterableOnce[A]): MultiSet[A] = iterableFactory.from(coll)
Expand All @@ -24,14 +24,12 @@ trait MultiSet[A]
override def equals(o: Any): Boolean = o match {
case that: MultiSet[A @unchecked] =>
(this eq that) ||
(that canEqual this) &&
(this.size == that.size) && {
try {
occurrences forall { case (elem, n) => that.get(elem) == n }
} catch {
that.canEqual(this) &&
this.size == that.size && {
try occurrences.forall { case (elem, n) => that.get(elem) == n }
catch {
case _: ClassCastException => false
}
}
}}
case _ => false
}

Expand All @@ -42,10 +40,10 @@ trait MultiSet[A]
trait MultiSetOps[A, +CC[X] <: MultiSet[X], +C <: MultiSet[A]]
extends IterableOps[A, CC, C] {

protected[this] def fromSpecificOccurrences(it: Iterable[(A, Int)]): C =
protected def fromSpecificOccurrences(it: Iterable[(A, Int)]): C =
fromSpecific(it.view.flatMap { case (e, n) => new View.Fill(n)(e) })

protected[this] def fromOccurrences[E](it: Iterable[(E, Int)]): CC[E] =
protected def fromOccurrences[E](it: Iterable[(E, Int)]): CC[E] =
// Note new MultiSet(it.to(Map)) would be more efficient but would also loose duplicates
iterableFactory.from(it.view.flatMap { case (e, n) => new View.Fill(n)(e) })

Expand Down
6 changes: 3 additions & 3 deletions src/main/scala/scala/collection/SortedMultiDict.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ trait SortedMultiDictOps[K, V, +CC[X, Y] <: MultiDict[X, Y], +C <: MultiDict[K,

def sortedMultiDictFactory: SortedMapFactory[CC]

protected[this] def sortedFromIterable[L : Ordering, W](it: Iterable[(L, W)]): CC[L, W] = sortedMultiDictFactory.from(it)
protected[this] def sortedFromSets[L : Ordering, W](it: Iterable[(L, Set[W])]): CC[L, W] =
protected def sortedFromIterable[L : Ordering, W](it: Iterable[(L, W)]): CC[L, W] = sortedMultiDictFactory.from(it)
protected def sortedFromSets[L : Ordering, W](it: Iterable[(L, Set[W])]): CC[L, W] =
sortedFromIterable(it.view.flatMap { case (l, ws) => ws.map(w => (l, w)) })

/** `this` sorted multidict upcasted to an unsorted multidict */
Expand Down Expand Up @@ -126,7 +126,7 @@ trait SortedMultiDictOps[K, V, +CC[X, Y] <: MultiDict[X, Y], +C <: MultiDict[K,
object SortedMultiDictOps {

class WithFilter[K, V, +IterableCC[_], +MultiDictCC[X, Y] <: MultiDict[X, Y], +CC[X, Y] <: MultiDict[X, Y]](
`this`: SortedMultiDictOps[K, V, CC, _] with MultiDictOps[K, V, MultiDictCC, _] with IterableOps[(K, V), IterableCC, _],
`this`: SortedMultiDictOps[K, V, CC, ?] & MultiDictOps[K, V, MultiDictCC, ?] & IterableOps[(K, V), IterableCC, ?],
p: ((K, V)) => Boolean
) extends MultiDictOps.WithFilter[K, V, IterableCC, MultiDictCC](`this`, p) {

Expand Down
6 changes: 3 additions & 3 deletions src/main/scala/scala/collection/SortedMultiSet.scala
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ trait SortedMultiSetOps[A, +CC[X] <: MultiSet[X], +C <: MultiSet[A]]
* is the minimum of the lengths of `this` and `that`
*/
def zip[B](that: Iterable[B])(implicit ev: Ordering[B]): CC[(A @uncheckedVariance, B)] = // sound bcs of VarianceNote
sortedFromIterable(new View.Zip(toIterable, that))(Ordering.Tuple2(ordering, implicitly))
sortedFromIterable(new View.Zip(toIterable, that))(using Ordering.Tuple2(ordering, implicitly))

/**
* @return a new collection resulting from applying the given partial
Expand Down Expand Up @@ -147,7 +147,7 @@ trait SortedMultiSetOps[A, +CC[X] <: MultiSet[X], +C <: MultiSet[A]]
// --- Override return type of methods that returned an unsorted MultiSet

override def zipWithIndex: CC[(A, Int)] =
sortedFromIterable(new View.ZipWithIndex(toIterable))(Ordering.Tuple2(ordering, implicitly))
sortedFromIterable(new View.ZipWithIndex(toIterable))(using Ordering.Tuple2(ordering, implicitly))

}

Expand All @@ -158,7 +158,7 @@ object SortedMultiSetOps {
* @define coll sorted collection
*/
class WithFilter[A, +IterableCC[_], +CC[X] <: MultiSet[X]](
`this`: SortedMultiSetOps[A, CC, _] with IterableOps[A, IterableCC, _],
`this`: SortedMultiSetOps[A, CC, ?] & IterableOps[A, IterableCC, ?],
p: A => Boolean
) extends IterableOps.WithFilter[A, IterableCC](`this`, p) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package scala.collection.decorators

import scala.collection.{BitSet, BitSetOps}

class BitSetDecorator[+C <: BitSet with BitSetOps[C]](protected val bs: C) {
class BitSetDecorator[+C <: BitSet & BitSetOps[C]](protected val bs: C) {

import BitSetDecorator._
import BitSetOps._
Expand Down
35 changes: 15 additions & 20 deletions src/main/scala/scala/collection/decorators/IteratorDecorator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package scala.collection
package decorators

import scala.annotation.tailrec
import scala.util.chaining._
import scala.util.control.NonFatal

/** Enriches Iterator with additional methods.
Expand Down Expand Up @@ -188,8 +189,8 @@ class IteratorDecorator[A](val `this`: Iterator[A]) extends AnyVal {
*/
def splitBy[K](f: A => K): Iterator[immutable.Seq[A]] =
new AbstractIterator[immutable.Seq[A]] {
private var hd: A = _
private var hdKey: K = _
private var hd: A = null.asInstanceOf[A] // todo uninitialized
private var hdKey: K = null.asInstanceOf[K] // todo uninitialized
private var hdDefined: Boolean = false

override def hasNext: Boolean = hdDefined || `this`.hasNext
Expand Down Expand Up @@ -240,32 +241,26 @@ class IteratorDecorator[A](val `this`: Iterator[A]) extends AnyVal {
}

/** Gives elements from the source iterator until the source iterator ends or throws a NonFatal exception.
*
* @param exceptionCaught a callback invoked from `hasNext` when the source iterator throws a NonFatal exception
* @return an iterator that takes items until the wrapped iterator ends or throws a NonFatal exception
* @see scala.util.control.NonFatal
* @note Reuse: $consumesAndProducesIterator
*/
def takeUntilException(exceptionCaught: Throwable => Unit): Iterator[A] = {
*
* @param exceptionCaught a callback invoked from `hasNext` when the source iterator throws a NonFatal exception
* @return an iterator that takes items until the wrapped iterator ends or throws a NonFatal exception
* @see scala.util.control.NonFatal
* @note Reuse: $consumesAndProducesIterator
*/
def takeUntilException(exceptionCaught: Throwable => Unit): Iterator[A] =
new AbstractIterator[A] {
private val wrapped = `this`.buffered

override def hasNext: Boolean = {
try {
val n = wrapped.hasNext
// By already invoking `head` (and therefore also `next` on `this`),
// we are sure that `wrapped.next` will not throw when it is used from
// `next`.
if (n) wrapped.head
n
} catch {
override def hasNext: Boolean =
// By already invoking `head` (and therefore also `next` on `this`),
// we are sure that `wrapped.next` will not throw when it is used from `next`.
try wrapped.hasNext.tap(if(_) wrapped.head)
catch {
case NonFatal(t) =>
exceptionCaught(t)
false
}
}

override def next(): A = wrapped.next()
}
}
}
2 changes: 1 addition & 1 deletion src/main/scala/scala/collection/decorators/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ package object decorators {
implicit def mapDecorator[C](coll: C)(implicit map: IsMap[C]): MapDecorator[C, map.type] =
new MapDecorator(coll)(map)

implicit def bitSetDecorator[C <: BitSet with BitSetOps[C]](bs: C): BitSetDecorator[C] =
implicit def bitSetDecorator[C <: BitSet & BitSetOps[C]](bs: C): BitSetDecorator[C] =
new BitSetDecorator(bs)

implicit def mutableBitSetDecorator(bs: mutable.BitSet): MutableBitSetDecorator =
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/scala/collection/decorators/views.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package decorators
/** Views used by decorators */
object View {

type SomeIterableOps[+A] = IterableOps[A, AnyConstr, _]
type SomeIterableOps[+A] = IterableOps[A, AnyConstr, ?]

class Intersperse[A](underlying: SomeIterableOps[A], sep: A) extends View[A] {
def iterator: Iterator[A] = underlying.iterator.intersperse(sep)
Expand All @@ -21,4 +21,4 @@ object View {
else underlying.knownSize
}

}
}
15 changes: 7 additions & 8 deletions src/main/scala/scala/collection/mutable/MultiDict.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ package scala
package collection
package mutable

/**
* A mutable multidict
* @tparam K the type of keys
* @tparam V the type of values
*/
/** A mutable multidict.
* @tparam K the type of keys
* @tparam V the type of values
*/
class MultiDict[K, V] private (elems: Map[K, Set[V]])
extends collection.MultiDict[K, V]
with Iterable[(K, V)]
Expand All @@ -27,7 +26,7 @@ class MultiDict[K, V] private (elems: Map[K, Set[V]])

def addOne(elem: (K, V)): this.type = {
val (k, v) = elem
elems.updateWith(k) {
val _ = elems.updateWith(k) {
case None => Some(Set(v))
case Some(vs) => Some(vs += v)
}
Expand All @@ -36,7 +35,7 @@ class MultiDict[K, V] private (elems: Map[K, Set[V]])

def subtractOne(elem: (K, V)): this.type = {
val (k, v) = elem
elems.updateWith(k) {
val _ = elems.updateWith(k) {
case Some(vs) =>
vs -= v
if (vs.nonEmpty) Some(vs) else None
Expand Down Expand Up @@ -69,4 +68,4 @@ object MultiDict extends MapFactory[MultiDict] {

def newBuilder[K, V]: Builder[(K, V), MultiDict[K, V]] = new GrowableBuilder[(K, V), MultiDict[K, V]](empty)

}
}
6 changes: 3 additions & 3 deletions src/main/scala/scala/collection/mutable/MultiSet.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ class MultiSetImpl[A] private[mutable] (val elems: Map[A, Int]) extends MultiSet
def occurrences: collection.Map[A, Int] = elems

def addOne(elem: A): this.type = {
elems.updateWith(elem) {
val _ = elems.updateWith(elem) {
case None => Some(1)
case Some(n) => Some(n + 1)
}
this
}

def subtractOne(elem: A): this.type = {
elems.updateWith(elem) {
val _ = elems.updateWith(elem) {
case Some(n) => if (n > 1) Some(n - 1) else None
case None => None
}
Expand All @@ -50,4 +50,4 @@ object MultiSet extends IterableFactory[MultiSet] {

def newBuilder[A]: Builder[A, MultiSet[A]] = new GrowableBuilder[A, MultiSet[A]](empty)

}
}
6 changes: 3 additions & 3 deletions src/main/scala/scala/collection/mutable/SortedMultiDict.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class SortedMultiDict[K, V] private (elems: SortedMap[K, Set[V]])(implicit val o

def addOne(elem: (K, V)): this.type = {
val (k, v) = elem
elems.updateWith(k) {
val _ = elems.updateWith(k) {
case None => Some(Set(v))
case Some(vs) => Some(vs += v)
}
Expand All @@ -40,7 +40,7 @@ class SortedMultiDict[K, V] private (elems: SortedMap[K, Set[V]])(implicit val o

def subtractOne(elem: (K, V)): this.type = {
val (k, v) = elem
elems.updateWith(k) {
val _ = elems.updateWith(k) {
case Some(vs) =>
vs -= v
if (vs.nonEmpty) Some(vs) else None
Expand Down Expand Up @@ -76,4 +76,4 @@ object SortedMultiDict extends SortedMapFactory[SortedMultiDict] {
def newBuilder[K: Ordering, V]: Builder[(K, V), SortedMultiDict[K, V]] =
new GrowableBuilder[(K, V), SortedMultiDict[K, V]](empty)

}
}
6 changes: 3 additions & 3 deletions src/main/scala/scala/collection/mutable/SortedMultiSet.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ class SortedMultiSet[A] private (elems: SortedMap[A, Int])(implicit val ordering
new SortedMultiSet(elems.rangeImpl(from, until))

def addOne(elem: A): this.type = {
elems.updateWith(elem) {
val _ = elems.updateWith(elem) {
case None => Some(1)
case Some(n) => Some(n + 1)
}
this
}

def subtractOne(elem: A): this.type = {
elems.updateWith(elem) {
val _ = elems.updateWith(elem) {
case Some(n) => if (n > 1) Some(n - 1) else None
case None => None
}
Expand All @@ -54,4 +54,4 @@ object SortedMultiSet extends SortedIterableFactory[SortedMultiSet] {

def newBuilder[A: Ordering]: Builder[A, SortedMultiSet[A]] = new GrowableBuilder[A, SortedMultiSet[A]](empty)

}
}

0 comments on commit 4094ebe

Please sign in to comment.