summaryrefslogtreecommitdiff
path: root/src/repl/scala/tools/nsc/interpreter/Phased.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/repl/scala/tools/nsc/interpreter/Phased.scala')
-rw-r--r--src/repl/scala/tools/nsc/interpreter/Phased.scala144
1 files changed, 144 insertions, 0 deletions
diff --git a/src/repl/scala/tools/nsc/interpreter/Phased.scala b/src/repl/scala/tools/nsc/interpreter/Phased.scala
new file mode 100644
index 0000000000..1cdbd65949
--- /dev/null
+++ b/src/repl/scala/tools/nsc/interpreter/Phased.scala
@@ -0,0 +1,144 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2013 LAMP/EPFL
+ * @author Paul Phillips
+ */
+
+package scala.tools.nsc
+package interpreter
+
+import scala.collection.immutable
+import scala.language.implicitConversions
+
+/** Mix this into an object and use it as a phasing
+ * swiss army knife.
+ */
+trait Phased {
+ val global: Global
+ import global._
+
+ private var active: PhaseName = NoPhaseName
+ private var multi: Seq[PhaseName] = Nil
+
+ def get = active
+ def set(phase: PhaseName): Boolean = phase match {
+ case NoPhaseName => false
+ case name => active = name ; true
+ }
+ def setMulti(phases: Seq[PhaseName]): Boolean = {
+ if (phases contains NoPhaseName) false
+ else {
+ multi = phases
+ true
+ }
+ }
+
+ private def parsePhaseChange(str: String): Option[Int] = {
+ if (str == "") Some(0)
+ else if (str startsWith ".prev") parsePhaseChange(str drop 5) map (_ - 1)
+ else if (str startsWith ".next") parsePhaseChange(str drop 5) map (_ + 1)
+ else str.head match {
+ case '+' | '-' =>
+ val (num, rest) = str.tail.span(_.isDigit)
+ val diff = if (str.head == '+') num.toInt else -num.toInt
+ parsePhaseChange(rest) map (_ + diff)
+ case _ =>
+ None
+ }
+ }
+
+ /** Takes a string like 4, typer+2, typer.next, etc.
+ * and turns it into a PhaseName instance.
+ */
+ private def parseInternal(str: String): PhaseName = {
+ if (str == "") NoPhaseName
+ else if (str forall (_.isDigit)) PhaseName(str.toInt)
+ else {
+ val (name, rest) = str.toLowerCase span (_.isLetter)
+ val start = PhaseName(name)
+ val change = parsePhaseChange(rest)
+
+ if (start.isEmpty || change.isEmpty) NoPhaseName
+ else PhaseName(start.id + change.get)
+ }
+ }
+ def parse(str: String): PhaseName =
+ try parseInternal(str)
+ catch { case _: Exception => NoPhaseName }
+
+ def atCurrent[T](body: => T): T = enteringPhase(get)(body)
+ def multi[T](body: => T): Seq[T] = multi map (ph => at(ph)(body))
+
+ def at[T](ph: PhaseName)(body: => T): T = {
+ val saved = get
+ set(ph)
+ try atCurrent(body)
+ finally set(saved)
+ }
+ def atMulti[T](phs: Seq[PhaseName])(body: => T): Seq[T] = {
+ val saved = multi
+ setMulti(phs)
+ try multi(body)
+ finally setMulti(saved)
+ }
+
+ def atMap[T](phs: Seq[PhaseName])(body: => T): Seq[(PhaseName, T)] =
+ phs zip atMulti(phs)(body)
+
+ object PhaseName {
+ implicit lazy val phaseNameOrdering: Ordering[PhaseName] = Ordering[Int] on (_.id)
+
+ lazy val all = List(
+ Parser, Namer, Packageobjects, Typer, Superaccessors, Pickler, Refchecks,
+ Selectiveanf, Liftcode, Selectivecps, Uncurry, Tailcalls, Specialize,
+ Explicitouter, Erasure, Lazyvals, Lambdalift, Constructors, Flatten, Mixin,
+ Cleanup, Delambdafy, Icode, Inliner, Closelim, Dce, Jvm, Terminal
+ )
+ lazy val nameMap = all.map(x => x.name -> x).toMap withDefaultValue NoPhaseName
+ multi = all
+
+ def apply(id: Int): PhaseName = all find (_.id == id) getOrElse NoPhaseName
+ implicit def apply(s: String): PhaseName = nameMap(s)
+ }
+ sealed abstract class PhaseName {
+ lazy val id = phase.id
+ lazy val name = toString.toLowerCase
+ def phase = currentRun.phaseNamed(name)
+ def isEmpty = this eq NoPhaseName
+ }
+
+ case object Parser extends PhaseName
+ case object Namer extends PhaseName
+ case object Packageobjects extends PhaseName
+ case object Typer extends PhaseName
+ case object Superaccessors extends PhaseName
+ case object Pickler extends PhaseName
+ case object Refchecks extends PhaseName
+ case object Selectiveanf extends PhaseName
+ case object Liftcode extends PhaseName
+ case object Selectivecps extends PhaseName
+ case object Uncurry extends PhaseName
+ case object Tailcalls extends PhaseName
+ case object Specialize extends PhaseName
+ case object Explicitouter extends PhaseName
+ case object Erasure extends PhaseName
+ case object Lazyvals extends PhaseName
+ case object Lambdalift extends PhaseName
+ case object Constructors extends PhaseName
+ case object Flatten extends PhaseName
+ case object Mixin extends PhaseName
+ case object Cleanup extends PhaseName
+ case object Delambdafy extends PhaseName
+ case object Icode extends PhaseName
+ case object Inliner extends PhaseName
+ case object Closelim extends PhaseName
+ case object Dce extends PhaseName
+ case object Jvm extends PhaseName
+ case object Terminal extends PhaseName
+ case object NoPhaseName extends PhaseName {
+ override lazy val id = -1
+ override lazy val name = phase.name
+ override def phase = NoPhase
+ }
+
+ implicit def phaseEnumToPhase(name: PhaseName): Phase = name.phase
+}