@@ -10,6 +10,7 @@ import ast.Trees._
10
10
import ast .{untpd , tpd }
11
11
import Contexts ._ , Symbols ._ , Types ._ , Names ._ , Constants ._ , Decorators ._ , Annotations ._ , Flags ._
12
12
import Denotations .MultiDenotation
13
+ import Comments .{Comment , CommentsContext }
13
14
import typer .Inliner
14
15
import NameKinds ._
15
16
import StdNames .nme
@@ -18,6 +19,7 @@ import printing.Printer
18
19
import printing .Texts ._
19
20
import util .SourceFile
20
21
import annotation .constructorOnly
22
+ import collection .mutable
21
23
22
24
object TreePickler {
23
25
@@ -44,6 +46,25 @@ class TreePickler(pickler: TastyPickler) {
44
46
private val forwardSymRefs = Symbols .newMutableSymbolMap[List [Addr ]]
45
47
private val pickledTypes = new java.util.IdentityHashMap [Type , Any ] // Value type is really Addr, but that's not compatible with null
46
48
49
+ /** A list of annotation trees for every member definition, so that later
50
+ * parallel position pickling does not need to access and force symbols.
51
+ */
52
+ private val annotTrees = util.HashTable [untpd.MemberDef , mutable.ListBuffer [Tree ]]()
53
+
54
+ /** A map from member definitions to their doc comments, so that later
55
+ * parallel comment pickling does not need to access symbols of trees (which
56
+ * would involve accessing symbols of named types and possibly changing phases
57
+ * in doing so).
58
+ */
59
+ private val docStrings = util.HashTable [untpd.MemberDef , Comment ]()
60
+
61
+ def treeAnnots (tree : untpd.MemberDef ): List [Tree ] =
62
+ val ts = annotTrees.lookup(tree)
63
+ if ts == null then Nil else ts.toList
64
+
65
+ def docString (tree : untpd.MemberDef ): Option [Comment ] =
66
+ Option (docStrings.lookup(tree))
67
+
47
68
private def withLength (op : => Unit ) = {
48
69
val lengthAddr = reserveRef(relative = true )
49
70
op
@@ -309,7 +330,8 @@ class TreePickler(pickler: TastyPickler) {
309
330
if (! tree.isEmpty) pickleTree(tree)
310
331
}
311
332
312
- def pickleDef (tag : Int , sym : Symbol , tpt : Tree , rhs : Tree = EmptyTree , pickleParams : => Unit = ())(using Context ): Unit = {
333
+ def pickleDef (tag : Int , mdef : MemberDef , tpt : Tree , rhs : Tree = EmptyTree , pickleParams : => Unit = ())(using Context ): Unit = {
334
+ val sym = mdef.symbol
313
335
assert(symRefs(sym) == NoAddr , sym)
314
336
registerDef(sym)
315
337
writeByte(tag)
@@ -321,16 +343,21 @@ class TreePickler(pickler: TastyPickler) {
321
343
case _ if tpt.isType => pickleTpt(tpt)
322
344
}
323
345
pickleTreeUnlessEmpty(rhs)
324
- pickleModifiers(sym)
346
+ pickleModifiers(sym, mdef )
325
347
}
348
+ for
349
+ docCtx <- ctx.docCtx
350
+ comment <- docCtx.docstring(sym)
351
+ do
352
+ docStrings.enter(mdef, comment)
326
353
}
327
354
328
355
def pickleParam (tree : Tree )(using Context ): Unit = {
329
356
registerTreeAddr(tree)
330
357
tree match {
331
- case tree : ValDef => pickleDef(PARAM , tree.symbol , tree.tpt)
332
- case tree : DefDef => pickleDef(PARAM , tree.symbol , tree.tpt, tree.rhs)
333
- case tree : TypeDef => pickleDef(TYPEPARAM , tree.symbol , tree.rhs)
358
+ case tree : ValDef => pickleDef(PARAM , tree, tree.tpt)
359
+ case tree : DefDef => pickleDef(PARAM , tree, tree.tpt, tree.rhs)
360
+ case tree : TypeDef => pickleDef(TYPEPARAM , tree, tree.rhs)
334
361
}
335
362
}
336
363
@@ -520,7 +547,7 @@ class TreePickler(pickler: TastyPickler) {
520
547
patterns.foreach(pickleTree)
521
548
}
522
549
case tree : ValDef =>
523
- pickleDef(VALDEF , tree.symbol , tree.tpt, tree.rhs)
550
+ pickleDef(VALDEF , tree, tree.tpt, tree.rhs)
524
551
case tree : DefDef =>
525
552
def pickleParamss (paramss : List [List [ValDef ]]): Unit = paramss match
526
553
case Nil =>
@@ -531,9 +558,9 @@ class TreePickler(pickler: TastyPickler) {
531
558
def pickleAllParams =
532
559
pickleParams(tree.tparams)
533
560
pickleParamss(tree.vparamss)
534
- pickleDef(DEFDEF , tree.symbol , tree.tpt, tree.rhs, pickleAllParams)
561
+ pickleDef(DEFDEF , tree, tree.tpt, tree.rhs, pickleAllParams)
535
562
case tree : TypeDef =>
536
- pickleDef(TYPEDEF , tree.symbol , tree.rhs)
563
+ pickleDef(TYPEDEF , tree, tree.rhs)
537
564
case tree : Template =>
538
565
registerDef(tree.symbol)
539
566
writeByte(TEMPLATE )
@@ -648,7 +675,7 @@ class TreePickler(pickler: TastyPickler) {
648
675
pickleName(id.name)
649
676
}
650
677
651
- def pickleModifiers (sym : Symbol )(using Context ): Unit = {
678
+ def pickleModifiers (sym : Symbol , mdef : MemberDef )(using Context ): Unit = {
652
679
import Flags ._
653
680
var flags = sym.flags
654
681
val privateWithin = sym.privateWithin
@@ -660,7 +687,7 @@ class TreePickler(pickler: TastyPickler) {
660
687
if (flags.is(ParamAccessor ) && sym.isTerm && ! sym.isSetter)
661
688
flags = flags &~ ParamAccessor // we only generate a tag for parameter setters
662
689
pickleFlags(flags, sym.isTerm)
663
- sym.annotations.foreach(pickleAnnotation(sym, _))
690
+ val annots = sym.annotations.foreach(pickleAnnotation(sym, mdef , _))
664
691
}
665
692
666
693
def pickleFlags (flags : FlagSet , isTerm : Boolean )(using Context ): Unit = {
@@ -723,12 +750,15 @@ class TreePickler(pickler: TastyPickler) {
723
750
ann.symbol == defn.BodyAnnot // inline bodies are reconstituted automatically when unpickling
724
751
}
725
752
726
- def pickleAnnotation (owner : Symbol , ann : Annotation )(using Context ): Unit = {
727
- if ( ! isUnpicklable(owner, ann)) {
753
+ def pickleAnnotation (owner : Symbol , mdef : MemberDef , ann : Annotation )(using Context ): Unit =
754
+ if ! isUnpicklable(owner, ann) then
728
755
writeByte(ANNOTATION )
729
756
withLength { pickleType(ann.symbol.typeRef); pickleTree(ann.tree) }
730
- }
731
- }
757
+ var treeBuf = annotTrees.lookup(mdef)
758
+ if treeBuf == null then
759
+ treeBuf = new mutable.ListBuffer [Tree ]
760
+ annotTrees.enter(mdef, treeBuf)
761
+ treeBuf += ann.tree
732
762
733
763
// ---- main entry points ---------------------------------------
734
764
0 commit comments