Skip to content

Commit 312f45d

Browse files
committed
Merge pull request scala#3255 from densh/pr/unliftable-3
Introduce Unliftable for Quasiquotes (take #3)
2 parents b345b42 + 495b7b8 commit 312f45d

34 files changed

+1081
-402
lines changed

src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala

+3-1
Original file line numberDiff line numberDiff line change
@@ -391,8 +391,10 @@ trait PatternTypers {
391391
else freshUnapplyArgType()
392392
)
393393
)
394+
val unapplyArgTree = Ident(unapplyArg) updateAttachment SubpatternsAttachment(args)
395+
394396
// clearing the type is necessary so that ref will be stabilized; see bug 881
395-
val fun1 = typedPos(fun.pos)(Apply(Select(fun.clearType(), unapplyMethod), Ident(unapplyArg) :: Nil))
397+
val fun1 = typedPos(fun.pos)(Apply(Select(fun.clearType(), unapplyMethod), unapplyArgTree :: Nil))
396398

397399
def makeTypedUnApply() = {
398400
// the union of the expected type and the inferred type of the argument to unapply

src/compiler/scala/tools/reflect/quasiquotes/Holes.scala

+148-132
Large diffs are not rendered by default.

src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala

+6-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,12 @@ trait Parsers { self: Quasiquotes =>
161161
}
162162

163163
object TermParser extends Parser {
164-
def entryPoint = { parser => gen.mkTreeOrBlock(parser.templateOrTopStatSeq()) }
164+
def entryPoint = { parser =>
165+
parser.templateOrTopStatSeq() match {
166+
case head :: Nil => Block(Nil, head)
167+
case lst => gen.mkTreeOrBlock(lst)
168+
}
169+
}
165170
}
166171

167172
object TypeParser extends Parser {

src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala

+23-18
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import scala.collection.{immutable, mutable}
1313
trait Placeholders { self: Quasiquotes =>
1414
import global._
1515
import Cardinality._
16+
import universeTypes._
1617

1718
// Step 1: Transform Scala source with holes into vanilla Scala source
1819

@@ -32,13 +33,17 @@ trait Placeholders { self: Quasiquotes =>
3233
def appendHole(tree: Tree, cardinality: Cardinality) = {
3334
val placeholderName = c.freshName(TermName(nme.QUASIQUOTE_PREFIX + sessionSuffix))
3435
sb.append(placeholderName)
35-
val holeTree = if (method == nme.unapply) Bind(placeholderName, Ident(nme.WILDCARD)) else tree
36-
holeMap(placeholderName) = Hole(holeTree, cardinality)
36+
val holeTree =
37+
if (method != nme.unapply) tree
38+
else Bind(placeholderName, tree)
39+
holeMap(placeholderName) = Hole(cardinality, holeTree)
3740
}
3841

3942
val iargs = method match {
4043
case nme.apply => args
41-
case nme.unapply => List.fill(parts.length - 1)(EmptyTree)
44+
case nme.unapply =>
45+
val (dummy @ Ident(nme.SELECTOR_DUMMY)) :: Nil = args
46+
dummy.attachments.get[SubpatternsAttachment].get.patterns
4247
case _ => global.abort("unreachable")
4348
}
4449

@@ -78,9 +83,9 @@ trait Placeholders { self: Quasiquotes =>
7883

7984
trait HolePlaceholder {
8085
def matching: PartialFunction[Any, Name]
81-
def unapply(scrutinee: Any): Option[(Tree, Location, Cardinality)] = {
86+
def unapply(scrutinee: Any): Option[Hole] = {
8287
val name = matching.lift(scrutinee)
83-
name.flatMap { holeMap.get(_).map { case Hole(repr, loc, card) => (repr, loc, card) } }
88+
name.flatMap { holeMap.get(_) }
8489
}
8590
}
8691

@@ -128,44 +133,44 @@ trait Placeholders { self: Quasiquotes =>
128133
}
129134

130135
object SymbolPlaceholder {
131-
def unapply(scrutinee: Any): Option[Tree] = scrutinee match {
132-
case Placeholder(tree, SymbolLocation, _) => Some(tree)
136+
def unapply(scrutinee: Any): Option[Hole] = scrutinee match {
137+
case Placeholder(hole: ApplyHole) if hole.tpe <:< symbolType => Some(hole)
133138
case _ => None
134139
}
135140
}
136141

137142
object CasePlaceholder {
138-
def unapply(tree: Tree): Option[(Tree, Location, Cardinality)] = tree match {
139-
case CaseDef(Apply(Ident(nme.QUASIQUOTE_CASE), List(Placeholder(tree, location, card))), EmptyTree, EmptyTree) => Some((tree, location, card))
143+
def unapply(tree: Tree): Option[Hole] = tree match {
144+
case CaseDef(Apply(Ident(nme.QUASIQUOTE_CASE), List(Placeholder(hole))), EmptyTree, EmptyTree) => Some(hole)
140145
case _ => None
141146
}
142147
}
143148

144149
object RefineStatPlaceholder {
145-
def unapply(tree: Tree): Option[(Tree, Location, Cardinality)] = tree match {
146-
case ValDef(_, Placeholder(tree, location, card), Ident(tpnme.QUASIQUOTE_REFINE_STAT), _) => Some((tree, location, card))
150+
def unapply(tree: Tree): Option[Hole] = tree match {
151+
case ValDef(_, Placeholder(hole), Ident(tpnme.QUASIQUOTE_REFINE_STAT), _) => Some(hole)
147152
case _ => None
148153
}
149154
}
150155

151156
object EarlyDefPlaceholder {
152-
def unapply(tree: Tree): Option[(Tree, Location, Cardinality)] = tree match {
153-
case ValDef(_, Placeholder(tree, location, card), Ident(tpnme.QUASIQUOTE_EARLY_DEF), _) => Some((tree, location, card))
157+
def unapply(tree: Tree): Option[Hole] = tree match {
158+
case ValDef(_, Placeholder(hole), Ident(tpnme.QUASIQUOTE_EARLY_DEF), _) => Some(hole)
154159
case _ => None
155160
}
156161
}
157162

158163
object PackageStatPlaceholder {
159-
def unapply(tree: Tree): Option[(Tree, Location, Cardinality)] = tree match {
160-
case ValDef(NoMods, Placeholder(tree, location, card), Ident(tpnme.QUASIQUOTE_PACKAGE_STAT), EmptyTree) => Some((tree, location, card))
164+
def unapply(tree: Tree): Option[Hole] = tree match {
165+
case ValDef(NoMods, Placeholder(hole), Ident(tpnme.QUASIQUOTE_PACKAGE_STAT), EmptyTree) => Some(hole)
161166
case _ => None
162167
}
163168
}
164169

165170
object ForEnumPlaceholder {
166-
def unapply(tree: Tree): Option[(Tree, Location, Cardinality)] = tree match {
167-
case build.SyntacticValFrom(Bind(Placeholder(tree, location, card), Ident(nme.WILDCARD)), Ident(nme.QUASIQUOTE_FOR_ENUM)) =>
168-
Some((tree, location, card))
171+
def unapply(tree: Tree): Option[Hole] = tree match {
172+
case build.SyntacticValFrom(Bind(Placeholder(hole), Ident(nme.WILDCARD)), Ident(nme.QUASIQUOTE_FOR_ENUM)) =>
173+
Some(hole)
169174
case _ => None
170175
}
171176
}

0 commit comments

Comments
 (0)