From f0519c9e384ab1e0c8379caa08ed73a7347cf59c Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 18 Aug 2014 23:18:19 +0200 Subject: Changed phase dependencies from names to classes. Don't want stringly types for this. --- src/dotty/tools/dotc/Flatten.scala | 15 +++++++ src/dotty/tools/dotc/core/Phases.scala | 47 ++++++++++++---------- src/dotty/tools/dotc/transform/ElimByName.scala | 2 +- src/dotty/tools/dotc/transform/Erasure.scala | 3 +- .../tools/dotc/transform/ExtensionMethods.scala | 2 +- src/dotty/tools/dotc/transform/TreeTransform.scala | 2 +- 6 files changed, 46 insertions(+), 25 deletions(-) create mode 100644 src/dotty/tools/dotc/Flatten.scala (limited to 'src/dotty/tools/dotc') diff --git a/src/dotty/tools/dotc/Flatten.scala b/src/dotty/tools/dotc/Flatten.scala new file mode 100644 index 000000000..71f669e26 --- /dev/null +++ b/src/dotty/tools/dotc/Flatten.scala @@ -0,0 +1,15 @@ +package dotty.tools.dotc +package transform + +import core._ +import DenotTransformers.SymTransformer +import Phases.Phase +import Contexts.Context +import SymDenotations.SymDenotation +import TreeTransforms.MiniPhaseTransform + +class Flatten extends MiniPhaseTransform with SymTransformer { thisTransformer => + override def phaseName = "flatten" + + def transformSym(ref: SymDenotation)(implicit ctx: Context) = ??? +} \ No newline at end of file diff --git a/src/dotty/tools/dotc/core/Phases.scala b/src/dotty/tools/dotc/core/Phases.scala index 43dadf38d..6baec3cf6 100644 --- a/src/dotty/tools/dotc/core/Phases.scala +++ b/src/dotty/tools/dotc/core/Phases.scala @@ -11,6 +11,8 @@ import scala.collection.mutable.{ListBuffer, ArrayBuffer} import dotty.tools.dotc.transform.TreeTransforms.{TreeTransformer, MiniPhase, TreeTransform} import dotty.tools.dotc.transform.TreeTransforms import Periods._ +import typer.{FrontEnd, RefChecks} +import dotty.tools.dotc.transform.{Erasure, Flatten} trait Phases { self: Context => @@ -73,7 +75,7 @@ object Phases { */ private def squashPhases(phasess: List[List[Phase]]): Array[Phase] = { val squashedPhases = ListBuffer[Phase]() - var prevPhases: Set[String] = Set.empty + var prevPhases: Set[Class[_ <: Phase]] = Set.empty var i = 0 while (i < phasess.length) { if (phasess(i).length > 1) { @@ -96,11 +98,11 @@ object Phases { override def transformations: Array[TreeTransform] = transforms.toArray } squashedPhases += block - prevPhases ++= phasess(i).map(_.phaseName) + prevPhases ++= phasess(i).map(_.getClazz) block.init(this, phasess(i).head.id, phasess(i).last.id) } else { squashedPhases += phasess(i).head - prevPhases += phasess(i).head.phaseName + prevPhases += phasess(i).head.getClazz } i += 1 } @@ -113,7 +115,7 @@ object Phases { */ def usePhases(phasess: List[List[Phase]], squash: Boolean = true) = { phases = (NoPhase :: phasess.flatten ::: new TerminalPhase :: Nil).toArray - var phasesAfter:Set[String] = Set.empty + var phasesAfter:Set[Class[_ <: Phase]] = Set.empty nextDenotTransformerId = new Array[Int](phases.length) denotTransformers = new Array[DenotTransformer](phases.length) var i = 0 @@ -122,7 +124,7 @@ object Phases { val unmetPreceedeRequirements = phases(i).runsAfter -- phasesAfter assert(unmetPreceedeRequirements.isEmpty, s"phase ${phases(i)} has unmet requirement: ${unmetPreceedeRequirements.mkString(", ")} should precede this phase") - phasesAfter += phases(i).phaseName + phasesAfter += phases(i).getClazz i += 1 } var lastTransformerId = i @@ -148,24 +150,24 @@ object Phases { config.println(s"nextDenotTransformerId = ${nextDenotTransformerId.deep}") } - def phaseNamed(name: String) = phases.find(_.phaseName == name).getOrElse(NoPhase) + def phaseOfClass(pclass: Class[_]) = phases.find(pclass.isInstance).getOrElse(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(name: String) { + private class PhaseCache(pclass: Class[_ <: Phase]) { private var myPhase: Phase = NoPhase def phase = { - if (myPhase eq NoPhase) myPhase = phaseNamed(name) + if (myPhase eq NoPhase) myPhase = phaseOfClass(pclass) myPhase } } - private val typerCache = new PhaseCache(typerName) - private val refChecksCache = new PhaseCache(refChecksName) - private val erasureCache = new PhaseCache(erasureName) - private val flattenCache = new PhaseCache(flattenName) + private val typerCache = new PhaseCache(classOf[FrontEnd]) + private val refChecksCache = new PhaseCache(classOf[RefChecks]) + private val erasureCache = new PhaseCache(classOf[Erasure]) + private val flattenCache = new PhaseCache(classOf[Flatten]) def typerPhase = typerCache.phase def refchecksPhase = refChecksCache.phase @@ -175,17 +177,12 @@ object Phases { def isAfterTyper(phase: Phase): Boolean = phase.id > typerPhase.id } - final val typerName = "frontend" - final val refChecksName = "refchecks" - final val erasureName = "erasure" - final val flattenName = "flatten" - trait Phase extends DotClass { def phaseName: String /** List of names of phases that should precede this phase */ - def runsAfter: Set[String] = Set.empty + def runsAfter: Set[Class[_ <: Phase]] = Set.empty def run(implicit ctx: Context): Unit @@ -223,9 +220,9 @@ object Phases { assert(myPeriod == Periods.InvalidPeriod, s"phase $this has already been used once; cannot be reused") myBase = base myPeriod = Period(start, end) - myErasedTypes = prev.phaseName == erasureName || prev.erasedTypes - myFlatClasses = prev.phaseName == flattenName || prev.flatClasses - myRefChecked = prev.phaseName == refChecksName || prev.refChecked + myErasedTypes = prev.getClass == classOf[Erasure] || prev.erasedTypes + myFlatClasses = prev.getClass == classOf[Flatten] || prev.flatClasses + myRefChecked = prev.getClass == classOf[RefChecks] || prev.refChecked } protected[Phases] def init(base: ContextBase, id: Int): Unit = init(base, id, id) @@ -246,4 +243,12 @@ object Phases { override def toString = phaseName } + + /** Dotty deviation: getClass yields Class[_], instead of [Class <: ]. + * 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]] + } } \ No newline at end of file diff --git a/src/dotty/tools/dotc/transform/ElimByName.scala b/src/dotty/tools/dotc/transform/ElimByName.scala index 93ac64044..59befe955 100644 --- a/src/dotty/tools/dotc/transform/ElimByName.scala +++ b/src/dotty/tools/dotc/transform/ElimByName.scala @@ -40,7 +40,7 @@ class ElimByName extends MiniPhaseTransform with InfoTransformer { thisTransform override def phaseName: String = "elimByName" - override def runsAfterGroupsOf: Set[String] = Set("splitter") + override def runsAfterGroupsOf = Set(classOf[Splitter]) // assumes idents and selects have symbols; interferes with splitter distribution // that's why it's "after group". diff --git a/src/dotty/tools/dotc/transform/Erasure.scala b/src/dotty/tools/dotc/transform/Erasure.scala index a48e4b3d0..179e5453b 100644 --- a/src/dotty/tools/dotc/transform/Erasure.scala +++ b/src/dotty/tools/dotc/transform/Erasure.scala @@ -24,13 +24,14 @@ import scala.collection.mutable.ListBuffer import dotty.tools.dotc.core.Flags import ValueClasses._ import TypeUtils._ +import com.sun.j3d.utils.behaviors.picking.Intersect class Erasure extends Phase with DenotTransformer { thisTransformer => override def phaseName: String = "erasure" /** List of names of phases that should precede this phase */ - override def runsAfter: Set[String] = Set("typeTestsCasts"/*, "intercepted"*/, "splitter", "elimRepeated") + override def runsAfter: Set[Class[_ <: Phase]] = Set(classOf[TypeTestsCasts], classOf[InterceptedMethods], classOf[Splitter], classOf[ElimRepeated]) def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation = ref match { case ref: SymDenotation => diff --git a/src/dotty/tools/dotc/transform/ExtensionMethods.scala b/src/dotty/tools/dotc/transform/ExtensionMethods.scala index 47ded1aef..a218731a6 100644 --- a/src/dotty/tools/dotc/transform/ExtensionMethods.scala +++ b/src/dotty/tools/dotc/transform/ExtensionMethods.scala @@ -29,7 +29,7 @@ class ExtensionMethods extends MacroTransform with DenotTransformer with FullPar /** the following two members override abstract members in Transform */ override def phaseName: String = "extmethods" - override def runsAfter: Set[String] = Set("elimRepeated") // TODO: add tailrec + override def runsAfter: Set[Class[_ <: Phase]] = Set(classOf[ElimRepeated]) override def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation = ref match { case ref: ClassDenotation if ref is ModuleClass => diff --git a/src/dotty/tools/dotc/transform/TreeTransform.scala b/src/dotty/tools/dotc/transform/TreeTransform.scala index 4e83142f7..c734f1ced 100644 --- a/src/dotty/tools/dotc/transform/TreeTransform.scala +++ b/src/dotty/tools/dotc/transform/TreeTransform.scala @@ -145,7 +145,7 @@ object TreeTransforms { /** List of names of phases that should have finished their processing of all compilation units * before this phase starts */ - def runsAfterGroupsOf: Set[String] = Set.empty + def runsAfterGroupsOf: Set[Class[_ <: Phase]] = Set.empty protected def mkTreeTransformer = new TreeTransformer { override def phaseName: String = thisPhase.phaseName -- cgit v1.2.3