Skip to content

Rename methods on FreshContext to make mutation obvious and avoid name clashes with methods in Context #98

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions src/dotty/tools/dotc/Compiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
.setNewMode(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 = {
Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/Driver.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions src/dotty/tools/dotc/config/PathResolver.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
Expand Down
66 changes: 33 additions & 33 deletions src/dotty/tools/dotc/core/Contexts.scala
Original file line number Diff line number Diff line change
Expand Up @@ -278,12 +278,13 @@ object Contexts {
}

final def withMode(mode: Mode): Context =
if (mode != this.mode) fresh.withNewMode(mode) else this
if (mode != this.mode) fresh.setNewMode(mode) else this

def withPhase(phase: PhaseId): Context =
if (this.phaseId == phaseId) this else fresh.withPhase(phase)
if (this.phaseId == phaseId) this else withPhase(this.base.phases(phaseId))
def withPhase(phase: Phase): Context =
withPhase(phase.id)
if (this.phaseId == phaseId) this else fresh.setPhase(phase)


final def addMode(mode: Mode): Context = withMode(this.mode | mode)
final def maskMode(mode: Mode): Context = withMode(this.mode & mode)
Expand All @@ -306,36 +307,35 @@ 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 setNewMode(mode: Mode): this.type = { this.mode = mode; this }
def setTyperState(typerState: TyperState): this.type = { this.typerState = typerState; this }
def setNewTyperState: 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 setNewScope: 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(phase: Phase): this.type = setPeriod(Period(runId, phase.id))

def setSetting[T](setting: Setting[T], value: T): this.type =
setSettings(setting.updateIn(sstate, value))

def enableDebug = setSetting(base.settings.debug, true)
}

/** A class defining the initial context with given context base
Expand Down
3 changes: 2 additions & 1 deletion src/dotty/tools/dotc/core/Periods.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package dotty.tools.dotc.core

import Contexts._
import dotty.tools.dotc.util.DotClass
import dotty.tools.dotc.core.Phases.Phase

/** Periods are the central "clock" of the compiler.
* A period consists of a run id and a phase id.
Expand All @@ -19,7 +20,7 @@ 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 =
Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/core/Phases.scala
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,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

Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/core/SymDenotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1352,7 +1352,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.
Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/core/TypeComparer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/printing/Disambiguation.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
4 changes: 2 additions & 2 deletions src/dotty/tools/dotc/transform/LazyVals.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)))
Expand Down Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions src/dotty/tools/dotc/typer/Applications.scala
Original file line number Diff line number Diff line change
Expand Up @@ -712,15 +712,15 @@ 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
}

/** Is given method reference applicable to argument types `args`?
* @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
}

Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/typer/FrontEnd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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(_))
Expand Down
18 changes: 9 additions & 9 deletions src/dotty/tools/dotc/typer/Implicits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down Expand Up @@ -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
}
}

Expand Down Expand Up @@ -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]
}
)

Expand Down Expand Up @@ -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.setNewMode(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))
Expand Down Expand Up @@ -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.setNewTyperState)
def refMatches(shadowing: Tree): Boolean =
ref.symbol == closureBody(shadowing).symbol || {
shadowing match {
Expand Down Expand Up @@ -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.setNewTyperState.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
Expand All @@ -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 ", "}")
Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/typer/Inferencing.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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.setNewTyperState
val result = new IsFullyDefinedAccumulator(force)(nestedCtx).process(tp)
if (result) nestedCtx.typerState.commit()
result
Expand Down
14 changes: 7 additions & 7 deletions src/dotty/tools/dotc/typer/Namer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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.setNewScope
selfInfo match {
case sym: Symbol if sym.exists && sym.name != nme.WILDCARD =>
localCtx.scope.asInstanceOf[MutableScope].enter(sym)
Expand Down Expand Up @@ -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 =>
Expand Down Expand Up @@ -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).setNewScope)
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).setNewScope)
case imp: Import =>
try {
val expr1 = typedAheadExpr(imp.expr, AnySelectionProto)
Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/typer/ProtoTypes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
Loading