Skip to content

Commit dfd02cb

Browse files
committed
Refactor static-site loading
1 parent f955f8b commit dfd02cb

File tree

14 files changed

+361
-301
lines changed

14 files changed

+361
-301
lines changed

docs/docs/usage/scaladoc/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ layout: doc-page
33
title: "Scaladoc"
44
---
55

6-
![scaladoc logo](images/scaladoc_logo.svg)
6+
![scaladoc logo](images/scaladoc-logo.png)
77

88
scaladoc is a tool to generate the API documentation of your Scala 3 projects. It provides similar features to `javadoc` as well as `jekyll` or `docusaurus`.

docs/sidebar.yml

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,35 @@
1-
sidebar:
2-
- title: Blog
1+
rootIndex: docs/index.md
2+
pages:
3+
# - title: Blog
34
- title: Usage
45
subsection:
56
- page: docs/usage/sbt-projects.md
67
- page: docs/usage/ide-support.md
78
- page: docs/usage/cbt-projects.md
8-
- page: docs/usage/scaladoc
9+
- title: Scaladoc
10+
index: docs/usage/scaladoc/index.md
11+
subsection:
12+
- page: docs/usage/scaladoc/docstrings.md
13+
- page: docs/usage/scaladoc/linking.md
14+
- page: docs/usage/scaladoc/search-engine.md
15+
- page: docs/usage/scaladoc/settings.md
16+
- page: docs/usage/scaladoc/site-versioning.md
17+
- page: docs/usage/scaladoc/static-site.md
918
- title: Reference
1019
subsection:
1120
- page: docs/reference/overview.md
1221
- title: New Types
1322
index: docs/reference/new-types/new-types.md
1423
subsection:
1524
- page: docs/reference/new-types/intersection-types.md
25+
- page: docs/reference/new-types/intersection-types-spec.md
1626
- page: docs/reference/new-types/union-types.md
27+
- page: docs/reference/new-types/union-types-spec.md
1728
- page: docs/reference/new-types/type-lambdas.md
29+
- page: docs/reference/new-types/type-lambdas-spec.md
1830
- page: docs/reference/new-types/match-types.md
1931
- page: docs/reference/new-types/dependent-function-types.md
32+
- page: docs/reference/new-types/dependent-function-types-spec.md
2033
- page: docs/reference/new-types/polymorphic-function-types.md
2134
- title: Enums
2235
index: docs/reference/enums/enums-index.md
@@ -26,16 +39,20 @@ sidebar:
2639
- page: docs/reference/enums/desugarEnums.md
2740
- title: Contextual Abstractions
2841
index: docs/reference/contextual/contextual.md
42+
directory: contextual
2943
subsection:
3044
- page: docs/reference/contextual/givens.md
3145
- page: docs/reference/contextual/using-clauses.md
3246
- page: docs/reference/contextual/context-bounds.md
3347
- page: docs/reference/contextual/given-imports.md
3448
- page: docs/reference/contextual/extension-methods.md
49+
- page: docs/reference/contextual/right-associative-extension-methods.md
3550
- page: docs/reference/contextual/type-classes.md
3651
- page: docs/reference/contextual/derivation.md
52+
- page: docs/reference/contextual/derivation-macro.md
3753
- page: docs/reference/contextual/multiversal-equality.md
3854
- page: docs/reference/contextual/context-functions.md
55+
- page: docs/reference/contextual/context-functions-spec.md
3956
- page: docs/reference/contextual/conversions.md
4057
- page: docs/reference/contextual/by-name-context-parameters.md
4158
- page: docs/reference/contextual/relationship-implicits.md
@@ -45,6 +62,7 @@ sidebar:
4562
- page: docs/reference/metaprogramming/inline.md
4663
- page: docs/reference/metaprogramming/compiletime-ops.md
4764
- page: docs/reference/metaprogramming/macros.md
65+
- page: docs/reference/metaprogramming/macros-spec.md
4866
- page: docs/reference/metaprogramming/staging.md
4967
- page: docs/reference/metaprogramming/reflection.md
5068
- page: docs/reference/metaprogramming/tasty-inspect.md
@@ -56,8 +74,10 @@ sidebar:
5674
- page: docs/reference/other-new-features/creator-applications.md
5775
- page: docs/reference/other-new-features/export.md
5876
- page: docs/reference/other-new-features/opaques.md
77+
- page: docs/reference/other-new-features/opaques-details.md
5978
- page: docs/reference/other-new-features/open-classes.md
6079
- page: docs/reference/other-new-features/parameter-untupling.md
80+
- page: docs/reference/other-new-features/parameter-untupling-spec.md
6181
- page: docs/reference/other-new-features/kind-polymorphism.md
6282
- page: docs/reference/other-new-features/matchable.md
6383
- page: docs/reference/other-new-features/threadUnsafe-annotation.md
@@ -69,23 +89,27 @@ sidebar:
6989
- page: docs/reference/other-new-features/type-test.md
7090
- page: docs/reference/other-new-features/experimental-defs.md
7191
- title: Other Changed Features
92+
directory: changed-features
7293
index: docs/reference/changed-features/changed-features.md
7394
subsection:
7495
- page: docs/reference/changed-features/numeric-literals.md
7596
- page: docs/reference/changed-features/structural-types.md
97+
- page: docs/reference/changed-features/structural-types-spec.md
7698
- page: docs/reference/changed-features/operators.md
7799
- page: docs/reference/changed-features/wildcards.md
78100
- page: docs/reference/changed-features/imports.md
79101
- page: docs/reference/changed-features/type-checking.md
80102
- page: docs/reference/changed-features/type-inference.md
81103
- page: docs/reference/changed-features/implicit-resolution.md
82104
- page: docs/reference/changed-features/implicit-conversions.md
105+
- page: docs/reference/changed-features/implicit-conversions-spec.md
83106
- page: docs/reference/changed-features/overload-resolution.md
84107
- page: docs/reference/changed-features/match-syntax.md
85108
- page: docs/reference/changed-features/vararg-splices.md
86109
- page: docs/reference/changed-features/pattern-bindings.md
87110
- page: docs/reference/changed-features/pattern-matching.md
88111
- page: docs/reference/changed-features/eta-expansion.md
112+
- page: docs/reference/changed-features/eta-expansion-spec.md
89113
- page: docs/reference/changed-features/compiler-plugins.md
90114
- page: docs/reference/changed-features/lazy-vals-init.md
91115
- page: docs/reference/changed-features/main-functions.md
@@ -101,15 +125,18 @@ sidebar:
101125
- page: docs/reference/dropped-features/package-objects.md
102126
- page: docs/reference/dropped-features/early-initializers.md
103127
- page: docs/reference/dropped-features/class-shadowing.md
128+
- page: docs/reference/dropped-features/class-shadowing-spec.md
104129
- page: docs/reference/dropped-features/limit22.md
105130
- page: docs/reference/dropped-features/xml.md
106131
- page: docs/reference/dropped-features/symlits.md
107132
- page: docs/reference/dropped-features/auto-apply.md
108133
- page: docs/reference/dropped-features/weak-conformance.md
134+
- page: docs/reference/dropped-features/weak-conformance-spec.md
109135
- page: docs/reference/dropped-features/nonlocal-returns.md
110136
- page: docs/reference/dropped-features/this-qualifier.md
111137
- page: docs/reference/dropped-features/wildcard-init.md
112138
- title: Experimental Features
139+
directory: experimental
113140
subsection:
114141
- page: docs/reference/experimental/overview.md
115142
- page: docs/reference/experimental/canthrow.md
@@ -124,6 +151,8 @@ sidebar:
124151
subsection:
125152
- page: docs/reference/language-versions/source-compatibility.md
126153
- page: docs/reference/language-versions/binary-compatibility.md
154+
- page: docs/reference/soft-modifier.md
155+
- page: docs/reference/features-classification.md
127156
- title: Contributing
128157
subsection:
129158
- page: docs/contributing/contribute-knowledge.md
@@ -132,6 +161,7 @@ sidebar:
132161
- page: docs/contributing/testing.md
133162
- page: docs/contributing/debugging.md
134163
- title: IDEs and Tools
164+
directory: tools
135165
subsection:
136166
- page: docs/contributing/tools/ide.md
137167
- page: docs/contributing/tools/mill.md

