summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDen Shabalin <den.shabalin@gmail.com>2013-09-05 13:35:42 +0200
committerDen Shabalin <den.shabalin@gmail.com>2013-09-05 20:42:10 +0200
commita455858fc19e47dca10f446df0f61297d0d60276 (patch)
tree002b867b22f973757c76ca70b506451987f6cf73
parent546e94099d667c6395582fcba321ef95578121a5 (diff)
downloadscala-a455858fc19e47dca10f446df0f61297d0d60276.tar.gz
scala-a455858fc19e47dca10f446df0f61297d0d60276.tar.bz2
scala-a455858fc19e47dca10f446df0f61297d0d60276.zip
SI-7723 better support for deconstruction of new expressions
-rw-r--r--src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala4
-rw-r--r--src/reflect/scala/reflect/api/BuildUtils.scala7
-rw-r--r--src/reflect/scala/reflect/internal/BuildUtils.scala15
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala1
-rw-r--r--test/files/scalacheck/quasiquotes/TermDeconstructionProps.scala17
5 files changed, 43 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
index fa305f3d07..cb84b5d8c7 100644
--- a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
+++ b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
@@ -9,7 +9,7 @@ trait Reifiers { self: Quasiquotes =>
import global._
import global.build.{SyntacticClassDef, SyntacticTraitDef, SyntacticModuleDef,
SyntacticBlock, SyntacticApplied, SyntacticTypeApplied,
- SyntacticFunction}
+ SyntacticFunction, SyntacticNew}
import global.treeInfo._
import global.definitions._
import Cardinality._
@@ -62,6 +62,8 @@ trait Reifiers { self: Quasiquotes =>
earlyDefs, parents, selfdef, body)
case SyntacticModuleDef(mods, name, earlyDefs, parents, selfdef, body) =>
reifyBuildCall(nme.SyntacticModuleDef, mods, name, earlyDefs, parents, selfdef, body)
+ case SyntacticNew(earlyDefs, parents, selfdef, body) =>
+ reifyBuildCall(nme.SyntacticNew, earlyDefs, parents, selfdef, body)
case SyntacticApplied(fun, argss) if argss.length > 1 =>
reifyBuildCall(nme.SyntacticApplied, fun, argss)
case SyntacticApplied(fun, argss @ (_ :+ (_ :+ Placeholder(_, _, DotDotDot)))) =>
diff --git a/src/reflect/scala/reflect/api/BuildUtils.scala b/src/reflect/scala/reflect/api/BuildUtils.scala
index 8b2e02c639..7b3e287da7 100644
--- a/src/reflect/scala/reflect/api/BuildUtils.scala
+++ b/src/reflect/scala/reflect/api/BuildUtils.scala
@@ -154,6 +154,13 @@ private[reflect] trait BuildUtils { self: Universe =>
def unapply(tree: Tree): Option[List[Tree]]
}
+ val SyntacticNew: SyntacticNewExtractor
+
+ trait SyntacticNewExtractor {
+ def apply(earlyDefs: List[Tree], parents: List[Tree], selfdef: ValDef, body: List[Tree]): Tree
+ def unapply(tree: Tree): Option[(List[Tree], List[Tree], ValDef, List[Tree])]
+ }
+
val SyntacticFunctionType: SyntacticFunctionTypeExtractor
trait SyntacticFunctionTypeExtractor {
diff --git a/src/reflect/scala/reflect/internal/BuildUtils.scala b/src/reflect/scala/reflect/internal/BuildUtils.scala
index 936ca91c68..eaa4f7cba8 100644
--- a/src/reflect/scala/reflect/internal/BuildUtils.scala
+++ b/src/reflect/scala/reflect/internal/BuildUtils.scala
@@ -343,6 +343,21 @@ trait BuildUtils { self: SymbolTable =>
case _ => None
}
}
+
+ object SyntacticNew extends SyntacticNewExtractor {
+ def apply(earlyDefs: List[Tree], parents: List[Tree], selfdef: ValDef, body: List[Tree]): Tree =
+ gen.mkNew(parents, selfdef, earlyDefs ::: body, NoPosition, NoPosition)
+
+ def unapply(tree: Tree): Option[(List[Tree], List[Tree], ValDef, List[Tree])] = tree match {
+ case SyntacticApplied(Select(New(SyntacticTypeApplied(ident, targs)), nme.CONSTRUCTOR), argss) =>
+ Some((Nil, SyntacticApplied(SyntacticTypeApplied(ident, targs), argss) :: Nil, emptyValDef, Nil))
+ case SyntacticBlock(SyntacticClassDef(_, tpnme.ANON_CLASS_NAME, Nil, _, List(Nil), earlyDefs, parents, selfdef, body) ::
+ Apply(Select(New(Ident(tpnme.ANON_CLASS_NAME)), nme.CONSTRUCTOR), Nil) :: Nil) =>
+ Some((earlyDefs, parents, selfdef, body))
+ case _ =>
+ None
+ }
+ }
}
val build: BuildApi = new BuildImpl
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index b9a32c481f..9ae86059f1 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -595,6 +595,7 @@ trait StdNames {
val SyntacticFunction: NameType = "SyntacticFunction"
val SyntacticFunctionType: NameType= "SyntacticFunctionType"
val SyntacticModuleDef: NameType = "SyntacticModuleDef"
+ val SyntacticNew: NameType = "SyntacticNew"
val SyntacticTraitDef: NameType = "SyntacticTraitDef"
val SyntacticTypeApplied: NameType = "SyntacticTypeApplied"
val This: NameType = "This"
diff --git a/test/files/scalacheck/quasiquotes/TermDeconstructionProps.scala b/test/files/scalacheck/quasiquotes/TermDeconstructionProps.scala
index 762625a46a..45c7ee4bb7 100644
--- a/test/files/scalacheck/quasiquotes/TermDeconstructionProps.scala
+++ b/test/files/scalacheck/quasiquotes/TermDeconstructionProps.scala
@@ -74,4 +74,21 @@ object TermDeconstructionProps extends QuasiquoteProperties("term deconstruction
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 => }")
+ }
}