diff options
author | Felix Mulder <felix.mulder@gmail.com> | 2016-11-02 11:08:28 +0100 |
---|---|---|
committer | Guillaume Martres <smarter@ubuntu.com> | 2016-11-22 01:35:07 +0100 |
commit | 8a61ff432543a29234193cd1f7c14abd3f3d31a0 (patch) | |
tree | a8147561d307af862c295cfc8100d271063bb0dd /src/dotty/tools/dotc/core/Phases.scala | |
parent | 6a455fe6da5ff9c741d91279a2dc6fe2fb1b472f (diff) | |
download | dotty-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.scala | 377 |
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]] - } -} |