Skip to content

Commit 06ea188

Browse files
committed
Packages are are now represenet as Members
Top level package now has all features as any other one.
1 parent f6b5c2d commit 06ea188

12 files changed

+88
-174
lines changed

scala3doc/src/dotty/dokka/ScalaModuleCreator.scala

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import org.jetbrains.dokka.model.DModule
77
import org.jetbrains.dokka.transformers.sources.SourceToDocumentableTranslator
88

99
import dotty.dokka.tasty.DokkaTastyInspector
10-
import org.jetbrains.dokka.pages._
10+
import org.jetbrains.dokka.pages.{Kind => _, _}
1111
import dotty.dokka.model.api._
1212
import org.jetbrains.dokka.model._
1313
import org.jetbrains.dokka.base.parsers.MarkdownParser
@@ -17,12 +17,25 @@ import kotlin.coroutines.Continuation
1717
class ScalaModuleProvider(using ctx: DocContext) extends SourceToDocumentableTranslator:
1818
override def invoke(sourceSet: DokkaSourceSet, cxt: DokkaContext, unused: Continuation[? >: DModule]) =
1919
val result = DokkaTastyInspector(new MarkdownParser(_ => null)).result()
20+
val (rootPck, rest) = result.partition(_.name == "<empty>")
2021

2122
def flattenMember(m: Member): Seq[(DRI, Member)] = (m.dri -> m) +: m.allMembers.flatMap(flattenMember)
2223

24+
val topLevelPackage = new DPackage(
25+
DRI(location = "<empty>"),
26+
JNil,
27+
JNil,
28+
JNil,
29+
JNil,
30+
JMap(),
31+
null,
32+
JSet(ctx.sourceSet),
33+
PropertyContainer.Companion.empty()
34+
).withNewMembers(rest ++ rootPck.flatMap(_.allMembers)).withKind(Kind.RootPackage).asInstanceOf[DPackage]
35+
2336
new DModule(
2437
sourceSet.getDisplayName,
25-
result.asJava,
38+
JList(topLevelPackage),
2639
JMap(),
2740
null,
2841
sourceSet.toSet,

scala3doc/src/dotty/dokka/model/api/api.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ trait ImplicitConversionProvider { def conversion: Option[ImplicitConversion] }
5454
trait Classlike
5555

5656
enum Kind(val name: String){
57+
case RootPackage extends Kind("")
5758
case Package extends Kind("package")
5859
case Class(typeParams: Seq[TypeParameter], argsLists: Seq[Seq[Parameter]])
5960
extends Kind("class") with Classlike

scala3doc/src/dotty/dokka/model/api/internalExtensions.scala

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,9 @@ extension (member: Member)
9999
val newExt = oldExt.copy(graph = oldExt.graph ++ edges)
100100
putInMember(newExt)
101101

102-
def updateRecusivly(op: Member => Member) = op(member).withMembers(member.allMembers.map(op))
102+
def updateRecusivly(op: Member => Member): Member =
103+
val newMembers = member.allMembers.map(_.updateRecusivly(op))
104+
op(member).withMembers(newMembers)
103105

104106
extension (bound: Bound)
105107
def asSignature: Signature = bound match
@@ -111,14 +113,18 @@ extension (bound: Bound)
111113
}
112114

113115
extension (m: DModule)
114-
def updatePackages(op: Seq[DPackage] => Seq[DPackage]): DModule =
116+
def updatePackages(op: Seq[Member] => Seq[Member]): DModule =
117+
val topLevelPck = m.getPackages.get(0)
118+
val newRoot = topLevelPck.withMembers(op(topLevelPck.allMembers))
119+
115120
m.copy(
116-
m.getName,
117-
op(m.getPackages.asScala.toSeq).asJava,
118-
m.getDocumentation,
119-
m.getExpectPresentInSet,
120-
m.getSourceSets,
121-
m.getExtra
122-
)
123-
124-
def updateMembers(op: Member => Member): DModule = updatePackages(_.map(p => p.updateRecusivly(op).asInstanceOf[DPackage]))
121+
m.getName,
122+
JList(newRoot.asInstanceOf[DPackage]),
123+
m.getDocumentation,
124+
m.getExpectPresentInSet,
125+
m.getSourceSets,
126+
m.getExtra
127+
)
128+
129+
def updateMembers(op: Member => Member): DModule =
130+
updatePackages(_.map(p => p.updateRecusivly(op)))

