summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/CompilationUnits.scala8
-rw-r--r--src/compiler/scala/tools/nsc/CompilerRun.scala2
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala659
-rw-r--r--src/compiler/scala/tools/nsc/backend/JavaPlatform.scala5
-rw-r--r--src/compiler/scala/tools/nsc/dependencies/DependencyAnalysis.scala28
-rw-r--r--src/compiler/scala/tools/nsc/settings/ScalaSettings.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala22
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala4
-rw-r--r--src/library/scala/util/Properties.scala1
-rw-r--r--test/files/run/programmatic-main.check51
10 files changed, 434 insertions, 348 deletions
diff --git a/src/compiler/scala/tools/nsc/CompilationUnits.scala b/src/compiler/scala/tools/nsc/CompilationUnits.scala
index 564e4f2705..3c5e033c74 100644
--- a/src/compiler/scala/tools/nsc/CompilationUnits.scala
+++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala
@@ -76,12 +76,12 @@ trait CompilationUnits { self: Global =>
reporter.warning(pos, msg)
def deprecationWarning(pos: Position, msg: String) =
- if (settings.deprecation.value) warning(pos, msg)
- else currentRun.deprecationWarnings = true
+ if (opt.deprecation) warning(pos, msg)
+ else currentRun.deprecationWarnings += 1
def uncheckedWarning(pos: Position, msg: String) =
- if (settings.unchecked.value) warning(pos, msg)
- else currentRun.uncheckedWarnings = true
+ if (opt.unchecked) warning(pos, msg)
+ else currentRun.uncheckedWarnings += 1
def incompleteInputError(pos: Position, msg:String) =
reporter.incompleteInputError(pos, msg)
diff --git a/src/compiler/scala/tools/nsc/CompilerRun.scala b/src/compiler/scala/tools/nsc/CompilerRun.scala
index 9cac12d896..e17ec6fd4c 100644
--- a/src/compiler/scala/tools/nsc/CompilerRun.scala
+++ b/src/compiler/scala/tools/nsc/CompilerRun.scala
@@ -11,7 +11,7 @@ class CompilerRun {
def namerPhase: Phase = NoPhase
def typerPhase: Phase = NoPhase
def refchecksPhase: Phase = NoPhase
- def explicitOuterPhase: Phase = NoPhase
+ def explicitouterPhase: Phase = NoPhase
def erasurePhase: Phase = NoPhase
def flattenPhase: Phase = NoPhase
def mixinPhase: Phase = NoPhase
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 12fbad6adb..60b43a3d17 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -6,13 +6,13 @@
package scala.tools.nsc
import java.io.{ File, FileOutputStream, PrintWriter, IOException, FileNotFoundException }
-import java.nio.charset.{ Charset, IllegalCharsetNameException, UnsupportedCharsetException }
+import java.nio.charset.{ Charset, CharsetDecoder, IllegalCharsetNameException, UnsupportedCharsetException }
import compat.Platform.currentTime
+import scala.collection.{ mutable, immutable }
import io.{ SourceReader, AbstractFile, Path }
import reporters.{ Reporter, ConsoleReporter }
import util.{ ClassPath, SourceFile, Statistics, BatchSourceFile, ScriptSourceFile, returning }
-import collection.mutable.{ HashSet, HashMap, ListBuffer }
import reflect.generic.{ PickleBuffer }
import symtab.{ Flags, SymbolTable, SymbolLoaders }
@@ -38,8 +38,7 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
// alternate constructors ------------------------------------------
def this(reporter: Reporter) =
- this(new Settings(err => reporter.error(null,err)),
- reporter)
+ this(new Settings(err => reporter.error(null, err)), reporter)
def this(settings: Settings) =
this(settings, new ConsoleReporter(settings))
@@ -57,14 +56,6 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
// sub-components --------------------------------------------------
- /** Print tree in detailed form */
- object nodePrinters extends {
- val global: Global.this.type = Global.this
- } with NodePrinters {
- infolevel = InfoLevel.Verbose
- }
- val nodeToString = nodePrinters.nodeToString
-
/** Generate ASTs */
object gen extends {
val global: Global.this.type = Global.this
@@ -83,6 +74,18 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
val global: Global.this.type = Global.this
} with ICodes
+ /** Scala primitives, used in genicode */
+ object scalaPrimitives extends {
+ val global: Global.this.type = Global.this
+ } with ScalaPrimitives
+
+ /** Computing pairs of overriding/overridden symbols */
+ object overridingPairs extends {
+ val global: Global.this.type = Global.this
+ } with OverridingPairs
+
+ // Optimizer components
+
/** ICode analysis for optimization */
object analysis extends {
val global: Global.this.type = Global.this
@@ -93,21 +96,26 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
val global: Global.this.type = Global.this
} with CopyPropagation
+ // Components for collecting and generating output
+
/** Some statistics (normally disabled) set with -Ystatistics */
object statistics extends {
val global: Global.this.type = Global.this
} with Statistics
- /** Computing pairs of overriding/overridden symbols */
- object overridingPairs extends {
+ /** Print tree in detailed form */
+ object nodePrinters extends {
val global: Global.this.type = Global.this
- } with OverridingPairs
+ } with NodePrinters {
+ infolevel = InfoLevel.Verbose
+ }
/** Representing ASTs as graphs */
object treeBrowsers extends {
val global: Global.this.type = Global.this
} with TreeBrowsers
+ val nodeToString = nodePrinters.nodeToString
val treeBrowser = treeBrowsers.create()
// ------------ Hooks for interactive mode-------------------------
@@ -126,96 +134,109 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
// ------------------ Reporting -------------------------------------
- def error(msg: String) = reporter.error(NoPosition, msg)
+ def inform(msg: String) = reporter.info(NoPosition, msg, true)
+ def error(msg: String) = reporter.error(NoPosition, msg)
def warning(msg: String) =
- if (settings.Xwarnfatal.value) reporter.error(NoPosition, msg)
+ if (opt.fatalWarnings) error(msg)
else reporter.warning(NoPosition, msg)
- def inform(msg: String) = reporter.info(NoPosition, msg, true)
- def inform[T](msg: String, value: T): T = { inform(msg+value); value }
-
- //reporter.info(null, msg, true)
-
- def informProgress(msg: String) =
- if (settings.verbose.value) inform("[" + msg + "]")
-
- def informTime(msg: String, start: Long) =
- informProgress(msg + " in " + (currentTime - start) + "ms")
-
- /*@inline final*/ def log(msg: => AnyRef) {
- if (settings.log contains phase.name) inform("[log " + phase + "] " + msg)
- }
- class ThrowableWithPosition(val pos: Int, val error: Throwable) extends Throwable
-
- def tryWith[T](pos: Int, body: => T): T =
- try body
- catch {
- case e : ThrowableWithPosition => throw e
- case te: TypeError => throw te
- case e : RuntimeException => throw new ThrowableWithPosition(pos, e)
- }
-
- def catchWith[T](source : SourceFile, body : => T) : T =
- try body
- catch {
- case e : ThrowableWithPosition =>
- logError("POS: " + source.dbg(e.pos), e)
- throw e.error
- }
+ def informProgress(msg: String) = if (opt.verbose) inform("[" + msg + "]")
+ def inform[T](msg: String, value: T): T = returning(value)(x => inform(msg + x))
+ def informTime(msg: String, start: Long) = informProgress(msg + " in " + (currentTime - start) + "ms")
def logError(msg: String, t: Throwable): Unit = ()
+ def log(msg: => AnyRef): Unit = if (opt.logPhase) inform("[log " + phase + "] " + msg)
// ------------ File interface -----------------------------------------
private val reader: SourceReader = {
- def stdCharset: Charset = {
- settings.encoding.value = Properties.sourceEncoding // A mandatory charset
- Charset.forName(settings.encoding.value)
- }
- val charset =
- try {
- Charset.forName(settings.encoding.value)
- } catch {
+ val defaultEncoding = Properties.sourceEncoding
+ val defaultReader = Properties.sourceReader
+
+ def loadCharset(name: String) =
+ try Some(Charset.forName(name))
+ catch {
case _: IllegalCharsetNameException =>
- error("illegal charset name '" + settings.encoding.value + "'")
- stdCharset
+ error("illegal charset name '" + name + "'")
+ None
case _: UnsupportedCharsetException =>
- error("unsupported charset '" + settings.encoding.value + "'")
- stdCharset
+ error("unsupported charset '" + name + "'")
+ None
}
- try {
- val clazz = Class.forName(settings.sourceReader.value)
- val ccon = clazz.getConstructor(classOf[java.nio.charset.CharsetDecoder], classOf[Reporter])
- ccon.newInstance(charset.newDecoder(), reporter).asInstanceOf[SourceReader]
- //new SourceReader(charset.newDecoder())
- } catch {
- case e =>
- error("exception while trying to instantiate source reader \""+settings.sourceReader.value+"\" ");
- new SourceReader(charset.newDecoder(), reporter)
+
+ val charset = opt.encoding flatMap loadCharset getOrElse {
+ settings.encoding.value = defaultEncoding // A mandatory charset
+ Charset.forName(defaultEncoding)
}
- }
- if (settings.make.value != "all")
- settings.dependenciesFile.value match {
- case "none" => ()
- case x =>
- val depFilePath = Path(x)
- if (depFilePath.exists) {
- /** The directory where file lookup should start */
- val rootPath = depFilePath.parent
- def toFile(path: String) = AbstractFile.getFile(rootPath resolve Path(path))
- dependencyAnalysis.loadFrom(AbstractFile.getFile(depFilePath), toFile)
- }
+ def loadReader(name: String): Option[SourceReader] = {
+ def ccon = Class.forName(name).getConstructor(classOf[CharsetDecoder], classOf[Reporter])
+
+ try Some(ccon.newInstance(charset.newDecoder(), reporter).asInstanceOf[SourceReader])
+ catch { case x =>
+ error("exception while trying to instantiate source reader '" + name + "'")
+ None
+ }
+ }
+
+ opt.sourceReader flatMap loadReader getOrElse {
+ new SourceReader(charset.newDecoder(), reporter)
}
+ }
- if (settings.verbose.value || settings.Ylogcp.value) {
+ if (!dependencyAnalysis.off)
+ dependencyAnalysis.loadDependencyAnalysis()
+
+ if (opt.verbose || opt.logClasspath) {
inform("[search path for source files: " + classPath.sourcepaths.mkString(",") + "]")
inform("[search path for class files: " + classPath.asClasspathString + "]")
}
- /** True if -Xscript has been set, indicating a script run.
- */
- def isScriptRun = settings.script.value != ""
+ /** Taking flag checking to a somewhat higher level. */
+ object opt {
+ // True if the given PhasesSetting includes the current phase.
+ def isActive(ph: Settings#PhasesSetting) = ph contains globalPhase.name
+ def wasActive(ph: Settings#PhasesSetting) = ph contains globalPhase.prev.name
+
+ // Some(value) if setting has been set by user, None otherwise.
+ def optSetting[T](s: Settings#Setting): Option[T] =
+ if (s.isDefault) None else Some(s.value.asInstanceOf[T])
+
+ def showClass = optSetting[String](settings.Xshowcls)
+ def showObject = optSetting[String](settings.Xshowobj)
+ def script = optSetting[String](settings.script)
+ def encoding = optSetting[String](settings.encoding)
+ def sourceReader = optSetting[String](settings.sourceReader)
+
+ def debug = settings.debug.value
+ def deprecation = settings.deprecation.value
+ def fatalWarnings = settings.Xwarnfatal.value
+ def logClasspath = settings.Ylogcp.value
+ def printLate = settings.printLate.value
+ def printStats = settings.Ystatistics.value
+ def showTrees = settings.Xshowtrees.value
+ def target = settings.target.value
+ def typerDebug = settings.Ytyperdebug.value
+ def unchecked = settings.unchecked.value
+ def verbose = settings.verbose.value
+ def writeICode = settings.writeICode.value
+
+ /** Flags as applied to the current or previous phase */
+ def browsePhase = isActive(settings.browse)
+ def logPhase = isActive(settings.log)
+ def printPhase = isActive(settings.Xprint)
+
+ def checkPhase = wasActive(settings.check)
+
+ /** Derived values */
+ def jvm = target startsWith "jvm"
+ def msil = target == "msil"
+ def verboseDebug = debug && verbose
+ def echoFilenames = opt.debug && (opt.verbose || currentRun.size < 5)
+ }
+
+ // True if -Xscript has been set, indicating a script run.
+ def isScriptRun = opt.script.isDefined
def getSourceFile(f: AbstractFile): BatchSourceFile =
if (isScriptRun) ScriptSourceFile(f, reader read f)
@@ -238,8 +259,7 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
val MaxPhases = 64
- val phaseWithId = new Array[Phase](MaxPhases)
- for (i <- List.range(0, MaxPhases)) phaseWithId(i) = NoPhase
+ val phaseWithId: Array[Phase] = Array.fill(MaxPhases)(NoPhase)
abstract class GlobalPhase(prev: Phase) extends Phase(prev) {
phaseWithId(id) = this
@@ -270,7 +290,7 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
}
final def applyPhase(unit: CompilationUnit) {
- if (doEchoFilenames)
+ if (opt.echoFilenames)
inform("[running phase " + name + " on " + unit + "]")
val unit0 = currentRun.currentUnit
@@ -286,6 +306,9 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
}
}
+ /** Switch to turn on detailed type logs */
+ var printTypings = opt.typerDebug
+
// phaseName = "parser"
object syntaxAnalyzer extends {
val global: Global.this.type = Global.this
@@ -293,16 +316,11 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
val runsRightAfter = None
} with SyntaxAnalyzer
- // factory method for
- // phaseName = "namer"
- // phaseName = "parser"
+ // factory for phases: namer, packageobjects, typer
object analyzer extends {
val global: Global.this.type = Global.this
} with Analyzer
- /** Switch to turn on detailed type logs */
- var printTypings = settings.Ytyperdebug.value
-
// phaseName = "superaccessors"
object superAccessors extends {
val global: Global.this.type = Global.this
@@ -334,7 +352,7 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
// phaseName = "uncurry"
object uncurry extends {
val global: Global.this.type = Global.this
- val runsAfter = List[String]("refchecks","liftcode")
+ val runsAfter = List[String]("refchecks", "liftcode")
val runsRightAfter = None
} with UnCurry
@@ -368,8 +386,8 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
// phaseName = "lazyvals"
object lazyVals extends {
- val global: Global.this.type = Global.this
final val FLAGS_PER_WORD = 32
+ val global: Global.this.type = Global.this
val runsAfter = List[String]("erasure")
val runsRightAfter = None
} with LazyVals
@@ -398,7 +416,7 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
// phaseName = "mixin"
object mixer extends {
val global: Global.this.type = Global.this
- val runsAfter = List[String]("flatten","constructors")
+ val runsAfter = List[String]("flatten", "constructors")
val runsRightAfter = None
} with Mixin
@@ -416,13 +434,6 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
val runsRightAfter = None
} with GenICode
- // phaseName = "???"
- object scalaPrimitives extends {
- val global: Global.this.type = Global.this
- val runsAfter = List[String]()
- val runsRightAfter = None
- } with ScalaPrimitives
-
// phaseName = "inliner"
object inliner extends {
val global: Global.this.type = Global.this
@@ -451,6 +462,8 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
val runsRightAfter = None
} with GenJVM
+ // This phase is optional: only added if settings.make option is given.
+ // phaseName = "dependencyAnalysis"
object dependencyAnalysis extends {
val global: Global.this.type = Global.this
val runsAfter = List("jvm")
@@ -461,19 +474,14 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
object terminal extends {
val global: Global.this.type = Global.this
val phaseName = "terminal"
- val runsAfter = List[String]("jvm","msil")
+ val runsAfter = List[String]("jvm", "msil")
val runsRightAfter = None
} with SubComponent {
private var cache: Option[GlobalPhase] = None
+ def reset(): Unit = cache = None
- def newPhase(prev: Phase): GlobalPhase = {
- if (cache.isEmpty) cache = Some(new TerminalPhase(prev))
- cache.get
- }
-
- def reset() {
- cache = None
- }
+ def newPhase(prev: Phase): GlobalPhase =
+ cache getOrElse returning(new TerminalPhase(prev))(x => cache = Some(x))
class TerminalPhase(prev: Phase) extends GlobalPhase(prev) {
def name = "terminal"
@@ -505,40 +513,56 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
object icodeChecker extends icodeCheckers.ICodeChecker()
object typer extends analyzer.Typer(
- analyzer.NoContext.make(EmptyTree, Global.this.definitions.RootClass, new Scope))
+ analyzer.NoContext.make(EmptyTree, Global.this.definitions.RootClass, new Scope)
+ )
- /* Add the internal compiler phases to the phases set
+ /** Add the internal compiler phases to the phases set.
+ * This implementation creates a description map at the same time.
*/
protected def computeInternalPhases() {
- phasesSet += syntaxAnalyzer // The parser
- phasesSet += analyzer.namerFactory // note: types are there because otherwise
- phasesSet += analyzer.packageObjects // consistency check after refchecks would fail.
- phasesSet += analyzer.typerFactory
- phasesSet += superAccessors // add super accessors
- phasesSet += pickler // serialize symbol tables
- phasesSet += refchecks // perform reference and override checking, translate nested objects
- phasesSet += uncurry // uncurry, translate function values to anonymous classes
- phasesSet += tailCalls // replace tail calls by jumps
- phasesSet += specializeTypes
- phasesSet += explicitOuter // replace C.this by explicit outer pointers, eliminate pattern matching
- phasesSet += erasure // erase types, add interfaces for traits
- phasesSet += lazyVals
- phasesSet += lambdaLift // move nested functions to top level
- phasesSet += constructors // move field definitions into constructors
- phasesSet += mixer // do mixin composition
- phasesSet += cleanup // some platform-specific cleanups
- phasesSet += genicode // generate portable intermediate code
- phasesSet += inliner // optimization: do inlining
- phasesSet += closureElimination // optimization: get rid of uncalled closures
- phasesSet += deadCode // optimization: get rid of dead cpde
- phasesSet += terminal // The last phase in the compiler chain
+ // Note: this fits -Xshow-phases into 80 column width, which it is
+ // desirable to preserve.
+ val phs = List(
+ syntaxAnalyzer -> "parse source into ASTs, perform simple desugaring",
+ analyzer.namerFactory -> "resolve names, attach symbols to named trees",
+ analyzer.packageObjects -> "load package objects",
+ analyzer.typerFactory -> "the meat and potatoes: type the trees",
+ superAccessors -> "add super accessors in traits and nested classes",
+ pickler -> "serialize symbol tables",
+ refchecks -> "reference and override checking, translate nested objects",
+ uncurry -> "uncurry, translate function values to anonymous classes",
+ tailCalls -> "replace tail calls by jumps",
+ specializeTypes -> "@specialized-driven class and method specialization",
+ explicitOuter -> "C.this refs become outer pointers, translate pattern matches",
+ erasure -> "erase types, add interfaces for traits",
+ lazyVals -> "allocate bitmaps, translate lazy vals into lazified defs",
+ lambdaLift -> "move nested functions to top level",
+ constructors -> "move field definitions into constructors",
+ mixer -> "mixin composition",
+ cleanup -> "platform-specific cleanups, generate reflective calls",
+ genicode -> "generate portable intermediate code",
+ inliner -> "optimization: do inlining",
+ closureElimination -> "optimization: eliminate uncalled closures",
+ deadCode -> "optimization: eliminate dead code",
+ terminal -> "The last phase in the compiler chain"
+ )
+
+ phs foreach (addToPhasesSet _).tupled
+ }
+ // This is slightly inelegant but it avoids adding a new member to SubComponent,
+ // and attractive -Xshow-phases output is unlikely if the descs span 20 files anyway.
+ private val otherPhaseDescriptions = Map(
+ "flatten" -> "eliminate inner classes",
+ "liftcode" -> "reify trees",
+ "jvm" -> "generate JVM bytecode"
+ ) withDefaultValue ""
+
+ protected def computePlatformPhases() = platform.platformPhases foreach { sub =>
+ addToPhasesSet(sub, otherPhaseDescriptions(sub.phaseName))
}
- protected def computePlatformPhases() = platform.platformPhases foreach (phasesSet += _)
-
- /* Helper method for sequncing the phase assembly
- */
- private def computePhaseDescriptors: List[SubComponent] = {
+ // sequences the phase assembly
+ protected def computePhaseDescriptors: List[SubComponent] = {
computeInternalPhases() // Global.scala
computePlatformPhases() // backend/Platform.scala
computePluginPhases() // plugins/Plugins.scala
@@ -549,7 +573,12 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
lazy val phaseDescriptors: List[SubComponent] = computePhaseDescriptors
/* The set of phase objects that is the basis for the compiler phase chain */
- protected val phasesSet : HashSet[SubComponent] = new HashSet[SubComponent]
+ protected val phasesSet = new mutable.HashSet[SubComponent]
+ protected val phasesDescMap = new mutable.HashMap[SubComponent, String] withDefaultValue ""
+ protected def addToPhasesSet(sub: SubComponent, descr: String) {
+ phasesSet += sub
+ phasesDescMap(sub) = descr
+ }
/** The names of the phases. */
lazy val phaseNames = {
@@ -558,8 +587,12 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
}
/** A description of the phases that will run */
- def phaseDescriptions: String =
- phaseNames mkString "\n" // todo: + " - " + phase.description
+ def phaseDescriptions: String = {
+ val width = phaseNames map (_.length) max
+ val fmt = "%" + width + "s %s\n"
+
+ phaseDescriptors map (ph => fmt.format(ph.phaseName, phasesDescMap(ph))) mkString
+ }
// ----------- Runs ---------------------------------------
@@ -574,51 +607,55 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
*/
override def currentRunId = curRunId
- def currentRunSize = currentRun.unitbufSize
- def doEchoFilenames = settings.debug.value && (settings.verbose.value || currentRunSize < 5)
def echoPhaseSummary(ph: Phase) = {
/** Only output a summary message under debug if we aren't echoing each file. */
- if (settings.debug.value && !doEchoFilenames)
- inform("[running phase " + ph.name + " on " + currentRunSize + " compilation units]")
+ if (opt.debug && !opt.echoFilenames)
+ inform("[running phase " + ph.name + " on " + currentRun.size + " compilation units]")
}
/** A Run is a single execution of the compiler on a sets of units
*/
class Run {
-
var isDefined = false
+ /** To be initialized from firstPhase. */
+ private var terminalPhase: Phase = NoPhase
+
+ /** Whether compilation should stop at or skip the phase with given name. */
+ protected def stopPhase(name: String) = settings.stop contains name
+ protected def skipPhase(name: String) = settings.skip contains name
+ /** As definitions.init requires phase != NoPhase, and calling phaseDescriptors.head
+ * will force init, there is some jockeying herein regarding init order: instead of
+ * taking the head descriptor we create a parser phase directly.
+ */
private val firstPhase = {
- // ----------- Initialization code -------------------------
+ /** Initialization. */
curRunId += 1
- assert(curRunId > 0)
curRun = this
- //Console.println("starting run: " + id)
-
- // Can not take the phaseDescriptors.head even though its the syntaxAnalyzer, this will implicitly
- // call definitions.init which uses phase and needs it to be != NoPhase
- val phase1 = syntaxAnalyzer.newPhase(NoPhase)
- phase = phase1
- definitions.init // needs phase to be defined != NoPhase,
- // that's why it is placed here.
- // The first phase in the compiler phase chain
- var p: Phase = phase1
+ /** Set phase to a newly created syntaxAnalyzer and call definitions.init. */
+ val parserPhase: Phase = syntaxAnalyzer.newPhase(NoPhase)
+ phase = parserPhase
+ definitions.init
- // Reset the cache in terminal, the chain could have been build before where nobody used it
- // This happens in the interpreter
+ // Flush the cache in the terminal phase: the chain could have been built
+ // before without being used. (This happens in the interpreter.)
terminal.reset
- // Each subcomponent is asked to deliver a newPhase that is chained together. If -Ystop:phasename is
- // given at command-line, this will stop with that phasename
- for (pd <- phaseDescriptors.tail.takeWhile(pd => !(stopPhase(pd.phaseName))))
- if (!(settings.skip contains pd.phaseName)) p = pd.newPhase(p)
+ // Each subcomponent supplies a phase, which are chained together.
+ // If -Ystop:phase is given, neither that phase nor any beyond it is added.
+ // If -Yskip:phase is given, that phase will be skipped.
+ val lastPhase = phaseDescriptors.tail .
+ takeWhile (pd => !stopPhase(pd.phaseName)) .
+ filterNot (pd => skipPhase(pd.phaseName)) .
+ foldLeft (parserPhase) ((chain, ph) => ph newPhase chain)
- // Ensure there is a terminal phase at the end, Normally there will then be two terminal phases at the end
- // if -Ystop:phasename was given, this makes sure that there is a terminal phase at the end
- p = terminal.newPhase(p)
+ // Ensure there is a terminal phase at the end, since -Ystop may have limited the phases.
+ terminalPhase =
+ if (lastPhase.name == "terminal") lastPhase
+ else terminal newPhase lastPhase
- phase1
+ parserPhase
}
// --------------- Miscellania -------------------------------
@@ -626,19 +663,18 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
/** The currently compiled unit; set from GlobalPhase */
var currentUnit: CompilationUnit = _
- /** Flags indicating whether deprecation warnings occurred */
- var deprecationWarnings: Boolean = false
- var uncheckedWarnings: Boolean = false
-
- def cancel { reporter.cancelled = true }
-
- // ------------------ Progress tracking -------------------------
+ /** Counts for certain classes of warnings during this run. */
+ var deprecationWarnings: Int = 0
+ var uncheckedWarnings: Int = 0
+ /** Progress tracking. Measured in "progress units" which are 1 per
+ * compilation unit per phase completed.
+ *
+ * @param current number of "progress units" completed
+ * @param total total number of "progress units" in run
+ */
def progress(current: Int, total: Int) {}
- private var phasec: Int = 0
- private var unitc: Int = 0
-
/** take note that phase is completed
* (for progress reporting)
*/
@@ -654,10 +690,14 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
unitc += 1
refreshProgress
}
- private def refreshProgress =
- if (compiledFiles.size > 0)
- progress((phasec * compiledFiles.size) + unitc,
- (phaseDescriptors.length-1) * compiledFiles.size) // terminal phase not part of the progress display
+
+ def cancel { reporter.cancelled = true }
+
+ private var phasec: Int = 0 // phases completed
+ private var unitc: Int = 0 // units completed this phase
+ private def currentProgress = (phasec * size) + unitc
+ private def totalProgress = (phaseDescriptors.size - 1) * size // -1: drops terminal phase
+ private def refreshProgress = if (size > 0) progress(currentProgress, totalProgress)
// ----- finding phases --------------------------------------------
@@ -667,34 +707,40 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
if (p.name != name) NoPhase else p
}
- val namerPhase = phaseNamed("namer")
- val typerPhase = phaseNamed("typer")
- val picklerPhase = phaseNamed("pickler")
- val refchecksPhase = phaseNamed("refchecks")
- val uncurryPhase = phaseNamed("uncurry")
-
- val explicitOuterPhase = phaseNamed("explicitouter")
- val erasurePhase = phaseNamed("erasure")
- val flattenPhase = phaseNamed("flatten")
- val mixinPhase = phaseNamed("mixin")
- val icodePhase = phaseNamed("icode")
+ val parserPhase = phaseNamed("parser")
+ val namerPhase = phaseNamed("namer")
+ // packageobjects
+ val typerPhase = phaseNamed("typer")
+ // superaccessors
+ val picklerPhase = phaseNamed("pickler")
+ val refchecksPhase = phaseNamed("refchecks")
+ val uncurryPhase = phaseNamed("uncurry")
+ // tailcalls, specialize
+ val explicitouterPhase = phaseNamed("explicitouter")
+ val erasurePhase = phaseNamed("erasure")
+ // lazyvals, lambdalift, constructors
+ val flattenPhase = phaseNamed("flatten")
+ val mixinPhase = phaseNamed("mixin")
+ val cleanupPhase = phaseNamed("cleanup")
+ val icodePhase = phaseNamed("icode")
+ // inliner, closelim, dce
+ val jvmPhase = phaseNamed("jvm")
+
+ def runIsAt(ph: Phase) = globalPhase.id == ph.id
+ def runIsPast(ph: Phase) = globalPhase.id > ph.id
isDefined = true
- /** A test whether compilation should stop at phase with given name */
- protected def stopPhase(name : String) = settings.stop.contains(name)
-
// ----------- Units and top-level classes and objects --------
- private var unitbuf = new ListBuffer[CompilationUnit]
- var compiledFiles = new HashSet[String]
+ private val unitbuf = new mutable.ListBuffer[CompilationUnit]
+ val compiledFiles = new mutable.HashSet[String]
private var _unitbufSize = 0
- def unitbufSize = _unitbufSize
+ def size = _unitbufSize
/** add unit to be compiled in this run */
private def addUnit(unit: CompilationUnit) {
-// unit.parseSettings()
unitbuf += unit
_unitbufSize += 1 // counting as they're added so size is cheap
compiledFiles += unit.source.file.path
@@ -704,10 +750,10 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
def units: Iterator[CompilationUnit] = unitbuf.iterator
/** A map from compiled top-level symbols to their source files */
- val symSource = new HashMap[Symbol, AbstractFile]
+ val symSource = new mutable.HashMap[Symbol, AbstractFile]
/** A map from compiled top-level symbols to their picklers */
- val symData = new HashMap[Symbol, PickleBuffer]
+ val symData = new mutable.HashMap[Symbol, PickleBuffer]
/** does this run compile given class, module, or case factory? */
def compiles(sym: Symbol): Boolean =
@@ -725,85 +771,92 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
// --------------- Compilation methods ----------------------------
+ protected def runCheckers() {
+ val toCheck = globalPhase.prev
+ val canCheck = toCheck.checkable
+ val fmt = if (canCheck) "[Now checking: %s]" else "[Not checkable: %s]"
+
+ inform(fmt format toCheck.name)
+
+ if (canCheck) {
+ phase = globalPhase
+ if (globalPhase.id >= icodePhase.id) icodeChecker.checkICodes
+ else treeChecker.checkTrees
+ }
+ }
+
/** Compile list of source files */
def compileSources(_sources: List[SourceFile]) {
- val depSources = dependencyAnalysis.filter(_sources.distinct) // bug #1268, scalac confused by duplicated filenames
- val sources = coreClassesFirst(depSources)
+ val depSources = dependencyAnalysis.calculateFiles(_sources.distinct) // bug #1268, scalac confused by duplicated filenames
+ val sources = coreClassesFirst(depSources)
if (reporter.hasErrors) // there is a problem already, e.g. a plugin was passed a bad option
return
+
val startTime = currentTime
reporter.reset
for (source <- sources) addUnit(new CompilationUnit(source))
globalPhase = firstPhase
- while (globalPhase != terminal.newPhase(NoPhase) && !reporter.hasErrors) {
+ while (globalPhase != terminalPhase && !reporter.hasErrors) {
val startTime = currentTime
phase = globalPhase
globalPhase.run
- if (settings.Xprint contains globalPhase.name)
- if (settings.writeICode.value && globalPhase.id >= icodePhase.id) writeICode()
- else if (settings.Xshowtrees.value) nodePrinters.printAll()
+
+ // write icode to *.icode files
+ if (opt.writeICode && (runIsAt(icodePhase) || opt.printPhase && runIsPast(icodePhase)))
+ writeICode()
+
+ // print trees
+ if (opt.printPhase || opt.printLate && runIsAt(cleanupPhase))
+ if (opt.showTrees) nodePrinters.printAll()
else printAllUnits()
- if (settings.printLate.value && globalPhase.name == "cleanup")
- printAllUnits()
- if (settings.browse contains globalPhase.name) treeBrowser.browse(units)
+ // browse trees with swing tree viewer
+ if (opt.browsePhase)
+ treeBrowser browse units
+
+ // progress update
informTime(globalPhase.description, startTime)
globalPhase = globalPhase.next
- if (settings.check contains globalPhase.prev.name) {
- if (globalPhase.prev.checkable) {
- phase = globalPhase
- inform("[Now checking: " + phase.prev.name + "]")
- if (globalPhase.id >= icodePhase.id) icodeChecker.checkICodes
- else treeChecker.checkTrees
- }
- else inform("[Not checkable: " + globalPhase.prev.name + "]")
- }
- if (settings.Ystatistics.value) statistics.print(phase)
+ // run tree/icode checkers
+ if (opt.checkPhase)
+ runCheckers()
+
+ // output collected statistics
+ if (opt.printStats)
+ statistics.print(phase)
+
advancePhase
}
- //println(narrowCount+" narrowings")
-
- if (settings.Xshowcls.value != "")
- showDef(newTermName(settings.Xshowcls.value), false)
- if (settings.Xshowobj.value != "")
- showDef(newTermName(settings.Xshowobj.value), true)
+ // print class and object definitions
+ opt.showClass foreach (x => showDef(newTypeName(x)))
+ opt.showObject foreach (x => showDef(newTermName(x)))
if (reporter.hasErrors) {
for ((sym, file) <- symSource.iterator) {
sym.reset(new loaders.SourcefileLoader(file))
- if (sym.isTerm) sym.moduleClass.reset(loaders.moduleClassLoader)
+ if (sym.isTerm)
+ sym.moduleClass reset loaders.moduleClassLoader
}
}
else {
- if (deprecationWarnings) {
- warning("there were deprecation warnings; re-run with " + settings.deprecation.name + " for details")
- }
- if (uncheckedWarnings) {
- warning("there were unchecked warnings; re-run with " + settings.unchecked.name + " for details")
- }
+ def warn(count: Int, what: String, option: Settings#BooleanSetting) = (
+ if (option.isDefault && count > 0)
+ warning("there were %d %s warnings; re-run with %s for details".format(count, what, option.name))
+ )
+ warn(deprecationWarnings, "deprecation", settings.deprecation)
+ warn(uncheckedWarnings, "unchecked", settings.unchecked)
+ // todo: migrationWarnings
}
+
symSource.keys foreach (x => resetPackageClass(x.owner))
informTime("total", startTime)
- if (!dependencyAnalysis.off) {
- settings.dependenciesFile.value match {
- case "none" =>
- case x =>
- val depFilePath = Path(x)
- if (!depFilePath.exists)
- dependencyAnalysis.dependenciesFile = AbstractFile.getFile(depFilePath.createFile())
-
- /** The directory where file lookup should start */
- val rootPath = depFilePath.parent.normalize
- def fromFile(file: AbstractFile): String =
- rootPath.relativize(Path(file.file).normalize).path
-
- dependencyAnalysis.saveDependencies(fromFile)
- }
- }
+ // record dependency data
+ if (!dependencyAnalysis.off)
+ dependencyAnalysis.saveDependencyAnalysis()
}
/** Compile list of abstract files */
@@ -828,31 +881,28 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
* to phase "namer".
*/
def compileLate(file: AbstractFile) {
- if (compiledFiles eq null) {
- val msg = "No class file for " + file + " was found\n(This file cannot be loaded as a source file)"
- inform(msg)
- throw new FatalError(msg)
- }
- else if (!(compiledFiles contains file.path)) {
+ if (!compiledFiles(file.path))
compileLate(new CompilationUnit(getSourceFile(file)))
- }
}
- /** Compile abstract file until `globalPhase`, but at least
- * to phase "namer".
+ /** Compile abstract file until `globalPhase`, but at least to phase "namer".
*/
def compileLate(unit: CompilationUnit) {
- addUnit(unit)
- var localPhase = firstPhase.asInstanceOf[GlobalPhase]
- while (localPhase != null && (localPhase.id < globalPhase.id || localPhase.id < typerPhase.id)/* && !reporter.hasErrors*/) {
- val oldSource = reporter.getSource
- reporter.withSource(unit.source) {
- atPhase(localPhase)(localPhase.applyPhase(unit))
+ def stop(ph: Phase) = ph == null || ph.id >= (globalPhase.id max typerPhase.id)
+ def loop(ph: Phase) {
+ if (stop(ph)) refreshProgress
+ else {
+ reporter.withSource(unit.source) {
+ atPhase(ph)(ph.asInstanceOf[GlobalPhase] applyPhase unit)
+ }
+ loop(ph.next match {
+ case `ph` => null // ph == ph.next implies terminal, and null ends processing
+ case x => x
+ })
}
- val newLocalPhase = localPhase.next.asInstanceOf[GlobalPhase]
- localPhase = if (localPhase == newLocalPhase) null else newLocalPhase
}
- refreshProgress
+ addUnit(unit)
+ loop(firstPhase)
}
/**
@@ -920,40 +970,43 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
def printAllUnits() {
print("[[syntax trees at end of " + phase + "]]")
- atPhase(phase.next) { currentRun.units foreach (treePrinter print _) }
+ atPhase(phase.next) { currentRun.units foreach treePrinter.print }
}
- def showDef(name: Name, module: Boolean) {
- def getSym(name: Name, module: Boolean): Symbol = {
- var i = name.length - 1
- while (i != 0 && name(i) != '#' && name(i) != '.') i -= 1
- if (i == 0)
- definitions.getModule(name)
- else {
- val root = getSym(name.subName(0, i), name(i) == '.')
- var selector = name.subName(i+1, name.length)
- if (module) selector = selector.toTypeName
- root.info.member(selector)
- }
+ def showDef(name: Name) {
+ val segments = name.toString split '.'
+ val container = segments.init.foldLeft(definitions.RootClass: Symbol)(_.info member _)
+ val target = if (name.isTypeName) newTypeName(segments.last) else newTermName(segments.last)
+
+ // If the name as given resolves to an existing symbol, show that.
+ // Otherwise we'll show every symbol in the current run with a matching name.
+ val syms = (container.info member target) match {
+ case NoSymbol => currentRun.symSource.keys filter (_.name == name) toList
+ case sym => List(sym)
+ }
+
+ syms foreach { sym =>
+ val name = "\n<<-- " + sym.kindString + " " + sym.fullName + " -->>\n"
+ val baseClasses = sym.info.baseClasses map (_.fullName) mkString ("Base classes:\n ", "\n ", "\n")
+ val members = atPhase(currentRun.typerPhase.next)(sym.info.members map (_.defString))
+ val memberStr = members.mkString("Members after phase typer:\n ", "\n ", "\n")
+
+ inform(List(name, baseClasses, memberStr) mkString "\n")
}
- val sym = getSym(name, module)
- inform("" + sym.name + ":" +(if (module) sym.tpe.typeSymbol.info else sym.info))
}
/** Returns the file with the given suffix for the given class. Used for icode writing. */
def getFile(clazz: Symbol, suffix: String): File = {
- val outdirname = settings.outputDirs.outputDirFor(clazz.sourceFile)
- var outdir = new File(if (outdirname.path == "") "." else outdirname.path)
- val filename = clazz.fullName
- var start = 0
- var end = filename.indexOf('.', start)
- while (end >= start) {
- outdir = new File(outdir, filename.substring(start, end))
- if (!outdir.exists()) outdir.mkdir()
- start = end + 1
- end = filename.indexOf('.', start)
- }
- new File(outdir, filename.substring(start) + suffix)
+ val outDir = Path(
+ settings.outputDirs.outputDirFor(clazz.sourceFile).path match {
+ case "" => "."
+ case path => path
+ }
+ )
+ val segments = clazz.fullName split '.'
+ val dir = segments.init.foldLeft(outDir)(_ / _).createDirectory()
+
+ new File(dir.path, segments.last + suffix)
}
private def writeICode() {
@@ -970,14 +1023,14 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
informProgress("wrote " + file)
} catch {
case ex: IOException =>
- if (settings.debug.value) ex.printStackTrace()
+ if (opt.debug) ex.printStackTrace()
error("could not write file " + file)
}
})
}
- def forJVM : Boolean = settings.target.value startsWith "jvm"
- def forMSIL: Boolean = settings.target.value == "msil"
+ def forJVM = opt.jvm
+ def forMSIL = opt.msil
def onlyPresentation = false
- def createJavadoc = false
+ def createJavadoc = false
}
diff --git a/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala b/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala
index c4365a82ac..ec367b61bb 100644
--- a/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala
+++ b/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala
@@ -18,7 +18,10 @@ trait JavaPlatform extends Platform[AbstractFile] {
lazy val classPath = new PathResolver(settings).result
def rootLoader = new loaders.JavaPackageLoader(classPath)
- private def depAnalysisPhase = if (settings.make.value != "all") List(dependencyAnalysis) else Nil
+ private def depAnalysisPhase =
+ if (settings.make.isDefault) Nil
+ else List(dependencyAnalysis)
+
def platformPhases = List(
flatten, // get rid of inner classes
liftcode, // generate reified trees
diff --git a/src/compiler/scala/tools/nsc/dependencies/DependencyAnalysis.scala b/src/compiler/scala/tools/nsc/dependencies/DependencyAnalysis.scala
index 30acdff594..e9cc191167 100644
--- a/src/compiler/scala/tools/nsc/dependencies/DependencyAnalysis.scala
+++ b/src/compiler/scala/tools/nsc/dependencies/DependencyAnalysis.scala
@@ -1,7 +1,8 @@
package scala.tools.nsc
package dependencies
+
import util.SourceFile
-import io.AbstractFile
+import io.{ AbstractFile, Path }
import collection._
import symtab.Flags
@@ -10,18 +11,35 @@ trait DependencyAnalysis extends SubComponent with Files {
val phaseName = "dependencyAnalysis"
- def off = settings.make.value == "all"
+ def off = settings.make.isDefault
+ def shouldCheckClasspath = settings.make.value != "transitivenocp"
def newPhase(prev: Phase) = new AnalysisPhase(prev)
+ private def depPath = Path(settings.dependenciesFile.value)
+ def loadDependencyAnalysis(): Boolean = (
+ depPath.path != "none" && depPath.isFile && loadFrom(
+ AbstractFile.getFile(depPath),
+ path => AbstractFile.getFile(depPath.parent resolve Path(path))
+ )
+ )
+ def saveDependencyAnalysis(): Unit = {
+ if (!depPath.exists)
+ dependenciesFile = AbstractFile.getFile(depPath.createFile())
+
+ /** The directory where file lookup should start */
+ val rootPath = depPath.parent.normalize
+ saveDependencies(
+ file => rootPath.relativize(Path(file.file).normalize).path
+ )
+ }
+
lazy val maxDepth = settings.make.value match {
case "changed" => 0
case "transitive" | "transitivenocp" => Int.MaxValue
case "immediate" => 1
}
- def shouldCheckClasspath = settings.make.value != "transitivenocp"
-
// todo: order insensible checking and, also checking timestamp?
def validateClasspath(cp1: String, cp2: String): Boolean = cp1 == cp2
@@ -87,7 +105,7 @@ trait DependencyAnalysis extends SubComponent with Files {
}
}
- def filter(files: List[SourceFile]): List[SourceFile] =
+ def calculateFiles(files: List[SourceFile]): List[SourceFile] =
if (off) files
else if (dependencies.isEmpty) {
println("No known dependencies. Compiling " +
diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
index 71b4f6d7bd..7156da076f 100644
--- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
@@ -77,7 +77,7 @@ trait ScalaSettings extends AbsScalaSettings with StandardScalaSettings {
val Xshowcls = StringSetting ("-Xshow-class", "class", "Show class info", "")
val Xshowobj = StringSetting ("-Xshow-object", "object", "Show object info", "")
val showPhases = BooleanSetting ("-Xshow-phases", "Print a synopsis of compiler phases")
- val sourceReader = StringSetting ("-Xsource-reader", "classname", "Specify a custom method for reading source files", "scala.tools.nsc.io.SourceReader")
+ val sourceReader = StringSetting ("-Xsource-reader", "classname", "Specify a custom method for reading source files", "")
val Xwarnfatal = BooleanSetting ("-Xfatal-warnings", "Fail the compilation if there are any warnings.")
val Xwarninit = BooleanSetting ("-Xwarninit", "Warn about possible changes in initialization semantics")
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
index 6fab87e9f6..2acfbaf098 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
@@ -1093,22 +1093,32 @@ abstract class Pickler extends SubComponent {
writeNat(MajorVersion)
writeNat(MinorVersion)
writeNat(ep)
- if (showSig) {
- println("Pickled info for "+rootName+" V"+MajorVersion+"."+MinorVersion)
- }
+ def matchesRoot(name: String) = (
+ rootName.toString == (
+ if (name contains '.') name.split('.').last
+ else name
+ )
+ )
+ val showClass = opt.showClass exists matchesRoot
+ def versionString = "V" + MajorVersion + "." + MinorVersion
+
+ if (showSig)
+ println("Pickled info for " + rootName + " in " + rootOwner.fullName + " " + versionString)
+
for (i <- 0 until ep) {
- if (showSig/* || rootName.toString == "StaticCompletion"*/) {
+ if (showSig) {
print((i formatted "%3d: ")+(writeIndex formatted "%5d: "))
printEntry(entries(i))
}
writeEntry(entries(i))
}
- if (settings.Xshowcls.value == rootName.toString) {
+
+ if (showClass) {
readIndex = 0
ShowPickled.printFile(this, Console.out)
}
}
- override def toString() = "" + rootName + " in " + rootOwner
+ override def toString = "" + rootName + " in " + rootOwner
}
}
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 9a436d86a3..906297a4b8 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -809,7 +809,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
val bridgesScope = new Scope
val bridgeTarget = new mutable.HashMap[Symbol, Symbol]
var bridges: List[Tree] = List()
- val opc = atPhase(currentRun.explicitOuterPhase) {
+ val opc = atPhase(currentRun.explicitouterPhase) {
new overridingPairs.Cursor(owner) {
override def parents: List[Type] = List(owner.info.parents.head)
override def exclude(sym: Symbol): Boolean =
@@ -820,7 +820,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
val member = opc.overriding
val other = opc.overridden
//Console.println("bridge? " + member + ":" + member.tpe + member.locationString + " to " + other + ":" + other.tpe + other.locationString);//DEBUG
- if (atPhase(currentRun.explicitOuterPhase)(!member.isDeferred)) {
+ if (atPhase(currentRun.explicitouterPhase)(!member.isDeferred)) {
val otpe = erasure(other.tpe);
val bridgeNeeded = atPhase(phase.next) (
!(other.tpe =:= member.tpe) &&
diff --git a/src/library/scala/util/Properties.scala b/src/library/scala/util/Properties.scala
index e4da90ee28..202fd63ef9 100644
--- a/src/library/scala/util/Properties.scala
+++ b/src/library/scala/util/Properties.scala
@@ -69,6 +69,7 @@ private[scala] trait PropertiesTrait
* Note that it uses "prop" i.e. looks in the scala jar, not the system properties.
*/
def sourceEncoding = scalaPropOrElse("file.encoding", "UTF-8")
+ def sourceReader = scalaPropOrElse("source.reader", "scala.tools.nsc.io.SourceReader")
/** This is the default text encoding, overridden (unreliably) with
* JAVA_OPTS="-Dfile.encoding=Foo"
diff --git a/test/files/run/programmatic-main.check b/test/files/run/programmatic-main.check
index e6c83a6f48..6cf6fa8ca6 100644
--- a/test/files/run/programmatic-main.check
+++ b/test/files/run/programmatic-main.check
@@ -1,25 +1,26 @@
-parser
-namer
-packageobjects
-typer
-superaccessors
-pickler
-refchecks
-liftcode
-uncurry
-tailcalls
-specialize
-explicitouter
-erasure
-lazyvals
-lambdalift
-constructors
-flatten
-mixin
-cleanup
-icode
-inliner
-closelim
-dce
-jvm
-terminal
+ parser parse source into ASTs, perform simple desugaring
+ namer resolve names, attach symbols to named trees
+packageobjects load package objects
+ typer the meat and potatoes: type the trees
+superaccessors add super accessors in traits and nested classes
+ pickler serialize symbol tables
+ refchecks reference and override checking, translate nested objects
+ liftcode reify trees
+ uncurry uncurry, translate function values to anonymous classes
+ tailcalls replace tail calls by jumps
+ specialize @specialized-driven class and method specialization
+ explicitouter C.this refs become outer pointers, translate pattern matches
+ erasure erase types, add interfaces for traits
+ lazyvals allocate bitmaps, translate lazy vals into lazified defs
+ lambdalift move nested functions to top level
+ constructors move field definitions into constructors
+ flatten eliminate inner classes
+ mixin mixin composition
+ cleanup platform-specific cleanups, generate reflective calls
+ icode generate portable intermediate code
+ inliner optimization: do inlining
+ closelim optimization: eliminate uncalled closures
+ dce optimization: eliminate dead code
+ jvm generate JVM bytecode
+ terminal The last phase in the compiler chain
+