Skip to content

Commit 90b7514

Browse files
committed
Decouple -print-tasty from compiler
To print the contents of a tasty file we only need the bytes of the file. The current architecture forced us to load the context and have a wroking classpath. When debugging, we sometimes need to see the contents of a tasty file witouth having the full classpath available. * Use `dotty.tools.dotc.core.TastyPrinter.main` as new entry point * Decouple `-decompile` from `-print-tasty` * Only require .tasty file to be able to print its contents * Keep the same CLI commands and flags
1 parent 38b983c commit 90b7514

File tree

9 files changed

+66
-39
lines changed

9 files changed

+66
-39
lines changed

compiler/src/dotty/tools/dotc/core/tasty/TastyPrinter.scala

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,42 @@ import TastyUnpickler._
1111
import util.Spans.offsetToInt
1212
import printing.Highlighting._
1313
import dotty.tools.tasty.TastyFormat.{ASTsSection, PositionsSection, CommentsSection}
14+
import java.nio.file.{Files, Paths}
1415

1516
object TastyPrinter:
16-
def show(bytes: Array[Byte])(using Context): String =
17+
18+
def showContents(bytes: Array[Byte], noColor: Boolean): String =
1719
val printer =
18-
if ctx.settings.color.value == "never" then new TastyPrinter(bytes)
20+
if noColor then new TastyPrinter(bytes)
1921
else new TastyAnsiiPrinter(bytes)
2022
printer.showContents()
2123

