Skip to content

Commit d4b4a92

Browse files
committed
Remove old highlighter code and ignore tests with unsupported features
1 parent ed464b0 commit d4b4a92

File tree

5 files changed

+31
-346
lines changed

5 files changed

+31
-346
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ object Formatting {
8484
case hb: HighlightBuffer =>
8585
hb.toString
8686
case str: String if ctx.settings.color.value != "never" =>
87-
new String(SyntaxHighlighting(str).toArray)
87+
SyntaxHighlighting.highlight(str)(ctx)
8888
case _ => super.showArg(arg)
8989
}
9090
}

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

Lines changed: 1 addition & 339 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ import dotty.tools.dotc.reporting.Reporter
1111
import dotty.tools.dotc.reporting.diagnostic.MessageContainer
1212
import dotty.tools.dotc.util.Positions.Position
1313

14-
import scala.annotation.switch
15-
import scala.collection.mutable.StringBuilder
16-
import util.{Chars, SourceFile}
14+
import util.SourceFile
1715

1816
import scala.collection.mutable
1917

@@ -30,342 +28,6 @@ object SyntaxHighlighting {
3028
val TypeColor = Console.MAGENTA
3129
val AnnotationColor = Console.MAGENTA
3230

33-
private def none(str: String) = str
34-
private def keyword(str: String) = KeywordColor + str + NoColor
35-
private def typeDef(str: String) = TypeColor + str + NoColor
36-
private def literal(str: String) = LiteralColor + str + NoColor
37-
private def valDef(str: String) = ValDefColor + str + NoColor
38-
private def operator(str: String) = TypeColor + str + NoColor
39-
private def annotation(str: String) =
40-
if (str.trim == "@") str else { AnnotationColor + str + NoColor }
41-
private val tripleQs = Console.RED_B + "???" + NoColor
42-
43-
private val keywords: Seq[String] = for {
44-
index <- IF to ERASED // All alpha keywords
45-
} yield tokenString(index)
46-
47-
private val interpolationPrefixes =
48-
'A' :: 'B' :: 'C' :: 'D' :: 'E' :: 'F' :: 'G' :: 'H' :: 'I' :: 'J' :: 'K' ::
49-
'L' :: 'M' :: 'N' :: 'O' :: 'P' :: 'Q' :: 'R' :: 'S' :: 'T' :: 'U' :: 'V' ::
50-
'W' :: 'X' :: 'Y' :: 'Z' :: '$' :: '_' :: 'a' :: 'b' :: 'c' :: 'd' :: 'e' ::
51-
'f' :: 'g' :: 'h' :: 'i' :: 'j' :: 'k' :: 'l' :: 'm' :: 'n' :: 'o' :: 'p' ::
52-
'q' :: 'r' :: 's' :: 't' :: 'u' :: 'v' :: 'w' :: 'x' :: 'y' :: 'z' :: Nil
53-
54-
private val typeEnders =
55-
'{' :: '}' :: ')' :: '(' :: '[' :: ']' :: '=' :: ' ' :: ',' :: '.' :: '|' ::
56-
'&' :: '\n' :: Nil
57-
58-
def apply(chars: Iterable[Char]): Iterable[Char] = {
59-
var prev: Char = 0
60-
var remaining = chars.toStream
61-
val newBuf = new StringBuilder
62-
var lastValDefToken = ""
63-
64-
@inline def keywordStart =
65-
prev == 0 || prev == ' ' || prev == '{' || prev == '(' ||
66-
prev == '\n' || prev == '[' || prev == ',' || prev == ':' ||
67-
prev == '|' || prev == '&'
68-
69-
@inline def numberStart(c: Char) =
70-
c.isDigit && (!prev.isLetter || prev == '.' || prev == ' ' || prev == '(' || prev == '\u0000')
71-
72-
def takeChar(): Char = takeChars(1).head
73-
def takeChars(x: Int): Seq[Char] = {
74-
val taken = remaining.take(x)
75-
remaining = remaining.drop(x)
76-
taken
77-
}
78-
79-
while (remaining.nonEmpty) {
80-
val n = takeChar()
81-
if (interpolationPrefixes.contains(n)) {
82-
// Interpolation prefixes are a superset of the keyword start chars
83-
val next = remaining.take(3).mkString
84-
if (next.startsWith("\"")) {
85-
newBuf += n
86-
prev = n
87-
if (remaining.nonEmpty) takeChar() // drop 1 for appendLiteral
88-
appendString('"', next == "\"\"\"")
89-
} else {
90-
if (n.isUpper && (keywordStart || prev == '.')) {
91-
appendWhile(n, !typeEnders.contains(_), typeDef)
92-
} else if (keywordStart) {
93-
append(n, keywords.contains(_), { kw =>
94-
if (kw == "new") typeDef(kw) else keyword(kw)
95-
})
96-
} else {
97-
newBuf += n
98-
prev = n
99-
}
100-
}
101-
} else {
102-
(n: @switch) match {
103-
case '/' =>
104-
if (remaining.nonEmpty) {
105-
remaining.head match {
106-
case '/' =>
107-
takeChar()
108-
eolComment()
109-
case '*' =>
110-
takeChar()
111-
blockComment()
112-
case x =>
113-
newBuf += '/'
114-
}
115-
} else newBuf += '/'
116-
case '=' =>
117-
append('=', _ == "=>", operator)
118-
case '<' =>
119-
append('<', { x => x == "<-" || x == "<:" || x == "<%" }, operator)
120-
case '>' =>
121-
append('>', { x => x == ">:" }, operator)
122-
case '#' =>
123-
if (prev != ' ' && prev != '.') newBuf append operator("#")
124-
else newBuf += n
125-
prev = '#'
126-
case '@' =>
127-
appendWhile('@', !typeEnders.contains(_), annotation)
128-
case '\"' =>
129-
appendString('\"', multiline = remaining.take(2).mkString == "\"\"")
130-
case '\'' =>
131-
appendSingleQuote('\'')
132-
case '`' =>
133-
appendTo('`', _ == '`', none)
134-
case _ => {
135-
if (n == '?' && remaining.take(2).mkString == "??") {
136-
takeChars(2)
137-
newBuf append tripleQs
138-
prev = '?'
139-
}
140-
else if (n.isUpper && keywordStart)
141-
appendWhile(n, !typeEnders.contains(_), typeDef)
142-
else if (numberStart(n)) {
143-
def isNumber(c: Char): Boolean =
144-
c.isDigit || c == '\u0000' || (c == '.' && remaining.nonEmpty && remaining.head.isDigit)
145-
appendWhile(n, isNumber, literal)
146-
} else
147-
newBuf += n; prev = n
148-
}
149-
}
150-
}
151-
}
152-
153-
def eolComment() = {
154-
newBuf append (CommentColor + "//")
155-
var curr = '/'
156-
while (curr != '\n' && remaining.nonEmpty) {
157-
curr = takeChar()
158-
newBuf += curr
159-
}
160-
prev = curr
161-
newBuf append NoColor
162-
}
163-
164-
def blockComment() = {
165-
newBuf append (CommentColor + "/*")
166-
var curr = '*'
167-
var open = 1
168-
while (open > 0 && remaining.nonEmpty) {
169-
curr = takeChar()
170-
if (curr == '@') {
171-
appendWhile('@', !typeEnders.contains(_), annotation)
172-
newBuf append CommentColor
173-
}
174-
else newBuf += curr
175-
176-
if (curr == '*' && remaining.nonEmpty) {
177-
curr = takeChar()
178-
newBuf += curr
179-
if (curr == '/') open -= 1
180-
} else if (curr == '/' && remaining.nonEmpty) {
181-
curr = takeChar()
182-
newBuf += curr
183-
if (curr == '*') open += 1
184-
}
185-
186-
if (Chars.isLineBreakChar(curr)) {
187-
newBuf append CommentColor
188-
}
189-
}
190-
prev = curr
191-
newBuf append NoColor
192-
}
193-
194-
def appendString(delim: Char, multiline: Boolean = false) = {
195-
var curr: Char = 0
196-
var continue = true
197-
var closing = 0
198-
val inInterpolation = interpolationPrefixes.contains(prev)
199-
newBuf append (LiteralColor + delim)
200-
201-
def shouldInterpolate =
202-
inInterpolation && curr == '$' && prev != '$' && remaining.nonEmpty
203-
204-
def interpolate() = {
205-
val next = takeChar()
206-
if (next == '$') {
207-
newBuf += curr
208-
newBuf += next
209-
prev = '$'
210-
} else if (next == '{') {
211-
var open = 1 // keep track of open blocks
212-
newBuf append (ValDefColor + curr)
213-
newBuf += next
214-
while (remaining.nonEmpty && open > 0) {
215-
var c = takeChar()
216-
newBuf += c
217-
if (c == '}') open -= 1
218-
else if (c == '{') open += 1
219-
}
220-
newBuf append LiteralColor
221-
} else {
222-
newBuf append (ValDefColor + curr)
223-
newBuf += next
224-
var c: Char = 'a'
225-
while (c.isLetterOrDigit && remaining.nonEmpty) {
226-
c = takeChar()
227-
if (c != '"') newBuf += c
228-
}
229-
newBuf append LiteralColor
230-
if (c == '"') {
231-
newBuf += c
232-
continue = false
233-
}
234-
}
235-
closing = 0
236-
}
237-
238-
while (continue && remaining.nonEmpty) {
239-
curr = takeChar()
240-
if (curr == '\\' && remaining.nonEmpty) {
241-
val next = takeChar()
242-
newBuf append (KeywordColor + curr)
243-
if (next == 'u') {
244-
val code = "u" + takeChars(4).mkString
245-
newBuf append code
246-
} else newBuf += next
247-
newBuf append LiteralColor
248-
closing = 0
249-
} else if (shouldInterpolate) {
250-
interpolate()
251-
} else if (curr == delim && multiline) {
252-
closing += 1
253-
if (closing == 3) continue = false
254-
newBuf += curr
255-
} else if (curr == delim) {
256-
continue = false
257-
newBuf += curr
258-
} else {
259-
newBuf += curr
260-
closing = 0
261-
}
262-
263-
if (Chars.isLineBreakChar(curr)) {
264-
newBuf append LiteralColor
265-
}
266-
}
267-
newBuf append NoColor
268-
prev = curr
269-
}
270-
271-
def appendSingleQuote(delim: Char) = remaining.take(3) match {
272-
case chr #:: '\'' #:: _ => // single character
273-
newBuf append LiteralColor
274-
newBuf appendAll s"'$chr'"
275-
newBuf append NoColor
276-
takeChars(2)
277-
prev = '\''
278-
case '\\' #:: chr #:: '\'' #:: _ => // escaped character
279-
newBuf append LiteralColor
280-
newBuf appendAll s"'\\$chr'"
281-
newBuf append NoColor
282-
takeChars(3)
283-
prev = '\''
284-
case _ => appendWhile(delim, !typeEnders.contains(_), literal)
285-
}
286-
287-
def append(c: Char, shouldHL: String => Boolean, highlight: String => String) = {
288-
var curr: Char = 0
289-
val sb = new StringBuilder(s"$c")
290-
291-
def delim(c: Char) = (c: @switch) match {
292-
case ' ' => true
293-
case '\n' => true
294-
case '(' => true
295-
case ')' => true
296-
case '[' => true
297-
case ']' => true
298-
case ':' => true
299-
case '@' => true
300-
case ',' => true
301-
case '.' => true
302-
case _ => false
303-
}
304-
305-
val valDefStarterTokens = "var" :: "val" :: "def" :: "case" :: Nil
306-
307-
/** lastValDefToken is used to check whether we want to show something
308-
* in valDef color or not. There are only a few cases when lastValDefToken
309-
* should be updated, that way we can avoid stopping coloring too early.
310-
* eg.: case A(x, y, z) => ???
311-
* Without this function only x would be colored.
312-
*/
313-
def updateLastToken(currentToken: String): String =
314-
(lastValDefToken, currentToken) match {
315-
case _ if valDefStarterTokens.contains(currentToken) => currentToken
316-
case (("val" | "var"), "=") => currentToken
317-
case ("case", ("=>" | "class" | "object")) => currentToken
318-
case ("def", _) => currentToken
319-
case _ => lastValDefToken
320-
}
321-
322-
while (remaining.nonEmpty && !delim(curr)) {
323-
curr = takeChar()
324-
if (!delim(curr)) sb += curr
325-
}
326-
327-
val str = sb.toString
328-
val toAdd =
329-
if (shouldHL(str))
330-
highlight(str)
331-
else if (valDefStarterTokens.contains(lastValDefToken) && !List("=", "=>").contains(str))
332-
valDef(str)
333-
else str
334-
val suffix = if (delim(curr)) s"$curr" else ""
335-
newBuf append (toAdd + suffix)
336-
lastValDefToken = updateLastToken(str)
337-
prev = curr
338-
}
339-
340-
def appendWhile(c: Char, pred: Char => Boolean, highlight: String => String) = {
341-
var curr: Char = 0
342-
val sb = new StringBuilder(s"$c")
343-
while (remaining.nonEmpty && pred(curr)) {
344-
curr = takeChar()
345-
if (pred(curr)) sb += curr
346-
}
347-
348-
val str = sb.toString
349-
val suffix = if (!pred(curr)) s"$curr" else ""
350-
newBuf append (highlight(str) + suffix)
351-
prev = curr
352-
}
353-
354-
def appendTo(c: Char, pred: Char => Boolean, highlight: String => String) = {
355-
var curr: Char = 0
356-
val sb = new StringBuilder(s"$c")
357-
while (remaining.nonEmpty && !pred(curr)) {
358-
curr = takeChar()
359-
sb += curr
360-
}
361-
362-
newBuf append highlight(sb.toString)
363-
prev = curr
364-
}
365-
366-
newBuf.toIterable
367-
}
368-
36931
private class NoReporter extends Reporter {
37032
override def doReport(m: MessageContainer)(implicit ctx: Context): Unit = ()
37133
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ trait MessageRendering {
6262

6363
val syntax =
6464
if (ctx.settings.color.value != "never")
65-
SyntaxHighlighting(pos.linesSlice).toArray
65+
SyntaxHighlighting.highlight(pos.linesSlice.mkString)(ctx).toArray
6666
else pos.linesSlice
6767
val lines = linesFrom(syntax)
6868
val (before, after) = pos.beforeAndAfterPoint

0 commit comments

Comments
 (0)