scala3doc/src/dotty/dokka/site/NavigationCreator.scala

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ package dotty.dokka
22
package site
33

44
import org.jetbrains.dokka.base.renderers.html.{NavigationNode, NavigationPage}
5-
import org.jetbrains.dokka.model.DPackage
65
import org.jetbrains.dokka.model.DModule
7-
import org.jetbrains.dokka.pages._
6+
import org.jetbrains.dokka.pages.{Kind => _, _}
87
import org.jetbrains.dokka.transformers.pages.PageTransformer
8+
import dotty.dokka.model.api._
99

1010
import scala.collection.JavaConverters._
1111

@@ -18,12 +18,9 @@ class NavigationCreator(using ctx: DocContext) extends PageTransformer:
1818
case cp: ContentPage => cp.getDocumentable match
1919
case null =>
2020
processChildren
21-
// Left over package from dokka
22-
case p: DPackage if p.getName == "<empty>" && p.getChildren.isEmpty =>
23-
Nil
24-
case p: DPackage =>
25-
val ss = p.getSourceSets.asScala.toSet.toDisplay
26-
List(new NavigationNode(p.getName, p.getDri, ss, JList())) ++ processChildren
21+
case m: Member if m.kind == Kind.Package =>
22+
val ss = m.getSourceSets.asScala.toSet.toDisplay
23+
List(new NavigationNode(m.name, m.dri, ss, JNil)) ++ processChildren
2724
case _: DModule =>
2825
processChildren
2926
case _ =>

