summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2014-02-07 17:06:58 +0100
committerEugene Burmako <xeno.by@gmail.com>2014-02-07 17:06:58 +0100
commit947baf2473a1f797545147e551740900013e5b1d (patch)
tree44c060566ff4652db5b25f89ef67022d668b2767
parent3306967c561e3ea34306419d5351b4e20673cc8b (diff)
parenta98eee51760c4961a5419747d2828d9765a9754b (diff)
downloadscala-947baf2473a1f797545147e551740900013e5b1d.tar.gz
scala-947baf2473a1f797545147e551740900013e5b1d.tar.bz2
scala-947baf2473a1f797545147e551740900013e5b1d.zip
Merge pull request #3477 from densh/topic/syntactic-empty-type-tree
Rename EmptyTypTree into SyntacticEmptyTypeTree
-rw-r--r--src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala2
-rw-r--r--src/reflect/scala/reflect/api/BuildUtils.scala7
-rw-r--r--src/reflect/scala/reflect/internal/BuildUtils.scala24
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala1
-rw-r--r--test/files/scalacheck/quasiquotes/TypeConstructionProps.scala2
-rw-r--r--test/files/scalacheck/quasiquotes/TypeDeconstructionProps.scala6
-rw-r--r--test/files/scalacheck/quasiquotes/TypecheckedProps.scala9
7 files changed, 38 insertions, 13 deletions
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
index 0c73214745..2eb50d5993 100644
--- a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
+++ b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
@@ -190,6 +190,8 @@ trait Reifiers { self: Quasiquotes =>
reifyBuildCall(nme.SyntacticFunction, args, body)
case SyntacticIdent(name, isBackquoted) =>
reifyBuildCall(nme.SyntacticIdent, name, isBackquoted)
+ case SyntacticEmptyTypeTree() =>
+ reifyBuildCall(nme.SyntacticEmptyTypeTree)
case Q(Placeholder(Hole(tree, DotDot))) =>
mirrorBuildCall(nme.SyntacticBlock, tree)
case Q(other) =>
diff --git a/src/reflect/scala/reflect/api/BuildUtils.scala b/src/reflect/scala/reflect/api/BuildUtils.scala
index 3bcf751ace..7aaa3973b3 100644
--- a/src/reflect/scala/reflect/api/BuildUtils.scala
+++ b/src/reflect/scala/reflect/api/BuildUtils.scala
@@ -248,6 +248,13 @@ private[reflect] trait BuildUtils { self: Universe =>
def unapply(tree: Tree): Option[(Tree)]
}
+ val SyntacticEmptyTypeTree: SyntacticEmptyTypeTreeExtractor
+
+ trait SyntacticEmptyTypeTreeExtractor {
+ def apply(): TypeTree
+ def unapply(tt: TypeTree): Boolean
+ }
+
val SyntacticFor: SyntacticForExtractor
val SyntacticForYield: SyntacticForExtractor
diff --git a/src/reflect/scala/reflect/internal/BuildUtils.scala b/src/reflect/scala/reflect/internal/BuildUtils.scala
index 6106339324..458c10e69b 100644
--- a/src/reflect/scala/reflect/internal/BuildUtils.scala
+++ b/src/reflect/scala/reflect/internal/BuildUtils.scala
@@ -537,13 +537,15 @@ trait BuildUtils { self: SymbolTable =>
def unapply(tree: Tree): Option[Tree] = gen.Filter.unapply(tree)
}
- // abstract over possible alternative representations of no type in valdef
- protected object EmptyTypTree {
- def unapply(tree: Tree): Boolean = tree match {
- case EmptyTree => true
- case tt: TypeTree if (tt.original == null || tt.original.isEmpty) => true
- case _ => false
- }
+ // If a tree in type position isn't provided by the user (e.g. `tpt` fields of
+ // `ValDef` and `DefDef`, function params etc), then it's going to be parsed as
+ // TypeTree with empty original and empty tpe. This extractor matches such trees
+ // so that one can write q"val x = 2" to match typecheck(q"val x = 2"). Note that
+ // TypeTree() is the only possible representation for empty trees in type positions.
+ // We used to sometimes receive EmptyTree in such cases, but not anymore.
+ object SyntacticEmptyTypeTree extends SyntacticEmptyTypeTreeExtractor {
+ def apply(): TypeTree = self.TypeTree()
+ def unapply(tt: TypeTree): Boolean = tt.original == null || tt.original.isEmpty
}
// match a sequence of desugared `val $pat = $value`
@@ -561,8 +563,8 @@ trait BuildUtils { self: SymbolTable =>
case ValDef(_, name1, _, Match(MaybeUnchecked(value), CaseDef(pat, EmptyTree, Ident(name2)) :: Nil)) :: UnPatSeq(rest)
if name1 == name2 =>
Some((pat, value) :: rest)
- // case q"${_} val $name: ${EmptyTypTree()} = $value" :: UnPatSeq(rest) =>
- case ValDef(_, name, EmptyTypTree(), value) :: UnPatSeq(rest) =>
+ // case q"${_} val $name: ${SyntacticEmptyTypeTree()} = $value" :: UnPatSeq(rest) =>
+ case ValDef(_, name, SyntacticEmptyTypeTree(), value) :: UnPatSeq(rest) =>
Some((Bind(name, self.Ident(nme.WILDCARD)), value) :: rest)
// case q"${_} val $name: $tpt = $value" :: UnPatSeq(rest) =>
case ValDef(_, name, tpt, value) :: UnPatSeq(rest) =>
@@ -604,8 +606,8 @@ trait BuildUtils { self: SymbolTable =>
def unapply(tree: Tree): Option[(Tree, Tree)] = tree match {
case Function(ValDef(Modifiers(PARAM, _, _), name, tpt, EmptyTree) :: Nil, body) =>
tpt match {
- case EmptyTypTree() => Some((Bind(name, self.Ident(nme.WILDCARD)), body))
- case _ => Some((Bind(name, Typed(self.Ident(nme.WILDCARD), tpt)), body))
+ case SyntacticEmptyTypeTree() => Some((Bind(name, self.Ident(nme.WILDCARD)), body))
+ case _ => Some((Bind(name, Typed(self.Ident(nme.WILDCARD), tpt)), body))
}
case UnVisitor(_, CaseDef(pat, EmptyTree, body) :: Nil) =>
Some((pat, body))
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index 53475be479..7c979e7bdc 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -602,6 +602,7 @@ trait StdNames {
val SyntacticBlock: NameType = "SyntacticBlock"
val SyntacticClassDef: NameType = "SyntacticClassDef"
val SyntacticDefDef: NameType = "SyntacticDefDef"
+ val SyntacticEmptyTypeTree: NameType = "SyntacticEmptyTypeTree"
val SyntacticFilter: NameType = "SyntacticFilter"
val SyntacticFor: NameType = "SyntacticFor"
val SyntacticForYield: NameType = "SyntacticForYield"
diff --git a/test/files/scalacheck/quasiquotes/TypeConstructionProps.scala b/test/files/scalacheck/quasiquotes/TypeConstructionProps.scala
index 0984032084..78b54a4e49 100644
--- a/test/files/scalacheck/quasiquotes/TypeConstructionProps.scala
+++ b/test/files/scalacheck/quasiquotes/TypeConstructionProps.scala
@@ -30,7 +30,7 @@ object TypeConstructionProps extends QuasiquoteProperties("type construction")
}
property("empty tq") = test {
- val tt: TypeTree = tq" "
+ val tt: TypeTree = tq""
assert(tt.tpe == null)
assert(tt.original == null)
}
diff --git a/test/files/scalacheck/quasiquotes/TypeDeconstructionProps.scala b/test/files/scalacheck/quasiquotes/TypeDeconstructionProps.scala
index 44f110a3d5..0fdcc19052 100644
--- a/test/files/scalacheck/quasiquotes/TypeDeconstructionProps.scala
+++ b/test/files/scalacheck/quasiquotes/TypeDeconstructionProps.scala
@@ -52,4 +52,10 @@ object TypeDeconstructionProps extends QuasiquoteProperties("type deconstruction
assert(arglast ≈ tq"C")
assert(restpe ≈ tq"D")
}
+
+ property("match empty type tree") = test {
+ val tq"" = TypeTree()
+ // matches because type tree isn't syntactic without original
+ val tq"" = tq"${typeOf[Int]}"
+ }
}
diff --git a/test/files/scalacheck/quasiquotes/TypecheckedProps.scala b/test/files/scalacheck/quasiquotes/TypecheckedProps.scala
index 2f501435e3..3afb47952c 100644
--- a/test/files/scalacheck/quasiquotes/TypecheckedProps.scala
+++ b/test/files/scalacheck/quasiquotes/TypecheckedProps.scala
@@ -75,4 +75,11 @@ object TypecheckedProps extends QuasiquoteProperties("typechecked") {
assert(f.original ≈ pq"Test.this.Cell")
assert(args ≈ List(pq"v"))
}
-} \ No newline at end of file
+
+ property("extract inferred val type") = test {
+ val typechecked = typecheck(q"val x = 42")
+ val q"val x = 42" = typechecked
+ val q"val x: ${tq""} = 42" = typechecked
+ val q"val x: ${t: Type} = 42" = typechecked
+ }
+}