Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: scala/scala-collection-compat
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v2.7.0
Choose a base ref
...
head repository: scala/scala-collection-compat
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v2.8.0
Choose a head ref

Commits on Mar 22, 2022

  1. add mailmap entry

    SethTisue committed Mar 22, 2022
    Copy the full SHA
    18cea32 View commit details

Commits on Mar 25, 2022

  1. Copy the full SHA
    e8494ab View commit details

Commits on Apr 4, 2022

  1. Verified

    This commit was signed with the committer’s verified signature.
    scala-steward Scala Steward
    Copy the full SHA
    0380bfa View commit details

Commits on Apr 12, 2022

  1. Verified

    This commit was signed with the committer’s verified signature.
    scala-steward Scala Steward
    Copy the full SHA
    4e75e4c View commit details

Commits on Apr 21, 2022

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    d8a362e View commit details
  2. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    b856f36 View commit details

Commits on May 19, 2022

  1. Copy the full SHA
    966617f View commit details

Commits on Jun 1, 2022

  1. Copy the full SHA
    68b1746 View commit details

Commits on Jun 2, 2022

  1. Merge pull request #534 from ryan-johnson-databricks/Iterator.nextOption

    Add Iterator.nextOption
    julienrf authored Jun 2, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    f7718aa View commit details

Commits on Jun 3, 2022

  1. Copy the full SHA
    171c6f0 View commit details
  2. Copy the full SHA
    a8f0e76 View commit details

Commits on Jun 28, 2022

  1. Verified

    This commit was signed with the committer’s verified signature.
    scala-steward Scala Steward
    Copy the full SHA
    7577fb9 View commit details

Commits on Jul 4, 2022

  1. Unverified

    This user has not yet uploaded their public signing key.
    Copy the full SHA
    44af94a View commit details
  2. Unverified

    This user has not yet uploaded their public signing key.
    Copy the full SHA
    96a4b8c View commit details
  3. formatting

    pedorich-n committed Jul 4, 2022

    Unverified

    This user has not yet uploaded their public signing key.
    Copy the full SHA
    54bce29 View commit details
  4. Rename self to fact

    pedorich-n committed Jul 4, 2022

    Unverified

    This user has not yet uploaded their public signing key.
    Copy the full SHA
    ed5116d View commit details

Commits on Jul 5, 2022

  1. Copy the full SHA
    cf398c8 View commit details

Commits on Jul 7, 2022

  1. Merge pull request #533 from haukeh/backport-optionconverters

    Backport scala.jdk.OptionConverters to 2.11 / 2.12
    lrytz authored Jul 7, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    7a1171d View commit details
  2. Merge pull request #541 from pedorich-n/option-companion-object-methods

    Option.when and Option.unless added
    lrytz authored Jul 7, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    3dcd0ae View commit details

