Skip to content

Commit f7b6248

Browse files
committed
Add package object support
1 parent 4a9691e commit f7b6248

File tree

2 files changed

+99
-7
lines changed

2 files changed

+99
-7
lines changed

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1859,9 +1859,9 @@ object Parsers {
18591859
case CASECLASS =>
18601860
classDef(posMods(start, mods | Case), docstring)
18611861
case OBJECT =>
1862-
objectDef(posMods(start, mods | Module))
1862+
objectDef(posMods(start, mods | Module), docstring)
18631863
case CASEOBJECT =>
1864-
objectDef(posMods(start, mods | Case | Module))
1864+
objectDef(posMods(start, mods | Case | Module), docstring)
18651865
case _ =>
18661866
syntaxErrorOrIncomplete("expected start of definition")
18671867
EmptyTree
@@ -1900,13 +1900,13 @@ object Parsers {
19001900

19011901
/** ObjectDef ::= Id TemplateOpt
19021902
*/
1903-
def objectDef(mods: Modifiers): ModuleDef = {
1903+
def objectDef(mods: Modifiers, docstring: Option[String] = None): ModuleDef = {
19041904
val name = ident()
19051905
val template = templateOpt(emptyConstructor())
19061906

19071907
ModuleDef(name, template)
19081908
.withMods(mods)
1909-
.withComment(in.getDocString())
1909+
.withComment(docstring)
19101910
}
19111911

19121912
/* -------- TEMPLATES ------------------------------------------- */
@@ -2131,7 +2131,8 @@ object Parsers {
21312131
if (in.token == PACKAGE) {
21322132
in.nextToken()
21332133
if (in.token == OBJECT) {
2134-
ts += objectDef(atPos(start, in.skipToken()) { Modifiers(Package) })
2134+
val docstring = in.getDocString()
2135+
ts += objectDef(atPos(start, in.skipToken()) { Modifiers(Package) }, docstring)
21352136
if (in.token != EOF) {
21362137
acceptStatSep()
21372138
ts ++= topStatSeq()

test/test/DottyDocTests.scala

Lines changed: 93 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import dotty.tools.dotc.Compiler
44
import dotty.tools.dotc.core.Phases.Phase
55
import dotty.tools.dotc.typer.FrontEnd
66
import dotty.tools.dotc.core.Contexts.Context
7-
import dotty.tools.dotc.ast.tpd
87
import dotty.tools.dotc.ast.Trees._
98

109
/** All tests need to extend this trait and define `source` and `assertion`
@@ -62,7 +61,10 @@ object DottyDocTests extends DottyTest {
6261
MultipleTraitsWithoutPackage,
6362
MultipleMixedEntitiesWithPackage,
6463
NestedClass,
65-
NestedClassThenOuter
64+
NestedClassThenOuter,
65+
Objects,
66+
ObjectsNestedClass,
67+
PackageObject
6668
)
6769

6870
def main(args: Array[String]): Unit = {
@@ -231,3 +233,92 @@ case object NestedClassThenOuter extends DottyDocTest {
231233
}
232234
}
233235
}
236+
237+
case object Objects extends DottyDocTest {
238+
override val source =
239+
"""
240+
|package p
241+
|
242+
|/** Object1 docstring */
243+
|object Object1
244+
|
245+
|/** Object2 docstring */
246+
|object Object2
247+
""".stripMargin
248+
249+
override def assertion = {
250+
case p @ PackageDef(_, Seq(o1: MemberDef[Untyped], o2: MemberDef[Untyped])) =>
251+
assert(o1.name.toString == "Object1")
252+
checkDocString(o1.rawComment, "/** Object1 docstring */")
253+
assert(o2.name.toString == "Object2")
254+
checkDocString(o2.rawComment, "/** Object2 docstring */")
255+
}
256+
}
257+
258+
case object ObjectsNestedClass extends DottyDocTest {
259+
override val source =
260+
"""
261+
|package p
262+
|
263+
|/** Object1 docstring */
264+
|object Object1
265+
|
266+
|/** Object2 docstring */
267+
|object Object2 {
268+
| class A1
269+
| /** Inner docstring */
270+
| class Inner
271+
|}
272+
""".stripMargin
273+
274+
import dotty.tools.dotc.ast.untpd._
275+
override def assertion = {
276+
case p @ PackageDef(_, Seq(o1: ModuleDef, o2: ModuleDef)) =>
277+
assert(o1.name.toString == "Object1")
278+
checkDocString(o1.rawComment, "/** Object1 docstring */")
279+
assert(o2.name.toString == "Object2")
280+
checkDocString(o2.rawComment, "/** Object2 docstring */")
281+
282+
o2.impl.body match {
283+
case _ :: (inner @ TypeDef(_,_)) :: _ => checkDocString(inner.rawComment, "/** Inner docstring */")
284+
case _ => assert(false, "Couldn't find inner class")
285+
}
286+
}
287+
}
288+
289+
case object PackageObject extends DottyDocTest {
290+
override val source =
291+
"""
292+
|/** Package object docstring */
293+
|package object foo {
294+
| /** Boo docstring */
295+
| case class Boo()
296+
|
297+
| /** Trait docstring */
298+
| trait Trait
299+
|
300+
| /** InnerObject docstring */
301+
| object InnerObject {
302+
| /** InnerClass docstring */
303+
| class InnerClass
304+
| }
305+
|}
306+
""".stripMargin
307+
308+
import dotty.tools.dotc.ast.untpd._
309+
override def assertion = {
310+
case PackageDef(_, Seq(p: ModuleDef)) => {
311+
checkDocString(p.rawComment, "/** Package object docstring */")
312+
313+
p.impl.body match {
314+
case (b: TypeDef) :: (t: TypeDef) :: (o: ModuleDef) :: Nil => {
315+
checkDocString(b.rawComment, "/** Boo docstring */")
316+
checkDocString(t.rawComment, "/** Trait docstring */")
317+
checkDocString(o.rawComment, "/** InnerObject docstring */")
318+
checkDocString(o.impl.body.head.asInstanceOf[TypeDef].rawComment, "/** InnerClass docstring */")
319+
}
320+
case _ => assert(false, "Incorrect structure inside package object")
321+
}
322+
}
323+
}
324+
}

0 commit comments

Comments
 (0)