Skip to content

Commit f3a61ea

Browse files
committed
Message rendering: colorize positional splice, then split
1 parent cc26359 commit f3a61ea

File tree

4 files changed

+55
-18
lines changed

4 files changed

+55
-18
lines changed

compiler/src/dotty/tools/dotc/printing/SyntaxHighlighting.scala

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import parsing.Tokens._
66
import scala.annotation.switch
77
import scala.collection.mutable.StringBuilder
88
import core.Contexts.Context
9+
import util.Chars.{ LF, FF, CR, SU }
910
import Highlighting.{Highlight, HighlightBuffer}
1011

1112
/** This object provides functions for syntax highlighting in the REPL */
@@ -26,7 +27,7 @@ object SyntaxHighlighting {
2627
private def valDef(str: String) = ValDefColor + str + NoColor
2728
private def operator(str: String) = TypeColor + str + NoColor
2829
private def annotation(str: String) =
29-
if (str.trim == "@") str else AnnotationColor + str + NoColor
30+
if (str.trim == "@") str else { AnnotationColor + str + NoColor }
3031
private val tripleQs = Console.RED_B + "???" + NoColor
3132

3233
private val keywords: Seq[String] = for {
@@ -152,7 +153,11 @@ object SyntaxHighlighting {
152153
var open = 1
153154
while (open > 0 && remaining.nonEmpty) {
154155
curr = takeChar()
155-
newBuf += curr
156+
if (curr == '@') {
157+
appendWhile('@', !typeEnders.contains(_), annotation)
158+
newBuf append CommentColor
159+
}
160+
else newBuf += curr
156161

157162
if (curr == '*' && remaining.nonEmpty) {
158163
curr = takeChar()
@@ -163,6 +168,11 @@ object SyntaxHighlighting {
163168
newBuf += curr
164169
if (curr == '*') open += 1
165170
}
171+
172+
(curr: @switch) match {
173+
case LF | FF | CR | SU => newBuf append CommentColor
174+
case _ => ()
175+
}
166176
}
167177
prev = curr
168178
newBuf append NoColor
@@ -236,6 +246,11 @@ object SyntaxHighlighting {
236246
newBuf += curr
237247
closing = 0
238248
}
249+
250+
(curr: @switch) match {
251+
case LF | FF | CR | SU => newBuf append LiteralColor
252+
case _ => ()
253+
}
239254
}
240255
newBuf append NoColor
241256
prev = curr

compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@ package reporting
55
import core.Contexts.Context
66
import core.Decorators._
77
import printing.Highlighting.{Blue, Red}
8+
import printing.SyntaxHighlighting
89
import diagnostic.{ErrorMessageID, Message, MessageContainer, NoExplanation}
910
import diagnostic.messages._
1011
import util.SourcePosition
12+
import util.Chars.{ LF, CR, FF, SU }
13+
import scala.annotation.switch
1114

1215
import scala.collection.mutable
1316

@@ -38,20 +41,36 @@ trait MessageRendering {
3841
*/
3942
def sourceLines(pos: SourcePosition)(implicit ctx: Context): (List[String], List[String], Int) = {
4043
var maxLen = Int.MinValue
41-
def render(xs: List[Int]) =
42-
xs.map(pos.source.offsetToLine(_))
43-
.map { lineNbr =>
44-
val prefix = s"${lineNbr + 1} |"
45-
maxLen = math.max(maxLen, prefix.length)
46-
(prefix, pos.lineContent(lineNbr).stripLineEnd)
47-
}
48-
.map { case (prefix, line) =>
49-
val lnum = Red(" " * math.max(0, maxLen - prefix.length) + prefix)
50-
hl"$lnum$line"
51-
}
44+
def render(offset: Int, line: String): String = {
45+
val lineNbr = pos.source.offsetToLine(offset)
46+
val prefix = s"${lineNbr + 1} |"
47+
maxLen = math.max(maxLen, prefix.length)
48+
val lnum = Red(" " * math.max(0, maxLen - prefix.length) + prefix).show
49+
lnum + line.stripLineEnd
50+
}
51+
52+
def linesFrom(arr: Array[Char]): List[String] = {
53+
def pred(c: Char) = (c: @switch) match {
54+
case LF | CR | FF | SU => true
55+
case _ => false
56+
}
57+
val (line, rest0) = arr.span(!pred(_))
58+
val (_, rest) = rest0.span(pred)
59+
new String(line) :: { if (rest.isEmpty) Nil else linesFrom(rest) }
60+
}
5261

62+
val syntax =
63+
if (ctx.settings.color.value != "never")
64+
SyntaxHighlighting(pos.linesSlice).toArray
65+
else pos.linesSlice
66+
val lines = linesFrom(syntax)
5367
val (before, after) = pos.beforeAndAfterPoint
54-
(render(before), render(after), maxLen)
68+
69+
(
70+
before.zip(lines).map { case (n, str) => render(n, str) },
71+
after.zip(lines.drop(before.length)).map { case (n, str) => render(n, str) },
72+
maxLen
73+
)
5574
}
5675

5776
/** The column markers aligned under the error */

compiler/src/dotty/tools/dotc/util/SourcePosition.scala

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,14 @@ extends interfaces.SourcePosition {
1212
def lineContent: String = source.lineContent(point)
1313

1414
def point: Int = pos.point
15+
1516
/** The line of the position, starting at 0 */
1617
def line: Int = source.offsetToLine(point)
1718

19+
/** Extracts the lines from the underlying source file as `Array[Char]`*/
20+
def linesSlice: Array[Char] =
21+
source.content.slice(source.startOfLine(start), source.nextLine(end))
22+
1823
/** The lines of the position */
1924
def lines: List[Int] =
2025
List.range(source.offsetToLine(start), source.offsetToLine(end + 1)) match {
@@ -25,9 +30,6 @@ extends interfaces.SourcePosition {
2530
def lineOffsets: List[Int] =
2631
lines.map(source.lineToOffset(_))
2732

28-
def lineContent(lineNumber: Int): String =
29-
source.lineContent(source.lineToOffset(lineNumber))
30-
3133
def beforeAndAfterPoint: (List[Int], List[Int]) =
3234
lineOffsets.partition(_ <= point)
3335

doc-tool/src/dotty/tools/dottydoc/model/comment/CommentParser.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import dotty.tools.dottydoc.util.syntax._
66
import dotty.tools.dotc.util.Positions._
77
import dotty.tools.dotc.core.Symbols._
88
import dotty.tools.dotc.core.Contexts.Context
9+
import dotty.tools.dotc.core.Decorators._
910
import scala.collection.mutable
1011
import dotty.tools.dotc.config.Printers.dottydoc
1112
import scala.util.matching.Regex
@@ -196,7 +197,7 @@ trait CommentParser extends util.MemberLookup {
196197
)
197198

198199
for ((key, _) <- bodyTags) ctx.docbase.warn(
199-
s"Tag '@${key.name}' is not recognised",
200+
hl"Tag '${"@" + key.name}' is not recognised",
200201
// FIXME: here the position is stretched out over the entire comment,
201202
// with the point being at the very end. This ensures that the entire
202203
// comment will be visible in error reporting. A more fine-grained

0 commit comments

Comments
 (0)