aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/Contexts.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-02-27 16:27:26 +0100
committerMartin Odersky <odersky@gmail.com>2013-02-27 16:27:26 +0100
commit62d0df5a8ef140a721e3e14d9dae34545ef9016d (patch)
tree07edc159ba9c359143ff7d3e3f5dbb701def636c /src/dotty/tools/dotc/core/Contexts.scala
parentb1f0eaa41cdf0a6bbc37078f6580b04f85ad5079 (diff)
downloaddotty-62d0df5a8ef140a721e3e14d9dae34545ef9016d.tar.gz
dotty-62d0df5a8ef140a721e3e14d9dae34545ef9016d.tar.bz2
dotty-62d0df5a8ef140a721e3e14d9dae34545ef9016d.zip
Cleaup of Contexts
Diffstat (limited to 'src/dotty/tools/dotc/core/Contexts.scala')
-rw-r--r--src/dotty/tools/dotc/core/Contexts.scala117
1 files changed, 101 insertions, 16 deletions
diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala
index ff9d3c454..a77910684 100644
--- a/src/dotty/tools/dotc/core/Contexts.scala
+++ b/src/dotty/tools/dotc/core/Contexts.scala
@@ -29,8 +29,8 @@ object Contexts {
* - Classes that need contexts for their initialization take an explicit parameter
* named `initctx`. They pass initctx to all positions where it is needed
* (and these positions should all be part of the intialization sequence of the class).
- * - Classes that need contexts that survive initialization are passed
- * a "condensed context", typically named `cctx` instead. Consensed contexts
+ * - Classes that need contexts that survive initialization are instead passed
+ * a "condensed context", typically named `cctx` (or they create one). Consensed contexts
* just add some basic information to the context base without the
* risk of capturing complete trees.
* - To make sure these rules are kept, it would be good to do a sanity
@@ -49,27 +49,32 @@ object Contexts {
with Cloneable { thiscontext =>
implicit val ctx: Context = this
+ /** The context base at the root */
val base: ContextBase
+ /** All outer contexts, ending in `base.initialCtx` and then `NoContext` */
def outersIterator = new Iterator[Context] {
var current = thiscontext
def hasNext = current != NoContext
def next = { val c = current; current = current.outer; c }
}
-
+ /** The outer context */
private[this] var _outer: Context = _
protected def outer_=(outer: Context) = _outer = outer
def outer: Context = _outer
+ /** The current context */
private[this] var _period: Period = _
protected def period_=(period: Period) = _period = period
def period: Period = _period
+ /** The current set of type constraints */
private[this] var _constraints: Constraints = _
protected def constraints_=(constraints: Constraints) = _constraints = constraints
def constraints: Constraints = _constraints
+ /** The current type comparer */
private[this] var _typeComparer: TypeComparer = _
protected def typeComparer_=(typeComparer: TypeComparer) = _typeComparer = typeComparer
@@ -80,34 +85,55 @@ object Contexts {
_typeComparer
}
+ /** The current position */
private[this] var _position: Position = _
protected def position_=(position: Position) = _position = position
def position: Position = _position
+ /** The current plain printer */
private[this] var _plainPrinter: Context => Printer = _
protected def plainPrinter_=(plainPrinter: Context => Printer) = _plainPrinter = plainPrinter
def plainPrinter: Context => Printer = _plainPrinter
+ /** The current refined printer */
private[this] var _refinedPrinter: Context => Printer = _
protected def refinedPrinter_=(refinedPrinter: Context => Printer) = _refinedPrinter = refinedPrinter
def refinedPrinter: Context => Printer = _refinedPrinter
+ /** The current owner symbol */
private[this] var _owner: Symbol = _
protected def owner_=(owner: Symbol) = _owner = owner
def owner: Symbol = _owner
+ /** The current settings values */
private[this] var _sstate: SettingsState = _
protected def sstate_=(sstate: SettingsState) = _sstate = sstate
def sstate: SettingsState = _sstate
+ /** The current tree */
private[this] var _tree: Tree = _
protected def tree_=(tree: Tree) = _tree = tree
def tree: Tree = _tree
+ /** The current reporter */
private[this] var _reporter: Reporter = _
protected def reporter_=(reporter: Reporter) = _reporter = reporter
def reporter: Reporter = _reporter
+ /** An optional diagostics buffer than is used by some checking code
+ * to leave provide more information in the buffer if it exists.
+ */
+ private var _diagnostics: Option[StringBuilder] = _
+ protected def diagnostics_=(diagnostics: Option[StringBuilder]) = _diagnostics = diagnostics
+ def diagnostics: Option[StringBuilder] = _diagnostics
+
+ /** Leave message in diagnostics buffer if it exists */
+ def diagnose(str: => String) =
+ for (sb <- diagnostics) {
+ sb.setLength(0)
+ sb.append(str)
+ }
+
/** The next outer context whose tree is a template or package definition */
def enclTemplate: Context = {
var c = this
@@ -116,36 +142,64 @@ object Contexts {
c
}
+ /** The current source file; will be derived from current
+ * compilation unit.
+ */
def source = io.NoSource // for now
+ /** Does current phase use an erased types interpretation? */
def erasedTypes: Boolean = phase.erasedTypes
+
+ /** Is the debug option set? */
def debug: Boolean = base.settings.debug.value
+ /** Is the verbose option set? */
+ def verbose: Boolean = base.settings.verbose.value
+
+
+ /** A condensed context containing essential information of this but
+ * no outer contexts except the initial context.
+ */
private var _condensed: CondensedContext = null
def condensed: CondensedContext = {
- if (_condensed == null)
+ if (_condensed eq outer.condensed)
_condensed = base.initialCtx.fresh
.withPeriod(period)
+ // constraints is not preserved in condensed
.withPlainPrinter(plainPrinter)
.withRefinedPrinter(refinedPrinter)
+ .withOwner(owner)
.withSettings(sstate)
+ // tree is not preserved in condensed
+ .withReporter(reporter)
+ .withDiagnostics(diagnostics)
_condensed
}
+ /** A fresh clone of this context. */
def fresh: FreshContext = {
val newctx = super.clone.asInstanceOf[FreshContext]
newctx.outer = this
- newctx._condensed = null
newctx
}
}
- abstract class CondensedContext extends Context
+ /** A condensed context provides only a small memory footprint over
+ * a Context base, and therefore can be stored without problems in
+ * long-lived objects.
+ */
+ abstract class CondensedContext extends Context {
+ override def condensed = this
+ }
+ /** A fresh context allows selective modification
+ * of its attributes using the with... methods.
+ */
abstract class FreshContext extends CondensedContext {
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 withPosition(position: Position): this.type = { this.position = position; this }
def withPlainPrinter(printer: Context => Printer): this.type = { this.plainPrinter = printer; this }
def withRefinedPrinter(printer: Context => Printer): this.type = { this.refinedPrinter = printer; this }
def withOwner(owner: Symbol): this.type = { this.owner = owner; this }
@@ -155,43 +209,55 @@ object Contexts {
def withDiagnostics(diagnostics: Option[StringBuilder]): this.type = { this.diagnostics = diagnostics; this }
}
- private class InitialContext(val base: ContextBase) extends FreshContext {
+ /** A class defining the initial context with given context base
+ * and set of possible settings.
+ */
+ private class InitialContext(val base: ContextBase, settings: SettingGroup) extends FreshContext {
outer = NoContext
period = Nowhere
constraints = Map()
+ position = NoPosition
plainPrinter = new PlainPrinter(_)
refinedPrinter = new RefinedPrinter(_)
owner = NoSymbol
+ sstate = settings.defaultState
tree = EmptyTree
reporter = new ConsoleReporter
+ diagnostics = None
}
object NoContext extends Context {
lazy val base = unsupported("base")
}
+ /** A context base defines state and associated methods that exist once per
+ * compiler run.
+ */
class ContextBase extends ContextState
with Transformers.TransformerBase
- with Printers.PrinterBase
with Denotations.DenotationsBase
with Phases.PhasesBase {
+ /** The applicable settings */
val settings = new ScalaSettings
- val initialCtx: Context = new InitialContext(this)
- .withSettings(settings.defaultState)
+ /** The initial context */
+ val initialCtx: Context = new InitialContext(this, settings)
+ /** The symbol loaders */
val loaders = new SymbolLoaders
+ /** The platform */
val platform: Platform = new JavaPlatform
+ /** The loader that loads the members of _root_ */
def rootLoader(implicit ctx: Context): SymbolLoader = platform.rootLoader
+ /** The standard definitions */
val definitions = new Definitions()(initialCtx)
-
}
- /** Mutable state of a context base, collected into a common class */
+ /** The essential mutable state of a context base, collected into a common class */
class ContextState {
// Symbols state
@@ -201,13 +267,13 @@ object Contexts {
def nextId = { _nextId += 1; _nextId }
- /** A map from a superclass id to the type-ref of the class that has it */
+ /** A map from a superclass id to the typeref of the class that has it */
private[core] var classOfId = new Array[TypeRef](InitialSuperIdsSize)
- /** A map from a the type-ref of a superclass to its superclass id */
+ /** A map from a the typeref of a class to its superclass id */
private[core] val superIdOfClass = new mutable.HashMap[TypeRef, Int]
- /** The last allocate superclass id */
+ /** The last allocated superclass id */
private[core] var lastSuperId = -1
/** Allocate and return next free superclass id */
@@ -222,27 +288,46 @@ object Contexts {
}
// SymDenotations state
+ /** A table where unique superclass bits are kept.
+ * These are bitsets that contain the superclass ids of all base classes of a class.
+ * Used to speed up isSubClass tests.
+ */
private[core] val uniqueBits = new util.HashSet[BitSet]("superbits", 1024)
// Types state
+ /** A table for hash consing unique types */
private[core] val uniques = new util.HashSet[Type]("uniques", initialUniquesCapacity) {
override def hash(x: Type): Int = x.hash
}
// TypeOps state
+ /** The number of recursive invocation of isVolatile */
private[core] var volatileRecursions: Int = 0
+
+ /** The set of types on which a currently active invocation of isVolatile exists. */
private[core] val pendingVolatiles = new mutable.HashSet[Type]
// Phases state
+ /** Phases by id */
private[core] var phases = new Array[Phase](MaxPossiblePhaseId + 1)
+
+ /** The number of defined phases. This includes NoPhase, so nphases >= 1 */
private[core] var nphases = 0
+
+ // Printers state
+ /** Number of recursive invocations of a show method on cuyrrent stack */
+ private[core] var showRecursions = 0
}
object Context {
+
+ /** Implicit conversion that injects all printer operations into a context */
implicit def toPrinter(ctx: Context) = ctx.printer(ctx)
+
+ /** implicit conversion that injects all ContextBase members into a context */
+ implicit def toBase(ctx: Context): ContextBase = ctx.base
}
- implicit def ctxToBase(ctx: Context): ContextBase = ctx.base
/** Initial size of superId table */
private final val InitialSuperIdsSize = 4096