Skip to content

Commit f2b6869

Browse files
Backport "Fix TASTy source position printer" to LTS (#20782)
Backports #19105 to the LTS branch. PR submitted by the release tooling. [skip ci]
2 parents 05352ac + 9f5c064 commit f2b6869

File tree

4 files changed

+73
-41
lines changed

4 files changed

+73
-41
lines changed

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

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package dotc
33
package core
44
package tasty
55

6+
import scala.compiletime.uninitialized
7+
68
import dotty.tools.tasty.{TastyFormat, TastyBuffer, TastyReader}
79
import TastyFormat.SOURCE
810
import TastyBuffer.{Addr, NameRef}
@@ -14,9 +16,9 @@ import Names.TermName
1416
class PositionUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName) {
1517
import reader.*
1618

17-
private var myLineSizes: Array[Int] = _
18-
private var mySpans: util.HashMap[Addr, Span] = _
19-
private var mySourcePaths: util.HashMap[Addr, String] = _
19+
private var myLineSizes: Array[Int] = uninitialized
20+
private var mySpans: util.HashMap[Addr, Span] = uninitialized
21+
private var mySourceNameRefs: util.HashMap[Addr, NameRef] = uninitialized
2022
private var isDefined = false
2123

2224
def ensureDefined(): Unit = {
@@ -29,15 +31,14 @@ class PositionUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName) {
2931
i += 1
3032

3133
mySpans = util.HashMap[Addr, Span]()
32-
mySourcePaths = util.HashMap[Addr, String]()
34+
mySourceNameRefs = util.HashMap[Addr, NameRef]()
3335
var curIndex = 0
3436
var curStart = 0
3537
var curEnd = 0
3638
while (!isAtEnd) {
3739
val header = readInt()
3840
if (header == SOURCE) {
39-
val path = nameAtRef(readNameRef()).toString
40-
mySourcePaths(Addr(curIndex)) = path
41+
mySourceNameRefs(Addr(curIndex)) = readNameRef()
4142
}
4243
else {
4344
val addrDelta = header >> 3
@@ -62,9 +63,9 @@ class PositionUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName) {
6263
mySpans
6364
}
6465

65-
private[tasty] def sourcePaths: util.ReadOnlyMap[Addr, String] = {
66+
private[tasty] def sourceNameRefs: util.ReadOnlyMap[Addr, NameRef] = {
6667
ensureDefined()
67-
mySourcePaths
68+
mySourceNameRefs
6869
}
6970

7071
private[tasty] def lineSizes: Array[Int] = {
@@ -73,5 +74,5 @@ class PositionUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName) {
7374
}
7475

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

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}
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
sb.append("\n\n")
@@ -106,8 +127,8 @@ class TastyPrinter(bytes: Array[Byte]) {
106127
import reader.*
107128
var indent = 0
108129
def newLine() = {
109-
val length = treeStr("%5d".format(index(currentAddr) - index(startAddr)))
110-
sb.append(s"\n $length:" + " " * indent)
130+
val length = treeStr("%6d".format(index(currentAddr) - index(startAddr)))
131+
sb.append(s"\n$length:" + " " * indent)
111132
}
112133
def printNat() = sb.append(treeStr(" " + readNat()))
113134
def printName() = {
@@ -163,8 +184,7 @@ class TastyPrinter(bytes: Array[Byte]) {
163184
}
164185
indent -= 2
165186
}
166-
sb.append(s"start = ${reader.startAddr}, base = $base, current = $currentAddr, end = $endAddr\n")
167-
sb.append(s"${endAddr.index - startAddr.index} bytes of AST, base = $currentAddr\n")
187+
sb.append(s"Trees (${endAddr.index - startAddr.index} bytes, starting from $base):")
168188
while (!isAtEnd) {
169189
printTree()
170190
newLine()
@@ -178,26 +198,30 @@ class TastyPrinter(bytes: Array[Byte]) {
178198
private val sb: StringBuilder = new StringBuilder
179199

180200
def unpickle(reader: TastyReader, tastyName: NameTable): String = {
201+
import reader.*
181202
val posUnpickler = new PositionUnpickler(reader, tastyName)
182-
sb.append(s" ${reader.endAddr.index - reader.currentAddr.index}")
183-
sb.append(" position bytes:\n")
203+
sb.append(s"Positions (${reader.endAddr.index - reader.startAddr.index} bytes, starting from $base):\n")
184204
val lineSizes = posUnpickler.lineSizes
185-
sb.append(s" lines: ${lineSizes.length}\n")
186-
sb.append(posUnpickler.lineSizes.mkString(" line sizes: ", ", ", "\n"))
187-
sb.append(" positions:\n")
205+
sb.append(s" lines: ${lineSizes.length}\n")
206+
sb.append(s" line sizes:\n")
207+
val windowSize = 20
208+
for window <-posUnpickler.lineSizes.sliding(windowSize, windowSize) do
209+
sb.append(" ").append(window.mkString(", ")).append("\n")
210+
// sb.append(posUnpickler.lineSizes.mkString(" line sizes: ", ", ", "\n"))
211+
sb.append(" positions:\n")
188212
val spans = posUnpickler.spans
189213
val sorted = spans.toSeq.sortBy(_._1.index)
190214
for ((addr, pos) <- sorted) {
191-
sb.append(treeStr("%10d".format(addr.index)))
215+
sb.append(treeStr("%6d".format(addr.index)))
192216
sb.append(s": ${offsetToInt(pos.start)} .. ${pos.end}\n")
193217
}
194218

195-
val sources = posUnpickler.sourcePaths
196-
sb.append(s"\n source paths:\n")
219+
val sources = posUnpickler.sourceNameRefs
220+
sb.append(s"\n source paths:\n")
197221
val sortedPath = sources.toSeq.sortBy(_._1.index)
198-
for ((addr, path) <- sortedPath) {
199-
sb.append(treeStr("%10d: ".format(addr.index)))
200-
sb.append(path)
222+
for ((addr, nameRef) <- sortedPath) {
223+
sb.append(treeStr("%6d: ".format(addr.index)))
224+
sb.append(nameStr(s"${nameRef.index} [${tastyName(nameRef)}]"))
201225
sb.append("\n")
202226
}
203227

@@ -210,14 +234,15 @@ class TastyPrinter(bytes: Array[Byte]) {
210234
private val sb: StringBuilder = new StringBuilder
211235

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

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

Lines changed: 9 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

@@ -28,7 +30,7 @@ object TastyUnpickler {
2830

2931
import TastyUnpickler.*
3032

31-
class TastyUnpickler(reader: TastyReader) {
33+
class TastyUnpickler(protected val reader: TastyReader) {
3234
import reader.*
3335

3436
def this(bytes: Array[Byte]) = this(new TastyReader(bytes))
@@ -88,17 +90,21 @@ class TastyUnpickler(reader: TastyReader) {
8890
result
8991
}
9092

91-
new TastyHeaderUnpickler(reader).readHeader()
93+
val header: TastyHeader = new TastyHeaderUnpickler(reader).readFullHeader()
9294

93-
locally {
95+
def readNames(): Unit =
9496
until(readEnd()) { nameAtRef.add(readNameContents()) }
97+
98+
def loadSections(): Unit = {
9599
while (!isAtEnd) {
96100
val secName = readString()
97101
val secEnd = readEnd()
98102
sectionReader(secName) = new TastyReader(bytes, currentAddr.index, secEnd.index, currentAddr.index)
99103
goto(secEnd)
100104
}
101105
}
106+
readNames()
107+
loadSections()
102108

103109
def unpickle[R](sec: SectionUnpickler[R]): Option[R] =
104110
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)