scala3doc/src/dotty/dokka/tasty/ClassLikeSupport.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -445,10 +445,12 @@ trait ClassLikeSupport:
445445
def mkMember[T <: Kind](
446446
symbol: Symbol,
447447
member: MemberExtension,
448-
compositeExt: CompositeMemberExtension = CompositeMemberExtension.empty): Member =
448+
compositeExt: CompositeMemberExtension = CompositeMemberExtension.empty,
449+
nameOverride: Symbol => String = _.normalizedName
450+
): Member =
449451
new DClass(
450452
symbol.dri,
451-
symbol.normalizedName,
453+
nameOverride(symbol),
452454
JNil,
453455
JNil,
454456
JNil,

scala3doc/src/dotty/dokka/tasty/PackageSupport.scala

Lines changed: 7 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,47 +6,21 @@ import org.jetbrains.dokka.links.PointingToDeclaration
66
import org.jetbrains.dokka.model.properties._
77
import org.jetbrains.dokka.model.doc.DocumentationNode
88
import dotty.dokka._
9-
import dotty.dokka.model.api.CompositeMemberExtension
9+
import dotty.dokka.model.api._
1010

1111
import collection.JavaConverters._
1212

1313
trait PackageSupport:
1414
self: TastyParser =>
1515
import qctx.reflect._
1616

17-
def parsePackage(pck: PackageClause): DPackage = {
18-
val name = extractPackageName(pck.pid.show)
19-
val documentation = pck.symbol.documentation
20-
DPackage(
21-
new DRI(name, null, null, PointingToDeclaration.INSTANCE, null),
22-
JList(),
23-
JList(),
24-
JList(),
25-
JList(),
26-
documentation.asJava,
27-
null,
28-
ctx.sourceSet.toSet,
29-
PropertyContainer.Companion.empty()
30-
)
31-
}
32-
33-
def parsePackageObject(pckObj: ClassDef): DPackage =
34-
parseClasslike(pckObj) match {
35-
case clazz: DClass =>
36-
DPackage(
37-
new DRI(pckObj.symbol.packageName, null, null, PointingToDeclaration.INSTANCE, null),
38-
clazz.getFunctions,
39-
clazz.getProperties,
40-
JList(),
41-
JList(),
42-
pckObj.symbol.documentation.asJava,
43-
null,
44-
ctx.sourceSet.toSet,
45-
PropertyContainer.Companion.empty()
46-
.plus(clazz.get(CompositeMemberExtension))
47-
)
48-
}
17+
def parsePackage(pck: PackageClause): (String, Member) =
18+
val name = extractPackageName(pck.pid.show)
19+
val mExt = MemberExtension.empty.copy(kind = Kind.Package)
20+
name -> mkMember(pck.symbol, mExt, nameOverride = _ => name)
4921

22+
def parsePackageObject(pckObj: ClassDef): (String, Member) =
23+
pckObj.symbol.packageName -> parseClasslike(pckObj).withKind(Kind.Package)
5024

5125
private def extractPackageName(pidShowNoColor: String): String = {
5226
val pidSplit = pidShowNoColor.split("\\.")

scala3doc/src/dotty/dokka/tasty/TastyParser.scala

Lines changed: 10 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import dotty.dokka.model.api._
2828
*/
2929
case class DokkaTastyInspector(parser: Parser)(using ctx: DocContext) extends DocTastyInspector:
3030

31-
private val topLevels = Seq.newBuilder[Documentable]
31+
private val topLevels = Seq.newBuilder[(String, Member)]
3232

3333
def processCompilationUnit(using q: Quotes)(root: q.reflect.Tree): Unit =
3434
// NOTE we avoid documenting definitions in the magical stdLibPatches directory;
@@ -48,72 +48,21 @@ case class DokkaTastyInspector(parser: Parser)(using ctx: DocContext) extends Do
4848
topLevels ++= parser.parseRootTree(root.asInstanceOf[parser.qctx.reflect.Tree])
4949
end processCompilationUnit
5050

51-
def result(): List[DPackage] =
51+
def result(): List[Member] =
5252
topLevels.clear()
5353
val filePaths = ctx.args.tastyFiles.map(_.getAbsolutePath).toList
5454
val classpath = ctx.args.classpath.split(java.io.File.pathSeparator).toList
5555

5656
inspectFilesInContext(classpath, filePaths)
5757

5858
val all = topLevels.result()
59-
val packages = all
60-
.filter(_.isInstanceOf[DPackage])
61-
.map(_.asInstanceOf[DPackage])
62-
.groupBy(_.getDri)
63-
.map((dri, pckgs) =>
64-
pckgs.reduce(_.mergeWith(_))
65-
)
66-
.toList
67-
.sortBy( pckg => pckg.dri.location.size )
68-
.reverse
69-
70-
71-
val byPackage = all.filter(_.dri != null).groupBy( p =>
72-
packages.find(d => p.dri.location.contains(d.dri.location)).getOrElse(throw IllegalStateException("No package for entries found"))
73-
)
74-
75-
byPackage
76-
.map {
77-
case (f, entries) => {
78-
val pck = new DPackage(
79-
f.getDri,
80-
f.getFunctions,
81-
f.getProperties,
82-
JList(),
83-
JList(),
84-
f.getDocumentation,
85-
null,
86-
JSet(ctx.sourceSet),
87-
f.getExtra
88-
)
89-
.withNewMembers(entries.filterNot(_.isInstanceOf[DPackage]).toList)
90-
.withKind(Kind.Package)
91-
92-
pck.asInstanceOf[DPackage]
93-
}
59+
all.groupBy(_._1).map { case (pckName, members) =>
60+
val (pcks, rest) = members.map(_._2).partition(_.kind == Kind.Package)
61+
pcks.reduce( (p1, p2) =>
62+
p1.withNewMembers(p2.allMembers) // TODO add doc
63+
).withNewMembers(rest)
9464
}.toList
9565

96-
extension (self: DPackage) def mergeWith(other: DPackage): DPackage =
97-
def nodes(p: DPackage): JList[TagWrapper] = p.getDocumentation.get(ctx.sourceSet) match
98-
case null => JList[TagWrapper]()
99-
case node => node.getChildren
100-
101-
mergeExtras(
102-
DPackage(
103-
self.getDri,
104-
(self.getFunctions.asScala ++ other.getFunctions.asScala).asJava,
105-
(self.getProperties.asScala ++ other.getProperties.asScala).asJava,
106-
JList(), // WARNING Merging is done before collecting classlikes, if it changes it needs to be refactored
107-
JList(),
108-
ctx.sourceSet.toMap(DocumentationNode(nodes(self) ++ nodes(other))),
109-
null,
110-
ctx.sourceSet.toSet,
111-
PropertyContainer.Companion.empty()
112-
),
113-
self,
114-
other
115-
)
116-
11766
/** Parses a single Tasty compilation unit. */
11867
case class TastyParser(qctx: Quotes, inspector: DokkaTastyInspector)(using val ctx: DocContext)
11968
extends ScaladocSupport with BasicSupport with TypesSupport with ClassLikeSupport with SyntheticsSupport with PackageSupport with NameNormalizer:
@@ -135,8 +84,8 @@ case class TastyParser(qctx: Quotes, inspector: DokkaTastyInspector)(using val c
13584
report.warning(s"Failed to process ${sym.fullName}:\n${throwableToString(t)}")
13685
None
13786

138-
def parseRootTree(root: Tree): Seq[Documentable] =
139-
val docs = Seq.newBuilder[Documentable]
87+
def parseRootTree(root: Tree): Seq[(String, Member)] =
88+
val docs = Seq.newBuilder[(String, Member)]
14089
object Traverser extends TreeTraverser:
14190
var seen: List[Tree] = Nil
14291

@@ -149,7 +98,7 @@ case class TastyParser(qctx: Quotes, inspector: DokkaTastyInspector)(using val c
14998
case packageObject: ClassDef if(packageObject.symbol.name.contains("package$")) =>
15099
docs += parsePackageObject(packageObject)
151100
case clazz: ClassDef if clazz.symbol.shouldDocumentClasslike =>
152-
docs += parseClasslike(clazz)
101+
docs += clazz.symbol.packageName -> parseClasslike(clazz)
153102
case _ =>
154103
}
155104
seen = seen.tail

scala3doc/src/dotty/dokka/transformers/ImplicitMembersExtensionTransformer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,4 @@ class ImplicitMembersExtensionTransformer(using DocContext) extends Documentable
6262
val expandedMembers = c.allMembers.map(expandMember(newImplicitMembers ++ Seq(c)))
6363
c.withMembers(newImplicitMembers ++ expandedMembers)
6464

65-
original.updatePackages(_.map(expandMember(Nil)(_).asInstanceOf[DPackage]))
65+
original.updatePackages(_.map(expandMember(Nil)(_)))

scala3doc/src/dotty/dokka/transformers/InheritanceInformationTransformer.scala

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ import dotty.dokka.model.api._
1212

1313
class InheritanceInformationTransformer(val ctx: DokkaContext) extends DocumentableTransformer:
1414
override def invoke(original: DModule, context: DokkaContext): DModule =
15-
val subtypes = getSupertypes(original).groupBy(_._1).transform((k, v) => v.map(_._2))
15+
val subtypes = getSupertypes(original.getPackages.get(0)).groupBy(_._1).transform((k, v) => v.map(_._2))
1616
original.updateMembers { m =>
1717
val st: Seq[LinkToType] = subtypes.getOrElse(m.dri, Nil)
1818
m.withKnownChildren(st).withNewGraphEdges(st.map(_ -> m.asLink))
1919
}
2020

21-
private def getSupertypes(d: Documentable): Seq[(DRI, LinkToType)] = d match
22-
case m: DModule => m.getPackages.asScala.toList.flatMap(p => getSupertypes(p))
23-
case c: Member =>
24-
val selfMapping = if !c.kind.isInstanceOf[Classlike] then Nil else c.parents.map(_._2 -> c.asLink)
25-
c.allMembers.flatMap(getSupertypes) ++ selfMapping
21+
private def getSupertypes(c: Member): Seq[(DRI, LinkToType)] =
22+
val selfMapping =
23+
if !c.kind.isInstanceOf[Classlike] then Nil
24+
else c.parents.map(_._2 -> c.asLink)
25+
c.allMembers.flatMap(getSupertypes) ++ selfMapping

scala3doc/src/dotty/dokka/translators/ScalaPageCreator.scala

Lines changed: 10 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -32,24 +32,22 @@ class ScalaPageCreator(
3232
private val contentBuilder =
3333
ScalaPageContentBuilder(commentsToContentConverter, signatureProvider)
3434

35-
override def pageForModule(m: DModule): ModulePageNode = super.pageForModule(m)
35+
override def pageForModule(m: DModule): ModulePageNode =
36+
val rootPackage = m.getPackages.get(0)
37+
new ModulePageNode(
38+
m.getName,
39+
contentBuilder.mkMemberInfo(rootPackage),
40+
m,
41+
pagesForMembers(rootPackage),
42+
JNil
43+
)
3644

3745
private def pagesForMembers(member: Member): JList[PageNode] =
3846
val all = member
39-
.membersBy(_.kind.isInstanceOf[Classlike])
47+
.membersBy(m => m.kind == Kind.Package || m.kind.isInstanceOf[Classlike])
4048
.filter(m => m.origin == Origin.RegularlyDefined && m.inheritedFrom.isEmpty)
4149
all.map(pageForMember(_)).asJava
4250

43-
override def pageForPackage(p: DPackage): PackagePageNode =
44-
PackagePageNode(
45-
p.name,
46-
contentBuilder.mkMemberInfo(p),
47-
JSet(p.dri),
48-
p,
49-
pagesForMembers(p),
50-
JNil
51-
)
52-
5351
def pageForMember(c: Member): ClasslikePageNode = {
5452
val name =
5553
if c.kind == Kind.Object && c.companion.isDefined then
@@ -66,38 +64,3 @@ class ScalaPageCreator(
6664
JNil,
6765
).modified(name, pagesForMembers(c)) // We need override default page
6866
}
69-
70-
override def contentForModule(m: DModule) = {
71-
def buildBlock = (builder: DocBuilder) => builder
72-
.group(kind = ContentKind.Cover) { gbuilder => gbuilder
73-
.cover(m.getName)()
74-
.descriptionIfNotEmpty(m)
75-
}
76-
.addChildren(contentForComments(m).asScala.toSeq)
77-
.groupingBlock(
78-
"Packages",
79-
List("" -> m.getPackages.asScala.toList.filter(_.allMembers.nonEmpty)),
80-
kind = ContentKind.Packages,
81-
sourceSets = m.getSourceSets.asScala.toSet
82-
)(
83-
(bdr, elem) => bdr
84-
) { (bdr, elem) => bdr
85-
.driLink(elem.getName, elem.getDri)
86-
}
87-
88-
contentBuilder.contentForDocumentable(m, buildBlock = buildBlock)
89-
}
90-
extension (b: DocBuilder)
91-
def descriptionIfNotEmpty(d: Documentable): DocBuilder = {
92-
val desc = this.contentForDescription(d).asScala.toSeq
93-
val res = if desc.isEmpty then b else b
94-
.sourceSetDependentHint(
95-
Set(d.getDri),
96-
d.getSourceSets.asScala.toSet,
97-
kind = ContentKind.SourceSetDependentHint,
98-
styles = Set(TextStyle.UnderCoverText)
99-
) { sourceSetBuilder => sourceSetBuilder
100-
.addChildren(desc)
101-
}
102-
res
103-
}

0 commit comments

Comments
 (0)