aboutsummaryrefslogtreecommitdiff
path: root/src
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
parentb1f0eaa41cdf0a6bbc37078f6580b04f85ad5079 (diff)
downloaddotty-62d0df5a8ef140a721e3e14d9dae34545ef9016d.tar.gz
dotty-62d0df5a8ef140a721e3e14d9dae34545ef9016d.tar.bz2
dotty-62d0df5a8ef140a721e3e14d9dae34545ef9016d.zip
Cleaup of Contexts
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/core/Contexts.scala117
-rw-r--r--src/dotty/tools/dotc/core/Printers.scala16
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala3
-rw-r--r--src/dotty/tools/dotc/core/SymbolLoaders.scala2
-rw-r--r--src/dotty/tools/dotc/core/pickling/ClassfileParser.scala7
-rw-r--r--src/dotty/tools/dotc/core/pickling/UnPickler.scala4
-rw-r--r--src/dotty/tools/dotc/reporting/Reporter.scala2
7 files changed, 112 insertions, 39 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
diff --git a/src/dotty/tools/dotc/core/Printers.scala b/src/dotty/tools/dotc/core/Printers.scala
index b65161c64..7bc835f36 100644
--- a/src/dotty/tools/dotc/core/Printers.scala
+++ b/src/dotty/tools/dotc/core/Printers.scala
@@ -10,18 +10,8 @@ trait Printers { this: Context =>
import Printers._
- def printer = if (base.settings.debug.value) plainPrinter else refinedPrinter
+ def printer = if (this.debug) plainPrinter else refinedPrinter
- private 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 {
@@ -38,10 +28,6 @@ object Printers {
val LeftArrowPrec = new Precedence(1)
val GlobalPrec = new Precedence(0)
- trait PrinterBase { self: ContextBase =>
- private[core] var showRecursions = 0
- }
-
abstract class Printer {
/** Show name, same as name.toString */
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index 5d2ec2dc0..799407b0c 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -649,6 +649,7 @@ object SymDenotations {
_superClassBits = ctx.uniqueBits.findEntryOrUpdate(seen.toImmutable)
}
+ /** A bitset that contains the superId's of all base classes */
private def superClassBits(implicit ctx: Context): BitSet = {
if (_superClassBits == null) computeSuperClassBits
_superClassBits
@@ -919,7 +920,7 @@ object SymDenotations {
|in ${denot.owner.showKind} ${denot.owner.showFullName} which is not available.
|It may be completely missing from the current classpath, or the version on
|the classpath might be incompatible with the version used when compiling $src.""".stripMargin)
- if (cctx.settings.debug.value) (new Throwable).printStackTrace
+ if (cctx.debug) (new Throwable).printStackTrace
initializeToDefaults(denot)
}
}
diff --git a/src/dotty/tools/dotc/core/SymbolLoaders.scala b/src/dotty/tools/dotc/core/SymbolLoaders.scala
index 5b5bf0078..59835beda 100644
--- a/src/dotty/tools/dotc/core/SymbolLoaders.scala
+++ b/src/dotty/tools/dotc/core/SymbolLoaders.scala
@@ -194,7 +194,7 @@ abstract class SymbolLoader extends LazyType {
override def complete(root: SymDenotation): Unit = {
def signalError(ex: Exception) {
- if (cctx.settings.debug.value) ex.printStackTrace()
+ if (cctx.debug) ex.printStackTrace()
val msg = ex.getMessage()
cctx.error(
if (msg eq null) "i/o error while loading " + root.name
diff --git a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
index 8e34aa0a9..390aac890 100644
--- a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
+++ b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
@@ -20,6 +20,7 @@ class ClassfileParser(
import ClassfileConstants._
import cctx.base.{settings, loaders, definitions => defn}
+ import cctx.{debug, verbose}
protected val in = new AbstractFileReader(classfile)
@@ -48,7 +49,7 @@ class ClassfileParser(
parseClass()
} catch {
case e: RuntimeException =>
- if (settings.debug.value) e.printStackTrace()
+ if (debug) e.printStackTrace()
throw new IOException(
s"""class file $classfile is broken, reading aborted with $e.getClass
|${Option(e.getMessage).getOrElse("")}""".stripMargin)
@@ -411,7 +412,7 @@ class ClassfileParser(
// with a `FatalError` exception, handled above. Here you'd end up after a NPE (for example),
// and that should never be swallowed silently.
cctx.warning("Caught: " + ex + " while parsing annotations in " + in.file)
- if (settings.debug.value) ex.printStackTrace()
+ if (debug) ex.printStackTrace()
None // ignore malformed annotations
}
@@ -433,7 +434,7 @@ class ClassfileParser(
case tpnme.SignatureATTR =>
val sig = pool.getExternalName(in.nextChar)
newType = sigToType(sig, sym)
- if (settings.debug.value && settings.verbose.value)
+ if (debug && verbose)
println("" + sym + "; signature = " + sig + " type = " + newType)
case tpnme.SyntheticATTR =>
sym.setFlag(Flags.SyntheticArtifact)
diff --git a/src/dotty/tools/dotc/core/pickling/UnPickler.scala b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
index 67e7d318f..1d0ad9e26 100644
--- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala
+++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
@@ -76,7 +76,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleRoot: Clas
import UnPickler._
- protected def debug = cctx.settings.debug.value
+ import cctx.debug
checkVersion()
@@ -98,7 +98,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleRoot: Clas
val ex = new BadSignature(
s"""error reading Scala signature of $classRoot from $source:
|error occured at position $readIndex: $msg""".stripMargin)
- /*if (settings.debug.value)*/ ex.printStackTrace()
+ /*if (debug)*/ ex.printStackTrace()
throw ex
}
diff --git a/src/dotty/tools/dotc/reporting/Reporter.scala b/src/dotty/tools/dotc/reporting/Reporter.scala
index 862e665ae..83b97bea2 100644
--- a/src/dotty/tools/dotc/reporting/Reporter.scala
+++ b/src/dotty/tools/dotc/reporting/Reporter.scala
@@ -19,7 +19,7 @@ trait Reporting { this: Context =>
inform(s"[log ${ctx.phasesStack.reverse.mkString(" -> ")}] $msg")
def debuglog(msg: => String)(implicit ctx: Context): Unit =
- if (ctx.settings.debug.value) log(msg)
+ if (ctx.debug) log(msg)
def informTime(msg: => String, start: Long)(implicit ctx: Context): Unit =
informProgress(msg + elapsed(start))