scaladoc-testcases/docs/sidebar.yml

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
sidebar:
2-
- title: Docs
3-
subsection:
4-
- page: docs/docs/f1.md
5-
- page: docs/docs/f2.md
6-
- page: docs/docs/f3.md
7-
- page: docs/docs/f4.md
1+
rootIndex: docs/index.md
2+
pages:
3+
- page: docs/docs/f1.md
4+
- page: docs/docs/f2.md
5+
- page: docs/docs/f3.md
6+
- page: docs/docs/f4.md

scaladoc/src/dotty/tools/scaladoc/renderers/Locations.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ trait Locations(using ctx: DocContext):
3434
cache.get(dri) match
3535
case null =>
3636
val path = dri match
37-
case `docsRootDRI` => List("docs", "index")
37+
// case `docsRootDRI` => List("docs", "index")
3838
case `apiPageDRI` =>
39-
if ctx.staticSiteContext.fold(false)(_.hasIndexFile)
39+
if ctx.args.apiSubdirectory && ctx.staticSiteContext.nonEmpty
4040
then List("api", "index")
4141
else List("index")
4242
case dri if dri.isStaticFile =>
@@ -88,6 +88,6 @@ trait Locations(using ctx: DocContext):
8888

8989
def pathToRoot(dri: DRI): String = rawLocation(dri).drop(1).map(_ => "..") match
9090
case Nil => ""
91-
case seq => seq.mkString("", "/", "/")
91+
case seq => seq.mkString("", "/" , "/")
9292

