Permalink
Browse files

Lift Some, None, Nil, Left, Right not just supertypes

Previously leaf concrete types were not lifted which
could have caused weird problems when types is too
precise:

  val s1 = Some(2)
  q"$s1" // used to fail
  • Loading branch information...
1 parent 722c743 commit ae4a2f0f7be884e050565243f3b651e49ceb72ef Denys Shabalin committed Jan 15, 2014
@@ -35,16 +35,22 @@ trait StandardLiftables { self: Universe =>
implicit def liftArray[T: Liftable]: Liftable[Array[T]] = Liftable { arr => callScala(nme.Array)(arr.map(lift(_)).toList) }
implicit def liftVector[T: Liftable]: Liftable[Vector[T]] = Liftable { vect => callCollection(nme.Vector)(vect.map(lift(_)).toList) }
implicit def liftList[T: Liftable]: Liftable[List[T]] = Liftable { lst => callCollection(nme.List)(lst.map(lift(_))) }
+ implicit def liftNil: Liftable[Nil.type] = Liftable { _ => selectScala(nme.collection, nme.immutable, nme.Nil) }
implicit def liftMap[K: Liftable, V: Liftable]: Liftable[Map[K, V]] = Liftable { m => callCollection(nme.Map)(m.toList.map(lift(_))) }
implicit def liftSet[T: Liftable]: Liftable[Set[T]] = Liftable { s => callCollection(nme.Set)(s.toList.map(lift(_))) }
+ implicit def liftSome[T: Liftable]: Liftable[Some[T]] = Liftable { case Some(v) => callScala(nme.Some)(lift(v) :: Nil) }
+ implicit def liftNone: Liftable[None.type] = Liftable { _ => selectScala(nme.None) }
implicit def liftOption[T: Liftable]: Liftable[Option[T]] = Liftable {
- case Some(v) => callScala(nme.Some)(lift(v) :: Nil)
- case None => selectScala(nme.None)
+ case some: Some[T] => lift(some)
+ case none: None.type => lift(none)
}
+
+ implicit def liftLeft[L: Liftable, R]: Liftable[Left[L, R]] = Liftable { case Left(v) => callScala(nme.util, nme.Left)(lift(v) :: Nil) }
+ implicit def liftRight[L, R: Liftable]: Liftable[Right[L, R]] = Liftable { case Right(v) => callScala(nme.util, nme.Right)(lift(v) :: Nil) }
implicit def liftEither[L: Liftable, R: Liftable]: Liftable[Either[L, R]] = Liftable {
- case Left(l) => callScala(nme.util, nme.Left)(lift(l) :: Nil)
- case Right(r) => callScala(nme.util, nme.Right)(lift(r) :: Nil)
+ case left: Left[L, R] => lift(left)
+ case right: Right[L, R] => lift(right)
}
implicit def liftTuple1[T1](implicit liftT1: Liftable[T1]): Liftable[Tuple1[T1]] = Liftable { t =>
@@ -220,6 +226,7 @@ trait StandardLiftables { self: Universe =>
val List = TermName("List")
val Map = TermName("Map")
val None = TermName("None")
+ val Nil = TermName("Nil")
val Right = TermName("Right")
val Set = TermName("Set")
val Some = TermName("Some")
@@ -111,4 +111,41 @@ object LiftableProps extends QuasiquoteProperties("liftable") {
assert(q"${(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21)")
assert(q"${(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22)}" ≈ q"(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22)")
}
-}
+
+ property("lift nil") = test {
+ val nil = Nil
+ assert(q"$nil" ≈ q"scala.collection.immutable.Nil")
+ }
+
+ property("lift some") = test {
+ val some1 = Some(1)
+ assert(q"$some1" ≈ q"scala.Some(1)")
+ val some2: Option[Int] = Some(1)
+ assert(q"$some2" ≈ q"scala.Some(1)")
+ }
+
+ property("lift none") = test {
+ val none1 = None
+ assert(q"$none1" ≈ q"scala.None")
+ val none2: Option[Int] = None
+ assert(q"$none2" ≈ q"scala.None")
+ }
+
+ property("lift left") = test {
+ val left1 = Left(1)
+ assert(q"$left1" ≈ q"scala.util.Left(1)")
+ val left2: Left[Int, Int] = Left(1)
+ assert(q"$left2" ≈ q"scala.util.Left(1)")
+ val left3: Either[Int, Int] = Left(1)
+ assert(q"$left3" ≈ q"scala.util.Left(1)")
+ }
+
+ property("lift right") = test {
+ val right1 = Right(1)
+ assert(q"$right1" ≈ q"scala.util.Right(1)")
+ val right2: Right[Int, Int] = Right(1)
+ assert(q"$right2" ≈ q"scala.util.Right(1)")
+ val right3: Either[Int, Int] = Right(1)
+ assert(q"$right3" ≈ q"scala.util.Right(1)")
+ }
+}

0 comments on commit ae4a2f0

Please sign in to comment.