Skip to content
This repository was archived by the owner on Dec 22, 2021. It is now read-only.
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
38 changes: 24 additions & 14 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,28 +1,36 @@
organization in ThisBuild := "ch.epfl.scala"
// Convenient setting that allows writing `set scalaVersion := dotty.value` in sbt shell to switch from Scala to Dotty
val dotty = settingKey[String]("dotty version")
dotty in ThisBuild := dottyLatestNightlyBuild.get

version in ThisBuild := "0.2.0-SNAPSHOT"
def targetingDotty: Def.Initialize[Boolean] = Def.setting(scalaVersion.value == dotty.value)

resolvers in ThisBuild += "scala-pr" at "https://scala-ci.typesafe.com/artifactory/scala-pr-validation-snapshots"
scalaVersion in ThisBuild := "2.12.2-ebe1180-SNAPSHOT" // from https://github.com/scala/scala/pull/5742
scalaBinaryVersion in ThisBuild := "2.12"

scalacOptions in ThisBuild ++=
Seq("-deprecation", "-feature", "-unchecked", "-opt-warnings", "-Yno-imports", "-language:higherKinds", "-opt:l:classpath")

testOptions in ThisBuild += Tests.Argument(TestFrameworks.JUnit, "-q", "-v", "-s", "-a")

fork in Test in ThisBuild := true

parallelExecution in Test in ThisBuild := false
val commonSettings = Seq(
organization := "ch.epfl.scala",
version := "0.2.0-SNAPSHOT",
resolvers += "scala-pr" at "https://scala-ci.typesafe.com/artifactory/scala-pr-validation-snapshots",
scalaOrganization := { if (targetingDotty.value) "ch.epfl.lamp" else scalaOrganization.value },
scalaBinaryVersion := { if (targetingDotty.value) "2.11" else "2.12" },
scalaVersion := "2.12.2-ebe1180-SNAPSHOT", // from https://github.com/scala/scala/pull/5742
crossScalaVersions := scalaVersion.value :: dotty.value :: Nil,
scalacOptions ++= Seq("-deprecation", "-feature", "-unchecked", "-opt-warnings", "-Yno-imports", "-language:higherKinds", "-opt:l:classpath"),
testOptions += Tests.Argument(TestFrameworks.JUnit, "-q", "-v", "-s", "-a"),
fork in Test := true,
parallelExecution in Test := false
)

