Skip to content

Commit 50a04c5

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 21fa1b4 commit 50a04c5

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
@@ -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,6 +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+
// FIXME: broken now now that symbols unpickled from TASTY have a position
444445
pos.exists && defRunId == ctx.runId
445446
}
446447

@@ -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
@@ -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)
@@ -453,11 +454,14 @@ class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpi
453454
rootd.symbol
454455
case _ =>
455456
val completer = adjustIfModule(new Completer(ctx.owner, subReader(start, end)))
457+
458+
val coord = coordAt(start)
459+
456460
if (isClass)
457-
ctx.newClassSymbol(ctx.owner, name.asTypeName, flags, completer, privateWithin, coord = start.index)
461+
ctx.newClassSymbol(ctx.owner, name.asTypeName, flags, completer, privateWithin, coord)
458462
else
459-
ctx.newSymbol(ctx.owner, name, flags, completer, privateWithin, coord = start.index)
460-
} // TODO set position somehow (but take care not to upset Symbol#isDefinedInCurrentRun)
463+
ctx.newSymbol(ctx.owner, name, flags, completer, privateWithin, coord)
464+
}
461465
sym.annotations = annots
462466
ctx.enter(sym)
463467
registerSym(start, sym)
@@ -985,7 +989,7 @@ class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpi
985989
case BIND =>
986990
val name = readName()
987991
val info = readType()
988-
val sym = ctx.newSymbol(ctx.owner, name, EmptyFlags, info)
992+
val sym = ctx.newSymbol(ctx.owner, name, EmptyFlags, info, coord = coordAt(start))
989993
registerSym(start, sym)
990994
Bind(sym, readTerm())
991995
case ALTERNATIVE =>
@@ -1001,7 +1005,7 @@ class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpi
10011005
val argPats = until(end)(readTerm())
10021006
UnApply(fn, implicitArgs, argPats, patType)
10031007
case REFINEDtpt =>
1004-
val refineCls = ctx.newRefinedClassSymbol
1008+
val refineCls = ctx.newRefinedClassSymbol(coordAt(start))
10051009
typeAtAddr(start) = refineCls.typeRef
10061010
val parent = readTpt()
10071011
val refinements = readStats(refineCls, end)(localContext(refineCls))
@@ -1077,21 +1081,32 @@ class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpi
10771081

10781082
// ------ Setting positions ------------------------------------------------
10791083

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

10971112
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)