diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyAnsiiPrinter.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyAnsiiPrinter.scala new file mode 100644 index 000000000000..d8d72a4e651e --- /dev/null +++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyAnsiiPrinter.scala @@ -0,0 +1,9 @@ +package dotty.tools.dotc +package core +package tasty + +class TastyAnsiiPrinter(bytes: Array[Byte]) extends TastyPrinter(bytes) { + override protected def nameStr(str: String): String = Console.MAGENTA + str + Console.RESET + override protected def treeStr(str: String): String = Console.YELLOW + str + Console.RESET + override protected def lengthStr(str: String): String = Console.CYAN + str + Console.RESET +} diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyHTMLPrinter.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyHTMLPrinter.scala index 28766cc9ff06..b234705413ae 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TastyHTMLPrinter.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyHTMLPrinter.scala @@ -2,16 +2,8 @@ package dotty.tools.dotc package core package tasty -import dotty.tools.tasty.TastyBuffer.NameRef - -import Contexts._, Decorators._ -import Names.Name -import TastyUnpickler._ -import util.Spans.offsetToInt -import printing.Highlighting._ - -class TastyHTMLPrinter(bytes: Array[Byte])(using Context) extends TastyPrinter(bytes) { - override protected def nameColor(str: String): String = s"$str" - override protected def treeColor(str: String): String = s"$str" - override protected def lengthColor(str: String): String = s"$str" +class TastyHTMLPrinter(bytes: Array[Byte]) extends TastyPrinter(bytes) { + override protected def nameStr(str: String): String = s"$str" + override protected def treeStr(str: String): String = s"$str" + override protected def lengthStr(str: String): String = s"$str" } diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyPrinter.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyPrinter.scala index f2ed4df5422c..9d8d6654a138 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TastyPrinter.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyPrinter.scala @@ -11,24 +11,31 @@ import TastyUnpickler._ import util.Spans.offsetToInt import printing.Highlighting._ -class TastyPrinter(bytes: Array[Byte])(using Context) { +object TastyPrinter: + def show(bytes: Array[Byte])(using Context): String = + val printer = + if ctx.settings.color.value == "never" then new TastyPrinter(bytes) + else new TastyAnsiiPrinter(bytes) + printer.showContents() + +class TastyPrinter(bytes: Array[Byte]) { private val sb: StringBuilder = new StringBuilder - val unpickler: TastyUnpickler = new TastyUnpickler(bytes) + private val unpickler: TastyUnpickler = new TastyUnpickler(bytes) import unpickler.{nameAtRef, unpickle} - def nameToString(name: Name): String = name.debugString + private def nameToString(name: Name): String = name.debugString - def nameRefToString(ref: NameRef): String = nameToString(nameAtRef(ref)) + private def nameRefToString(ref: NameRef): String = nameToString(nameAtRef(ref)) - def printNames(): Unit = + private def printNames(): Unit = for ((name, idx) <- nameAtRef.contents.zipWithIndex) { - val index = nameColor("%4d".format(idx)) + val index = nameStr("%4d".format(idx)) sb.append(index).append(": ").append(nameToString(name)).append("\n") } - def printContents(): String = { + def showContents(): String = { sb.append("Names:\n") printNames() sb.append("\n") @@ -59,13 +66,13 @@ class TastyPrinter(bytes: Array[Byte])(using Context) { import reader._ var indent = 0 def newLine() = { - val length = treeColor("%5d".format(index(currentAddr) - index(startAddr))) + val length = treeStr("%5d".format(index(currentAddr) - index(startAddr))) sb.append(s"\n $length:" + " " * indent) } - def printNat() = sb.append(treeColor(" " + readNat())) + def printNat() = sb.append(treeStr(" " + readNat())) def printName() = { val idx = readNat() - sb.append(nameColor(" " + idx + " [" + nameRefToString(NameRef(idx)) + "]")) + sb.append(nameStr(" " + idx + " [" + nameRefToString(NameRef(idx)) + "]")) } def printTree(): Unit = { newLine() @@ -74,7 +81,7 @@ class TastyPrinter(bytes: Array[Byte])(using Context) { indent += 2 if (tag >= firstLengthTreeTag) { val len = readNat() - sb.append(s"(${lengthColor(len.toString)})") + sb.append(s"(${lengthStr(len.toString)})") val end = currentAddr + len def printTrees() = until(end)(printTree()) tag match { @@ -116,7 +123,7 @@ class TastyPrinter(bytes: Array[Byte])(using Context) { } indent -= 2 } - sb.append(i"start = ${reader.startAddr}, base = $base, current = $currentAddr, end = $endAddr\n") + sb.append(s"start = ${reader.startAddr}, base = $base, current = $currentAddr, end = $endAddr\n") sb.append(s"${endAddr.index - startAddr.index} bytes of AST, base = $currentAddr\n") while (!isAtEnd) { printTree() @@ -136,7 +143,7 @@ class TastyPrinter(bytes: Array[Byte])(using Context) { sb.append(s" position bytes:\n") val sorted = spans.toSeq.sortBy(_._1.index) for ((addr, pos) <- sorted) { - sb.append(treeColor("%10d".format(addr.index))) + sb.append(treeStr("%10d".format(addr.index))) sb.append(s": ${offsetToInt(pos.start)} .. ${pos.end}\n") } sb.result @@ -153,14 +160,14 @@ class TastyPrinter(bytes: Array[Byte])(using Context) { sb.append(s" comment bytes:\n") val sorted = comments.toSeq.sortBy(_._1.index) for ((addr, cmt) <- sorted) { - sb.append(treeColor("%10d".format(addr.index))) + sb.append(treeStr("%10d".format(addr.index))) sb.append(s": ${cmt.raw} (expanded = ${cmt.isExpanded})\n") } sb.result } } - protected def nameColor(str: String): String = Magenta(str).show - protected def treeColor(str: String): String = Yellow(str).show - protected def lengthColor(str: String): String = Cyan(str).show + protected def nameStr(str: String): String = str + protected def treeStr(str: String): String = str + protected def lengthStr(str: String): String = str } diff --git a/compiler/src/dotty/tools/dotc/decompiler/DecompilationPrinter.scala b/compiler/src/dotty/tools/dotc/decompiler/DecompilationPrinter.scala index 7b58237133bf..ee74ac83d3b8 100644 --- a/compiler/src/dotty/tools/dotc/decompiler/DecompilationPrinter.scala +++ b/compiler/src/dotty/tools/dotc/decompiler/DecompilationPrinter.scala @@ -40,7 +40,7 @@ class DecompilationPrinter extends Phase { private def printToOutput(out: PrintStream)(using Context): Unit = { val unit = ctx.compilationUnit if (ctx.settings.printTasty.value) - println(new TastyPrinter(unit.pickled.head._2()).printContents()) + println(TastyPrinter.show(unit.pickled.head._2())) else { val unitFile = unit.source.toString.replace("\\", "/").replace(".class", ".tasty") out.println(s"/** Decompiled from $unitFile */") diff --git a/compiler/src/dotty/tools/dotc/decompiler/IDEDecompilerDriver.scala b/compiler/src/dotty/tools/dotc/decompiler/IDEDecompilerDriver.scala index bd8a668ff4d4..6e5d96170451 100644 --- a/compiler/src/dotty/tools/dotc/decompiler/IDEDecompilerDriver.scala +++ b/compiler/src/dotty/tools/dotc/decompiler/IDEDecompilerDriver.scala @@ -35,7 +35,7 @@ class IDEDecompilerDriver(val settings: List[String]) extends dotc.Driver { val unit = ctx.run.units.head val decompiled = QuoteContextImpl.showTree(unit.tpdTree) - val tree = new TastyHTMLPrinter(unit.pickled.head._2()).printContents() + val tree = new TastyHTMLPrinter(unit.pickled.head._2()).showContents() reporter.removeBufferedMessages.foreach(message => System.err.println(message)) (tree, decompiled) diff --git a/compiler/src/dotty/tools/dotc/quoted/PickledQuotes.scala b/compiler/src/dotty/tools/dotc/quoted/PickledQuotes.scala index 098927670e3b..efb3f7e0291e 100644 --- a/compiler/src/dotty/tools/dotc/quoted/PickledQuotes.scala +++ b/compiler/src/dotty/tools/dotc/quoted/PickledQuotes.scala @@ -173,14 +173,14 @@ object PickledQuotes { positionWarnings.foreach(report.warning(_)) val pickled = pickler.assembleParts() - quotePickling.println(s"**** pickled quote\n${new TastyPrinter(pickled).printContents()}") + quotePickling.println(s"**** pickled quote\n${TastyPrinter.show(pickled)}") pickled } /** Unpickle TASTY bytes into it's tree */ private def unpickle(pickledQuote: PickledQuote, isType: Boolean)(using Context): Tree = { val bytes = pickledQuote.bytes() - quotePickling.println(s"**** unpickling quote from TASTY\n${new TastyPrinter(bytes).printContents()}") + quotePickling.println(s"**** unpickling quote from TASTY\n${TastyPrinter.show(bytes)}") val mode = if (isType) UnpickleMode.TypeTree else UnpickleMode.Term val unpickler = new DottyUnpickler(bytes, mode) diff --git a/compiler/src/dotty/tools/dotc/transform/Pickler.scala b/compiler/src/dotty/tools/dotc/transform/Pickler.scala index 8999714958c6..c79796dc804a 100644 --- a/compiler/src/dotty/tools/dotc/transform/Pickler.scala +++ b/compiler/src/dotty/tools/dotc/transform/Pickler.scala @@ -90,7 +90,7 @@ class Pickler extends Phase { if pickling ne noPrinter then pickling.synchronized { println(i"**** pickled info of $cls") - println(new TastyPrinter(pickled).printContents()) + println(TastyPrinter.show(pickled)) } pickled }(using ExecutionContext.global)