Skip to content

Commit 12ae395

Browse files
committed
Move Symbol fields to SymDenotation
1 parent e52a3c9 commit 12ae395

File tree

3 files changed

+221
-47
lines changed

3 files changed

+221
-47
lines changed

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

Lines changed: 172 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ package core
55
import Periods._, Contexts._, Symbols._, Denotations._, Names._, NameOps._, Annotations._
66
import Types._, Flags._, Decorators._, DenotTransformers._, StdNames._, Scopes._
77
import NameOps._, NameKinds._
8-
import Phases.{Phase, typerPhase, unfusedPhases}
8+
import Phases.{Phase, typerPhase, flattenPhase, unfusedPhases}
99
import Constants.Constant
1010
import TypeApplications.TypeParamInfo
1111
import Scopes.Scope
@@ -17,7 +17,7 @@ import Trees.Literal
1717
import Variances.Variance
1818
import annotation.tailrec
1919
import util.SimpleIdentityMap
20-
import util.{SrcPos, SourcePosition, Stats}
20+
import util.{SrcPos, SourcePosition, SourceFile, NoSource, Stats}
2121
import util.Spans.*
2222
import java.util.WeakHashMap
2323
import scala.util.control.NonFatal
@@ -31,11 +31,37 @@ import scala.annotation.internal.sharable
3131

