@@ -374,83 +374,84 @@ object SyntaxHighlighting {
374374 override def doReport (m : MessageContainer )(implicit ctx : Context ): Unit = ()
375375 }
376376
377- private val ignoredKwds = Seq (nme.ARROWkw , nme.EQ , nme.EQL , nme.COLONkw )
377+ private val ignoredKwds = Set (nme.ARROWkw , nme.EQ , nme.EQL , nme.COLONkw )
378378
379379 def highlight (in : String )(ctx0 : Context ): String = {
380380 import dotty .tools .dotc .ast .untpd ._
381381
382382 implicit val ctx : Context = ctx0.fresh.setReporter(new NoReporter )
383383
384- val sf = new SourceFile (" <highlighting>" , in.toCharArray)
385- val p = new Parser (sf)
386- val s = new Scanner (sf)
387- val trees = p.blockStatSeq()
384+ val source = new SourceFile (" <highlighting>" , in.toCharArray)
385+ val parser = new Parser (source)
386+ val trees = parser.blockStatSeq()
388387
389- val outputH = Array .fill(in.length)(NoColor )
388+ val colorAt = Array .fill(in.length)(NoColor )
390389
391- def highlightRange (p : Position , color : String ): Unit = {
392- if (p.exists) {
393- for {
394- i <- p.start until math.min(p.end, outputH.length)
395- } outputH(i) = color
390+ def highlightRange (from : Int , to : Int , color : String ) = {
391+ try {
392+ for (i <- from until to)
393+ colorAt(i) = color
394+ } catch {
395+ case _ : IndexOutOfBoundsException =>
396+ ctx.error(" Encountered tree with invalid position, please open an issue with the code snippet that caused the error" )
396397 }
397398 }
399+ def highlightPosition (pos : Position , color : String ) =
400+ if (pos.exists) highlightRange(pos.start, pos.end, color)
398401
399- val treeTraverser = new UntypedTreeTraverser {
402+ val treeHighlighter = new UntypedTreeTraverser {
400403 def traverse (tree : Tree )(implicit ctx : Context ): Unit = {
401404 tree match {
402405 case tpe : TypeDef =>
403- highlightRange (tpe.namePos, TypeColor )
406+ highlightPosition (tpe.namePos, TypeColor )
404407 case _ : TypTree =>
405- highlightRange (tree.pos, TypeColor )
408+ highlightPosition (tree.pos, TypeColor )
406409 case mod : ModuleDef =>
407- highlightRange (mod.namePos, TypeColor )
410+ highlightPosition (mod.namePos, TypeColor )
408411 case v : ValOrDefDef =>
409- highlightRange (v.namePos, ValDefColor )
410- highlightRange (v.tpt.pos, TypeColor )
412+ highlightPosition (v.namePos, ValDefColor )
413+ highlightPosition (v.tpt.pos, TypeColor )
411414 case _ : Literal =>
412- highlightRange (tree.pos, LiteralColor )
415+ highlightPosition (tree.pos, LiteralColor )
413416 case _ =>
414417 }
415418 traverseChildren(tree)
416419 }
417420 }
418421
419- for {
420- t <- trees
421- } {
422- treeTraverser.traverse(t)
423- }
422+ for (tree <- trees)
423+ treeHighlighter.traverse(tree)
424424
425- val sb = new mutable. StringBuilder ( )
425+ val scanner = new Scanner (source )
426426
427- while (s .token != EOF ) {
428- val isKwd = isKeyword(s .token) && ! ignoredKwds.contains(s .name)
429- val offsetStart = s .offset
427+ while (scanner .token != EOF ) {
428+ val isKwd = isKeyword(scanner .token) && ! ignoredKwds.contains(scanner .name)
429+ val offsetStart = scanner .offset
430430
431- if (s .token == IDENTIFIER && s .name == nme.??? ) {
432- highlightRange(Position (s .offset, s .offset + s .name.length) , Console .RED_B )
431+ if (scanner .token == IDENTIFIER && scanner .name == nme.??? ) {
432+ highlightRange(scanner .offset, scanner .offset + scanner .name.length, Console .RED_B )
433433 }
434- s .nextToken()
434+ scanner .nextToken()
435435
436- if (isKwd) {
437- val offsetEnd = s .lastOffset
438- highlightRange (Position (offsetStart, offsetEnd), KeywordColor )
436+ if (isKwd) {
437+ val offsetEnd = scanner .lastOffset
438+ highlightPosition (Position (offsetStart, offsetEnd), KeywordColor )
439439 }
440440 }
441441
442- for {
443- idx <- outputH.indices
444- } {
445- if (idx == 0 || outputH(idx- 1 ) != outputH(idx)){
446- sb.append(outputH(idx))
442+ val sb = new mutable.StringBuilder ()
443+
444+ for (idx <- colorAt.indices) {
445+ if ( (idx == 0 && colorAt(idx) != NoColor )
446+ || (idx > 0 && colorAt(idx- 1 ) != colorAt(idx))) {
447+ sb.append(colorAt(idx))
447448 }
448449 sb.append(in(idx))
449450 }
450- if (outputH .last != NoColor ) {
451+ if (colorAt.nonEmpty && colorAt .last != NoColor ) {
451452 sb.append(NoColor )
452453 }
453454
454- sb.mkString
455+ sb.toString
455456 }
456457}
0 commit comments