@@ -9,7 +9,7 @@ import TastyFormat._, NameTags._, TastyTagOps._, TastyRefs._
99
1010object TastyUnpickler {
1111 def unpickleClass (in : TastyReader , clazz : ClassInfo , path : String ): Unit = {
12- val doPrint = false
12+ // val doPrint = false
1313 // val doPrint = path.contains("v1") && !path.contains("experimental2.tasty")
1414 // if (doPrint) TastyPrinter.printClassNames(in.fork, path)
1515 // if (doPrint) TastyPrinter.printPickle(in.fork, path)
@@ -23,7 +23,13 @@ object TastyUnpickler {
2323
2424 object trav extends Traverser {
2525 var pkgNames = List .empty[Name ]
26- val classes = new mutable.ListBuffer [(Name , ClsDef )]
26+ var clsNames = List .empty[Name ]
27+
28+ def dropHead [A ](xs : List [A ], head : A ) = xs match {
29+ case `head` :: ys => ys
30+ case x :: _ => throw new AssertionError (s " assertion failed: Expected head= $head but it was $x" )
31+ case _ => throw new AssertionError (s " assertion failed: Expected head= $head but list was empty " )
32+ }
2733
2834 override def traversePkg (pkg : Pkg ): Unit = {
2935 val pkgName = pkg.path match {
@@ -32,21 +38,22 @@ object TastyUnpickler {
3238 }
3339 pkgNames ::= pkgName
3440 super .traversePkg(pkg)
35- pkgNames match {
36- case n :: ns => pkgNames = ns.ensuring(n == pkgName, s " last= $n pkgName= $pkgName" )
37- case _ => assert(false , s " Expected $pkgName as last pkg name, was empty " )
38- }
41+ pkgNames = dropHead(pkgNames, pkgName)
3942 }
4043
4144 override def traverseClsDef (clsDef : ClsDef ): Unit = {
42- classes += ((pkgNames.headOption.getOrElse(nme.Empty ), clsDef))
45+ forEachClass(clsDef, pkgNames, clsNames)
46+ clsNames ::= clsDef.name
4347 super .traverseClsDef(clsDef)
48+ clsNames = dropHead(clsNames, clsDef.name)
4449 }
4550 }
46- trav.traverse(tree)
47- trav.classes.toList.foreach { case (pkgName, clsDef) =>
51+
52+ def forEachClass (clsDef : ClsDef , pkgNames : List [Name ], clsNames : List [Name ]): Unit = {
53+ val pkgName = pkgNames.headOption.getOrElse(nme.Empty )
4854 if (pkgName.source == clazz.owner.fullName) {
49- val cls = clazz.owner.classes.getOrElse(clsDef.name.source, NoClass )
55+ val clsName = (clsDef.name :: clsNames).reverseIterator.mkString(" $" )
56+ val cls = clazz.owner.classes.getOrElse(clsName, NoClass )
5057 if (cls != NoClass ) {
5158 cls._experimental |= clsDef.annots.exists(_.tycon.toString == " scala.annotation.experimental" )
5259 cls._experimental |= clsDef.annots.exists(_.tycon.toString == " scala.annotation.experimental2" )
@@ -62,6 +69,8 @@ object TastyUnpickler {
6269 }
6370 }
6471 }
72+
73+ trav.traverse(tree)
6574 }
6675
6776 def unpickleTree (in : TastyReader , names : Names ): Tree = {
@@ -108,7 +117,7 @@ object TastyUnpickler {
108117 DefDef (name, annots)
109118 }
110119
111- def readTemplate () = {
120+ def readTemplate (): Template = {
112121 // TypeParam* TermParam* parent_Term* Self? Stat* -- [typeparams] paramss extends parents { self => stats }, where Stat* always starts with the primary constructor.
113122 // TypeParam = TYPEPARAM Length NameRef type_Term Modifier* -- modifiers name bounds
114123 // TermParam = PARAM Length NameRef type_Term Modifier* -- modifiers name : type.
@@ -121,12 +130,14 @@ object TastyUnpickler {
121130 while (nextByte == PARAM || nextByte == EMPTYCLAUSE || nextByte == SPLITCLAUSE ) skipTree(readByte()) // tparams
122131 while (nextByte != SELFDEF && nextByte != DEFDEF ) skipTree(readByte()) // parents
123132 if (nextByte == SELFDEF ) skipTree(readByte()) // self
133+ val classes = new ListBuffer [ClsDef ]
124134 val meths = new ListBuffer [DefDef ]
125135 doUntil(end)(readByte match {
126- case DEFDEF => meths += readDefDef()
127- case tag => skipTree(tag)
136+ case TYPEDEF => readTypeDef() match { case clsDef : ClsDef => classes += clsDef case _ => }
137+ case DEFDEF => meths += readDefDef()
138+ case tag => skipTree(tag)
128139 })
129- Template (meths.toList)
140+ Template (classes.toList, meths.toList)
130141 }
131142
132143 def readClassDef (name : Name , end : Addr ) = ClsDef (name.toTypeName, readTemplate(), readAnnotsInMods(end)) // NameRef Template Modifier* -- modifiers class name template
@@ -199,7 +210,7 @@ object TastyUnpickler {
199210 final case class Pkg (path : Path , trees : List [Tree ]) extends Tree { def show = s " package $path${trees.map(" \n " + _).mkString}" }
200211
201212 final case class ClsDef (name : TypeName , template : Template , annots : List [Annot ]) extends Tree { def show = s " ${annots.map(" " + _ + " " ).mkString}class $name$template" }
202- final case class Template (meths : List [DefDef ]) extends Tree { def show = s " ${meths.map(" \n " + _).mkString}" }
213+ final case class Template (classes : List [ ClsDef ], meths : List [DefDef ]) extends Tree { def show = s " ${(classes ::: meths) .map(" \n " + _).mkString}" }
203214 final case class DefDef (name : Name , annots : List [Annot ] = Nil ) extends Tree { def show = s " ${annots.map(" " + _ + " " ).mkString}def $name" }
204215
205216 sealed trait Type extends Tree
@@ -225,14 +236,11 @@ object TastyUnpickler {
225236
226237 def traverseName (name : Name ) = ()
227238
228- def traverseTrees (trees : List [Tree ]) = trees.foreach(traverse)
229- def traverseAnnots (annots : List [Annot ]) = annots.foreach(traverse)
230-
231- def traversePkg (pkg : Pkg ) = { traverse(pkg.path); traverseTrees(pkg.trees) }
232- def traverseClsDef (clsDef : ClsDef ) = { traverseName(clsDef.name); traverseAnnots(clsDef.annots) }
233- def traverseTemplate (tmpl : Template ) = { traverseTrees(tmpl.meths) }
234- def traverseDefDef (defDef : DefDef ) = { traverseName(defDef.name); traverseAnnots(defDef.annots) }
235- def traverseAnnot (annot : Annot ) = { traverse(annot.tycon); traverse(annot.fullAnnotation) }
239+ def traversePkg (pkg : Pkg ) = { val Pkg (path, trees) = pkg; traverse(path); trees.foreach(traverse) }
240+ def traverseClsDef (clsDef : ClsDef ) = { val ClsDef (name, tmpl, annots) = clsDef; traverseName(name); traverseTemplate(tmpl); annots.foreach(traverse) }
241+ def traverseTemplate (tmpl : Template ) = { val Template (classes, meths) = tmpl; classes.foreach(traverse); meths.foreach(traverse) }
242+ def traverseDefDef (defDef : DefDef ) = { val DefDef (name, annots) = defDef; traverseName(name); annots.foreach(traverse) }
243+ def traverseAnnot (annot : Annot ) = { val Annot (tycon, fullAnnotation) = annot; traverse(tycon); traverse(fullAnnotation) }
236244
237245 def traversePath (path : Path ) = path match {
238246 case TypeRefPkg (fullyQual) => traverseName(fullyQual)
0 commit comments