3232
object SymDenotations {
3333

34+
type TreeOrProvider = tpd.TreeProvider | tpd.Tree
35+
36+
class SymCommon(
37+
//private[SymDenotations]
38+
var coord: Coord,
39+
//private[SymDenotations]
40+
val id: Int,
41+
//private[SymDenotations]
42+
val nestingLevel: Int):
43+
44+
//private[SymDenotations]
45+
var defTree: tpd.Tree | Null = null
46+
//private[SymDenotations]
47+
def asClass: ClassCommon = asInstanceOf[ClassCommon]
48+
end SymCommon
49+
50+
class ClassCommon(coord: Coord, id: Int, nestingLevel: Int,
51+
//private[SymDenotations]
52+
val assocFile: AbstractFile | Null = null)
53+
extends SymCommon(coord, id, nestingLevel):
54+
//private[SymDenotations]
55+
var treeOrProvider: TreeOrProvider = tpd.EmptyTree
56+
//private[SymDenotations]
57+
var source: SourceFile = NoSource
58+
3459
/** A sym-denotation represents the contents of a definition
3560
* during a period.
3661
*/
3762
class SymDenotation private[SymDenotations] (
3863
symbol: Symbol,
64+
final val common: SymCommon,
3965
final val maybeOwner: Symbol,
4066
final val name: Name,
4167
initFlags: FlagSet,
@@ -576,6 +602,55 @@ object SymDenotations {
576602

577603
myTargetName.nn
578604

605+
// ----- Symbol ops --------------------------------------------
606+
/*
607+
def coord: Coord = common.coord
608+
def id: Int = common.id
609+
def nestingLevel: Int = common.nestingLevel
610+
611+
/** Set the coordinate of this class, this is only useful when the coordinate is
612+
* not known at symbol creation. This is the case for root symbols
613+
* unpickled from TASTY.
614+
*
615+
* @pre coord == NoCoord
616+
*/
617+
private[core] def coord_=(c: Coord): Unit =
618+
// assert(myCoord == NoCoord)
619+
// This assertion fails for CommentPickling test.
620+
// TODO: figure out what's wrong in the setup of CommentPicklingTest and re-enable assertion.
621+
common.coord = c
622+
*/
623+
/** The source or class file from which this class or
624+
* the class containing this symbol was generated, null if not applicable.
625+
* Note that this the returned classfile might be the top-level class
626+
* containing this symbol instead of the directly enclosing class.
627+
* Overridden in ClassSymbol
628+
*/
629+
def associatedFile(using Context): AbstractFile | Null =
630+
topLevelClass.associatedFile
631+
/*
632+
/** The tree defining the symbol at pickler time, EmptyTree if none was retained
633+
* Only valid for initial denotations.
634+
*/
635+
private[core] def defTree: tpd.Tree =
636+
if common.defTree == null then tpd.EmptyTree else common.defTree.nn
637+
638+
/** Set defining tree if this symbol retains its definition tree
639+
* Only valid for initial denotations.
640+
*/
641+
private[core] def defTree_=(tree: tpd.Tree)(using Context): Unit =
642+
if retainsDefTree then common.defTree = tree
643+
644+
/** Does this symbol retain its definition tree?
645+
* A good policy for this needs to balance costs and benefits, where
646+
* costs are mainly memoty leaks, in particular across runs.
647+
*/
648+
def retainsDefTree(using Context): Boolean =
649+
ctx.settings.YretainTrees.value ||
650+
owner.isTerm || // no risk of leaking memory after a run for these
651+
isOneOf(InlineOrProxy) || // need to keep inline info
652+
ctx.settings.YcheckInit.value // initialization check
653+
*/
579654
// ----- Tests -------------------------------------------------
580655

581656
/** Is this denotation a class? */
@@ -1606,7 +1681,7 @@ object SymDenotations {
16061681
val privateWithin1 = if (privateWithin != null) privateWithin else this.privateWithin
16071682
val annotations1 = if (annotations != null) annotations else this.annotations
16081683
val rawParamss1 = if rawParamss != null then rawParamss else this.rawParamss
1609-
val d = SymDenotation(symbol, owner, name, initFlags1, info1, privateWithin1)
1684+
val d = SymDenotation(symbol, symbol.lastKnownDenotation.common, owner, name, initFlags1, info1, privateWithin1)
16101685
d.annotations = annotations1
16111686
d.rawParamss = rawParamss1
16121687
d.registeredCompanion = registeredCompanion
@@ -1777,12 +1852,13 @@ object SymDenotations {
17771852
*/
17781853
class ClassDenotation private[SymDenotations] (
17791854
symbol: Symbol,
1855+
common: ClassCommon,
17801856
maybeOwner: Symbol,
17811857
name: Name,
17821858
initFlags: FlagSet,
17831859
initInfo: Type,
17841860
initPrivateWithin: Symbol)
1785-
extends SymDenotation(symbol, maybeOwner, name, initFlags, initInfo, initPrivateWithin) {
1861+
extends SymDenotation(symbol, common, maybeOwner, name, initFlags, initInfo, initPrivateWithin) {
17861862

17871863
import util.EqHashMap
17881864

@@ -2422,19 +2498,100 @@ object SymDenotations {
24222498

24232499
override def registeredCompanion_=(c: Symbol) =
24242500
myCompanion = c
2501+
2502+
// ------ Symbol ops --------------------------------------------------------
2503+
2504+
//def assocFile: AbstractFile | Null = common.assocFile
2505+
2506+
/** The source or class file from which this class was generated, null if not applicable. */
2507+
override def associatedFile(using Context): AbstractFile | Null =
2508+
val af = common.assocFile
2509+
if af != null || this.is(Package) || this.owner.is(Package) then af
2510+
else super.associatedFile
2511+
2512+
/*
2513+
/** If this is a top-level class and `-Yretain-trees` (or `-from-tasty`) is set.
2514+
* Returns the TypeDef tree (possibly wrapped inside PackageDefs) for this class, otherwise EmptyTree.
2515+
* This will force the info of the class.
2516+
*/
2517+
private[core] def rootTree(using Context): tpd.Tree =
2518+
rootTreeContaining("")
2519+
2520+
/** Same as `tree` but load tree only if `id == ""` or the tree might contain `id`.
2521+
* For Tasty trees this means consulting whether the name table defines `id`.
2522+
* For already loaded trees, we maintain the referenced ids in an attachment.
2523+
*/
2524+
private[core] def rootTreeContaining(id: String)(using Context): tpd.Tree =
2525+
infoOrCompleter match
2526+
case _: NoCompleter =>
2527+
case _ => ensureCompleted()
2528+
common.treeOrProvider match
2529+
case fn: tpd.TreeProvider =>
2530+
if id.isEmpty || fn.mightContain(id) then
2531+
val tree = fn.tree
2532+
common.treeOrProvider = tree
2533+
tree
2534+
else tpd.EmptyTree
2535+
case tree: tpd.Tree @ unchecked =>
2536+
if id.isEmpty || mightContain(tree, id) then tree else tpd.EmptyTree
2537+
2538+
private[core] def rootTreeOrProvider: TreeOrProvider = common.treeOrProvider
2539+
2540+
private[core] def rootTreeOrProvider_=(t: TreeOrProvider)(using Context): Unit =
2541+
common.treeOrProvider = t
2542+
2543+
private def mightContain(tree: tpd.Tree, id: String)(using Context): Boolean = {
2544+
val ids = tree.getAttachment(Ids) match {
2545+
case Some(ids) => ids
2546+
case None =>
2547+
import tpd.TreeOps
2548+
val idSet = mutable.SortedSet[String]()
2549+
tree.foreachSubTree {
2550+
case tree: tpd.NameTree if tree.name.toTermName.isInstanceOf[SimpleName] =>
2551+
idSet += tree.name.toString
2552+
case _ =>
2553+
}
2554+
val ids = idSet.toArray
2555+
tree.putAttachment(Ids, ids)
2556+
ids
2557+
}
2558+
ids.binarySearch(id) >= 0
2559+
}
2560+
2561+
final def sourceOfClass(using Context): SourceFile = {
2562+
assert(this eq initial)
2563+
if !common.source.exists && !is(Package) then
2564+
// this allows sources to be added in annotations after `sourceOfClass` is first called
2565+
val file = associatedFile
2566+
if file != null && file.extension != "class" then
2567+
common.source = ctx.getSource(file)
2568+
else
2569+
common.source = defn.patchSource(symbol)
2570+
if !common.source.exists then
2571+
common.source = atPhaseNoLater(flattenPhase) {
2572+
topLevelClass.unforcedAnnotation(defn.SourceFileAnnot) match
2573+
case Some(sourceAnnot) => sourceAnnot.argumentConstant(0) match
2574+
case Some(Constant(path: String)) => ctx.getSource(path)
2575+
case none => NoSource
2576+
case none => NoSource
2577+
}
2578+
common.source
2579+
}
2580+
*/
24252581
}
24262582

24272583
/** The denotation of a package class.
24282584
* It overrides ClassDenotation to take account of package objects when looking for members
24292585
*/
24302586
final class PackageClassDenotation private[SymDenotations] (
24312587
symbol: Symbol,
2588+
common: ClassCommon,
24322589
ownerIfExists: Symbol,
24332590
name: Name,
24342591
initFlags: FlagSet,
24352592
initInfo: Type,
24362593
initPrivateWithin: Symbol)
2437-
extends ClassDenotation(symbol, ownerIfExists, name, initFlags, initInfo, initPrivateWithin) {
2594+
extends ClassDenotation(symbol, common, ownerIfExists, name, initFlags, initInfo, initPrivateWithin) {
24382595

24392596
private var packageObjsCache: List[ClassDenotation] = _
24402597
private var packageObjsRunId: RunId = NoRunId
@@ -2595,7 +2752,7 @@ object SymDenotations {
25952752
}
25962753

25972754
@sharable object NoDenotation
2598-
extends SymDenotation(NoSymbol, NoSymbol, "<none>".toTermName, Permanent, NoType) {
2755+
extends SymDenotation(NoSymbol, SymCommon(NoCoord, 0, 0), NoSymbol, "<none>".toTermName, Permanent, NoType) {
25992756
override def isTerm: Boolean = false
26002757
override def exists: Boolean = false
26012758
override def owner: Symbol = throw new AssertionError("NoDenotation.owner")
@@ -2609,6 +2766,7 @@ object SymDenotations {
26092766
override def filterWithPredicate(p: SingleDenotation => Boolean): SingleDenotation = this
26102767
override def filterDisjoint(denots: PreDenotation)(using Context): SingleDenotation = this
26112768
override def filterWithFlags(required: FlagSet, excluded: FlagSet)(using Context): SingleDenotation = this
2769+
override def associatedFile(using Context): AbstractFile | Null = NoSource.file
26122770

26132771
NoSymbol.denot = this
26142772
validFor = Period.allInRun(NoRunId)
@@ -2630,16 +2788,20 @@ object SymDenotations {
26302788
*/
26312789
def SymDenotation(
26322790
symbol: Symbol,
2791+
common: SymCommon,
26332792
owner: Symbol,
26342793
name: Name,
26352794
initFlags: FlagSet,
26362795
initInfo: Type,
26372796
initPrivateWithin: Symbol = NoSymbol)(using Context): SymDenotation = {
26382797
val result =
2639-
if (symbol.isClass)
2640-
if (initFlags.is(Package)) new PackageClassDenotation(symbol, owner, name, initFlags, initInfo, initPrivateWithin)
2641-
else new ClassDenotation(symbol, owner, name, initFlags, initInfo, initPrivateWithin)
2642-
else new SymDenotation(symbol, owner, name, initFlags, initInfo, initPrivateWithin)
2798+
if symbol.isClass then
2799+
if initFlags.is(Package) then
2800+
new PackageClassDenotation(symbol, common.asClass, owner, name, initFlags, initInfo, initPrivateWithin)
2801+
else
2802+
new ClassDenotation(symbol, common.asClass, owner, name, initFlags, initInfo, initPrivateWithin)
2803+
else
2804+
new SymDenotation(symbol, common, owner, name, initFlags, initInfo, initPrivateWithin)
26432805
result.validFor = currentStablePeriod
26442806
result
26452807
}

0 commit comments

Comments
 (0)