summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala7
-rw-r--r--src/reflect/scala/reflect/api/BuildUtils.scala16
-rw-r--r--src/reflect/scala/reflect/internal/BuildUtils.scala29
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala3
-rw-r--r--test/files/scalacheck/quasiquotes/DefinitionDeconstructionProps.scala9
5 files changed, 64 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
index 2e134ddd34..069ef09bc7 100644
--- a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
+++ b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
@@ -8,6 +8,7 @@ import scala.reflect.internal.Flags._
trait Reifiers { self: Quasiquotes =>
import global._
import global.build.{SyntacticClassDef, SyntacticTraitDef, SyntacticModuleDef,
+ SyntacticDefDef, SyntacticValDef, SyntacticVarDef,
SyntacticBlock, SyntacticApplied, SyntacticTypeApplied,
SyntacticFunction, SyntacticNew}
import global.treeInfo._
@@ -64,6 +65,12 @@ trait Reifiers { self: Quasiquotes =>
reifyBuildCall(nme.SyntacticModuleDef, mods, name, earlyDefs, parents, selfdef, body)
case SyntacticNew(earlyDefs, parents, selfdef, body) =>
reifyBuildCall(nme.SyntacticNew, earlyDefs, parents, selfdef, body)
+ case SyntacticDefDef(mods, name, tparams, vparamss, tpt, rhs) =>
+ reifyBuildCall(nme.SyntacticDefDef, mods, name, tparams, vparamss, tpt, rhs)
+ case SyntacticValDef(mods, name, tpt, rhs) =>
+ reifyBuildCall(nme.SyntacticValDef, mods, name, tpt, rhs)
+ case SyntacticVarDef(mods, name, tpt, rhs) =>
+ reifyBuildCall(nme.SyntacticVarDef, mods, name, tpt, rhs)
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 b80159d051..ee6515b547 100644
--- a/src/reflect/scala/reflect/api/BuildUtils.scala
+++ b/src/reflect/scala/reflect/api/BuildUtils.scala
@@ -175,5 +175,21 @@ private[reflect] trait BuildUtils { self: Universe =>
def unapply(tree: Tree): Option[(List[ValDef], Tree)]
}
+
+ val SyntacticDefDef: SyntacticDefDefExtractor
+
+ trait SyntacticDefDefExtractor {
+ def apply(mods: Modifiers, name: TermName, tparams: List[Tree], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): DefDef
+
+ def unapply(tree: Tree): Option[(Modifiers, TermName, List[Tree], List[List[ValDef]], Tree, Tree)]
+ }
+
+ val SyntacticValDef: SyntacticValDefExtractor
+ val SyntacticVarDef: SyntacticValDefExtractor
+
+ trait SyntacticValDefExtractor {
+ def apply(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree): ValDef
+ def unapply(tree: Tree): Option[(Modifiers, TermName, Tree, Tree)]
+ }
}
}
diff --git a/src/reflect/scala/reflect/internal/BuildUtils.scala b/src/reflect/scala/reflect/internal/BuildUtils.scala
index 0cbad0d641..7091b0e875 100644
--- a/src/reflect/scala/reflect/internal/BuildUtils.scala
+++ b/src/reflect/scala/reflect/internal/BuildUtils.scala
@@ -358,6 +358,35 @@ trait BuildUtils { self: SymbolTable =>
None
}
}
+
+ object SyntacticDefDef extends SyntacticDefDefExtractor {
+ def apply(mods: Modifiers, name: TermName, tparams: List[Tree], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): DefDef =
+ DefDef(mods, name, mkTparams(tparams), mkVparamss(vparamss), tpt, rhs)
+
+ def unapply(tree: Tree): Option[(Modifiers, TermName, List[Tree], List[List[ValDef]], Tree, Tree)] = tree match {
+ case DefDef(mods, name, tparams, vparamss, tpt, rhs) => Some((mods, name, tparams, vparamss, tpt, rhs))
+ case _ => None
+ }
+ }
+
+ trait SyntacticValDefBase extends SyntacticValDefExtractor {
+ val isMutable: Boolean
+
+ def apply(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree) = {
+ val mods1 = if (isMutable) mods | MUTABLE else mods
+ ValDef(mods1, name, tpt, rhs)
+ }
+
+ def unapply(tree: Tree): Option[(Modifiers, TermName, Tree, Tree)] = tree match {
+ case ValDef(mods, name, tpt, rhs) if mods.hasFlag(MUTABLE) == isMutable =>
+ Some((mods, name, tpt, rhs))
+ case _ =>
+ None
+ }
+ }
+
+ object SyntacticValDef extends SyntacticValDefBase { val isMutable = false }
+ object SyntacticVarDef extends SyntacticValDefBase { val isMutable = true }
}
val build: BuildApi = new BuildImpl
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index e52f3140c3..17a084f461 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -592,6 +592,7 @@ trait StdNames {
val SyntacticApplied: NameType = "SyntacticApplied"
val SyntacticBlock: NameType = "SyntacticBlock"
val SyntacticClassDef: NameType = "SyntacticClassDef"
+ val SyntacticDefDef: NameType = "SyntacticDefDef"
val SyntacticFunction: NameType = "SyntacticFunction"
val SyntacticFunctionType: NameType= "SyntacticFunctionType"
val SyntacticModuleDef: NameType = "SyntacticModuleDef"
@@ -600,6 +601,8 @@ trait StdNames {
val SyntacticTuple: NameType = "SyntacticTuple"
val SyntacticTupleType: NameType = "SyntacticTupleType"
val SyntacticTypeApplied: NameType = "SyntacticTypeApplied"
+ val SyntacticValDef: NameType = "SyntacticValDef"
+ val SyntacticVarDef: NameType = "SyntacticVarDef"
val This: NameType = "This"
val ThisType: NameType = "ThisType"
val True : NameType = "True"
diff --git a/test/files/scalacheck/quasiquotes/DefinitionDeconstructionProps.scala b/test/files/scalacheck/quasiquotes/DefinitionDeconstructionProps.scala
index d6b60c4351..fdfbfe871c 100644
--- a/test/files/scalacheck/quasiquotes/DefinitionDeconstructionProps.scala
+++ b/test/files/scalacheck/quasiquotes/DefinitionDeconstructionProps.scala
@@ -134,5 +134,14 @@ trait ValVarDeconstruction { self: QuasiquoteProperties =>
matches("val x: Int = 1")
matches("lazy val x: Int = 1")
matches("implicit val x = 1")
+ assertThrows[MatchError] { matches("var x = 1") }
+ }
+
+ property("exhaustive var matcher") = test {
+ def matches(line: String) { val q"$mods var $name: $tpt = $rhs" = parse(line) }
+ matches("var x: Int")
+ matches("var x: Int = 1")
+ matches("var x = 1")
+ assertThrows[MatchError] { matches("val x = 1") }
}
} \ No newline at end of file