Skip to content

Commit 8674fb6

Browse files
committed
Serialize source file changes
Serialize source file changes in positions section
1 parent 977eb84 commit 8674fb6

File tree

7 files changed

+98
-47
lines changed

7 files changed

+98
-47
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ object DottyUnpickler {
2323

2424
class PositionsSectionUnpickler extends SectionUnpickler[PositionUnpickler]("Positions") {
2525
def unpickle(reader: TastyReader, nameAtRef: NameTable): PositionUnpickler =
26-
new PositionUnpickler(reader)
26+
new PositionUnpickler(reader, nameAtRef)
2727
}
2828

2929
class CommentsSectionUnpickler extends SectionUnpickler[CommentUnpickler]("Comments") {

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

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@ package tasty
66
import ast._
77
import ast.Trees._
88
import ast.Trees.WithLazyField
9+
import util.SourceFile
910
import core._
10-
import Contexts._, Symbols._, Annotations._
11+
import Contexts._, Symbols._, Annotations._, Decorators._
1112
import collection.mutable
1213
import TastyBuffer._
1314
import util.Positions._
15+
import TastyFormat.SOURCE
1416

1517
class PositionPickler(pickler: TastyPickler, addrOfTree: untpd.Tree => Option[Addr]) {
1618
val buf: TastyBuffer = new TastyBuffer(5000)
@@ -59,31 +61,37 @@ class PositionPickler(pickler: TastyPickler, addrOfTree: untpd.Tree => Option[Ad
5961
case _ => false
6062
}
6163

62-
def traverse(x: Any): Unit = x match {
64+
def traverse(x: Any, curSource: SourceFile): Unit = x match {
6365
case x: untpd.Tree =>
66+
var source = curSource
6467
val pos = if (x.isInstanceOf[untpd.MemberDef]) x.pos else x.pos.toSynthetic
6568
if (pos.exists && (pos != x.initialPos.toSynthetic || alwaysNeedsPos(x))) {
6669
addrOfTree(x) match {
6770
case Some(addr) if !pickledIndices.contains(addr.index) =>
6871
//println(i"pickling $x with $pos at $addr")
6972
pickleDeltas(addr.index, pos)
73+
if (x.source != curSource) {
74+
buf.writeInt(SOURCE)
75+
buf.writeInt(pickler.nameBuffer.nameIndex(x.source.path.toTermName).index)
76+
source = curSource
77+
}
7078
case _ =>
7179
//println(i"no address for $x")
7280
}
7381
}
7482
//else if (x.pos.exists) println(i"skipping $x")
7583
x match {
7684
case x: untpd.MemberDef @unchecked =>
77-
for (ann <- x.symbol.annotations) traverse(ann.tree)
85+
for (ann <- x.symbol.annotations) traverse(ann.tree, source)
7886
case _ =>
7987
}
80-
traverse(x.productIterator)
88+
traverse(x.productIterator, source)
8189
case xs: TraversableOnce[_] =>
82-
xs.foreach(traverse)
90+
xs.foreach(traverse(_, curSource))
8391
case x: Annotation =>
84-
traverse(x.tree)
92+
traverse(x.tree, curSource)
8593
case _ =>
8694
}
87-
traverse(roots)
95+
for (root <- roots) traverse(root, root.source)
8896
}
8997
}

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

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,34 +5,59 @@ package tasty
55

66
import util.Positions._
77
import collection.{mutable, Map}
8-
import TastyBuffer.Addr
8+
import TastyBuffer.{Addr, NameRef}
9+
import TastyFormat.SOURCE
10+
import Names.TermName
911

1012
/** Unpickler for tree positions */
11-
class PositionUnpickler(reader: TastyReader) {
13+
class PositionUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName) {
1214
import reader._
1315

14-
private[tasty] lazy val positions: Map[Addr, Position] = {
15-
val positions = new mutable.HashMap[Addr, Position]
16-
var curIndex = 0
17-
var curStart = 0
18-
var curEnd = 0
19-
while (!isAtEnd) {
20-
val header = readInt()
21-
val addrDelta = header >> 3
22-
val hasStart = (header & 4) != 0
23-
val hasEnd = (header & 2) != 0
24-
val hasPoint = (header & 1) != 0
25-
curIndex += addrDelta
26-
assert(curIndex >= 0)
27-
if (hasStart) curStart += readInt()
28-
if (hasEnd) curEnd += readInt()
29-
positions(Addr(curIndex)) =
30-
if (hasPoint) Position(curStart, curEnd, curStart + readInt())
31-
else Position(curStart, curEnd)
16+
private var myPositions: mutable.HashMap[Addr, Position] = _
17+
private var mySourcePaths: mutable.HashMap[Addr, String] = _
18+
private var isDefined = false
19+
20+
def ensureDefined(): Unit =
21+
if (!isDefined) {
22+
myPositions = new mutable.HashMap[Addr, Position]
23+
mySourcePaths = new mutable.HashMap[Addr, String]
24+
var curIndex = 0
25+
var curStart = 0
26+
var curEnd = 0
27+
while (!isAtEnd) {
28+
val header = readInt()
29+
if (header == SOURCE) {
30+
val path = nameAtRef(readNameRef()).toString
31+
mySourcePaths(Addr(curIndex)) = path
32+
}
33+
else {
34+
val addrDelta = header >> 3
35+
val hasStart = (header & 4) != 0
36+
val hasEnd = (header & 2) != 0
37+
val hasPoint = (header & 1) != 0
38+
curIndex += addrDelta
39+
assert(curIndex >= 0)
40+
if (hasStart) curStart += readInt()
41+
if (hasEnd) curEnd += readInt()
42+
myPositions(Addr(curIndex)) =
43+
if (hasPoint) Position(curStart, curEnd, curStart + readInt())
44+
else Position(curStart, curEnd)
45+
}
46+
}
47+
isDefined = true
3248
}
33-
positions
49+
50+
private[tasty] def positions: Map[Addr, Position] = {
51+
ensureDefined()
52+
myPositions
53+
}
54+
55+
private[tasty] def sourcePaths: Map[Addr, String] = {
56+
ensureDefined()
57+
mySourcePaths
3458
}
3559

3660
def posAt(addr: Addr): Position = positions.getOrElse(addr, NoPosition)
61+
def sourcePathAt(addr: Addr): String = sourcePaths.getOrElse(addr, "")
3762
}
3863

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

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -218,14 +218,19 @@ Note: Tree tags are grouped into 5 categories that determine what follows, and t
218218
219219
Standard Section: "Positions" Assoc*
220220
221-
Assoc = Header offset_Delta? offset_Delta?
222-
Header = addr_Delta + // in one Nat: difference of address to last recorded node << 2 +
223-
hasStartDiff + // one bit indicating whether there follows a start address delta << 1
224-
hasEndDiff // one bit indicating whether there follows an end address delta
221+
Assoc = Header offset_Delta? offset_Delta? point_Delta?
222+
| SOURCE nameref_Int
223+
Header = addr_Delta + // in one Nat: difference of address to last recorded node << 3 +
224+
hasStartDiff + // one bit indicating whether there follows a start address delta << 2
225+
hasEndDiff + // one bit indicating whether there follows an end address delta << 1
226+
hasPoint // one bit indicating whether the new position has a point (i.e ^ position)
225227
// Nodes which have the same positions as their parents are omitted.
226228
// offset_Deltas give difference of start/end offset wrt to the
227229
// same offset in the previously recorded node (or 0 for the first recorded node)
228230
Delta = Int // Difference between consecutive offsets,
231+
SOURCE = 4 // Impossible as header
232+
233+
All elements of a position section are serialized as Ints
229234
230235
Standard Section: "Comments" Comment*
231236
@@ -272,7 +277,11 @@ object TastyFormat {
272277
}
273278
object NameTags extends NameTags
274279

275-
// AST tags
280+
// Position header
281+
282+
final val SOURCE = 4
283+
284+
// AST tags
276285
// Cat. 1: tag
277286

278287
final val firstSimpleTreeTag = UNITconst

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

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ package tasty
55
import Contexts._, Decorators._
66
import Names.Name
77
import TastyUnpickler._
8-
import TastyBuffer.NameRef
8+
import TastyBuffer.{Addr, NameRef}
99
import util.Positions.offsetToInt
1010
import printing.Highlighting._
1111

@@ -107,14 +107,16 @@ class TastyPrinter(bytes: Array[Byte])(implicit ctx: Context) {
107107

108108
class PositionSectionUnpickler extends SectionUnpickler[Unit]("Positions") {
109109
def unpickle(reader: TastyReader, tastyName: NameTable): Unit = {
110-
print(s" ${reader.endAddr.index - reader.currentAddr.index}")
111-
val positions = new PositionUnpickler(reader).positions
112-
println(s" position bytes:")
113-
val sorted = positions.toSeq.sortBy(_._1.index)
114-
for ((addr, pos) <- sorted) {
115-
print(treeColor("%10d".format(addr.index)))
116-
println(s": ${offsetToInt(pos.start)} .. ${pos.end}")
117-
}
110+
val unpickler = new PositionUnpickler(reader, tastyName)
111+
def printPart[T](dict: collection.Map[Addr, T])(show: T => String) =
112+
for ((addr, value) <- dict.toSeq.sortBy(_._1.index)) {
113+
print(treeColor("%10d".format(addr.index)))
114+
println(s": ${show(value)}")
115+
}
116+
println(s" ${reader.endAddr.index - reader.currentAddr.index} position bytes:")
117+
printPart(unpickler.positions)(pos => s"${pos.start} .. ${pos.end}")
118+
println("source path offsets:")
119+
printPart(unpickler.sourcePaths)(identity)
118120
}
119121
}
120122

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class TreePickler(pickler: TastyPickler) {
6464
}
6565
}
6666

67-
private def pickleName(name: Name): Unit = writeNat(nameIndex(name).index)
67+
def pickleName(name: Name): Unit = writeNat(nameIndex(name).index)
6868

6969
private def pickleNameAndSig(name: Name, sig: Signature): Unit =
7070
pickleName(

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

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import NameKinds._
1919
import typer.ConstFold
2020
import typer.Checking.checkNonCyclic
2121
import util.Positions._
22+
import util.SourceFile
2223
import ast.{TreeTypeMap, Trees, tpd, untpd}
2324
import Trees._
2425
import Decorators._
@@ -1250,7 +1251,7 @@ class TreeUnpickler(reader: TastyReader,
12501251
def readLaterWithOwner[T <: AnyRef](end: Addr, op: TreeReader => Context => T)(implicit ctx: Context): Symbol => Trees.Lazy[T] = {
12511252
val localReader = fork
12521253
goto(end)
1253-
owner => new LazyReader(localReader, owner, ctx.mode, op)
1254+
owner => new LazyReader(localReader, owner, ctx.mode, ctx.source, op)
12541255
}
12551256

12561257
def readHole(end: Addr, isType: Boolean)(implicit ctx: Context): Tree = {
@@ -1300,10 +1301,16 @@ class TreeUnpickler(reader: TastyReader,
13001301
}
13011302
}
13021303

1303-
class LazyReader[T <: AnyRef](reader: TreeReader, owner: Symbol, mode: Mode, op: TreeReader => Context => T) extends Trees.Lazy[T] {
1304+
class LazyReader[T <: AnyRef](
1305+
reader: TreeReader, owner: Symbol, mode: Mode, source: SourceFile,
1306+
op: TreeReader => Context => T) extends Trees.Lazy[T] {
13041307
def complete(implicit ctx: Context): T = {
13051308
pickling.println(i"starting to read at ${reader.reader.currentAddr} with owner $owner")
1306-
op(reader)(ctx.withPhaseNoLater(ctx.picklerPhase).withOwner(owner).withModeBits(mode))
1309+
op(reader)(ctx
1310+
.withPhaseNoLater(ctx.picklerPhase)
1311+
.withOwner(owner)
1312+
.withModeBits(mode)
1313+
.withSource(source))
13071314
}
13081315
}
13091316

0 commit comments

Comments
 (0)