Skip to content

Commit bfbd1af

Browse files
Merge pull request #4546 from dotty-staging/join-unpicklings
Join logic for unpickling top level and term tasty
2 parents 64497c6 + 0100c12 commit bfbd1af

File tree

5 files changed

+51
-36
lines changed

5 files changed

+51
-36
lines changed

compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ import dotty.tools.dotc.config.Printers._
66
import dotty.tools.dotc.core.Constants.Constant
77
import dotty.tools.dotc.core.Contexts._
88
import dotty.tools.dotc.core.Decorators._
9-
import dotty.tools.dotc.core.Flags._
109
import dotty.tools.dotc.core.StdNames._
1110
import dotty.tools.dotc.core.NameKinds
1211
import dotty.tools.dotc.core.Symbols._
1312
import dotty.tools.dotc.core.Types.Type
1413
import dotty.tools.dotc.core.tasty.TreePickler.Hole
1514
import dotty.tools.dotc.core.tasty.{TastyPickler, TastyPrinter, TastyString}
15+
import dotty.tools.dotc.core.tasty.TreeUnpickler.UnpickleMode
1616

1717
import scala.quoted.Types._
1818
import scala.quoted.Exprs._
@@ -99,15 +99,15 @@ object PickledQuotes {
9999

100100
/** Unpickle TASTY bytes into it's tree */
101101
private def unpickle(bytes: Array[Byte], splices: Seq[Any], isType: Boolean)(implicit ctx: Context): Tree = {
102-
val unpickler = new TastyUnpickler(bytes, splices)
103102
if (pickling ne noPrinter) {
104103
println(i"**** unpickling quote from TASTY")
105104
new TastyPrinter(bytes).printContents()
106105
}
107106

108-
val tree =
109-
if (isType) unpickler.unpickleTypeTree()
110-
else unpickler.unpickleExpr()
107+
val mode = if (isType) UnpickleMode.TypeTree else UnpickleMode.Term
108+
val unpickler = new QuoteUnpickler(bytes, splices, mode)
109+
unpickler.enter(Set.empty)
110+
val tree = unpickler.tree
111111

112112
if (pickling ne noPrinter)
113113
println(i"**** unpickle quote ${tree.show}")

compiler/src/dotty/tools/dotc/core/quoted/TastyUnpickler.scala renamed to compiler/src/dotty/tools/dotc/core/quoted/QuoteUnpickler.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ package dotty.tools.dotc.core.quoted
22

33
import dotty.tools.dotc.core.tasty._
44
import dotty.tools.dotc.core.tasty.TastyUnpickler.NameTable
5+
import dotty.tools.dotc.core.tasty.TreeUnpickler.UnpickleMode
56

6-
object TastyUnpickler {
7+
object QuoteUnpickler {
78
class QuotedTreeSectionUnpickler(posUnpickler: Option[PositionUnpickler], splices: Seq[Any])
89
extends DottyUnpickler.TreeSectionUnpickler(posUnpickler, None) {
910
override def unpickle(reader: TastyReader, nameAtRef: NameTable) =
@@ -15,9 +16,9 @@ object TastyUnpickler {
1516
* @param bytes the bytearray containing the Tasty file from which we unpickle
1617
* @param splices splices that will fill the holes in the quote
1718
*/
18-
class TastyUnpickler(bytes: Array[Byte], splices: Seq[Any]) extends DottyUnpickler(bytes) {
19+
class QuoteUnpickler(bytes: Array[Byte], splices: Seq[Any], mode: UnpickleMode) extends DottyUnpickler(bytes, mode) {
1920
import DottyUnpickler._
20-
import TastyUnpickler._
21+
import QuoteUnpickler._
2122

2223
protected override def treeSectionUnpickler(posUnpicklerOpt: Option[PositionUnpickler], commentUnpicklerOpt: Option[CommentUnpickler]): TreeSectionUnpickler =
2324
new QuotedTreeSectionUnpickler(posUnpicklerOpt, splices)

compiler/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import util.{SourceFile, NoSource}
1111
import Annotations.Annotation
1212
import classfile.ClassfileParser
1313
import Names.SimpleName
14+
import TreeUnpickler.UnpickleMode
1415

1516
object DottyUnpickler {
1617

@@ -36,8 +37,9 @@ object DottyUnpickler {
3637

3738
/** A class for unpickling Tasty trees and symbols.
3839
* @param bytes the bytearray containing the Tasty file from which we unpickle
40+
* @param mode the tasty file contains package (TopLevel), an expression (Term) or a type (TypeTree)
3941
*/
40-
class DottyUnpickler(bytes: Array[Byte]) extends ClassfileParser.Embedded with tpd.TreeProvider {
42+
class DottyUnpickler(bytes: Array[Byte], mode: UnpickleMode = UnpickleMode.TopLevel) extends ClassfileParser.Embedded with tpd.TreeProvider {
4143
import tpd._
4244
import DottyUnpickler._
4345

@@ -50,10 +52,7 @@ class DottyUnpickler(bytes: Array[Byte]) extends ClassfileParser.Embedded with t
5052
* @param roots a set of SymDenotations that should be overwritten by unpickling
5153
*/
5254
def enter(roots: Set[SymDenotation])(implicit ctx: Context): Unit =
53-
treeUnpickler.enterTopLevel(roots)
54-
55-
def unpickleExpr()(implicit ctx: Context): Tree =
56-
treeUnpickler.unpickleExpr()
55+
treeUnpickler.enter(roots)
5756

5857
def unpickleTypeTree()(implicit ctx: Context): Tree =
5958
treeUnpickler.unpickleTypeTree()
@@ -62,7 +61,7 @@ class DottyUnpickler(bytes: Array[Byte]) extends ClassfileParser.Embedded with t
6261
new TreeSectionUnpickler(posUnpicklerOpt, commentUnpicklerOpt)
6362
}
6463

65-
protected def computeTrees(implicit ctx: Context) = treeUnpickler.unpickle()
64+
protected def computeTrees(implicit ctx: Context) = treeUnpickler.unpickle(mode)
6665

6766
private[this] var ids: Array[String] = null
6867

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -74,18 +74,12 @@ class TreeUnpickler(reader: TastyReader,
7474
/** Enter all toplevel classes and objects into their scopes
7575
* @param roots a set of SymDenotations that should be overwritten by unpickling
7676
*/
77-
def enterTopLevel(roots: Set[SymDenotation])(implicit ctx: Context): Unit = {
77+
def enter(roots: Set[SymDenotation])(implicit ctx: Context): Unit = {
7878
this.roots = roots
7979
val rdr = new TreeReader(reader).fork
8080
ownerTree = new OwnerTree(NoAddr, 0, rdr.fork, reader.endAddr)
81-
rdr.indexStats(reader.endAddr)
82-
}
83-
84-
def unpickleExpr()(implicit ctx: Context): Tree = {
85-
this.roots = Set(ctx.owner)
86-
val rdr = new TreeReader(reader).fork
87-
ownerTree = new OwnerTree(NoAddr, 0, rdr.fork, reader.endAddr)
88-
rdr.readTerm()
81+
if (rdr.isTopLevel)
82+
rdr.indexStats(reader.endAddr)
8983
}
9084

9185
def unpickleTypeTree()(implicit ctx: Context): Tree = {
@@ -96,9 +90,14 @@ class TreeUnpickler(reader: TastyReader,
9690
}
9791

9892
/** The unpickled trees */
99-
def unpickle()(implicit ctx: Context): List[Tree] = {
93+
def unpickle(mode: UnpickleMode)(implicit ctx: Context): List[Tree] = {
10094
assert(roots != null, "unpickle without previous enterTopLevel")
101-
new TreeReader(reader).readTopLevel()
95+
val rdr = new TreeReader(reader)
96+
mode match {
97+
case UnpickleMode.TopLevel => rdr.readTopLevel()
98+
case UnpickleMode.Term => rdr.readTerm() :: Nil
99+
case UnpickleMode.TypeTree => rdr.readTpt() :: Nil
100+
}
102101
}
103102

104103
class Completer(owner: Symbol, reader: TastyReader) extends LazyType {
@@ -885,21 +884,22 @@ class TreeUnpickler(reader: TastyReader,
885884
}
886885

887886
def skipToplevel()(implicit ctx: Context): Unit= {
888-
if (!isAtEnd)
889-
nextByte match {
890-
case IMPORT | PACKAGE =>
891-
skipTree()
892-
skipToplevel()
893-
case _ =>
894-
}
887+
if (!isAtEnd && isTopLevel) {
888+
skipTree()
889+
skipToplevel()
890+
}
895891
}
896892

893+
def isTopLevel(implicit ctx: Context): Boolean =
894+
nextByte == IMPORT || nextByte == PACKAGE
895+
897896
def readTopLevel()(implicit ctx: Context): List[Tree] = {
898-
@tailrec def read(acc: ListBuffer[Tree]): List[Tree] = nextByte match {
899-
case IMPORT | PACKAGE =>
897+
@tailrec def read(acc: ListBuffer[Tree]): List[Tree] = {
898+
if (isTopLevel) {
900899
acc += readIndexedStat(NoSymbol)
901900
if (!isAtEnd) read(acc) else acc.toList
902-
case _ => // top-level trees which are not imports or packages are not part of tree
901+
}
902+
else // top-level trees which are not imports or packages are not part of tree
903903
acc.toList
904904
}
905905
read(new ListBuffer[tpd.Tree])
@@ -1298,6 +1298,21 @@ class TreeUnpickler(reader: TastyReader,
12981298

12991299
object TreeUnpickler {
13001300

1301+
/** Define the expected format of the tasty bytes
1302+
* - TopLevel: Tasty that contains a full class nested in its package
1303+
* - Term: Tasty that contains only a term tree
1304+
* - TypeTree: Tasty that contains only a type tree or a reference to a type
1305+
*/
1306+
sealed trait UnpickleMode
1307+
object UnpickleMode {
1308+
/** Unpickle a full class in some package */
1309+
object TopLevel extends UnpickleMode
1310+
/** Unpickle as a TermTree */
1311+
object Term extends UnpickleMode
1312+
/** Unpickle as a TypeTree */
1313+
object TypeTree extends UnpickleMode
1314+
}
1315+
13011316
/** A marker value used to detect cyclic reference while unpickling definitions. */
13021317
@sharable val PoisonTree: tpd.Tree = Thicket(Nil)
13031318

compiler/src/dotty/tools/dotc/transform/Pickler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class Pickler extends Phase {
9898
val unpicklers =
9999
for ((cls, pickler) <- picklers) yield {
100100
val unpickler = new DottyUnpickler(pickler.assembleParts())
101-
unpickler.enter(roots = Set())
101+
unpickler.enter(roots = Set.empty)
102102
cls -> unpickler
103103
}
104104
pickling.println("************* entered toplevel ***********")

0 commit comments

Comments
 (0)