summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/Global.scala
diff options
context:
space:
mode:
authorGrzegorz Kossakowski <grzegorz.kossakowski@gmail.com>2013-07-27 01:38:45 -0700
committerGrzegorz Kossakowski <grzegorz.kossakowski@gmail.com>2013-07-27 14:09:40 -0700
commitafbee09c8e0e7b1a4da1f8517c723dad9f1adb6f (patch)
tree9e0eba8ce1bff0af357aa4f84b3a905e00325bd9 /src/compiler/scala/tools/nsc/Global.scala
parent5eb4cdf1a7a466276a979d2952dbc30d416f423d (diff)
downloadscala-afbee09c8e0e7b1a4da1f8517c723dad9f1adb6f.tar.gz
scala-afbee09c8e0e7b1a4da1f8517c723dad9f1adb6f.tar.bz2
scala-afbee09c8e0e7b1a4da1f8517c723dad9f1adb6f.zip
Refactor the cake so SymbolTable does not depend on Global
This is rather large commit so I'll first explain the motivation behind it and then go through all changes in detail explaining the choices I made. The motivation behind this refactoring was to make SymbolTable unit testable. I wanted a lightweight way of initializing SymbolTable and then writing unit tests for subtyping algorithm, various functionality related to Symbols, etc. All of that should be possible by precisely controlling what we test, e.g., create types and symbols by hand and not have them defined in source code as we normally do in partest (functional) tests. The other motivation was to reduce and clarify dependencies we have in the compiler. Explicit dependencies lead to cleaner design. Also, explicit and reduces dependencies help incremental compilation which is a big problem for us in compiler's code base at the moment. One of the challenges I faced during that refactoring was cyclic dependency between Platform and SymbolLoaders. Platform depended on `SymbolLoaders.SymbolLoader` because it would define a root loader. SymbolLoaders depended on Platform for numerous reasons like deferring decision how to load a given symbol based on some Platform-specific hooks. I decided to break that cycle by removing methods related to symbol loading from Platform interface. One could argue, that better fix would be to make SymbolLoaders to not depend on Platform (backend) concept but that would be much bigger refactoring. Also, we have a new concept for dealing with symbol loading: Mirrors. For those reasons both `newClassLoader` and `rootLoader` were dropped from Platform interface. Note that JavaPlatform still depends on Global so it can access phases defined in Global to implement `platformPhases` method. Both GenICode and BCodeBodyBuilder have some Platform specific logic that requires casting because pattern matcher doesn't narrow types to give them a proper refinement. Check the changes for details. Some logging utilities has been moved from Global to SymbolTable because they are accessed by SymbolTable. Since Global inherits from SymbolTable this should be a source compatible change. The SymbolLoaders has dependency on `compileLate` method defined in Global. The purpose behind `compileLate` is not clear to me but the dependency looks a little bit dubious. At least we made that dependency explicit. ScaladocGlobal and Global defined in interactive has been adapted in a way that makes them compile both with quick.comp and 2.11.0-M4 so my refactorings are not blocking the modularization effort.
Diffstat (limited to 'src/compiler/scala/tools/nsc/Global.scala')
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala27
1 files changed, 15 insertions, 12 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index d1d5cd1f03..6417a54977 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -51,7 +51,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
class GlobalMirror extends Roots(NoSymbol) {
val universe: self.type = self
- def rootLoader: LazyType = platform.rootLoader
+ def rootLoader: LazyType = new loaders.PackageLoader(classPath)
override def toString = "compiler mirror"
}
@@ -80,10 +80,13 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
// platform specific elements
- type ThisPlatform = Platform { val global: Global.this.type }
+ protected class GlobalPlatform extends {
+ val global: Global.this.type = Global.this
+ val settings: Settings = Global.this.settings
+ } with JavaPlatform
- lazy val platform: ThisPlatform =
- new { val global: Global.this.type = Global.this } with JavaPlatform
+ type ThisPlatform = Platform { val symbolTable: Global.this.type }
+ lazy val platform: ThisPlatform = new GlobalPlatform
type PlatformClassPath = ClassPath[AbstractFile]
type OptClassPath = Option[PlatformClassPath]
@@ -265,12 +268,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
log("!!! " + msg) // such warnings always at least logged
}
- private def elapsedMessage(msg: String, start: Long) =
- msg + " in " + (currentTime - start) + "ms"
-
def informComplete(msg: String): Unit = reporter.withoutTruncating(inform(msg))
- def informProgress(msg: String) = if (settings.verbose) inform("[" + msg + "]")
- def informTime(msg: String, start: Long) = informProgress(elapsedMessage(msg, start))
def logError(msg: String, t: Throwable): Unit = ()
@@ -354,9 +352,11 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
getSourceFile(f)
}
- lazy val loaders = new SymbolLoaders {
- val global: Global.this.type = Global.this
- def lookupMemberAtTyperPhaseIfPossible(sym: Symbol, name: Name): Symbol = {
+ lazy val loaders = new {
+ val symbolTable: Global.this.type = Global.this
+ val platform: Global.this.platform.type = Global.this.platform
+ } with SymbolLoaders {
+ protected override def lookupMemberAtTyperPhaseIfPossible(sym: Symbol, name: Name): Symbol = {
def lookup = sym.info.member(name)
// if loading during initialization of `definitions` typerPhase is not yet set.
// in that case we simply load the member at the current phase
@@ -365,6 +365,9 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
else
enteringTyper { lookup }
}
+ protected override def compileLate(srcfile: AbstractFile): Unit =
+ currentRun.compileLate(srcfile)
+
}
/** Returns the mirror that loaded given symbol */