diff options
author | Martin Odersky <odersky@gmail.com> | 2016-09-01 19:10:48 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2016-10-02 16:11:21 +0200 |
commit | 617be516b261524c2f0762de10f2bde376043ad7 (patch) | |
tree | 093df00ecbb02bfe5b06b2040fad953a613b4f20 /src/dotty/tools/dotc | |
parent | faba2b7999bf73bf10116b391efbdd751054ead0 (diff) | |
download | dotty-617be516b261524c2f0762de10f2bde376043ad7.tar.gz dotty-617be516b261524c2f0762de10f2bde376043ad7.tar.bz2 dotty-617be516b261524c2f0762de10f2bde376043ad7.zip |
Print inlining positions in error messages
Error messages now print the inlined positions as well
as the position of the inlined call, recursively.
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r-- | src/dotty/tools/dotc/core/Contexts.scala | 8 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Decorators.scala | 14 | ||||
-rw-r--r-- | src/dotty/tools/dotc/reporting/ConsoleReporter.scala | 19 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Inliner.scala | 18 | ||||
-rw-r--r-- | src/dotty/tools/dotc/util/SourcePosition.scala | 6 |
5 files changed, 42 insertions, 23 deletions
diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala index ea0ab95e6..f2a1fe53e 100644 --- a/src/dotty/tools/dotc/core/Contexts.scala +++ b/src/dotty/tools/dotc/core/Contexts.scala @@ -370,12 +370,8 @@ object Contexts { /** The current source file; will be derived from current * compilation unit. */ - def source: SourceFile = { - val file = Inliner.inlinedSource - if (file.exists) file - else if (compilationUnit == null) NoSource - else compilationUnit.source - } + def source: SourceFile = + if (compilationUnit == null) NoSource else compilationUnit.source /** Does current phase use an erased types interpretation? */ def erasedTypes: Boolean = phase.erasedTypes diff --git a/src/dotty/tools/dotc/core/Decorators.scala b/src/dotty/tools/dotc/core/Decorators.scala index 387e7e466..fc546667d 100644 --- a/src/dotty/tools/dotc/core/Decorators.scala +++ b/src/dotty/tools/dotc/core/Decorators.scala @@ -7,6 +7,8 @@ import Contexts._, Names._, Phases._, printing.Texts._, printing.Printer, printi import util.Positions.Position, util.SourcePosition import collection.mutable.ListBuffer import dotty.tools.dotc.transform.TreeTransforms._ +import typer.Inliner +import ast.tpd.Inlined import scala.language.implicitConversions import printing.Formatting._ @@ -148,8 +150,16 @@ object Decorators { } } - implicit def sourcePos(pos: Position)(implicit ctx: Context): SourcePosition = - ctx.source.atPos(pos) + implicit def sourcePos(pos: Position)(implicit ctx: Context): SourcePosition = { + def recur(inlineds: Stream[Inlined], pos: Position): SourcePosition = inlineds match { + case inlined #:: rest => + Inliner.sourceFile(inlined).atPos(pos) + .withOuter(recur(rest, inlined.call.pos)) + case empty => + ctx.source.atPos(pos) + } + recur(Inliner.enclosingInlineds, pos) + } implicit class StringInterpolators(val sc: StringContext) extends AnyVal { diff --git a/src/dotty/tools/dotc/reporting/ConsoleReporter.scala b/src/dotty/tools/dotc/reporting/ConsoleReporter.scala index f35293d8d..deb772db5 100644 --- a/src/dotty/tools/dotc/reporting/ConsoleReporter.scala +++ b/src/dotty/tools/dotc/reporting/ConsoleReporter.scala @@ -21,11 +21,15 @@ class ConsoleReporter( /** maximal number of error messages to be printed */ protected def ErrorLimit = 100 - def printSourceLine(pos: SourcePosition) = - printMessage(pos.lineContent.stripLineEnd) - - def printColumnMarker(pos: SourcePosition) = - if (pos.exists) { printMessage(" " * pos.column + "^") } + def printPos(pos: SourcePosition): Unit = + if (pos.exists) { + printMessage(pos.lineContent.stripLineEnd) + printMessage(" " * pos.column + "^") + if (pos.outer.exists) { + printMessage(s"\n... this location is in code that was inlined at ${pos.outer}:\n") + printPos(pos.outer) + } + } /** Prints the message. */ def printMessage(msg: String): Unit = { writer.print(msg + "\n"); writer.flush() } @@ -34,10 +38,7 @@ class ConsoleReporter( def printMessageAndPos(msg: String, pos: SourcePosition)(implicit ctx: Context): Unit = { val posStr = if (pos.exists) s"$pos: " else "" printMessage(posStr + msg) - if (pos.exists) { - printSourceLine(pos) - printColumnMarker(pos) - } + printPos(pos) } override def doReport(d: Diagnostic)(implicit ctx: Context): Unit = d match { diff --git a/src/dotty/tools/dotc/typer/Inliner.scala b/src/dotty/tools/dotc/typer/Inliner.scala index 28c725b33..8d25e3250 100644 --- a/src/dotty/tools/dotc/typer/Inliner.scala +++ b/src/dotty/tools/dotc/typer/Inliner.scala @@ -82,11 +82,19 @@ object Inliner { def inlineContext(tree: untpd.Inlined)(implicit ctx: Context): Context = ctx.fresh.setProperty(InlinedCall, tree) - def inlinedSource(implicit ctx: Context): SourceFile = ctx.property(InlinedCall) match { - case Some(inlined) => - val file = inlined.call.symbol.sourceFile - if (file.exists) new SourceFile(file) else NoSource - case _ => NoSource + def enclosingInlineds(implicit ctx: Context): Stream[Inlined] = + ctx.property(InlinedCall) match { + case found @ Some(inlined) => + inlined #:: + enclosingInlineds( + ctx.outersIterator.dropWhile(_.property(InlinedCall) == found).next) + case _ => + Stream.Empty + } + + def sourceFile(inlined: Inlined)(implicit ctx: Context) = { + val file = inlined.call.symbol.sourceFile + if (file.exists) new SourceFile(file) else NoSource } } diff --git a/src/dotty/tools/dotc/util/SourcePosition.scala b/src/dotty/tools/dotc/util/SourcePosition.scala index 0b2b2aa0b..68a9b6403 100644 --- a/src/dotty/tools/dotc/util/SourcePosition.scala +++ b/src/dotty/tools/dotc/util/SourcePosition.scala @@ -5,7 +5,8 @@ package util import Positions.{Position, NoPosition} /** A source position is comprised of a position in a source file */ -case class SourcePosition(source: SourceFile, pos: Position) extends interfaces.SourcePosition { +case class SourcePosition(source: SourceFile, pos: Position, outer: SourcePosition = NoSourcePosition) +extends interfaces.SourcePosition { def exists = pos.exists def lineContent: String = source.lineContent(point) @@ -24,6 +25,8 @@ case class SourcePosition(source: SourceFile, pos: Position) extends interfaces. def endLine: Int = source.offsetToLine(end) def endColumn: Int = source.column(end) + def withOuter(outer: SourcePosition) = new SourcePosition(source, pos, outer) + override def toString = if (source.exists) s"${source.file}:${line + 1}" else s"(no source file, offset = ${pos.point})" @@ -32,5 +35,6 @@ case class SourcePosition(source: SourceFile, pos: Position) extends interfaces. /** A sentinel for a non-existing source position */ @sharable object NoSourcePosition extends SourcePosition(NoSource, NoPosition) { override def toString = "?" + override def withOuter(outer: SourcePosition) = outer } |