Skip to content

Commit e563b43

Browse files
committed
Implement comments as attachments instead of tree members
1 parent 69f4133 commit e563b43

File tree

3 files changed

+64
-63
lines changed

3 files changed

+64
-63
lines changed

src/dotty/tools/dotc/ast/Trees.scala

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -317,10 +317,6 @@ object Trees {
317317
private[ast] def rawMods: Modifiers[T] =
318318
if (myMods == null) genericEmptyModifiers else myMods
319319

320-
private[this] var myComment: Option[String] = None
321-
322-
def rawComment: Option[String] = myComment
323-
324320
def withMods(mods: Modifiers[Untyped]): ThisTree[Untyped] = {
325321
val tree = if (myMods == null || (myMods == mods)) this else clone.asInstanceOf[MemberDef[Untyped]]
326322
tree.setMods(mods)
@@ -329,11 +325,6 @@ object Trees {
329325

330326
def withFlags(flags: FlagSet): ThisTree[Untyped] = withMods(Modifiers(flags))
331327

332-
def withComment(cmt: Option[String]): ThisTree[Untyped] = {
333-
myComment = cmt
334-
asInstanceOf[ThisTree[Untyped]]
335-
}
336-
337328
protected def setMods(mods: Modifiers[T @uncheckedVariance]) = myMods = mods
338329

339330
override def envelope: Position = rawMods.pos.union(pos).union(initialPos)

src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,17 @@ import util.Positions._
2020
import Constants._
2121
import ScriptParsers._
2222
import annotation.switch
23-
import util.DotClass
23+
import util.{Attachment, DotClass}
2424

2525
object Parsers {
2626

2727
import ast.untpd._
2828

2929
case class OpInfo(operand: Tree, operator: Name, offset: Offset)
3030

31+
/** Comment attachment, attached to trees with documentation comments */
32+
val Comment = new Attachment.Key[String]
33+
3134
class ParensCounters {
3235
private var parCounts = new Array[Int](lastParen - firstParen)
3336

@@ -1750,9 +1753,11 @@ object Parsers {
17501753
}
17511754
} else EmptyTree
17521755
lhs match {
1753-
case (id @ Ident(name: TermName)) :: Nil =>
1754-
cpy.ValDef(id)(name, tpt, rhs).withMods(mods).withComment(docstring)
1755-
case _ =>
1756+
case (id @ Ident(name: TermName)) :: Nil => {
1757+
val valDef = cpy.ValDef(id)(name, tpt, rhs).withMods(mods)
1758+
docstring.map(x => valDef.putAttachment(Comment, x))
1759+
valDef
1760+
} case _ =>
17561761
PatDef(mods, lhs, tpt, rhs)
17571762
}
17581763
}
@@ -1796,7 +1801,9 @@ object Parsers {
17961801
accept(EQUALS)
17971802
expr()
17981803
}
1799-
DefDef(name, tparams, vparamss, tpt, rhs).withMods(mods1).withComment(docstring)
1804+
val defDef = DefDef(name, tparams, vparamss, tpt, rhs).withMods(mods1)
1805+
docstring.map(x => defDef.putAttachment(Comment, x))
1806+
defDef
18001807
}
18011808
}
18021809

@@ -1838,7 +1845,9 @@ object Parsers {
18381845
in.token match {
18391846
case EQUALS =>
18401847
in.nextToken()
1841-
TypeDef(name, tparams, typ()).withMods(mods).withComment(docstring)
1848+
val tDef = TypeDef(name, tparams, typ()).withMods(mods)
1849+
docstring.map(x => tDef.putAttachment(Comment, x))
1850+
tDef
18421851
case SUPERTYPE | SUBTYPE | SEMI | NEWLINE | NEWLINES | COMMA | RBRACE | EOF =>
18431852
TypeDef(name, tparams, typeBounds()).withMods(mods)
18441853
case _ =>
@@ -1884,9 +1893,9 @@ object Parsers {
18841893
}
18851894
val templ = templateOpt(constr)
18861895

1887-
TypeDef(name, templ)
1888-
.withMods(mods)
1889-
.withComment(docstring)
1896+
val tDef = TypeDef(name, templ).withMods(mods)
1897+
docstring.map(x => tDef.putAttachment(Comment, x))
1898+
tDef
18901899
}
18911900

18921901
/** ConstrMods ::= AccessModifier
@@ -1906,9 +1915,9 @@ object Parsers {
19061915
val name = ident()
19071916
val template = templateOpt(emptyConstructor())
19081917

1909-
ModuleDef(name, template)
1910-
.withMods(mods)
1911-
.withComment(docstring)
1918+
val mDef = ModuleDef(name, template).withMods(mods)
1919+
docstring.map(x => mDef.putAttachment(Comment, x))
1920+
mDef
19121921
}
19131922

19141923
/* -------- TEMPLATES ------------------------------------------- */

test/test/DottyDocParsingTests.scala

Lines changed: 43 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package test
22

33
import dotty.tools.dotc.core.Contexts.Context
44
import dotty.tools.dotc.ast.Trees._
5+
import dotty.tools.dotc.parsing.Parsers.Comment
56

67
import org.junit.Assert._
78
import org.junit.Test
@@ -31,7 +32,7 @@ class DottyDocParsingTests extends DottyTest {
3132

3233
checkFrontend(source) {
3334
case PackageDef(_, Seq(c: TypeDef)) =>
34-
assert(c.rawComment == None, "Should not have a comment, mainly used for exhaustive tests")
35+
assert(c.getAttachment(Comment) == None, "Should not have a comment, mainly used for exhaustive tests")
3536
}
3637
}
3738

@@ -46,7 +47,7 @@ class DottyDocParsingTests extends DottyTest {
4647

4748
checkFrontend(source) {
4849
case PackageDef(_, Seq(t @ TypeDef(name, _))) if name.toString == "Class" =>
49-
checkDocString(t.rawComment, "/** Hello world! */")
50+
checkDocString(t.getAttachment(Comment), "/** Hello world! */")
5051
}
5152
}
5253

@@ -61,7 +62,7 @@ class DottyDocParsingTests extends DottyTest {
6162

6263
checkFrontend(source) {
6364
case PackageDef(_, Seq(t @ TypeDef(name, _))) if name.toString == "Class" =>
64-
checkDocString(t.rawComment, "/** Hello /* multiple open */ world! */")
65+
checkDocString(t.getAttachment(Comment), "/** Hello /* multiple open */ world! */")
6566
}
6667
}
6768
@Test def multipleClassesInPackage() = {
@@ -79,8 +80,8 @@ class DottyDocParsingTests extends DottyTest {
7980
checkCompile("frontend", source) { (_, ctx) =>
8081
ctx.compilationUnit.untpdTree match {
8182
case PackageDef(_, Seq(c1 @ TypeDef(_,_), c2 @ TypeDef(_,_))) => {
82-
checkDocString(c1.rawComment, "/** Class1 docstring */")
83-
checkDocString(c2.rawComment, "/** Class2 docstring */")
83+
checkDocString(c1.getAttachment(Comment), "/** Class1 docstring */")
84+
checkDocString(c2.getAttachment(Comment), "/** Class2 docstring */")
8485
}
8586
}
8687
}
@@ -94,15 +95,15 @@ class DottyDocParsingTests extends DottyTest {
9495
""".stripMargin
9596

9697
checkFrontend(source) {
97-
case PackageDef(_, Seq(t @ TypeDef(_,_))) => checkDocString(t.rawComment, "/** Class without package */")
98+
case PackageDef(_, Seq(t @ TypeDef(_,_))) => checkDocString(t.getAttachment(Comment), "/** Class without package */")
9899
}
99100
}
100101

101102
@Test def SingleTraitWihoutPackage() = {
102103
val source = "/** Trait docstring */\ntrait Trait"
103104

104105
checkFrontend(source) {
105-
case PackageDef(_, Seq(t @ TypeDef(_,_))) => checkDocString(t.rawComment, "/** Trait docstring */")
106+
case PackageDef(_, Seq(t @ TypeDef(_,_))) => checkDocString(t.getAttachment(Comment), "/** Trait docstring */")
106107
}
107108
}
108109

@@ -118,8 +119,8 @@ class DottyDocParsingTests extends DottyTest {
118119

119120
checkFrontend(source) {
120121
case PackageDef(_, Seq(t1 @ TypeDef(_,_), t2 @ TypeDef(_,_))) => {
121-
checkDocString(t1.rawComment, "/** Trait1 docstring */")
122-
checkDocString(t2.rawComment, "/** Trait2 docstring */")
122+
checkDocString(t1.getAttachment(Comment), "/** Trait1 docstring */")
123+
checkDocString(t2.getAttachment(Comment), "/** Trait2 docstring */")
123124
}
124125
}
125126
}
@@ -144,10 +145,10 @@ class DottyDocParsingTests extends DottyTest {
144145

145146
checkFrontend(source) {
146147
case PackageDef(_, Seq(t1 @ TypeDef(_,_), c2 @ TypeDef(_,_), cc3 @ TypeDef(_,_), _, ac4 @ TypeDef(_,_))) => {
147-
checkDocString(t1.rawComment, "/** Trait1 docstring */")
148-
checkDocString(c2.rawComment, "/** Class2 docstring */")
149-
checkDocString(cc3.rawComment, "/** CaseClass3 docstring */")
150-
checkDocString(ac4.rawComment, "/** AbstractClass4 docstring */")
148+
checkDocString(t1.getAttachment(Comment), "/** Trait1 docstring */")
149+
checkDocString(c2.getAttachment(Comment), "/** Class2 docstring */")
150+
checkDocString(cc3.getAttachment(Comment), "/** CaseClass3 docstring */")
151+
checkDocString(ac4.getAttachment(Comment), "/** AbstractClass4 docstring */")
151152
}
152153
}
153154
}
@@ -164,9 +165,9 @@ class DottyDocParsingTests extends DottyTest {
164165

165166
checkFrontend(source) {
166167
case PackageDef(_, Seq(outer @ TypeDef(_, tpl @ Template(_,_,_,_)))) => {
167-
checkDocString(outer.rawComment, "/** Outer docstring */")
168+
checkDocString(outer.getAttachment(Comment), "/** Outer docstring */")
168169
tpl.body match {
169-
case (inner @ TypeDef(_,_)) :: _ => checkDocString(inner.rawComment, "/** Inner docstring */")
170+
case (inner @ TypeDef(_,_)) :: _ => checkDocString(inner.getAttachment(Comment), "/** Inner docstring */")
170171
case _ => assert(false, "Couldn't find inner class")
171172
}
172173
}
@@ -188,10 +189,10 @@ class DottyDocParsingTests extends DottyTest {
188189

189190
checkFrontend(source) {
190191
case PackageDef(_, Seq(o1 @ TypeDef(_, tpl @ Template(_,_,_,_)), o2 @ TypeDef(_,_))) => {
191-
checkDocString(o1.rawComment, "/** Outer1 docstring */")
192-
checkDocString(o2.rawComment, "/** Outer2 docstring */")
192+
checkDocString(o1.getAttachment(Comment), "/** Outer1 docstring */")
193+
checkDocString(o2.getAttachment(Comment), "/** Outer2 docstring */")
193194
tpl.body match {
194-
case (inner @ TypeDef(_,_)) :: _ => checkDocString(inner.rawComment, "/** Inner docstring */")
195+
case (inner @ TypeDef(_,_)) :: _ => checkDocString(inner.getAttachment(Comment), "/** Inner docstring */")
195196
case _ => assert(false, "Couldn't find inner class")
196197
}
197198
}
@@ -213,9 +214,9 @@ class DottyDocParsingTests extends DottyTest {
213214
checkFrontend(source) {
214215
case p @ PackageDef(_, Seq(o1: MemberDef[Untyped], o2: MemberDef[Untyped])) => {
215216
assertEquals(o1.name.toString, "Object1")
216-
checkDocString(o1.rawComment, "/** Object1 docstring */")
217+
checkDocString(o1.getAttachment(Comment), "/** Object1 docstring */")
217218
assertEquals(o2.name.toString, "Object2")
218-
checkDocString(o2.rawComment, "/** Object2 docstring */")
219+
checkDocString(o2.getAttachment(Comment), "/** Object2 docstring */")
219220
}
220221
}
221222
}
@@ -240,12 +241,12 @@ class DottyDocParsingTests extends DottyTest {
240241
checkFrontend(source) {
241242
case p @ PackageDef(_, Seq(o1: ModuleDef, o2: ModuleDef)) => {
242243
assert(o1.name.toString == "Object1")
243-
checkDocString(o1.rawComment, "/** Object1 docstring */")
244+
checkDocString(o1.getAttachment(Comment), "/** Object1 docstring */")
244245
assert(o2.name.toString == "Object2")
245-
checkDocString(o2.rawComment, "/** Object2 docstring */")
246+
checkDocString(o2.getAttachment(Comment), "/** Object2 docstring */")
246247

247248
o2.impl.body match {
248-
case _ :: (inner @ TypeDef(_,_)) :: _ => checkDocString(inner.rawComment, "/** Inner docstring */")
249+
case _ :: (inner @ TypeDef(_,_)) :: _ => checkDocString(inner.getAttachment(Comment), "/** Inner docstring */")
249250
case _ => assert(false, "Couldn't find inner class")
250251
}
251252
}
@@ -274,14 +275,14 @@ class DottyDocParsingTests extends DottyTest {
274275
import dotty.tools.dotc.ast.untpd._
275276
checkFrontend(source) {
276277
case PackageDef(_, Seq(p: ModuleDef)) => {
277-
checkDocString(p.rawComment, "/** Package object docstring */")
278+
checkDocString(p.getAttachment(Comment), "/** Package object docstring */")
278279

279280
p.impl.body match {
280281
case (b: TypeDef) :: (t: TypeDef) :: (o: ModuleDef) :: Nil => {
281-
checkDocString(b.rawComment, "/** Boo docstring */")
282-
checkDocString(t.rawComment, "/** Trait docstring */")
283-
checkDocString(o.rawComment, "/** InnerObject docstring */")
284-
checkDocString(o.impl.body.head.asInstanceOf[TypeDef].rawComment, "/** InnerClass docstring */")
282+
checkDocString(b.getAttachment(Comment), "/** Boo docstring */")
283+
checkDocString(t.getAttachment(Comment), "/** Trait docstring */")
284+
checkDocString(o.getAttachment(Comment), "/** InnerObject docstring */")
285+
checkDocString(o.impl.body.head.asInstanceOf[TypeDef].getAttachment(Comment), "/** InnerClass docstring */")
285286
}
286287
case _ => assert(false, "Incorrect structure inside package object")
287288
}
@@ -301,7 +302,7 @@ class DottyDocParsingTests extends DottyTest {
301302
import dotty.tools.dotc.ast.untpd._
302303
checkFrontend(source) {
303304
case PackageDef(_, Seq(c: TypeDef)) =>
304-
checkDocString(c.rawComment, "/** Real comment */")
305+
checkDocString(c.getAttachment(Comment), "/** Real comment */")
305306
}
306307
}
307308

@@ -320,7 +321,7 @@ class DottyDocParsingTests extends DottyTest {
320321
import dotty.tools.dotc.ast.untpd._
321322
checkFrontend(source) {
322323
case PackageDef(_, Seq(c: TypeDef)) =>
323-
checkDocString(c.rawComment, "/** Real comment */")
324+
checkDocString(c.getAttachment(Comment), "/** Real comment */")
324325
}
325326
}
326327

@@ -346,9 +347,9 @@ class DottyDocParsingTests extends DottyTest {
346347
case PackageDef(_, Seq(o: ModuleDef)) => {
347348
o.impl.body match {
348349
case (v1: MemberDef) :: (v2: MemberDef) :: (v3: MemberDef) :: Nil => {
349-
checkDocString(v1.rawComment, "/** val1 */")
350-
checkDocString(v2.rawComment, "/** val2 */")
351-
checkDocString(v3.rawComment, "/** val3 */")
350+
checkDocString(v1.getAttachment(Comment), "/** val1 */")
351+
checkDocString(v2.getAttachment(Comment), "/** val2 */")
352+
checkDocString(v3.getAttachment(Comment), "/** val3 */")
352353
}
353354
case _ => assert(false, "Incorrect structure inside object")
354355
}
@@ -378,9 +379,9 @@ class DottyDocParsingTests extends DottyTest {
378379
case PackageDef(_, Seq(o: ModuleDef)) => {
379380
o.impl.body match {
380381
case (v1: MemberDef) :: (v2: MemberDef) :: (v3: MemberDef) :: Nil => {
381-
checkDocString(v1.rawComment, "/** var1 */")
382-
checkDocString(v2.rawComment, "/** var2 */")
383-
checkDocString(v3.rawComment, "/** var3 */")
382+
checkDocString(v1.getAttachment(Comment), "/** var1 */")
383+
checkDocString(v2.getAttachment(Comment), "/** var2 */")
384+
checkDocString(v3.getAttachment(Comment), "/** var3 */")
384385
}
385386
case _ => assert(false, "Incorrect structure inside object")
386387
}
@@ -410,9 +411,9 @@ class DottyDocParsingTests extends DottyTest {
410411
case PackageDef(_, Seq(o: ModuleDef)) => {
411412
o.impl.body match {
412413
case (v1: MemberDef) :: (v2: MemberDef) :: (v3: MemberDef) :: Nil => {
413-
checkDocString(v1.rawComment, "/** def1 */")
414-
checkDocString(v2.rawComment, "/** def2 */")
415-
checkDocString(v3.rawComment, "/** def3 */")
414+
checkDocString(v1.getAttachment(Comment), "/** def1 */")
415+
checkDocString(v2.getAttachment(Comment), "/** def2 */")
416+
checkDocString(v3.getAttachment(Comment), "/** def3 */")
416417
}
417418
case _ => assert(false, "Incorrect structure inside object")
418419
}
@@ -442,9 +443,9 @@ class DottyDocParsingTests extends DottyTest {
442443
case PackageDef(_, Seq(o: ModuleDef)) => {
443444
o.impl.body match {
444445
case (v1: MemberDef) :: (v2: MemberDef) :: (v3: MemberDef) :: Nil => {
445-
checkDocString(v1.rawComment, "/** type1 */")
446-
checkDocString(v2.rawComment, "/** type2 */")
447-
checkDocString(v3.rawComment, "/** type3 */")
446+
checkDocString(v1.getAttachment(Comment), "/** type1 */")
447+
checkDocString(v2.getAttachment(Comment), "/** type2 */")
448+
checkDocString(v3.getAttachment(Comment), "/** type3 */")
448449
}
449450
case _ => assert(false, "Incorrect structure inside object")
450451
}

0 commit comments

Comments
 (0)