9393
def driExists(dri: DRI) = effectiveMembers.get(dri).isDefined || dri.isStaticFile

scaladoc/src/dotty/tools/scaladoc/renderers/Renderer.scala

Lines changed: 13 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,12 @@ abstract class Renderer(rootPackage: Member, val members: Map[DRI, Member], prot
4040
staticSite match
4141
case None => rootPckPage.withTitle(args.name)
4242
case Some(siteContext) =>
43-
val (indexes, templates) = siteContext.templates.partition(f =>
44-
f.templateFile.isIndexPage() && f.file.toPath.getParent() == siteContext.docsPath)
45-
if (indexes.size > 1)
46-
val msg = s"ERROR: Multiple index pages for doc found ${indexes.map(_.file)}"
47-
report.error(msg)
43+
val rootTemplate = siteContext.staticSiteRoot.rootTemplate
4844

4945
// Below code is for walking in order the tree and modifing its nodes basing on its neighbours
5046

51-
// First we flatten templates to get them sorted in-order
52-
def flattenedTemplates(template: LoadedTemplate): Seq[LoadedTemplate] =
53-
template +: template.children.flatMap(flattenedTemplates)
54-
5547
// We add dummy guards
56-
val allTemplates: Seq[Option[LoadedTemplate]] = None +: templates.flatMap(flattenedTemplates).map(Some(_)) :+ None
48+
val allTemplates: Seq[Option[LoadedTemplate]] = None +: siteContext.allTemplates.map(Some(_)) :+ None
5749

5850
// Let's gather the list of maps for each template with its in-order neighbours
5951
val newSettings: List[Map[String, Object]] = allTemplates.sliding(size = 3, step = 1).map {
@@ -82,34 +74,17 @@ abstract class Renderer(rootPackage: Member, val members: Map[DRI, Member], prot
8274
)
8375
updatedTemplates.result()
8476

85-
val newTemplates = updateSettings(templates, newSettings.to(ListBuffer))
77+
val newTemplates = updateSettings(Seq(siteContext.staticSiteRoot.rootTemplate), newSettings.to(ListBuffer))
8678
val templatePages = newTemplates.map(templateToPage(_, siteContext))
8779

88-
indexes.headOption match
89-
case None if templatePages.isEmpty=>
90-
rootPckPage.withTitle(args.name)
91-
case None =>
92-
Page(Link(args.name, docsRootDRI),"", templatePages :+ rootPckPage.withTitle("API"))
93-
case Some(indexPage) =>
94-
val newChildren = templatePages :+ rootPckPage.withTitle("API")
95-
templateToPage(indexPage, siteContext).withNewChildren(newChildren)
96-
97-
val hiddenPages: Seq[Page] =
98-
staticSite match
99-
case None =>
100-
Seq(navigablePage.copy( // Add index page that is a copy of api/index.html
101-
link = navigablePage.link.copy(dri = docsRootDRI),
102-
children = Nil
103-
))
104-
case Some(siteContext) =>
105-
// In case that we do not have an index page and we do not have any API entries
106-
// we want to create empty index page, so there is one
107-
val actualIndexTemplate = siteContext.indexTemplate() match {
108-
case None if effectiveMembers.isEmpty => Seq(siteContext.emptyIndexTemplate)
109-
case templates => templates.toSeq
110-
}
80+
val newRoot = newTemplates.head
11181

112-
(siteContext.orphanedTemplates ++ actualIndexTemplate).map(templateToPage(_, siteContext))
82+
if newRoot.children.size == 0 && newRoot.templateFile.rawCode == ""
83+
then rootPckPage.withTitle(args.name)
84+
else {
85+
val newRootPage = templateToPage(newRoot, siteContext)
86+
newRootPage.withNewChildren(Seq(rootPckPage.withTitle("API")))
87+
}
11388

11489
val redirectPages: Seq[Page] = staticSite.fold(Seq.empty)(siteContext => siteContext.redirectTemplates.map {
11590
case (template, driFrom, driTo) =>
@@ -121,22 +96,10 @@ abstract class Renderer(rootPackage: Member, val members: Map[DRI, Member], prot
12196
* Here we have to retrive index pages from hidden pages and replace fake index pages in navigable page tree.
12297
*/
12398
val allPages: Seq[Page] =
124-
def traversePages(page: Page): (Page, Seq[Page]) =
125-
val (newChildren, newPagesToRemove): (Seq[Page], Seq[Page]) = page.children.map(traversePages(_)).foldLeft((Seq[Page](), Seq[Page]())) {
126-
case ((pAcc, ptrAcc), (p, ptr)) => (pAcc :+ p, ptrAcc ++ ptr)
127-
}
128-
hiddenPages.find(_.link == page.link) match
129-
case None =>
130-
(page.copy(children = newChildren), newPagesToRemove)
131-
case Some(newPage) =>
132-
(newPage.copy(children = newChildren), newPagesToRemove :+ newPage)
133-
134-
val (newNavigablePage, pagesToRemove) = traversePages(navigablePage)
135-
136-
val all = newNavigablePage +: (hiddenPages.filterNot(pagesToRemove.contains) ++ redirectPages)
137-
// We need to check for conflicts only if we have top-level member called blog or docs
99+
val all = navigablePage +: redirectPages
100+
// We need to check for conflicts only if we have top-level member called docs
138101
val hasPotentialConflict =
139-
rootPackage.members.exists(m => m.name.startsWith("docs") || m.name.startsWith("blog"))
102+
rootPackage.members.exists(m => m.name.startsWith("docs"))
140103

141104
if hasPotentialConflict then
142105
def walk(page: Page): Unit =

scaladoc/src/dotty/tools/scaladoc/site/SidebarParser.scala

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,46 @@ import collection.JavaConverters._
88
import java.util.Optional
99

1010
enum Sidebar:
11-
case Category(title: Option[String], indexPath: Option[String], nested: List[Sidebar])
11+
case Root(index: Option[String], pages: List[Sidebar])
12+
case Category(title: Option[String], indexPath: Option[String], nested: List[Sidebar], directory: Option[String])
1213
case Page(title: Option[String], pagePath: String)
1314

1415
object Sidebar:
15-
case class RawInput(var title: String, var page: String, var index: String, var subsection: JList[RawInput]):
16-
def this() = this("", "", "", JList())
16+
case class RawRoot(var rootIndex: String, var pages: JList[RawInput]):
17+
def this() = this("", JList())
18+
19+
def setRootIndex(s: String) = rootIndex = s
20+
def setPages(l: JList[RawInput]) = pages = l
21+
22+
case class RawInput(var title: String, var page: String, var index: String, var subsection: JList[RawInput], var directory: String):
23+
def this() = this("", "", "", JList(), "")
1724

1825
def setTitle(t: String) = this.title = t
1926
def setPage(p: String) = this.page = p
2027
def setIndex(i: String) = this.index = i
2128
def setSubsection(s: JList[RawInput]) = this.subsection = s
29+
def setDirectory(d: String) = this.directory = d
2230

23-
type RawInnerTpe = JMap[String, JList[RawInput]]
24-
private object RawTypeRef extends TypeReference[RawInnerTpe]
31+
private object RootTypeRef extends TypeReference[RawRoot]
2532

2633
private def toSidebar(r: RawInput): Sidebar = r match
27-
case RawInput(title, page, index, subsection) if page.nonEmpty && index.isEmpty && subsection.isEmpty() || title == "Blog" =>
34+
case RawInput(title, page, index, subsection, dir) if page.nonEmpty && index.isEmpty && subsection.isEmpty() || title == "Blog" =>
2835
Sidebar.Page(Option.when(title.nonEmpty)(title), page)
29-
case RawInput(title, page, index, subsection) if page.isEmpty && !subsection.isEmpty() =>
30-
Sidebar.Category(Option.when(title.nonEmpty)(title), Option.when(index.nonEmpty)(index), subsection.asScala.map(toSidebar).toList)
36+
case RawInput(title, page, index, subsection, dir) if page.isEmpty && (!subsection.isEmpty() || !index.isEmpty()) =>
37+
Sidebar.Category(Option.when(title.nonEmpty)(title), Option.when(index.nonEmpty)(index), subsection.asScala.map(toSidebar).toList, Option.when(dir.nonEmpty)(dir))
38+
39+
def load(content: String): Sidebar.Root =
40+
val mapper = ObjectMapper(YAMLFactory())
41+
val root: RawRoot = mapper.readValue(content, RootTypeRef)
42+
43+
val rootIndex: String = root.rootIndex
44+
val pages: List[Sidebar] = root.pages.asScala.toList.map(toSidebar)
45+
Sidebar.Root(Option.when(rootIndex.nonEmpty)(rootIndex), pages)
3146

32-
def load(content: String): Seq[Sidebar] =
47+
def load(file: java.io.File): Sidebar.Root =
3348
val mapper = ObjectMapper(YAMLFactory())
34-
val raw: RawInnerTpe = mapper.readValue(content, RawTypeRef)
49+
val root: RawRoot = mapper.readValue(file, RootTypeRef)
3550

36-
raw.get("sidebar").asScala.toList.map(toSidebar)
51+
val rootIndex: String = root.rootIndex
52+
val pages: List[Sidebar] = root.pages.asScala.toList.map(toSidebar)
53+
Sidebar.Root(Option.when(rootIndex.nonEmpty)(rootIndex), pages)

0 commit comments

Comments
 (0)