aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/Compiler.scala16
-rw-r--r--src/dotty/tools/dotc/Driver.scala2
-rw-r--r--src/dotty/tools/dotc/config/PathResolver.scala4
-rw-r--r--src/dotty/tools/dotc/core/Contexts.scala74
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala53
-rw-r--r--src/dotty/tools/dotc/core/Periods.scala6
-rw-r--r--src/dotty/tools/dotc/core/Phases.scala118
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala10
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala2
-rw-r--r--src/dotty/tools/dotc/core/Types.scala4
-rw-r--r--src/dotty/tools/dotc/printing/Disambiguation.scala2
-rw-r--r--src/dotty/tools/dotc/transform/LazyVals.scala4
-rw-r--r--src/dotty/tools/dotc/transform/TreeTransform.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Applications.scala4
-rw-r--r--src/dotty/tools/dotc/typer/FrontEnd.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Implicits.scala18
-rw-r--r--src/dotty/tools/dotc/typer/Inferencing.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala14
-rw-r--r--src/dotty/tools/dotc/typer/ProtoTypes.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala20
-rw-r--r--test/test/DottyTest.scala10
-rw-r--r--test/test/ShowClassTests.scala4
22 files changed, 217 insertions, 156 deletions
diff --git a/src/dotty/tools/dotc/Compiler.scala b/src/dotty/tools/dotc/Compiler.scala
index 286ed3456..7b657b47b 100644
--- a/src/dotty/tools/dotc/Compiler.scala
+++ b/src/dotty/tools/dotc/Compiler.scala
@@ -42,18 +42,18 @@ class Compiler {
ctx.usePhases(phases)
val rootScope = new MutableScope
val bootstrap = ctx.fresh
- .withPeriod(Period(nextRunId, FirstPhaseId))
- .withScope(rootScope)
+ .setPeriod(Period(nextRunId, FirstPhaseId))
+ .setScope(rootScope)
rootScope.enter(ctx.definitions.RootPackage)(bootstrap)
val start = bootstrap.fresh
- .withOwner(defn.RootClass)
- .withTyper(new Typer)
- .withNewMode(Mode.ImplicitsEnabled)
- .withTyperState(new MutableTyperState(ctx.typerState, new ConsoleReporter()(ctx), isCommittable = true))
+ .setOwner(defn.RootClass)
+ .setTyper(new Typer)
+ .setMode(Mode.ImplicitsEnabled)
+ .setTyperState(new MutableTyperState(ctx.typerState, new ConsoleReporter()(ctx), isCommittable = true))
ctx.definitions.init(start) // set context of definitions to start
def addImport(ctx: Context, sym: Symbol) =
- ctx.fresh.withImportInfo(ImportInfo.rootImport(sym)(ctx))
- (start.withRunInfo(new RunInfo(start)) /: defn.RootImports)(addImport)
+ ctx.fresh.setImportInfo(ImportInfo.rootImport(sym)(ctx))
+ (start.setRunInfo(new RunInfo(start)) /: defn.RootImports)(addImport)
}
def newRun(implicit ctx: Context): Run = {
diff --git a/src/dotty/tools/dotc/Driver.scala b/src/dotty/tools/dotc/Driver.scala
index 892e4cf7d..5bf65544a 100644
--- a/src/dotty/tools/dotc/Driver.scala
+++ b/src/dotty/tools/dotc/Driver.scala
@@ -24,7 +24,7 @@ abstract class Driver extends DotClass {
def process(args: Array[String]): Reporter = {
val summary = CompilerCommand.distill(args)(initCtx)
- implicit val ctx: Context = initCtx.fresh.withSettings(summary.sstate)
+ implicit val ctx: Context = initCtx.fresh.setSettings(summary.sstate)
val fileNames = CompilerCommand.checkUsage(summary)
try {
doCompile(newCompiler(), fileNames)
diff --git a/src/dotty/tools/dotc/config/PathResolver.scala b/src/dotty/tools/dotc/config/PathResolver.scala
index 73c045c77..34678ae2b 100644
--- a/src/dotty/tools/dotc/config/PathResolver.scala
+++ b/src/dotty/tools/dotc/config/PathResolver.scala
@@ -135,7 +135,7 @@ object PathResolver {
def fromPathString(path: String)(implicit ctx: Context): JavaClassPath = {
val settings = ctx.settings.classpath.update(path)
- new PathResolver()(ctx.fresh.withSettings(settings)).result
+ new PathResolver()(ctx.fresh.setSettings(settings)).result
}
/** With no arguments, show the interesting values in Environment and Defaults.
@@ -152,7 +152,7 @@ object PathResolver {
val ArgsSummary(sstate, rest, errors) =
ctx.settings.processArguments(args.toList, true)
errors.foreach(println)
- val pr = new PathResolver()(ctx.fresh.withSettings(sstate))
+ val pr = new PathResolver()(ctx.fresh.setSettings(sstate))
println(" COMMAND: 'scala %s'".format(args.mkString(" ")))
println("RESIDUAL: 'scala %s'\n".format(rest.mkString(" ")))
pr.result.show
diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala
index 9fbba9a0f..8d083b29c 100644
--- a/src/dotty/tools/dotc/core/Contexts.scala
+++ b/src/dotty/tools/dotc/core/Contexts.scala
@@ -278,12 +278,16 @@ object Contexts {
}
final def withMode(mode: Mode): Context =
- if (mode != this.mode) fresh.withNewMode(mode) else this
+ if (mode != this.mode) fresh.setMode(mode) else this
+
+ /**
+ * This method will always return a phase period equal to phaseId, thus will never return squashed phases
+ */
+ final def withPhase(phaseId: PhaseId): Context =
+ if (this.phaseId == phaseId) this else fresh.setPhase(phaseId)
+ final def withPhase(phase: Phase): Context =
+ if (this.period == phase.period) this else fresh.setPhase(phase)
- def withPhase(phase: PhaseId): Context =
- if (this.phaseId == phaseId) this else fresh.withPhase(phase)
- def withPhase(phase: Phase): Context =
- withPhase(phase.id)
final def addMode(mode: Mode): Context = withMode(this.mode | mode)
final def maskMode(mode: Mode): Context = withMode(this.mode & mode)
@@ -306,36 +310,36 @@ object Contexts {
* of its attributes using the with... methods.
*/
abstract class FreshContext extends Context {
- def withPeriod(period: Period): this.type = { this.period = period; this }
- def withNewMode(mode: Mode): this.type = { this.mode = mode; this }
- def withTyperState(typerState: TyperState): this.type = { this.typerState = typerState; this }
- def withNewTyperState: this.type = withTyperState(typerState.fresh(isCommittable = true))
- def withExploreTyperState: this.type = withTyperState(typerState.fresh(isCommittable = false))
- def withPrinterFn(printer: Context => Printer): this.type = { this.printerFn = printer; this }
- def withOwner(owner: Symbol): this.type = { assert(owner != NoSymbol); this.owner = owner; this }
- def withSettings(sstate: SettingsState): this.type = { this.sstate = sstate; this }
- def withCompilationUnit(compilationUnit: CompilationUnit): this.type = { this.compilationUnit = compilationUnit; this }
- def withTree(tree: Tree[_ >: Untyped]): this.type = { this.tree = tree; this }
- def withScope(scope: Scope): this.type = { this.scope = scope; this }
- def withNewScope: this.type = { this.scope = newScope; this }
- def withTypeAssigner(typeAssigner: TypeAssigner): this.type = { this.typeAssigner = typeAssigner; this }
- def withTyper(typer: Typer): this.type = { this.scope = typer.scope; withTypeAssigner(typer) }
- def withImportInfo(importInfo: ImportInfo): this.type = { this.importInfo = importInfo; this }
- def withRunInfo(runInfo: RunInfo): this.type = { this.runInfo = runInfo; this }
- def withDiagnostics(diagnostics: Option[StringBuilder]): this.type = { this.diagnostics = diagnostics; this }
- def withTypeComparerFn(tcfn: Context => TypeComparer): this.type = { this.typeComparer = tcfn(this); this }
- def withSearchHistory(searchHistory: SearchHistory): this.type = { this.searchHistory = searchHistory; this }
- def withMoreProperties(moreProperties: Map[String, Any]): this.type = { this.moreProperties = moreProperties; this }
-
- def withProperty(prop: (String, Any)): this.type = withMoreProperties(moreProperties + prop)
-
- override def withPhase(pid: PhaseId): this.type = withPeriod(Period(runId, pid))
- override def withPhase(phase: Phase): this.type = withPhase(phase.id)
-
- def withSetting[T](setting: Setting[T], value: T): this.type =
- withSettings(setting.updateIn(sstate, value))
-
- def withDebug = withSetting(base.settings.debug, true)
+ def setPeriod(period: Period): this.type = { this.period = period; this }
+ def setMode(mode: Mode): this.type = { this.mode = mode; this }
+ def setTyperState(typerState: TyperState): this.type = { this.typerState = typerState; this }
+ def clearTyperState: this.type = setTyperState(typerState.fresh(isCommittable = true))
+ def setExploreTyperState: this.type = setTyperState(typerState.fresh(isCommittable = false))
+ def setPrinterFn(printer: Context => Printer): this.type = { this.printerFn = printer; this }
+ def setOwner(owner: Symbol): this.type = { assert(owner != NoSymbol); this.owner = owner; this }
+ def setSettings(sstate: SettingsState): this.type = { this.sstate = sstate; this }
+ def setCompilationUnit(compilationUnit: CompilationUnit): this.type = { this.compilationUnit = compilationUnit; this }
+ def setTree(tree: Tree[_ >: Untyped]): this.type = { this.tree = tree; this }
+ def setScope(scope: Scope): this.type = { this.scope = scope; this }
+ def clearScope: this.type = { this.scope = newScope; this }
+ def setTypeAssigner(typeAssigner: TypeAssigner): this.type = { this.typeAssigner = typeAssigner; this }
+ def setTyper(typer: Typer): this.type = { this.scope = typer.scope; setTypeAssigner(typer) }
+ def setImportInfo(importInfo: ImportInfo): this.type = { this.importInfo = importInfo; this }
+ def setRunInfo(runInfo: RunInfo): this.type = { this.runInfo = runInfo; this }
+ def setDiagnostics(diagnostics: Option[StringBuilder]): this.type = { this.diagnostics = diagnostics; this }
+ def setTypeComparerFn(tcfn: Context => TypeComparer): this.type = { this.typeComparer = tcfn(this); this }
+ def setSearchHistory(searchHistory: SearchHistory): this.type = { this.searchHistory = searchHistory; this }
+ def setMoreProperties(moreProperties: Map[String, Any]): this.type = { this.moreProperties = moreProperties; this }
+
+ def setProperty(prop: (String, Any)): this.type = setMoreProperties(moreProperties + prop)
+
+ def setPhase(pid: PhaseId): this.type = setPeriod(Period(runId, pid))
+ def setPhase(phase: Phase): this.type = setPeriod(Period(runId, phase.start, phase.end))
+
+ def setSetting[T](setting: Setting[T], value: T): this.type =
+ setSettings(setting.updateIn(sstate, value))
+
+ def setDebug = setSetting(base.settings.debug, true)
}
/** A class defining the initial context with given context base
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala
index 35f6bd56f..1e3dec255 100644
--- a/src/dotty/tools/dotc/core/Denotations.scala
+++ b/src/dotty/tools/dotc/core/Denotations.scala
@@ -19,6 +19,7 @@ import printing.Printer
import io.AbstractFile
import config.Config
import util.common._
+import collection.mutable.ListBuffer
import Decorators.SymbolIteratorDecorator
/** Denotations represent the meaning of symbols and named types.
@@ -459,7 +460,7 @@ object Denotations {
* 2) the union of all validity periods is a contiguous
* interval.
*/
- var nextInRun: SingleDenotation = this
+ private var nextInRun: SingleDenotation = this
/** The version of this SingleDenotation that was valid in the first phase
* of this run.
@@ -470,6 +471,17 @@ object Denotations {
current
}
+ def history: List[SingleDenotation] = {
+ val b = new ListBuffer[SingleDenotation]
+ var current = initial
+ do {
+ b += (current)
+ current = current.nextInRun
+ }
+ while (current ne initial)
+ b.toList
+ }
+
/** Move validity period of this denotation to a new run. Throw a StaleSymbol error
* if denotation is no longer valid.
*/
@@ -518,27 +530,30 @@ object Denotations {
cur = next
cur
} else {
+ //println(s"might need new denot for $cur, valid for ${cur.validFor} at $currentPeriod")
// not found, cur points to highest existing variant
- var startPid = cur.validFor.lastPhaseId + 1
- val nextTranformerId = ctx.nextDenotTransformerId(startPid)
- val transformer = ctx.denotTransformers(nextTranformerId)
- //println(s"transforming with $transformer")
- if (currentPeriod.lastPhaseId > transformer.id)
- next = transformer.transform(cur)(ctx.withPhase(startPid)).syncWithParents
- if (next eq cur)
- startPid = cur.validFor.firstPhaseId
+ val nextTransformerId = ctx.nextDenotTransformerId(cur.validFor.lastPhaseId)
+ if (currentPeriod.lastPhaseId <= nextTransformerId)
+ cur.validFor = Period(currentPeriod.runId, cur.validFor.firstPhaseId, nextTransformerId)
else {
- next match {
- case next: ClassDenotation => next.resetFlag(Frozen)
- case _ =>
+ var startPid = nextTransformerId + 1
+ val transformer = ctx.denotTransformers(nextTransformerId)
+ //println(s"transforming $this with $transformer")
+ next = transformer.transform(cur)(ctx.withPhase(transformer)).syncWithParents
+ if (next eq cur)
+ startPid = cur.validFor.firstPhaseId
+ else {
+ next match {
+ case next: ClassDenotation => next.resetFlag(Frozen)
+ case _ =>
+ }
+ next.nextInRun = cur.nextInRun
+ cur.nextInRun = next
+ cur = next
}
- next.nextInRun = cur.nextInRun
- cur.nextInRun = next
- cur = next
+ cur.validFor = Period(currentPeriod.runId, startPid, transformer.lastPhaseId)
+ //println(s"new denot: $cur, valid for ${cur.validFor}")
}
- cur.validFor = Period(
- currentPeriod.runId, startPid, transformer.lastPhaseId)
- //println(s"new denot: $cur, valid for ${cur.validFor}")
cur.current // multiple transformations could be required
}
} else {
@@ -562,7 +577,7 @@ object Denotations {
case denot: SymDenotation => s"in ${denot.owner}"
case _ => ""
}
- def msg = s"stale symbol; $this#${symbol.id}$ownerMsg, defined in run ${myValidFor.runId}, is referred to in run ${ctx.period.runId}"
+ def msg = s"stale symbol; $this#${symbol.id} $ownerMsg, defined in run ${myValidFor.runId}, is referred to in run ${ctx.runId}"
throw new StaleSymbol(msg)
}
diff --git a/src/dotty/tools/dotc/core/Periods.scala b/src/dotty/tools/dotc/core/Periods.scala
index 61f395c7d..4ab04fad0 100644
--- a/src/dotty/tools/dotc/core/Periods.scala
+++ b/src/dotty/tools/dotc/core/Periods.scala
@@ -19,11 +19,11 @@ abstract class Periods extends DotClass { self: Context =>
/** Execute `op` at given period */
def atPeriod[T](pd: Period)(op: Context => T): T =
- op(ctx.fresh.withPeriod(pd))
+ op(ctx.fresh.setPeriod(pd))
/** Execute `op` at given phase id */
def atPhase[T](pid: PhaseId)(op: Context => T): T =
- op(ctx.fresh.withPhase(pid))
+ op(ctx.withPhase(pid))
/** The period containing the current period where denotations do not change.
* We compute this by taking as first phase the first phase less or equal to
@@ -129,6 +129,8 @@ object Periods {
final val InitialPeriod = Period(InitialRunId, FirstPhaseId)
+ final val InvalidPeriod = Period(NoRunId, NoPhaseId)
+
/** An ordinal number for compiler runs. First run has number 1. */
type RunId = Int
final val NoRunId = 0
diff --git a/src/dotty/tools/dotc/core/Phases.scala b/src/dotty/tools/dotc/core/Phases.scala
index c49d314bc..12e700521 100644
--- a/src/dotty/tools/dotc/core/Phases.scala
+++ b/src/dotty/tools/dotc/core/Phases.scala
@@ -12,13 +12,14 @@ import dotty.tools.dotc.transform.TreeTransforms.{TreeTransformer, TreeTransform
import dotty.tools.dotc.transform.PostTyperTransformers.PostTyperTransformer
import dotty.tools.dotc.transform.TreeTransforms
import TreeTransforms.Separator
+import Periods._
trait Phases {
self: Context =>
import Phases._
- def phase: Phase = base.phases(period.phaseId)
+ def phase: Phase = base.phases(period.firstPhaseId)
def phasesStack: List[Phase] =
if ((this eq NoContext) || !phase.exists) Nil
@@ -45,8 +46,6 @@ object Phases {
// drop NoPhase at beginning
def allPhases = squashedPhases.tail
-
-
object NoPhase extends Phase {
override def exists = false
def name = "<no phase>"
@@ -68,26 +67,24 @@ object Phases {
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.
* if squashing is enabled, phases in same subgroup will be squashed to single phase.
*/
- def usePhases(phases: List[List[Phase]], squash: Boolean = true) = {
- this.phases = (NoPhase :: phases.flatten ::: new TerminalPhase :: Nil).toArray
- this.nextDenotTransformerId = new Array[Int](this.phases.length)
- this.denotTransformers = new Array[DenotTransformer](this.phases.length)
+ def usePhases(phasess: List[List[Phase]], squash: Boolean = false) = {
+ phases = (NoPhase :: phasess.flatten ::: new TerminalPhase :: Nil).toArray
+ nextDenotTransformerId = new Array[Int](phases.length)
+ denotTransformers = new Array[DenotTransformer](phases.length)
var i = 0
- while (i < this.phases.length) {
- this.phases(i)._id = i
+ while (i < phases.length) {
+ phases(i).init(this, i)
i += 1
}
var lastTransformerId = i
while (i > 0) {
i -= 1
- this.phases(i) match {
+ phases(i) match {
case transformer: DenotTransformer =>
lastTransformerId = i
denotTransformers(i) = transformer
@@ -100,11 +97,11 @@ object Phases {
val squashedPhases = ListBuffer[Phase]()
var postTyperEmmited = false
var i = 0
- while (i < phases.length) {
- if (phases(i).length > 1) {
- assert(phases(i).forall(x => x.isInstanceOf[TreeTransform]), "Only tree transforms can be squashed")
+ while (i < phasess.length) {
+ if (phasess(i).length > 1) {
+ assert(phasess(i).forall(x => x.isInstanceOf[TreeTransform]), "Only tree transforms can be squashed")
- val transforms = phases(i).asInstanceOf[List[TreeTransform]]
+ val transforms = phasess(i).asInstanceOf[List[TreeTransform]]
val block =
if (!postTyperEmmited) {
postTyperEmmited = true
@@ -117,8 +114,8 @@ object Phases {
override protected def transformations: Array[TreeTransform] = transforms.toArray
}
squashedPhases += block
- block._id = phases(i).head.id
- } else squashedPhases += phases(i).head
+ block.init(this, phasess(i).head.id, phasess(i).last.id)
+ } else squashedPhases += phasess(i).head
i += 1
}
this.squashedPhases = (NoPhase::squashedPhases.toList :::new TerminalPhase :: Nil).toArray
@@ -126,22 +123,41 @@ object Phases {
this.squashedPhases = this.phases
}
- config.println(s"Phases = ${this.phases.deep}")
- config.println(s"squashedPhases = ${this.squashedPhases.deep}")
+ config.println(s"Phases = ${phases.deep}")
+ config.println(s"squashedPhases = ${squashedPhases.deep}")
config.println(s"nextDenotTransformerId = ${nextDenotTransformerId.deep}")
}
- final val typerName = "typer"
- final val refchecksName = "refchecks"
- final val erasureName = "erasure"
- final val flattenName = "flatten"
+ def phaseNamed(name: String) = phases.find(_.name == name).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 var myPhase: Phase = NoPhase
+ def phase = {
+ if (myPhase eq NoPhase) myPhase = phaseNamed(name)
+ 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)
- lazy val typerPhase = phaseNamed(typerName)
- lazy val refchecksPhase = phaseNamed(refchecksName)
- lazy val erasurePhase = phaseNamed(erasureName)
- lazy val flattenPhase = phaseNamed(flattenName)
+ def typerPhase = typerCache.phase
+ def refchecksPhase = refChecksCache.phase
+ def erasurePhase = erasureCache.phase
+ def flattenPhase = flattenCache.phase
}
+ final val typerName = "typer"
+ final val refChecksName = "refchecks"
+ final val erasureName = "erasure"
+ final val flattenName = "flatten"
+
abstract class Phase extends DotClass {
def name: String
@@ -149,7 +165,7 @@ object Phases {
def run(implicit ctx: Context): Unit
def runOn(units: List[CompilationUnit])(implicit ctx: Context): Unit =
- for (unit <- units) run(ctx.fresh.withPhase(this).withCompilationUnit(unit))
+ for (unit <- units) run(ctx.fresh.setPhase(this).setCompilationUnit(unit))
def description: String = name
@@ -157,32 +173,52 @@ object Phases {
def exists: Boolean = true
- private[Phases] var _id = -1
+ private var myPeriod: Period = Periods.InvalidPeriod
+ private var myBase: ContextBase = null
+ private var myErasedTypes = false
+ private var myFlatClasses = false
+ private var myRefChecked = 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 = _id
+ def id = myPeriod.firstPhaseId
+
+ def period = myPeriod
+ def start = myPeriod.firstPhaseId
+ def end = myPeriod.lastPhaseId
+
+ final def erasedTypes = myErasedTypes
+ final def flatClasses = myFlatClasses
+ final def refChecked = myRefChecked
+
+ 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(start, end)
+ myErasedTypes = prev.name == erasureName || prev.erasedTypes
+ myFlatClasses = prev.name == flattenName || prev.flatClasses
+ myRefChecked = prev.name == refChecksName || prev.refChecked
+ }
+
+ protected[Phases] def init(base: ContextBase, id: Int): Unit = init(base, id, id)
final def <=(that: Phase)(implicit ctx: Context) =
exists && id <= that.id
- final def prev(implicit ctx: Context): Phase =
- if (id > FirstPhaseId) ctx.phases(id - 1) else ctx.NoPhase
+ final def prev: Phase =
+ if (id > FirstPhaseId) myBase.phases(start - 1) else myBase.NoPhase
- final def next(implicit ctx: Context): Phase =
- if (hasNext) ctx.phases(id + 1) else ctx.NoPhase
+ final def next: Phase =
+ if (hasNext) myBase.phases(end + 1) else myBase.NoPhase
- final def hasNext(implicit ctx: Context) = id + 1 < ctx.phases.length
+ final def hasNext = start >= FirstPhaseId && end + 1 < myBase.phases.length
- final def iterator(implicit ctx: Context) =
+ final def iterator =
Iterator.iterate(this)(_.next) takeWhile (_.hasNext)
- final def erasedTypes(implicit ctx: Context): Boolean = ctx.erasurePhase <= this
- final def flatClasses(implicit ctx: Context): Boolean = ctx.flattenPhase <= this
- final def refChecked(implicit ctx: Context): Boolean = ctx.refchecksPhase <= this
-
override def toString = name
}
} \ No newline at end of file
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index 362738caf..b5c7ea539 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -805,8 +805,12 @@ object SymDenotations {
/** The type parameters of this class */
override final def typeParams(implicit ctx: Context): List[TypeSymbol] = {
- def computeTypeParams = decls.filter(sym =>
- (sym is TypeParam) && sym.owner == symbol).asInstanceOf[List[TypeSymbol]]
+ def computeTypeParams = {
+ if (ctx.phase.erasedTypes && (this ne defn.ArrayClass)) Nil
+ else if (this ne initial) initial.asSymDenotation.typeParams
+ else decls.filter(sym =>
+ (sym is TypeParam) && sym.owner == symbol).asInstanceOf[List[TypeSymbol]]
+ }
if (myTypeParams == null) myTypeParams = computeTypeParams
myTypeParams
}
@@ -1352,7 +1356,7 @@ object SymDenotations {
val (location, src) =
if (file != null) (s" in $file", file.toString)
else ("", "the signature")
- val name = ctx.fresh.withSetting(ctx.settings.debugNames, true).nameString(denot.name)
+ val name = ctx.fresh.setSetting(ctx.settings.debugNames, true).nameString(denot.name)
ctx.error(
s"""|bad symbolic reference. A signature$location
|refers to $name in ${denot.owner.showKind} ${denot.owner.showFullName} which is not available.
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala
index ce1c1e869..cab09826b 100644
--- a/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -1134,7 +1134,7 @@ object TypeComparer {
/** Show trace of comparison operations when performing `op` as result string */
def explained[T](op: Context => T)(implicit ctx: Context): String = {
- val nestedCtx = ctx.fresh.withTypeComparerFn(new ExplainingTypeComparer(_))
+ val nestedCtx = ctx.fresh.setTypeComparerFn(new ExplainingTypeComparer(_))
op(nestedCtx)
nestedCtx.typeComparer.toString
}
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 7cd66f5dd..ce481759b 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -1028,7 +1028,7 @@ object Types {
val sym = lastSymbol
if (sym == null) loadDenot else denotOfSym(sym)
case d: SymDenotation =>
- if (ctx.stillValid(d)) d.current
+ if (d.validFor.runId == ctx.runId || ctx.stillValid(d)) d.current
else {
val newd = loadDenot
if (newd.exists) newd else d.staleSymbolError
@@ -1066,7 +1066,7 @@ object Types {
if (d.exists || ctx.phaseId == FirstPhaseId)
d
else {// name has changed; try load in earlier phase and make current
- val d = denot(ctx.fresh.withPhase(ctx.phaseId - 1)).current
+ val d = denot(ctx.withPhase(ctx.phaseId - 1)).current
if (d.exists) d
else throw new Error(s"failure to reload $this")
}
diff --git a/src/dotty/tools/dotc/printing/Disambiguation.scala b/src/dotty/tools/dotc/printing/Disambiguation.scala
index b830b353a..baacee42f 100644
--- a/src/dotty/tools/dotc/printing/Disambiguation.scala
+++ b/src/dotty/tools/dotc/printing/Disambiguation.scala
@@ -75,7 +75,7 @@ object Disambiguation {
def disambiguated(op: Context => String)(implicit ctx: Context): String = {
val dctx = ctx.printer match {
case dp: Printer => ctx
- case _ => ctx.fresh.withPrinterFn(newPrinter)
+ case _ => ctx.fresh.setPrinterFn(newPrinter)
}
val res = op(dctx)
dctx.printer match {
diff --git a/src/dotty/tools/dotc/transform/LazyVals.scala b/src/dotty/tools/dotc/transform/LazyVals.scala
index ffc2096f1..28a8d12d9 100644
--- a/src/dotty/tools/dotc/transform/LazyVals.scala
+++ b/src/dotty/tools/dotc/transform/LazyVals.scala
@@ -249,7 +249,7 @@ class LazyValTranformContext {
val flagSymbol = ctx.newSymbol(methodSymbol, "flag".toTermName, Flags.Mutable & Flags.Synthetic, defn.LongType)
val flagDef = ValDef(flagSymbol, Literal(Constant(0L)))
- val thiz = This(claz)(ctx.fresh.withOwner(claz))
+ val thiz = This(claz)(ctx.fresh.setOwner(claz))
val resultSymbol = ctx.newSymbol(methodSymbol, "result".toTermName, Flags.Mutable & Flags.Synthetic, tp)
val resultDef = ValDef(resultSymbol, Literal(initValue(tp.widen)))
@@ -313,7 +313,7 @@ class LazyValTranformContext {
val tpe = x.tpe.widen
val claz = x.symbol.owner.asClass
- val thiz = This(claz)(ctx.fresh.withOwner(claz))
+ val thiz = This(claz)(ctx.fresh.setOwner(claz))
val companion = claz.companionModule
val helperModule = ctx.requiredModule("dotty.runtime.LazyVals")
val getOffset = Select(Ident(helperModule.termRef), LazyVals.Names.getOffset.toTermName)
diff --git a/src/dotty/tools/dotc/transform/TreeTransform.scala b/src/dotty/tools/dotc/transform/TreeTransform.scala
index 2fa2f3abb..10857da5a 100644
--- a/src/dotty/tools/dotc/transform/TreeTransform.scala
+++ b/src/dotty/tools/dotc/transform/TreeTransform.scala
@@ -484,7 +484,7 @@ object TreeTransforms {
def transform(t: Tree)(implicit ctx: Context): Tree = {
val initialTransformations = transformations
- val contexts = initialTransformations.map(tr => ctx.fresh.withPhase(tr).ctx)
+ val contexts = initialTransformations.map(tr => ctx.withPhase(tr).ctx)
val info = new TransformerInfo(initialTransformations, new NXTransformations(initialTransformations), this, contexts)
initialTransformations.zipWithIndex.foreach{
case (transform, id) =>
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala
index 46a6ebf66..9a21e1c54 100644
--- a/src/dotty/tools/dotc/typer/Applications.scala
+++ b/src/dotty/tools/dotc/typer/Applications.scala
@@ -712,7 +712,7 @@ trait Applications extends Compatibility { self: Typer =>
* @param resultType The expected result type of the application
*/
def isApplicable(methRef: TermRef, targs: List[Type], args: List[Tree], resultType: Type)(implicit ctx: Context): Boolean = {
- val nestedContext = ctx.fresh.withExploreTyperState
+ val nestedContext = ctx.fresh.setExploreTyperState
new ApplicableToTrees(methRef, targs, args, resultType)(nestedContext).success
}
@@ -720,7 +720,7 @@ trait Applications extends Compatibility { self: Typer =>
* @param resultType The expected result type of the application
*/
def isApplicable(methRef: TermRef, args: List[Type], resultType: Type)(implicit ctx: Context): Boolean = {
- val nestedContext = ctx.fresh.withExploreTyperState
+ val nestedContext = ctx.fresh.setExploreTyperState
new ApplicableToTypes(methRef, args, resultType)(nestedContext).success
}
diff --git a/src/dotty/tools/dotc/typer/FrontEnd.scala b/src/dotty/tools/dotc/typer/FrontEnd.scala
index 0161c1f6f..697830fb1 100644
--- a/src/dotty/tools/dotc/typer/FrontEnd.scala
+++ b/src/dotty/tools/dotc/typer/FrontEnd.scala
@@ -41,7 +41,7 @@ class FrontEnd extends Phase {
}
override def runOn(units: List[CompilationUnit])(implicit ctx: Context): Unit = {
- val unitContexts = units map (unit => ctx.fresh.withCompilationUnit(unit))
+ val unitContexts = units map (unit => ctx.fresh.setCompilationUnit(unit))
unitContexts foreach (parse(_))
record("parsedTrees", ast.Trees.ntrees)
unitContexts foreach (enterSyms(_))
diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala
index fe1c938c9..8990d21a2 100644
--- a/src/dotty/tools/dotc/typer/Implicits.scala
+++ b/src/dotty/tools/dotc/typer/Implicits.scala
@@ -50,13 +50,13 @@ object Implicits {
case mt: MethodType =>
mt.isImplicit ||
mt.paramTypes.length != 1 ||
- !(argType <:< mt.paramTypes.head)(ctx.fresh.withExploreTyperState)
+ !(argType <:< mt.paramTypes.head)(ctx.fresh.setExploreTyperState)
case poly: PolyType =>
poly.resultType match {
case mt: MethodType =>
mt.isImplicit ||
mt.paramTypes.length != 1 ||
- !(argType <:< wildApprox(mt.paramTypes.head)(ctx.fresh.withExploreTyperState))
+ !(argType <:< wildApprox(mt.paramTypes.head)(ctx.fresh.setExploreTyperState))
case rtp =>
discardForView(wildApprox(rtp), argType)
}
@@ -90,7 +90,7 @@ object Implicits {
}
if (refs.isEmpty) refs
- else refs filter (refMatches(_)(ctx.fresh.withExploreTyperState.addMode(Mode.TypevarsMissContext))) // create a defensive copy of ctx to avoid constraint pollution
+ else refs filter (refMatches(_)(ctx.fresh.setExploreTyperState.addMode(Mode.TypevarsMissContext))) // create a defensive copy of ctx to avoid constraint pollution
}
}
@@ -370,7 +370,7 @@ trait Implicits { self: Typer =>
}
case _ =>
}
- inferView(dummyTreeOfType(from), to)(ctx.fresh.withExploreTyperState).isInstanceOf[SearchSuccess]
+ inferView(dummyTreeOfType(from), to)(ctx.fresh.setExploreTyperState).isInstanceOf[SearchSuccess]
}
)
@@ -419,7 +419,7 @@ trait Implicits { self: Typer =>
/** An implicit search; parameters as in `inferImplicit` */
class ImplicitSearch(protected val pt: Type, protected val argument: Tree, pos: Position)(implicit ctx: Context) {
- private def nestedContext = ctx.fresh.withNewMode(ctx.mode &~ Mode.ImplicitsEnabled)
+ private def nestedContext = ctx.fresh.setMode(ctx.mode &~ Mode.ImplicitsEnabled)
private def implicitProto(resultType: Type, f: Type => Type) =
if (argument.isEmpty) f(resultType) else ViewProto(f(argument.tpe.widen), f(resultType))
@@ -457,7 +457,7 @@ trait Implicits { self: Typer =>
pt)
val generated1 = adapt(generated, pt)
lazy val shadowing =
- typed(untpd.Ident(ref.name) withPos pos.toSynthetic, funProto)(nestedContext.withNewTyperState)
+ typed(untpd.Ident(ref.name) withPos pos.toSynthetic, funProto)(nestedContext.clearTyperState)
def refMatches(shadowing: Tree): Boolean =
ref.symbol == closureBody(shadowing).symbol || {
shadowing match {
@@ -485,12 +485,12 @@ trait Implicits { self: Typer =>
val history = ctx.searchHistory nest wildProto
val result =
if (history eq ctx.searchHistory) divergingImplicit(ref)
- else typedImplicit(ref)(nestedContext.withNewTyperState.withSearchHistory(history))
+ else typedImplicit(ref)(nestedContext.clearTyperState.setSearchHistory(history))
result match {
case fail: SearchFailure =>
rankImplicits(pending1, acc)
case best: SearchSuccess =>
- val newPending = pending1 filter (isAsGood(_, best.ref)(nestedContext.withExploreTyperState))
+ val newPending = pending1 filter (isAsGood(_, best.ref)(nestedContext.setExploreTyperState))
rankImplicits(newPending, best :: acc)
}
case nil => acc
@@ -499,7 +499,7 @@ trait Implicits { self: Typer =>
/** Convert a (possibly empty) list of search successes into a single search result */
def condense(hits: List[SearchSuccess]): SearchResult = hits match {
case best :: alts =>
- alts find (alt => isAsGood(alt.ref, best.ref)(ctx.fresh.withExploreTyperState)) match {
+ alts find (alt => isAsGood(alt.ref, best.ref)(ctx.fresh.setExploreTyperState)) match {
case Some(alt) =>
/* !!! DEBUG
println(i"ambiguous refs: ${hits map (_.ref) map (_.show) mkString ", "}")
diff --git a/src/dotty/tools/dotc/typer/Inferencing.scala b/src/dotty/tools/dotc/typer/Inferencing.scala
index 6d9afecab..9c4ce232e 100644
--- a/src/dotty/tools/dotc/typer/Inferencing.scala
+++ b/src/dotty/tools/dotc/typer/Inferencing.scala
@@ -30,7 +30,7 @@ trait Inferencing { this: Checking =>
* Variables that are successfully minimized do not count as uninstantiated.
*/
def isFullyDefined(tp: Type, force: ForceDegree.Value)(implicit ctx: Context): Boolean = {
- val nestedCtx = ctx.fresh.withNewTyperState
+ val nestedCtx = ctx.fresh.clearTyperState
val result = new IsFullyDefinedAccumulator(force)(nestedCtx).process(tp)
if (result) nestedCtx.typerState.commit()
result
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index 361de802c..e81949f05 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -288,11 +288,11 @@ class Namer { typer: Typer =>
/** A new context that summarizes an import statement */
def importContext(sym: Symbol, selectors: List[Tree])(implicit ctx: Context) =
- ctx.fresh.withImportInfo(new ImportInfo(sym, selectors))
+ ctx.fresh.setImportInfo(new ImportInfo(sym, selectors))
/** A new context for the interior of a class */
def inClassContext(selfInfo: DotClass /* Should be Type | Symbol*/)(implicit ctx: Context): Context = {
- val localCtx: Context = ctx.fresh.withNewScope
+ val localCtx: Context = ctx.fresh.clearScope
selfInfo match {
case sym: Symbol if sym.exists && sym.name != nme.WILDCARD =>
localCtx.scope.asInstanceOf[MutableScope].enter(sym)
@@ -330,7 +330,7 @@ class Namer { typer: Typer =>
def indexExpanded(stat: Tree)(implicit ctx: Context): Context = expanded(stat) match {
case pcl: PackageDef =>
val pkg = createPackageSymbol(pcl.pid)
- index(pcl.stats)(ctx.fresh.withOwner(pkg.moduleClass))
+ index(pcl.stats)(ctx.fresh.setOwner(pkg.moduleClass))
invalidateCompanions(pkg, Trees.flatten(pcl.stats map expanded))
ctx
case imp: Import =>
@@ -380,19 +380,19 @@ class Namer { typer: Typer =>
/** The completer of a symbol defined by a member def or import (except ClassSymbols) */
class Completer(val original: Tree)(implicit ctx: Context) extends LazyType {
- protected def localContext(owner: Symbol) = ctx.fresh.withOwner(owner).withTree(original)
+ protected def localContext(owner: Symbol) = ctx.fresh.setOwner(owner).setTree(original)
private def typeSig(sym: Symbol): Type = original match {
case original: ValDef =>
if (sym is Module) moduleValSig(sym)
- else valOrDefDefSig(original, sym, Nil, identity)(localContext(sym).withNewScope)
+ else valOrDefDefSig(original, sym, Nil, identity)(localContext(sym).clearScope)
case original: DefDef =>
val typer1 = new Typer
nestedTyper(sym) = typer1
- typer1.defDefSig(original, sym)(localContext(sym).withTyper(typer1))
+ typer1.defDefSig(original, sym)(localContext(sym).setTyper(typer1))
case original: TypeDef =>
assert(!original.isClassDef)
- typeDefSig(original, sym)(localContext(sym).withNewScope)
+ typeDefSig(original, sym)(localContext(sym).clearScope)
case imp: Import =>
try {
val expr1 = typedAheadExpr(imp.expr, AnySelectionProto)
diff --git a/src/dotty/tools/dotc/typer/ProtoTypes.scala b/src/dotty/tools/dotc/typer/ProtoTypes.scala
index 16fcc9db7..16869454f 100644
--- a/src/dotty/tools/dotc/typer/ProtoTypes.scala
+++ b/src/dotty/tools/dotc/typer/ProtoTypes.scala
@@ -38,7 +38,7 @@ object ProtoTypes {
/** Test compatibility after normalization in a fresh typerstate. */
def normalizedCompatible(tp: Type, pt: Type)(implicit ctx: Context) = {
- val nestedCtx = ctx.fresh.withExploreTyperState
+ val nestedCtx = ctx.fresh.setExploreTyperState
isCompatible(normalize(tp, pt)(nestedCtx), pt)(nestedCtx)
}
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 7c301a7f1..0ba53f8c0 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -587,7 +587,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
assignType(cpy.CaseDef(tree, pat, guard1, body1), body1)
}
val doCase: () => CaseDef =
- () => caseRest(typedPattern(tree.pat, selType))(ctx.fresh.withNewScope)
+ () => caseRest(typedPattern(tree.pat, selType))(ctx.fresh.clearScope)
(doCase /: gadtSyms)((op, tsym) => tsym.withGADTFlexType(op))()
}
@@ -835,7 +835,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
val pid1 = typedExpr(tree.pid, AnySelectionProto)
val pkg = pid1.symbol
val packageContext =
- if (pkg is Package) ctx.fresh.withOwner(pkg.moduleClass).withTree(tree)
+ if (pkg is Package) ctx.fresh.setOwner(pkg.moduleClass).setTree(tree)
else {
ctx.error(i"$pkg is not a packge", tree.pos)
ctx
@@ -872,8 +872,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
NoSymbol
}
def localContext = {
- val freshCtx = ctx.fresh.withTree(xtree)
- if (sym.exists) freshCtx.withOwner(sym)
+ val freshCtx = ctx.fresh.setTree(xtree)
+ if (sym.exists) freshCtx.setOwner(sym)
else freshCtx // can happen for self defs
}
@@ -884,13 +884,13 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
case tree: untpd.Bind => typedBind(tree, pt)
case tree: untpd.ValDef =>
if (tree.isEmpty) tpd.EmptyValDef
- else typedValDef(tree, sym)(localContext.withNewScope)
+ else typedValDef(tree, sym)(localContext.clearScope)
case tree: untpd.DefDef =>
val typer1 = nestedTyper.remove(sym).get
- typer1.typedDefDef(tree, sym)(localContext.withTyper(typer1))
+ typer1.typedDefDef(tree, sym)(localContext.setTyper(typer1))
case tree: untpd.TypeDef =>
if (tree.isClassDef) typedClassDef(tree, sym.asClass)(localContext)
- else typedTypeDef(tree, sym)(localContext.withNewScope)
+ else typedTypeDef(tree, sym)(localContext.clearScope)
case _ => typedUnadapted(desugar(tree), pt)
}
@@ -904,7 +904,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
case tree: untpd.Typed => typedTyped(tree, pt)
case tree: untpd.NamedArg => typedNamedArg(tree, pt)
case tree: untpd.Assign => typedAssign(tree, pt)
- case tree: untpd.Block => typedBlock(desugar.block(tree), pt)(ctx.fresh.withNewScope)
+ case tree: untpd.Block => typedBlock(desugar.block(tree), pt)(ctx.fresh.clearScope)
case tree: untpd.If => typedIf(tree, pt)
case tree: untpd.Function => typedFunction(tree, pt)
case tree: untpd.Closure => typedClosure(tree, pt)
@@ -970,7 +970,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
case Thicket(stats) :: rest =>
traverse(stats ++ rest)
case stat :: rest =>
- val nestedCtx = if (exprOwner == ctx.owner) ctx else ctx.fresh.withOwner(exprOwner)
+ val nestedCtx = if (exprOwner == ctx.owner) ctx else ctx.fresh.setOwner(exprOwner)
buf += typed(stat)(nestedCtx)
traverse(rest)
case nil =>
@@ -987,7 +987,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
typed(tree, pt)(ctx addMode Mode.Pattern)
def tryEither[T](op: Context => T)(fallBack: (T, TyperState) => T)(implicit ctx: Context) = {
- val nestedCtx = ctx.fresh.withNewTyperState
+ val nestedCtx = ctx.fresh.clearTyperState
val result = op(nestedCtx)
if (nestedCtx.reporter.hasErrors)
fallBack(result, nestedCtx.typerState)
diff --git a/test/test/DottyTest.scala b/test/test/DottyTest.scala
index fcc211175..604f5d500 100644
--- a/test/test/DottyTest.scala
+++ b/test/test/DottyTest.scala
@@ -22,14 +22,14 @@ class DottyTest {
val base = new ContextBase
import base.settings._
val ctx = base.initialCtx.fresh
- .withSetting(verbose, true)
+ .setSetting(verbose, true)
// .withSetting(debug, true)
// .withSetting(debugTrace, true)
// .withSetting(prompt, true)
- .withSetting(Ylogcp, true)
- .withSetting(printtypes, true)
- .withSetting(pageWidth, 90)
- .withSetting(log, List("<some"))
+ .setSetting(Ylogcp, true)
+ .setSetting(printtypes, true)
+ .setSetting(pageWidth, 90)
+ .setSetting(log, List("<some"))
// .withTyperState(new TyperState(new ConsoleReporter()(base.initialCtx)))
// .withSetting(uniqid, true)
diff --git a/test/test/ShowClassTests.scala b/test/test/ShowClassTests.scala
index 46f9e385e..5c6cb8d58 100644
--- a/test/test/ShowClassTests.scala
+++ b/test/test/ShowClassTests.scala
@@ -42,8 +42,8 @@ class ShowClassTests extends DottyTest {
"dotty.tools.dotc.core.pickling.AbstractFileReader")
def doTwice(test: Context => Unit)(implicit ctx: Context): Unit = {
- test(ctx.fresh.withSetting(ctx.base.settings.debug, true))
- test(ctx.fresh.withSetting(ctx.base.settings.debug, false))
+ test(ctx.fresh.setSetting(ctx.base.settings.debug, true))
+ test(ctx.fresh.setSetting(ctx.base.settings.debug, false))
}
def showPackage(pkg: TermSymbol)(implicit ctx: Context): Unit = {