Skip to content

Commit 41d3369

Browse files
committed
Make comment pickling context independent
1 parent 7d6e0aa commit 41d3369

File tree

3 files changed

+44
-28
lines changed

3 files changed

+44
-28
lines changed
Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package dotty.tools.dotc.core.tasty
22

3-
import dotty.tools.dotc.ast.tpd
3+
import dotty.tools.dotc.ast.{tpd, untpd}
44
import dotty.tools.dotc.core.Comments.{Comment, CommentsContext, ContextDocstrings}
55
import dotty.tools.dotc.core.Contexts._
66

@@ -9,36 +9,36 @@ import TastyBuffer.{Addr, NoAddr}
99

1010
import java.nio.charset.Charset
1111

12-
class CommentPickler(pickler: TastyPickler, addrOfTree: tpd.Tree => Addr)(using Context) {
12+
class CommentPickler(pickler: TastyPickler, addrOfTree: tpd.Tree => Addr, docString: untpd.MemberDef => Option[Comment]):
1313
private val buf = new TastyBuffer(5000)
1414
pickler.newSection("Comments", buf)
1515

16-
def pickleComment(root: tpd.Tree): Unit = {
17-
assert(ctx.docCtx.isDefined, "Trying to pickle comments, but there's no `docCtx`.")
18-
new Traverser(ctx.docCtx.get).traverse(root)
19-
}
16+
def pickleComment(root: tpd.Tree): Unit = traverse(root)
2017

21-
def pickleComment(addr: Addr, comment: Option[Comment]): Unit = comment match {
22-
case Some(cmt) if addr != NoAddr =>
23-
val bytes = cmt.raw.getBytes(Charset.forName("UTF-8"))
18+
private def pickleComment(addr: Addr, comment: Comment): Unit =
19+
if addr != NoAddr then
20+
val bytes = comment.raw.getBytes(Charset.forName("UTF-8"))
2421
val length = bytes.length
2522
buf.writeAddr(addr)
2623
buf.writeNat(length)
2724
buf.writeBytes(bytes, length)
28-
buf.writeLongInt(cmt.span.coords)
29-
case other =>
30-
()
31-
}
32-
33-
private class Traverser(docCtx: ContextDocstrings) extends tpd.TreeTraverser {
34-
override def traverse(tree: tpd.Tree)(using Context): Unit =
35-
tree match {
36-
case md: tpd.MemberDef =>
37-
val comment = docCtx.docstring(md.symbol)
38-
pickleComment(addrOfTree(md), comment)
39-
traverseChildren(md)
25+
buf.writeLongInt(comment.span.coords)
26+
27+
private def traverse(x: Any): Unit = x match
28+
case x: untpd.Tree @unchecked =>
29+
x match
30+
case x: tpd.MemberDef @unchecked => // at this point all MembderDefs are t(y)p(e)d.
31+
for comment <- docString(x) do pickleComment(addrOfTree(x), comment)
4032
case _ =>
41-
traverseChildren(tree)
42-
}
43-
}
44-
}
33+
val limit = x.productArity
34+
var n = 0
35+
while n < limit do
36+
traverse(x.productElement(n))
37+
n += 1
38+
case y :: ys =>
39+
traverse(y)
40+
traverse(ys)
41+
case _ =>
42+
43+
end CommentPickler
44+

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import ast.Trees._
1010
import ast.{untpd, tpd}
1111
import Contexts._, Symbols._, Types._, Names._, Constants._, Decorators._, Annotations._, Flags._
1212
import Denotations.MultiDenotation
13+
import Comments.{Comment, CommentsContext}
1314
import typer.Inliner
1415
import NameKinds._
1516
import StdNames.nme
@@ -50,10 +51,20 @@ class TreePickler(pickler: TastyPickler) {
5051
*/
5152
private val annotTrees = util.HashTable[untpd.MemberDef, mutable.ListBuffer[Tree]]()
5253

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+
5361
def treeAnnots(tree: untpd.MemberDef): List[Tree] =
5462
val ts = annotTrees.lookup(tree)
5563
if ts == null then Nil else ts.toList
5664

65+
def docString(tree: untpd.MemberDef): Option[Comment] =
66+
Option(docStrings.lookup(tree))
67+
5768
private def withLength(op: => Unit) = {
5869
val lengthAddr = reserveRef(relative = true)
5970
op
@@ -334,6 +345,11 @@ class TreePickler(pickler: TastyPickler) {
334345
pickleTreeUnlessEmpty(rhs)
335346
pickleModifiers(sym, mdef)
336347
}
348+
for
349+
docCtx <- ctx.docCtx
350+
comment <- docCtx.docstring(sym)
351+
do
352+
docStrings.enter(mdef, comment)
337353
}
338354

339355
def pickleParam(tree: Tree)(using Context): Unit = {

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,16 @@ class Pickler extends Phase {
6262
val treePkl = pickler.treePkl
6363
treePkl.pickle(tree :: Nil)
6464
val positionWarnings = new mutable.ListBuffer[String]()
65-
val parContext = ctx.fresh // TODO refine
66-
val pickledF = inContext(parContext) {
65+
val pickledF = inContext(ctx.fresh) {
6766
Future {
6867
treePkl.compactify()
6968
if tree.span.exists then
7069
new PositionPickler(pickler, treePkl.buf.addrOfTree, treePkl.treeAnnots)
7170
.picklePositions(tree :: Nil, positionWarnings)
7271

7372
if !ctx.settings.YdropComments.value then
74-
new CommentPickler(pickler, treePkl.buf.addrOfTree).pickleComment(tree)
73+
new CommentPickler(pickler, treePkl.buf.addrOfTree, treePkl.docString)
74+
.pickleComment(tree)
7575

7676
val pickled = pickler.assembleParts()
7777

0 commit comments

Comments
 (0)