Skip to content

Commit c9e004f

Browse files
committed
Give position to symbols when unpickling
Previously, unpickled symbols always had position NoCoord, now their position is set based on the corresponding tree position. This does not always match the position used when they were pickled so `testPickling` currently fails, this is fixed in the subsequent commits of this PR.
1 parent f3492c8 commit c9e004f

File tree

3 files changed

+41
-22
lines changed

3 files changed

+41
-22
lines changed

compiler/src/dotty/tools/dotc/core/Symbols.scala

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,8 @@ trait Symbols { this: Context =>
131131
newClassSymbol(owner, name, flags, completer, privateWithin, coord, assocFile)
132132
}
133133

134-
def newRefinedClassSymbol = newCompleteClassSymbol(
135-
ctx.owner, tpnme.REFINE_CLASS, NonMember, parents = Nil)
134+
def newRefinedClassSymbol(coord: Coord = NoCoord) =
135+
newCompleteClassSymbol(ctx.owner, tpnme.REFINE_CLASS, NonMember, parents = Nil, coord = coord)
136136

137137
/** Create a module symbol with associated module class
138138
* from its non-info fields and a function producing the info
@@ -441,7 +441,7 @@ object Symbols {
441441

442442
/** Does this symbol come from a currently compiled source file? */
443443
final def isDefinedInCurrentRun(implicit ctx: Context): Boolean = {
444-
pos.exists && defRunId == ctx.runId
444+
pos.exists && defRunId == ctx.runId && sourceFile == ctx.source.file
445445
}
446446

447447
final def isValidInCurrentRun(implicit ctx: Context): Boolean =
@@ -563,8 +563,12 @@ object Symbols {
563563
}
564564
}
565565

566-
/** The position of this symbol, or NoPosition is symbol was not loaded
567-
* from source.
566+
/** The position of this symbol, or NoPosition if the symbol was not loaded
567+
* from source or from TASTY. This is always a zero-extent position.
568+
*
569+
* NOTE: If the symbol was not loaded from the current compilation unit,
570+
* the implicit conversion `sourcePos` will return the wrong result, careful!
571+
* TODO: Consider changing this method return type to `SourcePosition`.
568572
*/
569573
def pos: Position = if (coord.isPosition) coord.toPosition else NoPosition
570574

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

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,8 @@ class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpi
254254
case TYPEARGtype =>
255255
TypeArgRef(readType(), readType().asInstanceOf[TypeRef], readNat())
256256
case BIND =>
257-
val sym = ctx.newSymbol(ctx.owner, readName().toTypeName, BindDefinedType, readType())
257+
val sym = ctx.newSymbol(ctx.owner, readName().toTypeName, BindDefinedType, readType(),
258+
coord = coordAt(start))
258259
registerSym(start, sym)
259260
if (currentAddr != end) readType()
260261
TypeRef(NoPrefix, sym)
@@ -451,11 +452,14 @@ class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpi
451452
rootd.symbol
452453
case _ =>
453454
val completer = adjustIfModule(new Completer(ctx.owner, subReader(start, end)))
455+
456+
val coord = coordAt(start)
457+
454458
if (isClass)
455-
ctx.newClassSymbol(ctx.owner, name.asTypeName, flags, completer, privateWithin, coord = start.index)
459+
ctx.newClassSymbol(ctx.owner, name.asTypeName, flags, completer, privateWithin, coord)
456460
else
457-
ctx.newSymbol(ctx.owner, name, flags, completer, privateWithin, coord = start.index)
458-
} // TODO set position somehow (but take care not to upset Symbol#isDefinedInCurrentRun)
461+
ctx.newSymbol(ctx.owner, name, flags, completer, privateWithin, coord)
462+
}
459463
sym.annotations = annots
460464
ctx.enter(sym)
461465
registerSym(start, sym)
@@ -983,7 +987,7 @@ class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpi
983987
case BIND =>
984988
val name = readName()
985989
val info = readType()
986-
val sym = ctx.newSymbol(ctx.owner, name, EmptyFlags, info)
990+
val sym = ctx.newSymbol(ctx.owner, name, EmptyFlags, info, coord = coordAt(start))
987991
registerSym(start, sym)
988992
Bind(sym, readTerm())
989993
case ALTERNATIVE =>
@@ -999,7 +1003,7 @@ class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpi
9991003
val argPats = until(end)(readTerm())
10001004
UnApply(fn, implicitArgs, argPats, patType)
10011005
case REFINEDtpt =>
1002-
val refineCls = ctx.newRefinedClassSymbol
1006+
val refineCls = ctx.newRefinedClassSymbol(coordAt(start))
10031007
typeAtAddr(start) = refineCls.typeRef
10041008
val parent = readTpt()
10051009
val refinements = readStats(refineCls, end)(localContext(refineCls))
@@ -1075,21 +1079,32 @@ class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpi
10751079

10761080
// ------ Setting positions ------------------------------------------------
10771081

1078-
/** Set position of `tree` at given `addr`. */
1079-
def setPos[T <: untpd.Tree](addr: Addr, tree: T)(implicit ctx: Context): tree.type =
1082+
/** Pickled position for `addr`. */
1083+
def posAt(addr: Addr)(implicit ctx: Context): Position =
10801084
if (ctx.mode.is(Mode.ReadPositions)) {
10811085
posUnpicklerOpt match {
10821086
case Some(posUnpickler) =>
1083-
//println(i"setPos $tree / ${tree.getClass} at $addr to ${posUnpickler.posAt(addr)}")
1084-
val pos = posUnpickler.posAt(addr)
1085-
if (pos.exists) tree.setPosUnchecked(pos)
1086-
tree
1087+
posUnpickler.posAt(addr)
10871088
case _ =>
1088-
//println(i"no pos $tree")
1089-
tree
1089+
NoPosition
10901090
}
1091-
}
1092-
else tree
1091+
} else NoPosition
1092+
1093+
/** Coordinate for the symbol at `addr`. */
1094+
def coordAt(addr: Addr)(implicit ctx: Context): Coord = {
1095+
val pos = posAt(addr)
1096+
if (pos.exists)
1097+
positionCoord(pos)
1098+
else
1099+
indexCoord(addr.index)
1100+
}
1101+
1102+
/** Set position of `tree` at given `addr`. */
1103+
def setPos[T <: untpd.Tree](addr: Addr, tree: T)(implicit ctx: Context): tree.type = {
1104+
val pos = posAt(addr)
1105+
if (pos.exists) tree.setPosUnchecked(pos)
1106+
tree
1107+
}
10931108
}
10941109

10951110
class LazyReader[T <: AnyRef](reader: TreeReader, op: TreeReader => Context => T) extends Trees.Lazy[T] {

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -757,7 +757,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
757757
args match {
758758
case ValDef(_, _, _) :: _ =>
759759
typedDependent(args.asInstanceOf[List[ValDef]])(
760-
ctx.fresh.setOwner(ctx.newRefinedClassSymbol).setNewScope)
760+
ctx.fresh.setOwner(ctx.newRefinedClassSymbol(tree.pos)).setNewScope)
761761
case _ =>
762762
typed(cpy.AppliedTypeTree(tree)(untpd.TypeTree(funCls.typeRef), args :+ body), pt)
763763
}

0 commit comments

Comments
 (0)