All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ildl.plugin.ildl.scala Maven / Gradle / Ivy

The newest version!
package ildl.plugin

import scala.tools.nsc.Global
import scala.tools.nsc.Phase
import scala.tools.nsc.plugins._
import scala.tools.nsc.transform._
import scala.tools.nsc.settings.ScalaVersion
import infrastructure._
import metadata._
import transform._
import postParser._
import inject._
import bridge._
import coerce._
import commit._
import tweakerasure._

/** Metadata and definitions */
trait ildlHelperComponent extends
  ildlDefinitions with
  ildlMetadata with
  ildlAddons {
  val global: Global
}

/** Post-parser component, which marks values and methods in the `adrt` scope */
trait PostParserComponent extends
    PluginComponent
    with TreeRewriters
    with PostParserTreeTransformer {

  val helper: ildlHelperComponent { val global: PostParserComponent.this.global.type }
}

/** The component that injects @repr annotations */
trait InjectComponent extends
    PluginComponent
    with InjectTreeTransformer
    with InjectInfoTransformer {

  val helper: ildlHelperComponent { val global: InjectComponent.this.global.type }

  def injectPhase: StdPhase

  def afterInject[T](op: => T): T = global.exitingPhase(injectPhase)(op)
  def beforeInject[T](op: => T): T = global.enteringPhase(injectPhase)(op)
}

/** The component that introduces coercions */
trait BridgeComponent extends
    PluginComponent
    with BridgeTreeTransformer
    with BridgeInfoTransformer {

  val helper: ildlHelperComponent { val global: BridgeComponent.this.global.type }

  def bridgePhase: StdPhase

  def afterBridge[T](op: => T): T = global.exitingPhase(bridgePhase)(op)
  def afterCoerce[T](op: => T): T
  def beforeBridge[T](op: => T): T = global.enteringPhase(bridgePhase)(op)
  def beforeCoerce[T](op: => T): T
}

/** The component that introduces coercions */
trait CoerceComponent extends
    PluginComponent
    with ReprAnnotationCheckers
    with CoerceTreeTransformer {

  val helper: ildlHelperComponent { val global: CoerceComponent.this.global.type }

  def coercePhase: StdPhase

  def afterCoerce[T](op: => T): T = global.exitingPhase(coercePhase)(op)
  def beforeCoerce[T](op: => T): T = global.enteringPhase(coercePhase)(op)
}

/** The component that introduces coercions */
trait CommitComponent extends
    PluginComponent
    with CommitInfoTransformer
    with CommitTreeTransformer {

  val helper: ildlHelperComponent { val global: CommitComponent.this.global.type }

  def commitPhase: StdPhase

  def afterCommit[T](op: => T): T = global.exitingPhase(commitPhase)(op)
  def beforeCommit[T](op: => T): T = global.enteringPhase(commitPhase)(op)
}

/** Tree preparer before retyping the tree */
trait TweakErasureComponent extends
    PluginComponent
    with TweakErasureTreeTransformer {

  val helper: ildlHelperComponent { val global: TweakErasureComponent.this.global.type }

  def tweakErasurePhase: Phase

  def afterTweakErasure[T](op: => T): T = global.exitingPhase(tweakErasurePhase)(op)
  def beforeTweakErasure[T](op: => T): T = global.enteringPhase(tweakErasurePhase)(op)
}


class ildl(val global: Global) extends Plugin {
  import global._

  val name = "ildl"
  val description = "Transforms your code"

  var flag_passive = false

  lazy val components =
    List[PluginComponent](PostParserPhase,
                          InjectPhase,
                          BridgePhase,
                          CoercePhase,
                          CommitPhase,
                          TweakErasurePhase)

  // LDL ftw!
  global.addAnnotationChecker(CoercePhase.ReprAnnotationChecker)

  override def processOptions(options: List[String], error: String => Unit) {
    for (option <- options) {
      option.toLowerCase() match {
        case "passive" => // do not honor annotations => do not transform the code
          flag_passive = true
        case _ =>
          error("ildl: Option not understood: " + option)
      }
    }
  }

  private object helperComponent extends ildlHelperComponent {
    val global: ildl.this.global.type = ildl.this.global

    def flag_passive = ildl.this.flag_passive
    def ildlBridgePhase: Phase = BridgePhase.bridgePhase
  }

  private object PostParserPhase extends {
    val helper = helperComponent
  } with PostParserComponent {
    val global: ildl.this.global.type = ildl.this.global
    val runsAfter = List("parser")
    override val runsRightAfter = Some("parser")
    val phaseName = "ildl-postparser"
  }

  private object InjectPhase extends {
    val helper = helperComponent
  } with InjectComponent {
    val global: ildl.this.global.type = ildl.this.global
    val runsAfter = List("typer")
    override val runsRightAfter = Some("typer")
    val phaseName = "ildl-inject"

    var injectPhase : StdPhase = _
    override def newPhase(prev: scala.tools.nsc.Phase): StdPhase = {
      injectPhase = new Phase(prev)
      injectPhase
    }
  }

  private object BridgePhase extends {
    val helper = helperComponent
  } with BridgeComponent {
    val global: ildl.this.global.type = ildl.this.global
    val runsAfter = List("uncurry")
    override val runsRightAfter = Some("uncurry")
    val phaseName = "ildl-bridge"

    var bridgePhase : StdPhase = _
    override def newPhase(prev: scala.tools.nsc.Phase): StdPhase = {
      bridgePhase = new BridgePhase(prev.asInstanceOf[BridgePhase.StdPhase])
      bridgePhase
    }

    def afterCoerce[T](op: => T): T = global.exitingPhase(CoercePhase.coercePhase)(op)
    def beforeCoerce[T](op: => T): T = global.enteringPhase(CoercePhase.coercePhase)(op)
  }

  private object CoercePhase extends {
    val helper = helperComponent
  } with CoerceComponent {
    val global: ildl.this.global.type = ildl.this.global
    val runsAfter = List(BridgePhase.phaseName)
    override val runsRightAfter = Some(BridgePhase.phaseName)
    val phaseName = "ildl-coerce"

    var coercePhase : StdPhase = _
    override def newPhase(prev: scala.tools.nsc.Phase): Phase = {
      coercePhase = new CoercePhase(prev.asInstanceOf[CoercePhase.StdPhase])
      coercePhase
    }
  }

  private object CommitPhase extends {
    val helper = helperComponent
  } with CommitComponent {
    val global: ildl.this.global.type = ildl.this.global
    val runsAfter = List(CoercePhase.phaseName)
    override val runsRightAfter = Some(CoercePhase.phaseName)
    val phaseName = "ildl-commit"

    var commitPhase : StdPhase = _
    override def newPhase(prev: scala.tools.nsc.Phase): StdPhase = {
      commitPhase = new Phase(prev)
      commitPhase
    }
  }

  private object TweakErasurePhase extends {
    val helper = helperComponent
  } with TweakErasureComponent {
    val global: ildl.this.global.type = ildl.this.global
    val runsAfter = Nil
    override val runsRightAfter = Some("posterasure")
    val phaseName = "ildl-tweakerasure"

    var tweakErasurePhase: Phase = _

    def newPhase(_prev: Phase) = {
      tweakErasurePhase = new TweakErasurePhase(_prev)
      tweakErasurePhase
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy