summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/Global.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2013-06-06 04:59:56 -0700
committerPaul Phillips <paulp@improving.org>2013-06-06 06:01:12 -0700
commit4f530c492d94e2c86dd906737a8d35806b5e450a (patch)
tree3badcdc481ea0d54ae39008f5dff6bc3b7fcb000 /src/compiler/scala/tools/nsc/Global.scala
parent5312d6305530eb14d369d0f4acaf7ca4e278ea72 (diff)
downloadscala-4f530c492d94e2c86dd906737a8d35806b5e450a.tar.gz
scala-4f530c492d94e2c86dd906737a8d35806b5e450a.tar.bz2
scala-4f530c492d94e2c86dd906737a8d35806b5e450a.zip
Cleanup of crash output.
I finally ran across the assert (or one of them) which produces such voluminous output that it scares the cattle. When you see "decls" in an assert, run. After silencing that, I extended the journey into quieting the default crash message down, way down. I assume this will be met only with sighs of relief. And then most challenging of all for some reason, I convinced it to only print the information once. Volume of crash data generated when reproducing the fsc bug shown below: Before this commit 1158 lines After this commit 27 lines Pretty sure there's more information in the 27 lines. To reproduce the crash: fsc src/library/scala/collection/immutable/IntMap.scala fsc src/library/scala/collection/immutable/IntMap.scala The first compile succeeds quietly; the second throws warnings out of the gate, then crashes. And the "after" output: error: Cannot create static reference to method equals because object GenMapLike$class has no source module error: fatal error: while compiling: /scala/trunk/src/library/scala/collection/immutable/IntMap.scala during phase: globalPhase=mixin, enteringPhase=cleanup library version: version 2.11.0-20130606-052937-392858b4f6 compiler version: version 2.11.0-20130606-055515-1856bec71b reconstructed args: -d /tmp last tree to typer: Ident(key$2) tree position: line 377 of /scala/trunk/src/library/scala/collection/immutable/IntMap.scala tree tpe: Int symbol: value key$2 (flags: <param> <synthetic>) symbol definition: key$2: Int (a TermSymbol) symbol package: scala.collection.immutable symbol owners: value key$2 -> constructor IntMap$$anonfun$unionWith$2 -> anonymous class anonfun$unionWith$2 call site: object IntMap$Nil in package immutable in package immutable == Source file context for tree position == 374 } 375 case (IntMap.Tip(key, value), x) => x.updateWith[S](key, value, (x, y) => f(key, y, x)) 376 case (x, IntMap.Tip(key, value)) => x.updateWith[S](key, value, (x, y) => f(key, x, y)) 377 case (IntMap.Nil, x) => x 378 case (x, IntMap.Nil) => x 379 } 380
Diffstat (limited to 'src/compiler/scala/tools/nsc/Global.scala')
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala58
1 files changed, 25 insertions, 33 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index a08633ffc8..981dfb24fe 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -1060,14 +1060,12 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
@inline final def enteringTyper[T](op: => T): T = enteringPhase(currentRun.typerPhase)(op)
@inline final def enteringUncurry[T](op: => T): T = enteringPhase(currentRun.uncurryPhase)(op)
- // Owners up to and including the first package class.
+ // Owners which aren't package classes.
private def ownerChainString(sym: Symbol): String = (
if (sym == null) ""
- else sym.ownerChain.span(!_.isPackageClass) match {
- case (xs, pkg :: _) => (xs :+ pkg) mkString " -> "
- case _ => sym.ownerChain mkString " -> " // unlikely
- }
+ else sym.ownerChain takeWhile (!_.isPackageClass) mkString " -> "
)
+
private def formatExplain(pairs: (String, Any)*): String = (
pairs.toList collect { case (k, v) if v != null => "%20s: %s".format(k, v) } mkString "\n"
)
@@ -1075,41 +1073,45 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
/** Don't want to introduce new errors trying to report errors,
* so swallow exceptions.
*/
- override def supplementErrorMessage(errorMessage: String): String =
+ override def supplementErrorMessage(errorMessage: String): String = {
if (currentRun.supplementedError) errorMessage
else try {
+ currentRun.supplementedError = true
val tree = analyzer.lastTreeToTyper
val sym = tree.symbol
val tpe = tree.tpe
- val enclosing = lastSeenContext.enclClassOrMethod.tree
+ val site = lastSeenContext.enclClassOrMethod.owner
+ val pos_s = if (tree.pos.isDefined) s"line ${tree.pos.line} of ${tree.pos.source.file}" else "<unknown>"
+ val context_s = try {
+ // Taking 3 before, 3 after the fingered line.
+ val start = 0 max (tree.pos.line - 3)
+ val xs = scala.reflect.io.File(tree.pos.source.file.file).lines drop start take 7
+ val strs = xs.zipWithIndex map { case (line, idx) => f"${start + idx}%6d $line" }
+ strs.mkString("== Source file context for tree position ==\n\n", "\n", "")
+ }
+ catch { case t: Exception => devWarning("" + t) ; "<Cannot read source file>" }
val info1 = formatExplain(
"while compiling" -> currentSource.path,
- "during phase" -> ( if (globalPhase eq phase) phase else "global=%s, enteringPhase=%s".format(globalPhase, phase) ),
+ "during phase" -> ( if (globalPhase eq phase) phase else "globalPhase=%s, enteringPhase=%s".format(globalPhase, phase) ),
"library version" -> scala.util.Properties.versionString,
"compiler version" -> Properties.versionString,
"reconstructed args" -> settings.recreateArgs.mkString(" ")
)
val info2 = formatExplain(
"last tree to typer" -> tree.summaryString,
+ "tree position" -> pos_s,
+ "tree tpe" -> tpe,
"symbol" -> Option(sym).fold("null")(_.debugLocationString),
- "symbol definition" -> Option(sym).fold("null")(_.defString),
- "tpe" -> tpe,
+ "symbol definition" -> Option(sym).fold("null")(s => s.defString + s" (a ${s.shortSymbolClass})"),
+ "symbol package" -> sym.enclosingPackage.fullName,
"symbol owners" -> ownerChainString(sym),
- "context owners" -> ownerChainString(lastSeenContext.owner)
+ "call site" -> (site.fullLocationString + " in " + site.enclosingPackage)
)
- val info3: List[String] = (
- ( List("== Enclosing template or block ==", nodePrinters.nodeToString(enclosing).trim) )
- ++ ( if (tpe eq null) Nil else List("== Expanded type of tree ==", typeDeconstruct.show(tpe)) )
- ++ ( if (!settings.debug) Nil else List("== Current unit body ==", nodePrinters.nodeToString(currentUnit.body)) )
- ++ ( List(errorMessage) )
- )
-
- currentRun.supplementedError = true
-
- ("\n" + info1) :: info2 :: info3 mkString "\n\n"
+ ("\n" + info1) :: info2 :: context_s :: Nil mkString "\n\n"
}
catch { case _: Exception | _: TypeError => errorMessage }
+ }
/** The id of the currently active run
*/
@@ -1493,18 +1495,8 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
compileUnits(sources map (new CompilationUnit(_)), firstPhase)
}
- def compileUnits(units: List[CompilationUnit], fromPhase: Phase) {
- try compileUnitsInternal(units, fromPhase)
- catch { case ex: Throwable =>
- val shown = if (settings.verbose)
- stackTraceString(ex)
- else
- stackTraceHeadString(ex) // note that error stacktraces do not print in fsc
-
- globalError(supplementErrorMessage("uncaught exception during compilation: " + shown))
- throw ex
- }
- }
+ def compileUnits(units: List[CompilationUnit], fromPhase: Phase): Unit =
+ compileUnitsInternal(units, fromPhase)
private def compileUnitsInternal(units: List[CompilationUnit], fromPhase: Phase) {
doInvalidation()