Search code examples
scalaread-eval-print-loop

How to use :phase power command in REPL?


Power mode of Scala REPL's enables :phase command:

:phase <phase>           set the implicit phase for power commands

I cannot seem to find documentation on how to use this command. For example, say I set parser compiler phase

scala> :phase parser
Active phase is now: Parser

What power command has been affected by it? How do I call these affected power commands? How does it differ from :settings -Xprint:parser?


Solution

  • The command causes your code to be evaluated enteringPhase, which is accomplished using intp.setExecutionWrapper. You can witness the wrapping with -Dscala.repl.debug.

    It wraps the "print" of REPL:

    lazy val $print: _root_.java.lang.String = $line4.$read.$iw.$iw.$r.phased.atCurrent {
    

    The phased object just adapts the call to enteringPhase.

    Here is an example where you see the erased type at a later phase:

    scala> global.rootMirror.staticClass("scala.Option").typeSignature
    res0: $r.global.Type =
    [+A <: <?>]AnyRef
            with IterableOnce[A]
            with Product
            with Serializable {
      def <init>(): Option[A]
      final def isEmpty: Boolean
      final def isDefined: Boolean
      final override def knownSize: Int
      def get: A
      final def getOrElse[B >: A](default: => B): B
      final def orNull[A1 >: A](implicit ev: Null <:< A1): A1
      final def map[B](f: A => B): Option[B]
      final def fold[B](ifEmpty: => B)(f: A => B): B
      final def flatMap[B](f: A => Option[B]): Option[B]
      def flatten[B](implicit ev: A <:< Option[B]): Option[B]
      final def filter(p: A => Boolean): Option[A]
      final def filterNot(p: A => Boolean): Option[A]
      final def nonEmpty: Boolean
      final def withFilter(p: A => Boolean): Option.this.WithFilter
      class WithFilter extends AnyRef
      final def...
    
    scala> global.rootMirror.staticClass("scala.Option").typeSignature.getClass
    res1: Class[_ <: $r.global.Type] = class scala.reflect.internal.Types$PolyType
    
    scala> :phase cleanup
    Active phase is now: Cleanup
    
    scala> global.rootMirror.staticClass("scala.Option").typeSignature.getClass
    res2: Class[_ <: $r.global.Type] = class scala.reflect.internal.Types$ClassInfoType
    
    scala> global.rootMirror.staticClass("scala.Option").typeSignature
    res3: $r.global.Type =
    Object
            with scala.collection.IterableOnce
            with Product
            with java.io.Serializable {
      def <init>(): Option
      final def isEmpty(): Boolean
      final def isDefined(): Boolean
      final override def knownSize(): Int
      def get(): Object
    [snip]
    

    The :type command in REPL is not affected because it calls exitingTyper.