diff options
author | Martin Odersky <odersky@gmail.com> | 2014-03-15 17:10:24 +0100 |
---|---|---|
committer | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2014-03-18 16:06:33 +0100 |
commit | 1dbf020c43639b0c37e9005f2692871d39676ac7 (patch) | |
tree | b1855130096b99917845a715344ba6a768ede1fc /src/dotty/tools/dotc/core/Phases.scala | |
parent | 76ea699ac1a76ee6048d7fe8239d0a1126581429 (diff) | |
download | dotty-1dbf020c43639b0c37e9005f2692871d39676ac7.tar.gz dotty-1dbf020c43639b0c37e9005f2692871d39676ac7.tar.bz2 dotty-1dbf020c43639b0c37e9005f2692871d39676ac7.zip |
Refactored denotation transformers
Many small and large changes. Added samplePhase to demonstrate functionality.
To test functioning, run the compiler with args
tests/pos/uncurry.scala -Ylog:sample,terminal
Diffstat (limited to 'src/dotty/tools/dotc/core/Phases.scala')
-rw-r--r-- | src/dotty/tools/dotc/core/Phases.scala | 53 |
1 files changed, 37 insertions, 16 deletions
diff --git a/src/dotty/tools/dotc/core/Phases.scala b/src/dotty/tools/dotc/core/Phases.scala index 14cab9821..81ab7acbf 100644 --- a/src/dotty/tools/dotc/core/Phases.scala +++ b/src/dotty/tools/dotc/core/Phases.scala @@ -4,6 +4,9 @@ package core import Periods._ import Contexts._ import util.DotClass +import DenotTransformers._ +import Denotations._ +import config.Printers._ trait Phases { self: Context => import Phases._ @@ -18,6 +21,8 @@ trait Phases { self: Context => 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) @@ -29,12 +34,13 @@ object Phases { trait PhasesBase { this: ContextBase => - def allPhases = phases.tail + def allPhases = phases.tail // drop NoPhase at beginning object NoPhase extends Phase { override def exists = false def name = "<no phase>" def run(implicit ctx: Context): Unit = unsupported("run") + def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation = unsupported("transform") } object SomePhase extends Phase { @@ -42,14 +48,38 @@ object Phases { def run(implicit ctx: Context): Unit = unsupported("run") } + /** A sentinel transformer object */ + class TerminalPhase extends DenotTransformer { + def name = "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 phaseNamed(name: String) = phases.find(_.name == name).getOrElse(NoPhase) /** Use the following phases in the order they are given. * The list should never contain NoPhase. */ - def usePhases(phases: List[Phase]) = - this.phases = (NoPhase :: phases).toArray + def usePhases(phases: List[Phase]) = { + this.phases = (NoPhase :: phases ::: new TerminalPhase :: Nil).toArray + this.nextTransformerId = new Array[Int](this.phases.length) + var i = 0 + while (i < this.phases.length) { + this.phases(i)._id = i + i += 1 + } + var lastTransformerId = i + while (i > 0) { + i -= 1 + if (this.phases(i).isInstanceOf[DenotTransformer]) lastTransformerId = i + nextTransformerId(i) = lastTransformerId + } + config.println(s"Phases = ${this.phases.deep}") + config.println(s"nextTransformId = ${nextTransformerId.deep}") + } final val typerName = "typer" final val refchecksName = "refchecks" @@ -69,7 +99,7 @@ object Phases { def run(implicit ctx: Context): Unit def runOn(units: List[CompilationUnit])(implicit ctx: Context): Unit = - for (unit <- units) run(ctx.fresh.withCompilationUnit(unit)) + for (unit <- units) run(ctx.fresh.withPhase(this).withCompilationUnit(unit)) def description: String = name @@ -77,22 +107,13 @@ object Phases { def exists: Boolean = true - private[this] var idCache = -1 + private[Phases] var _id = -1 /** 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. - * Returns -1 if the phase is not installed in the context. + * -1 if the phase is not installed in the context. */ - def id(implicit ctx: Context) = { - val id = idCache - val phases = ctx.phases - if (idCache >= 0 && idCache < phases.length && (phases(idCache) eq this)) - id - else { - idCache = phases indexOf this - idCache - } - } + def id = _id final def <= (that: Phase)(implicit ctx: Context) = exists && id <= that.id |