diff options
author | Paul Phillips <paulp@improving.org> | 2013-03-10 17:17:58 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2013-03-11 20:07:24 -0700 |
commit | 48cc8b47fcadaa187026ca0422178c9094e4b412 (patch) | |
tree | 32f3cce4559030e3088741390024c19eb5110bbe /src/repl/scala/tools/nsc/interpreter/ReplVals.scala | |
parent | 1b6297f642877dcc7edcd704a5d3cf99a12e54b8 (diff) | |
download | scala-48cc8b47fcadaa187026ca0422178c9094e4b412.tar.gz scala-48cc8b47fcadaa187026ca0422178c9094e4b412.tar.bz2 scala-48cc8b47fcadaa187026ca0422178c9094e4b412.zip |
Modularized the repl.
Following in the footsteps of scaladoc and interactive.
The interpreter sources move into src/repl, and are given
a separate build target. As with the others, at present
they are still packaged into scala-compiler.jar.
A summary of changes:
- repl requires use of ReplGlobal (this was already implied)
- macro code's repl-specific classloader hack pulled into overridable
method and overridden in ReplGlobal
- removed -Ygen-javap option to eliminate backend's dependency on javap
- removed -Yrepl-debug option (can still be enabled with -Dscala.repl.debug)
- pushed javap code into src/repl so javax.tools dependency can bee
weakened to the repl only
- removed some "show pickled" related code which hasn't worked right
in a while and isn't the right way to do it anymore anyway. Will
return to fix showPickled and provide it with some tests.
Diffstat (limited to 'src/repl/scala/tools/nsc/interpreter/ReplVals.scala')
-rw-r--r-- | src/repl/scala/tools/nsc/interpreter/ReplVals.scala | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/src/repl/scala/tools/nsc/interpreter/ReplVals.scala b/src/repl/scala/tools/nsc/interpreter/ReplVals.scala new file mode 100644 index 0000000000..ea100b25f2 --- /dev/null +++ b/src/repl/scala/tools/nsc/interpreter/ReplVals.scala @@ -0,0 +1,82 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2013 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools.nsc +package interpreter + +import scala.language.implicitConversions +import scala.reflect.api.{Universe => ApiUniverse} +import scala.reflect.runtime.{universe => ru} + +/** A class which the repl utilizes to expose predefined objects. + * The base implementation is empty; the standard repl implementation + * is StdReplVals. + */ +abstract class ReplVals { } + +class StdReplVals(final val r: ILoop) extends ReplVals { + final lazy val repl = r + final lazy val intp = r.intp + final lazy val power = r.power + final lazy val reader = r.in + final lazy val vals = this + final lazy val global: intp.global.type = intp.global + final lazy val isettings = intp.isettings + final lazy val completion = reader.completion + final lazy val history = reader.history + final lazy val phased = power.phased + final lazy val analyzer = global.analyzer + + object treedsl extends { val global: intp.global.type = intp.global } with ast.TreeDSL { } + + final lazy val typer = analyzer.newTyper( + analyzer.rootContext( + power.unit("").asInstanceOf[analyzer.global.CompilationUnit] + ) + ) + def lastRequest = intp.lastRequest + + class ReplImplicits extends power.Implicits2 { + import intp.global._ + + private val tagFn = ReplVals.mkCompilerTypeFromTag[intp.global.type](global) + implicit def mkCompilerTypeFromTag(sym: Symbol) = tagFn(sym) + } + + final lazy val replImplicits = new ReplImplicits + + def typed[T <: analyzer.global.Tree](tree: T): T = typer.typed(tree).asInstanceOf[T] +} + +object ReplVals { + /** Latest attempt to work around the challenge of foo.global.Type + * not being seen as the same type as bar.global.Type even though + * the globals are the same. Dependent method types to the rescue. + */ + def mkCompilerTypeFromTag[T <: Global](global: T) = { + import global._ + + /** We can't use definitions.compilerTypeFromTag directly because we're passing + * it to map and the compiler refuses to perform eta expansion on a method + * with a dependent return type. (Can this be relaxed?) To get around this + * I have this forwarder which widens the type and then cast the result back + * to the dependent type. + */ + def compilerTypeFromTag(t: ApiUniverse # WeakTypeTag[_]): Global#Type = + definitions.compilerTypeFromTag(t) + + class AppliedTypeFromTags(sym: Symbol) { + def apply[M](implicit m1: ru.TypeTag[M]): Type = + if (sym eq NoSymbol) NoType + else appliedType(sym, compilerTypeFromTag(m1).asInstanceOf[Type]) + + def apply[M1, M2](implicit m1: ru.TypeTag[M1], m2: ru.TypeTag[M2]): Type = + if (sym eq NoSymbol) NoType + else appliedType(sym, compilerTypeFromTag(m1).asInstanceOf[Type], compilerTypeFromTag(m2).asInstanceOf[Type]) + } + + (sym: Symbol) => new AppliedTypeFromTags(sym) + } +} |