@@ -2,10 +2,20 @@ package dotty.tools
2
2
package dotc
3
3
package printing
4
4
5
- import parsing .Tokens ._
5
+ import dotty .tools .dotc .core .Contexts .Context
6
+ import dotty .tools .dotc .core .StdNames ._
7
+ import dotty .tools .dotc .parsing .Parsers .Parser
8
+ import dotty .tools .dotc .parsing .Scanners .Scanner
9
+ import dotty .tools .dotc .parsing .Tokens ._
10
+ import dotty .tools .dotc .reporting .Reporter
11
+ import dotty .tools .dotc .reporting .diagnostic .MessageContainer
12
+ import dotty .tools .dotc .util .Positions .Position
13
+
6
14
import scala .annotation .switch
7
15
import scala .collection .mutable .StringBuilder
8
- import util .Chars
16
+ import util .{Chars , SourceFile }
17
+
18
+ import scala .collection .mutable
9
19
10
20
/** This object provides functions for syntax highlighting in the REPL */
11
21
object SyntaxHighlighting {
@@ -354,4 +364,85 @@ object SyntaxHighlighting {
354
364
355
365
newBuf.toIterable
356
366
}
367
+
368
+ private class NoReporter extends Reporter {
369
+ override def doReport (m : MessageContainer )(implicit ctx : Context ): Unit = ()
370
+ }
371
+
372
+ def highlight (in : String )(ctx0 : Context ): String = {
373
+ import dotty .tools .dotc .ast .untpd ._
374
+
375
+ implicit val ctx : Context = ctx0.fresh.setReporter(new NoReporter )
376
+
377
+ val sf = new SourceFile (" <highlighting>" , in.toCharArray)
378
+ val p = new Parser (sf)
379
+ val s = new Scanner (sf)
380
+ val trees = p.blockStatSeq()
381
+
382
+ val outputH = Array .fill(in.length)(NoColor )
383
+
384
+ def highlightRange (p : Position , color : String ): Unit = {
385
+ if (p.exists) {
386
+ for {
387
+ i <- p.start until math.min(p.end, outputH.length)
388
+ } outputH(i) = color
389
+ }
390
+ }
391
+
392
+ val treeTraverser = new UntypedTreeTraverser {
393
+ def traverse (tree : Tree )(implicit ctx : Context ): Unit = {
394
+ tree match {
395
+ case tpe : TypeDef =>
396
+ highlightRange(tpe.namePos, TypeColor )
397
+ case _ : TypTree =>
398
+ highlightRange(tree.pos, TypeColor )
399
+ case mod : ModuleDef =>
400
+ highlightRange(mod.namePos, TypeColor )
401
+ case v : ValOrDefDef =>
402
+ highlightRange(v.namePos, ValDefColor )
403
+ highlightRange(v.tpt.pos, TypeColor )
404
+ case _ : Literal =>
405
+ highlightRange(tree.pos, LiteralColor )
406
+ case _ =>
407
+ }
408
+ traverseChildren(tree)
409
+ }
410
+ }
411
+
412
+ for {
413
+ t <- trees
414
+ } {
415
+ treeTraverser.traverse(t)
416
+ }
417
+
418
+ val sb = new mutable.StringBuilder ()
419
+
420
+ while (s.token != EOF ) {
421
+ val isKwd = isKeyword(s.token)
422
+ val offsetStart = s.offset
423
+
424
+
425
+ if (s.token == IDENTIFIER && s.name == nme.??? ) {
426
+ highlightRange(Position (s.offset, s.offset + s.name.length), Console .RED_B )
427
+ }
428
+ s.nextToken()
429
+
430
+ if (isKwd) {
431
+ val offsetEnd = s.lastOffset
432
+ highlightRange(Position (offsetStart, offsetEnd), KeywordColor )
433
+ }
434
+ }
435
+
436
+ for {
437
+ idx <- outputH.indices
438
+ } {
439
+ if (idx == 0 || outputH(idx- 1 ) != outputH(idx)){
440
+ sb.append(outputH(idx))
441
+ }
442
+ sb.append(in(idx))
443
+ }
444
+ sb.append(NoColor )
445
+
446
+ sb.mkString
447
+ }
357
448
}
0 commit comments