1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
package dotty.tools.dotc
package core
package tasty
import Contexts._, Decorators._
import printing.Texts._
import TastyName._
import StdNames._
import TastyUnpickler._
import TastyBuffer.Addr
import util.Positions.{Position, offsetToInt}
import collection.mutable
class TastyPrinter(bytes: Array[Byte])(implicit ctx: Context) {
val unpickler = new TastyUnpickler(bytes)
import unpickler.{tastyName, unpickle}
def nameToString(name: TastyName): String = name match {
case Simple(name) => name.toString
case Qualified(qual, name) => nameRefToString(qual) + "." + nameRefToString(name)
case Signed(original, params, result) =>
i"${nameRefToString(original)}@${params.map(nameRefToString)}%,%:${nameRefToString(result)}"
case Expanded(prefix, original) => s"$prefix${nme.EXPAND_SEPARATOR}$original"
case ModuleClass(original) => nameRefToString(original) + "/MODULECLASS"
case SuperAccessor(accessed) => nameRefToString(accessed) + "/SUPERACCESSOR"
case DefaultGetter(meth, num) => nameRefToString(meth) + "/DEFAULTGETTER" + num
case Shadowed(original) => nameRefToString(original) + "/SHADOWED"
}
def nameRefToString(ref: NameRef): String = nameToString(tastyName(ref))
def printNames() =
for ((name, idx) <- tastyName.contents.zipWithIndex) {
val index = "%4d: ".format(idx)
println(index + nameToString(name))
}
def printContents(): Unit = {
println("Names:")
printNames()
println("Trees:")
unpickle(new TreeSectionUnpickler)
unpickle(new PositionSectionUnpickler)
}
class TreeSectionUnpickler extends SectionUnpickler[Unit]("ASTs") {
import TastyFormat._
def unpickle(reader: TastyReader, tastyName: TastyName.Table): Unit = {
import reader._
var indent = 0
def newLine() = {
val length = "%5d:".format(index(currentAddr) - index(startAddr))
print(s"\n $length" + " " * indent)
}
def printNat() = print(" " + readNat())
def printName() = {
val idx = readNat()
print(" ") ;print(idx); print("["); print(nameRefToString(NameRef(idx))); print("]")
}
def printTree(): Unit = {
newLine()
val tag = readByte()
print(" ");print(astTagToString(tag))
indent += 2
if (tag >= firstLengthTreeTag) {
val len = readNat()
print(s"($len)")
val end = currentAddr + len
def printTrees() = until(end)(printTree())
tag match {
case RENAMED =>
printName(); printName()
case VALDEF | DEFDEF | TYPEDEF | TYPEPARAM | PARAM | NAMEDARG | BIND =>
printName(); printTrees()
case REFINEDtype =>
printName(); printTree(); printTrees()
case RETURN =>
printNat(); printTrees()
case METHODtype | POLYtype =>
printTree()
until(end) { printName(); printTree() }
case PARAMtype =>
printNat(); printNat()
case _ =>
printTrees()
}
if (currentAddr != end) {
println(s"incomplete read, current = $currentAddr, end = $end")
goto(end)
}
}
else if (tag >= firstNatASTTreeTag) {
tag match {
case IDENT | SELECT | TERMREF | TYPEREF | SELFDEF => printName()
case _ => printNat()
}
printTree()
}
else if (tag >= firstASTTreeTag)
printTree()
else if (tag >= firstNatTreeTag)
tag match {
case TERMREFpkg | TYPEREFpkg | STRINGconst | IMPORTED => printName()
case _ => printNat()
}
indent -= 2
}
println(i"start = ${reader.startAddr}, base = $base, current = $currentAddr, end = $endAddr")
println(s"${endAddr.index - startAddr.index} bytes of AST, base = $currentAddr")
while (!isAtEnd) {
printTree()
newLine()
}
}
}
class PositionSectionUnpickler extends SectionUnpickler[Unit]("Positions") {
def unpickle(reader: TastyReader, tastyName: TastyName.Table): Unit = {
print(s"${reader.endAddr.index - reader.currentAddr.index}")
val positions = new PositionUnpickler(reader).positions
println(s" position bytes:")
val sorted = positions.toSeq.sortBy(_._1.index)
for ((addr, pos) <- sorted) println(s"${addr.index}: ${offsetToInt(pos.start)} .. ${pos.end}")
}
}
}
|