summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrzegorz Kossakowski <grzegorz.kossakowski@gmail.com>2012-09-20 02:05:15 -0700
committerGrzegorz Kossakowski <grzegorz.kossakowski@gmail.com>2012-09-20 02:05:15 -0700
commit4db37e459e9894d6c0ac20177e44062a9088b970 (patch)
tree4c5d5e61fe752b3c253eea4dcb2a24d73359def8
parent3b120ff12891968d02296abb60adb9137d335ae2 (diff)
parentb8362d6aa42433ea4d423f7498d5fae155dc68b0 (diff)
downloadscala-4db37e459e9894d6c0ac20177e44062a9088b970.tar.gz
scala-4db37e459e9894d6c0ac20177e44062a9088b970.tar.bz2
scala-4db37e459e9894d6c0ac20177e44062a9088b970.zip
Merge pull request #1358 from scalamacros/ticket/6392
SI-6392 wraps non-terms before typecheck/eval
-rw-r--r--src/compiler/scala/tools/reflect/ToolBoxFactory.scala15
-rw-r--r--test/files/run/t6392a.check1
-rw-r--r--test/files/run/t6392a.scala9
-rw-r--r--test/files/run/t6392b.check1
-rw-r--r--test/files/run/t6392b.scala9
5 files changed, 33 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
index 27d62e2bac..6300297f65 100644
--- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
+++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
@@ -69,6 +69,14 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
}
}
+ def wrapIntoTerm(tree: Tree): Tree =
+ if (!tree.isTerm) Block(List(tree), Literal(Constant(()))) else tree
+
+ def unwrapFromTerm(tree: Tree): Tree = tree match {
+ case Block(List(tree), Literal(Constant(()))) => tree
+ case tree => tree
+ }
+
def extractFreeTerms(expr0: Tree, wrapFreeTermRefs: Boolean): (Tree, scala.collection.mutable.LinkedHashMap[FreeTermSymbol, TermName]) = {
val freeTerms = expr0.freeTerms
val freeTermNames = scala.collection.mutable.LinkedHashMap[FreeTermSymbol, TermName]()
@@ -101,7 +109,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
// need to wrap the expr, because otherwise you won't be able to typecheck macros against something that contains free vars
var (expr, freeTerms) = extractFreeTerms(expr0, wrapFreeTermRefs = false)
val dummies = freeTerms.map{ case (freeTerm, name) => ValDef(NoMods, name, TypeTree(freeTerm.info), Select(Ident(PredefModule), newTermName("$qmark$qmark$qmark"))) }.toList
- expr = Block(dummies, expr)
+ expr = Block(dummies, wrapIntoTerm(expr))
// [Eugene] how can we implement that?
// !!! Why is this is in the empty package? If it's only to make
@@ -136,6 +144,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
}
}.transform(unwrapped)
new TreeTypeSubstituter(dummies1 map (_.symbol), dummies1 map (dummy => SingleType(NoPrefix, invertedIndex(dummy.symbol.name)))).traverse(unwrapped)
+ unwrapped = if (expr0.isTerm) unwrapped else unwrapFromTerm(unwrapped)
unwrapped
}
@@ -169,7 +178,9 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
}
})
- def compile(expr: Tree): () => Any = {
+ def compile(expr0: Tree): () => Any = {
+ val expr = wrapIntoTerm(expr0)
+
val freeTerms = expr.freeTerms // need to calculate them here, because later on they will be erased
val thunks = freeTerms map (fte => () => fte.value) // need to be lazy in order not to distort evaluation order
verify(expr)
diff --git a/test/files/run/t6392a.check b/test/files/run/t6392a.check
new file mode 100644
index 0000000000..ec969b5b93
--- /dev/null
+++ b/test/files/run/t6392a.check
@@ -0,0 +1 @@
+()
diff --git a/test/files/run/t6392a.scala b/test/files/run/t6392a.scala
new file mode 100644
index 0000000000..3a4f9fd0a5
--- /dev/null
+++ b/test/files/run/t6392a.scala
@@ -0,0 +1,9 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.tools.reflect.ToolBox
+
+object Test extends App {
+ val tb = cm.mkToolBox()
+ val c = tb.parse("object C")
+ println(tb.eval(c))
+} \ No newline at end of file
diff --git a/test/files/run/t6392b.check b/test/files/run/t6392b.check
new file mode 100644
index 0000000000..ee19836b95
--- /dev/null
+++ b/test/files/run/t6392b.check
@@ -0,0 +1 @@
+ModuleDef(Modifiers(), newTermName("C"), Template(List(Select(Ident(scala#PK), newTypeName("AnyRef")#TPE)), emptyValDef, List(DefDef(Modifiers(), nme.CONSTRUCTOR, List(), List(List()), TypeTree(), Block(List(Apply(Select(Super(This(newTypeName("C")), tpnme.EMPTY), nme.CONSTRUCTOR#PCTOR), List())), Literal(Constant(())))))))
diff --git a/test/files/run/t6392b.scala b/test/files/run/t6392b.scala
new file mode 100644
index 0000000000..f69a5aaf45
--- /dev/null
+++ b/test/files/run/t6392b.scala
@@ -0,0 +1,9 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.tools.reflect.ToolBox
+
+object Test extends App {
+ val tb = cm.mkToolBox()
+ val c = tb.parse("object C")
+ println(showRaw(tb.typeCheck(c), printKinds = true))
+} \ No newline at end of file