24+
def main(args: Array[String]): Unit = {
25+
// TODO: Decouple CliCommand from Context and use CliCommand.distill?
26+
val lineWidth = 80
27+
val line = "-" * lineWidth
28+
val noColor = args.contains("-color:never")
29+
var printLastLine = false
30+
for arg <- args if arg != "-print-tasty" do
31+
if arg == "-print-tasty" || arg == "-color:never" then () // skip
32+
else if arg.startsWith("-") then println(s"bad option '$arg' was ignored")
33+
else if !arg.endsWith(".tasty") then println(s"Not a '.tasty' file: $arg")
34+
else {
35+
val path = Paths.get(arg)
36+
if !Files.exists(path) then println("File not found: " + arg)
37+
else
38+
val bytes = Files.readAllBytes(path)
39+
println(line)
40+
println(arg)
41+
println(line)
42+
println(showContents(bytes, noColor))
43+
println()
44+
printLastLine = true
45+
}
46+
if printLastLine then
47+
println(line)
48+
}
49+
2250
class TastyPrinter(bytes: Array[Byte]) {
2351

2452
private val sb: StringBuilder = new StringBuilder

compiler/src/dotty/tools/dotc/decompiler/DecompilationPrinter.scala

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,8 @@ class DecompilationPrinter extends Phase {
4040

4141
private def printToOutput(out: PrintStream)(using Context): Unit = {
4242
val unit = ctx.compilationUnit
43-
if (ctx.settings.printTasty.value)
44-
println(TastyPrinter.show(unit.pickled.head._2()))
45-
else {
46-
val unitFile = unit.source.toString.replace("\\", "/").replace(".class", ".tasty")
47-
out.println(s"/** Decompiled from $unitFile */")
48-
out.println(QuotesImpl.showDecompiledTree(unit.tpdTree))
49-
}
43+
val unitFile = unit.source.toString.replace("\\", "/").replace(".class", ".tasty")
44+
out.println(s"/** Decompiled from $unitFile */")
45+
out.println(QuotesImpl.showDecompiledTree(unit.tpdTree))
5046
}
5147
}

compiler/src/dotty/tools/dotc/quoted/PickledQuotes.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ object PickledQuotes {
174174
positionWarnings.foreach(report.warning(_))
175175

176176
val pickled = pickler.assembleParts()
177-
quotePickling.println(s"**** pickled quote\n${TastyPrinter.show(pickled)}")
177+
quotePickling.println(s"**** pickled quote\n${TastyPrinter.showContents(pickled, ctx.settings.color.value == "never")}")
178178
pickled
179179
}
180180

@@ -195,7 +195,7 @@ object PickledQuotes {
195195
case pickled: String => TastyString.unpickle(pickled)
196196
case pickled: List[String] => TastyString.unpickle(pickled)
197197

198-
quotePickling.println(s"**** unpickling quote from TASTY\n${TastyPrinter.show(bytes)}")
198+
quotePickling.println(s"**** unpickling quote from TASTY\n${TastyPrinter.showContents(bytes, ctx.settings.color.value == "never")}")
199199

200200
val mode = if (isType) UnpickleMode.TypeTree else UnpickleMode.Term
201201
val unpickler = new DottyUnpickler(bytes, mode)

compiler/src/dotty/tools/dotc/transform/Pickler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class Pickler extends Phase {
9191
if pickling ne noPrinter then
9292
pickling.synchronized {
9393
println(i"**** pickled info of $cls")
94-
println(TastyPrinter.show(pickled))
94+
println(TastyPrinter.showContents(pickled, ctx.settings.color.value == "never"))
9595
}
9696
pickled
9797
}(using ExecutionContext.global)

compiler/test/dotty/tools/dotc/core/tasty/PathPicklingTest.scala

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -34,36 +34,29 @@ class PathPicklingTest {
3434
locally {
3535
val ignorantProcessLogger = ProcessLogger(_ => ())
3636
val options = TestConfiguration.defaultOptions
37-
.and("-d", s"$out/out.jar")
37+
.and("-d", out.toString)
3838
.and("-sourceroot", "tests/pos")
3939
.and(s"$cwd/tests/pos/i10430/lib.scala", s"$cwd/tests/pos/i10430/app.scala")
4040
val reporter = TestReporter.reporter(System.out, logLevel = ERROR)
4141
val rep = Main.process(options.all, reporter)
4242
assertFalse("Compilation failed.", rep.hasErrors)
4343
}
4444

45-
val decompiled =
46-
val outstream = new ByteArrayOutputStream()
47-
val options = TestConfiguration.defaultOptions
48-
.and("-print-tasty")
49-
.and("-color:never")
50-
.and(s"$out/out.jar")
51-
val reporter = TestReporter.reporter(System.out, logLevel = ERROR)
52-
val rep = Console.withOut(outstream) {
53-
decompiler.Main.process(options.all, reporter)
54-
}
55-
assertFalse("Decompilation failed.", rep.hasErrors)
56-
new String(outstream.toByteArray(), "UTF-8")
45+
def showTasty(path: String) =
46+
val bytes = Files.readAllBytes(Paths.get(path))
47+
TastyPrinter.showContents(bytes, noColor = true)
5748

58-
assertTrue(decompiled.contains(": i10430/lib.scala"))
59-
assertTrue(decompiled.contains(": i10430/app.scala"))
60-
assertTrue(decompiled.contains("[i10430/lib.scala]"))
61-
assertTrue(decompiled.contains("[i10430/app.scala]"))
49+
val libTasty = showTasty(s"$out/lib.tasty")
50+
assertTrue(libTasty.contains(": i10430/lib.scala"))
51+
assertTrue(libTasty.contains("[i10430/lib.scala]"))
52+
assertFalse(libTasty.contains(": i10430\\lib.scala"))
53+
assertFalse(libTasty.contains("[i10430\\lib.scala]"))
6254

63-
assertFalse(decompiled.contains(": i10430\\lib.scala"))
64-
assertFalse(decompiled.contains(": i10430\\app.scala"))
65-
assertFalse(decompiled.contains("[i10430\\lib.scala]"))
66-
assertFalse(decompiled.contains("[i10430\\app.scala]"))
55+
val appTasty = showTasty(s"$out/app.tasty")
56+
assertTrue(appTasty.contains(": i10430/app.scala"))
57+
assertTrue(appTasty.contains("[i10430/app.scala]"))
58+
assertFalse(appTasty.contains(": i10430\\app.scala"))
59+
assertFalse(appTasty.contains("[i10430\\app.scala]"))
6760
}
6861

6962
private def delete(file: JFile): Unit = {

dist/bin/common

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ default_java_opts="-Xmx768m -Xms768m"
200200

201201
CompilerMain=dotty.tools.dotc.Main
202202
DecompilerMain=dotty.tools.dotc.decompiler.Main
203+
TastyPrinterMain=dotty.tools.dotc.core.tasty.TastyPrinter
203204
ReplMain=dotty.tools.repl.Main
204205
ScriptingMain=dotty.tools.scripting.Main
205206

dist/bin/scalac

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ case "$1" in
4545
while [[ $# -gt 0 ]]; do addScript "$1" && shift ; done ;;
4646
-compile) PROG_NAME="$CompilerMain" && shift ;;
4747
-decompile) PROG_NAME="$DecompilerMain" && shift ;;
48-
-print-tasty) PROG_NAME="$DecompilerMain" && addScala "-print-tasty" && shift ;;
48+
-print-tasty) PROG_NAME="$TastyPrinterMain" && shift ;;
4949
-run) PROG_NAME="$ReplMain" && shift ;;
5050
-colors) colors=true && shift ;;
5151
-no-colors) unset colors && shift ;;

