summaryrefslogtreecommitdiff
path: root/src/reflect/scala/reflect/api/Universe.scala
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2012-06-08 02:36:10 +0200
committerEugene Burmako <xeno.by@gmail.com>2012-06-08 15:32:28 +0200
commit0b2f1bcf75d31c59b25e19eebcb80f39c155365b (patch)
tree8d9dfc50ef01ca48c068b232af7e67a723325388 /src/reflect/scala/reflect/api/Universe.scala
parent13213e3df0384b1fd815c0798758a22284572cdb (diff)
downloadscala-0b2f1bcf75d31c59b25e19eebcb80f39c155365b.tar.gz
scala-0b2f1bcf75d31c59b25e19eebcb80f39c155365b.tar.bz2
scala-0b2f1bcf75d31c59b25e19eebcb80f39c155365b.zip
Introduces scala-reflect.jar
Diffstat (limited to 'src/reflect/scala/reflect/api/Universe.scala')
-rw-r--r--src/reflect/scala/reflect/api/Universe.scala68
1 files changed, 68 insertions, 0 deletions
diff --git a/src/reflect/scala/reflect/api/Universe.scala b/src/reflect/scala/reflect/api/Universe.scala
new file mode 100644
index 0000000000..002cd2e673
--- /dev/null
+++ b/src/reflect/scala/reflect/api/Universe.scala
@@ -0,0 +1,68 @@
+package scala.reflect
+package api
+
+import language.experimental.macros
+
+abstract class Universe extends base.Universe
+ with Symbols
+ with Types
+ with FlagSets
+ with Names
+ with Trees
+ with TreePrinters
+ with Constants
+ with Positions
+ with Mirrors
+ 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