summaryrefslogtreecommitdiff
path: root/src/reflect
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2012-08-01 09:58:23 +0200
committerEugene Burmako <xeno.by@gmail.com>2012-08-02 15:51:21 +0200
commitf7164b871530a68b100d540b876187036c1c6cbc (patch)
treefe2372803470778cafea0dd65ab1e089f3fbf231 /src/reflect
parenta0a63c4558018a5e75149a45f7df775f731c26f1 (diff)
downloadscala-f7164b871530a68b100d540b876187036c1c6cbc.tar.gz
scala-f7164b871530a68b100d540b876187036c1c6cbc.tar.bz2
scala-f7164b871530a68b100d540b876187036c1c6cbc.zip
moves Expr from api to base
This is the first step in supporting serialization for exprs and type tags. Generally speaking universes and mirrors cannot be serialized (even not taking into account all the amount of scalac-specific transient stuff, java mirrors use classloaders, which are not serializable). Hence we can only serialize tree and type creators, and deserialize them into the mirror we surely know will be there - the scala.reflect.basis.rootMirror. To do that we need to have exprs in scala.reflect.base. Luckily all the trees are already in base, we only need to move a single file to scala-library.jar. Another good news is that reification logic is simplified, because we don't have to special case exprs as being defined in ApiUniverseClass.
Diffstat (limited to 'src/reflect')
-rw-r--r--src/reflect/scala/reflect/api/Exprs.scala62
-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
4 files changed, 8 insertions, 118 deletions
diff --git a/src/reflect/scala/reflect/api/Exprs.scala b/src/reflect/scala/reflect/api/Exprs.scala
deleted file mode 100644
index 8b2a3b4ea8..0000000000
--- a/src/reflect/scala/reflect/api/Exprs.scala
+++ /dev/null
@@ -1,62 +0,0 @@
-/* NSC -- new Scala compiler
- * Copyright 2005-2011 LAMP/EPFL
- * @author Martin Odersky
- */
-
-package scala.reflect
-package api
-
-import scala.reflect.base.TreeCreator
-
-trait Exprs { self: Universe =>
-
- /** An expression tree tagged with its type */
- trait Expr[+T] extends Equals with Serializable {
- val mirror: Mirror
- def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # Expr[T]
-
- def tree: Tree
- def staticTpe: Type
- def actualTpe: Type
-
- def splice: T
- val value: T
-
- /** case class accessories */
- override def canEqual(x: Any) = x.isInstanceOf[Expr[_]]
- override def equals(x: Any) = x.isInstanceOf[Expr[_]] && this.mirror == x.asInstanceOf[Expr[_]].mirror && this.tree == x.asInstanceOf[Expr[_]].tree
- override def hashCode = mirror.hashCode * 31 + tree.hashCode
- override def toString = "Expr["+staticTpe+"]("+tree+")"
- }
-
- object Expr {
- def apply[T: AbsTypeTag](mirror: MirrorOf[self.type], treec: TreeCreator): Expr[T] = new ExprImpl[T](mirror.asInstanceOf[Mirror], treec)
- def unapply[T](expr: Expr[T]): Option[Tree] = Some(expr.tree)
- }
-
- private class ExprImpl[+T: AbsTypeTag](val mirror: Mirror, val treec: TreeCreator) extends Expr[T] {
- def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # Expr[T] = {
- val otherMirror1 = otherMirror.asInstanceOf[MirrorOf[otherMirror.universe.type]]
- val tag1 = (implicitly[AbsTypeTag[T]] in otherMirror).asInstanceOf[otherMirror.universe.AbsTypeTag[T]]
- otherMirror.universe.Expr[T](otherMirror1, treec)(tag1)
- }
-
- lazy val tree: Tree = treec[Exprs.this.type](mirror)
- // [Eugene++] this is important
- // !!! 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 splice: T = throw new UnsupportedOperationException("""
- |the function you're calling has not been spliced by the compiler.
- |this means there is a cross-stage evaluation involved, and it needs to be invoked explicitly.
- |if you're sure this is not an oversight, add scala-compiler.jar to the classpath,
- |import `scala.tools.reflect.Eval` and call `<your expr>.eval` instead.""".trim.stripMargin)
- lazy val value: T = throw new UnsupportedOperationException("""
- |the value you're calling is only meant to be used in cross-stage path-dependent types.
- |if you want to splice the underlying expression, use `<your expr>.splice`.
- |if you want to get a value of the underlying expression, add scala-compiler.jar to the classpath,
- |import `scala.tools.reflect.Eval` and call `<your expr>.eval` instead.""".trim.stripMargin)
- }
-} \ 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[_]]