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