Skip to content

Commit 0b69be6

Browse files
committed
Add phase to deal with constructors
1 parent d8c02ec commit 0b69be6

13 files changed

+318
-54
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class DocCompiler extends Compiler {
3535
new LinkParamListTypes,
3636
new LinkImplicitlyAddedTypes,
3737
new LinkSuperTypes,
38+
new AlternateConstructors,
3839
new SortMembers))
3940
)
4041
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package dotty.tools
2+
package dottydoc
3+
package core
4+
5+
import dotc.core.Contexts.Context
6+
7+
import transform.DocMiniPhase
8+
import model._
9+
import model.internal._
10+
11+
/** This DocMiniPhase adds the alternate constructors, currently defined as
12+
* methods with the name `<init>`, to the Entity#constructors list
13+
*/
14+
class AlternateConstructors extends DocMiniPhase {
15+
def partitionMembers(ent: Entity with Constructors with Members): (List[List[ParamList]], List[Entity]) = {
16+
val (constructors, members) = ent.members.partition(x => x.name == "<init>")
17+
18+
val paramLists: List[List[ParamList]] = constructors.collect {
19+
case df: Def => df.paramLists
20+
}
21+
22+
(ent.constructors ++ paramLists, members)
23+
}
24+
25+
override def transformClass(implicit ctx: Context) = { case cls: ClassImpl =>
26+
val (constructors, members) = partitionMembers(cls)
27+
cls.copy(members = members, constructors = constructors)
28+
}
29+
30+
override def transformCaseClass(implicit ctx: Context) = { case cc: CaseClassImpl =>
31+
val (constructors, members) = partitionMembers(cc)
32+
cc.copy(members = members, constructors = constructors)
33+
}
34+
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ class DocASTPhase extends Phase {
9797
val name = n.decode.toString
9898
val newPath = prev :+ name
9999
//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), superTypes(t))
100+
TraitImpl(name, collectMembers(rhs), flags(t), newPath, typeParams(t.symbol), traitParameters(t.symbol), superTypes(t))
101101

102102
/** objects, on the format "Object$" so drop the last letter */
103103
case o @ TypeDef(n, rhs) if o.symbol.is(Flags.Module) =>
@@ -110,7 +110,7 @@ class DocASTPhase extends Phase {
110110
val name = n.decode.toString
111111
val newPath = prev :+ name
112112
//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), superTypes(c), None) match {
113+
(name, collectMembers(rhs), flags(c), newPath, typeParams(c.symbol), constructors(c.symbol), superTypes(c), None) match {
114114
case x if c.symbol.is(Flags.CaseClass) => CaseClassImpl.tupled(x)
115115
case x => ClassImpl.tupled(x)
116116
}

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

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -88,15 +88,16 @@ object transform {
8888

8989
newPackage
9090
}
91-
case c: Class => transformEntity(c, _.classTransformation) { newClass =>
91+
case c: Class => transformEntity(c, _.classTransformation) { cls =>
9292
ClassImpl(
93-
newClass.name,
94-
newClass.members.map(traverse),
95-
newClass.modifiers,
96-
newClass.path,
97-
newClass.typeParams,
98-
newClass.superTypes,
99-
newClass.comment
93+
cls.name,
94+
cls.members.map(traverse),
95+
cls.modifiers,
96+
cls.path,
97+
cls.typeParams,
98+
cls.constructors,
99+
cls.superTypes,
100+
cls.comment
100101
)
101102
}
102103
case cc: CaseClass => transformEntity(cc, _.caseClassTransformation) { cc =>
@@ -106,6 +107,7 @@ object transform {
106107
cc.modifiers,
107108
cc.path,
108109
cc.typeParams,
110+
cc.constructors,
109111
cc.superTypes,
110112
cc.comment
111113
)
@@ -117,6 +119,7 @@ object transform {
117119
trt.modifiers,
118120
trt.path,
119121
trt.typeParams,
122+
trt.traitParams,
120123
trt.superTypes,
121124
trt.comment
122125
)

dottydoc/src/dotty/tools/dottydoc/model/entities.scala

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ trait ParamList {
5757
def isImplicit: Boolean
5858
}
5959

60+
trait Constructors {
61+
def constructors: List[List[ParamList]]
62+
}
63+
6064
trait ImplicitlyAddedEntity extends Entity {
6165
def implicitlyAddedFrom: Option[Reference]
6266
}
@@ -67,15 +71,16 @@ trait Package extends Entity with Members {
6771
def children: List[Entity with Members]
6872
}
6973

70-
trait Class extends Entity with Modifiers with TypeParams with SuperTypes with Members {
74+
trait Class extends Entity with Modifiers with TypeParams with Constructors with SuperTypes with Members {
7175
val kind = "class"
7276
}
7377

74-
trait CaseClass extends Entity with Modifiers with TypeParams with SuperTypes with Members {
78+
trait CaseClass extends Entity with Modifiers with TypeParams with Constructors with SuperTypes with Members {
7579
override val kind = "case class"
7680
}
7781

7882
trait Trait extends Entity with Modifiers with TypeParams with SuperTypes with Members {
83+
def traitParams: List[ParamList]
7984
override val kind = "trait"
8085
}
8186

dottydoc/src/dotty/tools/dottydoc/model/factories.scala

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,17 @@ import references._
66
import dotty.tools.dotc
77
import dotc.core.Types._
88
import dotc.core.TypeApplications._
9-
import dotc.core.Flags
109
import dotc.core.Contexts.Context
11-
import dotc.core.Symbols.Symbol
10+
import dotc.core.Symbols.{ Symbol, ClassSymbol }
1211
import dotty.tools.dotc.core.SymDenotations._
1312
import dotty.tools.dotc.core.Names.TypeName
14-
import dotc.core.{ Flags => DottyFlags }
1513
import dotc.ast.Trees._
1614

1715

1816
object factories {
1917
import dotty.tools.dotc.ast.tpd._
2018
import dotty.tools.dottydoc.model.internal.ParamListImpl
21-
import DottyFlags._
19+
import dotc.core.Flags._
2220

2321
type TypeTree = dotty.tools.dotc.ast.Trees.Tree[Type]
2422

@@ -118,11 +116,11 @@ object factories {
118116
pt.paramNames.map(_.show.split("\\$").last)
119117
case ClassInfo(_, _, _, decls, _) =>
120118
decls.iterator
121-
.filter(_.flags is Flags.TypeParam)
119+
.filter(_.flags is TypeParam)
122120
.map { tp =>
123121
val prefix =
124-
if (tp.flags is Flags.Covariant) "+"
125-
else if (tp.flags is Flags.Contravariant) "-"
122+
if (tp.flags is Covariant) "+"
123+
else if (tp.flags is Contravariant) "-"
126124
else ""
127125
prefix + tp.name.show.split("\\$").last
128126
}
@@ -131,6 +129,15 @@ object factories {
131129
Nil
132130
}
133131

132+
def constructors(sym: Symbol)(implicit ctx: Context): List[List[ParamList]] = sym match {
133+
case sym: ClassSymbol =>
134+
paramLists(sym.primaryConstructor.info) :: Nil
135+
case _ => Nil
136+
}
137+
138+
def traitParameters(sym: Symbol)(implicit ctx: Context): List[ParamList] =
139+
constructors(sym).head
140+
134141
def paramLists(tpe: Type)(implicit ctx: Context): List[ParamList] = tpe match {
135142
case pt: PolyType =>
136143
paramLists(pt.resultType)

dottydoc/src/dotty/tools/dottydoc/model/internal.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ object internal {
2626
modifiers: List[String],
2727
path: List[String],
2828
typeParams: List[String] = Nil,
29+
constructors: List[List[ParamList]] = Nil,
2930
superTypes: List[MaterializableLink] = Nil,
3031
var comment: Option[Comment] = None
3132
) extends Class with Impl
@@ -36,6 +37,7 @@ object internal {
3637
modifiers: List[String],
3738
path: List[String],
3839
typeParams: List[String] = Nil,
40+
constructors: List[List[ParamList]] = Nil,
3941
superTypes: List[MaterializableLink] = Nil,
4042
var comment: Option[Comment] = None
4143
) extends CaseClass with Impl
@@ -46,6 +48,7 @@ object internal {
4648
modifiers: List[String],
4749
path: List[String],
4850
typeParams: List[String] = Nil,
51+
traitParams: List[ParamList] = Nil,
4952
superTypes: List[MaterializableLink] = Nil,
5053
var comment: Option[Comment] = None
5154
) extends Trait with Impl

dottydoc/src/dotty/tools/dottydoc/model/json.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ object json {
3434
def json: String = {
3535
val (secondTitle, secondValue, kind) = link match {
3636
case ul: UnsetLink => ("query".json, ul.query.json, "UnsetLink".json)
37-
case ml: MaterializedLink => ("target", ml.target.json, "MaterializedLink".json)
37+
case ml: MaterializedLink => ("target".json, ml.target.json, "MaterializedLink".json)
3838
case nl: NoLink => ("target".json, nl.target.json, "NoLink".json)
3939
}
4040
s"""{"title":${link.title.json},$secondTitle:${secondValue},"kind":$kind}"""
@@ -70,11 +70,11 @@ object json {
7070
case ent: Package =>
7171
s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"package"}"""
7272
case ent: Class =>
73-
s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"class"}"""
73+
s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"constructors":${ent.constructors.map(xs => xs.map(_.json).mkString("[",",","]")).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"class"}"""
7474
case ent: CaseClass =>
75-
s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"case class"}"""
75+
s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"constructors":${ent.constructors.map(xs => xs.map(_.json).mkString("[",",","]")).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"case class"}"""
7676
case ent: Trait =>
77-
s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"trait"}"""
77+
s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"typeParams":${ent.typeParams.map(_.json).mkString("[",",","]")},"traitParams":${ent.traitParams.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"trait"}"""
7878
case ent: Object =>
7979
s"""{"name":${ent.name.json},"members":${ent.members.map(_.json).mkString("[",",","]")},"modifiers":${ent.modifiers.map(_.json).mkString("[",",","]")},"path":${ent.path.map(_.json).mkString("[",",","]")},"superTypes":${ent.superTypes.map(_.json).mkString("[",",","]")},${ent.comment.map(_.json).fold("")(cmt => s""""comment":$cmt,""")}"kind":"object"}"""
8080
case ent: Def =>

dottydoc/test/BaseTest.scala

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import dotc.util.SourceFile
77
import dotc.core.Phases.Phase
88
import dotc.typer.FrontEnd
99
import dottydoc.core.DocASTPhase
10+
import model.Package
1011

1112
trait DottyTest {
1213
dotty.tools.dotc.parsing.Scanners // initialize keywords
@@ -21,34 +22,33 @@ trait DottyTest {
2122
ctx
2223
}
2324

24-
private def compilerWithChecker(assertion: DocASTPhase => Unit) = new DocCompiler {
25-
private[this] val docPhase = new DocASTPhase
26-
27-
override def phases =
28-
List(new FrontEnd) ::
29-
List(docPhase) ::
25+
private def compilerWithChecker(assertion: Map[String, Package] => Unit) = new DocCompiler {
26+
private[this] val assertionPhase: List[List[Phase]] =
3027
List(new Phase {
3128
def phaseName = "assertionPhase"
32-
override def run(implicit ctx: Context): Unit = assertion(docPhase)
33-
}) ::
34-
Nil
29+
override def run(implicit ctx: Context): Unit =
30+
assertion(ctx.docbase.packages[Package].toMap)
31+
}) :: Nil
32+
33+
override def phases =
34+
super.phases ++ assertionPhase
3535
}
3636

37-
def checkSource(source: String)(assertion: DocASTPhase => Unit): Unit = {
37+
def checkSource(source: String)(assertion: Map[String, Package] => Unit): Unit = {
3838
val c = compilerWithChecker(assertion)
3939
c.rootContext(ctx)
4040
val run = c.newRun
4141
run.compile(source)
4242
}
4343

44-
def checkFiles(sources: List[String])(assertion: DocASTPhase => Unit): Unit = {
44+
def checkFiles(sources: List[String])(assertion: Map[String, Package] => Unit): Unit = {
4545
val c = compilerWithChecker(assertion)
4646
c.rootContext(ctx)
4747
val run = c.newRun
4848
run.compile(sources)
4949
}
5050

51-
def checkSources(sourceFiles: List[SourceFile])(assertion: DocASTPhase => Unit): Unit = {
51+
def checkSources(sourceFiles: List[SourceFile])(assertion: Map[String, Package] => Unit): Unit = {
5252
val c = compilerWithChecker(assertion)
5353
c.rootContext(ctx)
5454
val run = c.newRun

0 commit comments

Comments
 (0)