Commits on Jul 8, 2022

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    05524d8 View commit details
  2. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    b7b0c0e View commit details
  3. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    11aace1 View commit details
  4. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    33feb8d View commit details
  5. GitHub Actions config: avoid duplicating Scala version numbers (#546)

    by using new sbt 1.7 feature
    SethTisue authored Jul 8, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    d77167d View commit details
  6. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    75c999f View commit details
  7. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    a6d5f2f View commit details
38 changes: 18 additions & 20 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -11,45 +11,43 @@ jobs:
fail-fast: false
matrix:
java: [8, 11, 17]
scala: [2.11.12, 2.12.15, 2.13.8, 3.0.2]
platform: [jvm, js, native]
scala: [2.11.x, 2.12.x, 2.13.x, 3.x]
platform: [JVM, JS, Native]
mode: [normal]
exclude:
- scala: 3.0.2
platform: native
- java: 11
platform: js
platform: JS
- java: 11
platform: native
platform: Native
- java: 17
platform: js
platform: JS
- java: 17
platform: native
platform: Native
include:
- java: 8
scala: 2.12.15
scala: 2.12.x
mode: testScalafix
platform: jvm
platform: JVM
- java: 8
scala: 2.12.15
scala: 2.12.x
mode: testBinaryCompat
platform: jvm
platform: JVM
- java: 8
scala: 2.12.15
scala: 2.12.x
mode: testScalafmt
platform: jvm
platform: JVM
- java: 8
scala: 2.12.15
scala: 2.12.x
mode: headerCheck
platform: jvm
platform: JVM
- java: 11
scala: 2.12.15
scala: 2.12.x
mode: normal
platform: jvm
platform: JVM
- java: 17
scala: 2.12.15
scala: 2.12.x
mode: normal
platform: jvm
platform: JVM
runs-on: ubuntu-latest
env:
CI_JDK: ${{matrix.java}}
2 changes: 2 additions & 0 deletions .mailmap
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
NthPortal <7505383+NthPortal@users.noreply.github.com>
NthPortal <nthportal@gmail.com>
Ethan Bell <ethan@thatdot.com>
Ethan Bell <ebgamer29@gmail.com>
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -49,7 +49,7 @@ And, it includes support for some non-collections classes such as the `@nowarn`

## Migration rules

The migration rules use scalafix. Please see the [official installation instructions](https://scalacenter.github.io/scalafix/docs/users/installation.html) and, in particular, check that your full Scala version is supported (ex 2.12.15).
The migration rules use scalafix. Please see the [official installation instructions](https://scalacenter.github.io/scalafix/docs/users/installation.html) and, in particular, check that your full Scala version is supported (ex 2.12.16).

```scala
// project/plugins.sbt
61 changes: 42 additions & 19 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -30,9 +30,9 @@ lazy val root = project
compat213JVM,
compat213JS,
compat213Native,
compat30JVM,
compat30JS,
compat31Native,
compat3JVM,
compat3JS,
compat3Native,
scalafixData211,
scalafixData212,
scalafixData213,
@@ -51,10 +51,9 @@ lazy val root = project
lazy val junit = libraryDependencies += "com.github.sbt" % "junit-interface" % "0.13.3" % Test

lazy val scala211 = "2.11.12"
lazy val scala212 = "2.12.15"
lazy val scala212 = "2.12.16"
lazy val scala213 = "2.13.8"
lazy val scala30 = "3.0.2"
lazy val scala31 = "3.1.1"
lazy val scala3 = "3.1.3"

lazy val compat = new MultiScalaCrossProject(
"compat",
@@ -91,11 +90,20 @@ lazy val compat = new MultiScalaCrossProject(
exclude[ReversedMissingMethodProblem]("scala.collection.compat.PackageShared.*"), // it's package-private
exclude[Problem]("scala.collection.compat.*PreservingBuilder*")
)
},
}
)
.jvmSettings(
Test / unmanagedSourceDirectories += (ThisBuild / baseDirectory).value / "compat/src/test/scala-jvm",
junit,
Compile / unmanagedSourceDirectories += {
val jvmParent = (ThisBuild / baseDirectory).value / "compat/jvm/src/main"
CrossVersion.partialVersion(scalaVersion.value) match {
case Some((3, _) | (2, 13)) =>
jvmParent / "scala-2.13"
case _ =>
jvmParent / "scala-2.11_2.12"
}
},
junit
)
.disablePlugins(ScalafixPlugin),
_.jsSettings(
@@ -111,6 +119,16 @@ lazy val compat = new MultiScalaCrossProject(
}
Seq(s"$opt:$x->$y/")
},
Test / unmanagedSourceDirectories += (ThisBuild / baseDirectory).value / "compat/src/test/scala-js",
Compile / unmanagedSourceDirectories += {
val jsAndNativeSourcesParent = (ThisBuild / baseDirectory).value / "compat/jsNative/src/main"
CrossVersion.partialVersion(scalaVersion.value) match {
case Some((3, _) | (2, 13)) =>
jsAndNativeSourcesParent / "scala-2.13"
case _ =>
jsAndNativeSourcesParent / "scala-2.11_2.12"
}
},
Test / fork := false // Scala.js cannot run forked tests
).jsEnablePlugins(ScalaJSJUnitPlugin),
_.nativeSettings(
@@ -122,6 +140,15 @@ lazy val compat = new MultiScalaCrossProject(
case Some((3, 1)) => mimaPreviousArtifacts.value.filter(_.revision != "2.6.0")
case _ => mimaPreviousArtifacts.value
}),
Compile / unmanagedSourceDirectories += {
val jsAndNativeSourcesParent = (ThisBuild / baseDirectory).value / "compat/jsNative/src/main"
CrossVersion.partialVersion(scalaVersion.value) match {
case Some((3, _) | (2, 13)) =>
jsAndNativeSourcesParent / "scala-2.13"
case _ =>
jsAndNativeSourcesParent / "scala-2.11_2.12"
}
},
libraryDependencies += "org.scala-native" %%% "junit-runtime" % nativeVersion,
Test / fork := false // Scala Native cannot run forked tests
)
@@ -130,8 +157,7 @@ lazy val compat = new MultiScalaCrossProject(
val compat211 = compat(Seq(JSPlatform, JVMPlatform, NativePlatform), scala211)
val compat212 = compat(Seq(JSPlatform, JVMPlatform, NativePlatform), scala212)
val compat213 = compat(Seq(JSPlatform, JVMPlatform, NativePlatform), scala213)
val compat30 = compat(Seq(JSPlatform, JVMPlatform), scala30)
val compat31 = compat(Seq(JVMPlatform, NativePlatform), scala31)
val compat3 = compat(Seq(JSPlatform, JVMPlatform, NativePlatform), scala3)

lazy val compat211JVM = compat211.jvm
lazy val compat211JS = compat211.js
@@ -142,9 +168,9 @@ lazy val compat212Native = compat212.native
lazy val compat213JVM = compat213.jvm
lazy val compat213JS = compat213.js
lazy val compat213Native = compat213.native
lazy val compat30JVM = compat30.jvm
lazy val compat30JS = compat30.js
lazy val compat31Native = compat31.native
lazy val compat3JVM = compat3.jvm
lazy val compat3JS = compat3.js
lazy val compat3Native = compat3.native

lazy val binaryCompatOld = project
.in(file("binary-compat/old"))
@@ -307,8 +333,7 @@ lazy val scalafixTests = project
.enablePlugins(BuildInfoPlugin, ScalafixTestkitPlugin)

val ciScalaVersion = sys.env.get("CI_SCALA_VERSION").flatMap(Version.parse)
val isScalaJs = sys.env.get("CI_PLATFORM") == Some("js")
val isScalaNative = sys.env.get("CI_PLATFORM") == Some("native")
val ciPlatform = sys.env.get("CI_PLATFORM").map(p => if (p == "JVM") "" else p)
val isScalafix = sys.env.get("CI_MODE") == Some("testScalafix")
val isScalafmt = sys.env.get("CI_MODE") == Some("testScalafmt")
val isBinaryCompat = sys.env.get("CI_MODE") == Some("testBinaryCompat")
@@ -342,9 +367,7 @@ inThisBuild {
).foreach(k =>
println(k.padTo(20, " ").mkString("") + " -> " + sys.env.getOrElse(k, "None")))

val platformSuffix = if (isScalaJs) "JS" else if (isScalaNative) "Native" else ""

val compatProject = "compat" + ciScalaVersion.get.binary + platformSuffix
val compatProject = s"compat${ciScalaVersion.get}${ciPlatform.get}"
val binaryCompatProject = "binaryCompat"

val testProjectPrefix =
@@ -366,7 +389,7 @@ inThisBuild {
}

Seq(
List(s"""++${sys.env.get("CI_SCALA_VERSION").get}!"""),
List(s"""++${sys.env.get("CI_SCALA_VERSION").get}"""),
List(s"$projectPrefix/clean"),
List(s"$testProjectPrefix/test"),
List(s"$projectPrefix/publishLocal"),
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Scala (https://www.scala-lang.org)
*
* Copyright EPFL and Lightbend, Inc.
*
* Licensed under Apache License 2.0
* (http://www.apache.org/licenses/LICENSE-2.0).
*
* See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*/

package scala.jdk

import java.util.Optional

/** This object provides extension methods that convert between Scala `Option` and Java `Optional`
* types.
*
* It differs from the JVM version as in it does not provide any conversions for the Optional primitive type
* wrappers which are available in the JDK but not in Scala-JS or Scala-Native.
*
* Scala `Option` is extended with a `toJava` method that creates a corresponding `Optional`.
*
* Java `Optional` is extended with a `toScala` method.
*
*
* Example usage:
*
* {{{
* import scala.jdk.OptionConverters._
* val a = Option("example").toJava // Creates java.util.Optional[String] containing "example"
* val b = (None: Option[String]).toJava // Creates an empty java.util.Optional[String]
* val c = a.toScala // Back to Option("example")
* val d = b.toScala // Back to None typed as Option[String]
* }}}
*/
object OptionConverters {

/** Provides conversions from Java `Optional` to Scala `Option` and specialized `Optional` types */
implicit class RichOptional[A](private val o: java.util.Optional[A]) extends AnyVal {

/** Convert a Java `Optional` to a Scala `Option` */
def toScala: Option[A] = if (o.isPresent) Some(o.get) else None

/** Convert a Java `Optional` to a Scala `Option` */
@deprecated("Use `toScala` instead", "2.13.0")
def asScala: Option[A] = if (o.isPresent) Some(o.get) else None
}

/** Provides conversions from Scala `Option` to Java `Optional` types */
implicit class RichOption[A](private val o: Option[A]) extends AnyVal {

/** Convert a Scala `Option` to a generic Java `Optional` */
def toJava: Optional[A] = o match {
case Some(a) => Optional.ofNullable(a); case _ => Optional.empty[A]
}

/** Convert a Scala `Option` to a generic Java `Optional` */
@deprecated("Use `toJava` instead", "2.13.0")
def asJava: Optional[A] = o match {
case Some(a) => Optional.ofNullable(a); case _ => Optional.empty[A]
}
}
}
121 changes: 121 additions & 0 deletions compat/jvm/src/main/scala-2.11_2.12/scala/jdk/OptionConverters.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
* Scala (https://www.scala-lang.org)
*
* Copyright EPFL and Lightbend, Inc.
*
* Licensed under Apache License 2.0
* (http://www.apache.org/licenses/LICENSE-2.0).
*
* See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*/

package scala.jdk

import java.util.{Optional, OptionalDouble, OptionalInt, OptionalLong}

/** This object provides extension methods that convert between Scala `Option` and Java `Optional`
* types.
*
* Scala `Option` is extended with a `toJava` method that creates a corresponding `Optional`, and
* a `toJavaPrimitive` method that creates a specialized variant (e.g., `OptionalInt`) if
* applicable.
*
* Java `Optional` is extended with a `toScala` method and a `toJavaPrimitive` method.
*
* Finally, specialized `Optional` types are extended with `toScala` and `toJavaGeneric` methods.
*
* Example usage:
*
* {{{
* import scala.jdk.OptionConverters._
* val a = Option("example").toJava // Creates java.util.Optional[String] containing "example"
* val b = (None: Option[String]).toJava // Creates an empty java.util.Optional[String]
* val c = a.toScala // Back to Option("example")
* val d = b.toScala // Back to None typed as Option[String]
* val e = Option(2.7).toJava // java.util.Optional[Double] containing boxed 2.7
* val f = Option(2.7).toJavaPrimitive // java.util.OptionalDouble containing 2.7 (not boxed)
* val g = f.toScala // Back to Option(2.7)
* val h = f.toJavaGeneric // Same as e
* val i = e.toJavaPrimitive // Same as f
* }}}
*/
object OptionConverters {

/** Provides conversions from Java `Optional` to Scala `Option` and specialized `Optional` types */
implicit class RichOptional[A](private val o: java.util.Optional[A]) extends AnyVal {

/** Convert a Java `Optional` to a Scala `Option` */
def toScala: Option[A] = if (o.isPresent) Some(o.get) else None

/** Convert a Java `Optional` to a Scala `Option` */
@deprecated("Use `toScala` instead", "2.13.0")
def asScala: Option[A] = if (o.isPresent) Some(o.get) else None

/** Convert a generic Java `Optional` to a specialized variant */
def toJavaPrimitive[O](implicit shape: OptionShape[A, O]): O = shape.fromJava(o)
}

/** Provides conversions from Scala `Option` to Java `Optional` types */
implicit class RichOption[A](private val o: Option[A]) extends AnyVal {

/** Convert a Scala `Option` to a generic Java `Optional` */
def toJava: Optional[A] = o match {
case Some(a) => Optional.ofNullable(a); case _ => Optional.empty[A]
}

/** Convert a Scala `Option` to a generic Java `Optional` */
@deprecated("Use `toJava` instead", "2.13.0")
def asJava: Optional[A] = o match {
case Some(a) => Optional.ofNullable(a); case _ => Optional.empty[A]
}

/** Convert a Scala `Option` to a specialized Java `Optional` */
def toJavaPrimitive[O](implicit shape: OptionShape[A, O]): O = shape.fromScala(o)
}

/** Provides conversions from `OptionalDouble` to Scala `Option` and the generic `Optional` */
implicit class RichOptionalDouble(private val o: OptionalDouble) extends AnyVal {

/** Convert a Java `OptionalDouble` to a Scala `Option` */
def toScala: Option[Double] = if (o.isPresent) Some(o.getAsDouble) else None

/** Convert a Java `OptionalDouble` to a Scala `Option` */
@deprecated("Use `toScala` instead", "2.13.0")
def asScala: Option[Double] = if (o.isPresent) Some(o.getAsDouble) else None

/** Convert a Java `OptionalDouble` to a generic Java `Optional` */
def toJavaGeneric: Optional[Double] =
if (o.isPresent) Optional.of(o.getAsDouble) else Optional.empty[Double]
}

/** Provides conversions from `OptionalInt` to Scala `Option` and the generic `Optional` */
implicit class RichOptionalInt(private val o: OptionalInt) extends AnyVal {

/** Convert a Java `OptionalInt` to a Scala `Option` */
def toScala: Option[Int] = if (o.isPresent) Some(o.getAsInt) else None

/** Convert a Java `OptionalInt` to a Scala `Option` */
@deprecated("Use `toScala` instead", "2.13.0")
def asScala: Option[Int] = if (o.isPresent) Some(o.getAsInt) else None

/** Convert a Java `OptionalInt` to a generic Java `Optional` */
def toJavaGeneric: Optional[Int] =
if (o.isPresent) Optional.of(o.getAsInt) else Optional.empty[Int]
}

/** Provides conversions from `OptionalLong` to Scala `Option` and the generic `Optional` */
implicit class RichOptionalLong(private val o: OptionalLong) extends AnyVal {

/** Convert a Java `OptionalLong` to a Scala `Option` */
def toScala: Option[Long] = if (o.isPresent) Some(o.getAsLong) else None

/** Convert a Java `OptionalLong` to a Scala `Option` */
@deprecated("Use `toScala` instead", "2.13.0")
def asScala: Option[Long] = if (o.isPresent) Some(o.getAsLong) else None

/** Convert a Java `OptionalLong` to a generic Java `Optional` */
def toJavaGeneric: Optional[Long] =
if (o.isPresent) Optional.of(o.getAsLong) else Optional.empty[Long]
}
}
74 changes: 74 additions & 0 deletions compat/jvm/src/main/scala-2.11_2.12/scala/jdk/OptionShape.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Scala (https://www.scala-lang.org)
*
* Copyright EPFL and Lightbend, Inc.
*
* Licensed under Apache License 2.0
* (http://www.apache.org/licenses/LICENSE-2.0).
*
* See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*/

package scala.jdk

import java.util.{Optional, OptionalDouble, OptionalInt, OptionalLong}
import java.{lang => jl}

import scala.annotation.implicitNotFound

/** A type class implementing conversions from a generic Scala `Option` or Java `Optional` to
* a specialized Java variant (for `Double`, `Int` and `Long`).
*
* @tparam A the primitive type wrapped in an option
* @tparam O the specialized Java `Optional` wrapping an element of type `A`
*/
@implicitNotFound("No specialized Optional type exists for elements of type ${A}")
sealed abstract class OptionShape[A, O] {

/** Converts from `Optional` to the specialized variant `O` */
def fromJava(o: Optional[A]): O

/** Converts from `Option` to the specialized variant `O` */
def fromScala(o: Option[A]): O
}

object OptionShape {
implicit val doubleOptionShape: OptionShape[Double, OptionalDouble] =
new OptionShape[Double, OptionalDouble] {
def fromJava(o: Optional[Double]): OptionalDouble =
if (o.isPresent) OptionalDouble.of(o.get) else OptionalDouble.empty

def fromScala(o: Option[Double]): OptionalDouble = o match {
case Some(d) => OptionalDouble.of(d)
case _ => OptionalDouble.empty
}
}
implicit val jDoubleOptionShape: OptionShape[jl.Double, OptionalDouble] =
doubleOptionShape.asInstanceOf[OptionShape[jl.Double, OptionalDouble]]

implicit val intOptionShape: OptionShape[Int, OptionalInt] = new OptionShape[Int, OptionalInt] {
def fromJava(o: Optional[Int]): OptionalInt =
if (o.isPresent) OptionalInt.of(o.get) else OptionalInt.empty

def fromScala(o: Option[Int]): OptionalInt = o match {
case Some(d) => OptionalInt.of(d)
case _ => OptionalInt.empty
}
}
implicit val jIntegerOptionShape: OptionShape[jl.Integer, OptionalInt] =
intOptionShape.asInstanceOf[OptionShape[jl.Integer, OptionalInt]]

implicit val longOptionShape: OptionShape[Long, OptionalLong] =
new OptionShape[Long, OptionalLong] {
def fromJava(o: Optional[Long]): OptionalLong =
if (o.isPresent) OptionalLong.of(o.get) else OptionalLong.empty

def fromScala(o: Option[Long]): OptionalLong = o match {
case Some(d) => OptionalLong.of(d)
case _ => OptionalLong.empty
}
}
implicit val jLongOptionShape: OptionShape[jl.Long, OptionalLong] =
longOptionShape.asInstanceOf[OptionShape[jl.Long, OptionalLong]]
}
Original file line number Diff line number Diff line change
@@ -282,6 +282,9 @@ private[compat] trait PackageShared {
implicit def toMapViewExtensionMethods[K, V, C <: scala.collection.Map[K, V]](
self: IterableView[(K, V), C]): MapViewExtensionMethods[K, V, C] =
new MapViewExtensionMethods[K, V, C](self)

implicit def toOptionCompanionExtension(fact: Option.type): OptionCompanionExtensionMethods =
new OptionCompanionExtensionMethods(fact)
}

class ImmutableSortedMapExtensions(private val fact: i.SortedMap.type) extends AnyVal {
@@ -348,6 +351,9 @@ class IteratorExtensionMethods[A](private val self: c.Iterator[A]) extends AnyVa
def sameElements[B >: A](that: c.TraversableOnce[B]): Boolean = {
self.sameElements(that.iterator)
}
def nextOption(): Option[A] = {
if (self.hasNext) Some(self.next()) else None
}
def concat[B >: A](that: c.TraversableOnce[B]): c.TraversableOnce[B] = self ++ that
def tapEach[U](f: A => U): c.Iterator[A] = self.map(a => { f(a); a })
}
@@ -584,3 +590,9 @@ class MutableQueueExtensionMethods[Element](private val self: m.Queue[Element])
def enqueueAll(iter: c.Iterable[Element]): Unit =
self.enqueue(iter.toIndexedSeq: _*)
}

class OptionCompanionExtensionMethods(private val fact: Option.type) extends AnyVal {
def when[A](cond: Boolean)(a: => A): Option[A] = if (cond) Some(a) else None

@inline def unless[A](cond: Boolean)(a: => A): Option[A] = when(!cond)(a)
}
55 changes: 55 additions & 0 deletions compat/src/test/scala-js/test/scala/jdk/OptionConvertersTest.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package test.scala.jdk

import org.junit.Assert.assertEquals
import org.junit.Test

import java.util.Optional
import scala.jdk.OptionConverters._

/**
* The tests were copied from the Scala 2.13 Standard Library. `scala.jdk.javaapi` stuff has been omitted and
* everything concerning `OptionalInt`, `OptionalDouble` and `OptionalLong` is only available in the jvm tests.
*
* See https://github.com/scala/scala/blob/2.13.x/test/junit/scala/jdk/OptionConvertersTest.scala.
*/
class OptionConvertersTest {
@Test
def scalaToEverything(): Unit = {
val o = Option("fish")
val n = None: Option[String]
val od = Option(2.7)
val nd = None: Option[Double]
val oi = Option(4)
val ni = None: Option[Int]
val ol = Option(-1L)
val nl = None: Option[Long]
assertEquals(o.toJava, Optional.of(o.get))
assertEquals(n.toJava, Optional.empty[String])
assertEquals(od.toJava.get: Double, Optional.of(od.get).get: Double, 0)
assertEquals(nd.toJava, Optional.empty[Double])
assertEquals(oi.toJava.get: Int, Optional.of(oi.get).get: Int)
assertEquals(ni.toJava, Optional.empty[Int])
assertEquals(ol.toJava.get: Long, Optional.of(ol.get).get: Long)
assertEquals(nl.toJava, Optional.empty[Long])
}

@Test
def javaGenericToEverything(): Unit = {
val o = Optional.of("fish")
val n = Optional.empty[String]
val od = Optional.of(2.7)
val nd = Optional.empty[Double]
val oi = Optional.of(4)
val ni = Optional.empty[Int]
val ol = Optional.of(-1L)
val nl = Optional.empty[Long]
assertEquals(o.toScala, Option(o.get))
assertEquals(n.toScala, Option.empty[String])
assertEquals(od.toScala, Option(od.get))
assertEquals(nd.toScala, Option.empty[Double])
assertEquals(oi.toScala, Option(oi.get))
assertEquals(ni.toScala, Option.empty[Int])
assertEquals(ol.toScala, Option(ol.get))
assertEquals(nl.toScala, Option.empty[Long])
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package test.scala.jdk

import org.junit.Assert.assertEquals
import org.junit.Test

import java.util._
import scala.jdk.OptionConverters._

/**
* The tests were copied from the Scala 2.13 Standard Library. `scala.jdk.javaapi` stuff has been omitted.
*
* See https://github.com/scala/scala/blob/2.13.x/test/junit/scala/jdk/OptionConvertersTest.scala.
*/
class OptionConvertersJVMTest {
@Test
def scalaToEverything(): Unit = {
val o = Option("fish")
val n = (None: Option[String])
val od = Option(2.7)
val nd = (None: Option[Double])

val oi = Option(4)
val ni = (None: Option[Int])
val ol = Option(-1L)
val nl = (None: Option[Long])
assertEquals(o.toJava, Optional.of(o.get))
assertEquals(n.toJava, Optional.empty[String])
assertEquals(od.toJava.get: Double, Optional.of(od.get).get: Double, 0)
assertEquals(nd.toJava, Optional.empty[Double])
assertEquals(od.toJavaPrimitive, OptionalDouble.of(od.get))
assertEquals(nd.toJavaPrimitive, OptionalDouble.empty)
assertEquals(oi.toJava.get: Int, Optional.of(oi.get).get: Int)
assertEquals(ni.toJava, Optional.empty[Int])
assertEquals(oi.toJavaPrimitive, OptionalInt.of(oi.get))
assertEquals(ni.toJavaPrimitive, OptionalInt.empty)
assertEquals(ol.toJava.get: Long, Optional.of(ol.get).get: Long)
assertEquals(nl.toJava, Optional.empty[Long])
assertEquals(ol.toJavaPrimitive, OptionalLong.of(ol.get))
assertEquals(nl.toJavaPrimitive, OptionalLong.empty)
}

@Test
def javaGenericToEverything(): Unit = {
val o = Optional.of("fish")
val n = Optional.empty[String]
val od = Optional.of(2.7)
val nd = Optional.empty[Double]
val oi = Optional.of(4)
val ni = Optional.empty[Int]
val ol = Optional.of(-1L)
val nl = Optional.empty[Long]
assertEquals(o.toScala, Option(o.get))
assertEquals(n.toScala, Option.empty[String])
assertEquals(od.toScala, Option(od.get))
assertEquals(nd.toScala, Option.empty[Double])
assertEquals(od.toJavaPrimitive, OptionalDouble.of(od.get))
assertEquals(nd.toJavaPrimitive, OptionalDouble.empty)
assertEquals(oi.toScala, Option(oi.get))
assertEquals(ni.toScala, Option.empty[Int])
assertEquals(oi.toJavaPrimitive, OptionalInt.of(oi.get))
assertEquals(ni.toJavaPrimitive, OptionalInt.empty)
assertEquals(ol.toScala, Option(ol.get))
assertEquals(nl.toScala, Option.empty[Long])
assertEquals(ol.toJavaPrimitive, OptionalLong.of(ol.get))
assertEquals(nl.toJavaPrimitive, OptionalLong.empty)
}

@Test
def javaOptionalDoubleToEverything(): Unit = {
val o = OptionalDouble.of(2.7)
val n = OptionalDouble.empty
assertEquals(o.toScala, Option(o.getAsDouble))
assertEquals(o.toJavaGeneric.get: Double, Optional.of(o.getAsDouble).get: Double, 0)
assertEquals(n.toScala, None: Option[Double])
assertEquals(n.toJavaGeneric, Optional.empty[Double])
}

@Test
def javaOptionalIntToEverything(): Unit = {
val o = OptionalInt.of(4)
val n = OptionalInt.empty
assertEquals(o.toScala, Option(o.getAsInt))
assertEquals(o.toJavaGeneric.get: Int, Optional.of(o.getAsInt).get: Int)
assertEquals(n.toScala, None: Option[Int])
assertEquals(n.toJavaGeneric, Optional.empty[Int])
}

@Test
def javaOptionalLongToEverything(): Unit = {
val o = OptionalLong.of(-1)
val n = OptionalLong.empty
assertEquals(o.toScala, Option(o.getAsLong))
assertEquals(o.toJavaGeneric.get: Long, Optional.of(o.getAsLong).get: Long)
assertEquals(n.toScala, None: Option[Long])
assertEquals(n.toJavaGeneric, Optional.empty[Long])
}
}
Original file line number Diff line number Diff line change
@@ -114,6 +114,14 @@ class CollectionTest {
assertEquals((Seq("bar", "baz"), Seq("foo".length, "test".length)), res)
}

@Test
def nextOption(): Unit = {
val it = Iterator(1, 2)
assertEquals(Some(1), it.nextOption())
assertEquals(Some(2), it.nextOption())
assertEquals(None, it.nextOption())
}

@Test
def tapEach(): Unit = {
var count = 0
48 changes: 48 additions & 0 deletions compat/src/test/scala/test/scala/collection/OptionTest.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Scala (https://www.scala-lang.org)
*
* Copyright EPFL and Lightbend, Inc.
*
* Licensed under Apache License 2.0
* (http://www.apache.org/licenses/LICENSE-2.0).
*
* See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*/

package test.scala.collection

import scala.collection.compat._
import org.junit.Test
import org.junit.Assert._

class OptionTest {

private val value: String = "example"
private val some: Option[String] = Some(value)
private val none: Option[String] = None

@Test
def testWhenTrue: Unit = {
val option = Option.when(true)(value)
assertEquals(option, some)
}

@Test
def testWhenFalse: Unit = {
val option = Option.when(false)(value)
assertEquals(option, none)
}

@Test
def testUnlessTrue: Unit = {
val option = Option.unless(true)(value)
assertEquals(option, none)
}

@Test
def testUnlessFalse: Unit = {
val option = Option.unless(false)(value)
assertEquals(option, some)
}
}
9 changes: 6 additions & 3 deletions project/MultiScalaProject.scala
Original file line number Diff line number Diff line change
@@ -21,16 +21,19 @@ import java.io.File
* _.settings(...) // Project => Project (scala version independent configurations)
* )
*
* // instanciate a sbt project
* // instantiate a sbt project
* lazy val myProject211 = myProject("2.11.12", _.settings(...) /* scala version dependent configurations */)
* lazy val myProject212 = myProject("2.12.14" , _.settings(...))
* lazy val myProject212 = myProject("2.12.16" , _.settings(...))
* // ...
* }}}
*/
trait MultiScala {
def majorMinor(in: String): String = {
val Array(major, minor, _) = in.split("\\.")
major + minor
if (major == "2")
s"$major$minor"
else
major
}

def projectIdPerScala(name: String, scalaV: String): String = s"$name${majorMinor(scalaV)}"
31 changes: 13 additions & 18 deletions project/Version.scala
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
case class Version(major: Int, minor: Int, patch: Int) {
def binary: String = s"${major}${minor}"
override def toString: String = s"${major}.${minor}.${patch}"
}

object Version {
// the (#.+)? part allows republishing for a new Scala version
private val versionRegex0 = "v?([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:#.+)?".r
private val versionRegex1 = "v?([0-9]+)\\.([0-9]+)\\.([0-9]+)-(.+)(?:#.+)?".r
private val versionRegex2 = "([0-9]+)\\.([0-9]+)(?:#.+)?".r
private val versionRegex3 = "([0-9]+)(?:#.+)?".r
def parse(raw: String): Option[Version] = {
// `(#.+)?` allows republishing for a new Scala version
// `|x` allows the sbt 1.7 style ".x" versions
private val versionRegex0 = "v?([0-9]+)\\.([0-9]+)\\.([0-9]+|x)(?:#.+)?".r
private val versionRegex1 = "v?([0-9]+)\\.([0-9]+)\\.([0-9]+|x)-(.+)(?:#.+)?".r
private val versionRegex2 = "([0-9]+)\\.([0-9]+|x)(?:#.+)?".r
def parse(raw: String): Option[String] = {
raw match {
case versionRegex0(major, minor, patch) =>
Some(Version(major.toInt, minor.toInt, patch.toInt))
case versionRegex1(major, minor, patch, _) =>
Some(Version(major.toInt, minor.toInt, patch.toInt))
case versionRegex0(major, minor, _) =>
Some(s"${major.toInt}${minor.toInt}")
case versionRegex1(major, minor, _, _) =>
Some(s"${major.toInt}${minor.toInt}")
case versionRegex2(major, "x") =>
Some(s"${major.toInt}")
case versionRegex2(major, minor) =>
Some(Version(major.toInt, minor.toInt, 0))
case versionRegex3(major) =>
Some(Version(major.toInt, 0, 0))
Some(s"${major.toInt}${minor.toInt}")
case _ =>
None
}
2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sbt.version=1.6.2
sbt.version=1.7.0-RC2
8 changes: 4 additions & 4 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.9.0")
addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.1.0")
addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.4")
addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % "1.1.0")
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.10.1")
addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.2.0")
addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.5")
addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % "1.2.0")
addSbtPlugin("org.scala-lang.modules" % "sbt-scala-module" % "3.0.1")
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.34")
addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.11.0")