val collections =
project.in(file("."))
.settings(commonSettings: _*)
.settings(
name := "collection-strawman",
libraryDependencies ++= Seq(
"org.scala-lang.modules" %% "scala-java8-compat" % "0.8.0",
"com.novocode" % "junit-interface" % "0.11" % Test
),
scalacOptions ++= {
if (targetingDotty.value) Seq("-language:Scala2")
else Nil
},
pomExtra :=
<developers>
<developer><id>ichoran</id><name>Rex Kerr</name></developer>
Expand Down Expand Up @@ -51,6 +59,7 @@ val timeBenchmark =
project.in(file("benchmarks/time"))
.dependsOn(collections)
.enablePlugins(JmhPlugin)
.settings(commonSettings: _*)
.settings(
charts := Def.inputTaskDyn {
val benchmarks = Def.spaceDelimited().parsed
Expand All @@ -68,6 +77,7 @@ val timeBenchmark =
val memoryBenchmark =
project.in(file("benchmarks/memory"))
.dependsOn(collections)
.settings(commonSettings: _*)
.settings(
libraryDependencies += "org.spire-math" %% "jawn-ast" % "0.10.4",
charts := Def.inputTaskDyn {
Expand Down
2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sbt.version=0.13.13
sbt.version=0.13.15
2 changes: 2 additions & 0 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.0.1")

addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.2.20")

addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % "0.1.0-RC2")

// for bencharts
libraryDependencies ++= Seq(
"org.jfree" % "jfreechart" % "1.0.14",
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/strawman/collection/BuildFrom.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ object BuildFrom {
}

/** Build the source collection type from a ConstrainedPolyBuildable */
implicit def buildFromConstrainedPolyBuildable[Ev[_], Impl[_], CC[_], A, E : Ev]: BuildFrom[ConstrainedPolyBuildable[A, CC, Ev], E] { type To = CC[E] } = new BuildFrom[ConstrainedPolyBuildable[A, CC, Ev], E] {
implicit def buildFromConstrainedPolyBuildable[Ev[_], CC[_], A, E : Ev]: BuildFrom[ConstrainedPolyBuildable[A, CC, Ev], E] { type To = CC[E] } = new BuildFrom[ConstrainedPolyBuildable[A, CC, Ev], E] {
//TODO: Reuse a prototype instance
type To = CC[E]
def newBuilder(from: ConstrainedPolyBuildable[A, CC, Ev]): Builder[E, To] = from.newConstrainedBuilder[E]
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/strawman/collection/Set.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package strawman
package collection

import scala.{Any, Boolean, Equals, inline, Int}
import scala.{Any, Boolean, Equals, `inline`, Int}
import scala.util.hashing.MurmurHash3

/** Base trait for set collections.
Expand Down Expand Up @@ -34,7 +34,7 @@ trait SetLike[A, +C[X] <: Set[X]]
* @param elem the element to test for membership.
* @return `true` if `elem` is contained in this set, `false` otherwise.
*/
@inline final def apply(elem: A): Boolean = this.contains(elem)
@`inline` final def apply(elem: A): Boolean = this.contains(elem)

def subsetOf(that: Set[A]): Boolean = this.forall(that)

Expand Down
8 changes: 4 additions & 4 deletions src/main/scala/strawman/collection/immutable/HashSet.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ package collection.immutable
import strawman.collection.{IterableFactory, Iterator}
import strawman.collection.mutable.{Builder, ImmutableSetBuilder}

import scala.{Any, AnyRef, Array, Boolean, inline, Int, NoSuchElementException, Serializable, SerialVersionUID, sys, Unit}
import scala.{Any, AnyRef, Array, Boolean, `inline`, Int, NoSuchElementException, Serializable, SerialVersionUID, sys, Unit}
import scala.Predef.assert
import java.lang.Integer

Expand Down Expand Up @@ -166,7 +166,7 @@ object HashSet extends IterableFactory[HashSet] {
}
} else this

private def writeObject(out: java.io.ObjectOutputStream) {
private def writeObject(out: java.io.ObjectOutputStream): Unit = {
// this cannot work - reading things in might produce different
// hash codes and remove the collision. however this is never called
// because no references to this class are ever handed out to client code
Expand All @@ -175,7 +175,7 @@ object HashSet extends IterableFactory[HashSet] {
//out.writeObject(kvs)
}

private def readObject(in: java.io.ObjectInputStream) {
private def readObject(in: java.io.ObjectInputStream): Unit = {
sys.error("cannot deserialize an immutable.HashSet where all items have the same 32-bit hash code")
//kvs = in.readObject().asInstanceOf[ListSet[A]]
//hash = computeHash(kvs.)
Expand Down Expand Up @@ -342,6 +342,6 @@ object HashSet extends IterableFactory[HashSet] {
* In many internal operations the empty set is represented as null for performance reasons. This method converts
* null to the empty set for use in public methods
*/
@inline private def nullToEmpty[A](s: HashSet[A]): HashSet[A] = if (s eq null) empty[A] else s
@`inline` private def nullToEmpty[A](s: HashSet[A]): HashSet[A] = if (s eq null) empty[A] else s

}
2 changes: 1 addition & 1 deletion src/main/scala/strawman/collection/immutable/ListSet.scala
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ sealed class ListSet[A]

@tailrec private[this] def removeInternal(k: A, cur: ListSet[A], acc: List[ListSet[A]]): ListSet[A] =
if (cur.isEmpty) acc.last
else if (k == cur.elem) acc.foldLeft(cur.next) { case (t, h) => new t.Node(h.elem) }
else if (k == cur.elem) acc.foldLeft(cur.next)((t, h) => new t.Node(h.elem))
else removeInternal(k, cur.next, cur :: acc)

override protected def next: ListSet[A] = ListSet.this
Expand Down
24 changes: 12 additions & 12 deletions src/main/scala/strawman/collection/immutable/RedBlackTree.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import collection.Iterator
import scala.annotation.tailrec
import scala.annotation.meta.getter

import scala.{Array, Boolean, inline, Int, None, NoSuchElementException, Option, Ordering, Serializable, Some, sys, Unit}
import scala.{Array, Boolean, `inline`, Int, None, NoSuchElementException, Option, Ordering, Serializable, Some, sys, Unit}
import java.lang.{Integer, String}

/** An object containing the RedBlack tree implementation used by for `TreeMaps` and `TreeSets`.
Expand Down Expand Up @@ -96,15 +96,15 @@ private[collection] object RedBlackTree {

def foreach[A,B,U](tree:Tree[A,B], f:((A,B)) => U):Unit = if (tree ne null) _foreach(tree,f)

private[this] def _foreach[A, B, U](tree: Tree[A, B], f: ((A, B)) => U) {
private[this] def _foreach[A, B, U](tree: Tree[A, B], f: ((A, B)) => U): Unit = {
if (tree.left ne null) _foreach(tree.left, f)
f((tree.key, tree.value))
if (tree.right ne null) _foreach(tree.right, f)
}

def foreachKey[A, U](tree:Tree[A,_], f: A => U):Unit = if (tree ne null) _foreachKey(tree,f)

private[this] def _foreachKey[A, U](tree: Tree[A, _], f: A => U) {
private[this] def _foreachKey[A, U](tree: Tree[A, _], f: A => U): Unit = {
if (tree.left ne null) _foreachKey(tree.left, f)
f((tree.key))
if (tree.right ne null) _foreachKey(tree.right, f)
Expand Down Expand Up @@ -422,7 +422,7 @@ private[collection] object RedBlackTree {
}

/*
* Forcing direct fields access using the @inline annotation helps speed up
* Forcing direct fields access using the @`inline` annotation helps speed up
* various operations (especially smallest/greatest and update/delete).
*
* Unfortunately the direct field access is not guaranteed to work (but
Expand All @@ -431,12 +431,12 @@ private[collection] object RedBlackTree {
* An alternative is to implement the these classes using plain old Java code...
*/
sealed abstract class Tree[A, +B](
@(inline @getter) final val key: A,
@(inline @getter) final val value: B,
@(inline @getter) final val left: Tree[A, B],
@(inline @getter) final val right: Tree[A, B])
@(`inline` @getter) final val key: A,
@(`inline` @getter) final val value: B,
@(`inline` @getter) final val left: Tree[A, B],
@(`inline` @getter) final val right: Tree[A, B])
extends Serializable {
@(inline @getter) final val count: Int = 1 + RedBlackTree.count(left) + RedBlackTree.count(right)
@(`inline` @getter) final val count: Int = 1 + RedBlackTree.count(left) + RedBlackTree.count(right)
def black: Tree[A, B]
def red: Tree[A, B]
}
Expand All @@ -458,11 +458,11 @@ private[collection] object RedBlackTree {
}

object RedTree {
@inline def apply[A, B](key: A, value: B, left: Tree[A, B], right: Tree[A, B]) = new RedTree(key, value, left, right)
@`inline` def apply[A, B](key: A, value: B, left: Tree[A, B], right: Tree[A, B]) = new RedTree(key, value, left, right)
def unapply[A, B](t: RedTree[A, B]) = Some((t.key, t.value, t.left, t.right))
}
object BlackTree {
@inline def apply[A, B](key: A, value: B, left: Tree[A, B], right: Tree[A, B]) = new BlackTree(key, value, left, right)
@`inline` def apply[A, B](key: A, value: B, left: Tree[A, B], right: Tree[A, B]) = new BlackTree(key, value, left, right)
def unapply[A, B](t: BlackTree[A, B]) = Some((t.key, t.value, t.left, t.right))
}

Expand All @@ -485,7 +485,7 @@ private[collection] object RedBlackTree {
else if (tree.left eq null) tree
else findLeftMostOrPopOnEmpty(goLeft(tree))

private[this] def pushNext(tree: Tree[A, B]) {
private[this] def pushNext(tree: Tree[A, B]): Unit = {
stackOfNexts(index) = tree
index += 1
}
Expand Down
16 changes: 8 additions & 8 deletions src/main/scala/strawman/collection/immutable/TrieIterator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,14 @@ private[collection] abstract class TrieIterator[+T](elems: Array[Iterable[T]]) e
case _ => false
}

final class DupIterator(xs: Array[Iterable[T]]) extends {
override val initDepth = outer.depth
override val initArrayStack: Array[Array[Iterable[T @uV]]] = outer.arrayStack
override val initPosStack = outer.posStack
override val initArrayD: Array[Iterable[T @uV]] = outer.arrayD
override val initPosD = outer.posD
override val initSubIter = outer.subIter
} with TrieIterator[T](xs) {
final class DupIterator(xs: Array[Iterable[T]] @uV) extends TrieIterator[T](xs) {
override def initDepth = outer.depth
override def initArrayStack: Array[Array[Iterable[T @uV]]] = outer.arrayStack
override def initPosStack = outer.posStack
override def initArrayD: Array[Iterable[T @uV]] = outer.arrayD
override def initPosD = outer.posD
override def initSubIter = outer.subIter

final override def getElem(x: AnyRef): T = outer.getElem(x)
}

Expand Down
8 changes: 4 additions & 4 deletions src/test/scala/strawman/collection/test/Test.scala
Original file line number Diff line number Diff line change
Expand Up @@ -290,15 +290,15 @@ class StrawmanTest {
}

def equality(): Unit = {
val list = List(1, 2, 3)
val lazyList = LazyList(1, 2, 3)
val list: Iterable[Int] = List(1, 2, 3)
val lazyList: Iterable[Int] = LazyList(1, 2, 3)
val buffer = ArrayBuffer(1, 2, 3)
assert(list == lazyList)
assert(list.## == lazyList.##)
assert(list == buffer)
assert(list == (buffer: Iterable[Int]))
assert(list.## == buffer.##)
buffer += 4
assert(list != buffer)
assert(list != (buffer: Iterable[Int]))
assert(list.## != buffer.##)
}

Expand Down
9 changes: 5 additions & 4 deletions src/test/scala/strawman/collection/test/TraverseTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import strawman.collection._

import scala.{Any, Either, Int, Left, None, Option, Right, Some, Unit}
import scala.Predef.ArrowAssoc
import scala.math.Ordering
import java.lang.String

class TraverseTest {
Expand Down Expand Up @@ -38,7 +39,7 @@ class TraverseTest {
case (Right(builder), Right(b)) => Right(builder += b)
case (Left(a) , _) => Left(a)
case (_ , Left(a)) => Left(a)
}.map(_.result)
}.right.map(_.result)

@Test
def optionSequence1Test: Unit = {
Expand All @@ -57,7 +58,8 @@ class TraverseTest {
val o1t: Option[immutable.List[Int]] = o1

val xs2 = immutable.TreeSet(Some("foo"), Some("bar"), None)
val o2 = optionSequence(xs2)
val o2 = optionSequence(xs2)(
BuildFrom.buildFromConstrainedPolyBuildable[Ordering, immutable.TreeSet, Option[String], String])
val o2t: Option[immutable.TreeSet[String]] = o2

// Breakout-like use case from https://github.com/scala/scala/pull/5233:
Expand All @@ -68,9 +70,8 @@ class TraverseTest {

@Test
def eitherSequenceTest: Unit = {
val xs3 = mutable.ListBuffer(Right("foo"), Left(0), Right("bar"))
val xs3: mutable.ListBuffer[Either[Int, String]] = mutable.ListBuffer(Right("foo"), Left(0), Right("bar"))
val e1 = eitherSequence(xs3)
val e1t: Either[Int, mutable.ListBuffer[String]] = e1
}

}