summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala4
-rw-r--r--src/reflect/scala/reflect/internal/ReificationSupport.scala29
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala1
-rw-r--r--src/reflect/scala/reflect/internal/TreeGen.scala2
4 files changed, 21 insertions, 15 deletions
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
index 61fb22bc73..481897d0ec 100644
--- a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
+++ b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
@@ -202,10 +202,14 @@ trait Reifiers { self: Quasiquotes =>
// not to cause infinite recursion.
case block @ SyntacticBlock(stats) if block.isInstanceOf[Block] =>
reifyBuildCall(nme.SyntacticBlock, stats)
+ case SyntheticUnit() =>
+ reifyBuildCall(nme.SyntacticBlock, Nil)
case Try(block, catches, finalizer) =>
reifyBuildCall(nme.SyntacticTry, block, catches, finalizer)
case Match(selector, cases) =>
reifyBuildCall(nme.SyntacticMatch, selector, cases)
+ case CaseDef(pat, guard, body) if fillListHole.isDefinedAt(body) =>
+ mirrorCall(nme.CaseDef, reify(pat), reify(guard), mirrorBuildCall(nme.SyntacticBlock, fillListHole(body)))
// parser emits trees with scala package symbol to ensure
// that some names hygienically point to various scala package
// members; we need to preserve this symbol to preserve
diff --git a/src/reflect/scala/reflect/internal/ReificationSupport.scala b/src/reflect/scala/reflect/internal/ReificationSupport.scala
index ea230a215b..7f345845fe 100644
--- a/src/reflect/scala/reflect/internal/ReificationSupport.scala
+++ b/src/reflect/scala/reflect/internal/ReificationSupport.scala
@@ -94,7 +94,11 @@ trait ReificationSupport { self: SymbolTable =>
def setSymbol[T <: Tree](tree: T, sym: Symbol): T = { tree.setSymbol(sym); tree }
- def toStats(tree: Tree): List[Tree] = SyntacticBlock.unapply(tree).get
+ def toStats(tree: Tree): List[Tree] = tree match {
+ case EmptyTree => Nil
+ case SyntacticBlock(stats) => stats
+ case _ => throw new IllegalArgumentException(s"can't flatten $tree")
+ }
def mkAnnotation(tree: Tree): Tree = tree match {
case SyntacticNew(Nil, SyntacticApplied(SyntacticTypeApplied(_, _), _) :: Nil, noSelfType, Nil) =>
@@ -239,7 +243,7 @@ trait ReificationSupport { self: SymbolTable =>
def unapply(templ: Template): Option[(List[Tree], ValDef, Modifiers, List[List[ValDef]], List[Tree], List[Tree])] = {
val Template(parents, selfType, _) = templ
val tbody = treeInfo.untypecheckedTemplBody(templ)
-
+
def result(ctorMods: Modifiers, vparamss: List[List[ValDef]], edefs: List[Tree], body: List[Tree]) =
Some((parents, selfType, ctorMods, vparamss, edefs, body))
def indexOfCtor(trees: List[Tree]) =
@@ -448,28 +452,25 @@ trait ReificationSupport { self: SymbolTable =>
* block as a list of elements rather than (stats, expr) pair
* it also:
*
- * 1. Treats of q"" (empty tree) as zero-element block.
- *
- * 2. Strips trailing synthetic units which are inserted by the
+ * 1. Strips trailing synthetic units which are inserted by the
* compiler if the block ends with a definition rather
- * than an expression.
+ * than an expression or is empty.
*
- * 3. Matches non-block term trees and recognizes them as
+ * 2. Matches non-block term trees and recognizes them as
* single-element blocks for sake of consistency with
* compiler's default to treat single-element blocks with
- * expressions as just expressions.
+ * expressions as just expressions. The only exception is q""
+ * which is not considered to be a block.
*/
object SyntacticBlock extends SyntacticBlockExtractor {
- def apply(stats: List[Tree]): Tree =
- if (stats.isEmpty) EmptyTree
- else gen.mkBlock(stats)
+ def apply(stats: List[Tree]): Tree = gen.mkBlock(stats)
def unapply(tree: Tree): Option[List[Tree]] = tree match {
case bl @ self.Block(stats, SyntheticUnit()) => Some(treeInfo.untypecheckedBlockBody(bl))
case bl @ self.Block(stats, expr) => Some(treeInfo.untypecheckedBlockBody(bl) :+ expr)
- case EmptyTree => Some(Nil)
- case _ if tree.isTerm => Some(tree :: Nil)
- case _ => None
+ case SyntheticUnit() => Some(Nil)
+ case _ if tree.isTerm && tree.nonEmpty => Some(tree :: Nil)
+ case _ => None
}
}
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index f3467ff9f4..339923a061 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -580,6 +580,7 @@ trait StdNames {
val AnyVal: NameType = "AnyVal"
val Apply: NameType = "Apply"
val ArrayAnnotArg: NameType = "ArrayAnnotArg"
+ val CaseDef: NameType = "CaseDef"
val ClassInfoType: NameType = "ClassInfoType"
val ConstantType: NameType = "ConstantType"
val EmptyPackage: NameType = "EmptyPackage"
diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala
index 6011289baf..9066c73393 100644
--- a/src/reflect/scala/reflect/internal/TreeGen.scala
+++ b/src/reflect/scala/reflect/internal/TreeGen.scala
@@ -452,7 +452,7 @@ abstract class TreeGen {
/** Create block of statements `stats` */
def mkBlock(stats: List[Tree]): Tree =
- if (stats.isEmpty) Literal(Constant(()))
+ if (stats.isEmpty) mkSyntheticUnit()
else if (!stats.last.isTerm) Block(stats, mkSyntheticUnit())
else if (stats.length == 1) stats.head
else Block(stats.init, stats.last)