diff options
author | Eugene Burmako <xeno.by@gmail.com> | 2012-08-25 11:04:37 +0200 |
---|---|---|
committer | Eugene Burmako <xeno.by@gmail.com> | 2012-08-25 11:04:37 +0200 |
commit | 5bdfddefd7ff13476185b67d869a92c6c9f94506 (patch) | |
tree | bffc3880864828ce34726e8d994f5a64e4c6c09a /test/files | |
parent | 07a0b702ab00223f6f849868f0982cdb7994af66 (diff) | |
download | scala-5bdfddefd7ff13476185b67d869a92c6c9f94506.tar.gz scala-5bdfddefd7ff13476185b67d869a92c6c9f94506.tar.bz2 scala-5bdfddefd7ff13476185b67d869a92c6c9f94506.zip |
SI-6281 macroArgs for defs with implicit args
macroArgs now correctly calculates the argss in case when a macro def
has implicit parameters.
Macro impls can never have implicit parameters other than type tag evidences,
so tags will always come in a separate parameter list w.r.t other parameters
of macro impls (which are in 1-to-1 correspondence with the parameters of
macro defs).
Example 1:
def w/o implicits: (params1)...(paramsN)
impl w/o tags: (params1')...(paramsN')
Example 2:
def w/o implicits: (params1)...(paramsN)
impl w tags: (params1')...(paramsN')(implicit tags)
Example 3:
def w implicits: (params1)...(paramsN)(implicit paramsN+1)
impl w/o tags: (params1')...(paramsN')(paramsN+1')
Note: paramsN+1' is not an implicit parameter list
because impls cannot have implicit parameters other than tags
Example 4:
def w implicits: (params1)...(paramsN)(implicit paramsN+1)
impl w tags: (params1')...(paramsN')(paramsN+1')(implicit tags)
Therefore we don't need to merge the argss.last (that correspond to implicit
parameters of macro defs) with tags, as it was incorrectly coded before.
We just need to append tags to argss.
Diffstat (limited to 'test/files')
4 files changed, 65 insertions, 0 deletions
diff --git a/test/files/run/macro-expand-implicit-argument.check b/test/files/run/macro-expand-implicit-argument.check new file mode 100644 index 0000000000..fb42345748 --- /dev/null +++ b/test/files/run/macro-expand-implicit-argument.check @@ -0,0 +1 @@ +List(1, 2, 3)
diff --git a/test/files/run/macro-expand-implicit-argument.flags b/test/files/run/macro-expand-implicit-argument.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/run/macro-expand-implicit-argument.flags @@ -0,0 +1 @@ +-language:experimental.macros
\ No newline at end of file diff --git a/test/files/run/macro-expand-implicit-argument/Macros_1.scala b/test/files/run/macro-expand-implicit-argument/Macros_1.scala new file mode 100644 index 0000000000..7629c5a9e2 --- /dev/null +++ b/test/files/run/macro-expand-implicit-argument/Macros_1.scala @@ -0,0 +1,59 @@ +import annotation.tailrec +import scala.math.{min, max} +import scala.{specialized => spec} + +import language.experimental.macros + +import scala.reflect.{ClassTag, TypeTag} +import scala.reflect.macros.Context + +object Macros { + def alloc[@spec A:ClassTag](src:Array[A], s1:Int, len:Int) = { + val as = Array.ofDim[A](len) + System.arraycopy(src, s1, as, 0, len) + as + } + + /** + * Efficient alternative to Array.apply. + * + * "As seen on scala-internals!" + */ + def array[A](as:A*)(implicit ct: ClassTag[A]) = macro arrayMacro[A] + + /** + * Takes in something like: + * ArrayUtil.alloc[Int](11, 22, 33, 44)(ct) + * + * and builds a tree like: + * { + * val arr:Array[Int] = ct.newArray(4) + * arr.update(0, 11) + * arr.update(1, 22) + * arr.update(2, 33) + * arr.update(3, 44) + * arr + * } + */ + def arrayMacro[A:c.AbsTypeTag](c:Context)(as:c.Expr[A]*)(ct: c.Expr[ClassTag[A]]): c.Expr[Array[A]] = { + import c.mirror._ + import c.universe._ + def const(x:Int) = Literal(Constant(x)) + + val n = as.length + val arr = newTermName("arr") + + val create = Apply(Select(ct.tree, "newArray"), List(const(n))) + val arrtpe = TypeTree(implicitly[c.AbsTypeTag[Array[A]]].tpe) + val valdef = ValDef(Modifiers(), arr, arrtpe, create) + + val updates = (0 until n).map { + i => Apply(Select(Ident(arr), "update"), List(const(i), as(i).tree)) + } + + val exprs = Seq(valdef) ++ updates ++ Seq(Ident(arr)) + val block = Block(exprs:_*) + + c.Expr[Array[A]](block) + } +}
\ No newline at end of file diff --git a/test/files/run/macro-expand-implicit-argument/Test_2.scala b/test/files/run/macro-expand-implicit-argument/Test_2.scala new file mode 100644 index 0000000000..ce8a068fb4 --- /dev/null +++ b/test/files/run/macro-expand-implicit-argument/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + import Macros._ + println(array(1, 2, 3).toList) +}
\ No newline at end of file |