diff options
author | Den Shabalin <den.shabalin@gmail.com> | 2013-12-02 16:56:37 +0100 |
---|---|---|
committer | Den Shabalin <den.shabalin@gmail.com> | 2013-12-10 16:02:45 +0100 |
commit | 1188f95acf71486c4a75b9ad428a92e6e401f5cd (patch) | |
tree | 9eb308c7f20bbffc50d38886da2a8a91889368a9 /test/files/scalacheck | |
parent | 4c899ea34c01eebf1215abd579d11393cf20a487 (diff) | |
download | scala-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')
-rw-r--r-- | test/files/scalacheck/quasiquotes/Test.scala | 1 | ||||
-rw-r--r-- | test/files/scalacheck/quasiquotes/UnliftableProps.scala | 112 |
2 files changed, 113 insertions, 0 deletions
diff --git a/test/files/scalacheck/quasiquotes/Test.scala b/test/files/scalacheck/quasiquotes/Test.scala index 8b1e779ab2..0253533248 100644 --- a/test/files/scalacheck/quasiquotes/Test.scala +++ b/test/files/scalacheck/quasiquotes/Test.scala @@ -8,6 +8,7 @@ object Test extends Properties("quasiquotes") { include(PatternConstructionProps) include(PatternDeconstructionProps) include(LiftableProps) + include(UnliftableProps) include(ErrorProps) include(DefinitionConstructionProps) include(DefinitionDeconstructionProps) 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)) + } +} |