Skip to content

Commit deec4c1

Browse files
committed
Improve handling of parameters in Tasty format
Using two different tags for empty parameter lists and parameter splits leads to a more straightforward encoding. Also: shift tags around to create more free slots for single element trees.
1 parent 9591d96 commit deec4c1

File tree

3 files changed

+72
-57
lines changed

3 files changed

+72
-57
lines changed

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -550,11 +550,17 @@ class TreePickler(pickler: TastyPickler) {
550550
case tree: ValDef =>
551551
pickleDef(VALDEF, tree, tree.tpt, tree.rhs)
552552
case tree: DefDef =>
553-
def pickleParamss(paramss: List[List[ValDef]]): Unit = paramss match
553+
def pickleParamss(paramss: List[List[Tree]]): Unit = paramss match
554554
case Nil =>
555-
case params :: rest =>
555+
case Nil :: rest =>
556+
writeByte(EMPTYCLAUSE)
557+
pickleParamss(rest)
558+
case (params @ (param1 :: _)) :: rest =>
556559
pickleParams(params)
557-
if params.isEmpty || rest.nonEmpty then writeByte(PARAMEND)
560+
rest match
561+
case (param2 :: _) :: _ if param1.symbol.isType == param2.symbol.isType =>
562+
writeByte(SPLITCLAUSE)
563+
case _ =>
558564
pickleParamss(rest)
559565
def pickleAllParams =
560566
pickleParams(tree.tparams)

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

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ class TreeUnpickler(reader: TastyReader,
139139
def skipParams(): Unit =
140140
while
141141
val tag = nextByte
142-
tag == PARAM || tag == TYPEPARAM || tag == PARAMEND
142+
tag == PARAM || tag == TYPEPARAM || tag == EMPTYCLAUSE || tag == SPLITCLAUSE
143143
do skipTree()
144144

145145
/** Record all directly nested definitions and templates in current tree
@@ -780,12 +780,15 @@ class TreeUnpickler(reader: TastyReader,
780780
val tag = readByte()
781781
val end = readEnd()
782782

783-
def readParamss(using Context): List[List[ValDef]] = nextByte match
784-
case PARAM | PARAMEND =>
785-
readParams[ValDef](PARAM) ::
786-
(if nextByte == PARAMEND then { readByte(); readParamss } else Nil)
787-
case _ =>
788-
Nil
783+
def readParamss()(using Context): List[List[Tree]] =
784+
def readRest() =
785+
if nextByte == SPLITCLAUSE then readByte()
786+
readParamss()
787+
nextByte match
788+
case PARAM => readParams[ValDef](PARAM) :: readRest()
789+
case TYPEPARAM => readParams[TypeDef](TYPEPARAM) :: readRest()
790+
case EMPTYCLAUSE => readByte(); Nil :: readRest()
791+
case _ => Nil
789792

790793
val localCtx = localContext(sym)
791794

@@ -819,7 +822,7 @@ class TreeUnpickler(reader: TastyReader,
819822
val tree: MemberDef = tag match {
820823
case DEFDEF =>
821824
val tparams = readParams[TypeDef](TYPEPARAM)(using localCtx)
822-
val vparamss = readParamss(using localCtx)
825+
val vparamss = readParamss()(using localCtx).asInstanceOf[List[List[ValDef]]]
823826
val tpt = readTpt()(using localCtx)
824827
val typeParams = tparams.map(_.symbol)
825828
val valueParamss = normalizeIfConstructor(

tasty/src/dotty/tools/tasty/TastyFormat.scala

Lines changed: 52 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -62,17 +62,21 @@ Standard-Section: "ASTs" TopLevelStat*
6262
IMPORT Length qual_Term Selector* -- import qual selectors
6363
EXPORT Length qual_Term Selector* -- export qual selectors
6464
ValOrDefDef = VALDEF Length NameRef type_Term rhs_Term? Modifier* -- modifiers val name : type (= rhs)?
65-
DEFDEF Length NameRef TypeParam* Params* returnType_Term
66-
rhs_Term? Modifier* -- modifiers def name [typeparams] paramss : returnType (= rhs)?
65+
DEFDEF Length NameRef Param* returnType_Term rhs_Term?
66+
Modifier* -- modifiers def name [typeparams] paramss : returnType (= rhs)?
6767
Selector = IMPORTED name_NameRef -- name, "_" for normal wildcards, "" for given wildcards
6868
RENAMED to_NameRef -- => name
6969
BOUNDED type_Term -- type bound
7070
7171
TypeParam = TYPEPARAM Length NameRef type_Term Modifier* -- modifiers name bounds
72-
Param = PARAM Length NameRef type_Term rhs_Term? Modifier* -- modifiers name : type (= rhs_Term)?. `rhsTerm` is present in the case of an aliased class parameter
73-
PARAMEND -- ends a parameter clause
72+
TermParam = PARAM Length NameRef type_Term rhs_Term? Modifier* -- modifiers name : type (= rhs_Term)?. `rhsTerm` is present in the case of an aliased class parameter
73+
EMPTYCLAUSE -- an empty parameter clause ()
74+
SPLITCLAUSE -- splits two non-empty parameter clauses of the same kind
75+
Param = TypeParam
76+
TermParam
7477
-- needed if previous parameter clause is empty or another parameter clause follows
75-
Template = TEMPLATE Length TypeParam* Param* parent_Term* Self? Stat* -- [typeparams] paramss extends parents { self => stats }, where Stat* always starts with the primary constructor.
78+
Template = TEMPLATE Length TypeParam* TermParam* parent_Term* Self?
79+
Stat* -- [typeparams] paramss extends parents { self => stats }, where Stat* always starts with the primary constructor.
7680
Self = SELFDEF selfName_NameRef selfType_Term -- selfName : selfType
7781
7882
Term = Path -- Paths represent both types and terms
@@ -222,9 +226,9 @@ Note: The signature of a SELECTin or TERMREFin node is the signature of the sele
222226
223227
Note: Tree tags are grouped into 5 categories that determine what follows, and thus allow to compute the size of the tagged tree in a generic way.
224228
225-
Category 1 (tags 1-49) : tag
226-
Category 2 (tags 50-79) : tag Nat
227-
Category 3 (tags 80-109) : tag AST
229+
Category 1 (tags 1-59) : tag
230+
Category 2 (tags 60-89) : tag Nat
231+
Category 3 (tags 90-109) : tag AST
228232
Category 4 (tags 110-127): tag Nat AST
229233
Category 5 (tags 128-255): tag Length <payload>
230234
@@ -260,8 +264,8 @@ Standard Section: "Comments" Comment*
260264
object TastyFormat {
261265

262266
final val header: Array[Int] = Array(0x5C, 0xA1, 0xAB, 0x1F)
263-
val MajorVersion: Int = 26
264-
val MinorVersion: Int = 1
267+
val MajorVersion: Int = 27
268+
val MinorVersion: Int = 0
265269

266270
final val ASTsSection = "ASTs"
267271
final val PositionsSection = "Positions"
@@ -374,46 +378,47 @@ object TastyFormat {
374378
final val PARAMsetter = 38
375379
final val EXPORTED = 39
376380
final val OPEN = 40
377-
final val PARAMEND = 41
378-
final val PARAMalias = 42
379-
final val TRANSPARENT = 43
380-
final val INFIX = 44
381+
final val PARAMalias = 41
382+
final val TRANSPARENT = 42
383+
final val INFIX = 43
384+
final val EMPTYCLAUSE = 44
385+
final val SPLITCLAUSE = 45
381386

382387
// Cat. 2: tag Nat
383388

384-
final val SHAREDterm = 50
385-
final val SHAREDtype = 51
386-
final val TERMREFdirect = 52
387-
final val TYPEREFdirect = 53
388-
final val TERMREFpkg = 54
389-
final val TYPEREFpkg = 55
390-
final val RECthis = 56
391-
final val BYTEconst = 57
392-
final val SHORTconst = 58
393-
final val CHARconst = 59
394-
final val INTconst = 60
395-
final val LONGconst = 61
396-
final val FLOATconst = 62
397-
final val DOUBLEconst = 63
398-
final val STRINGconst = 64
399-
final val IMPORTED = 65
400-
final val RENAMED = 66
389+
final val SHAREDterm = 60
390+
final val SHAREDtype = 61
391+
final val TERMREFdirect = 62
392+
final val TYPEREFdirect = 63
393+
final val TERMREFpkg = 64
394+
final val TYPEREFpkg = 65
395+
final val RECthis = 66
396+
final val BYTEconst = 67
397+
final val SHORTconst = 68
398+
final val CHARconst = 69
399+
final val INTconst = 70
400+
final val LONGconst = 71
401+
final val FLOATconst = 72
402+
final val DOUBLEconst = 73
403+
final val STRINGconst = 74
404+
final val IMPORTED = 75
405+
final val RENAMED = 76
401406

402407
// Cat. 3: tag AST
403408

404-
final val THIS = 80
405-
final val QUALTHIS = 81
406-
final val CLASSconst = 82
407-
final val BYNAMEtype = 83
408-
final val BYNAMEtpt = 84
409-
final val NEW = 85
410-
final val THROW = 86
411-
final val IMPLICITarg = 87
412-
final val PRIVATEqualified = 88
413-
final val PROTECTEDqualified = 89
414-
final val RECtype = 90
415-
final val SINGLETONtpt = 91
416-
final val BOUNDED = 92
409+
final val THIS = 90
410+
final val QUALTHIS = 91
411+
final val CLASSconst = 92
412+
final val BYNAMEtype = 93
413+
final val BYNAMEtpt = 94
414+
final val NEW = 95
415+
final val THROW = 96
416+
final val IMPLICITarg = 97
417+
final val PRIVATEqualified = 98
418+
final val PROTECTEDqualified = 99
419+
final val RECtype = 100
420+
final val SINGLETONtpt = 101
421+
final val BOUNDED = 102
417422

418423
// Cat. 4: tag Nat AST
419424

@@ -493,7 +498,7 @@ object TastyFormat {
493498

494499
/** Useful for debugging */
495500
def isLegalTag(tag: Int): Boolean =
496-
firstSimpleTreeTag <= tag && tag <= INFIX ||
501+
firstSimpleTreeTag <= tag && tag <= SPLITCLAUSE ||
497502
firstNatTreeTag <= tag && tag <= RENAMED ||
498503
firstASTTreeTag <= tag && tag <= BOUNDED ||
499504
firstNatASTTreeTag <= tag && tag <= NAMEDARG ||
@@ -602,8 +607,9 @@ object TastyFormat {
602607
case PARAMsetter => "PARAMsetter"
603608
case EXPORTED => "EXPORTED"
604609
case OPEN => "OPEN"
605-
case PARAMEND => "PARAMEND"
606610
case PARAMalias => "PARAMalias"
611+
case EMPTYCLAUSE => "EMPTYCLAUSE"
612+
case SPLITCLAUSE => "SPLITCLAUSE"
607613

608614
case SHAREDterm => "SHAREDterm"
609615
case SHAREDtype => "SHAREDtype"

0 commit comments

Comments
 (0)