project/Build.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -643,13 +643,14 @@ object Build {
643643
arg != "-with-compiler" && arg != "-Ythrough-tasty")
644644

645645
val main =
646-
if (decompile || printTasty) "dotty.tools.dotc.decompiler.Main"
646+
if (decompile) "dotty.tools.dotc.decompiler.Main"
647+
else if (printTasty) "dotty.tools.dotc.core.tasty.TastyPrinter"
647648
else if (debugFromTasty) "dotty.tools.dotc.fromtasty.Debug"
648649
else "dotty.tools.dotc.Main"
649650

650651
var extraClasspath = Seq(scalaLib, dottyLib)
651652

652-
if ((decompile || printTasty) && !args.contains("-classpath"))
653+
if (decompile && !args.contains("-classpath"))
653654
extraClasspath ++= Seq(".")
654655

655656
if (args0.contains("-with-compiler")) {
@@ -664,7 +665,7 @@ object Build {
664665
extraClasspath ++= Seq(dottyCompiler, dottyInterfaces, asm, dottyStaging, dottyTastyInspector, tastyCore)
665666
}
666667

667-
val fullArgs = main :: insertClasspathInArgs(args, extraClasspath.mkString(File.pathSeparator))
668+
val fullArgs = main :: (if (printTasty) args else insertClasspathInArgs(args, extraClasspath.mkString(File.pathSeparator)))
668669

669670
(Compile / runMain).toTask(fullArgs.mkString(" ", " ", ""))
670671
}.evaluated,

project/scripts/cmdTests

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,16 @@ clear_out "$OUT"
2323
"$SBT" ";scalac $SOURCE ; scala $MAIN" > "$tmp"
2424
grep -qe "$EXPECTED_OUTPUT" "$tmp"
2525

26+
echo "testing sbt scalac -print-tasty"
27+
clear_out "$OUT"
28+
"$SBT" ";scalac $SOURCE -d $OUT ;scalac -print-tasty -color:never $TASTY" > "$tmp"
29+
grep -qe "0: ASTs" "$tmp"
30+
grep -qe "0: tests/pos/HelloWorld.scala" "$tmp"
31+
2632
echo "testing that paths SourceFile annotations are relativized"
2733
clear_out "$OUT"
28-
"$SBT" "scalac -d $OUT/out.jar -sourceroot tests/pos $(pwd)/tests/pos/i10430/lib.scala $(pwd)/tests/pos/i10430/app.scala"
29-
"$SBT" "scalac -decompile -print-tasty -color:never $OUT/out.jar" > "$tmp"
34+
"$SBT" "scalac -d $OUT -sourceroot tests/pos $(pwd)/tests/pos/i10430/lib.scala $(pwd)/tests/pos/i10430/app.scala"
35+
"$SBT" "scalac -print-tasty -color:never $OUT/lib.tasty $OUT/app.tasty" > "$tmp"
3036
cat "$tmp" # for debugging
3137
grep -q ": i10430/lib.scala" "$tmp"
3238
grep -q ": i10430/app.scala" "$tmp"
@@ -82,3 +88,5 @@ clear_out "$OUT"
8288
# fi
8389
# fi
8490
# done 3<"$tmp1" 4<"./tests/vulpix-tests/meta/sbt-output.check"
91+
92+
echo "cmdTests successful"

0 commit comments

Comments
 (0)