aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-01-29 09:44:37 +0100
committerMartin Odersky <odersky@gmail.com>2013-01-29 09:44:37 +0100
commitbbc4f7a3234937e5f79e8310e6fff2f9b4af0f98 (patch)
tree36537cd033d5e37a489839f2970245df9db5e544 /src/dotty/tools
parent9770566c50baff03a7e61344c203b29db8750e8f (diff)
downloaddotty-bbc4f7a3234937e5f79e8310e6fff2f9b4af0f98.tar.gz
dotty-bbc4f7a3234937e5f79e8310e6fff2f9b4af0f98.tar.bz2
dotty-bbc4f7a3234937e5f79e8310e6fff2f9b4af0f98.zip
New Context architecture based on cloning
Diffstat (limited to 'src/dotty/tools')
-rw-r--r--src/dotty/tools/dotc/core/Contexts.scala111
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala2
-rw-r--r--src/dotty/tools/dotc/core/Periods.scala16
-rw-r--r--src/dotty/tools/dotc/core/Printers.scala57
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala13
-rw-r--r--src/dotty/tools/dotc/core/Symbols.scala13
-rw-r--r--src/dotty/tools/dotc/core/Transformers.scala20
-rw-r--r--src/dotty/tools/dotc/core/TypeOps.scala13
-rw-r--r--src/dotty/tools/dotc/core/Types.scala4
9 files changed, 166 insertions, 83 deletions
diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala
index 645820792..6bfc6233b 100644
--- a/src/dotty/tools/dotc/core/Contexts.scala
+++ b/src/dotty/tools/dotc/core/Contexts.scala
@@ -13,52 +13,95 @@ import collection.immutable.BitSet
object Contexts {
- val NoContext: Context = null
-
- abstract class Context extends Periods with Substituters with TypeOps {
+ abstract class Context extends Periods with Substituters with TypeOps with Cloneable {
implicit val ctx: Context = this
- val underlying: Context
- val root: RootContext
- val period: Period
- def constraints: Constraints
- def typeComparer: TypeComparer
- def printer: Printer = ???
- def names: NameTable
+
+ def base: ContextBase
+
+ private[this] var _underlying: Context = _
+ protected def underlying_=(underlying: Context) = _underlying = underlying
+ def underlying: Context = _underlying
+
+ private[this] var _period: Period = _
+ protected def period_=(period: Period) = _period = period
+ def period: Period = _period
+
+ private[this] var _constraints: Constraints = _
+ protected def constraints_=(constraints: Constraints) = _constraints = constraints
+ def constraints: Constraints = _constraints
+
+ private[this] var _typeComparer: TypeComparer = _
+ protected def typeComparer_=(typeComparer: TypeComparer) = _typeComparer = typeComparer
+
+ def typeComparer: TypeComparer = {
+ if ((_typeComparer eq underlying.typeComparer) &&
+ (constraints ne underlying.constraints))
+ _typeComparer = new TypeComparer(this)
+ _typeComparer
+ }
+
+ private[this] var _printer: Printer = _
+ protected def printer_=(printer: Printer) = _printer = printer
+ def printer: Printer = _printer
+
+ private[this] var _owner: Symbol = _
+ protected def owner_=(owner: Symbol) = _owner = owner
+ def owner: Symbol = _owner
+
+ private[this] var _diagnostics: Option[StringBuilder] = _
+ protected def diagnostics_=(diagnostics: Option[StringBuilder]) = _diagnostics = diagnostics
+ def diagnostics: Option[StringBuilder] = _diagnostics
+
+ def diagnose(str: => String) =
+ for (sb <- diagnostics) {
+ sb.setLength(0)
+ sb.append(str)
+ }
+
+
+ def phase: Phase = ??? // phase(period.phaseId)
def enclClass: Context = ???
- def phase: Phase = ???
- def owner: Symbol = ???
def erasedTypes: Boolean = ???
+// def settings: Settings = ???
+ def warning(msg: String) = ???
+
+ def fresh: FreshContext = {
+ val newctx = super.clone.asInstanceOf[FreshContext]
+ newctx.underlying = this
+ newctx
+ }
+
}
- abstract class DiagnosticsContext(ctx: Context) extends SubContext(ctx) {
- var diagnostics: () => String
+ abstract class FreshContext extends Context {
+ def withPeriod(period: Period): this.type = { this.period = period; this }
+ def withPhase(pid: PhaseId): this.type = withPeriod(Period(runId, pid))
+ def withConstraints(constraints: Constraints): this.type = { this.constraints = constraints; this }
+ def withPrinter(printer: Printer): this.type = { this.printer = printer; this }
+ def withOwner(owner: Symbol): this.type = { this.owner = owner; this }
+ def withDiagnostics(diagnostics: Option[StringBuilder]): this.type = { this.diagnostics = diagnostics; this }
}
- abstract class SubContext(val underlying: Context) extends Context {
- val root: RootContext = underlying.root
- val period: Period = underlying.period
- val constraints = underlying.constraints
- def names: NameTable = root.names
- lazy val typeComparer =
- if (constraints eq underlying.constraints) underlying.typeComparer
- else new TypeComparer(this)
+ private class InitialContext(val base: ContextBase) extends FreshContext {
+ underlying = NoContext
+ period = Nowhere
+ constraints = Map()
+ printer = new StdPrinter
+ owner = NoSymbol
}
- class RootContext extends Context
- with Transformers {
+ object NoContext extends Context {
+ val base = unsupported("base")
+ }
- val underlying: Context = throw new UnsupportedOperationException("RootContext.underlying")
- def typeComparer: TypeComparer = ???
+ class ContextBase extends Transformers.TransformerBase
+ with Printers.PrinterBase {
- val root: RootContext = this
- val period = Nowhere
- val names: NameTable = new NameTable
- val variance = 1
+ val initialCtx: Context = new InitialContext(this)
- var lastPhaseId: Int = NoPhaseId
- lazy val definitions = new Definitions()(this)
+ val names: NameTable = new NameTable
- val constraints: Constraints = Map()
+ lazy val definitions = new Definitions()(initialCtx)
// Symbols state
/** A map from a superclass id to the class that has it */
@@ -94,6 +137,8 @@ object Contexts {
private[core] val pendingVolatiles = new mutable.HashSet[Type]
}
+ implicit def ctxToBase(ctx: Context): ContextBase = ctx.base
+
/** Initial size of superId table */
private final val InitialSuperIdsSize = 4096
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala
index 461ef2f17..e3c73fdb3 100644
--- a/src/dotty/tools/dotc/core/Denotations.scala
+++ b/src/dotty/tools/dotc/core/Denotations.scala
@@ -334,7 +334,7 @@ object Denotations {
} else {
// not found, current points to highest existing variant
var startPid = current.validFor.lastPhaseId + 1
- val trans = ctx.root.transformersFor(current)
+ val trans = ctx.transformersFor(current)
val endPid = trans.nextTransformer(startPid + 1).phaseId - 1
next = trans.nextTransformer(startPid) transform current
if (next eq current)
diff --git a/src/dotty/tools/dotc/core/Periods.scala b/src/dotty/tools/dotc/core/Periods.scala
index 97384e509..3a91b48cb 100644
--- a/src/dotty/tools/dotc/core/Periods.scala
+++ b/src/dotty/tools/dotc/core/Periods.scala
@@ -7,7 +7,7 @@ import Contexts._
* run ids represent compiler runs
* phase ids represent compiler phases
*/
-abstract class Periods { self: Context =>
+abstract class Periods extends DotClass { self: Context =>
import Periods._
/** The current phase identifier */
@@ -16,23 +16,13 @@ abstract class Periods { self: Context =>
/** The current run identifier */
def runId = period.runId
- /** A new context that differs from the current one in its period */
- def withPeriod(pd: Period): Context =
- if (period == pd) this
- else new SubContext(self) {
- override val period = pd
- }
-
- /** A new context that differs from the current one in its phase */
- def withPhase(pid: PhaseId): Context = withPeriod(Period(runId, pid))
-
/** Execute `op` at given period */
def atPeriod[T](pd: Period)(op: Context => T) =
- op(ctx withPeriod pd)
+ op(ctx.fresh.withPeriod(pd))
/** Execute `op` at given phase id */
def atPhase[T](pid: PhaseId)(op: Context => T) =
- op(ctx withPhase pid)
+ op(ctx.fresh.withPhase(pid))
}
object Periods {
diff --git a/src/dotty/tools/dotc/core/Printers.scala b/src/dotty/tools/dotc/core/Printers.scala
index 67d4d3422..d7476c433 100644
--- a/src/dotty/tools/dotc/core/Printers.scala
+++ b/src/dotty/tools/dotc/core/Printers.scala
@@ -3,8 +3,28 @@ package core
import Types._, Symbols._, Contexts._, Scopes._
+trait Printers {
+
+ private[this] var _diagnostics: Option[StringBuilder] = _
+ protected def diagnostics_=(diagnostics: Option[StringBuilder]) = _diagnostics = diagnostics
+ def diagnostics: Option[StringBuilder] = _diagnostics
+
+ def diagnose(str: => String) =
+ for (sb <- diagnostics) {
+ sb.setLength(0)
+ sb.append(str)
+ }
+}
+
+
object Printers {
+ trait PrinterBase { self: ContextBase =>
+
+ private[core] var showRecursions = 0
+
+ }
+
abstract class Printer {
def show(tp: Type)(implicit ctx: Context): String
def show(sym: Symbol)(implicit ctx: Context): String
@@ -13,9 +33,41 @@ object Printers {
def show(sc: Scope)(implicit ctx: Context): String
}
+ object StdPrinter {
+ final val maxShowRecursions = 50
+ }
+
class StdPrinter extends Printer {
- def show(tp: Type)(implicit ctx: Context): String = ???
- def show(sym: Symbol)(implicit ctx: Context): String = ???
+ import StdPrinter._
+
+ def controlled(op: => String)(implicit ctx: Context): String =
+ if (ctx.showRecursions < maxShowRecursions)
+ try {
+ ctx.showRecursions += 1
+ op
+ } finally {
+ ctx.showRecursions -= 1
+ }
+ else {
+ if (???/*ctx.settings.debug.value*/) {
+ ctx.warning("Exceeded recursion depth attempting to print type.")
+ (new Throwable).printStackTrace
+ }
+ "..."
+ }
+
+ def show(tp: Type)(implicit ctx: Context): String = controlled {
+ tp match {
+ case TermRef(pre, name) =>
+ ??? // showPrefix(pre) + show(name)
+
+
+
+ }
+ }
+ def show(sym: Symbol)(implicit ctx: Context): String = controlled {
+ ???
+ }
def showLocated(sym: Symbol)(implicit ctx: Context): String = ???
def showDef(sym: Symbol)(implicit ctx: Context): String = ???
def show(sc: Scope)(implicit ctx: Context): String =
@@ -23,4 +75,5 @@ object Printers {
}
+
} \ 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 0a1138e46..0748cf42d 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -232,16 +232,13 @@ object SymDenotations {
/** Is protected access to target symbol permitted? */
def isProtectedAccessOK = {
- def fail(diagnostics: () => String): Boolean = {
- ctx match {
- case ctx: DiagnosticsContext => ctx.diagnostics = diagnostics
- case _ =>
- }
+ def fail(str: => String): Boolean = {
+ ctx.diagnose(str)
false
}
val cls = owner.enclosingSubClass
if (!cls.exists)
- fail(() =>
+ fail(
s"""Access to protected $this not permitted because
|enclosing ${ctx.enclClass.owner.showLocated} is not a subclass of
|${owner.showLocated} where target is defined""".stripMargin)
@@ -249,7 +246,7 @@ object SymDenotations {
pre.widen.typeSymbol.isSubClassOrCompanion(cls) ||
cls.isModuleClass &&
pre.widen.typeSymbol.isSubClassOrCompanion(cls.linkedClass)))
- fail(() =>
+ fail(
s"""Access to protected ${symbol.show} not permitted because
|prefix type ${pre.widen.show} does not conform to
|${cls.showLocated} where the access takes place""".stripMargin)
@@ -449,7 +446,7 @@ object SymDenotations {
to
}
baseClassesVar = symbol :: addParentBaseClasses(parents, Nil)
- superClassBitsVar = ctx.root.uniqueBits.findEntryOrUpdate(seen.toImmutable)
+ superClassBitsVar = ctx.uniqueBits.findEntryOrUpdate(seen.toImmutable)
}
def superClassBits(implicit ctx: Context): BitSet = {
diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala
index 74c29802d..127e36f4d 100644
--- a/src/dotty/tools/dotc/core/Symbols.scala
+++ b/src/dotty/tools/dotc/core/Symbols.scala
@@ -285,16 +285,15 @@ object Symbols {
def superId(implicit ctx: Context): Int = {
val hint = superIdHint
- val rctx = ctx.root
- if (hint >= 0 && hint <= rctx.lastSuperId && (rctx.classOfId(hint) eq this)) hint
+ if (hint >= 0 && hint <= ctx.lastSuperId && (ctx.classOfId(hint) eq this)) hint
else {
- val id = rctx.superIdOfClass get this match {
+ val id = ctx.superIdOfClass get this match {
case Some(id) =>
id
case None =>
- val id = rctx.nextSuperId
- rctx.superIdOfClass(this) = id
- rctx.classOfId(id) = this
+ val id = ctx.nextSuperId
+ ctx.superIdOfClass(this) = id
+ ctx.classOfId(id) = this
id
}
superIdHint = id
@@ -312,7 +311,7 @@ object Symbols {
override def exists = false
}
- implicit def defn(implicit ctx: Context): Definitions = ctx.root.definitions
+ implicit def defn(implicit ctx: Context): Definitions = ctx.definitions
implicit def toFlagSet(sym: Symbol)(implicit ctx: Context): FlagSet = sym.flags
diff --git a/src/dotty/tools/dotc/core/Transformers.scala b/src/dotty/tools/dotc/core/Transformers.scala
index ee943e13e..a87356f39 100644
--- a/src/dotty/tools/dotc/core/Transformers.scala
+++ b/src/dotty/tools/dotc/core/Transformers.scala
@@ -4,20 +4,20 @@ package core
import Periods._, SymDenotations._, Contexts._, Types._, Denotations._
import java.lang.AssertionError
-trait Transformers { self: RootContext =>
+trait Transformers
- import Transformers._
+object Transformers {
- def transformersFor(ref: SingleDenotation): TransformerGroup = ref match {
- case _: SymDenotation => denotTransformers
- case _ => refTransformers
- }
+ trait TransformerBase { self: ContextBase =>
- val denotTransformers = new TransformerGroup
- val refTransformers = new TransformerGroup
-}
+ def transformersFor(ref: SingleDenotation): TransformerGroup = ref match {
+ case _: SymDenotation => denotTransformers
+ case _ => refTransformers
+ }
-object Transformers {
+ val denotTransformers = new TransformerGroup
+ val refTransformers = new TransformerGroup
+ }
val lastPhaseId = 31
diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala
index 5e25ab4a9..e75dc74f1 100644
--- a/src/dotty/tools/dotc/core/TypeOps.scala
+++ b/src/dotty/tools/dotc/core/TypeOps.scala
@@ -89,23 +89,22 @@ trait TypeOps { this: Context =>
// because volatile checking is done before all cycles are detected.
// the case to avoid is an abstract type directly or
// indirectly upper-bounded by itself. See #2918
- import ctx.root.{ volatileRecursions, pendingVolatiles }
try {
- volatileRecursions += 1
- if (volatileRecursions < LogVolatileThreshold)
+ ctx.volatileRecursions += 1
+ if (ctx.volatileRecursions < LogVolatileThreshold)
test
- else if (pendingVolatiles(tp))
+ else if (ctx.pendingVolatiles(tp))
false // we can return false here, because a cycle will be detected
// here afterwards and an error will result anyway.
else
try {
- pendingVolatiles += tp
+ ctx.pendingVolatiles += tp
test
} finally {
- pendingVolatiles -= tp
+ ctx.pendingVolatiles -= tp
}
} finally {
- volatileRecursions -= 1
+ ctx.volatileRecursions -= 1
}
}
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index dcef49d0d..dfa09a4c5 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -508,7 +508,7 @@ object Types {
def unique[T <: Type](tp: T)(implicit ctx: Context): T = {
if (tp.hash == NotCached) tp
- else ctx.root.uniques.findEntryOrUpdate(tp).asInstanceOf[T]
+ else ctx.uniques.findEntryOrUpdate(tp).asInstanceOf[T]
}
/** A marker trait for type proxies.
@@ -583,7 +583,7 @@ object Types {
throw new MalformedType(prefix, d.symbol)
d
} else {// name has changed; try load in earlier phase and make current
- denot(ctx.withPhase(ctx.phaseId - 1)).current
+ denot(ctx.fresh.withPhase(ctx.phaseId - 1)).current
}
}
}