summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDenys Shabalin <denys.shabalin@typesafe.com>2014-01-16 12:01:30 +0100
committerDenys Shabalin <denys.shabalin@typesafe.com>2014-01-16 12:45:38 +0100
commit8e9862473abd03bded2d3afa60c777099f7872c5 (patch)
treedf2b1fcbd893a77ea63717f6290146357214b3cf /src
parent393829489a1e352c2ed659b16b6bea24069f4f9a (diff)
downloadscala-8e9862473abd03bded2d3afa60c777099f7872c5.tar.gz
scala-8e9862473abd03bded2d3afa60c777099f7872c5.tar.bz2
scala-8e9862473abd03bded2d3afa60c777099f7872c5.zip
SI-8076 improve support for implicit argument list
This adds support for construction and deconstruction of implicit argument list which was originally suggested by @cvogt. 1. Splicing vale into implicit argument list automatically adds implicit flag to them: val x = q"val x: Int" q"def foo(implicit $x)" // <=> q"def foo(implicit x: Int)" 2. One might extract implicit argument list separately from other argument lists: val q”def foo(...$argss)(implicit ..$impl)" = q"def foo(implicit x: Int) // argss is Nil, impl contains valdef for x But this doesn't require you to always extract it separatly: val q”def foo(...$argss)" = q"def foo(implicit x: Int) // argss contains valdef for x
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala8
-rw-r--r--src/reflect/scala/reflect/api/BuildUtils.scala7
-rw-r--r--src/reflect/scala/reflect/internal/BuildUtils.scala14
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala1
4 files changed, 28 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
index 58baad01a1..9c0a036541 100644
--- a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
+++ b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
@@ -160,8 +160,12 @@ trait Reifiers { self: Quasiquotes =>
reifyBuildCall(nme.SyntacticObjectDef, 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 SyntacticDefDef(mods, name, tparams, build.ImplicitParams(vparamss, implparams), tpt, rhs) =>
+ if (implparams.nonEmpty)
+ mirrorBuildCall(nme.SyntacticDefDef, reify(mods), reify(name), reify(tparams),
+ reifyBuildCall(nme.ImplicitParams, vparamss, implparams), reify(tpt), reify(rhs))
+ else
+ reifyBuildCall(nme.SyntacticDefDef, mods, name, tparams, vparamss, tpt, rhs)
case SyntacticValDef(mods, name, tpt, rhs) if tree != noSelfType =>
reifyBuildCall(nme.SyntacticValDef, mods, name, tpt, rhs)
case SyntacticVarDef(mods, name, tpt, rhs) =>
diff --git a/src/reflect/scala/reflect/api/BuildUtils.scala b/src/reflect/scala/reflect/api/BuildUtils.scala
index 89492e75c4..d70fa01ae6 100644
--- a/src/reflect/scala/reflect/api/BuildUtils.scala
+++ b/src/reflect/scala/reflect/api/BuildUtils.scala
@@ -94,6 +94,13 @@ private[reflect] trait BuildUtils { self: Universe =>
def freshTypeName(prefix: String): TypeName
+ val ImplicitParams: ImplicitParamsExtractor
+
+ trait ImplicitParamsExtractor {
+ def apply(paramss: List[List[ValDef]], implparams: List[ValDef]): List[List[ValDef]]
+ def unapply(vparamss: List[List[ValDef]]): Some[(List[List[ValDef]], List[ValDef])]
+ }
+
val ScalaDot: ScalaDotExtractor
trait ScalaDotExtractor {
diff --git a/src/reflect/scala/reflect/internal/BuildUtils.scala b/src/reflect/scala/reflect/internal/BuildUtils.scala
index 657b098952..292413674b 100644
--- a/src/reflect/scala/reflect/internal/BuildUtils.scala
+++ b/src/reflect/scala/reflect/internal/BuildUtils.scala
@@ -86,6 +86,10 @@ trait BuildUtils { self: SymbolTable =>
"""consider reformatting it into q"val $name: $T = $default" shape""")
}
+ def mkImplicitParam(args: List[Tree]): List[ValDef] = args.map(mkImplicitParam)
+
+ def mkImplicitParam(tree: Tree): ValDef = mkParam(tree, IMPLICIT | PARAM)
+
def mkTparams(tparams: List[Tree]): List[TypeDef] =
tparams.map {
case td: TypeDef => copyTypeDef(td)(mods = (td.mods | PARAM) & (~DEFERRED))
@@ -143,6 +147,16 @@ trait BuildUtils { self: SymbolTable =>
protected implicit def fresh: FreshNameCreator = self.currentFreshNameCreator
+ object ImplicitParams extends ImplicitParamsExtractor {
+ def apply(paramss: List[List[ValDef]], implparams: List[ValDef]): List[List[ValDef]] =
+ if (implparams.nonEmpty) paramss :+ mkImplicitParam(implparams) else paramss
+
+ def unapply(vparamss: List[List[ValDef]]): Some[(List[List[ValDef]], List[ValDef])] = vparamss match {
+ case init :+ (last @ (initlast :: _)) if initlast.mods.isImplicit => Some((init, last))
+ case _ => Some((vparamss, Nil))
+ }
+ }
+
object FlagsRepr extends FlagsReprExtractor {
def apply(bits: Long): FlagSet = bits
def unapply(flags: Long): Some[Long] = Some(flags)
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index 73ad9def73..49c26ca58d 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -576,6 +576,7 @@ trait StdNames {
val Flag : NameType = "Flag"
val FlagsRepr: NameType = "FlagsRepr"
val Ident: NameType = "Ident"
+ val ImplicitParams: NameType = "ImplicitParams"
val Import: NameType = "Import"
val Literal: NameType = "Literal"
val LiteralAnnotArg: NameType = "LiteralAnnotArg"