aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/Phases.scala
diff options
context:
space:
mode:
authorFelix Mulder <felix.mulder@gmail.com>2016-11-02 11:08:28 +0100
committerGuillaume Martres <smarter@ubuntu.com>2016-11-22 01:35:07 +0100
commit8a61ff432543a29234193cd1f7c14abd3f3d31a0 (patch)
treea8147561d307af862c295cfc8100d271063bb0dd /src/dotty/tools/dotc/core/Phases.scala
parent6a455fe6da5ff9c741d91279a2dc6fe2fb1b472f (diff)
downloaddotty-8a61ff432543a29234193cd1f7c14abd3f3d31a0.tar.gz
dotty-8a61ff432543a29234193cd1f7c14abd3f3d31a0.tar.bz2
dotty-8a61ff432543a29234193cd1f7c14abd3f3d31a0.zip
Move compiler and compiler tests to compiler dir
Diffstat (limited to 'src/dotty/tools/dotc/core/Phases.scala')
-rw-r--r--src/dotty/tools/dotc/core/Phases.scala377
1 files changed, 0 insertions, 377 deletions
diff --git a/src/dotty/tools/dotc/core/Phases.scala b/src/dotty/tools/dotc/core/Phases.scala
deleted file mode 100644
index 222e2235d..000000000
--- a/src/dotty/tools/dotc/core/Phases.scala
+++ /dev/null
@@ -1,377 +0,0 @@
-package dotty.tools.dotc
-package core
-
-import Periods._
-import Contexts._
-import dotty.tools.backend.jvm.{LabelDefs, GenBCode}
-import dotty.tools.dotc.core.Symbols.ClassSymbol
-import util.DotClass
-import DenotTransformers._
-import Denotations._
-import Decorators._
-import config.Printers.config
-import scala.collection.mutable.{ListBuffer, ArrayBuffer}
-import dotty.tools.dotc.transform.TreeTransforms.{TreeTransformer, MiniPhase, TreeTransform}
-import dotty.tools.dotc.transform._
-import Periods._
-import typer.{FrontEnd, RefChecks}
-import ast.tpd
-
-trait Phases {
- self: Context =>
-
- import Phases._
-
- def phase: Phase = base.phases(period.firstPhaseId)
-
- def phasesStack: List[Phase] =
- if ((this eq NoContext) || !phase.exists) Nil
- else phase :: outersIterator.dropWhile(_.phase == phase).next.phasesStack
-
- /** Execute `op` at given phase */
- def atPhase[T](phase: Phase)(op: Context => T): T =
- atPhase(phase.id)(op)
-
- def atNextPhase[T](op: Context => T): T = atPhase(phase.next)(op)
-
- def atPhaseNotLaterThan[T](limit: Phase)(op: Context => T): T =
- if (!limit.exists || phase <= limit) op(this) else atPhase(limit)(op)
-
- def atPhaseNotLaterThanTyper[T](op: Context => T): T =
- atPhaseNotLaterThan(base.typerPhase)(op)
-
- def isAfterTyper: Boolean = base.isAfterTyper(phase)
-}
-
-object Phases {
-
- trait PhasesBase {
- this: ContextBase =>
-
- // drop NoPhase at beginning
- def allPhases = (if (squashedPhases.nonEmpty) squashedPhases else phases).tail
-
- object NoPhase extends Phase {
- override def exists = false
- def phaseName = "<no phase>"
- def run(implicit ctx: Context): Unit = unsupported("run")
- def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation = unsupported("transform")
- }
-
- object SomePhase extends Phase {
- def phaseName = "<some phase>"
- def run(implicit ctx: Context): Unit = unsupported("run")
- }
-
- /** A sentinel transformer object */
- class TerminalPhase extends DenotTransformer {
- def phaseName = "terminal"
- def run(implicit ctx: Context): Unit = unsupported("run")
- def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation =
- unsupported("transform")
- override def lastPhaseId(implicit ctx: Context) = id
- }
-
- def phasePlan = this.phasesPlan
- def setPhasePlan(phasess: List[List[Phase]]) = this.phasesPlan = phasess
-
- /** Squash TreeTransform's beloning to same sublist to a single TreeTransformer
- * Each TreeTransform gets own period,
- * whereas a combined TreeTransformer gets period equal to union of periods of it's TreeTransforms
- */
- def squashPhases(phasess: List[List[Phase]],
- phasesToSkip: List[String], stopBeforePhases: List[String], stopAfterPhases: List[String], YCheckAfter: List[String]): List[Phase] = {
- val squashedPhases = ListBuffer[Phase]()
- var prevPhases: Set[Class[_ <: Phase]] = Set.empty
- val YCheckAll = YCheckAfter.contains("all")
-
- var stop = false
- val filteredPhases = phasess.map(_.filter { p =>
- val pstop = stop
- stop = stop | stopBeforePhases.contains(p.phaseName) | stopAfterPhases.contains(p.phaseName)
- !(pstop || stopBeforePhases.contains(p.phaseName) || phasesToSkip.contains(p.phaseName))
- })
-
- var i = 0
-
- while (i < filteredPhases.length) {
- if (filteredPhases(i).nonEmpty) { //could be empty due to filtering
- val filteredPhaseBlock = filteredPhases(i)
- val phaseToAdd =
- if (filteredPhaseBlock.length > 1) {
- val phasesInBlock: Set[String] = filteredPhaseBlock.map(_.phaseName).toSet
- for (phase <- filteredPhaseBlock) {
- phase match {
- case p: MiniPhase =>
- val unmetRequirements = p.runsAfterGroupsOf &~ prevPhases
- assert(unmetRequirements.isEmpty,
- s"${phase.phaseName} requires ${unmetRequirements.mkString(", ")} to be in different TreeTransformer")
-
- case _ =>
- assert(false, s"Only tree transforms can be squashed, ${phase.phaseName} can not be squashed")
- }
- }
- val block = new TreeTransformer {
- override def phaseName: String = miniPhases.map(_.phaseName).mkString("TreeTransform:{", ", ", "}")
- override def miniPhases: Array[MiniPhase] = filteredPhaseBlock.asInstanceOf[List[MiniPhase]].toArray
- }
- prevPhases ++= filteredPhaseBlock.map(_.getClazz)
- block
- } else { // block of a single phase, no squashing
- val phase = filteredPhaseBlock.head
- prevPhases += phase.getClazz
- phase
- }
- squashedPhases += phaseToAdd
- val shouldAddYCheck = YCheckAfter.containsPhase(phaseToAdd) || YCheckAll
- if (shouldAddYCheck) {
- val checker = new TreeChecker
- squashedPhases += checker
- }
- }
-
- i += 1
- }
- squashedPhases.toList
- }
-
- /** Use the following phases in the order they are given.
- * The list should never contain NoPhase.
- * if squashing is enabled, phases in same subgroup will be squashed to single phase.
- */
- def usePhases(phasess: List[Phase], squash: Boolean = true) = {
-
- val flatPhases = collection.mutable.ListBuffer[Phase]()
-
- phasess.foreach(p => p match {
- case t: TreeTransformer => flatPhases ++= t.miniPhases
- case _ => flatPhases += p
- })
-
- phases = (NoPhase :: flatPhases.toList ::: new TerminalPhase :: Nil).toArray
- var phasesAfter:Set[Class[_ <: Phase]] = Set.empty
- nextDenotTransformerId = new Array[Int](phases.length)
- denotTransformers = new Array[DenotTransformer](phases.length)
-
- var phaseId = 0
- def nextPhaseId = {
- phaseId += 1
- phaseId // starting from 1 as NoPhase is 0
- }
-
- def checkRequirements(p: Phase) = {
- val unmetPrecedeRequirements = p.runsAfter -- phasesAfter
- assert(unmetPrecedeRequirements.isEmpty,
- s"phase ${p} has unmet requirement: ${unmetPrecedeRequirements.mkString(", ")} should precede this phase")
- phasesAfter += p.getClazz
-
- }
- var i = 0
-
- while (i < phasess.length) {
- val phase = phasess(i)
- phase match {
- case t: TreeTransformer =>
- val miniPhases = t.miniPhases
- miniPhases.foreach{ phase =>
- checkRequirements(phase)
- phase.init(this, nextPhaseId)}
- t.init(this, miniPhases.head.id, miniPhases.last.id)
- case _ =>
- phase.init(this, nextPhaseId)
- checkRequirements(phase)
- }
-
- i += 1
- }
-
- phases.last.init(this, nextPhaseId) // init terminal phase
-
- i = phases.length
- var lastTransformerId = i
- while (i > 0) {
- i -= 1
- val phase = phases(i)
- phase match {
- case transformer: DenotTransformer =>
- lastTransformerId = i
- denotTransformers(i) = transformer
- case _ =>
- }
- nextDenotTransformerId(i) = lastTransformerId
- }
-
- if (squash) {
- this.squashedPhases = (NoPhase :: phasess).toArray
- } else {
- this.squashedPhases = this.phases
- }
-
- config.println(s"Phases = ${phases.deep}")
- config.println(s"nextDenotTransformerId = ${nextDenotTransformerId.deep}")
- }
-
- def phaseOfClass(pclass: Class[_]) = phases.find(pclass.isInstance).getOrElse(NoPhase)
-
- private val cachedPhases = collection.mutable.Set[PhaseCache]()
- private def cleanPhaseCache = cachedPhases.foreach(_.myPhase = NoPhase)
-
- /** A cache to compute the phase with given name, which
- * stores the phase as soon as phaseNamed returns something
- * different from NoPhase.
- */
- private class PhaseCache(pclass: Class[_ <: Phase]) {
- var myPhase: Phase = NoPhase
- def phase = {
- if (myPhase eq NoPhase) myPhase = phaseOfClass(pclass)
- myPhase
- }
- cachedPhases += this
- }
-
- private val typerCache = new PhaseCache(classOf[FrontEnd])
- private val picklerCache = new PhaseCache(classOf[Pickler])
-
- private val refChecksCache = new PhaseCache(classOf[RefChecks])
- private val elimRepeatedCache = new PhaseCache(classOf[ElimRepeated])
- private val extensionMethodsCache = new PhaseCache(classOf[ExtensionMethods])
- private val erasureCache = new PhaseCache(classOf[Erasure])
- private val elimErasedValueTypeCache = new PhaseCache(classOf[ElimErasedValueType])
- private val patmatCache = new PhaseCache(classOf[PatternMatcher])
- private val lambdaLiftCache = new PhaseCache(classOf[LambdaLift])
- private val flattenCache = new PhaseCache(classOf[Flatten])
- private val explicitOuterCache = new PhaseCache(classOf[ExplicitOuter])
- private val gettersCache = new PhaseCache(classOf[Getters])
- private val genBCodeCache = new PhaseCache(classOf[GenBCode])
-
- def typerPhase = typerCache.phase
- def picklerPhase = picklerCache.phase
- def refchecksPhase = refChecksCache.phase
- def elimRepeatedPhase = elimRepeatedCache.phase
- def extensionMethodsPhase = extensionMethodsCache.phase
- def erasurePhase = erasureCache.phase
- def elimErasedValueTypePhase = elimErasedValueTypeCache.phase
- def patmatPhase = patmatCache.phase
- def lambdaLiftPhase = lambdaLiftCache.phase
- def flattenPhase = flattenCache.phase
- def explicitOuterPhase = explicitOuterCache.phase
- def gettersPhase = gettersCache.phase
- def genBCodePhase = genBCodeCache.phase
-
- def isAfterTyper(phase: Phase): Boolean = phase.id > typerPhase.id
- }
-
- trait Phase extends DotClass {
-
- def phaseName: String
-
- /** List of names of phases that should precede this phase */
- def runsAfter: Set[Class[_ <: Phase]] = Set.empty
-
- def run(implicit ctx: Context): Unit
-
- def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] =
- units.map { unit =>
- val unitCtx = ctx.fresh.setPhase(this.start).setCompilationUnit(unit)
- run(unitCtx)
- unitCtx.compilationUnit
- }
-
- def description: String = phaseName
-
- /** Output should be checkable by TreeChecker */
- def isCheckable: Boolean = true
-
- /** Check what the phase achieves, to be called at any point after it is finished.
- */
- def checkPostCondition(tree: tpd.Tree)(implicit ctx: Context): Unit = ()
-
- /** If set, allow missing or superfluous arguments in applications
- * and type applications.
- */
- def relaxedTyping: Boolean = false
-
- /** Is this phase the standard typerphase? True for FrontEnd, but
- * not for other first phases (such as FromTasty). The predicate
- * is tested in some places that perform checks and corrections. It's
- * different from isAfterTyper (and cheaper to test).
- */
- def isTyper = false
-
- def exists: Boolean = true
-
- private var myPeriod: Period = Periods.InvalidPeriod
- private var myBase: ContextBase = null
- private var myErasedTypes = false
- private var myFlatClasses = false
- private var myRefChecked = false
- private var mySymbolicRefs = false
- private var myLabelsReordered = false
-
-
- /** The sequence position of this phase in the given context where 0
- * is reserved for NoPhase and the first real phase is at position 1.
- * -1 if the phase is not installed in the context.
- */
- def id = myPeriod.firstPhaseId
-
- def period = myPeriod
- def start = myPeriod.firstPhaseId
- def end = myPeriod.lastPhaseId
-
- final def erasedTypes = myErasedTypes // Phase is after erasure
- final def flatClasses = myFlatClasses // Phase is after flatten
- final def refChecked = myRefChecked // Phase is after RefChecks
- final def symbolicRefs = mySymbolicRefs // Phase is after ResolveSuper, newly generated TermRefs should be symbolic
- final def labelsReordered = myLabelsReordered // Phase is after LabelDefs, labels are flattened and owner chains don't mirror this
-
- protected[Phases] def init(base: ContextBase, start: Int, end:Int): Unit = {
- if (start >= FirstPhaseId)
- assert(myPeriod == Periods.InvalidPeriod, s"phase $this has already been used once; cannot be reused")
- myBase = base
- myPeriod = Period(NoRunId, start, end)
- myErasedTypes = prev.getClass == classOf[Erasure] || prev.erasedTypes
- myFlatClasses = prev.getClass == classOf[Flatten] || prev.flatClasses
- myRefChecked = prev.getClass == classOf[RefChecks] || prev.refChecked
- mySymbolicRefs = prev.getClass == classOf[ResolveSuper] || prev.symbolicRefs
- myLabelsReordered = prev.getClass == classOf[LabelDefs] || prev.labelsReordered
- }
-
- protected[Phases] def init(base: ContextBase, id: Int): Unit = init(base, id, id)
-
- final def <=(that: Phase) =
- exists && id <= that.id
-
- final def prev: Phase =
- if (id > FirstPhaseId) myBase.phases(start - 1) else myBase.NoPhase
-
- final def next: Phase =
- if (hasNext) myBase.phases(end + 1) else myBase.NoPhase
-
- final def hasNext = start >= FirstPhaseId && end + 1 < myBase.phases.length
-
- final def iterator =
- Iterator.iterate(this)(_.next) takeWhile (_.hasNext)
-
- override def toString = phaseName
- }
-
- trait NeedsCompanions {
- def isCompanionNeeded(cls: ClassSymbol)(implicit ctx: Context): Boolean
- }
-
- /** Replace all instances of `oldPhaseClass` in `current` phases
- * by the result of `newPhases` applied to the old phase.
- */
- def replace(oldPhaseClass: Class[_ <: Phase], newPhases: Phase => List[Phase], current: List[List[Phase]]): List[List[Phase]] =
- current.map(_.flatMap(phase =>
- if (oldPhaseClass.isInstance(phase)) newPhases(phase) else phase :: Nil))
-
- /** Dotty deviation: getClass yields Class[_], instead of [Class <: <type of receiver>].
- * We can get back the old behavior using this decorator. We should also use the same
- * trick for standard getClass.
- */
- private implicit class getClassDeco[T](val x: T) extends AnyVal {
- def getClazz: Class[_ <: T] = x.getClass.asInstanceOf[Class[_ <: T]]
- }
-}