diff options
author | Den Shabalin <den.shabalin@gmail.com> | 2013-12-02 16:31:33 +0100 |
---|---|---|
committer | Den Shabalin <den.shabalin@gmail.com> | 2013-12-10 16:02:45 +0100 |
commit | 4c899ea34c01eebf1215abd579d11393cf20a487 (patch) | |
tree | 2b730c5274281f94b216f7f59a2ccfb7ef82160c /src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala | |
parent | 4be6ea147a7d8f300c1e6db2a216b50fe8cf5dc7 (diff) | |
download | scala-4c899ea34c01eebf1215abd579d11393cf20a487.tar.gz scala-4c899ea34c01eebf1215abd579d11393cf20a487.tar.bz2 scala-4c899ea34c01eebf1215abd579d11393cf20a487.zip |
Refactor Holes and Reifiers slices of Quasiquotes cake
This commit performs a number of preliminary refactoring needed to
implement unliftable:
1. Replace previous inheritance-heavy implementation of Holes with
similar but much simpler one. Holes are now split into two different
categories: ApplyHole and UnapplyHole which correspondingly represent
information about holes in construction and deconstruction quasiquotes.
2. Make Placeholders extract holes rather than their field values. This
is required to be able to get additional mode-specific information
from holes (e.g. only ApplyHoles have types).
3. Bring ApplyReifier & UnapplyReifier even closer to the future where
there is just a single base Reifier with mode parameter.
Along the way a few bugs were fixed:
1. SI-7980 SI-7996 fail with nice error on bottom types splices
2. Use asSeenFrom instead of typeArguments in parseCardinality.
This fixes a crash if T <:< Iterable[Tree] but does not itself
have any type arguments.
3. Fix spurious error message on splicing of Lists through Liftable[List[T]]
Diffstat (limited to 'src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala')
-rw-r--r-- | src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala | 41 |
1 files changed, 23 insertions, 18 deletions
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala b/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala index 54be9123c7..bdb44ad9a2 100644 --- a/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala +++ b/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala @@ -13,6 +13,7 @@ import scala.collection.{immutable, mutable} trait Placeholders { self: Quasiquotes => import global._ import Cardinality._ + import universeTypes._ // Step 1: Transform Scala source with holes into vanilla Scala source @@ -32,13 +33,17 @@ trait Placeholders { self: Quasiquotes => def appendHole(tree: Tree, cardinality: Cardinality) = { val placeholderName = c.freshName(TermName(nme.QUASIQUOTE_PREFIX + sessionSuffix)) sb.append(placeholderName) - val holeTree = if (method == nme.unapply) Bind(placeholderName, Ident(nme.WILDCARD)) else tree - holeMap(placeholderName) = Hole(holeTree, cardinality) + val holeTree = + if (method != nme.unapply) tree + else Bind(placeholderName, tree) + holeMap(placeholderName) = Hole(cardinality, holeTree) } val iargs = method match { case nme.apply => args - case nme.unapply => List.fill(parts.length - 1)(EmptyTree) + case nme.unapply => + val (dummy @ Ident(nme.SELECTOR_DUMMY)) :: Nil = args + dummy.attachments.get[SubpatternsAttachment].get.patterns case _ => global.abort("unreachable") } @@ -78,9 +83,9 @@ trait Placeholders { self: Quasiquotes => trait HolePlaceholder { def matching: PartialFunction[Any, Name] - def unapply(scrutinee: Any): Option[(Tree, Location, Cardinality)] = { + def unapply(scrutinee: Any): Option[Hole] = { val name = matching.lift(scrutinee) - name.flatMap { holeMap.get(_).map { case Hole(repr, loc, card) => (repr, loc, card) } } + name.flatMap { holeMap.get(_) } } } @@ -128,44 +133,44 @@ trait Placeholders { self: Quasiquotes => } object SymbolPlaceholder { - def unapply(scrutinee: Any): Option[Tree] = scrutinee match { - case Placeholder(tree, SymbolLocation, _) => Some(tree) + def unapply(scrutinee: Any): Option[Hole] = scrutinee match { + case Placeholder(hole: ApplyHole) if hole.tpe <:< symbolType => Some(hole) case _ => None } } object CasePlaceholder { - def unapply(tree: Tree): Option[(Tree, Location, Cardinality)] = tree match { - case CaseDef(Apply(Ident(nme.QUASIQUOTE_CASE), List(Placeholder(tree, location, card))), EmptyTree, EmptyTree) => Some((tree, location, card)) + def unapply(tree: Tree): Option[Hole] = tree match { + case CaseDef(Apply(Ident(nme.QUASIQUOTE_CASE), List(Placeholder(hole))), EmptyTree, EmptyTree) => Some(hole) case _ => None } } object RefineStatPlaceholder { - def unapply(tree: Tree): Option[(Tree, Location, Cardinality)] = tree match { - case ValDef(_, Placeholder(tree, location, card), Ident(tpnme.QUASIQUOTE_REFINE_STAT), _) => Some((tree, location, card)) + def unapply(tree: Tree): Option[Hole] = tree match { + case ValDef(_, Placeholder(hole), Ident(tpnme.QUASIQUOTE_REFINE_STAT), _) => Some(hole) case _ => None } } object EarlyDefPlaceholder { - def unapply(tree: Tree): Option[(Tree, Location, Cardinality)] = tree match { - case ValDef(_, Placeholder(tree, location, card), Ident(tpnme.QUASIQUOTE_EARLY_DEF), _) => Some((tree, location, card)) + def unapply(tree: Tree): Option[Hole] = tree match { + case ValDef(_, Placeholder(hole), Ident(tpnme.QUASIQUOTE_EARLY_DEF), _) => Some(hole) case _ => None } } object PackageStatPlaceholder { - def unapply(tree: Tree): Option[(Tree, Location, Cardinality)] = tree match { - case ValDef(NoMods, Placeholder(tree, location, card), Ident(tpnme.QUASIQUOTE_PACKAGE_STAT), EmptyTree) => Some((tree, location, card)) + def unapply(tree: Tree): Option[Hole] = tree match { + case ValDef(NoMods, Placeholder(hole), Ident(tpnme.QUASIQUOTE_PACKAGE_STAT), EmptyTree) => Some(hole) case _ => None } } object ForEnumPlaceholder { - def unapply(tree: Tree): Option[(Tree, Location, Cardinality)] = tree match { - case build.SyntacticValFrom(Bind(Placeholder(tree, location, card), Ident(nme.WILDCARD)), Ident(nme.QUASIQUOTE_FOR_ENUM)) => - Some((tree, location, card)) + def unapply(tree: Tree): Option[Hole] = tree match { + case build.SyntacticValFrom(Bind(Placeholder(hole), Ident(nme.WILDCARD)), Ident(nme.QUASIQUOTE_FOR_ENUM)) => + Some(hole) case _ => None } } |