@@ -41,23 +41,36 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table) {
41
41
this .positions = positions
42
42
}
43
43
44
+ /** A map from addresses of definition entries to the symbols they define */
44
45
private val symAtAddr = new mutable.HashMap [Addr , Symbol ]
45
- private val unpickledSyms = new mutable.HashSet [Symbol ]
46
+
47
+ /** A temporary map from addresses of definition entries to the trees they define.
48
+ * Used to remember trees of symbols that are created by a completion. Emptied
49
+ * once the tree is inlined into a larger tree.
50
+ */
46
51
private val treeAtAddr = new mutable.HashMap [Addr , Tree ]
47
- private val typeAtAddr = new mutable.HashMap [Addr , Type ] // currently populated only for types that are known to be SHAREd.
52
+
53
+ /** A map from addresses of type entries to the types they define.
54
+ * Currently only populated for types that might be recursively referenced
55
+ * from within themselves (i.e. RefinedTypes, PolyTypes, MethodTypes).
56
+ */
57
+ private val typeAtAddr = new mutable.HashMap [Addr , Type ]
48
58
49
59
/** The root symbol denotation which are defined by the Tasty file associated with this
50
60
* TreeUnpickler. Set by `enterTopLevel`.
51
61
*/
52
62
private var roots : Set [SymDenotation ] = null
53
63
64
+ /** The root symbols that are defined in this Tasty file. This
65
+ * is a subset of `roots.map(_.symbol)`.
66
+ */
67
+ private var seenRoots : Set [Symbol ] = Set ()
68
+
54
69
/** The root owner tree. See `OwnerTree` class definition. Set by `enterTopLevel`. */
55
70
private var ownerTree : OwnerTree = _
56
71
57
- private def registerSym (addr : Addr , sym : Symbol ) = {
72
+ private def registerSym (addr : Addr , sym : Symbol ) =
58
73
symAtAddr(addr) = sym
59
- unpickledSyms += sym
60
- }
61
74
62
75
/** Enter all toplevel classes and objects into their scopes
63
76
* @param roots a set of SymDenotations that should be overwritten by unpickling
@@ -466,6 +479,7 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table) {
466
479
new Completer (ctx.owner, subReader(start, end)) with SymbolLoaders .SecondCompleter )
467
480
rootd.flags = flags &~ Touched // allow one more completion
468
481
rootd.privateWithin = privateWithin
482
+ seenRoots += rootd.symbol
469
483
rootd.symbol
470
484
case _ =>
471
485
val completer = adjustIfModule(new Completer (ctx.owner, subReader(start, end)))
@@ -675,7 +689,14 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table) {
675
689
case TYPEDEF | TYPEPARAM =>
676
690
if (sym.isClass) {
677
691
val companion = sym.scalacLinkedClass
678
- if (companion != NoSymbol && unpickledSyms.contains(companion)) {
692
+
693
+ // Is the companion defined in the same Tasty file as `sym`?
694
+ // The only case top check here is if `sym` is a root. In this case
695
+ // `companion` might have been entered by the environment but it might
696
+ // been missing from the Tasty file. So we check explicitly for that.
697
+ def isCodefined =
698
+ roots.contains(companion.denot) == seenRoots.contains(companion)
699
+ if (companion.exists && isCodefined) {
679
700
import transform .SymUtils ._
680
701
if (sym is Flags .ModuleClass ) sym.registerCompanionMethod(nme.COMPANION_CLASS_METHOD , companion)
681
702
else sym.registerCompanionMethod(nme.COMPANION_MODULE_METHOD , companion)
0 commit comments