summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/reflect/internal/Definitions.scala1
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Aliases.scala34
-rw-r--r--src/compiler/scala/reflect/makro/runtime/CapturedVariables.scala7
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Context.scala11
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Enclosures.scala3
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Evals.scala18
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Exprs.scala2
-rw-r--r--src/compiler/scala/reflect/makro/runtime/FrontEnds.scala21
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Infrastructure.scala36
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Mirrors.scala40
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Names.scala4
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Parsers.scala25
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Reifiers.scala8
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Settings.scala6
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Traces.scala2
-rw-r--r--src/compiler/scala/reflect/makro/runtime/TypeTags.scala4
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Typers.scala40
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Util.scala2
-rw-r--r--src/compiler/scala/reflect/reify/Taggers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala33
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala4
-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
30 files changed, 293 insertions, 119 deletions
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala
index b3a651563e..3b32d475ce 100644
--- a/src/compiler/scala/reflect/internal/Definitions.scala
+++ b/src/compiler/scala/reflect/internal/Definitions.scala
@@ -477,6 +477,7 @@ trait Definitions extends api.StandardDefinitions {
lazy val MacroContextClass = getClassIfDefined("scala.reflect.makro.Context") // defined in scala-reflect.jar, so we need to be careful
def MacroContextPrefix = if (MacroContextClass != NoSymbol) getMemberMethod(MacroContextClass, nme.prefix) else NoSymbol
def MacroContextPrefixType = if (MacroContextClass != NoSymbol) getMemberType(MacroContextClass, tpnme.PrefixType) else NoSymbol
+ def MacroContextUniverse = if (MacroContextClass != NoSymbol) getMemberMethod(MacroContextClass, nme.universe) else NoSymbol
def MacroContextMirror = if (MacroContextClass != NoSymbol) getMemberMethod(MacroContextClass, nme.mirror) else NoSymbol
def MacroContextReify = if (MacroContextClass != NoSymbol) getMemberMethod(MacroContextClass, nme.reify) else NoSymbol
lazy val MacroImplAnnotation = requiredClass[scala.reflect.makro.internal.macroImpl]
diff --git a/src/compiler/scala/reflect/makro/runtime/Aliases.scala b/src/compiler/scala/reflect/makro/runtime/Aliases.scala
index 30b015b201..76c2834102 100644
--- a/src/compiler/scala/reflect/makro/runtime/Aliases.scala
+++ b/src/compiler/scala/reflect/makro/runtime/Aliases.scala
@@ -4,20 +4,24 @@ package runtime
trait Aliases {
self: Context =>
- /** Aliases of mirror types */
- override type Symbol = mirror.Symbol
- override type Type = mirror.Type
- override type Name = mirror.Name
- override type Tree = mirror.Tree
- // override type Position = mirror.Position
- override type Scope = mirror.Scope
- override type Modifiers = mirror.Modifiers
- override type Expr[+T] = mirror.Expr[T]
- override type TypeTag[T] = mirror.TypeTag[T]
- override type ConcreteTypeTag[T] = mirror.ConcreteTypeTag[T]
+ override type Symbol = universe.Symbol
+ override type Type = universe.Type
+ override type Name = universe.Name
+ override type TermName = universe.TermName
+ override type TypeName = universe.TypeName
+ override type Tree = universe.Tree
+ // override type Position = universe.Position
+ override type Scope = universe.Scope
+ override type Modifiers = universe.Modifiers
- /** Creator/extractor objects for Expr and TypeTag values */
- override val TypeTag = mirror.TypeTag
- override val ConcreteTypeTag = mirror.ConcreteTypeTag
- override val Expr = mirror.Expr
+ override type Expr[+T] = universe.Expr[T]
+ override val Expr = universe.Expr
+
+ override type TypeTag[T] = universe.TypeTag[T]
+ override type ConcreteTypeTag[T] = universe.ConcreteTypeTag[T]
+ override val TypeTag = universe.TypeTag
+ override val ConcreteTypeTag = universe.ConcreteTypeTag
+ override def typeTag[T](implicit ttag: TypeTag[T]) = ttag
+ override def concreteTypeTag[T](implicit cttag: ConcreteTypeTag[T]) = cttag
+ override def typeOf[T](implicit ttag: TypeTag[T]): Type = ttag.tpe
} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/makro/runtime/CapturedVariables.scala b/src/compiler/scala/reflect/makro/runtime/CapturedVariables.scala
index 4e93d4e06d..021b93ceee 100644
--- a/src/compiler/scala/reflect/makro/runtime/CapturedVariables.scala
+++ b/src/compiler/scala/reflect/makro/runtime/CapturedVariables.scala
@@ -5,10 +5,11 @@ trait CapturedVariables {
self: Context =>
import mirror._
+ import universe._
- def captureVariable(vble: Symbol): Unit = mirror.captureVariable(vble)
+ def captureVariable(vble: Symbol): Unit = universe.captureVariable(vble)
- def referenceCapturedVariable(vble: Symbol): Tree = mirror.referenceCapturedVariable(vble)
+ def referenceCapturedVariable(vble: Symbol): Tree = universe.referenceCapturedVariable(vble)
- def capturedVariableType(vble: Symbol): Type = mirror.capturedVariableType(vble)
+ def capturedVariableType(vble: Symbol): Type = universe.capturedVariableType(vble)
} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/makro/runtime/Context.scala b/src/compiler/scala/reflect/makro/runtime/Context.scala
index 6faf045d75..7fd7a358b8 100644
--- a/src/compiler/scala/reflect/makro/runtime/Context.scala
+++ b/src/compiler/scala/reflect/makro/runtime/Context.scala
@@ -8,21 +8,26 @@ abstract class Context extends scala.reflect.makro.Context
with CapturedVariables
with Infrastructure
with Enclosures
+ with Mirrors
with Names
with Reifiers
with FrontEnds
with Settings
with Typers
+ with Parsers
with Exprs
with TypeTags
+ with Evals
with Util
with Traces {
- val mirror: Global
+ val universe: Global
- val callsiteTyper: mirror.analyzer.Typer
+ val mirror: MirrorOf[universe.type] = new ContextMirror
+
+ val callsiteTyper: universe.analyzer.Typer
val prefix: Expr[PrefixType]
val expandee: Tree
-} \ No newline at end of file
+}
diff --git a/src/compiler/scala/reflect/makro/runtime/Enclosures.scala b/src/compiler/scala/reflect/makro/runtime/Enclosures.scala
index ab38fc024d..80c35d22ff 100644
--- a/src/compiler/scala/reflect/makro/runtime/Enclosures.scala
+++ b/src/compiler/scala/reflect/makro/runtime/Enclosures.scala
@@ -4,6 +4,7 @@ package runtime
trait Enclosures {
self: Context =>
+ import universe._
import mirror._
private def site = callsiteTyper.context
@@ -16,7 +17,7 @@ trait Enclosures {
val enclosingApplication: Tree = enclTrees collectFirst { case t: Apply => t } getOrElse EmptyTree
val enclosingClass: Tree = site.enclClass.tree
val enclosingImplicits: List[(Type, Tree)] = site.openImplicits
- val enclosingMacros: List[Context] = this :: mirror.analyzer.openMacros // include self
+ val enclosingMacros: List[Context] = this :: universe.analyzer.openMacros // include self
val enclosingMethod: Tree = site.enclMethod.tree
val enclosingPosition: Position = if (enclPoses.isEmpty) NoPosition else enclPoses.head.pos
val enclosingUnit: CompilationUnit = currentRun.currentUnit
diff --git a/src/compiler/scala/reflect/makro/runtime/Evals.scala b/src/compiler/scala/reflect/makro/runtime/Evals.scala
new file mode 100644
index 0000000000..0574359a19
--- /dev/null
+++ b/src/compiler/scala/reflect/makro/runtime/Evals.scala
@@ -0,0 +1,18 @@
+package scala.reflect.makro
+package runtime
+
+import scala.reflect.runtime.{universe => ru}
+import scala.tools.reflect.ToolBox
+
+trait Evals {
+ self: Context =>
+
+ private lazy val evalMirror = ru.runtimeMirror(libraryClassLoader)
+ private lazy val evalToolBox = evalMirror.mkToolBox()
+ private lazy val evalImporter = ru.mkImporter(universe).asInstanceOf[ru.Importer { val from: universe.type }]
+
+ def eval[T](expr: Expr[T]): T = {
+ val imported = evalImporter.importTree(expr.tree)
+ evalToolBox.runExpr(imported).asInstanceOf[T]
+ }
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/makro/runtime/Exprs.scala b/src/compiler/scala/reflect/makro/runtime/Exprs.scala
index d47ff4e450..df2ea0c3ea 100644
--- a/src/compiler/scala/reflect/makro/runtime/Exprs.scala
+++ b/src/compiler/scala/reflect/makro/runtime/Exprs.scala
@@ -4,5 +4,5 @@ package runtime
trait Exprs {
self: Context =>
- def Expr[T: TypeTag](tree: Tree): Expr[T] = mirror.Expr[T](mirror.rootMirror, mirror.FixedMirrorTreeCreator(mirror.rootMirror, tree))
+ def Expr[T: TypeTag](tree: Tree): Expr[T] = universe.Expr[T](mirror, universe.FixedMirrorTreeCreator(mirror, tree))
}
diff --git a/src/compiler/scala/reflect/makro/runtime/FrontEnds.scala b/src/compiler/scala/reflect/makro/runtime/FrontEnds.scala
index a21c8f90c9..6644c579ac 100644
--- a/src/compiler/scala/reflect/makro/runtime/FrontEnds.scala
+++ b/src/compiler/scala/reflect/makro/runtime/FrontEnds.scala
@@ -4,31 +4,32 @@ package runtime
trait FrontEnds extends scala.tools.reflect.FrontEnds {
self: Context =>
+ import universe._
import mirror._
- override type Position = mirror.Position
+ override type Position = universe.Position
- def frontEnd: FrontEnd = wrapReporter(mirror.reporter)
+ def frontEnd: FrontEnd = wrapReporter(universe.reporter)
def setFrontEnd(frontEnd: FrontEnd): this.type = {
- mirror.reporter = wrapFrontEnd(frontEnd)
+ universe.reporter = wrapFrontEnd(frontEnd)
this
}
def withFrontEnd[T](frontEnd: FrontEnd)(op: => T): T = {
- val old = mirror.reporter
+ val old = universe.reporter
setFrontEnd(frontEnd)
try op
- finally mirror.reporter = old
+ finally universe.reporter = old
}
- def echo(pos: Position, msg: String): Unit = mirror.reporter.echo(pos, msg)
+ def echo(pos: Position, msg: String): Unit = universe.reporter.echo(pos, msg)
- def info(pos: Position, msg: String, force: Boolean): Unit = mirror.reporter.info(pos, msg, force)
+ def info(pos: Position, msg: String, force: Boolean): Unit = universe.reporter.info(pos, msg, force)
- def hasWarnings: Boolean = mirror.reporter.hasErrors
+ def hasWarnings: Boolean = universe.reporter.hasErrors
- def hasErrors: Boolean = mirror.reporter.hasErrors
+ def hasErrors: Boolean = universe.reporter.hasErrors
def warning(pos: Position, msg: String): Unit = callsiteTyper.context.warning(pos, msg)
@@ -39,7 +40,7 @@ trait FrontEnds extends scala.tools.reflect.FrontEnds {
throw new AbortMacroException(pos, msg)
}
- def interactive(): Unit = mirror.reporter match {
+ def interactive(): Unit = universe.reporter match {
case reporter: tools.nsc.reporters.AbstractReporter => reporter.displayPrompt()
case _ => ()
}
diff --git a/src/compiler/scala/reflect/makro/runtime/Infrastructure.scala b/src/compiler/scala/reflect/makro/runtime/Infrastructure.scala
index 6d8e55cc35..76c4b21731 100644
--- a/src/compiler/scala/reflect/makro/runtime/Infrastructure.scala
+++ b/src/compiler/scala/reflect/makro/runtime/Infrastructure.scala
@@ -1,26 +1,44 @@
package scala.reflect.makro
package runtime
+import scala.tools.nsc.util.ScalaClassLoader
+
trait Infrastructure {
self: Context =>
- val forJVM: Boolean = mirror.forJVM
+ val forJVM: Boolean = universe.forJVM
+
+ val forMSIL: Boolean = universe.forMSIL
+
+ val forInteractive: Boolean = universe.forInteractive
- val forMSIL: Boolean = mirror.forMSIL
+ val forScaladoc: Boolean = universe.forScaladoc
- val forInteractive: Boolean = mirror.forInteractive
+ val currentRun: Run = universe.currentRun
- val forScaladoc: Boolean = mirror.forScaladoc
+ val libraryClassPath: List[java.net.URL] = universe.classPath.asURLs
- val currentRun: Run = mirror.currentRun
+ lazy val libraryClassLoader: ClassLoader = {
+ val classpath = libraryClassPath
+ var loader: ClassLoader = ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader)
+
+ // [Eugene] a heuristic to detect REPL
+ if (universe.settings.exposeEmptyPackage.value) {
+ import scala.tools.nsc.interpreter._
+ val virtualDirectory = universe.settings.outputDirs.getSingleOutput.get
+ loader = new AbstractFileClassLoader(virtualDirectory, loader) {}
+ }
+
+ loader
+ }
- type Run = mirror.Run
+ type Run = universe.Run
object Run extends RunExtractor {
def unapply(run: Run): Option[(CompilationUnit, List[CompilationUnit])] = Some(run.currentUnit, run.units.toList)
}
- type CompilationUnit = mirror.CompilationUnit
+ type CompilationUnit = universe.CompilationUnit
object CompilationUnit extends CompilationUnitExtractor {
def unapply(compilationUnit: CompilationUnit): Option[(java.io.File, Array[Char], Tree)] = Some(compilationUnit.source.file.file, compilationUnit.source.content, compilationUnit.body)
@@ -28,7 +46,7 @@ trait Infrastructure {
val currentMacro: Symbol = expandee.symbol
- val globalCache: collection.mutable.Map[Any, Any] = mirror.analyzer.globalMacroCache
+ val globalCache: collection.mutable.Map[Any, Any] = universe.analyzer.globalMacroCache
- val cache: collection.mutable.Map[Any, Any] = mirror.analyzer.perRunMacroCache.getOrElseUpdate(currentMacro, collection.mutable.Map[Any, Any]())
+ val cache: collection.mutable.Map[Any, Any] = universe.analyzer.perRunMacroCache.getOrElseUpdate(currentMacro, collection.mutable.Map[Any, Any]())
} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/makro/runtime/Mirrors.scala b/src/compiler/scala/reflect/makro/runtime/Mirrors.scala
new file mode 100644
index 0000000000..79fa07fdb4
--- /dev/null
+++ b/src/compiler/scala/reflect/makro/runtime/Mirrors.scala
@@ -0,0 +1,40 @@
+package scala.reflect.makro
+package runtime
+
+import scala.tools.nsc.util.ScalaClassLoader
+
+trait Mirrors {
+ self: Context =>
+
+ import universe._
+ import definitions._
+
+ class ContextMirror extends RootsBase(NoSymbol) {
+ val universe: self.universe.type = self.universe
+ def rootLoader: LazyType = rootMirror.rootLoader
+
+ val RootPackage = rootMirror.RootPackage
+ val RootClass = rootMirror.RootClass
+ val EmptyPackage = rootMirror.EmptyPackage
+ val EmptyPackageClass = rootMirror.EmptyPackageClass
+
+ // [Eugene++] this still doesn't solve the problem of invoking `c.typeCheck` on the code that refers to packageless symbols
+ override protected def mirrorMissingHook(owner: Symbol, name: Name): Symbol = {
+ if (owner.isRoot && isJavaClass(name.toString)) EmptyPackageClass.info decl name
+ else NoSymbol
+ }
+
+ private def isJavaClass(path: String): Boolean =
+ try {
+ val classpath = platform.classPath.asURLs
+ var classLoader = ScalaClassLoader.fromURLs(classpath)
+ Class.forName(path, true, classLoader)
+ true
+ } catch {
+ case (_: ClassNotFoundException) | (_: NoClassDefFoundError) | (_: IncompatibleClassChangeError) =>
+ false
+ }
+
+ override def toString = "macro context mirror"
+ }
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/makro/runtime/Names.scala b/src/compiler/scala/reflect/makro/runtime/Names.scala
index d8ecc2b89e..5b1a41a13d 100644
--- a/src/compiler/scala/reflect/makro/runtime/Names.scala
+++ b/src/compiler/scala/reflect/makro/runtime/Names.scala
@@ -14,7 +14,7 @@ trait Names {
freshNameCreator.newName(name)
}
- def fresh(name: Name): Name = {
- name.mapName(freshNameCreator.newName(_))
+ def fresh[NameType <: Name](name: NameType): NameType = {
+ name.mapName(freshNameCreator.newName(_)).asInstanceOf[NameType]
}
} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/makro/runtime/Parsers.scala b/src/compiler/scala/reflect/makro/runtime/Parsers.scala
new file mode 100644
index 0000000000..ac8d09f592
--- /dev/null
+++ b/src/compiler/scala/reflect/makro/runtime/Parsers.scala
@@ -0,0 +1,25 @@
+package scala.reflect.makro
+package runtime
+
+import language.existentials
+import scala.tools.reflect.ToolBox
+import scala.tools.reflect.ToolBoxError
+
+trait Parsers {
+ self: Context =>
+
+ def parse(code: String): Tree =
+ // todo. provide decent implementation
+ try {
+ import scala.reflect.runtime.{universe => ru}
+ val parsed = ru.rootMirror.mkToolBox().parseExpr(code)
+ val importer = universe.mkImporter(ru)
+ importer.importTree(parsed)
+ } catch {
+ case ToolBoxError(msg, cause) =>
+ throw new ParseError(universe.NoPosition, msg)
+ }
+
+ case class ParseError(val pos: Position, val msg: String) extends Throwable(msg)
+ object ParseError extends ParseErrorExtractor
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/makro/runtime/Reifiers.scala b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala
index 95e031ebc8..7d404128fb 100644
--- a/src/compiler/scala/reflect/makro/runtime/Reifiers.scala
+++ b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala
@@ -9,19 +9,19 @@ package runtime
trait Reifiers {
self: Context =>
- import mirror._
+ import universe._
import definitions._
lazy val reflectMirrorPrefix: Tree = ???
def reifyTree(prefix: Tree, tree: Tree): Tree =
- scala.reflect.reify.`package`.reifyTree(mirror)(callsiteTyper, prefix, tree)
+ scala.reflect.reify.`package`.reifyTree(universe)(callsiteTyper, prefix, tree)
def reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, concrete: Boolean = false): Tree =
- scala.reflect.reify.`package`.reifyType(mirror)(callsiteTyper, prefix, tpe, dontSpliceAtTopLevel, concrete)
+ scala.reflect.reify.`package`.reifyType(universe)(callsiteTyper, prefix, tpe, dontSpliceAtTopLevel, concrete)
def reifyRuntimeClass(tpe: Type, concrete: Boolean = true): Tree =
- scala.reflect.reify.`package`.reifyRuntimeClass(mirror)(callsiteTyper, tpe, concrete)
+ scala.reflect.reify.`package`.reifyRuntimeClass(universe)(callsiteTyper, tpe, concrete)
def unreifyTree(tree: Tree): Tree =
Select(tree, definitions.ExprSplice)
diff --git a/src/compiler/scala/reflect/makro/runtime/Settings.scala b/src/compiler/scala/reflect/makro/runtime/Settings.scala
index 32f7115db8..8288180b8d 100644
--- a/src/compiler/scala/reflect/makro/runtime/Settings.scala
+++ b/src/compiler/scala/reflect/makro/runtime/Settings.scala
@@ -5,12 +5,12 @@ trait Settings {
self: Context =>
def settings: List[String] = {
- val optionName = mirror.settings.XmacroSettings.name
+ val optionName = universe.settings.XmacroSettings.name
val settings = compilerSettings.find(opt => opt.startsWith(optionName)).map(opt => opt.substring(optionName.length + 1)).getOrElse("")
settings.split(",").toList
}
- def compilerSettings: List[String] = mirror.settings.recreateArgs
+ def compilerSettings: List[String] = universe.settings.recreateArgs
def setCompilerSettings(options: String): this.type =
// todo. is not going to work with quoted arguments with embedded whitespaces
@@ -19,7 +19,7 @@ trait Settings {
def setCompilerSettings(options: List[String]): this.type = {
val settings = new tools.nsc.Settings(_ => ())
// [Eugene] what settings should we exclude?
- settings.copyInto(mirror.settings)
+ settings.copyInto(universe.settings)
this
}
diff --git a/src/compiler/scala/reflect/makro/runtime/Traces.scala b/src/compiler/scala/reflect/makro/runtime/Traces.scala
index 6b61842316..225ee1f62b 100644
--- a/src/compiler/scala/reflect/makro/runtime/Traces.scala
+++ b/src/compiler/scala/reflect/makro/runtime/Traces.scala
@@ -4,5 +4,5 @@ package runtime
trait Traces extends util.Traces {
self: Context =>
- def globalSettings = mirror.settings
+ def globalSettings = universe.settings
}
diff --git a/src/compiler/scala/reflect/makro/runtime/TypeTags.scala b/src/compiler/scala/reflect/makro/runtime/TypeTags.scala
index a8e67da56a..b4ac01eedf 100644
--- a/src/compiler/scala/reflect/makro/runtime/TypeTags.scala
+++ b/src/compiler/scala/reflect/makro/runtime/TypeTags.scala
@@ -4,6 +4,6 @@ package runtime
trait TypeTags {
self: Context =>
- def TypeTag[T](tpe: Type): TypeTag[T] = mirror.TypeTag[T](mirror.rootMirror, mirror.FixedMirrorTypeCreator(mirror.rootMirror, tpe))
- def ConcreteTypeTag[T](tpe: Type): ConcreteTypeTag[T] = mirror.ConcreteTypeTag[T](mirror.rootMirror, mirror.FixedMirrorTypeCreator(mirror.rootMirror, tpe))
+ def TypeTag[T](tpe: Type): TypeTag[T] = universe.TypeTag[T](mirror, universe.FixedMirrorTypeCreator(mirror, tpe))
+ def ConcreteTypeTag[T](tpe: Type): ConcreteTypeTag[T] = universe.ConcreteTypeTag[T](mirror, universe.FixedMirrorTypeCreator(mirror, tpe))
}
diff --git a/src/compiler/scala/reflect/makro/runtime/Typers.scala b/src/compiler/scala/reflect/makro/runtime/Typers.scala
index 704d3d7ac2..18c1714d15 100644
--- a/src/compiler/scala/reflect/makro/runtime/Typers.scala
+++ b/src/compiler/scala/reflect/makro/runtime/Typers.scala
@@ -4,11 +4,11 @@ package runtime
trait Typers {
self: Context =>
- def openMacros: List[Context] = this :: mirror.analyzer.openMacros
+ def openMacros: List[Context] = this :: universe.analyzer.openMacros
def openImplicits: List[(Type, Tree)] = callsiteTyper.context.openImplicits
- def typeCheck(tree: Tree, pt: Type = mirror.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = {
+ def typeCheck(tree: Tree, 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 wrapper1 = if (!withImplicitViewsDisabled) (callsiteTyper.context.withImplicitsEnabled[Tree] _) else (callsiteTyper.context.withImplicitsDisabled[Tree] _)
val wrapper2 = if (!withMacrosDisabled) (callsiteTyper.context.withMacrosEnabled[Tree] _) else (callsiteTyper.context.withMacrosDisabled[Tree] _)
@@ -18,28 +18,28 @@ trait Typers {
// typechecking uses silent anyways (e.g. in typedSelect), so you'll only waste your time
// I'd advise fixing the root cause: finding why the context is not set to report errors
// (also see reflect.runtime.ToolBoxes.typeCheckExpr for a workaround that might work for you)
- wrapper(callsiteTyper.silent(_.typed(tree, mirror.analyzer.EXPRmode, pt)) match {
- case mirror.analyzer.SilentResultValue(result) =>
+ wrapper(callsiteTyper.silent(_.typed(tree, universe.analyzer.EXPRmode, pt)) match {
+ case universe.analyzer.SilentResultValue(result) =>
macroLogVerbose(result)
result
- case error @ mirror.analyzer.SilentTypeError(_) =>
+ case error @ universe.analyzer.SilentTypeError(_) =>
macroLogVerbose(error.err.errMsg)
- if (!silent) throw new mirror.TypeError(error.err.errPos, error.err.errMsg)
- mirror.EmptyTree
+ if (!silent) throw new universe.TypeError(error.err.errPos, error.err.errMsg)
+ universe.EmptyTree
})
}
def inferImplicitValue(pt: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: Position = enclosingPosition): Tree = {
macroLogVerbose("inferring implicit value of type %s, macros = %s".format(pt, !withMacrosDisabled))
- import mirror.analyzer.SearchResult
+ import universe.analyzer.SearchResult
val context = callsiteTyper.context
val wrapper1 = if (!withMacrosDisabled) (context.withMacrosEnabled[SearchResult] _) else (context.withMacrosDisabled[SearchResult] _)
def wrapper (inference: => SearchResult) = wrapper1(inference)
- wrapper(mirror.analyzer.inferImplicit(mirror.EmptyTree, pt, true, false, context, !silent, pos)) match {
+ wrapper(universe.analyzer.inferImplicit(universe.EmptyTree, pt, true, false, context, !silent, pos)) match {
case failure if failure.tree.isEmpty =>
macroLogVerbose("implicit search has failed. to find out the reason, turn on -Xlog-implicits")
- if (context.hasErrors) throw new mirror.TypeError(context.errBuffer.head.errPos, context.errBuffer.head.errMsg)
- mirror.EmptyTree
+ if (context.hasErrors) throw new universe.TypeError(context.errBuffer.head.errPos, context.errBuffer.head.errMsg)
+ universe.EmptyTree
case success =>
success.tree
}
@@ -47,29 +47,29 @@ trait Typers {
def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, reportAmbiguous: Boolean = true, pos: Position = enclosingPosition): Tree = {
macroLogVerbose("inferring implicit view from %s to %s for %s, macros = %s, reportAmbiguous = %s".format(from, to, tree, !withMacrosDisabled, reportAmbiguous))
- import mirror.analyzer.SearchResult
+ import universe.analyzer.SearchResult
val context = callsiteTyper.context
val wrapper1 = if (!withMacrosDisabled) (context.withMacrosEnabled[SearchResult] _) else (context.withMacrosDisabled[SearchResult] _)
def wrapper (inference: => SearchResult) = wrapper1(inference)
- val fun1 = mirror.definitions.FunctionClass(1)
- val viewTpe = mirror.TypeRef(fun1.typeConstructor.prefix, fun1, List(from, to))
- wrapper(mirror.analyzer.inferImplicit(tree, viewTpe, reportAmbiguous, true, context, !silent, pos)) match {
+ val fun1 = universe.definitions.FunctionClass(1)
+ val viewTpe = universe.TypeRef(fun1.typeConstructor.prefix, fun1, List(from, to))
+ wrapper(universe.analyzer.inferImplicit(tree, viewTpe, reportAmbiguous, true, context, !silent, pos)) match {
case failure if failure.tree.isEmpty =>
macroLogVerbose("implicit search has failed. to find out the reason, turn on -Xlog-implicits")
- if (context.hasErrors) throw new mirror.TypeError(context.errBuffer.head.errPos, context.errBuffer.head.errMsg)
- mirror.EmptyTree
+ if (context.hasErrors) throw new universe.TypeError(context.errBuffer.head.errPos, context.errBuffer.head.errMsg)
+ universe.EmptyTree
case success =>
success.tree
}
}
- type TypeError = mirror.TypeError
+ type TypeError = universe.TypeError
object TypeError extends TypeErrorExtractor {
def unapply(error: TypeError): Option[(Position, String)] = Some((error.pos, error.msg))
}
- def resetAllAttrs(tree: Tree): Tree = mirror.resetAllAttrs(tree)
+ def resetAllAttrs(tree: Tree): Tree = universe.resetAllAttrs(tree)
- def resetLocalAttrs(tree: Tree): Tree = mirror.resetLocalAttrs(tree)
+ def resetLocalAttrs(tree: Tree): Tree = universe.resetLocalAttrs(tree)
} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/makro/runtime/Util.scala b/src/compiler/scala/reflect/makro/runtime/Util.scala
index 2671155721..09ed47efdd 100644
--- a/src/compiler/scala/reflect/makro/runtime/Util.scala
+++ b/src/compiler/scala/reflect/makro/runtime/Util.scala
@@ -4,7 +4,7 @@ package runtime
trait Util {
self: Context =>
- import mirror._
+ import universe._
def literalNull = Expr[Null](Literal(Constant(null)))(TypeTag.Null)
diff --git a/src/compiler/scala/reflect/reify/Taggers.scala b/src/compiler/scala/reflect/reify/Taggers.scala
index 26b8b1efde..d8da7e74ff 100644
--- a/src/compiler/scala/reflect/reify/Taggers.scala
+++ b/src/compiler/scala/reflect/reify/Taggers.scala
@@ -6,7 +6,7 @@ import scala.reflect.makro.runtime.Context
abstract class Taggers {
val c: Context
- import c.mirror._
+ import c.universe._
import definitions._
val coreTags = Map(
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index ed3f372cb2..96fcdd793e 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -26,7 +26,7 @@ import java.lang.reflect.{Array => jArray, Method => jMethod}
* def fooBar[T: c.TypeTag]
* (c: scala.reflect.makro.Context)
* (xs: c.Expr[List[T]])
- * : c.mirror.Tree = {
+ * : c.Tree = {
* ...
* }
*
@@ -200,8 +200,8 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
implicit class AugmentedString(s: String) {
def abbreviateCoreAliases: String = { // hack!
var result = s
- result = result.replace("c.mirror.TypeTag", "c.TypeTag")
- result = result.replace("c.mirror.Expr", "c.Expr")
+ result = result.replace("c.universe.TypeTag", "c.TypeTag")
+ result = result.replace("c.universe.Expr", "c.Expr")
result
}
}
@@ -770,8 +770,8 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
private def macroContext(typer: Typer, prefixTree: Tree, expandeeTree: Tree): MacroContext =
new {
- val mirror: self.global.type = self.global
- val callsiteTyper: mirror.analyzer.Typer = typer.asInstanceOf[global.analyzer.Typer]
+ val universe: self.global.type = self.global
+ val callsiteTyper: universe.analyzer.Typer = typer.asInstanceOf[global.analyzer.Typer]
val expandee = expandeeTree
} with UnaffiliatedMacroContext {
// todo. infer precise typetag for this Expr, namely the PrefixType member of the Context refinement
@@ -787,26 +787,23 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
* @return list of runtime objects to pass to the implementation obtained by ``macroRuntime''
*/
private def macroArgs(typer: Typer, expandee: Tree): Option[List[Any]] = {
- val macroDef = expandee.symbol
- val runtime = macroRuntime(macroDef) orElse { return None }
- var prefixTree: Tree = EmptyTree
- var typeArgs = List[Tree]()
- val exprArgs = ListBuffer[List[Expr[_]]]()
-
+ val macroDef = expandee.symbol
+ val runtime = macroRuntime(macroDef) orElse { return None }
+ val prefixTree = expandee.collect{ case Select(qual, name) => qual }.headOption.getOrElse(EmptyTree)
+ val context = expandee.attachments.get[MacroRuntimeAttachment].flatMap(_.macroContext).getOrElse(macroContext(typer, prefixTree, expandee))
+ var typeArgs = List[Tree]()
+ val exprArgs = ListBuffer[List[Expr[_]]]()
def collectMacroArgs(tree: Tree): Unit = tree match {
case Apply(fn, args) =>
// todo. infer precise typetag for this Expr, namely the declared type of the corresponding macro impl argument
- exprArgs.prepend(args map (arg => Expr(rootMirror, FixedMirrorTreeCreator(rootMirror, arg))(TypeTag.Nothing)))
+ exprArgs.prepend(args map (arg => context.Expr[Nothing](arg)(TypeTag.Nothing)))
collectMacroArgs(fn)
case TypeApply(fn, args) =>
typeArgs = args
collectMacroArgs(fn)
- case Select(qual, name) =>
- prefixTree = qual
case _ =>
}
collectMacroArgs(expandee)
- val context = expandee.attachments.get[MacroAttachment].flatMap(_.macroContext).getOrElse(macroContext(typer, prefixTree, expandee))
var argss: List[List[Any]] = List(context) :: exprArgs.toList
macroTraceVerbose("argss: ")(argss)
val rawArgss =
@@ -1115,7 +1112,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
delayed += expandee -> undetparams
// need to save typer context for `macroExpandAll`
// need to save macro context to preserve enclosures
- expandee addAttachment MacroAttachment(delayed = true, typerContext = typer.context, macroContext = Some(context.asInstanceOf[MacroContext]))
+ expandee addAttachment MacroRuntimeAttachment(delayed = true, typerContext = typer.context, macroContext = Some(context.asInstanceOf[MacroContext]))
Delay(expandee)
}
else {
@@ -1130,7 +1127,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
case x => x
}
finally {
- expandee.removeAttachment[MacroAttachment]
+ expandee.removeAttachment[MacroRuntimeAttachment]
if (!isSuccess) openMacros = openMacros.tail
}
}
@@ -1281,7 +1278,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
override def transform(tree: Tree) = super.transform(tree match {
// todo. expansion should work from the inside out
case wannabe if (delayed contains wannabe) && calculateUndetparams(wannabe).isEmpty =>
- val context = wannabe.attachments.get[MacroAttachment].get.typerContext
+ val context = wannabe.attachments.get[MacroRuntimeAttachment].get.typerContext
delayed -= wannabe
context.implicitsEnabled = typer.context.implicitsEnabled
context.enrichmentEnabled = typer.context.enrichmentEnabled
diff --git a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
index 3033230603..190b18711c 100644
--- a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
@@ -5,6 +5,6 @@ trait StdAttachments {
self: Analyzer =>
type UnaffiliatedMacroContext = scala.reflect.makro.runtime.Context
- type MacroContext = UnaffiliatedMacroContext { val mirror: self.global.type }
- case class MacroAttachment(delayed: Boolean, typerContext: Context, macroContext: Option[MacroContext])
+ type MacroContext = UnaffiliatedMacroContext { val universe: self.global.type }
+ case class MacroRuntimeAttachment(delayed: Boolean, typerContext: Context, macroContext: Option[MacroContext])
} \ No newline at end of file
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]
+}