aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r--src/dotty/tools/dotc/reporting/ConsoleReporter.scala46
-rw-r--r--src/dotty/tools/dotc/util/SourceFile.scala2
-rw-r--r--src/dotty/tools/dotc/util/SourcePosition.scala11
3 files changed, 40 insertions, 19 deletions
diff --git a/src/dotty/tools/dotc/reporting/ConsoleReporter.scala b/src/dotty/tools/dotc/reporting/ConsoleReporter.scala
index 45933d954..d96ff48a4 100644
--- a/src/dotty/tools/dotc/reporting/ConsoleReporter.scala
+++ b/src/dotty/tools/dotc/reporting/ConsoleReporter.scala
@@ -32,24 +32,35 @@ class ConsoleReporter(
def stripColor(str: String): String =
str.replaceAll("\u001B\\[[;\\d]*m", "")
- def sourceLine(pos: SourcePosition)(implicit ctx: Context): (String, Int) = {
- val lineNum = s"${pos.line}:"
- (lineNum + hl"${pos.lineContent.stripLineEnd}", lineNum.length)
- }
+ def sourceLines(pos: SourcePosition)(implicit ctx: Context): (List[String], Int) = {
+ var maxLen = Int.MinValue
+ val lines = pos.lines
+ .map { lineNbr =>
+ val prefix = s"${lineNbr + 1} |"
+ maxLen = math.max(maxLen, prefix.length)
+ (prefix, pos.lineContent(lineNbr).stripLineEnd)
+ }
+ .map { case (prefix, line) =>
+ val lnum = Red(" " * math.max(0, maxLen - prefix.length) + prefix)
+ hl"$lnum$line"
+ }
- def columnMarker(pos: SourcePosition, offset: Int)(implicit ctx: Context) =
- if (pos.startLine == pos.endLine) {
- val whitespace = " " * (pos.startColumn + offset)
- val carets =
- Red("^" * math.max(1, pos.endColumn - pos.startColumn))
+ (lines, maxLen)
+ }
- whitespace + carets.show
- } else {
- Red(" " * (pos.column + offset) + "^").show
+ def columnMarker(pos: SourcePosition, offset: Int)(implicit ctx: Context) = {
+ val prefix = " " * (offset - 1)
+ val whitespace = " " * pos.startColumn
+ val carets = Red {
+ if (pos.startLine == pos.endLine)
+ "^" * math.max(1, pos.endColumn - pos.startColumn)
+ else "^"
}
+ s"$prefix|$whitespace${carets.show}"
+ }
+
def errorMsg(pos: SourcePosition, msg: String, offset: Int)(implicit ctx: Context) = {
- var hasLongLines = false
val leastWhitespace = msg.lines.foldLeft(Int.MaxValue) { (minPad, line) =>
val lineLength = stripColor(line).length
val padding =
@@ -59,9 +70,8 @@ class ConsoleReporter(
else minPad
}
- msg
- .lines
- .map { line => " " * leastWhitespace + line }
+ msg.lines
+ .map { line => " " * (offset - 1) + "|" + (" " * (leastWhitespace - offset)) + line }
.mkString(sys.props("line.separator"))
}
@@ -85,11 +95,11 @@ class ConsoleReporter(
def printMessageAndPos(msg: Message, pos: SourcePosition, diagnosticLevel: String)(implicit ctx: Context): Unit = {
printMessage(posStr(pos, diagnosticLevel, msg))
if (pos.exists) {
- val (src, offset) = sourceLine(pos)
+ val (srcLines, offset) = sourceLines(pos)
val marker = columnMarker(pos, offset)
val err = errorMsg(pos, msg.msg, offset)
- printMessage(List(src, marker, err).mkString("\n"))
+ printMessage((srcLines ::: marker :: err :: Nil).mkString("\n"))
} else printMessage(msg.msg)
}
diff --git a/src/dotty/tools/dotc/util/SourceFile.scala b/src/dotty/tools/dotc/util/SourceFile.scala
index 8bd0ecfd6..1d4c9c2ab 100644
--- a/src/dotty/tools/dotc/util/SourceFile.scala
+++ b/src/dotty/tools/dotc/util/SourceFile.scala
@@ -97,7 +97,7 @@ case class SourceFile(file: AbstractFile, content: Array[Char]) extends interfac
private lazy val lineIndices: Array[Int] = calculateLineIndices(content)
/** Map line to offset of first character in line */
- def lineToOffset(index : Int): Int = lineIndices(index)
+ def lineToOffset(index: Int): Int = lineIndices(index)
/** A cache to speed up offsetToLine searches to similar lines */
private var lastLine = 0
diff --git a/src/dotty/tools/dotc/util/SourcePosition.scala b/src/dotty/tools/dotc/util/SourcePosition.scala
index 68a9b6403..d0f9cb887 100644
--- a/src/dotty/tools/dotc/util/SourcePosition.scala
+++ b/src/dotty/tools/dotc/util/SourcePosition.scala
@@ -14,6 +14,17 @@ extends interfaces.SourcePosition {
def point: Int = pos.point
/** The line of the position, starting at 0 */
def line: Int = source.offsetToLine(point)
+
+ /** The lines of the position */
+ def lines: List[Int] =
+ List.range(source.offsetToLine(start), source.offsetToLine(end)) match {
+ case Nil => line :: Nil
+ case xs => xs
+ }
+
+ def lineContent(lineNumber: Int): String =
+ source.lineContent(source.lineToOffset(lineNumber))
+
/** The column of the position, starting at 0 */
def column: Int = source.column(point)