Skip to content

Commit 890d74e

Browse files
slothspotallanrenucci
authored andcommitted
Remove old highlighter code and ignore tests with unsupported features
1 parent 9a4a064 commit 890d74e

File tree

5 files changed

+12
-345
lines changed

5 files changed

+12
-345
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 & 338 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,341 +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 (prefix, after) = remaining.span(interpolationPrefixes.contains)
84-
if (after.startsWith("\"")) {
85-
newBuf += n ++= prefix
86-
prev = prefix.lastOption.getOrElse(n)
87-
if (remaining.nonEmpty) takeChars(prefix.length + 1) // drop 1 for appendLiteral
88-
appendString('"', after.startsWith("\"\"\""), true)
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 == "\"\"", false)
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, inInterpolation: Boolean) = {
195-
var curr: Char = 0
196-
var continue = true
197-
var closing = 0
198-
newBuf append (LiteralColor + delim)
199-
200-
def shouldInterpolate =
201-
inInterpolation && curr == '$' && prev != '$' && remaining.nonEmpty
202-
203-
def interpolate() = {
204-
val next = takeChar()
205-
if (next == '$') {
206-
newBuf += curr
207-
newBuf += next
208-
prev = '$'
209-
} else if (next == '{') {
210-
var open = 1 // keep track of open blocks
211-
newBuf append (ValDefColor + curr)
212-
newBuf += next
213-
while (remaining.nonEmpty && open > 0) {
214-
var c = takeChar()
215-
newBuf += c
216-
if (c == '}') open -= 1
217-
else if (c == '{') open += 1
218-
}
219-
newBuf append LiteralColor
220-
} else {
221-
newBuf append (ValDefColor + curr)
222-
newBuf += next
223-
var c: Char = 'a'
224-
while (c.isLetterOrDigit && remaining.nonEmpty) {
225-
c = takeChar()
226-
if (c != '"') newBuf += c
227-
}
228-
newBuf append LiteralColor
229-
if (c == '"') {
230-
newBuf += c
231-
continue = false
232-
}
233-
}
234-
closing = 0
235-
}
236-
237-
while (continue && remaining.nonEmpty) {
238-
curr = takeChar()
239-
if (curr == '\\' && remaining.nonEmpty) {
240-
val next = takeChar()
241-
newBuf append (KeywordColor + curr)
242-
if (next == 'u') {
243-
val code = "u" + takeChars(4).mkString
244-
newBuf append code
245-
} else newBuf += next
246-
newBuf append LiteralColor
247-
closing = 0
248-
} else if (shouldInterpolate) {
249-
interpolate()
250-
} else if (curr == delim && multiline) {
251-
closing += 1
252-
if (closing == 3) continue = false
253-
newBuf += curr
254-
} else if (curr == delim) {
255-
continue = false
256-
newBuf += curr
257-
} else {
258-
newBuf += curr
259-
closing = 0
260-
}
261-
262-
if (Chars.isLineBreakChar(curr)) {
263-
newBuf append LiteralColor
264-
}
265-
}
266-
newBuf append NoColor
267-
prev = curr
268-
}
269-
270-
def appendSingleQuote(delim: Char) = remaining.take(3) match {
271-
case chr #:: '\'' #:: _ => // single character
272-
newBuf append LiteralColor
273-
newBuf appendAll s"'$chr'"
274-
newBuf append NoColor
275-
takeChars(2)
276-
prev = '\''
277-
case '\\' #:: chr #:: '\'' #:: _ => // escaped character
278-
newBuf append LiteralColor
279-
newBuf appendAll s"'\\$chr'"
280-
newBuf append NoColor
281-
takeChars(3)
282-
prev = '\''
283-
case _ => appendWhile(delim, !typeEnders.contains(_), literal)
284-
}
285-
286-
def append(c: Char, shouldHL: String => Boolean, highlight: String => String) = {
287-
var curr: Char = 0
288-
val sb = new StringBuilder(s"$c")
289-
290-
def delim(c: Char) = (c: @switch) match {
291-
case ' ' => true
292-
case '\n' => true
293-
case '(' => true
294-
case ')' => true
295-
case '[' => true
296-
case ']' => true
297-
case ':' => true
298-
case '@' => true
299-
case ',' => true
300-
case '.' => true
301-
case _ => false
302-
}
303-
304-
val valDefStarterTokens = "var" :: "val" :: "def" :: "case" :: Nil
305-
306-
/** lastValDefToken is used to check whether we want to show something
307-
* in valDef color or not. There are only a few cases when lastValDefToken
308-
* should be updated, that way we can avoid stopping coloring too early.
309-
* eg.: case A(x, y, z) => ???
310-
* Without this function only x would be colored.
311-
*/
312-
def updateLastToken(currentToken: String): String =
313-
(lastValDefToken, currentToken) match {
314-
case _ if valDefStarterTokens.contains(currentToken) => currentToken
315-
case (("val" | "var"), "=") => currentToken
316-
case ("case", ("=>" | "class" | "object")) => currentToken
317-
case ("def", _) => currentToken
318-
case _ => lastValDefToken
319-
}
320-
321-
while (remaining.nonEmpty && !delim(curr)) {
322-
curr = takeChar()
323-
if (!delim(curr)) sb += curr
324-
}
325-
326-
val str = sb.toString
327-
val toAdd =
328-
if (shouldHL(str))
329-
highlight(str)
330-
else if (valDefStarterTokens.contains(lastValDefToken) && !List("=", "=>").contains(str))
331-
valDef(str)
332-
else str
333-
val suffix = if (delim(curr)) s"$curr" else ""
334-
newBuf append (toAdd + suffix)
335-
lastValDefToken = updateLastToken(str)
336-
prev = curr
337-
}
338-
339-
def appendWhile(c: Char, pred: Char => Boolean, highlight: String => String) = {
340-
var curr: Char = 0
341-
val sb = new StringBuilder(s"$c")
342-
while (remaining.nonEmpty && pred(curr)) {
343-
curr = takeChar()
344-
if (pred(curr)) sb += curr
345-
}
346-
347-
val str = sb.toString
348-
val suffix = if (!pred(curr)) s"$curr" else ""
349-
newBuf append (highlight(str) + suffix)
350-
prev = curr
351-
}
352-
353-
def appendTo(c: Char, pred: Char => Boolean, highlight: String => String) = {
354-
var curr: Char = 0
355-
val sb = new StringBuilder(s"$c")
356-
while (remaining.nonEmpty && !pred(curr)) {
357-
curr = takeChar()
358-
sb += curr
359-
}
360-
361-
newBuf append highlight(sb.toString)
362-
prev = curr
363-
}
364-
365-
newBuf.toIterable
366-
}
367-
36831
private class NoReporter extends Reporter {
36932
override def doReport(m: MessageContainer)(implicit ctx: Context): Unit = ()
37033
}

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)