Skip to content

add Scala 3 to crossbuild #215

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Mar 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import: scala/scala-dev:travis/default.yml
language: scala

scala:
- 3.0.0-RC1
- 2.11.12
- 2.12.13
- 2.13.5
Expand Down
70 changes: 38 additions & 32 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,21 @@ ThisBuild / versionScheme := Some("early-semver")
ThisBuild / versionPolicyIntention := Compatibility.BinaryAndSourceCompatible

lazy val commonSettings = Seq(
scalacOptions ++= Seq("-feature", "-deprecation", "-unchecked"),

unmanagedSourceDirectories in Compile ++= {
(unmanagedSourceDirectories in Compile).value.flatMap { dir =>
Compile / unmanagedSourceDirectories ++= {
(Compile / unmanagedSourceDirectories).value.flatMap { dir =>
CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, 13)) => Seq(file(dir.getPath ++ "-2.13+"))
case Some((2, 11)) => Seq(file(dir.getPath ++ "-2.13-"), file(dir.getPath ++ "-2.11"))
case _ => Seq(file(dir.getPath ++ "-2.13-"))
case Some((2, 12)) => Seq(file(dir.getPath ++ "-2.13-"))
case _ => Seq(file(dir.getPath ++ "-2.13+"))
}
}
},

unmanagedSourceDirectories in Test ++= {
(unmanagedSourceDirectories in Test).value.flatMap { dir =>
Test / unmanagedSourceDirectories ++= {
(Test / unmanagedSourceDirectories).value.flatMap { dir =>
CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, 13)) => Seq(file(dir.getPath ++ "-2.13+"))
case Some((2, 11)) => Seq(file(dir.getPath ++ "-2.13-"), file(dir.getPath ++ "-2.11"))
case _ => Seq(file(dir.getPath ++ "-2.13-"))
case Some((2, 12)) => Seq(file(dir.getPath ++ "-2.13-"))
case _ => Seq(file(dir.getPath ++ "-2.13+"))
}
}
},
Expand All @@ -48,7 +45,9 @@ lazy val commonSettings = Seq(
lazy val fnGen = (project in file("fnGen"))
.settings(commonSettings)
.settings(
fork in run := true, // Needed if you run this project directly
crossScalaVersions := Seq("2.12.13"),
scalaVersion := crossScalaVersions.value.head,
run / fork := true, // Needed if you run this project directly
libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value,
libraryDependencies += "org.scala-lang" % "scala-compiler" % scalaVersion.value
)
Expand All @@ -73,10 +72,11 @@ lazy val scalaJava8Compat = (project in file("."))

libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % "test",

// we're still in 0.x land so we could choose to break bincompat,
// but let's at least be aware when we're doing it. also we should
// think about going 1.0, it's been a while
scalaModuleMimaPreviousVersion := Some("0.9.1"),
scalaModuleMimaPreviousVersion := {
// pending resolution of https://github.com/scalacenter/sbt-version-policy/issues/62
if (isDotty.value) None
else Some("0.9.1")
},

mimaBinaryIssueFilters ++= {
import com.typesafe.tools.mima.core._, ProblemFilters._
Expand All @@ -93,19 +93,19 @@ lazy val scalaJava8Compat = (project in file("."))

testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-a"),

(sourceGenerators in Compile) += Def.task {
val out = (sourceManaged in Compile).value
(Compile / sourceGenerators) += Def.task {
val out = (Compile / sourceManaged).value
if (!out.exists) IO.createDirectory(out)
val canon = out.getCanonicalPath
val args = (new File(canon, "FunctionConverters.scala")).toString :: Nil
val runTarget = (mainClass in Compile in fnGen).value getOrElse "No main class defined for function conversion generator"
val classPath = (fullClasspath in Compile in fnGen).value
val runTarget = (fnGen / Compile / mainClass).value getOrElse "No main class defined for function conversion generator"
val classPath = (fnGen / Compile / fullClasspath).value
runner.value.run(runTarget, classPath.files, args, streams.value.log)
(out ** "*.scala").get
}.taskValue,

sourceGenerators in Compile += Def.task {
val dir = (sourceManaged in Compile).value
Compile / sourceGenerators += Def.task {
val dir = (Compile / sourceManaged).value
val write = jwrite(dir) _
if(scalaVersion.value.startsWith("2.11.")) {
Seq(write("JFunction", CodeGen.factory)) ++
Expand All @@ -118,8 +118,8 @@ lazy val scalaJava8Compat = (project in file("."))
} else CodeGen.create212.map(write.tupled)
}.taskValue,

sourceGenerators in Test += Def.task {
Seq(jwrite((sourceManaged in Test).value)("TestApi", CodeGen.testApi))
Test / sourceGenerators += Def.task {
Seq(jwrite((Test / sourceManaged).value)("TestApi", CodeGen.testApi))
}.taskValue,

initialize := {
Expand All @@ -131,23 +131,29 @@ lazy val scalaJava8Compat = (project in file("."))
sys.error("Java 8 or higher is required for this project.")
},

publishArtifact in packageDoc := !disableDocs
packageDoc / publishArtifact := !disableDocs
)
.settings(
inConfig(JavaDoc)(Defaults.configSettings) ++ {
if (disableDocs) Nil
else Seq(
packageDoc in Compile := (packageDoc in JavaDoc).value,
sources in JavaDoc := {
Compile / packageDoc := (JavaDoc / packageDoc).value,
JavaDoc / sources := {
val allJavaSources =
(target.value / "java" ** "*.java").get ++
(sources in Compile).value.filter(_.getName.endsWith(".java"))
(Compile / sources).value.filter(_.getName.endsWith(".java"))
allJavaSources.filterNot(_.getName.contains("FuturesConvertersImpl.java")) // this file triggers bugs in genjavadoc
},
javacOptions in JavaDoc := Seq("-Xdoclint:none"),
artifactName in packageDoc in JavaDoc := ((sv, mod, art) => "" + mod.name + "_" + sv.binary + "-" + mod.revision + "-javadoc.jar"),
libraryDependencies += compilerPlugin("com.typesafe.genjavadoc" % "genjavadoc-plugin" % "0.16" cross CrossVersion.full),
scalacOptions in Compile += "-P:genjavadoc:out=" + (target.value / "java")
JavaDoc / javacOptions := Seq("-Xdoclint:none"),
JavaDoc / packageDoc / artifactName := ((sv, mod, art) => "" + mod.name + "_" + sv.binary + "-" + mod.revision + "-javadoc.jar"),
libraryDependencies ++= (
if (isDotty.value) Seq()
else Seq(compilerPlugin("com.typesafe.genjavadoc" % "genjavadoc-plugin" % "0.16" cross CrossVersion.full))
),
Compile / scalacOptions ++= (
if (isDotty.value) Seq()
else Seq(s"""-P:genjavadoc:out=${target.value / "java"}""")
),
)
}
)
Expand Down
2 changes: 1 addition & 1 deletion fnGen/WrapFnGen.scala
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ object WrapFnGen {

private def buildWrappersViaReflection: Seq[SamConversionCode] = {

val pack: Symbol = rootMirror.getPackageIfDefined(TermName("java.util.function"))
val pack: Symbol = rootMirror.getPackageIfDefined("java.util.function")

case class Jfn(iface: Symbol, sam: Symbol) {
lazy val genericCount = iface.typeParams.length
Expand Down
1 change: 1 addition & 0 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
addSbtPlugin("org.scala-lang.modules" % "sbt-scala-module" % "2.2.4")
addSbtPlugin("ch.epfl.scala" % "sbt-version-policy" % "1.0.0-RC5")
addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % "0.5.3")
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import scala.collection.{IterableOnce, Stepper, StepperShape}
import scala.compat.java8.converterImpl._
import scala.jdk.CollectionConverters._
import scala.jdk._
import scala.language.{higherKinds, implicitConversions}
import scala.language.implicitConversions

/** Defines extension methods to create Java Streams for Scala collections, available through
* [[scala.compat.java8.StreamConverters]].
Expand Down Expand Up @@ -86,7 +86,7 @@ trait StreamExtensions {

implicit class MapHasParKeyValueStream[K, V, CC[X, Y] <: collection.MapOps[X, Y, collection.Map, _]](cc: CC[K, V]) {
private type MapOpsWithEfficientKeyStepper = collection.MapOps[K, V, collection.Map, _] { def keyStepper[S <: Stepper[_]](implicit shape : StepperShape[K, S]) : S with EfficientSplit }
private type MapOpsWithEfficientValueStepper = collection.MapOps[K, V, collection.Map, _] { def valueStepper[V1 >: V, S <: Stepper[_]](implicit shape : StepperShape[V1, S]) : S with EfficientSplit }
private type MapOpsWithEfficientValueStepper = collection.MapOps[K, V, collection.Map, _] { def valueStepper[S <: Stepper[_]](implicit shape : StepperShape[V, S]) : S with EfficientSplit }
private type MapOpsWithEfficientStepper = collection.MapOps[K, V, collection.Map, _] { def stepper[S <: Stepper[_]](implicit shape : StepperShape[(K, V), S]) : S with EfficientSplit }

/** Create a parallel [[java.util.stream.Stream Java Stream]] for the keys of this map. If
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,26 @@ package scala.compat.java8.converterImpl
import scala.language.implicitConversions

trait Priority3AccumulatorConverters {
implicit def collectionCanAccumulate[A](underlying: IterableOnce[A]) = new CollectionCanAccumulate[A](underlying)
implicit def collectionCanAccumulate[A](underlying: IterableOnce[A]): CollectionCanAccumulate[A] =
new CollectionCanAccumulate[A](underlying)
}

trait Priority2AccumulatorConverters extends Priority3AccumulatorConverters {
implicit def accumulateDoubleCollection(underlying: IterableOnce[Double]) = new AccumulateDoubleCollection(underlying)
implicit def accumulateIntCollection(underlying: IterableOnce[Int]) = new AccumulateIntCollection(underlying)
implicit def accumulateLongCollection(underlying: IterableOnce[Long]) = new AccumulateLongCollection(underlying)
implicit def accumulateAnyArray[A](underlying: Array[A]) = new AccumulateAnyArray(underlying)
implicit def accumulateDoubleCollection(underlying: IterableOnce[Double]): AccumulateDoubleCollection =
new AccumulateDoubleCollection(underlying)
implicit def accumulateIntCollection(underlying: IterableOnce[Int]): AccumulateIntCollection =
new AccumulateIntCollection(underlying)
implicit def accumulateLongCollection(underlying: IterableOnce[Long]): AccumulateLongCollection =
new AccumulateLongCollection(underlying)
implicit def accumulateAnyArray[A](underlying: Array[A]): AccumulateAnyArray[A] =
new AccumulateAnyArray(underlying)
}

trait Priority1AccumulatorConverters extends Priority2AccumulatorConverters {
implicit def accumulateDoubleArray(underlying: Array[Double]) = new AccumulateDoubleArray(underlying)
implicit def accumulateIntArray(underlying: Array[Int]) = new AccumulateIntArray(underlying)
implicit def accumulateLongArray(underlying: Array[Long]) = new AccumulateLongArray(underlying)
implicit def accumulateDoubleArray(underlying: Array[Double]): AccumulateDoubleArray =
new AccumulateDoubleArray(underlying)
implicit def accumulateIntArray(underlying: Array[Int]): AccumulateIntArray =
new AccumulateIntArray(underlying)
implicit def accumulateLongArray(underlying: Array[Long]): AccumulateLongArray =
new AccumulateLongArray(underlying)
}
2 changes: 1 addition & 1 deletion src/main/scala/scala/compat/java8/FutureConverters.scala
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ object FutureConverters {
*/
def toJava[T](f: Future[T]): CompletionStage[T] = {
f match {
case p: P[T] => p.wrapped
case p: P[T @unchecked] => p.wrapped
case _ =>
val cf = new CF[T](f)
implicit val ec = InternalCallbackExecutor
Expand Down
57 changes: 30 additions & 27 deletions src/main/scala/scala/compat/java8/OptionConverters.scala
Original file line number Diff line number Diff line change
Expand Up @@ -58,30 +58,33 @@ object OptionConverters {
/** Converts from `Option` to a manually specialized variant `That` */
def fromScala(o: Option[A]): That
}

/** Implementation of creation of `OptionalDouble` from `Option[Double]` or `Optional[Double]`*/
implicit val specializer_OptionalDouble = new SpecializerOfOptions[Double, OptionalDouble] {
/** Creates an `OptionalDouble` from `Optional[Double]` */
def fromJava(o: Optional[Double]): OptionalDouble = if (o.isPresent) OptionalDouble.of(o.get) else OptionalDouble.empty
/** Creates an `OptionalDouble` from `Option[Double]` */
def fromScala(o: Option[Double]): OptionalDouble = o match { case Some(d) => OptionalDouble.of(d); case _ => OptionalDouble.empty }
}

implicit val specializer_OptionalDouble: SpecializerOfOptions[Double, OptionalDouble] =
new SpecializerOfOptions[Double, OptionalDouble] {
/** Creates an `OptionalDouble` from `Optional[Double]` */
def fromJava(o: Optional[Double]): OptionalDouble = if (o.isPresent) OptionalDouble.of(o.get) else OptionalDouble.empty
/** Creates an `OptionalDouble` from `Option[Double]` */
def fromScala(o: Option[Double]): OptionalDouble = o match { case Some(d) => OptionalDouble.of(d); case _ => OptionalDouble.empty }
}

/** Implementation of creation of `OptionalInt` from `Option[Int]` or `Optional[Int]`*/
implicit val specializer_OptionalInt = new SpecializerOfOptions[Int, OptionalInt] {
/** Creates an `OptionalInt` from `Optional[Int]` */
def fromJava(o: Optional[Int]): OptionalInt = if (o.isPresent) OptionalInt.of(o.get) else OptionalInt.empty
/** Creates an `OptionalInt` from `Option[Int]` */
def fromScala(o: Option[Int]): OptionalInt = o match { case Some(d) => OptionalInt.of(d); case _ => OptionalInt.empty }
}

implicit val specializer_OptionalInt: SpecializerOfOptions[Int, OptionalInt] =
new SpecializerOfOptions[Int, OptionalInt] {
/** Creates an `OptionalInt` from `Optional[Int]` */
def fromJava(o: Optional[Int]): OptionalInt = if (o.isPresent) OptionalInt.of(o.get) else OptionalInt.empty
/** Creates an `OptionalInt` from `Option[Int]` */
def fromScala(o: Option[Int]): OptionalInt = o match { case Some(d) => OptionalInt.of(d); case _ => OptionalInt.empty }
}

/** Implementation of creation of `OptionalLong` from `Option[Long]` or `Optional[Long]`*/
implicit val specializer_OptionalLong = new SpecializerOfOptions[Long, OptionalLong] {
/** Creates an `OptionalLong` from `Optional[Long]` */
def fromJava(o: Optional[Long]): OptionalLong = if (o.isPresent) OptionalLong.of(o.get) else OptionalLong.empty
/** Creates an `OptionalLong` from `Option[Long]` */
def fromScala(o: Option[Long]): OptionalLong = o match { case Some(d) => OptionalLong.of(d); case _ => OptionalLong.empty }
}
implicit val specializer_OptionalLong: SpecializerOfOptions[Long, OptionalLong] =
new SpecializerOfOptions[Long, OptionalLong] {
/** Creates an `OptionalLong` from `Optional[Long]` */
def fromJava(o: Optional[Long]): OptionalLong = if (o.isPresent) OptionalLong.of(o.get) else OptionalLong.empty
/** Creates an `OptionalLong` from `Option[Long]` */
def fromScala(o: Option[Long]): OptionalLong = o match { case Some(d) => OptionalLong.of(d); case _ => OptionalLong.empty }
}

/** Provides conversions from `java.util.Optional` to Scala `Option` or primitive `java.util.Optional` types */
implicit class RichOptionalGeneric[A](val underlying: java.util.Optional[A]) extends AnyVal {
Expand All @@ -90,42 +93,42 @@ object OptionConverters {
/** Create a specialized primitive variant of this generic `Optional`, if an appropriate one exists */
def asPrimitive[That](implicit specOp: SpecializerOfOptions[A, That]): That = specOp.fromJava(underlying)
}

/** Provides conversions from `scala.Option` to Java `Optional` types, either generic or primitive */
implicit class RichOptionForJava8[A](val underlying: Option[A]) extends AnyVal {
/** Create a `java.util.Optional` version of this `Option` (not specialized) */
def asJava: Optional[A] = underlying match { case Some(a) => Optional.ofNullable(a); case _ => Optional.empty[A] }
/** Create a specialized primitive `java.util.Optional` type, if an appropriate one exists */
def asPrimitive[That](implicit specOp: SpecializerOfOptions[A, That]): That = specOp.fromScala(underlying)
}

/** Provides conversions from `java.util.OptionalDouble` to the generic `Optional` and Scala `Option` */
implicit class RichOptionalDouble(val underlying: OptionalDouble) extends AnyVal {
/** Create a `scala.Option` version of this `OptionalDouble` */
def asScala: Option[Double] = if (underlying.isPresent) Some(underlying.getAsDouble) else None
/** Create a generic `java.util.Optional` version of this `OptionalDouble` */
def asGeneric: Optional[Double] = if (underlying.isPresent) Optional.of(underlying.getAsDouble) else Optional.empty[Double]
}

/** Provides conversions from `java.util.OptionalInt` to the generic `Optional` and Scala `Option` */
implicit class RichOptionalInt(val underlying: OptionalInt) extends AnyVal {
/** Create a `scala.Option` version of this `OptionalInt` */
def asScala: Option[Int] = if (underlying.isPresent) Some(underlying.getAsInt) else None
/** Create a generic `java.util.Optional` version of this `OptionalInt` */
def asGeneric: Optional[Int] = if (underlying.isPresent) Optional.of(underlying.getAsInt) else Optional.empty[Int]
}

/** Provides conversions from `java.util.OptionalLong` to the generic `Optional` and Scala `Option` */
implicit class RichOptionalLong(val underlying: OptionalLong) extends AnyVal {
/** Create a `scala.Option` version of this `OptionalLong` */
def asScala: Option[Long] = if (underlying.isPresent) Some(underlying.getAsLong) else None
/** Create a generic `java.util.Optional` version of this `OptionalLong` */
def asGeneric: Optional[Long] = if (underlying.isPresent) Optional.of(underlying.getAsLong) else Optional.empty[Long]
}

/** Conversion from Scala `Option` to Java `Optional` without using implicits, for convenient use from Java. */
final def toJava[A](o: Option[A]): Optional[A] = o match { case Some(a) => Optional.ofNullable(a); case _ => Optional.empty[A] }

/** Conversion from Java `Optional` to Scala `Option` without using implicits, for convenient use from Java */
final def toScala[A](o: Optional[A]): Option[A] = if (o.isPresent) Some(o.get) else None

Expand Down
Loading