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