diff options
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 = { |