Skip to content

Commit 48d7a5d

Browse files
committed
Remove NonEntity in Dottydoc
This special entity was used to mean that an entity needs to be removed from the doc AST after the transformation. Instead, we refactor the DocMiniPhases to have them return a `List[Entity]` (rather than a single `Entity`, as before). It follows that removing an entity from the AST means returning an empty list after transformation. This change will be necessary to be able to support multiple `@usecase` sections in the documentation, because it means that the transformation has to introduce multiple `Entity`-es.
1 parent 8bacff5 commit 48d7a5d

20 files changed

+152
-225
lines changed

doc-tool/src/dotty/tools/dottydoc/core/AlternateConstructorsPhase.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ class AlternateConstructors extends DocMiniPhase {
2424

2525
override def transformClass(implicit ctx: Context) = { case cls: ClassImpl =>
2626
val (constructors, members) = partitionMembers(cls)
27-
cls.copy(members = members, constructors = constructors)
27+
cls.copy(members = members, constructors = constructors) :: Nil
2828
}
2929

3030
override def transformCaseClass(implicit ctx: Context) = { case cc: CaseClassImpl =>
3131
val (constructors, members) = partitionMembers(cc)
32-
cc.copy(members = members, constructors = constructors)
32+
cc.copy(members = members, constructors = constructors) :: Nil
3333
}
3434
}

