Skip to content

Commit 646453a

Browse files
committed
Add infrastructure for pickling/unpickling with holes and splices
1 parent 300c37e commit 646453a

File tree

5 files changed

+39
-3
lines changed

5 files changed

+39
-3
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ object DottyUnpickler {
2020
class TreeSectionUnpickler(posUnpickler: Option[PositionUnpickler])
2121
extends SectionUnpickler[TreeUnpickler]("ASTs") {
2222
def unpickle(reader: TastyReader, nameAtRef: NameTable) =
23-
new TreeUnpickler(reader, nameAtRef, posUnpickler)
23+
new TreeUnpickler(reader, nameAtRef, posUnpickler, Seq.empty)
2424
}
2525

2626
class PositionsSectionUnpickler extends SectionUnpickler[PositionUnpickler]("Positions") {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package dotty.tools
2+
package dotc
3+
package core
4+
package tasty
5+
6+
import ast.Trees._
7+
8+
object Splicing {
9+
import ast.tpd._
10+
11+
type Splice = AnyRef /* tpd.Tree | tpd.Tree => tpd.Tree */
12+
13+
case class Hole(args: List[Tree]) extends TermTree
14+
}

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ Standard-Section: "ASTs" TopLevelStat*
109109
BYNAMEtpt underlying_Term
110110
EMPTYTREE
111111
SHARED term_ASTRef
112+
HOLE Length idx_Nat arg_Tree*
112113
Application = APPLY Length fn_Term arg_Term*
113114
114115
TYPEAPPLY Length fn_Term arg_Type*
@@ -396,6 +397,7 @@ object TastyFormat {
396397
final val ANNOTATION = 173
397398
final val TERMREFin = 174
398399
final val TYPEREFin = 175
400+
final val HOLE = 255
399401

400402
final val firstSimpleTreeTag = UNITconst
401403
final val firstNatTreeTag = SHARED
@@ -555,6 +557,7 @@ object TastyFormat {
555557
case SUPERtype => "SUPERtype"
556558
case TERMREFin => "TERMREFin"
557559
case TYPEREFin => "TYPEREFin"
560+
558561
case REFINEDtype => "REFINEDtype"
559562
case REFINEDtpt => "REFINEDtpt"
560563
case APPLIEDtype => "APPLIEDtype"
@@ -576,14 +579,15 @@ object TastyFormat {
576579
case ANNOTATION => "ANNOTATION"
577580
case PRIVATEqualified => "PRIVATEqualified"
578581
case PROTECTEDqualified => "PROTECTEDqualified"
582+
case HOLE => "HOLE"
579583
}
580584

581585
/** @return If non-negative, the number of leading references (represented as nats) of a length/trees entry.
582586
* If negative, minus the number of leading non-reference trees.
583587
*/
584588
def numRefs(tag: Int) = tag match {
585589
case VALDEF | DEFDEF | TYPEDEF | TYPEPARAM | PARAM | NAMEDARG | RETURN | BIND |
586-
SELFDEF | REFINEDtype | TERMREFin | TYPEREFin => 1
590+
SELFDEF | REFINEDtype | TERMREFin | TYPEREFin | HOLE => 1
587591
case RENAMED | PARAMtype => 2
588592
case POLYtype | METHODtype | TYPELAMBDAtype => -1
589593
case _ => 0

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import StdNames.nme
1414
import TastyBuffer._
1515
import TypeApplications._
1616
import transform.SymUtils._
17+
import Splicing.Hole
1718
import config.Config
1819

1920
class TreePickler(pickler: TastyPickler) {
@@ -27,6 +28,8 @@ class TreePickler(pickler: TastyPickler) {
2728
private val forwardSymRefs = Symbols.newMutableSymbolMap[List[Addr]]
2829
private val pickledTypes = new java.util.IdentityHashMap[Type, Any] // Value type is really Addr, but that's not compatible with null
2930

31+
private var holeCount = 0
32+
3033
private def withLength(op: => Unit) = {
3134
val lengthAddr = reserveRef(relative = true)
3235
op
@@ -542,6 +545,13 @@ class TreePickler(pickler: TastyPickler) {
542545
case TypeBoundsTree(lo, hi) =>
543546
writeByte(TYPEBOUNDStpt)
544547
withLength { pickleTree(lo); pickleTree(hi) }
548+
case Hole(args) =>
549+
writeByte(HOLE)
550+
withLength {
551+
writeNat(holeCount)
552+
holeCount += 1
553+
args.foreach(pickleTree)
554+
}
545555
}
546556
catch {
547557
case ex: AssertionError =>

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import util.Positions._
1111
import ast.{tpd, Trees, untpd}
1212
import Trees._
1313
import Decorators._
14+
import Splicing.Splice
1415
import transform.SymUtils._
1516
import TastyUnpickler._, TastyBuffer._
1617
import scala.annotation.{tailrec, switch}
@@ -25,7 +26,10 @@ import config.Config
2526
* @param tastyName the nametable
2627
* @param posUNpicklerOpt the unpickler for positions, if it exists
2728
*/
28-
class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpicklerOpt: Option[PositionUnpickler]) {
29+
class TreeUnpickler(reader: TastyReader,
30+
nameAtRef: NameRef => TermName,
31+
posUnpicklerOpt: Option[PositionUnpickler],
32+
splices: Seq[Splice]) {
2933
import TastyFormat._
3034
import TreeUnpickler._
3135
import tpd._
@@ -1031,6 +1035,10 @@ class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpi
10311035
LambdaTypeTree(tparams, body)
10321036
case TYPEBOUNDStpt =>
10331037
TypeBoundsTree(readTpt(), readTpt())
1038+
case HOLE =>
1039+
val idx = readNat()
1040+
val args = until(end)(readTerm())
1041+
(splices(idx) /: args)(_.asInstanceOf[Tree => Tree](_)).asInstanceOf[Tree]
10341042
case _ =>
10351043
readPathTerm()
10361044
}

0 commit comments

Comments
 (0)