diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/dotty/tools/dotc/core/Contexts.scala | 117 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Printers.scala | 16 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/SymDenotations.scala | 3 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/SymbolLoaders.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/pickling/ClassfileParser.scala | 7 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/pickling/UnPickler.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/reporting/Reporter.scala | 2 |
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)) |