Skip to content

Commit 0426fe7

Browse files
authored
Merge pull request #1502 from felixmulder/topic/dottydoc-usecases-param
[doc] Usecases with docbase as param
2 parents 10ff949 + 9bcf282 commit 0426fe7

28 files changed

+1037
-613
lines changed

dottydoc/src/dotty/tools/dottydoc/DottyDoc.scala

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package dotty.tools
22
package dottydoc
33

4+
import dotty.tools.dottydoc.util.syntax._
45
import core._
56
import core.transform._
67
import dotc.config.CompilerCommand
78
import dotc.config.Printers.dottydoc
89
import dotc.core.Contexts._
10+
import dotc.core.Comments.ContextDoc
911
import dotc.core.Phases.Phase
1012
import dotc.typer.FrontEnd
1113
import dotc.{ CompilationUnit, Compiler, Driver, Run }
@@ -31,7 +33,9 @@ class DocCompiler extends Compiler {
3133
List(new DocFrontEnd),
3234
List(new DocImplicitsPhase),
3335
List(new DocASTPhase),
34-
List(DocMiniTransformations(new LinkReturnTypes,
36+
List(DocMiniTransformations(new UsecasePhase,
37+
new DocstringPhase,
38+
new LinkReturnTypes,
3539
new LinkParamListTypes,
3640
new LinkImplicitlyAddedTypes,
3741
new LinkSuperTypes,
@@ -54,6 +58,7 @@ abstract class DocDriver extends Driver {
5458

5559
ctx.setSettings(summary.sstate)
5660
ctx.setSetting(ctx.settings.YkeepComments, true)
61+
ctx.setProperty(ContextDoc, new ContextDottydoc)
5762

5863
val fileNames = CompilerCommand.checkUsage(summary, sourcesRequired)(ctx)
5964
(fileNames, ctx)
@@ -65,7 +70,7 @@ abstract class DocDriver extends Driver {
6570
val (fileNames, ctx) = setup(args, initCtx.fresh)
6671
doCompile(newCompiler(ctx), fileNames)(ctx)
6772

68-
ctx.docbase.packages[Package]
73+
ctx.docbase.packages
6974
}
7075

7176
def compiledDocsJava(args: Array[String]): JMap[String, Package] =
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package dotty.tools
2+
package dottydoc
3+
package core
4+
5+
import dotc.core.Symbols.Symbol
6+
import dotc.core.Comments.ContextDocstrings
7+
import model.Package
8+
9+
class ContextDottydoc extends ContextDocstrings {
10+
import scala.collection.mutable
11+
12+
private[this] val _packages: mutable.Map[String, Package] = mutable.Map.empty
13+
def packages: Map[String, Package] = _packages.toMap
14+
def packagesMutable: mutable.Map[String, Package] = _packages
15+
16+
/** Should perhaps factorize this into caches that get flushed */
17+
private var _defs: Map[Symbol, Set[Symbol]] = Map.empty
18+
def defs(sym: Symbol): Set[Symbol] = _defs.get(sym).getOrElse(Set.empty)
19+
20+
def addDef(s: Symbol, d: Symbol): Unit = _defs = (_defs + {
21+
s -> _defs.get(s).map(xs => xs + d).getOrElse(Set(d))
22+
})
23+
}

dottydoc/src/dotty/tools/dottydoc/core/DocASTPhase.scala

Lines changed: 28 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -7,36 +7,25 @@ import dotc.ast.Trees._
77
import dotc.CompilationUnit
88
import dotc.config.Printers.dottydoc
99
import dotc.core.Contexts.Context
10+
import dotc.core.Comments.ContextDocstrings
1011
import dotc.core.Phases.Phase
1112
import dotc.core.Symbols.{ Symbol, NoSymbol }
1213

1314
class DocASTPhase extends Phase {
1415
import model._
1516
import model.factories._
1617
import model.internal._
17-
import model.parsers.WikiParser
1818
import model.comment.Comment
1919
import dotty.tools.dotc.core.Flags
2020
import dotty.tools.dotc.ast.tpd._
21+
import dotty.tools.dottydoc.util.syntax._
2122
import util.traversing._
2223
import util.internal.setters._
2324

2425
def phaseName = "docphase"
2526

26-
private[this] val commentParser = new WikiParser
27-
28-
/** Saves the commentParser function for later evaluation, for when the AST has been filled */
29-
def track(symbol: Symbol, ctx: Context, parent: Symbol = NoSymbol)(op: => Entity) = {
30-
val entity = op
31-
32-
if (entity != NonEntity)
33-
commentParser += (entity, symbol, parent, ctx)
34-
35-
entity
36-
}
37-
3827
/** Build documentation hierarchy from existing tree */
39-
def collect(tree: Tree, prev: List[String] = Nil)(implicit ctx: Context): Entity = track(tree.symbol, ctx) {
28+
def collect(tree: Tree, prev: List[String] = Nil)(implicit ctx: Context): Entity = {
4029
val implicitConversions = ctx.docbase.defs(tree.symbol)
4130

4231
def collectList(xs: List[Tree], ps: List[String]): List[Entity] =
@@ -58,28 +47,26 @@ class DocASTPhase extends Phase {
5847
val defs = sym.info.bounds.hi.membersBasedOnFlags(Flags.Method, Flags.Synthetic | Flags.Private)
5948
.filterNot(_.symbol.owner.name.show == "Any")
6049
.map { meth =>
61-
track(meth.symbol, ctx, tree.symbol) {
62-
DefImpl(
63-
meth.symbol.name.show,
64-
Nil,
65-
path(meth.symbol),
66-
returnType(meth.info),
67-
typeParams(meth.symbol),
68-
paramLists(meth.info),
69-
implicitlyAddedFrom = Some(returnType(meth.symbol.owner.info))
70-
)
71-
}
50+
DefImpl(
51+
meth.symbol,
52+
meth.symbol.name.show,
53+
Nil,
54+
path(meth.symbol),
55+
returnType(meth.info),
56+
typeParams(meth.symbol),
57+
paramLists(meth.info),
58+
implicitlyAddedFrom = Some(returnType(meth.symbol.owner.info))
59+
)
7260
}.toList
7361

7462
val vals = sym.info.fields.filterNot(_.symbol.is(Flags.Private | Flags.Synthetic)).map { value =>
75-
track(value.symbol, ctx, tree.symbol) {
76-
ValImpl(
77-
value.symbol.name.show,
78-
Nil, path(value.symbol),
79-
returnType(value.info),
80-
implicitlyAddedFrom = Some(returnType(value.symbol.owner.info))
81-
)
82-
}
63+
ValImpl(
64+
value.symbol,
65+
value.symbol.name.show,
66+
Nil, path(value.symbol),
67+
returnType(value.info),
68+
implicitlyAddedFrom = Some(returnType(value.symbol.owner.info))
69+
)
8370
}
8471

8572
defs ++ vals
@@ -90,38 +77,38 @@ class DocASTPhase extends Phase {
9077
/** package */
9178
case pd @ PackageDef(pid, st) =>
9279
val newPath = prev :+ pid.name.toString
93-
addEntity(PackageImpl(newPath.mkString("."), collectEntityMembers(st, newPath), newPath))
80+
addEntity(PackageImpl(pd.symbol, newPath.mkString("."), collectEntityMembers(st, newPath), newPath))
9481

9582
/** trait */
9683
case t @ TypeDef(n, rhs) if t.symbol.is(Flags.Trait) =>
9784
val name = n.decode.toString
9885
val newPath = prev :+ name
9986
//TODO: should not `collectMember` from `rhs` - instead: get from symbol, will get inherited members as well
100-
TraitImpl(name, collectMembers(rhs), flags(t), newPath, typeParams(t.symbol), traitParameters(t.symbol), superTypes(t))
87+
TraitImpl(t.symbol, name, collectMembers(rhs), flags(t), newPath, typeParams(t.symbol), traitParameters(t.symbol), superTypes(t))
10188

10289
/** objects, on the format "Object$" so drop the last letter */
10390
case o @ TypeDef(n, rhs) if o.symbol.is(Flags.Module) =>
10491
val name = n.decode.toString.dropRight(1)
10592
//TODO: should not `collectMember` from `rhs` - instead: get from symbol, will get inherited members as well
106-
ObjectImpl(name, collectMembers(rhs, prev :+ name), flags(o), prev :+ (name + "$"), superTypes(o))
93+
ObjectImpl(o.symbol, name, collectMembers(rhs, prev :+ name), flags(o), prev :+ (name + "$"), superTypes(o))
10794

10895
/** class / case class */
10996
case c @ TypeDef(n, rhs) if c.symbol.isClass =>
11097
val name = n.decode.toString
11198
val newPath = prev :+ name
11299
//TODO: should not `collectMember` from `rhs` - instead: get from symbol, will get inherited members as well
113-
(name, collectMembers(rhs), flags(c), newPath, typeParams(c.symbol), constructors(c.symbol), superTypes(c), None) match {
100+
(c.symbol, name, collectMembers(rhs), flags(c), newPath, typeParams(c.symbol), constructors(c.symbol), superTypes(c), None) match {
114101
case x if c.symbol.is(Flags.CaseClass) => CaseClassImpl.tupled(x)
115102
case x => ClassImpl.tupled(x)
116103
}
117104

118105
/** def */
119106
case d: DefDef =>
120-
DefImpl(d.name.decode.toString, flags(d), path(d.symbol), returnType(d.tpt.tpe), typeParams(d.symbol), paramLists(d.symbol.info))
107+
DefImpl(d.symbol, d.name.decode.toString, flags(d), path(d.symbol), returnType(d.tpt.tpe), typeParams(d.symbol), paramLists(d.symbol.info))
121108

122109
/** val */
123110
case v: ValDef if !v.symbol.is(Flags.ModuleVal) =>
124-
ValImpl(v.name.decode.toString, flags(v), path(v.symbol), returnType(v.tpt.tpe))
111+
ValImpl(v.symbol, v.name.decode.toString, flags(v), path(v.symbol), returnType(v.tpt.tpe))
125112

126113
case x => {
127114
//dottydoc.println(s"Found unwanted entity: $x (${x.pos},\n${x.show}")
@@ -175,15 +162,8 @@ class DocASTPhase extends Phase {
175162
child <- parent.children
176163
} setParent(child, to = parent)
177164

178-
// (3) Create documentation template from docstrings, with internal links
179-
println("Generating documentation, this might take a while...")
180-
commentParser.parse(packages)
181-
182-
// (4) Clear caches
183-
commentParser.clear()
184-
185-
// (5) Update Doc AST in ctx.base
186-
for (kv <- packages) ctx.docbase.packages += kv
165+
// (3) Update Doc AST in ctx.base
166+
for (kv <- packages) ctx.docbase.packagesMutable += kv
187167

188168
// Return super's result
189169
compUnits

dottydoc/src/dotty/tools/dottydoc/core/DocImplicitsPhase.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package core
55
import dotty.tools.dotc.transform.TreeTransforms.{ MiniPhaseTransform, TransformerInfo }
66
import dotty.tools.dotc.core.Flags
77
import dotc.core.Contexts.Context
8+
import util.syntax._
89

910
class DocImplicitsPhase extends MiniPhaseTransform { thisTransformer =>
1011
import dotty.tools.dotc.ast.tpd._
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package dotty.tools
2+
package dottydoc
3+
package core
4+
5+
import dotc.core.Contexts.Context
6+
import transform.DocMiniPhase
7+
import model._
8+
import model.internal._
9+
import model.comment._
10+
import BodyParsers._
11+
import util.syntax._
12+
13+
class DocstringPhase extends DocMiniPhase with CommentParser with CommentCleaner {
14+
private def parsedComment[E <: Entity](ent: E)(implicit ctx: Context): Option[Comment] =
15+
ctx.docbase.docstring(ent.symbol).map { cmt =>
16+
parse(ent, ctx.docbase.packages, clean(cmt.raw), cmt.raw, cmt.pos)
17+
.toComment(_.toHtml(ent))
18+
}
19+
20+
override def transformPackage(implicit ctx: Context) = { case ent: PackageImpl =>
21+
ent.copy(comment = parsedComment(ent))
22+
}
23+
24+
override def transformClass(implicit ctx: Context) = { case ent: ClassImpl =>
25+
ent.copy(comment = parsedComment(ent))
26+
}
27+
28+
override def transformCaseClass(implicit ctx: Context) = { case ent: CaseClassImpl =>
29+
ent.copy(comment = parsedComment(ent))
30+
}
31+
32+
override def transformTrait(implicit ctx: Context) = { case ent: TraitImpl =>
33+
ent.copy(comment = parsedComment(ent))
34+
}
35+
36+
override def transformObject(implicit ctx: Context) = { case ent: ObjectImpl =>
37+
ent.copy(comment = parsedComment(ent))
38+
}
39+
40+
override def transformDef(implicit ctx: Context) = { case ent: DefImpl =>
41+
ent.copy(comment = parsedComment(ent))
42+
}
43+
44+
override def transformVal(implicit ctx: Context) = { case ent: ValImpl =>
45+
ent.copy(comment = parsedComment(ent))
46+
}
47+
}

dottydoc/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ package core
44

55
import dotc.CompilationUnit
66
import dotc.core.Contexts.Context
7+
import dotc.core.Comments.ContextDocstrings
78
import dotc.core.Phases.Phase
89
import model._
910
import model.internal._
11+
import util.syntax._
1012

1113
object transform {
1214
/**
@@ -43,9 +45,9 @@ object transform {
4345
override def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] = {
4446
for {
4547
rootName <- rootPackages
46-
pack = ctx.docbase.packages[Package](rootName)
48+
pack = ctx.docbase.packages(rootName)
4749
transformed = performPackageTransform(pack)
48-
} yield ctx.docbase.packages(rootName) = transformed
50+
} yield ctx.docbase.packagesMutable(rootName) = transformed
4951
super.runOn(units)
5052
}
5153

@@ -77,19 +79,21 @@ object transform {
7779
def traverse(ent: Entity): Entity = ent match {
7880
case p: Package => transformEntity(p, _.packageTransformation) { p =>
7981
val newPackage = PackageImpl(
82+
p.symbol,
8083
p.name,
8184
p.members.map(traverse),
8285
p.path,
8386
p.comment
8487
)
8588

8689
// Update reference in context to newPackage
87-
ctx.docbase.packages[Package] += (newPackage.path.mkString(".") -> newPackage)
90+
ctx.docbase.packagesMutable += (newPackage.path.mkString(".") -> newPackage)
8891

8992
newPackage
9093
}
9194
case c: Class => transformEntity(c, _.classTransformation) { cls =>
9295
ClassImpl(
96+
cls.symbol,
9397
cls.name,
9498
cls.members.map(traverse),
9599
cls.modifiers,
@@ -102,6 +106,7 @@ object transform {
102106
}
103107
case cc: CaseClass => transformEntity(cc, _.caseClassTransformation) { cc =>
104108
CaseClassImpl(
109+
cc.symbol,
105110
cc.name,
106111
cc.members.map(traverse),
107112
cc.modifiers,
@@ -114,6 +119,7 @@ object transform {
114119
}
115120
case trt: Trait => transformEntity(trt, _.traitTransformation) { trt =>
116121
TraitImpl(
122+
trt.symbol,
117123
trt.name,
118124
trt.members.map(traverse),
119125
trt.modifiers,
@@ -126,6 +132,7 @@ object transform {
126132
}
127133
case obj: Object => transformEntity(obj, _.objectTransformation) { obj =>
128134
ObjectImpl(
135+
obj.symbol,
129136
obj.name,
130137
obj.members.map(traverse),
131138
obj.modifiers,
@@ -136,6 +143,7 @@ object transform {
136143
}
137144
case df: Def => transformEntity(df, _.defTransformation) { df =>
138145
DefImpl(
146+
df.symbol,
139147
df.name,
140148
df.modifiers,
141149
df.path,
@@ -148,6 +156,7 @@ object transform {
148156
}
149157
case vl: Val => transformEntity(vl, _.valTransformation) { vl =>
150158
ValImpl(
159+
vl.symbol,
151160
vl.name,
152161
vl.modifiers,
153162
vl.path,

0 commit comments

Comments
 (0)