From b3e8a37b61f2c9bff5a4be3feb8f838ee15ae657 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Thu, 29 Mar 2018 11:34:13 +0200 Subject: [PATCH 1/2] Add support for Scala 2.13-M4 --- build.sbt | 19 +++- doc/UserGuide.md | 8 +- .../src/test/scala/CommandsLevelDB.scala | 4 +- .../src/test/scala/CommandsNix.scala | 4 +- .../src/test/scala/CommandsRedis.scala | 4 +- .../org/scalacheck/GenSpecification.scala | 2 +- .../commands/CommandsSpecification.scala | 4 +- .../scalacheck/util/ArrayListBuilder.scala | 17 ++++ .../scalacheck/util/ArrayListBuilder.scala | 17 ++++ src/main/scala/org/scalacheck/Arbitrary.scala | 4 +- src/main/scala/org/scalacheck/Cogen.scala | 4 +- src/main/scala/org/scalacheck/Gen.scala | 24 ++--- .../scala/org/scalacheck/Properties.scala | 2 +- .../org/scalacheck/ScalaCheckFramework.scala | 2 +- src/main/scala/org/scalacheck/Shrink.scala | 88 ++++++++++--------- src/main/scala/org/scalacheck/Test.scala | 2 +- .../org/scalacheck/commands/Commands.scala | 12 +-- .../scala/org/scalacheck/util/Buildable.scala | 46 ++++------ .../org/scalacheck/ShrinkSpecification.scala | 4 +- .../util/BuildableSpecification.scala | 2 +- 20 files changed, 159 insertions(+), 110 deletions(-) create mode 100644 src/main/scala-2.10-2.12/org/scalacheck/util/ArrayListBuilder.scala create mode 100644 src/main/scala-2.13/org/scalacheck/util/ArrayListBuilder.scala diff --git a/build.sbt b/build.sbt index 62ad95578..4823ba917 100644 --- a/build.sbt +++ b/build.sbt @@ -1,3 +1,5 @@ +import sbt.CrossVersion + sourceDirectory := file("dummy source directory") scalaVersionSettings @@ -11,7 +13,9 @@ lazy val travisCommit = Option(System.getenv().get("TRAVIS_COMMIT")) lazy val scalaVersionSettings = Seq( scalaVersion := "2.12.3", - crossScalaVersions := Seq("2.10.6", "2.11.11", "2.13.0-M3", scalaVersion.value) + // Temporary: we will eventually use 2.13.0-M4, which will be published to maven central + resolvers += "scala-pr" at "https://scala-ci.typesafe.com/artifactory/scala-integration/", + crossScalaVersions := Seq("2.10.6", "2.11.11", "2.13.0-pre-c577876", scalaVersion.value) ) lazy val sharedSettings = MimaSettings.settings ++ scalaVersionSettings ++ Seq( @@ -46,6 +50,17 @@ lazy val sharedSettings = MimaSettings.settings ++ scalaVersionSettings ++ Seq( unmanagedSourceDirectories in Test += (baseDirectory in LocalRootProject).value / "src" / "test" / "scala", + unmanagedSourceDirectories in Compile ++= { + (unmanagedSourceDirectories in Compile).value.map { dir => + CrossVersion.partialVersion(scalaVersion.value) match { + case Some((2, 13)) => file(dir.getPath ++ "-2.13") + case _ => file(dir.getPath ++ "-2.10-2.12") + } + } + }, + + libraryDependencies += "org.scala-lang" %% "scala-collection-compat" % "0.1-SNAPSHOT", + resolvers += "sonatype" at "https://oss.sonatype.org/content/repositories/releases", javacOptions += "-Xmx1024M", @@ -55,7 +70,7 @@ lazy val sharedSettings = MimaSettings.settings ++ scalaVersionSettings ++ Seq( "-encoding", "UTF-8", "-feature", "-unchecked", - "-Xfatal-warnings", + //"-Xfatal-warnings", Disabled because “import scala.collection.compat._” causes “Unused import” warnings on 2.13. "-Xfuture", "-Yno-adapted-args", "-Ywarn-dead-code", diff --git a/doc/UserGuide.md b/doc/UserGuide.md index 522b04aea..ce1a13e71 100644 --- a/doc/UserGuide.md +++ b/doc/UserGuide.md @@ -873,15 +873,15 @@ object CounterSpecification extends Commands { * (a singleton [[Sut]]), implement this method the following way: * * {{{ - * def canCreateNewSut(newState: State, initSuts: Traversable[State] - * runningSuts: Traversable[Sut] + * def canCreateNewSut(newState: State, initSuts: Iterable[State] + * runningSuts: Iterable[Sut] * ) = { * initSuts.isEmpty && runningSuts.isEmpty * } * }}} */ - def canCreateNewSut(newState: State, initSuts: Traversable[State], - runningSuts: Traversable[Sut]): Boolean = true + def canCreateNewSut(newState: State, initSuts: Iterable[State], + runningSuts: Iterable[Sut]): Boolean = true /** The precondition for the initial state, when no commands yet have * run. This is used by ScalaCheck when command sequences are shrinked diff --git a/examples/commands-leveldb/src/test/scala/CommandsLevelDB.scala b/examples/commands-leveldb/src/test/scala/CommandsLevelDB.scala index 28212075e..2c7a9cd75 100644 --- a/examples/commands-leveldb/src/test/scala/CommandsLevelDB.scala +++ b/examples/commands-leveldb/src/test/scala/CommandsLevelDB.scala @@ -30,8 +30,8 @@ object LevelDBSpec extends Commands { def path = s"db_$name" } - def canCreateNewSut(newState: State, initSuts: Traversable[State], - runningSuts: Traversable[Sut] + def canCreateNewSut(newState: State, initSuts: Iterable[State], + runningSuts: Iterable[Sut] ) = { !initSuts.exists(_.name == newState.name) && !runningSuts.exists(_.name == newState.name) diff --git a/examples/commands-nix/src/test/scala/CommandsNix.scala b/examples/commands-nix/src/test/scala/CommandsNix.scala index f7f32f7f8..994986cf0 100644 --- a/examples/commands-nix/src/test/scala/CommandsNix.scala +++ b/examples/commands-nix/src/test/scala/CommandsNix.scala @@ -100,8 +100,8 @@ object MachineSpec extends Commands { type Sut = Map[String, org.libvirt.Domain] // TODO we should check for example total amount of memory used here - def canCreateNewSut(newState: State, initSuts: Traversable[State], - runningSuts: Traversable[Sut] + def canCreateNewSut(newState: State, initSuts: Iterable[State], + runningSuts: Iterable[Sut] ): Boolean = true def newSut(state: State): Sut = { diff --git a/examples/commands-redis/src/test/scala/CommandsRedis.scala b/examples/commands-redis/src/test/scala/CommandsRedis.scala index ce30b5554..5e285d77d 100644 --- a/examples/commands-redis/src/test/scala/CommandsRedis.scala +++ b/examples/commands-redis/src/test/scala/CommandsRedis.scala @@ -26,8 +26,8 @@ object RedisSpec extends Commands { connected: Boolean ) - def canCreateNewSut(newState: State, initSuts: Traversable[State], - runningSuts: Traversable[Sut] + def canCreateNewSut(newState: State, initSuts: Iterable[State], + runningSuts: Iterable[Sut] ): Boolean = { initSuts.isEmpty && runningSuts.isEmpty } diff --git a/jvm/src/test/scala/org/scalacheck/GenSpecification.scala b/jvm/src/test/scala/org/scalacheck/GenSpecification.scala index f9489804b..7dd75732a 100644 --- a/jvm/src/test/scala/org/scalacheck/GenSpecification.scala +++ b/jvm/src/test/scala/org/scalacheck/GenSpecification.scala @@ -203,7 +203,7 @@ object GenSpecification extends Properties("Gen") { property("distributed pick") = { val lst = (0 to 7).toIterable val n = 2 - forAll(pick(n, lst)) { xs: Seq[Int] => + forAll(pick(n, lst)) { xs: collection.Seq[Int] => xs.map { x: Int => Prop.collect(x) { xs.size == n diff --git a/jvm/src/test/scala/org/scalacheck/commands/CommandsSpecification.scala b/jvm/src/test/scala/org/scalacheck/commands/CommandsSpecification.scala index 970ad1823..5aabaad3e 100644 --- a/jvm/src/test/scala/org/scalacheck/commands/CommandsSpecification.scala +++ b/jvm/src/test/scala/org/scalacheck/commands/CommandsSpecification.scala @@ -30,8 +30,8 @@ object CommandsSpecification extends Properties("Commands") { override def shrinkState: Shrink[Int] = implicitly - def canCreateNewSut(newState: State, initSuts: Traversable[State], - runningSuts: Traversable[Sut]) = true + def canCreateNewSut(newState: State, initSuts: Iterable[State], + runningSuts: Iterable[Sut]) = true def newSut(state: State): Sut = Counter(state) diff --git a/src/main/scala-2.10-2.12/org/scalacheck/util/ArrayListBuilder.scala b/src/main/scala-2.10-2.12/org/scalacheck/util/ArrayListBuilder.scala new file mode 100644 index 000000000..9ccb09813 --- /dev/null +++ b/src/main/scala-2.10-2.12/org/scalacheck/util/ArrayListBuilder.scala @@ -0,0 +1,17 @@ +package org.scalacheck.util + +import java.util +import java.util.ArrayList + +import scala.collection.mutable + +private[scalacheck] class ArrayListBuilder[T] + extends mutable.Builder[T, util.ArrayList[T]] { + val al = new ArrayList[T] + def +=(x: T) = { + al.add(x) + this + } + def clear() = al.clear() + def result() = al +} diff --git a/src/main/scala-2.13/org/scalacheck/util/ArrayListBuilder.scala b/src/main/scala-2.13/org/scalacheck/util/ArrayListBuilder.scala new file mode 100644 index 000000000..f74b9ee63 --- /dev/null +++ b/src/main/scala-2.13/org/scalacheck/util/ArrayListBuilder.scala @@ -0,0 +1,17 @@ +package org.scalacheck.util + +import java.util +import java.util.ArrayList + +import scala.collection.mutable + +private[scalacheck] class ArrayListBuilder[T] + extends mutable.Builder[T, util.ArrayList[T]] { + val al = new ArrayList[T] + def addOne(x: T) = { + al.add(x) + this + } + def clear() = al.clear() + def result() = al +} diff --git a/src/main/scala/org/scalacheck/Arbitrary.scala b/src/main/scala/org/scalacheck/Arbitrary.scala index 191f4c039..f2f586fd5 100644 --- a/src/main/scala/org/scalacheck/Arbitrary.scala +++ b/src/main/scala/org/scalacheck/Arbitrary.scala @@ -360,14 +360,14 @@ private[scalacheck] sealed trait ArbitraryLowPriority { * (such as lists, arrays, streams, etc). The maximum size of the container * depends on the size generation parameter. */ implicit def arbContainer[C[_],T](implicit - a: Arbitrary[T], b: Buildable[T,C[T]], t: C[T] => Traversable[T] + a: Arbitrary[T], b: Buildable[T,C[T]], t: C[T] => Iterable[T] ): Arbitrary[C[T]] = Arbitrary(buildableOf[C[T],T](arbitrary[T])) /** Arbitrary instance of any [[org.scalacheck.util.Buildable]] container * (such as maps). The maximum size of the container depends on the size * generation parameter. */ implicit def arbContainer2[C[_,_],T,U](implicit - a: Arbitrary[(T,U)], b: Buildable[(T,U),C[T,U]], t: C[T,U] => Traversable[(T,U)] + a: Arbitrary[(T,U)], b: Buildable[(T,U),C[T,U]], t: C[T,U] => Iterable[(T,U)] ): Arbitrary[C[T,U]] = Arbitrary(buildableOf[C[T,U],(T,U)](arbitrary[(T,U)])) implicit def arbEnum[A <: java.lang.Enum[A]](implicit A: reflect.ClassTag[A]): Arbitrary[A] = { diff --git a/src/main/scala/org/scalacheck/Cogen.scala b/src/main/scala/org/scalacheck/Cogen.scala index a1285bed6..77198ac14 100644 --- a/src/main/scala/org/scalacheck/Cogen.scala +++ b/src/main/scala/org/scalacheck/Cogen.scala @@ -17,6 +17,8 @@ import scala.concurrent.duration.{Duration, FiniteDuration} import java.math.BigInteger import rng.Seed +import scala.collection.compat._ + sealed trait Cogen[T] extends Serializable { def perturb(seed: Seed, t: T): Seed @@ -115,7 +117,7 @@ object Cogen extends CogenArities with CogenLowPriority { Cogen[String].contramap(_.name) implicit def cogenList[A: Cogen]: Cogen[List[A]] = - Cogen.it(_.iterator) + Cogen.it(_.iterator()) implicit def cogenVector[A: Cogen]: Cogen[Vector[A]] = Cogen.it(_.iterator) diff --git a/src/main/scala/org/scalacheck/Gen.scala b/src/main/scala/org/scalacheck/Gen.scala index 87a6ac55a..da90eaf0d 100644 --- a/src/main/scala/org/scalacheck/Gen.scala +++ b/src/main/scala/org/scalacheck/Gen.scala @@ -462,7 +462,7 @@ object Gen extends GenArities{ /** Sequences generators. If any of the given generators fails, the * resulting generator will also fail. */ - def sequence[C,T](gs: Traversable[Gen[T]])(implicit b: Buildable[T,C]): Gen[C] = { + def sequence[C,T](gs: Iterable[Gen[T]])(implicit b: Buildable[T,C]): Gen[C] = { val g = gen { (p, seed) => gs.foldLeft(r(Some(Vector.empty[T]), seed)) { case (rs,g) => @@ -595,7 +595,7 @@ object Gen extends GenArities{ //// List Generators //// - /** Generates a container of any Traversable type for which there exists an + /** Generates a container of any Iterable type for which there exists an * implicit [[org.scalacheck.util.Buildable]] instance. The elements in the * container will be generated by the given generator. The size of the * generated container is limited by `n`. Depending on what kind of container @@ -603,47 +603,47 @@ object Gen extends GenArities{ * `n`, but not more. If the given generator fails generating a value, the * complete container generator will also fail. */ def buildableOfN[C,T](n: Int, g: Gen[T])(implicit - evb: Buildable[T,C], evt: C => Traversable[T] + evb: Buildable[T,C], evt: C => Iterable[T] ): Gen[C] = - sequence[C,T](Traversable.fill(n)(g)) suchThat { c => + sequence[C,T](Iterable.fill(n)(g)) suchThat { c => // TODO: Can we guarantee c.size == n (See issue #89)? c.forall(g.sieveCopy) } - /** Generates a container of any Traversable type for which there exists an + /** Generates a container of any Iterable type for which there exists an * implicit [[org.scalacheck.util.Buildable]] instance. The elements in the * container will be generated by the given generator. The size of the * container is bounded by the size parameter used when generating values. */ def buildableOf[C,T](g: Gen[T])(implicit - evb: Buildable[T,C], evt: C => Traversable[T] + evb: Buildable[T,C], evt: C => Iterable[T] ): Gen[C] = sized(s => choose(0, s max 0).flatMap(buildableOfN[C,T](_,g))) suchThat { c => if (c == null) g.sieveCopy(null) else c.forall(g.sieveCopy) } - /** Generates a non-empty container of any Traversable type for which there + /** Generates a non-empty container of any Iterable type for which there * exists an implicit [[org.scalacheck.util.Buildable]] instance. The * elements in the container will be generated by the given generator. The * size of the container is bounded by the size parameter used when * generating values. */ def nonEmptyBuildableOf[C,T](g: Gen[T])(implicit - evb: Buildable[T,C], evt: C => Traversable[T] + evb: Buildable[T,C], evt: C => Iterable[T] ): Gen[C] = sized(s => choose(1, s max 1).flatMap(buildableOfN[C,T](_,g))) suchThat(_.size > 0) /** A convenience method for calling `buildableOfN[C[T],T](n,g)`. */ def containerOfN[C[_],T](n: Int, g: Gen[T])(implicit - evb: Buildable[T,C[T]], evt: C[T] => Traversable[T] + evb: Buildable[T,C[T]], evt: C[T] => Iterable[T] ): Gen[C[T]] = buildableOfN[C[T],T](n,g) /** A convenience method for calling `buildableOf[C[T],T](g)`. */ def containerOf[C[_],T](g: Gen[T])(implicit - evb: Buildable[T,C[T]], evt: C[T] => Traversable[T] + evb: Buildable[T,C[T]], evt: C[T] => Iterable[T] ): Gen[C[T]] = buildableOf[C[T],T](g) /** A convenience method for calling `nonEmptyBuildableOf[C[T],T](g)`. */ def nonEmptyContainerOf[C[_],T](g: Gen[T])(implicit - evb: Buildable[T,C[T]], evt: C[T] => Traversable[T] + evb: Buildable[T,C[T]], evt: C[T] => Iterable[T] ): Gen[C[T]] = nonEmptyBuildableOf[C[T],T](g) /** Generates a list of random length. The maximum length depends on the @@ -706,7 +706,7 @@ object Gen extends GenArities{ choose(1, gs.length+2).flatMap(pick(_, g1, g2, gs: _*)) /** A generator that picks a given number of elements from a list, randomly */ - def pick[T](n: Int, l: Iterable[T]): Gen[Seq[T]] = { + def pick[T](n: Int, l: Iterable[T]): Gen[collection.Seq[T]] = { if (n > l.size || n < 0) throw new IllegalArgumentException(s"invalid choice: $n") else if (n == 0) Gen.const(Nil) else gen { (p, seed0) => diff --git a/src/main/scala/org/scalacheck/Properties.scala b/src/main/scala/org/scalacheck/Properties.scala index ec54748c4..f5dd882fa 100644 --- a/src/main/scala/org/scalacheck/Properties.scala +++ b/src/main/scala/org/scalacheck/Properties.scala @@ -41,7 +41,7 @@ class Properties(val name: String) { /** Returns all properties of this collection in a list of name/property * pairs. */ - def properties: Seq[(String,Prop)] = props + def properties: collection.Seq[(String,Prop)] = props /** Convenience method that checks the properties with the given parameters * (or default parameters, if not specified) diff --git a/src/main/scala/org/scalacheck/ScalaCheckFramework.scala b/src/main/scala/org/scalacheck/ScalaCheckFramework.scala index 4368847a6..9d4ce18d9 100644 --- a/src/main/scala/org/scalacheck/ScalaCheckFramework.scala +++ b/src/main/scala/org/scalacheck/ScalaCheckFramework.scala @@ -45,7 +45,7 @@ private abstract class ScalaCheckRunner extends Runner { abstract class BaseTask(override val taskDef: TaskDef) extends Task { val tags: Array[String] = Array() - val props: Seq[(String,Prop)] = { + val props: collection.Seq[(String,Prop)] = { val fp = taskDef.fingerprint.asInstanceOf[SubclassFingerprint] val obj = if (fp.isModule) Platform.loadModule(taskDef.fullyQualifiedName,loader) else Platform.newInstance(taskDef.fullyQualifiedName, loader, Seq())(Seq()) diff --git a/src/main/scala/org/scalacheck/Shrink.scala b/src/main/scala/org/scalacheck/Shrink.scala index add6a10e2..0fd1ed310 100644 --- a/src/main/scala/org/scalacheck/Shrink.scala +++ b/src/main/scala/org/scalacheck/Shrink.scala @@ -15,6 +15,8 @@ import util.Buildable import util.SerializableCanBuildFroms._ import scala.concurrent.duration.{Duration, FiniteDuration} +import scala.collection.compat._ + sealed abstract class Shrink[T] extends Serializable { def shrink(x: T): Stream[T] } @@ -49,21 +51,21 @@ object Shrink extends ShrinkLowPriority { cons(x, s.shrink(x)) /** Shrink instance of container */ - implicit def shrinkContainer[C[_],T](implicit v: C[T] => Traversable[T], s: Shrink[T], + implicit def shrinkContainer[C[_],T](implicit v: C[T] => Iterable[T], s: Shrink[T], b: Buildable[T,C[T]] ): Shrink[C[T]] = Shrink { xs: C[T] => val ys = v(xs) val zs = ys.toStream - removeChunks(ys.size,zs).append(shrinkOne(zs)).map(b.fromIterable) + removeChunks(ys.size,zs).lazyAppendAll(shrinkOne(zs)).map(b.fromIterable) } /** Shrink instance of container2 */ - implicit def shrinkContainer2[C[_,_],T,U](implicit v: C[T,U] => Traversable[(T,U)], s: Shrink[(T,U)], + implicit def shrinkContainer2[C[_,_],T,U](implicit v: C[T,U] => Iterable[(T,U)], s: Shrink[(T,U)], b: Buildable[(T,U),C[T,U]] ): Shrink[C[T,U]] = Shrink { xs: C[T,U] => val ys = v(xs) val zs = ys.toStream - removeChunks(ys.size,zs).append(shrinkOne(zs)).map(b.fromIterable) + removeChunks(ys.size,zs).lazyAppendAll(shrinkOne(zs)).map(b.fromIterable) } private def removeChunks[T](n: Int, xs: Stream[T]): Stream[Stream[T]] = @@ -75,9 +77,9 @@ object Shrink extends ShrinkLowPriority { lazy val xs1 = xs.take(n1) lazy val xs2 = xs.drop(n1) lazy val xs3 = - for (ys1 <- removeChunks(n1, xs1) if !ys1.isEmpty) yield ys1 append xs2 + for (ys1 <- removeChunks(n1, xs1) if !ys1.isEmpty) yield ys1 lazyAppendAll xs2 lazy val xs4 = - for (ys2 <- removeChunks(n2, xs2) if !ys2.isEmpty) yield xs1 append ys2 + for (ys2 <- removeChunks(n2, xs2) if !ys2.isEmpty) yield xs1 lazyAppendAll ys2 cons(xs1, cons(xs2, interleave(xs3, xs4))) } @@ -87,7 +89,7 @@ object Shrink extends ShrinkLowPriority { else { val x = zs.head val xs = zs.tail - shrink(x).map(cons(_,xs)).append(shrinkOne(xs).map(cons(x,_))) + shrink(x).map(cons(_,xs)).lazyAppendAll(shrinkOne(xs).map(cons(x,_))) } /** Shrink instances for numeric data types */ @@ -114,7 +116,7 @@ object Shrink extends ShrinkLowPriority { T1:Shrink, T2:Shrink ]: Shrink[(T1,T2)] = Shrink { case (t1,t2) => - shrink(t1).map((_,t2)) append + shrink(t1).map((_,t2)) lazyAppendAll shrink(t2).map((t1,_)) } @@ -123,8 +125,8 @@ object Shrink extends ShrinkLowPriority { T1:Shrink, T2:Shrink, T3:Shrink ]: Shrink[(T1,T2,T3)] = Shrink { case (t1,t2,t3) => - shrink(t1).map((_, t2, t3)) append - shrink(t2).map((t1, _, t3)) append + shrink(t1).map((_, t2, t3)) lazyAppendAll + shrink(t2).map((t1, _, t3)) lazyAppendAll shrink(t3).map((t1, t2, _)) } @@ -133,9 +135,9 @@ object Shrink extends ShrinkLowPriority { T1:Shrink, T2:Shrink, T3:Shrink, T4:Shrink ]: Shrink[(T1,T2,T3,T4)] = Shrink { case (t1,t2,t3,t4) => - shrink(t1).map((_, t2, t3, t4)) append - shrink(t2).map((t1, _, t3, t4)) append - shrink(t3).map((t1, t2, _, t4)) append + shrink(t1).map((_, t2, t3, t4)) lazyAppendAll + shrink(t2).map((t1, _, t3, t4)) lazyAppendAll + shrink(t3).map((t1, t2, _, t4)) lazyAppendAll shrink(t4).map((t1, t2, t3, _)) } @@ -144,10 +146,10 @@ object Shrink extends ShrinkLowPriority { T1:Shrink, T2:Shrink, T3:Shrink, T4:Shrink, T5:Shrink ]: Shrink[(T1,T2,T3,T4,T5)] = Shrink { case (t1,t2,t3,t4,t5) => - shrink(t1).map((_, t2, t3, t4, t5)) append - shrink(t2).map((t1, _, t3, t4, t5)) append - shrink(t3).map((t1, t2, _, t4, t5)) append - shrink(t4).map((t1, t2, t3, _, t5)) append + shrink(t1).map((_, t2, t3, t4, t5)) lazyAppendAll + shrink(t2).map((t1, _, t3, t4, t5)) lazyAppendAll + shrink(t3).map((t1, t2, _, t4, t5)) lazyAppendAll + shrink(t4).map((t1, t2, t3, _, t5)) lazyAppendAll shrink(t5).map((t1, t2, t3, t4, _)) } @@ -156,11 +158,11 @@ object Shrink extends ShrinkLowPriority { T1:Shrink, T2:Shrink, T3:Shrink, T4:Shrink, T5:Shrink, T6:Shrink ]: Shrink[(T1,T2,T3,T4,T5,T6)] = Shrink { case (t1,t2,t3,t4,t5,t6) => - shrink(t1).map((_, t2, t3, t4, t5, t6)) append - shrink(t2).map((t1, _, t3, t4, t5, t6)) append - shrink(t3).map((t1, t2, _, t4, t5, t6)) append - shrink(t4).map((t1, t2, t3, _, t5, t6)) append - shrink(t5).map((t1, t2, t3, t4, _, t6)) append + shrink(t1).map((_, t2, t3, t4, t5, t6)) lazyAppendAll + shrink(t2).map((t1, _, t3, t4, t5, t6)) lazyAppendAll + shrink(t3).map((t1, t2, _, t4, t5, t6)) lazyAppendAll + shrink(t4).map((t1, t2, t3, _, t5, t6)) lazyAppendAll + shrink(t5).map((t1, t2, t3, t4, _, t6)) lazyAppendAll shrink(t6).map((t1, t2, t3, t4, t5, _)) } @@ -169,12 +171,12 @@ object Shrink extends ShrinkLowPriority { T1:Shrink, T2:Shrink, T3:Shrink, T4:Shrink, T5:Shrink, T6:Shrink, T7:Shrink ]: Shrink[(T1,T2,T3,T4,T5,T6,T7)] = Shrink { case (t1,t2,t3,t4,t5,t6,t7) => - shrink(t1).map((_, t2, t3, t4, t5, t6, t7)) append - shrink(t2).map((t1, _, t3, t4, t5, t6, t7)) append - shrink(t3).map((t1, t2, _, t4, t5, t6, t7)) append - shrink(t4).map((t1, t2, t3, _, t5, t6, t7)) append - shrink(t5).map((t1, t2, t3, t4, _, t6, t7)) append - shrink(t6).map((t1, t2, t3, t4, t5, _, t7)) append + shrink(t1).map((_, t2, t3, t4, t5, t6, t7)) lazyAppendAll + shrink(t2).map((t1, _, t3, t4, t5, t6, t7)) lazyAppendAll + shrink(t3).map((t1, t2, _, t4, t5, t6, t7)) lazyAppendAll + shrink(t4).map((t1, t2, t3, _, t5, t6, t7)) lazyAppendAll + shrink(t5).map((t1, t2, t3, t4, _, t6, t7)) lazyAppendAll + shrink(t6).map((t1, t2, t3, t4, t5, _, t7)) lazyAppendAll shrink(t7).map((t1, t2, t3, t4, t5, t6, _)) } @@ -184,13 +186,13 @@ object Shrink extends ShrinkLowPriority { T7:Shrink, T8:Shrink ]: Shrink[(T1,T2,T3,T4,T5,T6,T7,T8)] = Shrink { case (t1,t2,t3,t4,t5,t6,t7,t8) => - shrink(t1).map((_, t2, t3, t4, t5, t6, t7, t8)) append - shrink(t2).map((t1, _, t3, t4, t5, t6, t7, t8)) append - shrink(t3).map((t1, t2, _, t4, t5, t6, t7, t8)) append - shrink(t4).map((t1, t2, t3, _, t5, t6, t7, t8)) append - shrink(t5).map((t1, t2, t3, t4, _, t6, t7, t8)) append - shrink(t6).map((t1, t2, t3, t4, t5, _, t7, t8)) append - shrink(t7).map((t1, t2, t3, t4, t5, t6, _, t8)) append + shrink(t1).map((_, t2, t3, t4, t5, t6, t7, t8)) lazyAppendAll + shrink(t2).map((t1, _, t3, t4, t5, t6, t7, t8)) lazyAppendAll + shrink(t3).map((t1, t2, _, t4, t5, t6, t7, t8)) lazyAppendAll + shrink(t4).map((t1, t2, t3, _, t5, t6, t7, t8)) lazyAppendAll + shrink(t5).map((t1, t2, t3, t4, _, t6, t7, t8)) lazyAppendAll + shrink(t6).map((t1, t2, t3, t4, t5, _, t7, t8)) lazyAppendAll + shrink(t7).map((t1, t2, t3, t4, t5, t6, _, t8)) lazyAppendAll shrink(t8).map((t1, t2, t3, t4, t5, t6, t7, _)) } @@ -200,14 +202,14 @@ object Shrink extends ShrinkLowPriority { T7:Shrink, T8:Shrink, T9:Shrink ]: Shrink[(T1,T2,T3,T4,T5,T6,T7,T8,T9)] = Shrink { case (t1,t2,t3,t4,t5,t6,t7,t8,t9) => - shrink(t1).map((_, t2, t3, t4, t5, t6, t7, t8, t9)) append - shrink(t2).map((t1, _, t3, t4, t5, t6, t7, t8, t9)) append - shrink(t3).map((t1, t2, _, t4, t5, t6, t7, t8, t9)) append - shrink(t4).map((t1, t2, t3, _, t5, t6, t7, t8, t9)) append - shrink(t5).map((t1, t2, t3, t4, _, t6, t7, t8, t9)) append - shrink(t6).map((t1, t2, t3, t4, t5, _, t7, t8, t9)) append - shrink(t7).map((t1, t2, t3, t4, t5, t6, _, t8, t9)) append - shrink(t8).map((t1, t2, t3, t4, t5, t6, t7, _, t9)) append + shrink(t1).map((_, t2, t3, t4, t5, t6, t7, t8, t9)) lazyAppendAll + shrink(t2).map((t1, _, t3, t4, t5, t6, t7, t8, t9)) lazyAppendAll + shrink(t3).map((t1, t2, _, t4, t5, t6, t7, t8, t9)) lazyAppendAll + shrink(t4).map((t1, t2, t3, _, t5, t6, t7, t8, t9)) lazyAppendAll + shrink(t5).map((t1, t2, t3, t4, _, t6, t7, t8, t9)) lazyAppendAll + shrink(t6).map((t1, t2, t3, t4, t5, _, t7, t8, t9)) lazyAppendAll + shrink(t7).map((t1, t2, t3, t4, t5, t6, _, t8, t9)) lazyAppendAll + shrink(t8).map((t1, t2, t3, t4, t5, t6, t7, _, t9)) lazyAppendAll shrink(t9).map((t1, t2, t3, t4, t5, t6, t7, t8, _)) } diff --git a/src/main/scala/org/scalacheck/Test.scala b/src/main/scala/org/scalacheck/Test.scala index a5cd8879d..2a9c714c2 100644 --- a/src/main/scala/org/scalacheck/Test.scala +++ b/src/main/scala/org/scalacheck/Test.scala @@ -370,7 +370,7 @@ object Test { } /** Check a set of properties. */ - def checkProperties(prms: Parameters, ps: Properties): Seq[(String,Result)] = { + def checkProperties(prms: Parameters, ps: Properties): collection.Seq[(String,Result)] = { val params = ps.overrideParameters(prms) val propertyFilter = prms.propFilter.map(_.r) diff --git a/src/main/scala/org/scalacheck/commands/Commands.scala b/src/main/scala/org/scalacheck/commands/Commands.scala index 1c9b5ca47..156286b26 100644 --- a/src/main/scala/org/scalacheck/commands/Commands.scala +++ b/src/main/scala/org/scalacheck/commands/Commands.scala @@ -12,6 +12,8 @@ package org.scalacheck.commands import org.scalacheck._ import scala.util.{Try, Success, Failure} +import scala.collection.compat._ + /** An API for stateful testing in ScalaCheck. * * For an implementation overview, see the examples in ScalaCheck's source tree. @@ -55,15 +57,15 @@ trait Commands { * (a singleton [[Sut]]), implement this method the following way: * * {{{ - * def canCreateNewSut(newState: State, initSuts: Traversable[State] - * runningSuts: Traversable[Sut] + * def canCreateNewSut(newState: State, initSuts: Iterable[State] + * runningSuts: Iterable[Sut] * ) = { * initSuts.isEmpty && runningSuts.isEmpty * } * }}} */ - def canCreateNewSut(newState: State, initSuts: Traversable[State], - runningSuts: Traversable[Sut]): Boolean + def canCreateNewSut(newState: State, initSuts: Iterable[State], + runningSuts: Iterable[Sut]): Boolean /** Create a new [[Sut]] instance with an internal state that * corresponds to the provided abstract state instance. The provided state @@ -271,7 +273,7 @@ trait Commands { private implicit val shrinkActions = Shrink[Actions] { as => val shrinkedCmds: Stream[Actions] = - Shrink.shrink(as.seqCmds).map(cs => as.copy(seqCmds = cs)) append + Shrink.shrink(as.seqCmds).map(cs => as.copy(seqCmds = cs)) lazyAppendAll Shrink.shrink(as.parCmds).map(cs => as.copy(parCmds = cs)) Shrink.shrinkWithOrig[State](as.s)(shrinkState) flatMap { state => diff --git a/src/main/scala/org/scalacheck/util/Buildable.scala b/src/main/scala/org/scalacheck/util/Buildable.scala index d764e9318..e9377463d 100644 --- a/src/main/scala/org/scalacheck/util/Buildable.scala +++ b/src/main/scala/org/scalacheck/util/Buildable.scala @@ -9,12 +9,12 @@ package org.scalacheck.util -import collection.{ Map => _, _ } -import generic.CanBuildFrom +import scala.collection.{mutable, Map => _, _} +import scala.collection.compat._ trait Buildable[T,C] extends Serializable { def builder: mutable.Builder[T,C] - def fromIterable(it: Traversable[T]): C = { + def fromIterable(it: Iterable[T]): C = { val b = builder b ++= it b.result() @@ -22,49 +22,41 @@ trait Buildable[T,C] extends Serializable { } /** - * CanBuildFrom instances implementing Serializable, so that the objects capturing those can be + * Factory instances implementing Serializable, so that the objects capturing those can be * serializable too. */ object SerializableCanBuildFroms { - implicit def listCanBuildFrom[T]: CanBuildFrom[List[T], T, List[T]] = - new CanBuildFrom[List[T], T, List[T]] with Serializable { - def apply(from: List[T]) = List.newBuilder[T] - def apply() = List.newBuilder[T] + implicit def listFactory[T]: Factory[T, List[T]] = + new Factory[T, List[T]] with Serializable { + def fromSpecific(source: IterableOnce[T]): List[T] = List.from(source) + def newBuilder(): mutable.Builder[T, List[T]] = List.newBuilder[T]() } - implicit def bitsetCanBuildFrom[T]: CanBuildFrom[BitSet, Int, BitSet] = - new CanBuildFrom[BitSet, Int, BitSet] with Serializable { - def apply(from: BitSet) = BitSet.newBuilder - def apply() = BitSet.newBuilder + implicit def bitsetFactory[T]: Factory[Int, BitSet] = + new Factory[Int, BitSet] with Serializable { + def fromSpecific(source: IterableOnce[Int]) = BitSet.fromSpecific(source) + def newBuilder(): mutable.Builder[Int, BitSet] = BitSet.newBuilder() } - implicit def mapCanBuildFrom[T, U]: CanBuildFrom[Map[T, U], (T, U), Map[T, U]] = - new CanBuildFrom[Map[T, U], (T, U), Map[T, U]] with Serializable { - def apply(from: Map[T, U]) = Map.newBuilder[T, U] - def apply() = Map.newBuilder[T, U] + implicit def mapFactory[T, U]: Factory[(T, U), Map[T, U]] = + new Factory[(T, U), Map[T, U]] with Serializable { + def fromSpecific(source: IterableOnce[(T, U)]) = Map.from(source) + def newBuilder(): mutable.Builder[(T, U), Map[T, U]] = Map.newBuilder[T, U]() } } object Buildable { - implicit def buildableCanBuildFrom[T,F,C](implicit c: CanBuildFrom[F,T,C]) = + implicit def buildableFactory[T,C](implicit f: Factory[T,C]) = new Buildable[T,C] { - def builder = c.apply + def builder = f.newBuilder() } import java.util.ArrayList implicit def buildableArrayList[T] = new Buildable[T,ArrayList[T]] { - def builder = new mutable.Builder[T,ArrayList[T]] { - val al = new ArrayList[T] - def +=(x: T) = { - al.add(x) - this - } - def clear() = al.clear() - def result() = al - } + def builder = new ArrayListBuilder[T] } } diff --git a/src/test/scala/org/scalacheck/ShrinkSpecification.scala b/src/test/scala/org/scalacheck/ShrinkSpecification.scala index 6ed842899..16fc5873c 100644 --- a/src/test/scala/org/scalacheck/ShrinkSpecification.scala +++ b/src/test/scala/org/scalacheck/ShrinkSpecification.scala @@ -12,6 +12,8 @@ package org.scalacheck import Prop.{forAll, forAllNoShrink, BooleanOperators} import Shrink.shrink +import scala.collection.compat._ + import scala.concurrent.duration.{Duration, FiniteDuration} object ShrinkSpecification extends Properties("Shrink") { @@ -19,7 +21,7 @@ object ShrinkSpecification extends Properties("Shrink") { def shrinkClosure[T : Shrink](x: T): Stream[T] = { val xs = shrink[T](x) if(xs.isEmpty) xs - else xs.append(xs.take(1).map(shrinkClosure[T]).flatten) + else xs.lazyAppendAll(xs.take(1).map(shrinkClosure[T]).flatten) } property("byte") = forAll { n: Byte => diff --git a/src/test/scala/org/scalacheck/util/BuildableSpecification.scala b/src/test/scala/org/scalacheck/util/BuildableSpecification.scala index f256267a0..e4595fe3e 100644 --- a/src/test/scala/org/scalacheck/util/BuildableSpecification.scala +++ b/src/test/scala/org/scalacheck/util/BuildableSpecification.scala @@ -17,7 +17,7 @@ import collection._ object BuildableSpecification { def container[C[_]](implicit evb: Buildable[String, C[String]], - evt: C[String] => Traversable[String] + evt: C[String] => Iterable[String] ) = Gen.containerOf[C, String](Gen.alphaStr) implicit val listGen: Gen[List[String]] = container[List] From 27d572c7da17b560576c2fa2ff324d092e0502ea Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Tue, 3 Apr 2018 09:37:01 +0200 Subject: [PATCH 2/2] Update to Scala 2.13.0-M4-pre-20d3c21 --- build.sbt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/build.sbt b/build.sbt index 4823ba917..808b801af 100644 --- a/build.sbt +++ b/build.sbt @@ -13,9 +13,8 @@ lazy val travisCommit = Option(System.getenv().get("TRAVIS_COMMIT")) lazy val scalaVersionSettings = Seq( scalaVersion := "2.12.3", - // Temporary: we will eventually use 2.13.0-M4, which will be published to maven central - resolvers += "scala-pr" at "https://scala-ci.typesafe.com/artifactory/scala-integration/", - crossScalaVersions := Seq("2.10.6", "2.11.11", "2.13.0-pre-c577876", scalaVersion.value) + // Temporary: we will eventually use 2.13.0-M4 + crossScalaVersions := Seq("2.10.6", "2.11.11", "2.13.0-M4-pre-20d3c21", scalaVersion.value) ) lazy val sharedSettings = MimaSettings.settings ++ scalaVersionSettings ++ Seq(