scala.tools.nsc.interpreter.ReplVals.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scala-compiler Show documentation
Show all versions of scala-compiler Show documentation
Compiler for the Scala Programming Language
/* 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._
import definitions._
/** 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)
}
}