@@ -109,17 +109,27 @@ class TreeUnpickler(reader: TastyReader,
109109 while (nextByte == PARAMS || nextByte == TYPEPARAM ) skipTree()
110110
111111 /** Record all directly nested definitions and templates in current tree
112- * as `OwnerTree`s in `buf`
112+ * as `OwnerTree`s in `buf`.
113+ * A complication concerns member definitions. These are lexically nested in a
114+ * Template node, but need to be listed separately in the OwnerTree of the enclosing class
115+ * in order not to confuse owner chains.
113116 */
114117 def scanTree (buf : ListBuffer [OwnerTree ], mode : MemberDefMode = AllDefs ): Unit = {
115118 val start = currentAddr
116119 val tag = readByte()
117120 tag match {
118- case VALDEF | DEFDEF | TYPEDEF | TYPEPARAM | PARAM | TEMPLATE | BIND =>
121+ case VALDEF | DEFDEF | TYPEDEF | TYPEPARAM | PARAM | TEMPLATE =>
119122 val end = readEnd()
120123 for (i <- 0 until numRefs(tag)) readNat()
121- if (tag == TEMPLATE ) scanTrees(buf, end, MemberDefsOnly )
122- if (mode != NoMemberDefs ) buf += new OwnerTree (start, tag, fork, end)
124+ if (tag == TEMPLATE ) {
125+ // Read all member definitions now, whereas non-members are children of
126+ // template's owner tree.
127+ val nonMemberReader = fork
128+ scanTrees(buf, end, MemberDefsOnly )
129+ buf += new OwnerTree (start, tag, nonMemberReader, end)
130+ }
131+ else if (mode != NoMemberDefs )
132+ buf += new OwnerTree (start, tag, fork, end)
123133 goto(end)
124134 case tag =>
125135 if (mode == MemberDefsOnly ) skipTree(tag)
@@ -132,7 +142,11 @@ class TreeUnpickler(reader: TastyReader,
132142 }
133143 else {
134144 for (i <- 0 until nrefs) readNat()
135- scanTrees(buf, end)
145+ if (tag == BIND ) {
146+ buf += new OwnerTree (start, tag, fork, end)
147+ goto(end)
148+ }
149+ else scanTrees(buf, end)
136150 }
137151 }
138152 else if (tag >= firstNatASTTreeTag) { readNat(); scanTree(buf) }
@@ -1172,11 +1186,16 @@ class TreeUnpickler(reader: TastyReader,
11721186 */
11731187 class OwnerTree (val addr : Addr , tag : Int , reader : TreeReader , val end : Addr ) {
11741188
1189+ private var myChildren : List [OwnerTree ] = null
1190+
11751191 /** All definitions that have the definition at `addr` as closest enclosing definition */
1176- lazy val children : List [OwnerTree ] = {
1177- val buf = new ListBuffer [OwnerTree ]
1178- reader.scanTrees(buf, end, if (tag == TEMPLATE ) NoMemberDefs else AllDefs )
1179- buf.toList
1192+ def children : List [OwnerTree ] = {
1193+ if (myChildren == null ) myChildren = {
1194+ val buf = new ListBuffer [OwnerTree ]
1195+ reader.scanTrees(buf, end, if (tag == TEMPLATE ) NoMemberDefs else AllDefs )
1196+ buf.toList
1197+ }
1198+ myChildren
11801199 }
11811200
11821201 /** Find the owner of definition at `addr` */
@@ -1195,13 +1214,19 @@ class TreeUnpickler(reader: TastyReader,
11951214 }
11961215 catch {
11971216 case ex : TreeWithoutOwner =>
1198- println(i " no owner for $addr among $cs" ) // DEBUG
1217+ pickling.println(i " no owner for $addr among $cs%, % " )
1218+ throw ex
1219+ }
1220+ try search(children, NoSymbol )
1221+ catch {
1222+ case ex : TreeWithoutOwner =>
1223+ pickling.println(s " ownerTree = $ownerTree" )
11991224 throw ex
12001225 }
1201- search(children, NoSymbol )
12021226 }
12031227
1204- override def toString = s " OwnerTree( ${addr.index}, ${end.index}"
1228+ override def toString =
1229+ s " OwnerTree( ${addr.index}, ${end.index}, ${if (myChildren == null ) " ?" else myChildren.mkString(" " )}) "
12051230 }
12061231}
12071232
0 commit comments