summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/Global.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/tools/nsc/Global.scala')
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala426
1 files changed, 149 insertions, 277 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index a618b080c8..7417d9c09d 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -7,17 +7,17 @@ package scala
package tools
package nsc
-import java.io.{ File, FileOutputStream, PrintWriter, IOException, FileNotFoundException }
+import java.io.{File, FileNotFoundException, IOException}
import java.net.URL
-import java.nio.charset.{ Charset, CharsetDecoder, IllegalCharsetNameException, UnsupportedCharsetException }
-import scala.collection.{ mutable, immutable }
-import io.{ SourceReader, AbstractFile, Path }
-import reporters.{ Reporter, ConsoleReporter }
-import util.{ ClassFileLookup, ClassPath, MergedClassPath, StatisticsInfo, returning }
+import java.nio.charset.{Charset, CharsetDecoder, IllegalCharsetNameException, UnsupportedCharsetException}
+import scala.collection.{immutable, mutable}
+import io.{AbstractFile, Path, SourceReader}
+import reporters.Reporter
+import util.{ClassPath, StatisticsInfo, returning}
import scala.reflect.ClassTag
-import scala.reflect.internal.util.{ SourceFile, NoSourceFile, BatchSourceFile, ScriptSourceFile }
+import scala.reflect.internal.util.{BatchSourceFile, NoSourceFile, ScalaClassLoader, ScriptSourceFile, SourceFile}
import scala.reflect.internal.pickling.PickleBuffer
-import symtab.{ Flags, SymbolTable, SymbolTrackers }
+import symtab.{Flags, SymbolTable, SymbolTrackers}
import symtab.classfile.Pickler
import plugins.Plugins
import ast._
@@ -25,16 +25,11 @@ import ast.parser._
import typechecker._
import transform.patmat.PatternMatching
import transform._
-import backend.icode.{ ICodes, GenICode, ICodeCheckers }
-import backend.{ ScalaPrimitives, JavaPlatform }
+import backend.{JavaPlatform, ScalaPrimitives}
import backend.jvm.GenBCode
-import backend.jvm.GenASM
-import backend.opt.{ Inliners, InlineExceptionHandlers, ConstantOptimization, ClosureElimination, DeadCodeElimination }
-import backend.icode.analysis._
import scala.language.postfixOps
import scala.tools.nsc.ast.{TreeGen => AstTreeGen}
-import scala.tools.nsc.classpath.FlatClassPath
-import scala.tools.nsc.settings.ClassPathRepresentationType
+import scala.tools.nsc.classpath._
class Global(var currentSettings: Settings, var reporter: Reporter)
extends SymbolTable
@@ -58,12 +53,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
class GlobalMirror extends Roots(NoSymbol) {
val universe: self.type = self
- def rootLoader: LazyType = {
- settings.YclasspathImpl.value match {
- case ClassPathRepresentationType.Flat => new loaders.PackageLoaderUsingFlatClassPath(FlatClassPath.RootPackage, flatClassPath)
- case ClassPathRepresentationType.Recursive => new loaders.PackageLoader(recursiveClassPath)
- }
- }
+ def rootLoader: LazyType = new loaders.PackageLoader(ClassPath.RootPackage, classPath)
override def toString = "compiler mirror"
}
implicit val MirrorTag: ClassTag[Mirror] = ClassTag[Mirror](classOf[GlobalMirror])
@@ -90,7 +80,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
this(new Settings(err => reporter.error(null, err)), reporter)
def this(settings: Settings) =
- this(settings, new ConsoleReporter(settings))
+ this(settings, Global.reporter(settings))
def picklerPhase: Phase = if (currentRun.isDefined) currentRun.picklerPhase else NoPhase
@@ -106,17 +96,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
type ThisPlatform = JavaPlatform { val global: Global.this.type }
lazy val platform: ThisPlatform = new GlobalPlatform
- type PlatformClassPath = ClassPath[AbstractFile]
- type OptClassPath = Option[PlatformClassPath]
-
- def classPath: ClassFileLookup[AbstractFile] = settings.YclasspathImpl.value match {
- case ClassPathRepresentationType.Flat => flatClassPath
- case ClassPathRepresentationType.Recursive => recursiveClassPath
- }
-
- private def recursiveClassPath: ClassPath[AbstractFile] = platform.classPath
-
- private def flatClassPath: FlatClassPath = platform.flatClassPath
+ def classPath: ClassPath = platform.classPath
// sub-components --------------------------------------------------
@@ -140,12 +120,12 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
val global: Global.this.type = Global.this
} with ConstantFolder
- /** ICode generator */
- object icodes extends {
- val global: Global.this.type = Global.this
- } with ICodes
+ /** For sbt compatibility (https://github.com/scala/scala/pull/4588) */
+ object icodes {
+ class IClass(val symbol: Symbol)
+ }
- /** Scala primitives, used in genicode */
+ /** Scala primitives, used the backend */
object scalaPrimitives extends {
val global: Global.this.type = Global.this
} with ScalaPrimitives
@@ -157,18 +137,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
type SymbolPair = overridingPairs.SymbolPair
- // Optimizer components
-
- /** ICode analysis for optimization */
- object analysis extends {
- val global: Global.this.type = Global.this
- } with TypeFlowAnalysis
-
- /** Copy propagation for optimization */
- object copyPropagation extends {
- val global: Global.this.type = Global.this
- } with CopyPropagation
-
// Components for collecting and generating output
/** Some statistics (normally disabled) set with -Ystatistics */
@@ -302,7 +270,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
// Over 200 closure objects are eliminated by inlining this.
@inline final def log(msg: => AnyRef) {
if (shouldLogAtThisPhase)
- inform("[log %s%s] %s".format(globalPhase, atPhaseStackMessage, msg))
+ inform(s"[log $globalPhase$atPhaseStackMessage] $msg")
}
@inline final override def debuglog(msg: => String) {
@@ -324,10 +292,10 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
try Some(Charset.forName(name))
catch {
case _: IllegalCharsetNameException =>
- globalError("illegal charset name '" + name + "'")
+ globalError(s"illegal charset name '$name'")
None
case _: UnsupportedCharsetException =>
- globalError("unsupported charset '" + name + "'")
+ globalError(s"unsupported charset '$name'")
None
}
@@ -400,15 +368,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
def apply(unit: CompilationUnit): Unit
- private val isErased = prev.name == "erasure" || prev.erasedTypes
- override def erasedTypes: Boolean = isErased
- private val isFlat = prev.name == "flatten" || prev.flatClasses
- override def flatClasses: Boolean = isFlat
- private val isSpecialized = prev.name == "specialize" || prev.specialized
- override def specialized: Boolean = isSpecialized
- private val isRefChecked = prev.name == "refchecks" || prev.refChecked
- override def refChecked: Boolean = isRefChecked
-
/** Is current phase cancelled on this unit? */
def cancelled(unit: CompilationUnit) = {
// run the typer only if in `createJavadoc` mode
@@ -422,15 +381,18 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
if (settings.debug && (settings.verbose || currentRun.size < 5))
inform("[running phase " + name + " on " + unit + "]")
+ if (!cancelled(unit)) {
+ currentRun.informUnitStarting(this, unit)
+ try withCurrentUnitNoLog(unit)(task)
+ finally currentRun.advanceUnit()
+ }
+ }
+ final def withCurrentUnitNoLog(unit: CompilationUnit)(task: => Unit) {
val unit0 = currentUnit
try {
currentRun.currentUnit = unit
- if (!cancelled(unit)) {
- currentRun.informUnitStarting(this, unit)
- task
- }
- currentRun.advanceUnit()
+ task
} finally {
//assert(currentUnit == unit)
currentRun.currentUnit = unit0
@@ -591,59 +553,10 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
val runsRightAfter = None
} with Delambdafy
- // phaseName = "icode"
- object genicode extends {
- val global: Global.this.type = Global.this
- val runsAfter = List("cleanup")
- val runsRightAfter = None
- } with GenICode
-
- // phaseName = "inliner"
- object inliner extends {
- val global: Global.this.type = Global.this
- val runsAfter = List("icode")
- val runsRightAfter = None
- } with Inliners
-
- // phaseName = "inlinehandlers"
- object inlineExceptionHandlers extends {
- val global: Global.this.type = Global.this
- val runsAfter = List("inliner")
- val runsRightAfter = None
- } with InlineExceptionHandlers
-
- // phaseName = "closelim"
- object closureElimination extends {
- val global: Global.this.type = Global.this
- val runsAfter = List("inlinehandlers")
- val runsRightAfter = None
- } with ClosureElimination
-
- // phaseName = "constopt"
- object constantOptimization extends {
- val global: Global.this.type = Global.this
- val runsAfter = List("closelim")
- val runsRightAfter = None
- } with ConstantOptimization
-
- // phaseName = "dce"
- object deadCode extends {
- val global: Global.this.type = Global.this
- val runsAfter = List("closelim")
- val runsRightAfter = None
- } with DeadCodeElimination
-
- // phaseName = "jvm", ASM-based version
- object genASM extends {
- val global: Global.this.type = Global.this
- val runsAfter = List("dce")
- val runsRightAfter = None
- } with GenASM
-
// phaseName = "bcode"
object genBCode extends {
val global: Global.this.type = Global.this
- val runsAfter = List("dce")
+ val runsAfter = List("cleanup")
val runsRightAfter = None
} with GenBCode
@@ -674,13 +587,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
val global: Global.this.type = Global.this
} with TreeCheckers
- /** Icode verification */
- object icodeCheckers extends {
- val global: Global.this.type = Global.this
- } with ICodeCheckers
-
- object icodeChecker extends icodeCheckers.ICodeChecker()
-
object typer extends analyzer.Typer(
analyzer.NoContext.make(EmptyTree, RootClass, newScope)
)
@@ -713,12 +619,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
mixer -> "mixin composition",
delambdafy -> "remove lambdas",
cleanup -> "platform-specific cleanups, generate reflective calls",
- genicode -> "generate portable intermediate code",
- inliner -> "optimization: do inlining",
- inlineExceptionHandlers -> "optimization: inline exception handlers",
- closureElimination -> "optimization: eliminate uncalled closures",
- constantOptimization -> "optimization: optimize null and other constants",
- deadCode -> "optimization: eliminate dead code",
terminal -> "the last phase during a compilation run"
)
@@ -858,12 +758,9 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
/** Extend classpath of `platform` and rescan updated packages. */
def extendCompilerClassPath(urls: URL*): Unit = {
- if (settings.YclasspathImpl.value == ClassPathRepresentationType.Flat)
- throw new UnsupportedOperationException("Flat classpath doesn't support extending the compiler classpath")
-
- val newClassPath = platform.classPath.mergeUrlsIntoClassPath(urls: _*)
+ val urlClasspaths = urls.map(u => ClassPathFactory.newClassPath(AbstractFile.getURL(u), settings))
+ val newClassPath = AggregateClassPath.createAggregate(platform.classPath +: urlClasspaths : _*)
platform.currentClassPath = Some(newClassPath)
- // Reload all specified jars into this compiler instance
invalidateClassPathEntries(urls.map(_.getPath): _*)
}
@@ -896,43 +793,54 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
* entries on the classpath.
*/
def invalidateClassPathEntries(paths: String*): Unit = {
- if (settings.YclasspathImpl.value == ClassPathRepresentationType.Flat)
- throw new UnsupportedOperationException("Flat classpath doesn't support the classpath invalidation")
-
- implicit object ClassPathOrdering extends Ordering[PlatformClassPath] {
- def compare(a:PlatformClassPath, b:PlatformClassPath) = a.asClassPathString compare b.asClassPathString
+ implicit object ClassPathOrdering extends Ordering[ClassPath] {
+ def compare(a: ClassPath, b: ClassPath): Int = a.asClassPathString compareTo b.asClassPathString
}
val invalidated, failed = new mutable.ListBuffer[ClassSymbol]
- classPath match {
- case cp: MergedClassPath[_] =>
- def assoc(path: String): List[(PlatformClassPath, PlatformClassPath)] = {
- val dir = AbstractFile.getDirectory(path)
- val canonical = dir.canonicalPath
- def matchesCanonical(e: ClassPath[_]) = e.origin match {
- case Some(opath) =>
- AbstractFile.getDirectory(opath).canonicalPath == canonical
- case None =>
- false
- }
- cp.entries find matchesCanonical match {
- case Some(oldEntry) =>
- List(oldEntry -> cp.context.newClassPath(dir))
- case None =>
- error(s"Error adding entry to classpath. During invalidation, no entry named $path in classpath $classPath")
- List()
- }
- }
- val subst = immutable.TreeMap(paths flatMap assoc: _*)
- if (subst.nonEmpty) {
- platform updateClassPath subst
- informProgress(s"classpath updated on entries [${subst.keys mkString ","}]")
- def mkClassPath(elems: Iterable[PlatformClassPath]): PlatformClassPath =
- if (elems.size == 1) elems.head
- else new MergedClassPath(elems, recursiveClassPath.context)
- val oldEntries = mkClassPath(subst.keys)
- val newEntries = mkClassPath(subst.values)
- mergeNewEntries(newEntries, RootClass, Some(recursiveClassPath), Some(oldEntries), invalidated, failed)
- }
+
+ def assoc(path: String): Option[(ClassPath, ClassPath)] = {
+ def origin(lookup: ClassPath): Option[String] = lookup match {
+ case cp: JFileDirectoryLookup[_] => Some(cp.dir.getPath)
+ case cp: ZipArchiveFileLookup[_] => Some(cp.zipFile.getPath)
+ case _ => None
+ }
+
+ def entries(lookup: ClassPath): Seq[ClassPath] = lookup match {
+ case cp: AggregateClassPath => cp.aggregates
+ case cp: ClassPath => Seq(cp)
+ }
+
+ val dir = AbstractFile.getDirectory(path) // if path is a `jar`, this is a FileZipArchive (isDirectory is true)
+ val canonical = dir.canonicalPath // this is the canonical path of the .jar
+ def matchesCanonical(e: ClassPath) = origin(e) match {
+ case Some(opath) =>
+ AbstractFile.getDirectory(opath).canonicalPath == canonical
+ case None =>
+ false
+ }
+ entries(classPath) find matchesCanonical match {
+ case Some(oldEntry) =>
+ Some(oldEntry -> ClassPathFactory.newClassPath(dir, settings))
+ case None =>
+ error(s"Error adding entry to classpath. During invalidation, no entry named $path in classpath $classPath")
+ None
+ }
+ }
+ val subst = immutable.TreeMap(paths flatMap assoc: _*)
+ if (subst.nonEmpty) {
+ platform updateClassPath subst
+ informProgress(s"classpath updated on entries [${subst.keys mkString ","}]")
+ def mkClassPath(elems: Iterable[ClassPath]): ClassPath =
+ if (elems.size == 1) elems.head
+ else AggregateClassPath.createAggregate(elems.toSeq: _*)
+ val oldEntries = mkClassPath(subst.keys)
+ val newEntries = mkClassPath(subst.values)
+ classPath match {
+ case cp: ClassPath => mergeNewEntries(
+ RootClass, "",
+ oldEntries, newEntries, cp,
+ invalidated, failed)
+ }
}
def show(msg: String, syms: scala.collection.Traversable[Symbol]) =
if (syms.nonEmpty)
@@ -941,66 +849,61 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
show("could not invalidate system packages", failed)
}
- /** Merges new classpath entries into the symbol table
- *
- * @param newEntries The new classpath entries
- * @param root The root symbol to be resynced (a package class)
- * @param allEntries Optionally, the corresponding package in the complete current classpath
- * @param oldEntries Optionally, the corresponding package in the old classpath entries
- * @param invalidated A listbuffer collecting the invalidated package classes
- * @param failed A listbuffer collecting system package classes which could not be invalidated
+ /**
+ * Merges new classpath entries into the symbol table
*
- * The merging strategy is determined by the absence or presence of classes and packages.
+ * @param packageClass The ClassSymbol for the package being updated
+ * @param fullPackageName The full name of the package being updated
+ * @param oldEntries The classpath that was removed, it is no longer part of fullClasspath
+ * @param newEntries The classpath that was added, it is already part of fullClasspath
+ * @param fullClasspath The full classpath, equivalent to global.classPath
+ * @param invalidated A ListBuffer collecting the invalidated package classes
+ * @param failed A ListBuffer collecting system package classes which could not be invalidated
*
- * If either oldEntries or newEntries contains classes, root is invalidated provided that a corresponding package
- * exists in allEntries. Otherwise it is removed.
- * Otherwise, the action is determined by the following matrix, with columns:
+ * If either oldEntries or newEntries contains classes in the current package, the package symbol
+ * is re-initialized to a fresh package loader, provided that a corresponding package exists in
+ * fullClasspath. Otherwise it is removed.
*
- * old sym action
- * + + recurse into all child packages of newEntries
- * - + invalidate root
- * - - create and enter root
- *
- * Here, old means classpath, and sym means symboltable. + is presence of an entry in its column, - is absence.
+ * Otherwise, sub-packages in newEntries are looked up in the symbol table (created if
+ * non-existent) and the merge function is called recursively.
*/
- private def mergeNewEntries(newEntries: PlatformClassPath, root: ClassSymbol,
- allEntries: OptClassPath, oldEntries: OptClassPath,
- invalidated: mutable.ListBuffer[ClassSymbol], failed: mutable.ListBuffer[ClassSymbol]) {
- ifDebug(informProgress(s"syncing $root, $oldEntries -> $newEntries"))
-
- val getName: ClassPath[AbstractFile] => String = (_.name)
- def hasClasses(cp: OptClassPath) = cp.isDefined && cp.get.classes.nonEmpty
- def invalidateOrRemove(root: ClassSymbol) = {
- allEntries match {
- case Some(cp) => root setInfo new loaders.PackageLoader(cp)
- case None => root.owner.info.decls unlink root.sourceModule
- }
- invalidated += root
+ private def mergeNewEntries(packageClass: ClassSymbol, fullPackageName: String,
+ oldEntries: ClassPath, newEntries: ClassPath, fullClasspath: ClassPath,
+ invalidated: mutable.ListBuffer[ClassSymbol], failed: mutable.ListBuffer[ClassSymbol]): Unit = {
+ ifDebug(informProgress(s"syncing $packageClass, $oldEntries -> $newEntries"))
+
+ def packageExists(cp: ClassPath): Boolean = {
+ val (parent, _) = PackageNameUtils.separatePkgAndClassNames(fullPackageName)
+ cp.packages(parent).exists(_.name == fullPackageName)
}
- def subPackage(cp: PlatformClassPath, name: String): OptClassPath =
- cp.packages find (cp1 => getName(cp1) == name)
- val classesFound = hasClasses(oldEntries) || newEntries.classes.nonEmpty
- if (classesFound && !isSystemPackageClass(root)) {
- invalidateOrRemove(root)
- } else {
- if (classesFound) {
- if (root.isRoot) invalidateOrRemove(EmptyPackageClass)
- else failed += root
- }
- if (!oldEntries.isDefined) invalidateOrRemove(root)
+ def invalidateOrRemove(pkg: ClassSymbol) = {
+ if (packageExists(fullClasspath))
+ pkg setInfo new loaders.PackageLoader(fullPackageName, fullClasspath)
else
- for (pstr <- newEntries.packages.map(getName)) {
- val pname = newTermName(pstr)
- val pkg = (root.info decl pname) orElse {
- // package does not exist in symbol table, create symbol to track it
- assert(!subPackage(oldEntries.get, pstr).isDefined)
- loaders.enterPackage(root, pstr, new loaders.PackageLoader(allEntries.get))
- }
- mergeNewEntries(subPackage(newEntries, pstr).get, pkg.moduleClass.asClass,
- subPackage(allEntries.get, pstr), subPackage(oldEntries.get, pstr),
- invalidated, failed)
+ pkg.owner.info.decls unlink pkg.sourceModule
+ invalidated += pkg
+ }
+
+ val classesFound = oldEntries.classes(fullPackageName).nonEmpty || newEntries.classes(fullPackageName).nonEmpty
+ if (classesFound) {
+ // if the package contains classes either in oldEntries or newEntries, the package is invalidated (or removed if there are no more classes in it)
+ if (!isSystemPackageClass(packageClass)) invalidateOrRemove(packageClass)
+ else if (packageClass.isRoot) invalidateOrRemove(EmptyPackageClass)
+ else failed += packageClass
+ } else {
+ // no new or removed classes in the current package
+ for (p <- newEntries.packages(fullPackageName)) {
+ val (_, subPackageName) = PackageNameUtils.separatePkgAndClassNames(p.name)
+ val subPackage = packageClass.info.decl(newTermName(subPackageName)) orElse {
+ // package does not exist in symbol table, create a new symbol
+ loaders.enterPackage(packageClass, subPackageName, new loaders.PackageLoader(p.name, fullClasspath))
}
+ mergeNewEntries(
+ subPackage.moduleClass.asClass, p.name,
+ oldEntries, newEntries, fullClasspath,
+ invalidated, failed)
+ }
}
}
@@ -1057,9 +960,9 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
@inline final def enteringErasure[T](op: => T): T = enteringPhase(currentRun.erasurePhase)(op)
@inline final def enteringExplicitOuter[T](op: => T): T = enteringPhase(currentRun.explicitouterPhase)(op)
@inline final def enteringFlatten[T](op: => T): T = enteringPhase(currentRun.flattenPhase)(op)
- @inline final def enteringIcode[T](op: => T): T = enteringPhase(currentRun.icodePhase)(op)
@inline final def enteringMixin[T](op: => T): T = enteringPhase(currentRun.mixinPhase)(op)
@inline final def enteringDelambdafy[T](op: => T): T = enteringPhase(currentRun.delambdafyPhase)(op)
+ @inline final def enteringJVM[T](op: => T): T = enteringPhase(currentRun.jvmPhase)(op)
@inline final def enteringPickler[T](op: => T): T = enteringPhase(currentRun.picklerPhase)(op)
@inline final def enteringSpecialize[T](op: => T): T = enteringPhase(currentRun.specializePhase)(op)
@inline final def enteringTyper[T](op: => T): T = enteringPhase(currentRun.typerPhase)(op)
@@ -1333,8 +1236,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
// val superaccessorsPhase = phaseNamed("superaccessors")
val picklerPhase = phaseNamed("pickler")
val refchecksPhase = phaseNamed("refchecks")
- // val selectiveanfPhase = phaseNamed("selectiveanf")
- // val selectivecpsPhase = phaseNamed("selectivecps")
val uncurryPhase = phaseNamed("uncurry")
// val tailcallsPhase = phaseNamed("tailcalls")
val specializePhase = phaseNamed("specialize")
@@ -1348,20 +1249,10 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
val mixinPhase = phaseNamed("mixin")
val delambdafyPhase = phaseNamed("delambdafy")
val cleanupPhase = phaseNamed("cleanup")
- val icodePhase = phaseNamed("icode")
- val inlinerPhase = phaseNamed("inliner")
- val inlineExceptionHandlersPhase = phaseNamed("inlinehandlers")
- val closelimPhase = phaseNamed("closelim")
- val dcePhase = phaseNamed("dce")
- // val jvmPhase = phaseNamed("jvm")
+ val jvmPhase = phaseNamed("jvm")
def runIsAt(ph: Phase) = globalPhase.id == ph.id
- def runIsAtOptimiz = {
- runIsAt(inlinerPhase) || // listing phases in full for robustness when -Ystop-after has been given.
- runIsAt(inlineExceptionHandlersPhase) ||
- runIsAt(closelimPhase) ||
- runIsAt(dcePhase)
- }
+ def runIsAtOptimiz = runIsAt(jvmPhase)
isDefined = true
@@ -1373,13 +1264,17 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
unitbuf += unit
compiledFiles += unit.source.file.path
}
- private def checkDeprecatedSettings(unit: CompilationUnit) {
+ private def warnDeprecatedAndConflictingSettings(unit: CompilationUnit) {
// issue warnings for any usage of deprecated settings
settings.userSetSettings filter (_.isDeprecated) foreach { s =>
currentRun.reporting.deprecationWarning(NoPosition, s.name + " is deprecated: " + s.deprecationMessage.get)
}
- if (settings.target.value.contains("jvm-1.5"))
- currentRun.reporting.deprecationWarning(NoPosition, settings.target.name + ":" + settings.target.value + " is deprecated: use target for Java 1.6 or above.")
+ val supportedTarget = "jvm-1.8"
+ if (settings.target.value != supportedTarget) {
+ currentRun.reporting.deprecationWarning(NoPosition, settings.target.name + ":" + settings.target.value + " is deprecated and has no effect, setting to " + supportedTarget)
+ settings.target.value = supportedTarget
+ }
+ settings.conflictWarning.foreach(reporter.warning(NoPosition, _))
}
/* An iterator returning all the units being compiled in this run */
@@ -1420,8 +1315,8 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
if (canCheck) {
phase = globalPhase
- if (globalPhase.id >= icodePhase.id) icodeChecker.checkICodes()
- else treeChecker.checkTrees()
+ if (globalPhase.id <= cleanupPhase.id)
+ treeChecker.checkTrees()
}
}
@@ -1470,7 +1365,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
def compileSources(sources: List[SourceFile]) = if (!reporter.hasErrors) {
def checkDeprecations() = {
- checkDeprecatedSettings(newCompilationUnit(""))
+ warnDeprecatedAndConflictingSettings(newCompilationUnit(""))
reporting.summarizeErrors()
}
@@ -1492,7 +1387,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
val startTime = currentTime
reporter.reset()
- checkDeprecatedSettings(unitbuf.head)
+ warnDeprecatedAndConflictingSettings(unitbuf.head)
globalPhase = fromPhase
while (globalPhase.hasNext && !reporter.hasErrors) {
@@ -1502,14 +1397,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
// progress update
informTime(globalPhase.description, startTime)
- val shouldWriteIcode = (
- (settings.writeICode.isSetByUser && (settings.writeICode containsPhase globalPhase))
- || (!settings.Xprint.doAllPhases && (settings.Xprint containsPhase globalPhase) && runIsAtOptimiz)
- )
- if (shouldWriteIcode) {
- // Write *.icode files when -Xprint-icode or -Xprint:<some-optimiz-phase> was given.
- writeICode()
- } else if ((settings.Xprint containsPhase globalPhase) || settings.printLate && runIsAt(cleanupPhase)) {
+ if ((settings.Xprint containsPhase globalPhase) || settings.printLate && runIsAt(cleanupPhase)) {
// print trees
if (settings.Xshowtrees || settings.XshowtreesCompact || settings.XshowtreesStringified) nodePrinters.printAll()
else printAllUnits()
@@ -1530,7 +1418,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
// move the pointer
globalPhase = globalPhase.next
- // run tree/icode checkers
+ // run tree checkers
if (settings.check containsPhase globalPhase.prev)
runCheckers()
@@ -1674,33 +1562,17 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
/** Returns the file with the given suffix for the given class. Used for icode writing. */
def getFile(clazz: Symbol, suffix: String): File = getFile(clazz.sourceFile, clazz.fullName split '.', suffix)
- private def writeICode() {
- val printer = new icodes.TextPrinter(writer = null, icodes.linearizer)
- icodes.classes.values foreach { cls =>
- val file = {
- val module = if (cls.symbol.hasModuleFlag) "$" else ""
- val faze = if (settings.debug) phase.name else f"${phase.id}%02d" // avoid breaking windows build with long filename
- getFile(cls.symbol, s"$module-$faze.icode")
- }
-
- try {
- val stream = new FileOutputStream(file)
- printer.setWriter(new PrintWriter(stream, true))
- try
- printer.printClass(cls)
- finally
- stream.close()
- informProgress(s"wrote $file")
- } catch {
- case e: IOException =>
- if (settings.debug) e.printStackTrace()
- globalError(s"could not write file $file")
- }
- }
- }
def createJavadoc = false
}
object Global {
def apply(settings: Settings, reporter: Reporter): Global = new Global(settings, reporter)
+
+ def apply(settings: Settings): Global = new Global(settings, reporter(settings))
+
+ private def reporter(settings: Settings): Reporter = {
+ //val loader = ScalaClassLoader(getClass.getClassLoader) // apply does not make delegate
+ val loader = new ClassLoader(getClass.getClassLoader) with ScalaClassLoader
+ loader.create[Reporter](settings.reporter.value, settings.errorFn)(settings)
+ }
}