Skip to content

Commit 5fdd40b

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. Symbol#isDefinedInCurrentRun is broken by this commit and fixed in a latter commit in this PR.
1 parent 21e90d8 commit 5fdd40b

File tree

3 files changed

+41
-21
lines changed

3 files changed

+41
-21
lines changed

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

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

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

136136
/** Create a module symbol with associated module class
137137
* from its non-info fields and a function producing the info
@@ -444,6 +444,7 @@ object Symbols {
444444

445445
/** Does this symbol come from a currently compiled source file? */
446446
final def isDefinedInCurrentRun(implicit ctx: Context): Boolean = {
447+
// FIXME: broken now now that symbols unpickled from TASTY have a position
447448
pos.exists && defRunId == ctx.runId
448449
}
449450

@@ -563,8 +564,12 @@ object Symbols {
563564
}
564565
}
565566

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

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

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,8 @@ class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpi
259259
case TYPEARGtype =>
260260
TypeArgRef(readType(), readType().asInstanceOf[TypeRef], readNat())
261261
case BIND =>
262-
val sym = ctx.newSymbol(ctx.owner, readName().toTypeName, BindDefinedType, readType())
262+
val sym = ctx.newSymbol(ctx.owner, readName().toTypeName, BindDefinedType, readType(),
263+
coord = coordAt(start))
263264
registerSym(start, sym)
264265
if (currentAddr != end) readType()
265266
TypeRef(NoPrefix, sym)
@@ -464,11 +465,14 @@ class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpi
464465
rootd.symbol
465466
case _ =>
466467
val completer = adjustIfModule(new Completer(ctx.owner, subReader(start, end)))
468+
469+
val coord = coordAt(start)
470+
467471
if (isClass)
468-
ctx.newClassSymbol(ctx.owner, name.asTypeName, flags, completer, privateWithin, coord = start.index)
472+
ctx.newClassSymbol(ctx.owner, name.asTypeName, flags, completer, privateWithin, coord)
469473
else
470-
ctx.newSymbol(ctx.owner, name, flags, completer, privateWithin, coord = start.index)
471-
} // TODO set position somehow (but take care not to upset Symbol#isDefinedInCurrentRun)
474+
ctx.newSymbol(ctx.owner, name, flags, completer, privateWithin, coord)
475+
}
472476
sym.annotations = annots
473477
ctx.enter(sym)
474478
registerSym(start, sym)
@@ -995,7 +999,7 @@ class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpi
995999
case BIND =>
9961000
val name = readName()
9971001
val info = readType()
998-
val sym = ctx.newSymbol(ctx.owner, name, EmptyFlags, info)
1002+
val sym = ctx.newSymbol(ctx.owner, name, EmptyFlags, info, coord = coordAt(start))
9991003
registerSym(start, sym)
10001004
Bind(sym, readTerm())
10011005
case ALTERNATIVE =>
@@ -1011,7 +1015,7 @@ class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpi
10111015
val argPats = until(end)(readTerm())
10121016
UnApply(fn, implicitArgs, argPats, patType)
10131017
case REFINEDtpt =>
1014-
val refineCls = ctx.newRefinedClassSymbol
1018+
val refineCls = ctx.newRefinedClassSymbol(coordAt(start))
10151019
typeAtAddr(start) = refineCls.typeRef
10161020
val parent = readTpt()
10171021
val refinements = readStats(refineCls, end)(localContext(refineCls))
@@ -1087,21 +1091,32 @@ class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpi
10871091

10881092
// ------ Setting positions ------------------------------------------------
10891093

1090-
/** Set position of `tree` at given `addr`. */
1091-
def setPos[T <: untpd.Tree](addr: Addr, tree: T)(implicit ctx: Context): tree.type =
1094+
/** Pickled position for `addr`. */
1095+
def posAt(addr: Addr)(implicit ctx: Context): Position =
10921096
if (ctx.mode.is(Mode.ReadPositions)) {
10931097
posUnpicklerOpt match {
10941098
case Some(posUnpickler) =>
1095-
//println(i"setPos $tree / ${tree.getClass} at $addr to ${posUnpickler.posAt(addr)}")
1096-
val pos = posUnpickler.posAt(addr)
1097-
if (pos.exists) tree.setPosUnchecked(pos)
1098-
tree
1099+
posUnpickler.posAt(addr)
10991100
case _ =>
1100-
//println(i"no pos $tree")
1101-
tree
1101+
NoPosition
11021102
}
1103-
}
1104-
else tree
1103+
} else NoPosition
1104+
1105+
/** Coordinate for the symbol at `addr`. */
1106+
def coordAt(addr: Addr)(implicit ctx: Context): Coord = {
1107+
val pos = posAt(addr)
1108+
if (pos.exists)
1109+
positionCoord(pos)
1110+
else
1111+
indexCoord(addr.index)
1112+
}
1113+
1114+
/** Set position of `tree` at given `addr`. */
1115+
def setPos[T <: untpd.Tree](addr: Addr, tree: T)(implicit ctx: Context): tree.type = {
1116+
val pos = posAt(addr)
1117+
if (pos.exists) tree.setPosUnchecked(pos)
1118+
tree
1119+
}
11051120
}
11061121

11071122
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
@@ -759,7 +759,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
759759
args match {
760760
case ValDef(_, _, _) :: _ =>
761761
typedDependent(args.asInstanceOf[List[ValDef]])(
762-
ctx.fresh.setOwner(ctx.newRefinedClassSymbol).setNewScope)
762+
ctx.fresh.setOwner(ctx.newRefinedClassSymbol(tree.pos)).setNewScope)
763763
case _ =>
764764
typed(cpy.AppliedTypeTree(tree)(untpd.TypeTree(funCls.typeRef), args :+ body), pt)
765765
}

0 commit comments

Comments
 (0)