Skip to content

Commit 1f3af47

Browse files
authored
Fix TASTy source position printer (#19105)
Based on #19106 Now it properly shows that the sources form the position section are references in the name table. This includes the coloring of the indices and referenced names. ```diff source paths: - 0: t/Test.scala + 0: 21 [t/Test.scala] ``` <img width="272" alt="Screenshot 2023-11-30 at 10 32 35" src="https://github.com/lampepfl/dotty/assets/3648029/36c87ff4-0a21-4af9-907d-1b36d3f70496"> Can be reproduced with ```scala // Test.scala class Test ``` ``` scalac -Yprint-tasty Test.scala ```
2 parents 4d45087 + 931eae4 commit 1f3af47

File tree

4 files changed

+70
-39
lines changed

4 files changed

+70
-39
lines changed

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

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class PositionUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName) {
1818

1919
private var myLineSizes: Array[Int] = uninitialized
2020
private var mySpans: util.HashMap[Addr, Span] = uninitialized
21-
private var mySourcePaths: util.HashMap[Addr, String] = uninitialized
21+
private var mySourceNameRefs: util.HashMap[Addr, NameRef] = uninitialized
2222
private var isDefined = false
2323

2424
def ensureDefined(): Unit = {
@@ -31,15 +31,14 @@ class PositionUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName) {
3131
i += 1
3232

3333
mySpans = util.HashMap[Addr, Span]()
34-
mySourcePaths = util.HashMap[Addr, String]()
34+
mySourceNameRefs = util.HashMap[Addr, NameRef]()
3535
var curIndex = 0
3636
var curStart = 0
3737
var curEnd = 0
3838
while (!isAtEnd) {
3939
val header = readInt()
4040
if (header == SOURCE) {
41-
val path = nameAtRef(readNameRef()).toString
42-
mySourcePaths(Addr(curIndex)) = path
41+
mySourceNameRefs(Addr(curIndex)) = readNameRef()
4342
}
4443
else {
4544
val addrDelta = header >> 3
@@ -64,9 +63,9 @@ class PositionUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName) {
6463
mySpans
6564
}
6665

67-
private[tasty] def sourcePaths: util.ReadOnlyMap[Addr, String] = {
66+
private[tasty] def sourceNameRefs: util.ReadOnlyMap[Addr, NameRef] = {
6867
ensureDefined()
69-
mySourcePaths
68+
mySourceNameRefs
7069
}
7170

7271
private[tasty] def lineSizes: Array[Int] = {
@@ -75,5 +74,5 @@ class PositionUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName) {
7574
}
7675

7776
def spanAt(addr: Addr): Span = spans.getOrElse(addr, NoSpan)
78-
def sourcePathAt(addr: Addr): String = sourcePaths.getOrElse(addr, "")
77+
def sourcePathAt(addr: Addr): String = sourceNameRefs.get(addr).fold("")(nameAtRef(_).toString)
7978
}

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

Lines changed: 53 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ import util.Spans.offsetToInt
1212
import dotty.tools.tasty.TastyFormat.{ASTsSection, PositionsSection, CommentsSection, AttributesSection}
1313
import java.nio.file.{Files, Paths}
1414
import dotty.tools.io.{JarArchive, Path}
15+
import dotty.tools.tasty.TastyFormat.header
16+
17+
import scala.compiletime.uninitialized
18+
import dotty.tools.tasty.TastyBuffer.Addr
1519

1620
object TastyPrinter:
1721

@@ -62,26 +66,43 @@ class TastyPrinter(bytes: Array[Byte]) {
6266

6367
private val sb: StringBuilder = new StringBuilder
6468

65-
private val unpickler: TastyUnpickler = new TastyUnpickler(bytes)
69+
class TastyPrinterUnpickler extends TastyUnpickler(bytes) {
70+
var namesStart: Addr = uninitialized
71+
var namesEnd: Addr = uninitialized
72+
override def readNames() = {
73+
namesStart = reader.currentAddr
74+
super.readNames()
75+
namesEnd = reader.currentAddr
76+
}
77+
}
78+
79+
private val unpickler: TastyPrinterUnpickler = new TastyPrinterUnpickler
6680
import unpickler.{nameAtRef, unpickle}
6781

6882
private def nameToString(name: Name): String = name.debugString
6983

7084
private def nameRefToString(ref: NameRef): String = nameToString(nameAtRef(ref))
7185

86+
private def printHeader(): Unit =
87+
val header = unpickler.header
88+
sb.append("Header:\n")
89+
sb.append(s" version: ${header.majorVersion}.${header.minorVersion}.${header.experimentalVersion}\n")
90+
sb.append(" tooling: ").append(header.toolingVersion).append("\n")
91+
sb.append(" UUID: ").append(header.uuid).append("\n")
92+
sb.append("\n")
93+
7294
private def printNames(): Unit =
95+
sb.append(s"Names (${unpickler.namesEnd.index - unpickler.namesStart.index} bytes, starting from ${unpickler.namesStart.index}):\n")
7396
for ((name, idx) <- nameAtRef.contents.zipWithIndex) {
74-
val index = nameStr("%4d".format(idx))
97+
val index = nameStr("%6d".format(idx))
7598
sb.append(index).append(": ").append(nameToString(name)).append("\n")
7699
}
77100

78101
def showContents(): String = {
79-
sb.append("Names:\n")
102+
printHeader()
80103
printNames()
81-
sb.append("\n")
82-
sb.append("Trees:\n")
83104
unpickle(new TreeSectionUnpickler) match {
84-
case Some(s) => sb.append(s)
105+
case Some(s) => sb.append("\n\n").append(s)
85106
case _ =>
86107
}
87108
unpickle(new PositionSectionUnpickler) match {
@@ -108,8 +129,8 @@ class TastyPrinter(bytes: Array[Byte]) {
108129
import reader.*
109130
var indent = 0
110131
def newLine() = {
111-
val length = treeStr("%5d".format(index(currentAddr) - index(startAddr)))
112-
sb.append(s"\n $length:" + " " * indent)
132+
val length = treeStr("%6d".format(index(currentAddr) - index(startAddr)))
133+
sb.append(s"\n$length:" + " " * indent)
113134
}
114135
def printNat() = sb.append(treeStr(" " + readNat()))
115136
def printName() = {
@@ -165,8 +186,7 @@ class TastyPrinter(bytes: Array[Byte]) {
165186
}
166187
indent -= 2
167188
}
168-
sb.append(s"start = ${reader.startAddr}, base = $base, current = $currentAddr, end = $endAddr\n")
169-
sb.append(s"${endAddr.index - startAddr.index} bytes of AST, base = $currentAddr\n")
189+
sb.append(s"Trees (${endAddr.index - startAddr.index} bytes, starting from $base):")
170190
while (!isAtEnd) {
171191
printTree()
172192
newLine()
@@ -180,26 +200,30 @@ class TastyPrinter(bytes: Array[Byte]) {
180200
private val sb: StringBuilder = new StringBuilder
181201

182202
def unpickle(reader: TastyReader, tastyName: NameTable): String = {
203+
import reader.*
183204
val posUnpickler = new PositionUnpickler(reader, tastyName)
184-
sb.append(s" ${reader.endAddr.index - reader.currentAddr.index}")
185-
sb.append(" position bytes:\n")
205+
sb.append(s"Positions (${reader.endAddr.index - reader.startAddr.index} bytes, starting from $base):\n")
186206
val lineSizes = posUnpickler.lineSizes
187-
sb.append(s" lines: ${lineSizes.length}\n")
188-
sb.append(posUnpickler.lineSizes.mkString(" line sizes: ", ", ", "\n"))
189-
sb.append(" positions:\n")
207+
sb.append(s" lines: ${lineSizes.length}\n")
208+
sb.append(s" line sizes:\n")
209+
val windowSize = 20
210+
for window <-posUnpickler.lineSizes.sliding(windowSize, windowSize) do
211+
sb.append(" ").append(window.mkString(", ")).append("\n")
212+
// sb.append(posUnpickler.lineSizes.mkString(" line sizes: ", ", ", "\n"))
213+
sb.append(" positions:\n")
190214
val spans = posUnpickler.spans
191215
val sorted = spans.toSeq.sortBy(_._1.index)
192216
for ((addr, pos) <- sorted) {
193-
sb.append(treeStr("%10d".format(addr.index)))
217+
sb.append(treeStr("%6d".format(addr.index)))
194218
sb.append(s": ${offsetToInt(pos.start)} .. ${pos.end}\n")
195219
}
196220

197-
val sources = posUnpickler.sourcePaths
198-
sb.append(s"\n source paths:\n")
221+
val sources = posUnpickler.sourceNameRefs
222+
sb.append(s"\n source paths:\n")
199223
val sortedPath = sources.toSeq.sortBy(_._1.index)
200-
for ((addr, path) <- sortedPath) {
201-
sb.append(treeStr("%10d: ".format(addr.index)))
202-
sb.append(path)
224+
for ((addr, nameRef) <- sortedPath) {
225+
sb.append(treeStr("%6d: ".format(addr.index)))
226+
sb.append(nameStr(s"${nameRef.index} [${tastyName(nameRef)}]"))
203227
sb.append("\n")
204228
}
205229

@@ -212,14 +236,15 @@ class TastyPrinter(bytes: Array[Byte]) {
212236
private val sb: StringBuilder = new StringBuilder
213237

214238
def unpickle(reader: TastyReader, tastyName: NameTable): String = {
215-
sb.append(s" ${reader.endAddr.index - reader.currentAddr.index}")
239+
import reader.*
216240
val comments = new CommentUnpickler(reader).comments
217-
sb.append(s" comment bytes:\n")
218-
val sorted = comments.toSeq.sortBy(_._1.index)
219-
for ((addr, cmt) <- sorted) {
220-
sb.append(treeStr("%10d".format(addr.index)))
221-
sb.append(s": ${cmt.raw} (expanded = ${cmt.isExpanded})\n")
222-
}
241+
if !comments.isEmpty then
242+
sb.append(s"Comments (${reader.endAddr.index - reader.startAddr.index} bytes, starting from $base):\n")
243+
val sorted = comments.toSeq.sortBy(_._1.index)
244+
for ((addr, cmt) <- sorted) {
245+
sb.append(treeStr("%6d".format(addr.index)))
246+
sb.append(s": ${cmt.raw} (expanded = ${cmt.isExpanded})\n")
247+
}
223248
sb.result
224249
}
225250
}

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

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import TastyBuffer.NameRef
1111
import scala.collection.mutable
1212
import Names.{TermName, termName, EmptyTermName}
1313
import NameKinds.*
14+
import dotty.tools.tasty.TastyHeader
15+
import dotty.tools.tasty.TastyBuffer.Addr
1416

1517
object TastyUnpickler {
1618

@@ -61,7 +63,7 @@ object TastyUnpickler {
6163

6264
import TastyUnpickler.*
6365

64-
class TastyUnpickler(reader: TastyReader) {
66+
class TastyUnpickler(protected val reader: TastyReader) {
6567
import reader.*
6668

6769
def this(bytes: Array[Byte]) = this(new TastyReader(bytes))
@@ -121,17 +123,22 @@ class TastyUnpickler(reader: TastyReader) {
121123
result
122124
}
123125

124-
val header = new TastyHeaderUnpickler(scala3CompilerConfig, reader).readFullHeader()
126+
val header: TastyHeader =
127+
new TastyHeaderUnpickler(scala3CompilerConfig, reader).readFullHeader()
125128

126-
locally {
129+
def readNames(): Unit =
127130
until(readEnd()) { nameAtRef.add(readNameContents()) }
131+
132+
def loadSections(): Unit = {
128133
while (!isAtEnd) {
129134
val secName = readString()
130135
val secEnd = readEnd()
131136
sectionReader(secName) = new TastyReader(bytes, currentAddr.index, secEnd.index, currentAddr.index)
132137
goto(secEnd)
133138
}
134139
}
140+
readNames()
141+
loadSections()
135142

136143
def unpickle[R](sec: SectionUnpickler[R]): Option[R] =
137144
for (reader <- sectionReader.get(sec.name)) yield

project/scripts/cmdTests

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ echo "testing sbt scalac -print-tasty"
2727
clear_out "$OUT"
2828
"$SBT" ";scalac $SOURCE -d $OUT ;scalac -print-tasty -color:never $TASTY" > "$tmp"
2929
grep -qe "0: ASTs" "$tmp"
30-
grep -qe "0: tests/pos/HelloWorld.scala" "$tmp"
30+
grep -qe "0: 41 \[tests/pos/HelloWorld.scala\]" "$tmp"
3131

3232
echo "testing that paths SourceFile annotations are relativized"
3333
clear_out "$OUT"

0 commit comments

Comments
 (0)