summaryrefslogtreecommitdiff
path: root/src/library
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2012-06-06 14:29:05 +0200
committerEugene Burmako <xeno.by@gmail.com>2012-06-08 15:31:58 +0200
commitce67870e64afabf75363679bcee597812ad223e9 (patch)
treece84ef7673977b0dde4ed13ca1276e25517d6b9c /src/library
parentbdff66e2730518f449634375b1f3d19689d72b1e (diff)
downloadscala-ce67870e64afabf75363679bcee597812ad223e9.tar.gz
scala-ce67870e64afabf75363679bcee597812ad223e9.tar.bz2
scala-ce67870e64afabf75363679bcee597812ad223e9.zip
brings macros up to speed
Before reflection refactoring, macro contexts only exposed a mirror. Now it's time to expose both a universe (the compiler instance) and a mirror (a macro-specific symbol resolver). By the way, speaking of mirrors. Macro contexts have their own mirror, which is different from compiler's rootMirror. This is done because macros need to be able to resolve stuff from empty package. Reflection refactoring brought major changes to runtime evaluation, which got dropped from universes and now requires scala-compiler.jar. However there are macro users, who would like to do eval inside macros. To help them we expose `libraryClassLoader` to manually build toolboxes, and also a simple-to-use `c.eval` method. I've also sneakily introduced `c.parse`, because it's something that has also been frequently requested. Moreover, it might help Scaladoc. So I decided that it might be worth it to add this new functionality.
Diffstat (limited to 'src/library')
-rw-r--r--src/library/scala/reflect/makro/Aliases.scala34
-rw-r--r--src/library/scala/reflect/makro/Context.scala9
-rw-r--r--src/library/scala/reflect/makro/Evals.scala8
-rw-r--r--src/library/scala/reflect/makro/FrontEnds.scala2
-rw-r--r--src/library/scala/reflect/makro/Infrastructure.scala29
-rw-r--r--src/library/scala/reflect/makro/Names.scala2
-rw-r--r--src/library/scala/reflect/makro/Parsers.scala17
-rw-r--r--src/library/scala/reflect/makro/Typers.scala2
-rw-r--r--src/library/scala/reflect/makro/package.scala6
9 files changed, 86 insertions, 23 deletions
diff --git a/src/library/scala/reflect/makro/Aliases.scala b/src/library/scala/reflect/makro/Aliases.scala
index d7dd111f22..5e9ebdb263 100644
--- a/src/library/scala/reflect/makro/Aliases.scala
+++ b/src/library/scala/reflect/makro/Aliases.scala
@@ -3,26 +3,24 @@ package scala.reflect.makro
trait Aliases {
self: Context =>
- /** Aliases of mirror types */
- type Symbol = mirror.Symbol
- type Type = mirror.Type
- type Name = mirror.Name
- type Tree = mirror.Tree
- // type Position = mirror.Position
- type Scope = mirror.Scope
- type Modifiers = mirror.Modifiers
- type Expr[+T] = mirror.Expr[T]
- type TypeTag[T] = mirror.TypeTag[T]
- type ConcreteTypeTag[T] = mirror.ConcreteTypeTag[T]
+ type Symbol = universe.Symbol
+ type Type = universe.Type
+ type Name = universe.Name
+ type TermName = universe.TermName
+ type TypeName = universe.TypeName
+ type Tree = universe.Tree
+ // type Position = universe.Position
+ type Scope = universe.Scope
+ type Modifiers = universe.Modifiers
- /** Creator/extractor objects for Expr and TypeTag values */
- val TypeTag = mirror.TypeTag
- val ConcreteTypeTag = mirror.ConcreteTypeTag
- val Expr = mirror.Expr
+ type Expr[+T] = universe.Expr[T]
+ val Expr = universe.Expr
- /** incantations for summoning tags */
- def tag[T](implicit ttag: TypeTag[T]) = ttag
+ type TypeTag[T] = universe.TypeTag[T]
+ type ConcreteTypeTag[T] = universe.ConcreteTypeTag[T]
+ val TypeTag = universe.TypeTag
+ val ConcreteTypeTag = universe.ConcreteTypeTag
def typeTag[T](implicit ttag: TypeTag[T]) = ttag
- def concreteTag[T](implicit cttag: ConcreteTypeTag[T]) = cttag
def concreteTypeTag[T](implicit cttag: ConcreteTypeTag[T]) = cttag
+ def typeOf[T](implicit ttag: TypeTag[T]): Type = ttag.tpe
}
diff --git a/src/library/scala/reflect/makro/Context.scala b/src/library/scala/reflect/makro/Context.scala
index fb77405d37..58fd0d3df3 100644
--- a/src/library/scala/reflect/makro/Context.scala
+++ b/src/library/scala/reflect/makro/Context.scala
@@ -15,12 +15,17 @@ trait Context extends Aliases
with FrontEnds
with Settings
with Typers
+ with Parsers
with Exprs
with TypeTags
+ with Evals
with Util {
- /** The mirror that corresponds to the compile-time universe */
- val mirror: Universe
+ /** The compile-time universe */
+ val universe: Universe
+
+ /** The mirror of the compile-time universe */
+ val mirror: MirrorOf[universe.type]
/** The type of the prefix tree from which the macro is selected */
type PrefixType
diff --git a/src/library/scala/reflect/makro/Evals.scala b/src/library/scala/reflect/makro/Evals.scala
new file mode 100644
index 0000000000..e34f74ca1b
--- /dev/null
+++ b/src/library/scala/reflect/makro/Evals.scala
@@ -0,0 +1,8 @@
+package scala.reflect.makro
+
+trait Evals {
+ self: Context =>
+
+ /** .. */
+ def eval[T](expr: Expr[T]): T
+} \ No newline at end of file
diff --git a/src/library/scala/reflect/makro/FrontEnds.scala b/src/library/scala/reflect/makro/FrontEnds.scala
index d76907cdc8..7e47701ffa 100644
--- a/src/library/scala/reflect/makro/FrontEnds.scala
+++ b/src/library/scala/reflect/makro/FrontEnds.scala
@@ -5,7 +5,7 @@ trait FrontEnds extends scala.reflect.api.FrontEnds {
import mirror._
- type Position = mirror.Position
+ type Position = universe.Position
/** Exposes means to control the compiler UI */
def frontEnd: FrontEnd
diff --git a/src/library/scala/reflect/makro/Infrastructure.scala b/src/library/scala/reflect/makro/Infrastructure.scala
index 2bf49dca77..69394a27ea 100644
--- a/src/library/scala/reflect/makro/Infrastructure.scala
+++ b/src/library/scala/reflect/makro/Infrastructure.scala
@@ -23,6 +23,35 @@ trait Infrastructure {
*/
val currentRun: Run
+ /** Exposes library classpath.
+ */
+ val libraryClassPath: List[java.net.URL]
+
+ /** Exposes a classloader that corresponds to the library classpath.
+ *
+ * With this classloader you can perform on-the-fly evaluation of macro arguments.
+ * For example, consider this code snippet:
+ *
+ * def staticEval[T](x: T) = macro staticEval[T]
+ *
+ * def staticEval[T: c.TypeTag](c: Context)(x: c.Expr[T]) = {
+ * import scala.reflect.runtime.{universe => ru}
+ * val mirror = ru.runtimeMirror(c.libraryClassLoader)
+ * import scala.tools.reflect.ToolBox
+ * val toolBox = mirror.mkToolBox()
+ * val importer = ru.mkImporter(c.universe).asInstanceOf[ru.Importer { val from: c.universe.type }]
+ * val tree = c.resetAllAttrs(x.tree.duplicate)
+ * val imported = importer.importTree(tree)
+ * val valueOfX = toolBox.runExpr(imported).asInstanceOf[T]
+ * ...
+ * }
+ *
+ * // [Eugene++] using this guy will tremendously slow down the compilation
+ * // https://twitter.com/xeno_by/status/201248317831774208
+ * // todo. we need to address this somehow
+ */
+ def libraryClassLoader: ClassLoader
+
/** As seen by macro API, compilation run is an opaque type that can be deconstructed into:
* 1) Current compilation unit
* 2) List of all compilation units that comprise the run
diff --git a/src/library/scala/reflect/makro/Names.scala b/src/library/scala/reflect/makro/Names.scala
index 8a823d19cb..c842c48e52 100644
--- a/src/library/scala/reflect/makro/Names.scala
+++ b/src/library/scala/reflect/makro/Names.scala
@@ -10,5 +10,5 @@ trait Names {
def fresh(name: String): String
/** Creates a fresh name from the provided name */
- def fresh(name: Name): Name
+ def fresh[NameType <: Name](name: NameType): NameType
}
diff --git a/src/library/scala/reflect/makro/Parsers.scala b/src/library/scala/reflect/makro/Parsers.scala
new file mode 100644
index 0000000000..737d387434
--- /dev/null
+++ b/src/library/scala/reflect/makro/Parsers.scala
@@ -0,0 +1,17 @@
+package scala.reflect.makro
+
+trait Parsers {
+ self: Context =>
+
+ /** .. */
+ // todo. distinguish between `parseExpr` and `parse`
+ def parse(code: String): Tree
+
+ /** Represents an error during parsing
+ */
+ type ParseError <: Throwable
+ val ParseError: ParseErrorExtractor
+ abstract class ParseErrorExtractor {
+ def unapply(error: ParseError): Option[(Position, String)]
+ }
+} \ No newline at end of file
diff --git a/src/library/scala/reflect/makro/Typers.scala b/src/library/scala/reflect/makro/Typers.scala
index 90024a4f7a..2087309520 100644
--- a/src/library/scala/reflect/makro/Typers.scala
+++ b/src/library/scala/reflect/makro/Typers.scala
@@ -3,7 +3,7 @@ package scala.reflect.makro
trait Typers {
self: Context =>
- import mirror._
+ import universe._
/** Contexts that represent macros in-flight, including the current one. Very much like a stack trace, but for macros only.
* Can be useful for interoperating with other macros and for imposing compiler-friendly limits on macro expansion.
diff --git a/src/library/scala/reflect/makro/package.scala b/src/library/scala/reflect/makro/package.scala
new file mode 100644
index 0000000000..3c0e51030e
--- /dev/null
+++ b/src/library/scala/reflect/makro/package.scala
@@ -0,0 +1,6 @@
+package scala.reflect
+
+package object makro {
+
+ type MirrorOf[U <: base.Universe with Singleton] = base.MirrorOf[U]
+}