aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Mulder <felix.mulder@gmail.com>2016-09-29 15:45:46 +0200
committerFelix Mulder <felix.mulder@gmail.com>2016-10-10 13:25:36 +0200
commit0781b31fa4e3d22cb6a51882b8d632ea9a16ed6f (patch)
treed0b89359d2af440640e457f04d6d6a945251a592
parenta0026a09d76c09266c368c7a07a0cc2c5994367e (diff)
downloaddotty-0781b31fa4e3d22cb6a51882b8d632ea9a16ed6f.tar.gz
dotty-0781b31fa4e3d22cb6a51882b8d632ea9a16ed6f.tar.bz2
dotty-0781b31fa4e3d22cb6a51882b8d632ea9a16ed6f.zip
Handle multiline messages in ConsoleReporter
-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
-rw-r--r--tests/repl/errmsgs.check90
-rw-r--r--tests/repl/imports.check16
5 files changed, 90 insertions, 75 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)
diff --git a/tests/repl/errmsgs.check b/tests/repl/errmsgs.check
index b8cff5ba2..2a65fd949 100644
--- a/tests/repl/errmsgs.check
+++ b/tests/repl/errmsgs.check
@@ -2,46 +2,46 @@ scala> class Inv[T](x: T)
defined class Inv
scala> val x: List[String] = List(1)
-- [E006] Type Mismatch Error: <console> -------------------------------------------------------------------------------
-3:val x: List[String] = List(1)
- ^
- found: Int(1)
- required: String
-
+4 |val x: List[String] = List(1)
+ | ^
+ | found: Int(1)
+ | required: String
+ |
scala> val y: List[List[String]] = List(List(1))
-- [E006] Type Mismatch Error: <console> -------------------------------------------------------------------------------
-3:val y: List[List[String]] = List(List(1))
- ^
- found: Int(1)
- required: String
-
+4 |val y: List[List[String]] = List(List(1))
+ | ^
+ | found: Int(1)
+ | required: String
+ |
scala> val z: (List[String], List[Int]) = (List(1), List("a"))
-- [E006] Type Mismatch Error: <console> -------------------------------------------------------------------------------
-3:val z: (List[String], List[Int]) = (List(1), List("a"))
- ^
- found: Int(1)
- required: String
-
+4 |val z: (List[String], List[Int]) = (List(1), List("a"))
+ | ^
+ | found: Int(1)
+ | required: String
+ |
-- [E006] Type Mismatch Error: <console> -------------------------------------------------------------------------------
-3:val z: (List[String], List[Int]) = (List(1), List("a"))
- ^^^
- found: String("a")
- required: Int
-
+4 |val z: (List[String], List[Int]) = (List(1), List("a"))
+ | ^^^
+ | found: String("a")
+ | required: Int
+ |
scala> val a: Inv[String] = new Inv(new Inv(1))
-- [E006] Type Mismatch Error: <console> -------------------------------------------------------------------------------
-4:val a: Inv[String] = new Inv(new Inv(1))
- ^^^^^
- found: Inv[T]
- required: String
-
- where: T is a type variable with constraint >: Int(1)
+5 |val a: Inv[String] = new Inv(new Inv(1))
+ | ^^^^^
+ | found: Inv[T]
+ | required: String
+ |
+ | where: T is a type variable with constraint >: Int(1)
scala> val b: Inv[String] = new Inv(1)
-- [E006] Type Mismatch Error: <console> -------------------------------------------------------------------------------
-4:val b: Inv[String] = new Inv(1)
- ^
- found: Int(1)
- required: String
-
+5 |val b: Inv[String] = new Inv(1)
+ | ^
+ | found: Int(1)
+ | required: String
+ |
scala> abstract class C {
type T
val x: T
@@ -58,19 +58,19 @@ scala> abstract class C {
}
}
-- [E006] Type Mismatch Error: <console> -------------------------------------------------------------------------------
-8: var y: T = x
- ^
- found: C.this.T(C.this.x)
- required: T'
-
- where: T is a type in class C
- T' is a type in the initalizer of value s which is an alias of String
+9 | var y: T = x
+ | ^
+ | found: C.this.T(C.this.x)
+ | required: T'
+ |
+ | where: T is a type in class C
+ | T' is a type in the initalizer of value s which is an alias of String
-- [E006] Type Mismatch Error: <console> -------------------------------------------------------------------------------
-12: val z: T = y
- ^
- found: T(y)
- required: T'
-
- where: T is a type in the initalizer of value s which is an alias of String
- T' is a type in method f which is an alias of Int
+13 | val z: T = y
+ | ^
+ | found: T(y)
+ | required: T'
+ |
+ | where: T is a type in the initalizer of value s which is an alias of String
+ | T' is a type in method f which is an alias of Int
scala> :quit
diff --git a/tests/repl/imports.check b/tests/repl/imports.check
index 2e8d5dcf9..9743d2b94 100644
--- a/tests/repl/imports.check
+++ b/tests/repl/imports.check
@@ -8,17 +8,11 @@ scala> import o._
import o._
scala> buf += xs
-- [E006] Type Mismatch Error: <console> -------------------------------------------------------------------------------
-10:buf += xs
- ^^
- found: scala.collection.immutable.List[Int](o.xs)
- required: String
-
--- [E006] Type Mismatch Error: <console> -------------------------------------------------------------------------------
-10:buf += xs
- ^^^^^^^^^
- found: String
- required: scala.collection.mutable.ListBuffer[Int]
-
+11 |buf += xs
+ | ^^
+ | found: scala.collection.immutable.List[Int](o.xs)
+ | required: String
+ |
scala> buf ++= xs
res1: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3)
scala> :quit