summaryrefslogtreecommitdiff
path: root/src/compiler/scala/reflect/macros/contexts
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/reflect/macros/contexts')
-rw-r--r--src/compiler/scala/reflect/macros/contexts/Context.scala3
-rw-r--r--src/compiler/scala/reflect/macros/contexts/Evals.scala2
-rw-r--r--src/compiler/scala/reflect/macros/contexts/Internals.scala47
-rw-r--r--src/compiler/scala/reflect/macros/contexts/Typers.scala15
4 files changed, 60 insertions, 7 deletions
diff --git a/src/compiler/scala/reflect/macros/contexts/Context.scala b/src/compiler/scala/reflect/macros/contexts/Context.scala
index 87dac18849..f3dd29d8b2 100644
--- a/src/compiler/scala/reflect/macros/contexts/Context.scala
+++ b/src/compiler/scala/reflect/macros/contexts/Context.scala
@@ -15,7 +15,8 @@ abstract class Context extends scala.reflect.macros.blackbox.Context
with Parsers
with Evals
with ExprUtils
- with Traces {
+ with Traces
+ with Internals {
val universe: Global
diff --git a/src/compiler/scala/reflect/macros/contexts/Evals.scala b/src/compiler/scala/reflect/macros/contexts/Evals.scala
index 180a998c39..a715af986c 100644
--- a/src/compiler/scala/reflect/macros/contexts/Evals.scala
+++ b/src/compiler/scala/reflect/macros/contexts/Evals.scala
@@ -9,7 +9,7 @@ trait Evals {
private lazy val evalMirror = ru.runtimeMirror(universe.analyzer.defaultMacroClassloader)
private lazy val evalToolBox = evalMirror.mkToolBox()
- private lazy val evalImporter = ru.mkImporter(universe).asInstanceOf[ru.Importer { val from: universe.type }]
+ private lazy val evalImporter = ru.internal.createImporter(universe).asInstanceOf[ru.Importer { val from: universe.type }]
def eval[T](expr: Expr[T]): T = {
expr.tree match {
diff --git a/src/compiler/scala/reflect/macros/contexts/Internals.scala b/src/compiler/scala/reflect/macros/contexts/Internals.scala
new file mode 100644
index 0000000000..8c784d7e54
--- /dev/null
+++ b/src/compiler/scala/reflect/macros/contexts/Internals.scala
@@ -0,0 +1,47 @@
+package scala.reflect.macros
+package contexts
+
+trait Internals extends scala.tools.nsc.transform.TypingTransformers {
+ self: Context =>
+
+ import global._
+
+ lazy val internal: ContextInternalApi = new global.SymbolTableInternal with ContextInternalApi {
+ val enclosingOwner = callsiteTyper.context.owner
+
+ class HofTransformer(hof: (Tree, TransformApi) => Tree) extends Transformer {
+ val api = new TransformApi {
+ def recur(tree: Tree): Tree = hof(tree, this)
+ def default(tree: Tree): Tree = superTransform(tree)
+ }
+ def superTransform(tree: Tree) = super.transform(tree)
+ override def transform(tree: Tree): Tree = hof(tree, api)
+ }
+
+ def transform(tree: Tree)(transformer: (Tree, TransformApi) => Tree): Tree = new HofTransformer(transformer).transform(tree)
+
+ class HofTypingTransformer(hof: (Tree, TypingTransformApi) => Tree) extends TypingTransformer(callsiteTyper.context.unit) { self =>
+ currentOwner = callsiteTyper.context.owner
+ curTree = EmptyTree
+ localTyper = global.analyzer.newTyper(callsiteTyper.context.make(unit = callsiteTyper.context.unit))
+
+ val api = new TypingTransformApi {
+ def recur(tree: Tree): Tree = hof(tree, this)
+ def default(tree: Tree): Tree = superTransform(tree)
+ def atOwner[T](owner: Symbol)(op: => T): T = self.atOwner(owner)(op)
+ def atOwner[T](tree: Tree, owner: Symbol)(op: => T): T = self.atOwner(tree, owner)(op)
+ def currentOwner: Symbol = self.currentOwner
+ def typecheck(tree: Tree): Tree = localTyper.typed(tree)
+ }
+ def superTransform(tree: Tree) = super.transform(tree)
+ override def transform(tree: Tree): Tree = hof(tree, api)
+ }
+
+ def typingTransform(tree: Tree)(transformer: (Tree, TypingTransformApi) => Tree): Tree = new HofTypingTransformer(transformer).transform(tree)
+
+ def typingTransform(tree: Tree, owner: Symbol)(transformer: (Tree, TypingTransformApi) => Tree): Tree = {
+ val trans = new HofTypingTransformer(transformer)
+ trans.atOwner(owner)(trans.transform(tree))
+ }
+ }
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/macros/contexts/Typers.scala b/src/compiler/scala/reflect/macros/contexts/Typers.scala
index f80b43b636..28c1e3ddb3 100644
--- a/src/compiler/scala/reflect/macros/contexts/Typers.scala
+++ b/src/compiler/scala/reflect/macros/contexts/Typers.scala
@@ -1,8 +1,6 @@
package scala.reflect.macros
package contexts
-import scala.reflect.internal.Mode
-
trait Typers {
self: Context =>
@@ -10,17 +8,24 @@ trait Typers {
def openImplicits: List[ImplicitCandidate] = callsiteTyper.context.openImplicits.map(_.toImplicitCandidate)
+ type TypecheckMode = scala.reflect.internal.Mode
+ val TypecheckMode = scala.reflect.internal.Mode
+ val TERMmode = TypecheckMode.EXPRmode
+ val TYPEmode = TypecheckMode.TYPEmode | TypecheckMode.FUNmode
+ val PATTERNmode = TypecheckMode.PATTERNmode
+
/**
* @see [[scala.tools.reflect.ToolBox.typeCheck]]
*/
- def typecheck(tree: Tree, pt: Type = universe.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = {
+ def typecheck(tree: Tree, mode: TypecheckMode = TERMmode, pt: Type = universe.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = {
macroLogVerbose("typechecking %s with expected type %s, implicit views = %s, macros = %s".format(tree, pt, !withImplicitViewsDisabled, !withMacrosDisabled))
val context = callsiteTyper.context
val withImplicitFlag = if (!withImplicitViewsDisabled) (context.withImplicitsEnabled[Tree] _) else (context.withImplicitsDisabled[Tree] _)
val withMacroFlag = if (!withMacrosDisabled) (context.withMacrosEnabled[Tree] _) else (context.withMacrosDisabled[Tree] _)
def withContext(tree: => Tree) = withImplicitFlag(withMacroFlag(tree))
- def typecheckInternal(tree: Tree) = callsiteTyper.silent(_.typed(universe.duplicateAndKeepPositions(tree), pt), reportAmbiguousErrors = false)
- universe.wrappingIntoTerm(tree)(wrappedTree => withContext(typecheckInternal(wrappedTree) match {
+ def withWrapping(tree: Tree)(op: Tree => Tree) = if (mode == TERMmode) universe.wrappingIntoTerm(tree)(op) else op(tree)
+ def typecheckInternal(tree: Tree) = callsiteTyper.silent(_.typed(universe.duplicateAndKeepPositions(tree), mode, pt), reportAmbiguousErrors = false)
+ withWrapping(tree)(wrappedTree => withContext(typecheckInternal(wrappedTree) match {
case universe.analyzer.SilentResultValue(result) =>
macroLogVerbose(result)
result