summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/reflect/reify/Reifier.scala2
-rw-r--r--src/compiler/scala/reflect/reify/utils/Extractors.scala28
-rw-r--r--src/compiler/scala/tools/reflect/FastTrack.scala2
-rw-r--r--src/library/scala/reflect/base/Base.scala2
-rw-r--r--src/library/scala/reflect/base/Exprs.scala (renamed from src/reflect/scala/reflect/api/Exprs.scala)6
-rw-r--r--src/library/scala/reflect/base/Trees.scala3
-rw-r--r--src/library/scala/reflect/base/Universe.scala50
-rw-r--r--src/reflect/scala/reflect/api/Trees.scala2
-rw-r--r--src/reflect/scala/reflect/api/Universe.scala49
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala13
10 files changed, 69 insertions, 88 deletions
diff --git a/src/compiler/scala/reflect/reify/Reifier.scala b/src/compiler/scala/reflect/reify/Reifier.scala
index 5503ff2977..53e01309cb 100644
--- a/src/compiler/scala/reflect/reify/Reifier.scala
+++ b/src/compiler/scala/reflect/reify/Reifier.scala
@@ -115,7 +115,7 @@ abstract class Reifier extends States
// todo. maybe try `resetLocalAttrs` once the dust settles
var importantSymbols = Set[Symbol](
NothingClass, AnyClass, SingletonClass, PredefModule, ScalaRunTimeModule, TypeCreatorClass, TreeCreatorClass, MirrorOfClass,
- BaseUniverseClass, ApiUniverseClass, JavaUniverseClass, ReflectRuntimePackage, ReflectRuntimeCurrentMirror)
+ BaseUniverseClass, JavaUniverseClass, ReflectRuntimePackage, ReflectRuntimeCurrentMirror)
importantSymbols ++= importantSymbols map (_.companionSymbol)
importantSymbols ++= importantSymbols map (_.moduleClass)
importantSymbols ++= importantSymbols map (_.linkedClassOfClass)
diff --git a/src/compiler/scala/reflect/reify/utils/Extractors.scala b/src/compiler/scala/reflect/reify/utils/Extractors.scala
index 7352b2cbd5..ebe3957e69 100644
--- a/src/compiler/scala/reflect/reify/utils/Extractors.scala
+++ b/src/compiler/scala/reflect/reify/utils/Extractors.scala
@@ -20,11 +20,6 @@ trait Extractors {
// ()
// };
// def apply[U >: Nothing <: scala.reflect.base.Universe with Singleton]($m$untyped: scala.reflect.base.MirrorOf[U]): U#Tree = {
- // val $u: scala.reflect.api.Universe = $m$untyped.universe.asInstanceOf[scala.reflect.api.Universe];
- // val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror];
- // applyImpl($m).asInstanceOf[U#Tree];
- // }
- // def applyImpl[U >: Nothing <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.base.MirrorOf[U]): U#Tree = {
// val $u: U = $m$untyped.universe;
// val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror];
// $u.Apply($u.Select($u.Select($u.build.This($m.staticPackage("scala.collection.immutable").moduleClass), $u.newTermName("List")), $u.newTermName("apply")), List($u.Literal($u.Constant(1)), $u.Literal($u.Constant(2))))
@@ -51,23 +46,7 @@ trait Extractors {
val tparamu = newTypeName("U")
val (reifierBase, reifierName, reifierTpt, reifierUniverse) = flavor match {
case tpnme.REIFY_TYPECREATOR_PREFIX => (TypeCreatorClass, nme.apply, SelectFromTypeTree(Ident(tparamu), tpnme.Type), BaseUniverseClass)
- case tpnme.REIFY_TREECREATOR_PREFIX => (TreeCreatorClass, nme.applyImpl, SelectFromTypeTree(Ident(BaseUniverseClass), tpnme.Tree), ApiUniverseClass)
- case _ => throw new Error(s"unexpected flavor $flavor")
- }
- val reifierPreamble = flavor match {
- case tpnme.REIFY_TYPECREATOR_PREFIX => Nil
- case tpnme.REIFY_TREECREATOR_PREFIX => List[Tree](
- DefDef(NoMods,
- nme.apply,
- List(TypeDef(Modifiers(PARAM), tparamu, List(), TypeBoundsTree(Ident(NothingClass), CompoundTypeTree(Template(List(Ident(BaseUniverseClass), Ident(SingletonClass)), emptyValDef, List()))))),
- List(List(ValDef(Modifiers(PARAM), nme.MIRROR_UNTYPED, AppliedTypeTree(Ident(MirrorOfClass), List(Ident(tparamu))), EmptyTree))),
- SelectFromTypeTree(Ident(tparamu), tpnme.Tree),
- Block(
- ValDef(NoMods, nme.UNIVERSE_SHORT, Ident(ApiUniverseClass), TypeApply(Select(Select(Ident(nme.MIRROR_UNTYPED), nme.universe), nme.asInstanceOf_), List(Ident(ApiUniverseClass)))),
- ValDef(NoMods, nme.MIRROR_SHORT, Select(Ident(nme.UNIVERSE_SHORT), tpnme.Mirror), TypeApply(Select(Ident(nme.MIRROR_UNTYPED), nme.asInstanceOf_), List(Select(Ident(nme.UNIVERSE_SHORT), tpnme.Mirror)))),
- TypeApply(Select(Apply(TypeApply(Ident(reifierName), List(SingletonTypeTree(Ident(nme.UNIVERSE_SHORT)))), List(Ident(nme.MIRROR_SHORT))), nme.asInstanceOf_), List(SelectFromTypeTree(Ident(tparamu), tpnme.Tree)))
- ))
- )
+ case tpnme.REIFY_TREECREATOR_PREFIX => (TreeCreatorClass, nme.apply, SelectFromTypeTree(Ident(tparamu), tpnme.Tree), BaseUniverseClass)
case _ => throw new Error(s"unexpected flavor $flavor")
}
val reifierBody = {
@@ -98,8 +77,7 @@ trait Extractors {
Template(List(Ident(reifierBase)),
emptyValDef,
List(
- DefDef(NoMods, nme.CONSTRUCTOR, List(), List(List()), TypeTree(), Block(List(Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), List())), Literal(Constant(()))))
- ) ++ reifierPreamble ++ List(
+ DefDef(NoMods, nme.CONSTRUCTOR, List(), List(List()), TypeTree(), Block(List(Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), List())), Literal(Constant(())))),
DefDef(NoMods,
reifierName,
List(TypeDef(Modifiers(PARAM), tparamu, List(), TypeBoundsTree(Ident(NothingClass), CompoundTypeTree(Template(List(Ident(reifierUniverse), Ident(SingletonClass)), emptyValDef, List()))))),
@@ -128,7 +106,7 @@ trait Extractors {
case Block(
List(udef @ ValDef(_, _, _, universe), mdef @ ValDef(_, _, _, mirror)),
Apply(
- Apply(TypeApply(_, List(ttpe @ TypeTree())), List(_, Block(List(ClassDef(_, _, _, Template(_, _, List(_, _, DefDef(_, _, _, _, _, Block(_ :: _ :: symbolTable1, rtree)))))), _))),
+ Apply(TypeApply(_, List(ttpe @ TypeTree())), List(_, Block(List(ClassDef(_, _, _, Template(_, _, List(_, DefDef(_, _, _, _, _, Block(_ :: _ :: symbolTable1, rtree)))))), _))),
// todo. doesn't take into account optimizations such as $u.TypeTag.Int or the upcoming closure optimization
List(Apply(TypeApply(tagFactory @ Select(_, _), _), List(_, Block(List(ClassDef(_, _, _, Template(_, _, List(_, DefDef(_, _, _, _, _, Block(_ :: _ :: symbolTable2, rtpe)))))), _))))))
if udef.name == nme.UNIVERSE_SHORT && mdef.name == nme.MIRROR_SHORT =>
diff --git a/src/compiler/scala/tools/reflect/FastTrack.scala b/src/compiler/scala/tools/reflect/FastTrack.scala
index 237ef813c7..e093c64c72 100644
--- a/src/compiler/scala/tools/reflect/FastTrack.scala
+++ b/src/compiler/scala/tools/reflect/FastTrack.scala
@@ -38,7 +38,7 @@ trait FastTrack {
MacroInternal_materializeClassTag bindTo { case (c, Apply(TypeApply(_, List(tt)), List(u))) => c.materializeClassTag(u, tt.tpe) }
MacroInternal_materializeAbsTypeTag bindTo { case (c, Apply(TypeApply(_, List(tt)), List(u))) => c.materializeTypeTag(u, EmptyTree, tt.tpe, concrete = false) }
MacroInternal_materializeTypeTag bindTo { case (c, Apply(TypeApply(_, List(tt)), List(u))) => c.materializeTypeTag(u, EmptyTree, tt.tpe, concrete = true) }
- ApiUniverseReify bindTo { case (c, Apply(TypeApply(_, List(tt)), List(expr))) => c.materializeExpr(c.prefix.tree, EmptyTree, expr) }
+ BaseUniverseReify bindTo { case (c, Apply(TypeApply(_, List(tt)), List(expr))) => c.materializeExpr(c.prefix.tree, EmptyTree, expr) }
ReflectRuntimeCurrentMirror bindTo { case (c, _) => scala.reflect.runtime.Macros.currentMirror(c).tree }
StringContext_f bindTo { case (c, app@Apply(Select(Apply(_, parts), _), args)) => c.macro_StringInterpolation_f(parts, args, app.pos) }
registry
diff --git a/src/library/scala/reflect/base/Base.scala b/src/library/scala/reflect/base/Base.scala
index b887b87732..714fd365ef 100644
--- a/src/library/scala/reflect/base/Base.scala
+++ b/src/library/scala/reflect/base/Base.scala
@@ -466,6 +466,8 @@ class Base extends Universe { self =>
def treeToString(tree: Tree) = s"<tree ${tree.getClass}>"
+ def treeType(tree: Tree) = NoType
+
trait TermTree extends Tree
trait TypTree extends Tree
diff --git a/src/reflect/scala/reflect/api/Exprs.scala b/src/library/scala/reflect/base/Exprs.scala
index 8b2a3b4ea8..a92860f558 100644
--- a/src/reflect/scala/reflect/api/Exprs.scala
+++ b/src/library/scala/reflect/base/Exprs.scala
@@ -4,9 +4,7 @@
*/
package scala.reflect
-package api
-
-import scala.reflect.base.TreeCreator
+package base
trait Exprs { self: Universe =>
@@ -46,7 +44,7 @@ trait Exprs { self: Universe =>
// !!! remove when we have improved type inference for singletons
// search for .type] to find other instances
lazy val staticTpe: Type = implicitly[AbsTypeTag[T]].tpe
- def actualTpe: Type = tree.tpe
+ def actualTpe: Type = treeType(tree)
def splice: T = throw new UnsupportedOperationException("""
|the function you're calling has not been spliced by the compiler.
diff --git a/src/library/scala/reflect/base/Trees.scala b/src/library/scala/reflect/base/Trees.scala
index ab03b7a89f..4e8a520625 100644
--- a/src/library/scala/reflect/base/Trees.scala
+++ b/src/library/scala/reflect/base/Trees.scala
@@ -34,6 +34,9 @@ trait Trees { self: Universe =>
/** Obtains string representation of a tree */
protected def treeToString(tree: Tree): String
+ /** Obtains the type of the tree (we intentionally don't expose `tree.tpe` in base) */
+ protected def treeType(tree: Tree): Type
+
/** Tree is the basis for scala's abstract syntax. The nodes are
* implemented as case classes, and the parameters which initialize
* a given tree are immutable: however Trees have several mutable
diff --git a/src/library/scala/reflect/base/Universe.scala b/src/library/scala/reflect/base/Universe.scala
index 93ddcb9f55..6f37214fa8 100644
--- a/src/library/scala/reflect/base/Universe.scala
+++ b/src/library/scala/reflect/base/Universe.scala
@@ -10,9 +10,57 @@ abstract class Universe extends Symbols
with Constants
with AnnotationInfos
with Positions
+ with Exprs
with TypeTags
with TagInterop
with StandardDefinitions
with StandardNames
with BuildUtils
- with Mirrors \ No newline at end of file
+ with Mirrors
+{
+ /** Given an expression, generate a tree that when compiled and executed produces the original tree.
+ * The produced tree will be bound to the Universe it was called from.
+ *
+ * For instance, given the abstract syntax tree representation of the <[ x + 1 ]> expression:
+ *
+ * {{{
+ * Apply(Select(Ident("x"), "+"), List(Literal(Constant(1))))
+ * }}}
+ *
+ * The reifier transforms it to the following expression:
+ *
+ * {{{
+ * <[
+ * val $u: u.type = u // where u is a reference to the Universe that calls the reify
+ * $u.Expr[Int]($u.Apply($u.Select($u.Ident($u.newFreeVar("x", <Int>, x), "+"), List($u.Literal($u.Constant(1))))))
+ * ]>
+ * }}}
+ *
+ * Reification performs expression splicing (when processing Expr.splice)
+ * and type splicing (for every type T that has a TypeTag[T] implicit in scope):
+ *
+ * {{{
+ * val two = mirror.reify(2) // Literal(Constant(2))
+ * val four = mirror.reify(two.splice + two.splice) // Apply(Select(two.tree, newTermName("$plus")), List(two.tree))
+ *
+ * def macroImpl[T](c: Context) = {
+ * ...
+ * // T here is just a type parameter, so the tree produced by reify won't be of much use in a macro expansion
+ * // however, if T were annotated with c.TypeTag (which would declare an implicit parameter for macroImpl)
+ * // then reification would subtitute T with the TypeTree that was used in a TypeApply of this particular macro invocation
+ * val factory = c.reify{ new Queryable[T] }
+ * ...
+ * }
+ * }}}
+ *
+ * The transformation looks mostly straightforward, but it has its tricky parts:
+ * * Reifier retains symbols and types defined outside the reified tree, however
+ * locally defined entities get erased and replaced with their original trees
+ * * Free variables are detected and wrapped in symbols of the type FreeVar
+ * * Mutable variables that are accessed from a local function are wrapped in refs
+ * * Since reified trees can be compiled outside of the scope they've been created in,
+ * special measures are taken to ensure that all members accessed in the reifee remain visible
+ */
+ // implementation is magically hardwired to `scala.reflect.reify.Taggers`
+ def reify[T](expr: T): Expr[T] = ??? // macro
+} \ No newline at end of file
diff --git a/src/reflect/scala/reflect/api/Trees.scala b/src/reflect/scala/reflect/api/Trees.scala
index 8165f599b2..06c7ddeda4 100644
--- a/src/reflect/scala/reflect/api/Trees.scala
+++ b/src/reflect/scala/reflect/api/Trees.scala
@@ -109,6 +109,8 @@ trait Trees extends base.Trees { self: Universe =>
def duplicate: this.type
}
+ override protected def treeType(tree: Tree) = tree.tpe
+
override type TermTree >: Null <: Tree with TermTreeApi
/** The API that all term trees support */
diff --git a/src/reflect/scala/reflect/api/Universe.scala b/src/reflect/scala/reflect/api/Universe.scala
index da05b5ba46..3dce0f218e 100644
--- a/src/reflect/scala/reflect/api/Universe.scala
+++ b/src/reflect/scala/reflect/api/Universe.scala
@@ -14,53 +14,4 @@ abstract class Universe extends base.Universe
with StandardDefinitions
with StandardNames
with Importers
- with Exprs
with AnnotationInfos
-{
-
- /** Given an expression, generate a tree that when compiled and executed produces the original tree.
- * The produced tree will be bound to the Universe it was called from.
- *
- * For instance, given the abstract syntax tree representation of the <[ x + 1 ]> expression:
- *
- * {{{
- * Apply(Select(Ident("x"), "+"), List(Literal(Constant(1))))
- * }}}
- *
- * The reifier transforms it to the following expression:
- *
- * {{{
- * <[
- * val $u: u.type = u // where u is a reference to the Universe that calls the reify
- * $u.Expr[Int]($u.Apply($u.Select($u.Ident($u.newFreeVar("x", <Int>, x), "+"), List($u.Literal($u.Constant(1))))))
- * ]>
- * }}}
- *
- * Reification performs expression splicing (when processing Expr.splice)
- * and type splicing (for every type T that has a TypeTag[T] implicit in scope):
- *
- * {{{
- * val two = mirror.reify(2) // Literal(Constant(2))
- * val four = mirror.reify(two.splice + two.splice) // Apply(Select(two.tree, newTermName("$plus")), List(two.tree))
- *
- * def macroImpl[T](c: Context) = {
- * ...
- * // T here is just a type parameter, so the tree produced by reify won't be of much use in a macro expansion
- * // however, if T were annotated with c.TypeTag (which would declare an implicit parameter for macroImpl)
- * // then reification would subtitute T with the TypeTree that was used in a TypeApply of this particular macro invocation
- * val factory = c.reify{ new Queryable[T] }
- * ...
- * }
- * }}}
- *
- * The transformation looks mostly straightforward, but it has its tricky parts:
- * * Reifier retains symbols and types defined outside the reified tree, however
- * locally defined entities get erased and replaced with their original trees
- * * Free variables are detected and wrapped in symbols of the type FreeVar
- * * Mutable variables that are accessed from a local function are wrapped in refs
- * * Since reified trees can be compiled outside of the scope they've been created in,
- * special measures are taken to ensure that all members accessed in the reifee remain visible
- */
- // implementation is magically hardwired to `scala.reflect.reify.Taggers`
- def reify[T](expr: T): Expr[T] = ??? // macro
-} \ No newline at end of file
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index 0fd86cdb3a..bc2120a738 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -471,11 +471,11 @@ trait Definitions extends api.StandardDefinitions {
lazy val OptManifestClass = requiredClass[scala.reflect.OptManifest[_]]
lazy val NoManifest = requiredModule[scala.reflect.NoManifest.type]
- lazy val ExprsClass = getClassIfDefined("scala.reflect.api.Exprs") // defined in scala-reflect.jar, so we need to be careful
- lazy val ExprClass = if (ExprsClass != NoSymbol) getMemberClass(ExprsClass, tpnme.Expr) else NoSymbol
- def ExprSplice = if (ExprsClass != NoSymbol) getMemberMethod(ExprClass, nme.splice) else NoSymbol
- def ExprValue = if (ExprsClass != NoSymbol) getMemberMethod(ExprClass, nme.value) else NoSymbol
- lazy val ExprModule = if (ExprsClass != NoSymbol) getMemberModule(ExprsClass, nme.Expr) else NoSymbol
+ lazy val ExprsClass = requiredClass[scala.reflect.base.Exprs]
+ lazy val ExprClass = getMemberClass(ExprsClass, tpnme.Expr)
+ def ExprSplice = getMemberMethod(ExprClass, nme.splice)
+ def ExprValue = getMemberMethod(ExprClass, nme.value)
+ lazy val ExprModule = getMemberModule(ExprsClass, nme.Expr)
lazy val ClassTagModule = requiredModule[scala.reflect.ClassTag[_]]
lazy val ClassTagClass = requiredClass[scala.reflect.ClassTag[_]]
@@ -486,8 +486,7 @@ trait Definitions extends api.StandardDefinitions {
lazy val TypeTagModule = getMemberModule(TypeTagsClass, nme.TypeTag)
lazy val BaseUniverseClass = requiredClass[scala.reflect.base.Universe]
- lazy val ApiUniverseClass = getClassIfDefined("scala.reflect.api.Universe") // defined in scala-reflect.jar, so we need to be careful
- def ApiUniverseReify = if (ApiUniverseClass != NoSymbol) getMemberMethod(ApiUniverseClass, nme.reify) else NoSymbol
+ def BaseUniverseReify = getMemberMethod(BaseUniverseClass, nme.reify)
lazy val JavaUniverseClass = getClassIfDefined("scala.reflect.api.JavaUniverse") // defined in scala-reflect.jar, so we need to be careful
lazy val MirrorOfClass = requiredClass[scala.reflect.base.MirrorOf[_]]