summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2012-12-29 05:22:31 -0800
committerEugene Burmako <xeno.by@gmail.com>2012-12-29 05:22:31 -0800
commit26c27d831db5d68c4b65c0f1eb6d7286798814b5 (patch)
treecb8fd8b0144f15a4d579b79390ea58170f364f6d
parent8c7e034d528017afea18e9f345be71f7485380ee (diff)
parent48cdfefb95ee43ded08688d6c99a8c3a32d47f18 (diff)
downloadscala-26c27d831db5d68c4b65c0f1eb6d7286798814b5.tar.gz
scala-26c27d831db5d68c4b65c0f1eb6d7286798814b5.tar.bz2
scala-26c27d831db5d68c4b65c0f1eb6d7286798814b5.zip
Merge pull request #1818 from scalamacros/topic/auto-duplicate-expansions
macro expansions are now auto-duplicated
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala8
-rw-r--r--src/reflect/scala/reflect/internal/Trees.scala7
-rw-r--r--test/files/run/macro-duplicate.check0
-rw-r--r--test/files/run/macro-duplicate.flags1
-rw-r--r--test/files/run/macro-duplicate/Impls_Macros_1.scala29
-rw-r--r--test/files/run/macro-duplicate/Test_2.scala6
6 files changed, 46 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index 6ed879af14..768d739b4b 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -694,9 +694,11 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
var expectedTpe = expandee.tpe
if (isNullaryInvocation(expandee)) expectedTpe = expectedTpe.finalResultType
- var typechecked = typecheck("macro def return type", expanded, expectedTpe)
- typechecked = typecheck("expected type", typechecked, pt)
- typechecked
+ // also see http://groups.google.com/group/scala-internals/browse_thread/thread/492560d941b315cc
+ val expanded0 = duplicateAndKeepPositions(expanded)
+ val expanded1 = typecheck("macro def return type", expanded0, expectedTpe)
+ val expanded2 = typecheck("expected type", expanded1, pt)
+ expanded2
} finally {
popMacroContext()
}
diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala
index 2029fb67b3..35e10d73c8 100644
--- a/src/reflect/scala/reflect/internal/Trees.scala
+++ b/src/reflect/scala/reflect/internal/Trees.scala
@@ -1501,15 +1501,18 @@ trait Trees extends api.Trees { self: SymbolTable =>
}
}
- private lazy val duplicator = new Transformer {
+ private lazy val duplicator = new Duplicator(focusPositions = true)
+ private class Duplicator(focusPositions: Boolean) extends Transformer {
override val treeCopy = newStrictTreeCopier
override def transform(t: Tree) = {
val t1 = super.transform(t)
- if ((t1 ne t) && t1.pos.isRange) t1 setPos t.pos.focus
+ if ((t1 ne t) && t1.pos.isRange && focusPositions) t1 setPos t.pos.focus
t1
}
}
+ def duplicateAndKeepPositions(tree: Tree) = new Duplicator(focusPositions = false) transform tree
+
// ------ copiers -------------------------------------------
def copyDefDef(tree: Tree)(
diff --git a/test/files/run/macro-duplicate.check b/test/files/run/macro-duplicate.check
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/files/run/macro-duplicate.check
diff --git a/test/files/run/macro-duplicate.flags b/test/files/run/macro-duplicate.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/macro-duplicate.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-duplicate/Impls_Macros_1.scala b/test/files/run/macro-duplicate/Impls_Macros_1.scala
new file mode 100644
index 0000000000..de81923330
--- /dev/null
+++ b/test/files/run/macro-duplicate/Impls_Macros_1.scala
@@ -0,0 +1,29 @@
+import scala.reflect.macros.Context
+
+object Macros {
+ def impl(c: Context) = {
+ import c.universe._
+ val Expr(Block((cdef: ClassDef) :: Nil, _)) = reify { class C { def x = 2 } }
+ val cdef1 =
+ new Transformer {
+ override def transform(tree: Tree): Tree = tree match {
+ case Template(_, _, ctor :: defs) =>
+ val defs1 = defs collect {
+ case ddef @ DefDef(mods, name, tparams, vparamss, tpt, body) =>
+ val future = Select(Select(Select(Ident(newTermName("scala")), newTermName("concurrent")), newTermName("package")), newTermName("future"))
+ val Future = Select(Select(Ident(newTermName("scala")), newTermName("concurrent")), newTypeName("Future"))
+ val tpt1 = if (tpt.isEmpty) tpt else AppliedTypeTree(Future, List(tpt))
+ val body1 = Apply(future, List(body))
+ val name1 = newTermName("async" + name.toString.capitalize)
+ DefDef(mods, name1, tparams, vparamss, tpt1, body1)
+ }
+ Template(Nil, emptyValDef, ctor +: defs ::: defs1)
+ case _ =>
+ super.transform(tree)
+ }
+ } transform cdef
+ c.Expr[Unit](Block(cdef1 :: Nil, Literal(Constant(()))))
+ }
+
+ def foo = macro impl
+} \ No newline at end of file
diff --git a/test/files/run/macro-duplicate/Test_2.scala b/test/files/run/macro-duplicate/Test_2.scala
new file mode 100644
index 0000000000..6dbd4382d3
--- /dev/null
+++ b/test/files/run/macro-duplicate/Test_2.scala
@@ -0,0 +1,6 @@
+import scala.concurrent._
+import ExecutionContext.Implicits.global
+
+object Test extends App {
+ Macros.foo
+} \ No newline at end of file