doc-tool/src/dotty/tools/dottydoc/core/DocASTPhase.scala

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@ package core
55
/** Dotty and Dottydoc imports */
66
import dotc.ast.Trees._
77
import dotc.CompilationUnit
8-
import dotc.config.Printers.dottydoc
98
import dotc.core.Contexts.Context
10-
import dotc.core.Comments.ContextDocstrings
11-
import dotc.core.Types.{PolyType, NoType}
9+
import dotc.core.Types.PolyType
1210
import dotc.core.Phases.Phase
1311
import dotc.core.Symbols.{ Symbol, NoSymbol }
1412
import dotc.core.NameOps._
@@ -17,7 +15,6 @@ class DocASTPhase extends Phase {
1715
import model._
1816
import model.factories._
1917
import model.internal._
20-
import model.comment.Comment
2118
import dotty.tools.dotc.core.Flags
2219
import dotty.tools.dotc.ast.tpd._
2320
import dotty.tools.dottydoc.util.syntax._
@@ -27,20 +24,20 @@ class DocASTPhase extends Phase {
2724
def phaseName = "docASTPhase"
2825

2926
/** Build documentation hierarchy from existing tree */
30-
def collect(tree: Tree)(implicit ctx: Context): Entity = {
27+
def collect(tree: Tree)(implicit ctx: Context): List[Entity] = {
3128
val implicitConversions = ctx.docbase.defs(tree.symbol)
3229

3330
def collectList(xs: List[Tree]): List[Entity] =
34-
xs.map(collect).filter(_ != NonEntity)
31+
xs.flatMap(collect)
3532

3633
def collectEntityMembers(xs: List[Tree]) =
3734
collectList(xs).asInstanceOf[List[Entity with Members]]
3835

3936
def collectMembers(tree: Tree)(implicit ctx: Context): List[Entity] = {
40-
val defs = (tree match {
37+
val defs = tree match {
4138
case t: Template => collectList(t.body)
4239
case _ => Nil
43-
})
40+
}
4441

4542
defs ++ implicitConversions.flatMap(membersFromSymbol)
4643
}
@@ -83,55 +80,57 @@ class DocASTPhase extends Phase {
8380
}
8481

8582

86-
if (tree.symbol.is(Flags.Synthetic) && !tree.symbol.is(Flags.Module)) NonEntity
83+
if (tree.symbol.is(Flags.Synthetic) && !tree.symbol.is(Flags.Module)) Nil
8784
else tree match {
8885
/** package */
8986
case pd @ PackageDef(pid, st) =>
90-
addPackage(PackageImpl(pd.symbol, annotations(pd.symbol), pd.symbol.showFullName, collectEntityMembers(st), path(pd.symbol)))
87+
addPackage(PackageImpl(pd.symbol, annotations(pd.symbol), pd.symbol.showFullName, collectEntityMembers(st), path(pd.symbol))) :: Nil
9188

9289
/** type alias */
9390
case t: TypeDef if !t.isClassDef =>
9491
val sym = t.symbol
9592
if (sym.is(Flags.Synthetic | Flags.Param))
96-
NonEntity
93+
Nil
9794
else {
9895
val tparams = t.rhs.tpe match {
9996
case tp: PolyType => tp.paramNames.map(_.show)
10097
case _ => Nil
10198
}
102-
TypeAliasImpl(sym, annotations(sym), flags(t), t.name.show.split("\\$\\$").last, path(sym), alias(t.rhs.tpe), tparams)
99+
TypeAliasImpl(sym, annotations(sym), flags(t), t.name.show.split("\\$\\$").last, path(sym), alias(t.rhs.tpe), tparams) :: Nil
103100
}
104101

105102
/** trait */
106103
case t @ TypeDef(n, rhs) if t.symbol.is(Flags.Trait) =>
107104
//TODO: should not `collectMember` from `rhs` - instead: get from symbol, will get inherited members as well
108-
TraitImpl(t.symbol, annotations(t.symbol), n.show, collectMembers(rhs), flags(t), path(t.symbol), typeParams(t.symbol), traitParameters(t.symbol), superTypes(t))
105+
TraitImpl(t.symbol, annotations(t.symbol), n.show, collectMembers(rhs), flags(t), path(t.symbol), typeParams(t.symbol), traitParameters(t.symbol), superTypes(t)) :: Nil
109106

110107
/** objects, on the format "Object$" so drop the last letter */
111108
case o @ TypeDef(n, rhs) if o.symbol.is(Flags.Module) =>
112109
//TODO: should not `collectMember` from `rhs` - instead: get from symbol, will get inherited members as well
113-
ObjectImpl(o.symbol, annotations(o.symbol), o.name.stripModuleClassSuffix.show, collectMembers(rhs), flags(o), path(o.symbol), superTypes(o))
110+
ObjectImpl(o.symbol, annotations(o.symbol), o.name.stripModuleClassSuffix.show, collectMembers(rhs), flags(o), path(o.symbol), superTypes(o)) :: Nil
114111

115112
/** class / case class */
116113
case c @ TypeDef(n, rhs) if c.symbol.isClass =>
117114
//TODO: should not `collectMember` from `rhs` - instead: get from symbol, will get inherited members as well
118-
(c.symbol, annotations(c.symbol), n.show, collectMembers(rhs), flags(c), path(c.symbol), typeParams(c.symbol), constructors(c.symbol), superTypes(c), None, Nil, NonEntity) match {
119-
case x if c.symbol.is(Flags.CaseClass) => CaseClassImpl.tupled(x)
120-
case x => ClassImpl.tupled(x)
115+
val parameters = (c.symbol, annotations(c.symbol), n.show, collectMembers(rhs), flags(c), path(c.symbol), typeParams(c.symbol), constructors(c.symbol), superTypes(c), None, Nil, None)
116+
if (c.symbol.is(Flags.CaseClass)) {
117+
CaseClassImpl.tupled(parameters) :: Nil
118+
} else {
119+
ClassImpl.tupled(parameters) :: Nil
121120
}
122121

123122
/** def */
124123
case d: DefDef =>
125-
DefImpl(d.symbol, annotations(d.symbol), d.name.decode.toString, flags(d), path(d.symbol), returnType(d.tpt.tpe), typeParams(d.symbol), paramLists(d.symbol.info))
124+
DefImpl(d.symbol, annotations(d.symbol), d.name.decode.toString, flags(d), path(d.symbol), returnType(d.tpt.tpe), typeParams(d.symbol), paramLists(d.symbol.info)) :: Nil
126125

127126
/** val */
128127
case v: ValDef if !v.symbol.is(Flags.ModuleVal) =>
129128
val kind = if (v.symbol.is(Flags.Mutable)) "var" else "val"
130-
ValImpl(v.symbol, annotations(v.symbol), v.name.decode.toString, flags(v), path(v.symbol), returnType(v.tpt.tpe), kind)
129+
ValImpl(v.symbol, annotations(v.symbol), v.name.decode.toString, flags(v), path(v.symbol), returnType(v.tpt.tpe), kind) :: Nil
131130

132131
case x => {
133132
ctx.docbase.debug(s"Found unwanted entity: $x (${x.pos},\n${x.show}")
134-
NonEntity
133+
Nil
135134
}
136135
}
137136
}
@@ -158,7 +157,7 @@ class DocASTPhase extends Phase {
158157
if (old.annotations.isEmpty) old.annotations = newPkg.annotations
159158
mergeMembers(newPkg, old)
160159
if (old.superTypes.isEmpty) old.superTypes = newPkg.superTypes
161-
if (!old.comment.isDefined) old.comment = newPkg.comment
160+
if (old.comment.isEmpty) old.comment = newPkg.comment
162161
old
163162
}
164163

@@ -178,9 +177,9 @@ class DocASTPhase extends Phase {
178177
def createAndInsert(currentPkg: PackageImpl, path: List[String]): PackageImpl = {
179178
(path: @unchecked) match {
180179
case x :: Nil => {
181-
val existingPkg = currentPkg.members.collect {
180+
val existingPkg = currentPkg.members.collectFirst {
182181
case p: PackageImpl if p.name == newPkg.name => p
183-
}.headOption
182+
}
184183

185184
if (existingPkg.isDefined) mergedPackages(existingPkg.get, newPkg)
186185
else {
@@ -190,9 +189,9 @@ class DocASTPhase extends Phase {
190189
}
191190
case x :: xs => {
192191
val subPkg = s"${currentPkg.name}.$x"
193-
val existingPkg = currentPkg.members.collect {
192+
val existingPkg = currentPkg.members.collectFirst {
194193
case p: PackageImpl if p.name == subPkg => p
195-
}.headOption
194+
}
196195

197196
if (existingPkg.isDefined) createAndInsert(existingPkg.get, xs)
198197
else {

doc-tool/src/dotty/tools/dottydoc/core/DocstringPhase.scala

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import transform.DocMiniPhase
99
import model._
1010
import model.internal._
1111
import model.comment._
12-
import HtmlParsers._
1312
import util.syntax._
1413

1514
/** Phase to add docstrings to the Dottydoc AST */
@@ -42,34 +41,34 @@ class DocstringPhase extends DocMiniPhase with CommentParser with CommentCleaner
4241
}
4342

4443
override def transformPackage(implicit ctx: Context) = { case ent: PackageImpl =>
45-
ent.copy(comment = parsedComment(ent))
44+
ent.copy(comment = parsedComment(ent)) :: Nil
4645
}
4746

4847
override def transformClass(implicit ctx: Context) = { case ent: ClassImpl =>
49-
ent.copy(comment = parsedComment(ent))
48+
ent.copy(comment = parsedComment(ent)) :: Nil
5049
}
5150

5251
override def transformCaseClass(implicit ctx: Context) = { case ent: CaseClassImpl =>
53-
ent.copy(comment = parsedComment(ent))
52+
ent.copy(comment = parsedComment(ent)) :: Nil
5453
}
5554

5655
override def transformTrait(implicit ctx: Context) = { case ent: TraitImpl =>
57-
ent.copy(comment = parsedComment(ent))
56+
ent.copy(comment = parsedComment(ent)) :: Nil
5857
}
5958

6059
override def transformObject(implicit ctx: Context) = { case ent: ObjectImpl =>
61-
ent.copy(comment = parsedComment(ent))
60+
ent.copy(comment = parsedComment(ent)) :: Nil
6261
}
6362

6463
override def transformDef(implicit ctx: Context) = { case ent: DefImpl =>
65-
ent.copy(comment = parsedComment(ent))
64+
ent.copy(comment = parsedComment(ent)) :: Nil
6665
}
6766

6867
override def transformVal(implicit ctx: Context) = { case ent: ValImpl =>
69-
ent.copy(comment = parsedComment(ent))
68+
ent.copy(comment = parsedComment(ent)) :: Nil
7069
}
7170

7271
override def transformTypeAlias(implicit ctx: Context) = { case ent: TypeAliasImpl =>
73-
ent.copy(comment = parsedComment(ent))
72+
ent.copy(comment = parsedComment(ent)) :: Nil
7473
}
7574
}

doc-tool/src/dotty/tools/dottydoc/core/LinkCompanionsPhase.scala

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,44 +3,40 @@ package dottydoc
33
package core
44

55
import dotc.core.Contexts.Context
6-
import dotc.ast.tpd
76

87
import transform.DocMiniPhase
98
import model.internal._
109
import model._
11-
import model.factories._
12-
import dotty.tools.dotc.core.Symbols.Symbol
13-
import util.syntax._
1410

1511
class LinkCompanions extends DocMiniPhase {
1612
private def linkCompanions(ent: Entity)(implicit ctx: Context): ent.type = {
1713
ent.children.groupBy(_.name).foreach {
18-
case (_, List(x1: Companion, x2: Companion)) => {
14+
case (_, List(x1: Companion, x2: Companion)) =>
1915
x1.companionPath = x2.path
2016
x2.companionPath = x1.path
21-
}
17+
2218
case _ => ()
2319
}
2420
ent
2521
}
2622

2723
override def transformPackage(implicit ctx: Context) = { case ent: PackageImpl =>
28-
linkCompanions(ent)
24+
linkCompanions(ent) :: Nil
2925
}
3026

3127
override def transformClass(implicit ctx: Context) = { case ent: ClassImpl =>
32-
linkCompanions(ent)
28+
linkCompanions(ent) :: Nil
3329
}
3430

3531
override def transformCaseClass(implicit ctx: Context) = { case ent: CaseClassImpl =>
36-
linkCompanions(ent)
32+
linkCompanions(ent) :: Nil
3733
}
3834

3935
override def transformObject(implicit ctx: Context) = { case ent: ObjectImpl =>
40-
linkCompanions(ent)
36+
linkCompanions(ent) :: Nil
4137
}
4238

4339
override def transformTrait(implicit ctx: Context) = { case ent: TraitImpl =>
44-
linkCompanions(ent)
40+
linkCompanions(ent) :: Nil
4541
}
4642
}

doc-tool/src/dotty/tools/dottydoc/core/PackageObjectsPhase.scala

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,29 @@ package dotty.tools
22
package dottydoc
33
package core
44

5-
import dotty.tools.dotc.core.Symbols.Symbol
65
import dotc.core.Contexts.Context
7-
import dotc.ast.tpd
8-
96
import model._
107
import model.internal._
11-
import util.syntax._
128
import transform.DocMiniPhase
139

1410
class PackageObjectsPhase extends DocMiniPhase {
1511

1612
override def transformPackage(implicit ctx: Context) = { case pkg: PackageImpl =>
1713
pkg
1814
.members
19-
.collect { case o: Object if o.symbol.isPackageObject => o }
20-
.headOption
15+
.collectFirst { case o: Object if o.symbol.isPackageObject => o }
2116
.map { obj =>
2217
pkg.copy(
2318
members = obj.members ++ pkg.members,
2419
superTypes = obj.superTypes,
2520
comment = obj.comment
2621
)
2722
}
28-
.getOrElse(pkg)
23+
.getOrElse(pkg) :: Nil
2924
}
3025

3126
override def transformObject(implicit ctx: Context) = { case obj: Object =>
32-
if (obj.symbol.isPackageObject) NonEntity
33-
else obj
27+
if (obj.symbol.isPackageObject) Nil
28+
else obj :: Nil
3429
}
3530
}

doc-tool/src/dotty/tools/dottydoc/core/RemoveEmptyPackagesPhase.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import model._
99

1010
class RemoveEmptyPackages extends DocMiniPhase {
1111
override def transformPackage(implicit ctx: Context) = { case p: Package =>
12-
if (p.members.exists(_.kind != "package")) p
13-
else NonEntity
12+
if (p.members.exists(_.kind != "package")) p :: Nil
13+
else Nil
1414
}
1515
}

doc-tool/src/dotty/tools/dottydoc/core/SortMembersPhase.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,22 +34,22 @@ class SortMembers extends DocMiniPhase {
3434
}
3535

3636
override def transformPackage(implicit ctx: Context) = { case p: PackageImpl =>
37-
p.copy(members = sort(p.members))
37+
p.copy(members = sort(p.members)) :: Nil
3838
}
3939

4040
override def transformClass(implicit ctx: Context) = { case c: ClassImpl =>
41-
c.copy(members = sort(c.members))
41+
c.copy(members = sort(c.members)) :: Nil
4242
}
4343

4444
override def transformCaseClass(implicit ctx: Context) = { case cc: CaseClassImpl =>
45-
cc.copy(members = sort(cc.members))
45+
cc.copy(members = sort(cc.members)) :: Nil
4646
}
4747

4848
override def transformTrait(implicit ctx: Context) = { case t: TraitImpl =>
49-
t.copy(members = sort(t.members))
49+
t.copy(members = sort(t.members)) :: Nil
5050
}
5151

5252
override def transformObject(implicit ctx: Context) = { case o: ObjectImpl =>
53-
o.copy(members = sort(o.members))
53+
o.copy(members = sort(o.members)) :: Nil
5454
}
5555
}

0 commit comments

Comments
 (0)