summaryrefslogtreecommitdiff
path: root/test/scalacheck/scala/reflect/quasiquotes/TermDeconstructionProps.scala
diff options
context:
space:
mode:
Diffstat (limited to 'test/scalacheck/scala/reflect/quasiquotes/TermDeconstructionProps.scala')
-rw-r--r--test/scalacheck/scala/reflect/quasiquotes/TermDeconstructionProps.scala258
1 files changed, 258 insertions, 0 deletions
diff --git a/test/scalacheck/scala/reflect/quasiquotes/TermDeconstructionProps.scala b/test/scalacheck/scala/reflect/quasiquotes/TermDeconstructionProps.scala
new file mode 100644
index 0000000000..73bfba41bc
--- /dev/null
+++ b/test/scalacheck/scala/reflect/quasiquotes/TermDeconstructionProps.scala
@@ -0,0 +1,258 @@
+package scala.reflect.quasiquotes
+
+import org.scalacheck._, Prop._, Gen._, Arbitrary._
+import scala.reflect.runtime.universe._, Flag._
+
+object TermDeconstructionProps extends QuasiquoteProperties("term deconstruction") {
+ property("f(..x) = f") = test {
+ // see SI-8008
+ assertThrows[MatchError] {
+ val q"f(..$args)" = q"f"
+ }
+ }
+
+ property("f(x)") = forAll { (x: Tree) =>
+ val q"f($x1)" = q"f($x)"
+ x1 ≈ x
+ }
+
+ property("f(..xs)") = forAll { (x1: Tree, x2: Tree) =>
+ val q"f(..$xs)" = q"f($x1, $x2)"
+ xs ≈ List(x1, x2)
+ }
+
+ property("f(y, ..ys)") = forAll { (x1: Tree, x2: Tree, x3: Tree) =>
+ val q"f($y, ..$ys)" = q"f($x1, $x2, $x3)"
+ y ≈ x1 && ys ≈ List(x2, x3)
+ }
+
+ property("f(y1, y2, ..ys)") = forAll { (x1: Tree, x2: Tree, x3: Tree) =>
+ val q"f($y1, $y2, ..$ys)" = q"f($x1, $x2, $x3)"
+ y1 ≈ x1 && y2 ≈ x2 && ys ≈ List(x3)
+ }
+
+ property("f(y1, ..ys, yn)") = forAll { (x1: Tree, x2: Tree, x3: Tree, x4: Tree) =>
+ val q"f($y1, ..$ys, $yn)" = q"f($x1, $x2, $x3, $x4)"
+ y1 ≈ x1 && ys ≈ List(x2, x3) && yn ≈ x4
+ }
+
+ property("f(..ys, y_{n-1}, y_n)") = forAll { (x1: Tree, x2: Tree, x3: Tree, x4: Tree) =>
+ val q"f(..$ys, $yn1, $yn)" = q"f($x1, $x2, $x3, $x4)"
+ ys ≈ List(x1, x2) && yn1 ≈ x3 && yn ≈ x4
+ }
+
+ property("f(...xss)") = forAll { (x1: Tree, x2: Tree) =>
+ val q"f(...$xss)" = q"f($x1)($x2)"
+ xss ≈ List(List(x1), List(x2))
+ }
+
+ property("f(...$xss)(..$last)") = forAll { (x1: Tree, x2: Tree, x3: Tree) =>
+ val q"f(...$xss)(..$last)" = q"f($x1)($x2)($x3)"
+ xss ≈ List(List(x1), List(x2)) && last ≈ List(x3)
+ }
+
+ property("f(...$xss)(..$lastinit, $lastlast)") = forAll { (x1: Tree, x2: Tree, x3: Tree, x4: Tree) =>
+ val q"f(...$xss)(..$lastinit, $lastlast)" = q"f($x1)($x2, $x3, $x4)"
+ xss ≈ List(List(x1)) && lastinit ≈ List(x2, x3) && lastlast ≈ x4
+ }
+
+ property("f(...xss) = f") = forAll { (x1: Tree, x2: Tree) =>
+ val q"f(...$xss)" = q"f"
+ xss ≈ List()
+ }
+
+ property("deconstruct unit as tuple") = test {
+ val q"(..$xs)" = q"()"
+ assert(xs.isEmpty)
+ }
+
+ property("deconstruct tuple") = test {
+ val q"(..$xs)" = q"(a, b)"
+ assert(xs ≈ List(q"a", q"b"))
+ }
+
+ property("deconstruct tuple mixed") = test {
+ val q"($first, ..$rest)" = q"(a, b, c)"
+ assert(first ≈ q"a")
+ assert(rest ≈ List(q"b", q"c"))
+ }
+
+ property("deconstruct tuple last element") = test {
+ val q"($first, ..$rest, $last)" = q"(a, b, c, d)"
+ assert(first ≈ q"a")
+ assert(rest ≈ List(q"b", q"c"))
+ assert(last ≈ q"d")
+ }
+
+ property("deconstruct expr as tuple") = test {
+ val q"(..$elems)" = q"foo"
+ assert(elems ≈ List(q"foo"))
+ }
+
+ property("deconstruct cases") = test {
+ val q"$x match { case ..$cases }" = q"x match { case 1 => case 2 => }"
+ assert(x ≈ q"x")
+ assert(cases ≈ List(cq"1 =>", cq"2 =>"))
+ }
+
+ property("deconstruct splitting last case") = test {
+ val q"$_ match { case ..$cases case $last }" = q"x match { case 1 => case 2 => case 3 => }"
+ assert(cases ≈ List(cq"1 =>", cq"2 =>"))
+ assert(last ≈ cq"3 =>")
+ }
+
+ property("deconstruct block") = test {
+ val q"{ ..$xs }" = q"{ x1; x2; x3 }"
+ assert(xs ≈ List(q"x1", q"x2", q"x3"))
+ }
+
+ property("deconstruct last element of a block") = test {
+ val q"{ ..$xs; $x }" = q"x1; x2; x3; x4"
+ assert(xs ≈ List(q"x1", q"x2", q"x3"))
+ assert(x ≈ q"x4")
+ }
+
+ property("exhaustive function matcher") = test {
+ def matches(line: String) { val q"(..$args) => $body" = parse(line) }
+ matches("() => bippy")
+ matches("(y: Y) => y oh y")
+ matches("(x: X, y: Y) => x and y")
+ }
+
+ property("exhaustive new pattern") = test {
+ def matches(line: String) {
+ val q"new { ..$early } with $name[..$targs](...$vargss) with ..$mixin { $self => ..$body }" = parse(line)
+ }
+ matches("new foo")
+ matches("new foo { body }")
+ matches("new foo[t]")
+ matches("new foo(x)")
+ matches("new foo[t](x)")
+ matches("new foo[t](x) { body }")
+ matches("new foo with bar")
+ matches("new foo with bar { body }")
+ matches("new { anonymous }")
+ matches("new { val early = 1 } with Parent[Int] { body }")
+ matches("new Foo { selfie => }")
+ }
+
+ property("exhaustive assign pattern") = test {
+ def matches(tree: Tree) { val q"$rhs = $lhs" = tree }
+ matches(parse("left = right"))
+ matches(parse("arr(1) = 2"))
+ matches(AssignOrNamedArg(EmptyTree, EmptyTree))
+ }
+
+ property("deconstruct update 1") = test {
+ val q"$obj(..$args) = $value" = q"foo(bar) = baz"
+ assert(obj ≈ q"foo")
+ assert(args ≈ List(q"bar"))
+ assert(value ≈ q"baz")
+ }
+
+ property("deconstruct update 2") = test {
+ val q"$left = $value" = q"foo(bar) = baz"
+ assert(left ≈ q"foo(bar)")
+ assert(value ≈ q"baz")
+ }
+
+ property("deconstruct while loop") = test {
+ val q"while($cond) $body" = parse("while(cond) body")
+ assert(cond ≈ q"cond")
+ assert(body ≈ q"body")
+ }
+
+ property("deconstruct do while loop") = test {
+ val q"do $body while($cond)" = parse("do body while(cond)")
+ assert(cond ≈ q"cond")
+ assert(body ≈ q"body")
+ }
+
+ property("deconstruct anonymous function with placeholders") = test {
+ val q"{ $f(_) }" = q"{ foo(_) }"
+ assert(f ≈ q"foo")
+ val q"{ _.$member }" = q"{ _.foo }"
+ assert(member ≈ TermName("foo"))
+ val q"{ _ + $x }" = q"{ _ + x }"
+ assert(x ≈ q"x")
+ val q"{ _ * _ }" = q"{ _ * _ }"
+ }
+
+ property("si-8275 a") = test {
+ val cq"_ => ..$stats" = cq"_ => foo; bar"
+ assert(stats ≈ List(q"foo", q"bar"))
+ }
+
+ property("si-8275 b") = test {
+ val cq"_ => ..$init; $last" = cq"_ => a; b; c"
+ assert(init ≈ List(q"a", q"b"))
+ assert(last ≈ q"c")
+ }
+
+ property("si-8275 c") = test {
+ val cq"_ => ..$stats" = cq"_ =>"
+ assert(stats.isEmpty)
+ assertEqAst(q"{ case _ => ..$stats }", "{ case _ => }")
+ }
+
+ property("can't flatten type into block") = test {
+ assertThrows[IllegalArgumentException] {
+ val tpt = tq"List[Int]"
+ q"..$tpt; ()"
+ }
+ }
+
+ property("term select doesn't match type select") = test {
+ assertThrows[MatchError] {
+ val q"$qual.$name" = tq"foo.bar"
+ }
+ }
+
+ property("type application doesn't match applied type") = test {
+ assertThrows[MatchError] {
+ val q"$f[..$targs]" = tq"foo[bar]"
+ }
+ }
+
+ property("match doesn't match partial function") = test {
+ assertThrows[MatchError] {
+ val q"$_ match { case ..$_ }" = q"{ case _ => }"
+ }
+ }
+
+ property("deconstruct partial function") = test {
+ val q"{ case ..$cases }" = q"{ case a => b case c => d }"
+ val List(cq"a => b", cq"c => d") = cases
+ }
+
+ property("SI-8350 `new C` and `new C()` are equivalent") = test {
+ val q"new C" = q"new C()"
+ val q"new C()" = q"new C"
+ }
+
+ property("SI-8350 new applications extracted only for non-empty ctor calls") = test{
+ val q"new $c1" = q"new C()"
+ assert(c1 ≈ tq"C")
+ val q"new $c2" = q"new C(x)"
+ assert(c2 ≈ q"${tq"C"}(x)")
+ }
+
+ property("SI-8350 original test case") = test {
+ val q"new ..$parents" = q"new Foo with Bar"
+ assert(parents ≈ List(tq"Foo", tq"Bar"))
+ }
+
+ property("SI-8387 new is not an application") = test {
+ val `new` = q"new F(x)"
+ val q"$f(...$argss)" = `new`
+ assert(f ≈ `new`)
+ assert(argss.isEmpty)
+ }
+
+ property("SI-8703 extract block with single expression") = test {
+ val q"{ $a }" = Block(Nil, q"1")
+ val Literal(Constant(1)) = a
+ val q"{ $b }" = q"2"
+ val Literal(Constant(2)) = b
+ }
+}