-
-
-
Try Scala 3
-
There are multiple ways of getting started with Scala 3.
-
- - You can try Scala 3 in your browser with Scastie.
- - If you already have sbt installed, you can create a Scala 3 project and sbt will take care of the rest.
- - You can install all necessary dependencies with coursier by running
cs setup
. You can also run cs install scala3-compiler
or cs install scala3-repl
to install command-line commands for the compiler and repl, correspondingly.
- - You can manually install Scala 3 on your computer.
-
-
-
Install Scala 3
-
If you are a Mac user, you can install Scala 3 with brew:
-
brew install lampepfl/brew/dotty
-
-
- If you are a Linux or Windows user, as a prerequisite you need a JDK 8 or later properly installed on your system. The environment variable JAVA_HOME
should point to your Java installation.
- For Windows users, we recommend using the Windows subsystem for linux or some other bash shell like git bash.
- Then download the latest release. Optionally add the path of the folder bin/
to the system environment variable PATH
.
-
-
-
Now you can compile Scala source code:
-
scalac hello.scala
-
-
To start the REPL, run: scala
.
-
-
Create a Scala 3 Project
-
The fastest way to create a new project in Scala 3 is using sbt (1.1.4+).
-
-
Create a Scala 3 project:
-
sbt new scala/scala3.g8
-
-
Or a Scala 3 project that cross compiles with Scala 2:
-
sbt new lampepfl/dotty-cross.g8
-
-
For documentation see the Scala 3 Example Project.
-
-
Learn more about Scala 3
-
You can find much more information about Scala 3 in ...
-
-
-
diff --git a/docs/sidebar.yml b/docs/sidebar.yml
index be2d0d0e59d9..3322200acc32 100644
--- a/docs/sidebar.yml
+++ b/docs/sidebar.yml
@@ -1,155 +1,186 @@
-sidebar:
- - title: Blog
+index: index.md
+subsection:
- title: Usage
subsection:
- - page: docs/usage/sbt-projects.md
- - page: docs/usage/ide-support.md
- - page: docs/usage/cbt-projects.md
- - page: docs/usage/scaladoc
+ - page: usage/sbt-projects.md
+ - page: usage/ide-support.md
+ - page: usage/cbt-projects.md
+ - title: Scaladoc
+ index: usage/scaladoc/index.md
+ subsection:
+ - page: usage/scaladoc/docstrings.md
+ - page: usage/scaladoc/linking.md
+ - page: usage/scaladoc/search-engine.md
+ - page: usage/scaladoc/settings.md
+ - page: usage/scaladoc/site-versioning.md
+ - page: usage/scaladoc/static-site.md
- title: Reference
subsection:
- - page: docs/reference/overview.md
+ - page: reference/overview.md
- title: New Types
- index: docs/reference/new-types/new-types.md
+ index: reference/new-types/new-types.md
subsection:
- - page: docs/reference/new-types/intersection-types.md
- - page: docs/reference/new-types/union-types.md
- - page: docs/reference/new-types/type-lambdas.md
- - page: docs/reference/new-types/match-types.md
- - page: docs/reference/new-types/dependent-function-types.md
- - page: docs/reference/new-types/polymorphic-function-types.md
+ - page: reference/new-types/intersection-types.md
+ - page: reference/new-types/intersection-types-spec.md
+ - page: reference/new-types/union-types.md
+ - page: reference/new-types/union-types-spec.md
+ - page: reference/new-types/type-lambdas.md
+ - page: reference/new-types/type-lambdas-spec.md
+ - page: reference/new-types/match-types.md
+ - page: reference/new-types/dependent-function-types.md
+ - page: reference/new-types/dependent-function-types-spec.md
+ - page: reference/new-types/polymorphic-function-types.md
- title: Enums
- index: docs/reference/enums/enums-index.md
+ index: reference/enums/enums-index.md
subsection:
- - page: docs/reference/enums/enums.md
- - page: docs/reference/enums/adts.md
- - page: docs/reference/enums/desugarEnums.md
+ - page: reference/enums/enums.md
+ - page: reference/enums/adts.md
+ - page: reference/enums/desugarEnums.md
- title: Contextual Abstractions
- index: docs/reference/contextual/contextual.md
+ index: reference/contextual/contextual.md
+ directory: contextual
subsection:
- - page: docs/reference/contextual/givens.md
- - page: docs/reference/contextual/using-clauses.md
- - page: docs/reference/contextual/context-bounds.md
- - page: docs/reference/contextual/given-imports.md
- - page: docs/reference/contextual/extension-methods.md
- - page: docs/reference/contextual/type-classes.md
- - page: docs/reference/contextual/derivation.md
- - page: docs/reference/contextual/multiversal-equality.md
- - page: docs/reference/contextual/context-functions.md
- - page: docs/reference/contextual/conversions.md
- - page: docs/reference/contextual/by-name-context-parameters.md
- - page: docs/reference/contextual/relationship-implicits.md
+ - page: reference/contextual/givens.md
+ - page: reference/contextual/using-clauses.md
+ - page: reference/contextual/context-bounds.md
+ - page: reference/contextual/given-imports.md
+ - page: reference/contextual/extension-methods.md
+ - page: reference/contextual/right-associative-extension-methods.md
+ - page: reference/contextual/type-classes.md
+ - page: reference/contextual/derivation.md
+ - page: reference/contextual/derivation-macro.md
+ - page: reference/contextual/multiversal-equality.md
+ - page: reference/contextual/context-functions.md
+ - page: reference/contextual/context-functions-spec.md
+ - page: reference/contextual/conversions.md
+ - page: reference/contextual/by-name-context-parameters.md
+ - page: reference/contextual/relationship-implicits.md
- title: Metaprogramming
- index: docs/reference/metaprogramming/metaprogramming.md
+ index: reference/metaprogramming/metaprogramming.md
subsection:
- - page: docs/reference/metaprogramming/inline.md
- - page: docs/reference/metaprogramming/compiletime-ops.md
- - page: docs/reference/metaprogramming/macros.md
- - page: docs/reference/metaprogramming/staging.md
- - page: docs/reference/metaprogramming/reflection.md
- - page: docs/reference/metaprogramming/tasty-inspect.md
+ - page: reference/metaprogramming/inline.md
+ - page: reference/metaprogramming/compiletime-ops.md
+ - page: reference/metaprogramming/macros.md
+ - page: reference/metaprogramming/macros-spec.md
+ - page: reference/metaprogramming/staging.md
+ - page: reference/metaprogramming/reflection.md
+ - page: reference/metaprogramming/tasty-inspect.md
- title: Other New Features
- index: docs/reference/other-new-features/other-new-types.md
+ index: reference/other-new-features/other-new-types.md
subsection:
- - page: docs/reference/other-new-features/trait-parameters.md
- - page: docs/reference/other-new-features/transparent-traits.md
- - page: docs/reference/other-new-features/creator-applications.md
- - page: docs/reference/other-new-features/export.md
- - page: docs/reference/other-new-features/opaques.md
- - page: docs/reference/other-new-features/open-classes.md
- - page: docs/reference/other-new-features/parameter-untupling.md
- - page: docs/reference/other-new-features/kind-polymorphism.md
- - page: docs/reference/other-new-features/matchable.md
- - page: docs/reference/other-new-features/threadUnsafe-annotation.md
- - page: docs/reference/other-new-features/targetName.md
- - page: docs/reference/other-new-features/control-syntax.md
- - page: docs/reference/other-new-features/indentation.md
- - page: docs/reference/other-new-features/safe-initialization.md
- - page: docs/reference/other-new-features/type-test.md
- - page: docs/reference/other-new-features/experimental-defs.md
+ - page: reference/other-new-features/trait-parameters.md
+ - page: reference/other-new-features/transparent-traits.md
+ - page: reference/other-new-features/creator-applications.md
+ - page: reference/other-new-features/export.md
+ - page: reference/other-new-features/opaques.md
+ - page: reference/other-new-features/opaques-details.md
+ - page: reference/other-new-features/open-classes.md
+ - page: reference/other-new-features/parameter-untupling.md
+ - page: reference/other-new-features/parameter-untupling-spec.md
+ - page: reference/other-new-features/kind-polymorphism.md
+ - page: reference/other-new-features/matchable.md
+ - page: reference/other-new-features/threadUnsafe-annotation.md
+ - page: reference/other-new-features/targetName.md
+ - page: reference/other-new-features/control-syntax.md
+ - page: reference/other-new-features/indentation.md
+ - page: reference/other-new-features/safe-initialization.md
+ - page: reference/other-new-features/type-test.md
+ - page: reference/other-new-features/experimental-defs.md
- title: Other Changed Features
- index: docs/reference/changed-features/changed-features.md
+ directory: changed-features
+ index: reference/changed-features/changed-features.md
subsection:
- - page: docs/reference/changed-features/numeric-literals.md
- - page: docs/reference/changed-features/structural-types.md
- - page: docs/reference/changed-features/operators.md
- - page: docs/reference/changed-features/wildcards.md
- - page: docs/reference/changed-features/imports.md
- - page: docs/reference/changed-features/type-checking.md
- - page: docs/reference/changed-features/type-inference.md
- - page: docs/reference/changed-features/implicit-resolution.md
- - page: docs/reference/changed-features/implicit-conversions.md
- - page: docs/reference/changed-features/overload-resolution.md
- - page: docs/reference/changed-features/match-syntax.md
- - page: docs/reference/changed-features/vararg-splices.md
- - page: docs/reference/changed-features/pattern-bindings.md
- - page: docs/reference/changed-features/pattern-matching.md
- - page: docs/reference/changed-features/eta-expansion.md
- - page: docs/reference/changed-features/compiler-plugins.md
- - page: docs/reference/changed-features/lazy-vals-init.md
- - page: docs/reference/changed-features/main-functions.md
+ - page: reference/changed-features/numeric-literals.md
+ - page: reference/changed-features/structural-types.md
+ - page: reference/changed-features/structural-types-spec.md
+ - page: reference/changed-features/operators.md
+ - page: reference/changed-features/wildcards.md
+ - page: reference/changed-features/imports.md
+ - page: reference/changed-features/type-checking.md
+ - page: reference/changed-features/type-inference.md
+ - page: reference/changed-features/implicit-resolution.md
+ - page: reference/changed-features/implicit-conversions.md
+ - page: reference/changed-features/implicit-conversions-spec.md
+ - page: reference/changed-features/overload-resolution.md
+ - page: reference/changed-features/match-syntax.md
+ - page: reference/changed-features/vararg-splices.md
+ - page: reference/changed-features/pattern-bindings.md
+ - page: reference/changed-features/pattern-matching.md
+ - page: reference/changed-features/eta-expansion.md
+ - page: reference/changed-features/eta-expansion-spec.md
+ - page: reference/changed-features/compiler-plugins.md
+ - page: reference/changed-features/lazy-vals-init.md
+ - page: reference/changed-features/main-functions.md
- title: Dropped Features
- index: docs/reference/dropped-features/dropped-features.md
+ index: reference/dropped-features/dropped-features.md
subsection:
- - page: docs/reference/dropped-features/delayed-init.md
- - page: docs/reference/dropped-features/macros.md
- - page: docs/reference/dropped-features/existential-types.md
- - page: docs/reference/dropped-features/type-projection.md
- - page: docs/reference/dropped-features/do-while.md
- - page: docs/reference/dropped-features/procedure-syntax.md
- - page: docs/reference/dropped-features/package-objects.md
- - page: docs/reference/dropped-features/early-initializers.md
- - page: docs/reference/dropped-features/class-shadowing.md
- - page: docs/reference/dropped-features/limit22.md
- - page: docs/reference/dropped-features/xml.md
- - page: docs/reference/dropped-features/symlits.md
- - page: docs/reference/dropped-features/auto-apply.md
- - page: docs/reference/dropped-features/weak-conformance.md
- - page: docs/reference/dropped-features/nonlocal-returns.md
- - page: docs/reference/dropped-features/this-qualifier.md
- - page: docs/reference/dropped-features/wildcard-init.md
+ - page: reference/dropped-features/delayed-init.md
+ - page: reference/dropped-features/macros.md
+ - page: reference/dropped-features/existential-types.md
+ - page: reference/dropped-features/type-projection.md
+ - page: reference/dropped-features/do-while.md
+ - page: reference/dropped-features/procedure-syntax.md
+ - page: reference/dropped-features/package-objects.md
+ - page: reference/dropped-features/early-initializers.md
+ - page: reference/dropped-features/class-shadowing.md
+ - page: reference/dropped-features/class-shadowing-spec.md
+ - page: reference/dropped-features/limit22.md
+ - page: reference/dropped-features/xml.md
+ - page: reference/dropped-features/symlits.md
+ - page: reference/dropped-features/auto-apply.md
+ - page: reference/dropped-features/weak-conformance.md
+ - page: reference/dropped-features/weak-conformance-spec.md
+ - page: reference/dropped-features/nonlocal-returns.md
+ - page: reference/dropped-features/this-qualifier.md
+ - page: reference/dropped-features/wildcard-init.md
- title: Experimental Features
+ directory: experimental
subsection:
- - page: docs/reference/experimental/overview.md
- - page: docs/reference/experimental/canthrow.md
- - page: docs/reference/experimental/erased-defs.md
- - page: docs/reference/experimental/named-typeargs.md
- - page: docs/reference/experimental/numeric-literals.md
- - page: docs/reference/experimental/explicit-nulls.md
- - page: docs/reference/experimental/cc.md
- - page: docs/reference/syntax.md
+ - page: reference/experimental/overview.md
+ - page: reference/experimental/canthrow.md
+ - page: reference/experimental/erased-defs.md
+ - page: reference/experimental/erased-defs-spec.md
+ - page: reference/experimental/named-typeargs.md
+ - page: reference/experimental/named-typeargs-spec.md
+ - page: reference/experimental/numeric-literals.md
+ - page: reference/experimental/explicit-nulls.md
+ - page: reference/experimental/cc.md
+ - page: reference/syntax.md
- title: Language Versions
- index: docs/reference/language-versions/language-versions.md
+ index: reference/language-versions/language-versions.md
subsection:
- - page: docs/reference/language-versions/source-compatibility.md
- - page: docs/reference/language-versions/binary-compatibility.md
+ - page: reference/language-versions/source-compatibility.md
+ - page: reference/language-versions/binary-compatibility.md
+ - page: reference/soft-modifier.md
+ - page: reference/features-classification.md
- title: Contributing
subsection:
- - page: docs/contributing/contribute-knowledge.md
- - page: docs/contributing/getting-started.md
- - page: docs/contributing/workflow.md
- - page: docs/contributing/testing.md
- - page: docs/contributing/debugging.md
+ - page: contributing/contribute-knowledge.md
+ - page: contributing/getting-started.md
+ - page: contributing/workflow.md
+ - page: contributing/testing.md
+ - page: contributing/debugging.md
- title: IDEs and Tools
+ directory: tools
subsection:
- - page: docs/contributing/tools/ide.md
- - page: docs/contributing/tools/mill.md
- - page: docs/contributing/tools/scalafix.md
+ - page: contributing/tools/ide.md
+ - page: contributing/tools/mill.md
+ - page: contributing/tools/scalafix.md
- title: Procedures
subsection:
- - page: docs/contributing/procedures/release.md
- - page: docs/contributing/procedures/vulpix.md
+ - page: contributing/procedures/release.md
+ - page: contributing/procedures/vulpix.md
- title: Internals
subsection:
- - page: docs/internals/backend.md
- - page: docs/internals/classpaths.md
- - page: docs/internals/core-data-structures.md
- - page: docs/internals/contexts.md
- - page: docs/internals/dotc-scalac.md
- - page: docs/internals/higher-kinded-v2.md
- - page: docs/internals/overall-structure.md
- - page: docs/internals/periods.md
- - page: docs/internals/syntax.md
- - page: docs/internals/type-system.md
- - page: docs/internals/dotty-internals-1-notes.md
- - page: docs/internals/debug-macros.md
+ - page: internals/backend.md
+ - page: internals/classpaths.md
+ - page: internals/core-data-structures.md
+ - page: internals/contexts.md
+ - page: internals/dotc-scalac.md
+ - page: internals/higher-kinded-v2.md
+ - page: internals/overall-structure.md
+ - page: internals/periods.md
+ - page: internals/syntax.md
+ - page: internals/type-system.md
+ - page: internals/dotty-internals-1-notes.md
+ - page: internals/debug-macros.md
diff --git a/project/Build.scala b/project/Build.scala
index e91849fdd1d3..21321e60d6d7 100644
--- a/project/Build.scala
+++ b/project/Build.scala
@@ -326,7 +326,7 @@ object Build {
Seq(
"-skip-by-regex:.+\\.internal($|\\..+)",
"-skip-by-regex:.+\\.impl($|\\..+)",
- "-project-logo", "docs/logo.svg",
+ "-project-logo", "docs/_assets/images/logo.svg",
"-social-links:" +
"github::https://github.com/lampepfl/dotty," +
"discord::https://discord.com/invite/scala," +
diff --git a/project/DocumentationWebsite.scala b/project/DocumentationWebsite.scala
index 60a11e919e62..778c70ad2f0d 100644
--- a/project/DocumentationWebsite.scala
+++ b/project/DocumentationWebsite.scala
@@ -13,8 +13,8 @@ object DocumentationWebsite {
): Seq[File] = {
- val contributorsTestcasesDestinationFile = Paths.get("scaladoc-testcases", "docs", "js", "contributors.js").toFile
- val contributorsDestinationFile = Paths.get("docs", "js", "contributors.js").toFile
+ val contributorsTestcasesDestinationFile = Paths.get("scaladoc-testcases", "docs", "_assets", "js", "contributors.js").toFile
+ val contributorsDestinationFile = Paths.get("docs", "_assets", "js", "contributors.js").toFile
sbt.IO.copyFile(contributorsFile, contributorsTestcasesDestinationFile)
sbt.IO.copyFile(contributorsFile, contributorsDestinationFile)
@@ -25,8 +25,8 @@ object DocumentationWebsite {
val cssCodeSnippetsSourceFile = cssSourceFileBase / "code-snippets.css"
sbt.IO.copyFile(cssCodeSnippetsSourceFile, cssCodeSnippetsDesitnationFile)
- val cssContentContributorsTestcasesDesitnationFile = Paths.get("docs", "css", "content-contributors.css").toFile
- val cssContentContributorsDesitnationFile = Paths.get("scaladoc-testcases", "docs", "css", "content-contributors.css").toFile
+ val cssContentContributorsTestcasesDesitnationFile = Paths.get("docs", "_assets", "css", "content-contributors.css").toFile
+ val cssContentContributorsDesitnationFile = Paths.get("scaladoc-testcases", "docs", "_assets", "css", "content-contributors.css").toFile
val cssContentContributorsSourceFile = cssContentContributorsSourceBaseFile / "content-contributors.css"
sbt.IO.copyFile(cssContentContributorsSourceFile, cssContentContributorsTestcasesDesitnationFile)
sbt.IO.copyFile(cssContentContributorsSourceFile, cssContentContributorsDesitnationFile)
diff --git a/project/scripts/cmdScaladocTests b/project/scripts/cmdScaladocTests
index ce8d310fb248..ff25bc6a3940 100755
--- a/project/scripts/cmdScaladocTests
+++ b/project/scripts/cmdScaladocTests
@@ -29,7 +29,7 @@ dist/target/pack/bin/scaladoc \
"-external-mappings:.*scala/.*::scaladoc3::https://dotty.epfl.ch/api/,.*java/.*::javadoc::https://docs.oracle.com/javase/8/docs/api/" \
"-skip-by-regex:.+\.internal($|\..+)" \
"-skip-by-regex:.+\.impl($|\..+)" \
- -project-logo docs/logo.svg \
+ -project-logo docs/_assets/images/logo.svg \
-social-links:github::https://github.com/lampepfl/dotty,discord::https://discord.com/invite/scala,twitter::https://twitter.com/scala_lang \
-Ygenerate-inkuire \
"-skip-by-id:scala.runtime.stdLibPatches" \
diff --git a/scaladoc-testcases/docs/css/bootstrap.min.css b/scaladoc-testcases/docs/_assets/css/bootstrap.min.css
similarity index 100%
rename from scaladoc-testcases/docs/css/bootstrap.min.css
rename to scaladoc-testcases/docs/_assets/css/bootstrap.min.css
diff --git a/scaladoc-testcases/docs/docs/docs/f1.md b/scaladoc-testcases/docs/_docs/docs/f1.md
similarity index 100%
rename from scaladoc-testcases/docs/docs/docs/f1.md
rename to scaladoc-testcases/docs/_docs/docs/f1.md
diff --git a/scaladoc-testcases/docs/docs/docs/f2.md b/scaladoc-testcases/docs/_docs/docs/f2.md
similarity index 100%
rename from scaladoc-testcases/docs/docs/docs/f2.md
rename to scaladoc-testcases/docs/_docs/docs/f2.md
diff --git a/scaladoc-testcases/docs/docs/docs/f3.md b/scaladoc-testcases/docs/_docs/docs/f3.md
similarity index 100%
rename from scaladoc-testcases/docs/docs/docs/f3.md
rename to scaladoc-testcases/docs/_docs/docs/f3.md
diff --git a/scaladoc-testcases/docs/docs/docs/f4.md b/scaladoc-testcases/docs/_docs/docs/f4.md
similarity index 100%
rename from scaladoc-testcases/docs/docs/docs/f4.md
rename to scaladoc-testcases/docs/_docs/docs/f4.md
diff --git a/scaladoc-testcases/docs/docs/index.md b/scaladoc-testcases/docs/_docs/index.md
similarity index 100%
rename from scaladoc-testcases/docs/docs/index.md
rename to scaladoc-testcases/docs/_docs/index.md
diff --git a/scaladoc-testcases/docs/sidebar.yml b/scaladoc-testcases/docs/sidebar.yml
index 6ab7a4936ede..51f8e87f2ad6 100644
--- a/scaladoc-testcases/docs/sidebar.yml
+++ b/scaladoc-testcases/docs/sidebar.yml
@@ -1,7 +1,6 @@
-sidebar:
- - title: Docs
- subsection:
- - page: docs/docs/f1.md
- - page: docs/docs/f2.md
- - page: docs/docs/f3.md
- - page: docs/docs/f4.md
+index: index.md
+subsection:
+ - page: docs/f1.md
+ - page: docs/f2.md
+ - page: docs/f3.md
+ - page: docs/f4.md
diff --git a/scaladoc-testcases/src/docs/tests/Adoc.scala b/scaladoc-testcases/src/_docs/tests/Adoc.scala
similarity index 59%
rename from scaladoc-testcases/src/docs/tests/Adoc.scala
rename to scaladoc-testcases/src/_docs/tests/Adoc.scala
index af93f9eddfa0..04b2c3918023 100644
--- a/scaladoc-testcases/src/docs/tests/Adoc.scala
+++ b/scaladoc-testcases/src/_docs/tests/Adoc.scala
@@ -1,4 +1,4 @@
-package docs.tests
+package _docs.tests
class Adoc:
def foo = 123
diff --git a/scaladoc/src/dotty/tools/scaladoc/renderers/HtmlRenderer.scala b/scaladoc/src/dotty/tools/scaladoc/renderers/HtmlRenderer.scala
index b743163eaaf7..d71fe03a9c13 100644
--- a/scaladoc/src/dotty/tools/scaladoc/renderers/HtmlRenderer.scala
+++ b/scaladoc/src/dotty/tools/scaladoc/renderers/HtmlRenderer.scala
@@ -31,32 +31,29 @@ class HtmlRenderer(rootPackage: Member, members: Map[DRI, Member])(using ctx: Do
val renderedResources = renderResources()
super.render()
- private def specificResources(page: Page): Set[String] =
- page.children.toSet.flatMap(specificResources) ++ (page.content match
- case r: ResolvedTemplate =>
- r.resolved.resources.toSet
- case _ => Set.empty
- )
-
private def renderResources(): Seq[String] =
- def siteRoot = staticSite.get.root.toPath
- def pathToResource(p: String) = Resource.File(p, siteRoot.resolve(p))
-
- def harvestResources(path: String) =
- val siteImgPath = siteRoot.resolve(path)
- if !Files.exists(siteImgPath) then Nil
- else
- val allPaths = Files.walk(siteImgPath, FileVisitOption.FOLLOW_LINKS)
- val files = allPaths.filter(Files.isRegularFile(_)).iterator().asScala
- files.map(p => siteRoot.relativize(p).toString).toList
-
- val staticResources = staticSite.toSeq.flatMap { _ =>
- harvestResources("images") ++ harvestResources("resources")
- }
-
- val siteResourcesPaths = allPages.toSet.flatMap(specificResources) ++ staticResources
-
- val resources = siteResourcesPaths.toSeq.map(pathToResource) ++ allResources(allPages) ++ onlyRenderedResources
+ import scala.util.Using
+ import scala.jdk.CollectionConverters._
+ // All static site resources need to be in _assets folder
+ val staticSiteResources = staticSite
+ .map(_.root.toPath.resolve("_assets").toFile)
+ .filter(f => f.exists && f.isDirectory)
+ .toSeq
+ .flatMap { resourceFile =>
+ resourceFile.listFiles.toSeq.map(_.toPath).flatMap { file =>
+ Using(Files.walk(file)) { stream =>
+ stream.iterator().asScala.toSeq
+ .map(from => Resource.File(resourceFile.toPath.relativize(from).toString, from))
+ }.fold (
+ { t =>
+ report.warn(s"Error occured while processing _assets file.", t)
+ Seq.empty
+ },
+ identity
+ )
+ }
+ }
+ val resources = staticSiteResources ++ allResources(allPages) ++ onlyRenderedResources
resources.flatMap(renderResource)
def mkHead(page: Page): AppliedTag =
@@ -124,7 +121,7 @@ class HtmlRenderer(rootPackage: Member, members: Map[DRI, Member])(using ctx: Do
)
)
- nav.children match
+ nav.children.filterNot(_.hidden) match
case Nil => isSelected -> div(cls := s"ni ${if isSelected then "expanded" else ""}")(linkHtml())
case children =>
val nested = children.map(renderNested(_))
diff --git a/scaladoc/src/dotty/tools/scaladoc/renderers/Locations.scala b/scaladoc/src/dotty/tools/scaladoc/renderers/Locations.scala
index bcdaa2bb5a5a..1c55cb8124e1 100644
--- a/scaladoc/src/dotty/tools/scaladoc/renderers/Locations.scala
+++ b/scaladoc/src/dotty/tools/scaladoc/renderers/Locations.scala
@@ -34,9 +34,8 @@ trait Locations(using ctx: DocContext):
cache.get(dri) match
case null =>
val path = dri match
- case `docsRootDRI` => List("docs", "index")
case `apiPageDRI` =>
- if ctx.staticSiteContext.fold(false)(_.hasIndexFile)
+ if ctx.args.apiSubdirectory && ctx.staticSiteContext.nonEmpty
then List("api", "index")
else List("index")
case dri if dri.isStaticFile =>
@@ -88,6 +87,6 @@ trait Locations(using ctx: DocContext):
def pathToRoot(dri: DRI): String = rawLocation(dri).drop(1).map(_ => "..") match
case Nil => ""
- case seq => seq.mkString("", "/", "/")
+ case seq => seq.mkString("", "/" , "/")
def driExists(dri: DRI) = effectiveMembers.get(dri).isDefined || dri.isStaticFile
diff --git a/scaladoc/src/dotty/tools/scaladoc/renderers/Renderer.scala b/scaladoc/src/dotty/tools/scaladoc/renderers/Renderer.scala
index d0b51bf54e6f..45a080d4828a 100644
--- a/scaladoc/src/dotty/tools/scaladoc/renderers/Renderer.scala
+++ b/scaladoc/src/dotty/tools/scaladoc/renderers/Renderer.scala
@@ -15,7 +15,7 @@ import java.nio.file.Files
import java.nio.file.FileVisitOption
import java.io.File
-case class Page(link: Link, content: Member | ResolvedTemplate | String, children: Seq[Page]):
+case class Page(link: Link, content: Member | ResolvedTemplate | String, children: Seq[Page], hidden: Boolean = false):
def withNewChildren(newChildren: Seq[Page]) = copy(children = children ++ newChildren)
def withTitle(newTitle: String) = copy(link = link.copy(name = newTitle))
@@ -40,20 +40,12 @@ abstract class Renderer(rootPackage: Member, val members: Map[DRI, Member], prot
staticSite match
case None => rootPckPage.withTitle(args.name)
case Some(siteContext) =>
- val (indexes, templates) = siteContext.templates.partition(f =>
- f.templateFile.isIndexPage() && f.file.toPath.getParent() == siteContext.docsPath)
- if (indexes.size > 1)
- val msg = s"ERROR: Multiple index pages for doc found ${indexes.map(_.file)}"
- report.error(msg)
+ val rootTemplate = siteContext.staticSiteRoot.rootTemplate
// Below code is for walking in order the tree and modifing its nodes basing on its neighbours
- // First we flatten templates to get them sorted in-order
- def flattenedTemplates(template: LoadedTemplate): Seq[LoadedTemplate] =
- template +: template.children.flatMap(flattenedTemplates)
-
// We add dummy guards
- val allTemplates: Seq[Option[LoadedTemplate]] = None +: templates.flatMap(flattenedTemplates).map(Some(_)) :+ None
+ val allTemplates: Seq[Option[LoadedTemplate]] = None +: siteContext.allTemplates.map(Some(_)) :+ None
// Let's gather the list of maps for each template with its in-order neighbours
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
)
updatedTemplates.result()
- val newTemplates = updateSettings(templates, newSettings.to(ListBuffer))
+ val newTemplates = updateSettings(Seq(rootTemplate), newSettings.to(ListBuffer))
val templatePages = newTemplates.map(templateToPage(_, siteContext))
- indexes.headOption match
- case None if templatePages.isEmpty=>
- rootPckPage.withTitle(args.name)
- case None =>
- Page(Link(args.name, docsRootDRI),"", templatePages :+ rootPckPage.withTitle("API"))
- case Some(indexPage) =>
- val newChildren = templatePages :+ rootPckPage.withTitle("API")
- templateToPage(indexPage, siteContext).withNewChildren(newChildren)
-
- val hiddenPages: Seq[Page] =
- staticSite match
- case None =>
- Seq(navigablePage.copy( // Add index page that is a copy of api/index.html
- link = navigablePage.link.copy(dri = docsRootDRI),
- children = Nil
- ))
- case Some(siteContext) =>
- // In case that we do not have an index page and we do not have any API entries
- // we want to create empty index page, so there is one
- val actualIndexTemplate = siteContext.indexTemplate() match {
- case None if effectiveMembers.isEmpty => Seq(siteContext.emptyIndexTemplate)
- case templates => templates.toSeq
- }
+ val newRoot = newTemplates.head
- (siteContext.orphanedTemplates ++ actualIndexTemplate).map(templateToPage(_, siteContext))
+ if newRoot.children.isEmpty && newRoot.templateFile.rawCode.isEmpty
+ then rootPckPage.withTitle(args.name)
+ else {
+ val newRootPage = templateToPage(newRoot, siteContext)
+ newRootPage.withNewChildren(Seq(rootPckPage.withTitle("API")))
+ }
val redirectPages: Seq[Page] = staticSite.fold(Seq.empty)(siteContext => siteContext.redirectTemplates.map {
case (template, driFrom, driTo) =>
@@ -121,22 +96,10 @@ abstract class Renderer(rootPackage: Member, val members: Map[DRI, Member], prot
* Here we have to retrive index pages from hidden pages and replace fake index pages in navigable page tree.
*/
val allPages: Seq[Page] =
- def traversePages(page: Page): (Page, Seq[Page]) =
- val (newChildren, newPagesToRemove): (Seq[Page], Seq[Page]) = page.children.map(traversePages(_)).foldLeft((Seq[Page](), Seq[Page]())) {
- case ((pAcc, ptrAcc), (p, ptr)) => (pAcc :+ p, ptrAcc ++ ptr)
- }
- hiddenPages.find(_.link == page.link) match
- case None =>
- (page.copy(children = newChildren), newPagesToRemove)
- case Some(newPage) =>
- (newPage.copy(children = newChildren), newPagesToRemove :+ newPage)
-
- val (newNavigablePage, pagesToRemove) = traversePages(navigablePage)
-
- val all = newNavigablePage +: (hiddenPages.filterNot(pagesToRemove.contains) ++ redirectPages)
- // We need to check for conflicts only if we have top-level member called blog or docs
+ val all = navigablePage +: redirectPages
+ // We need to check for conflicts only if we have top-level member called docs
val hasPotentialConflict =
- rootPackage.members.exists(m => m.name.startsWith("docs") || m.name.startsWith("blog"))
+ rootPackage.members.exists(m => m.name.startsWith("_docs"))
if hasPotentialConflict then
def walk(page: Page): Unit =
diff --git a/scaladoc/src/dotty/tools/scaladoc/renderers/SiteRenderer.scala b/scaladoc/src/dotty/tools/scaladoc/renderers/SiteRenderer.scala
index 566ccd81ab62..ad97b19fbb24 100644
--- a/scaladoc/src/dotty/tools/scaladoc/renderers/SiteRenderer.scala
+++ b/scaladoc/src/dotty/tools/scaladoc/renderers/SiteRenderer.scala
@@ -22,7 +22,7 @@ trait SiteRenderer(using DocContext) extends Locations:
def templateToPage(t: LoadedTemplate, staticSiteCtx: StaticSiteContext): Page =
val dri = staticSiteCtx.driFor(t.file.toPath)
val content = ResolvedTemplate(t, staticSiteCtx)
- Page(Link(t.templateFile.title.name, dri), content, t.children.map(templateToPage(_, staticSiteCtx)))
+ Page(Link(t.templateFile.title.name, dri), content, t.children.map(templateToPage(_, staticSiteCtx)), t.hidden)
private val HashRegex = "([^#]+)(#.+)".r
@@ -37,18 +37,28 @@ trait SiteRenderer(using DocContext) extends Locations:
res.headOption.map(pathToPage(pageDri, _) + prefix)
def processLocalLink(str: String): String =
- Try(URL(str)).map(_ => str).toOption.orElse {
- tryAsDri(str)
- }.orElse {
- Option.when(
- Files.exists(Paths.get(content.ctx.root.toPath.toAbsolutePath.toString, str))
- )(
- resolveLink(pageDri, str.stripPrefix("/"))
- )
- }.getOrElse {
- report.warn(s"Unable to resolve link '$str'", content.template.file)
- str
- }
+ val staticSiteRootPath = content.ctx.root.toPath.toAbsolutePath
+ def asValidURL: Option[String] = Try(URL(str)).toOption.map(_ => str)
+ def asAsset: Option[String] = Option.when(
+ Files.exists(staticSiteRootPath.resolve("_assets").resolve(str.stripPrefix("/")))
+ )(
+ resolveLink(pageDri, str.stripPrefix("/"))
+ )
+ def asStaticSite: Option[String] = tryAsDri(str)
+
+ /* Link resolving checks performs multiple strategies with following priority:
+ 1. We check if the link is a valid URL e.g. http://dotty.epfl.ch
+ 2. We check if the link leads to other static site
+ 3. We check if the link leads to existing asset e.g. images/logo.svg ->