summaryrefslogtreecommitdiff
path: root/test/files/scalacheck/quasiquotes/UnliftableProps.scala
diff options
context:
space:
mode:
authorDen Shabalin <den.shabalin@gmail.com>2013-12-02 16:56:37 +0100
committerDen Shabalin <den.shabalin@gmail.com>2013-12-10 16:02:45 +0100
commit1188f95acf71486c4a75b9ad428a92e6e401f5cd (patch)
tree9eb308c7f20bbffc50d38886da2a8a91889368a9 /test/files/scalacheck/quasiquotes/UnliftableProps.scala
parent4c899ea34c01eebf1215abd579d11393cf20a487 (diff)
downloadscala-1188f95acf71486c4a75b9ad428a92e6e401f5cd.tar.gz
scala-1188f95acf71486c4a75b9ad428a92e6e401f5cd.tar.bz2
scala-1188f95acf71486c4a75b9ad428a92e6e401f5cd.zip
Introduce support for Unliftable for Quasiquotes
Unliftable is a type class similar to existing Liftable that lets users to extract custom data types out of trees with the help of straightforward type ascription syntax: val q“foo.bar(${baz: Baz})” = ... This will use Unliftable[Baz] to extract custom data type Baz out of a tree nested inside of the another tree. A simpler example would be extracting of constant values: val q”${x: Int} + ${y: Int}” = q”1 + 2”
Diffstat (limited to 'test/files/scalacheck/quasiquotes/UnliftableProps.scala')
-rw-r--r--test/files/scalacheck/quasiquotes/UnliftableProps.scala112
1 files changed, 112 insertions, 0 deletions
diff --git a/test/files/scalacheck/quasiquotes/UnliftableProps.scala b/test/files/scalacheck/quasiquotes/UnliftableProps.scala
new file mode 100644
index 0000000000..c574672c2a
--- /dev/null
+++ b/test/files/scalacheck/quasiquotes/UnliftableProps.scala
@@ -0,0 +1,112 @@
+import org.scalacheck._, Prop._, Gen._, Arbitrary._
+import scala.reflect.runtime.universe._, Flag._
+
+object UnliftableProps extends QuasiquoteProperties("unliftable") {
+ property("unlift name") = test {
+ val termname0 = TermName("foo")
+ val typename0 = TypeName("foo")
+ val q"${termname1: TermName}" = Ident(termname0)
+ assert(termname1 == termname0)
+ val q"${typename1: TypeName}" = Ident(typename0)
+ assert(typename1 == typename0)
+ val q"${name1: Name}" = Ident(termname0)
+ assert(name1 == termname0)
+ val q"${name2: Name}" = Ident(typename0)
+ assert(name2 == typename0)
+ }
+
+ property("unlift type") = test {
+ val q"${tpe: Type}" = TypeTree(typeOf[Int])
+ assert(tpe =:= typeOf[Int])
+ }
+
+ property("unlift constant") = test {
+ val q"${const: Constant}" = Literal(Constant("foo"))
+ assert(const == Constant("foo"))
+ }
+
+ property("unlift char") = test {
+ val q"${c: Char}" = Literal(Constant('0'))
+ assert(c.isInstanceOf[Char] && c == '0')
+ }
+
+ property("unlift byte") = test {
+ val q"${b: Byte}" = Literal(Constant(0: Byte))
+ assert(b.isInstanceOf[Byte] && b == 0)
+ }
+
+ property("unlift short") = test {
+ val q"${s: Short}" = Literal(Constant(0: Short))
+ assert(s.isInstanceOf[Short] && s == 0)
+ }
+
+ property("unlift int") = test {
+ val q"${i: Int}" = Literal(Constant(0: Int))
+ assert(i.isInstanceOf[Int] && i == 0)
+ }
+
+ property("unlift long") = test {
+ val q"${l: Long}" = Literal(Constant(0L: Long))
+ assert(l.isInstanceOf[Long] && l == 0L)
+ }
+
+ property("unlift float") = test {
+ val q"${f: Float}" = Literal(Constant(0.0f: Float))
+ assert(f.isInstanceOf[Float] && f == 0.0f)
+ }
+
+ property("unlift double") = test {
+ val q"${d: Double}" = Literal(Constant(0.0: Double))
+ assert(d.isInstanceOf[Double] && d == 0.0)
+ }
+
+ property("unlift bool") = test {
+ val q"${b: Boolean}" = q"true"
+ assert(b.isInstanceOf[Boolean] && b == true)
+ }
+
+ property("unlift string") = test {
+ val q"${s: String}" = q""" "foo" """
+ assert(s.isInstanceOf[String] && s == "foo")
+ }
+
+ property("unlift scala.symbol") = test {
+ val q"${s: scala.Symbol}" = q"'foo"
+ assert(s.isInstanceOf[scala.Symbol] && s == 'foo)
+ }
+
+ implicit def unliftList[T: Unliftable]: Unliftable[List[T]] = Unliftable {
+ case q"scala.collection.immutable.List(..$args)" if args.forall { implicitly[Unliftable[T]].unapply(_).nonEmpty } =>
+ val ut = implicitly[Unliftable[T]]
+ args.flatMap { ut.unapply(_) }
+ }
+
+ property("unlift list (1)") = test {
+ val orig = List(1, 2)
+ val q"${l1: List[Int]}" = q"$orig" // q"List(1, 2)"
+ assert(l1 == orig)
+ val q"f(..${l2: List[Int]})" = q"f(..$orig)" // q"f(1, 2)
+ assert(l2 == orig)
+ }
+
+ property("unlift list (2)") = test {
+ val orig2 = List(List(1, 2), List(3))
+ val q"f(${l3: List[List[Int]]})" = q"f($orig2)" // q"f(List(List(1, 2), List(3)))
+ assert(l3 == orig2)
+ val q"f(..${l4: List[List[Int]]})" = q"f(..$orig2)" // q"f(List(1, 2), List(3))"
+ assert(l4 == orig2)
+ val q"f(...${l5: List[List[Int]]})" = q"f(...$orig2)" // q"f(1, 2)(3)
+ assert(l5 == orig2)
+ }
+
+ property("don't unlift non-tree splicee (1)") = test {
+ val q"${a: TermName}.${b: TermName}" = q"a.b"
+ assert(a == TermName("a"))
+ assert(b == TermName("b"))
+ }
+
+ property("don't unlift non-tree splicee (2)") = test {
+ val q"${mods: Modifiers} def foo" = q"def foo"
+ assert(mods == Modifiers(DEFERRED))
+ }
+}