From 5f2d0461489c62c8b5348225db66b6ac844959b6 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Sat, 20 May 2017 17:49:20 +0200 Subject: [PATCH] Fix #2063: Print tabs in message padding --- .../dotc/reporting/MessageRendering.scala | 17 ++++++-------- .../dotty/tools/dotc/util/SourceFile.scala | 11 ++++++++++ .../tools/dotc/util/SourcePosition.scala | 1 + tests/repl/i2063.check | 22 +++++++++++++++++++ 4 files changed, 41 insertions(+), 10 deletions(-) create mode 100644 tests/repl/i2063.check diff --git a/compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala b/compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala index 98af775dabcf..dfdcbde73a66 100644 --- a/compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala +++ b/compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala @@ -77,14 +77,13 @@ trait MessageRendering { /** The column markers aligned under the error */ def columnMarker(pos: SourcePosition, offset: Int)(implicit ctx: Context): String = { val prefix = " " * (offset - 1) - val whitespace = " " * pos.startColumn + val padding = pos.startColumnPadding val carets = Red { if (pos.startLine == pos.endLine) "^" * math.max(1, pos.endColumn - pos.startColumn) else "^" } - - s"$prefix|$whitespace${carets.show}" + s"$prefix|$padding${carets.show}" } /** The error message (`msg`) aligned under `pos` @@ -92,18 +91,16 @@ trait MessageRendering { * @return aligned error message */ def errorMsg(pos: SourcePosition, msg: String, offset: Int)(implicit ctx: Context): String = { - val leastWhitespace = msg.lines.foldLeft(Int.MaxValue) { (minPad, line) => + val padding = msg.lines.foldLeft(pos.startColumnPadding) { (pad, line) => val lineLength = stripColor(line).length - val currPad = math.min( - math.max(0, ctx.settings.pageWidth.value - offset - lineLength), - offset + pos.startColumn - ) + val maxPad = math.max(0, ctx.settings.pageWidth.value - offset - lineLength) - offset - math.min(currPad, minPad) + if (maxPad < pad.length) " " * maxPad + else pad } msg.lines - .map { line => " " * (offset - 1) + "|" + (" " * (leastWhitespace - offset)) + line} + .map { line => " " * (offset - 1) + "|" + padding + line} .mkString(sys.props("line.separator")) } diff --git a/compiler/src/dotty/tools/dotc/util/SourceFile.scala b/compiler/src/dotty/tools/dotc/util/SourceFile.scala index 1a17fb8ee445..a9a18f91cbfa 100644 --- a/compiler/src/dotty/tools/dotc/util/SourceFile.scala +++ b/compiler/src/dotty/tools/dotc/util/SourceFile.scala @@ -136,6 +136,17 @@ case class SourceFile(file: AbstractFile, content: Array[Char]) extends interfac col } + /** The padding of the column corresponding to `offset`, includes tabs */ + def startColumnPadding(offset: Int): String = { + var idx = startOfLine(offset) + val pad = new StringBuilder + while (idx != offset) { + pad.append(if (idx < length && content(idx) == '\t') '\t' else ' ') + idx += 1 + } + pad.result() + } + override def toString = file.toString } diff --git a/compiler/src/dotty/tools/dotc/util/SourcePosition.scala b/compiler/src/dotty/tools/dotc/util/SourcePosition.scala index be5c469952be..85c2f42d53d8 100644 --- a/compiler/src/dotty/tools/dotc/util/SourcePosition.scala +++ b/compiler/src/dotty/tools/dotc/util/SourcePosition.scala @@ -39,6 +39,7 @@ extends interfaces.SourcePosition { def start: Int = pos.start def startLine: Int = source.offsetToLine(start) def startColumn: Int = source.column(start) + def startColumnPadding: String = source.startColumnPadding(start) def end: Int = pos.end def endLine: Int = source.offsetToLine(end) diff --git a/tests/repl/i2063.check b/tests/repl/i2063.check new file mode 100644 index 000000000000..4cfee5d03b20 --- /dev/null +++ b/tests/repl/i2063.check @@ -0,0 +1,22 @@ +scala> class Foo extends Bar // with one tab +-- [E006] Unbound Identifier Error: :4:18 ----------------------------- +4 | class Foo extends Bar // with one tab + | ^^^ + | not found: type Bar + +longer explanation available when compiling with `-explain` +scala> class Foo extends Bar // with spaces +-- [E006] Unbound Identifier Error: :4:96 ----------------------------- +4 | class Foo extends Bar // with spaces + | ^^^ + | not found: type Bar + +longer explanation available when compiling with `-explain` +scala> class Foo extends Bar // with tabs +-- [E006] Unbound Identifier Error: :4:99 ----------------------------- +4 | class Foo extends Bar // with tabs + | ^^^ + | not found: type Bar + +longer explanation available when compiling with `-explain` +scala> :quit