diff options
author | Paul Phillips <paulp@improving.org> | 2013-06-08 00:45:39 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2013-06-08 00:45:39 -0700 |
commit | 800a17d9c22631dc2cd1a217486832e6aca1ea89 (patch) | |
tree | 618ef860e87bc228441c9d05071b729f718755a9 | |
parent | aefdbd3f923826c6efe87d6f5dbaa84095c090ce (diff) | |
parent | 4f530c492d94e2c86dd906737a8d35806b5e450a (diff) | |
download | scala-800a17d9c22631dc2cd1a217486832e6aca1ea89.tar.gz scala-800a17d9c22631dc2cd1a217486832e6aca1ea89.tar.bz2 scala-800a17d9c22631dc2cd1a217486832e6aca1ea89.zip |
Merge pull request #2638 from paulp/pr/error-output
Cleanup of crash output.
-rw-r--r-- | src/compiler/scala/tools/nsc/Global.scala | 58 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/Trees.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/Mixin.scala | 9 |
3 files changed, 30 insertions, 39 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() diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index 8391ebdafc..41d89aa3b4 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -221,7 +221,7 @@ trait Trees extends scala.reflect.internal.Trees { self: Global => try unit.body = transform(unit.body) catch { case ex: Exception => - println(supplementErrorMessage("unhandled exception while transforming "+unit)) + log(supplementErrorMessage("unhandled exception while transforming "+unit)) throw ex } } diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala index eca958fd8d..e0b1d9ea80 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -594,11 +594,10 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { sym.owner.info //todo: needed? sym.owner.owner.info //todo: needed? - assert( - sym.owner.sourceModule ne NoSymbol, - "" + sym.fullLocationString + " in " + sym.owner.owner + " " + sym.owner.owner.info.decls - ) - REF(sym.owner.sourceModule) DOT sym + if (sym.owner.sourceModule eq NoSymbol) + abort(s"Cannot create static reference to $sym because ${sym.safeOwner} has no source module") + else + REF(sym.owner.sourceModule) DOT sym } def needsInitAndHasOffset(sym: Symbol) = |