Skip to content

Commit 23336c0

Browse files
committed
Introduce generation config for Scaladoc
1 parent 1476a30 commit 23336c0

File tree

3 files changed

+338
-86
lines changed

3 files changed

+338
-86
lines changed

library/src/scala/quoted/Exprs.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ object Exprs:
55
/** Matches literal sequence of literal constant value expressions and return a sequence of values.
66
*
77
* Usage:
8-
* ```scala
8+
* ```scala sc:nocompile
99
* inline def sum(args: Int*): Int = ${ sumExpr('args) }
1010
* def sumExpr(argsExpr: Expr[Seq[Int]])(using Quotes): Expr[Int] = argsExpr match
1111
* case Varargs(Exprs(args)) =>

project/Build.scala

Lines changed: 156 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import java.io.File
22
import java.nio.file._
33

44
import Modes._
5+
import ScaladocGeneration._
56
import com.jsuereth.sbtpgp.PgpKeys
67
import sbt.Keys._
78
import sbt._
@@ -59,6 +60,8 @@ object DottyJSPlugin extends AutoPlugin {
5960
}
6061

6162
object Build {
63+
import ScaladocConfigs._
64+
6265
val referenceVersion = "3.1.2-RC1"
6366

6467
val baseVersion = "3.1.3-RC1"
@@ -1287,39 +1290,15 @@ object Build {
12871290
libraryDependencies += ("org.scala-js" %%% "scalajs-dom" % "1.1.0").cross(CrossVersion.for3Use2_13)
12881291
)
12891292

1290-
def generateDocumentation(targets: Seq[String], name: String, outDir: String, ref: String, params: Seq[String] = Nil, includeExternalMappings: Boolean = true) =
1293+
def generateDocumentation(configTask: Def.Initialize[Task[GenerationConfig]]) =
12911294
Def.taskDyn {
1292-
val distLocation = (dist / pack).value
1293-
val projectVersion = version.value
1294-
IO.createDirectory(file(outDir))
1295-
val stdLibVersion = stdlibVersion(NonBootstrapped)
1296-
val scalaLib = findArtifactPath(externalCompilerClasspathTask.value, "scala-library")
1297-
val dottyLib = (`scala3-library` / Compile / classDirectory).value
1298-
// TODO add versions etc.
1299-
def srcManaged(v: String, s: String) = s"out/bootstrap/stdlib-bootstrapped/scala-$v/src_managed/main/$s-library-src"
1300-
def scalaSrcLink(v: String, s: String) = s"-source-links:${s}github://scala/scala/v$v#src/library"
1301-
def dottySrcLink(v: String, sourcesPrefix: String = "", outputPrefix: String = "") =
1302-
sys.env.get("GITHUB_SHA") match {
1303-
case Some(sha) =>
1304-
s"-source-links:${sourcesPrefix}github://${sys.env("GITHUB_REPOSITORY")}/$sha$outputPrefix"
1305-
case None => s"-source-links:${sourcesPrefix}github://lampepfl/dotty/$v$outputPrefix"
1306-
}
1307-
1308-
val revision = Seq("-revision", ref, "-project-version", projectVersion)
1309-
val cmd = Seq(
1310-
"-d",
1311-
outDir,
1312-
"-project",
1313-
name,
1314-
scalaSrcLink(stdLibVersion, srcManaged(dottyNonBootstrappedVersion, "scala") + "="),
1315-
dottySrcLink(referenceVersion, srcManaged(dottyNonBootstrappedVersion, "dotty") + "=", "#library/src"),
1316-
dottySrcLink(referenceVersion),
1317-
"-Ygenerate-inkuire",
1318-
) ++ scalacOptionsDocSettings(includeExternalMappings) ++ revision ++ params ++ targets
1319-
import _root_.scala.sys.process._
1320-
val escapedCmd = cmd.map(arg => if(arg.contains(" ")) s""""$arg"""" else arg)
1295+
val config = configTask.value
1296+
config.get[OutputDir].foreach { outDir =>
1297+
IO.createDirectory(file(outDir.value))
1298+
}
1299+
val command = generateCommand(config)
13211300
Def.task {
1322-
(Compile / run).toTask(escapedCmd.mkString(" ", " ", "")).value
1301+
(Compile / run).toTask(command).value
13231302
}
13241303
}
13251304

@@ -1363,66 +1342,40 @@ object Build {
13631342
Test / testcasesSourceRoot := ((`scaladoc-testcases` / baseDirectory).value / "src").getAbsolutePath.toString,
13641343
run / baseDirectory := (ThisBuild / baseDirectory).value,
13651344
generateSelfDocumentation := Def.taskDyn {
1366-
generateDocumentation(
1367-
(Compile / classDirectory).value.getAbsolutePath :: Nil,
1368-
"scaladoc", "scaladoc/output/self", VersionUtil.gitHash, Seq("-usejavacp")
1369-
)
1345+
generateDocumentation(Scaladoc)
13701346
}.value,
1347+
13711348
generateScalaDocumentation := Def.inputTaskDyn {
1372-
val extraArgs = spaceDelimited("[output]").parsed
1373-
val dest = file(extraArgs.headOption.getOrElse("scaladoc/output/scala3")).getAbsoluteFile
1374-
val justAPI = extraArgs.drop(1).headOption == Some("--justAPI")
13751349
val majorVersion = (LocalProject("scala3-library-bootstrapped") / scalaBinaryVersion).value
1376-
val dottyJars: Seq[java.io.File] = Seq(
1377-
(`stdlib-bootstrapped`/Compile/products).value,
1378-
(`scala3-interfaces`/Compile/products).value,
1379-
(`tasty-core-bootstrapped`/Compile/products).value,
1380-
).flatten
1381-
1382-
val roots = dottyJars.map(_.getAbsolutePath)
1383-
1384-
val managedSources =
1385-
(`stdlib-bootstrapped`/Compile/sourceManaged).value / "scala-library-src"
1386-
val projectRoot = (ThisBuild/baseDirectory).value.toPath
1387-
val stdLibRoot = projectRoot.relativize(managedSources.toPath.normalize())
1388-
val docRootFile = stdLibRoot.resolve("rootdoc.txt")
1389-
1390-
val dottyManagesSources =
1391-
(`stdlib-bootstrapped`/Compile/sourceManaged).value / "dotty-library-src"
1392-
1393-
val dottyLibRoot = projectRoot.relativize(dottyManagesSources.toPath.normalize())
1394-
1395-
def generateDocTask =
1396-
generateDocumentation(
1397-
roots, "Scala 3", dest.getAbsolutePath, "main",
1398-
Seq(
1399-
"-comment-syntax", "wiki",
1400-
s"-source-links:docs=github://lampepfl/dotty/main#docs",
1401-
"-doc-root-content", docRootFile.toString,
1402-
"-versions-dictionary-url",
1403-
"https://scala-lang.org/api/versions.json",
1404-
"-Ydocument-synthetic-types",
1405-
s"-snippet-compiler:${dottyLibRoot}/scala/quoted=compile,${dottyLibRoot}/scala/compiletime=compile"
1406-
) ++ (if (justAPI) Nil else Seq("-siteroot", "docs", "-Yapi-subdirectory")), includeExternalMappings = false)
1407-
1408-
if (dottyJars.isEmpty) Def.task { streams.value.log.error("Dotty lib wasn't found") }
1409-
else if (justAPI) generateDocTask
1410-
else Def.task{
1411-
IO.write(dest / "versions" / "latest-nightly-base", majorVersion)
1412-
1413-
// This file is used by GitHub Pages when the page is available in a custom domain
1414-
IO.write(dest / "CNAME", "dotty.epfl.ch")
1415-
}.dependsOn(generateDocTask)
1350+
1351+
val extraArgs = spaceDelimited("[<output-dir>] [--justAPI]").parsed
1352+
val outputDirOverride = extraArgs.headOption.fold(identity[GenerationConfig](_))(newDir => {
1353+
config: GenerationConfig => config.add(OutputDir(newDir))
1354+
})
1355+
val justAPIArg: Option[String] = extraArgs.drop(1).find(_ == "--justAPI")
1356+
val justAPI = justAPIArg.fold(identity[GenerationConfig](_))(_ => {
1357+
config: GenerationConfig => config.remove[SiteRoot]
1358+
})
1359+
val overrideFunc = outputDirOverride.andThen(justAPI)
1360+
1361+
val config = Def.task {
1362+
overrideFunc(Scala3.value)
1363+
}
1364+
1365+
val writeAdditionalFiles = Def.task {
1366+
val dest = file(config.value.get[OutputDir].get.value)
1367+
if (justAPIArg.isEmpty) {
1368+
IO.write(dest / "versions" / "latest-nightly-base", majorVersion)
1369+
// This file is used by GitHub Pages when the page is available in a custom domain
1370+
IO.write(dest / "CNAME", "dotty.epfl.ch")
1371+
}
1372+
}
1373+
1374+
writeAdditionalFiles.dependsOn(generateDocumentation(config))
14161375
}.evaluated,
14171376

14181377
generateTestcasesDocumentation := Def.taskDyn {
1419-
generateDocumentation(
1420-
(Test / Build.testcasesOutputDir).value,
1421-
"scaladoc testcases",
1422-
"scaladoc/output/testcases",
1423-
"main",
1424-
Seq("-usejavacp", "-snippet-compiler:scaladoc-testcases/docs=compile", "-siteroot", "scaladoc-testcases/docs")
1425-
)
1378+
generateDocumentation(Testcases)
14261379
}.value,
14271380

14281381
Test / buildInfoKeys := Seq[BuildInfoKey](
@@ -1803,3 +1756,121 @@ object Build {
18031756
})
18041757
}
18051758
}
1759+
1760+
object ScaladocConfigs {
1761+
import Build._
1762+
private lazy val currentYear: String = java.util.Calendar.getInstance().get(java.util.Calendar.YEAR).toString
1763+
1764+
def dottyExternalMapping = ".*scala/.*::scaladoc3::https://dotty.epfl.ch/api/"
1765+
def javaExternalMapping = ".*java/.*::javadoc::https://docs.oracle.com/javase/8/docs/api/"
1766+
1767+
lazy val DefaultGenerationConfig = Def.task {
1768+
def distLocation = (dist / pack).value
1769+
def projectVersion = version.value
1770+
def stdLibVersion = stdlibVersion(NonBootstrapped)
1771+
def scalaLib = findArtifactPath(externalCompilerClasspathTask.value, "scala-library")
1772+
def dottyLib = (`scala3-library` / Compile / classDirectory).value
1773+
def srcManaged(v: String, s: String) = s"out/bootstrap/stdlib-bootstrapped/scala-$v/src_managed/main/$s-library-src"
1774+
def scalaSrcLink(v: String, s: String) = s"${s}github://scala/scala/v$v#src/library"
1775+
def dottySrcLink(v: String, sourcesPrefix: String = "", outputPrefix: String = "") =
1776+
sys.env.get("GITHUB_SHA") match {
1777+
case Some(sha) =>
1778+
s"${sourcesPrefix}github://${sys.env("GITHUB_REPOSITORY")}/$sha$outputPrefix"
1779+
case None => s"${sourcesPrefix}github://lampepfl/dotty/$v$outputPrefix"
1780+
}
1781+
1782+
def defaultSourceLinks: SourceLinks = SourceLinks(
1783+
List(
1784+
scalaSrcLink(stdLibVersion, srcManaged(dottyNonBootstrappedVersion, "scala") + "="),
1785+
dottySrcLink(referenceVersion, srcManaged(dottyNonBootstrappedVersion, "dotty") + "=", "#library/src"),
1786+
dottySrcLink(referenceVersion)
1787+
)
1788+
)
1789+
def socialLinks = SocialLinks(List(
1790+
"github::https://github.com/lampepfl/dotty",
1791+
"discord::https://discord.com/invite/scala",
1792+
"twitter::https://twitter.com/scala_lang",
1793+
))
1794+
def projectLogo = ProjectLogo("docs/_assets/images/logo.svg")
1795+
def skipByRegex = SkipByRegex(List(".+\\.internal($|\\..+)", ".+\\.impl($|\\..+)"))
1796+
def skipById = SkipById(List(
1797+
"scala.runtime.stdLibPatches",
1798+
"scala.runtime.MatchCase"
1799+
))
1800+
def projectFooter = ProjectFooter(s"Copyright (c) 2002-$currentYear, LAMP/EPFL")
1801+
def defaultTemplate = DefaultTemplate("static-site-main")
1802+
GenerationConfig(
1803+
List(),
1804+
ProjectVersion(projectVersion),
1805+
GenerateInkuire(true),
1806+
defaultSourceLinks,
1807+
skipByRegex,
1808+
skipById,
1809+
projectLogo,
1810+
socialLinks,
1811+
projectFooter,
1812+
defaultTemplate,
1813+
Author(true),
1814+
Groups(true)
1815+
)
1816+
}
1817+
1818+
lazy val Scaladoc = Def.task {
1819+
DefaultGenerationConfig.value
1820+
.add(UseJavacp(true))
1821+
.add(ProjectName("scaladoc"))
1822+
.add(OutputDir("scaladoc/output/self"))
1823+
.add(Revision(VersionUtil.gitHash))
1824+
.add(ExternalMappings(List(dottyExternalMapping, javaExternalMapping)))
1825+
.withTargets((Compile / classDirectory).value.getAbsolutePath :: Nil)
1826+
}
1827+
1828+
lazy val Testcases = Def.task {
1829+
val tastyRoots = (Test / Build.testcasesOutputDir).value
1830+
DefaultGenerationConfig.value
1831+
.add(UseJavacp(true))
1832+
.add(OutputDir("scaladoc/output/testcases"))
1833+
.add(ProjectName("scaladoc testcases"))
1834+
.add(Revision("main"))
1835+
.add(SnippetCompiler(List("scaladoc-testcases/docs=compile")))
1836+
.add(SiteRoot("scaladoc-testcases/docs"))
1837+
.add(ExternalMappings(List(dottyExternalMapping, javaExternalMapping)))
1838+
.withTargets(tastyRoots)
1839+
}
1840+
1841+
lazy val Scala3 = Def.task {
1842+
val dottyJars: Seq[java.io.File] = Seq(
1843+
(`stdlib-bootstrapped`/Compile/products).value,
1844+
(`scala3-interfaces`/Compile/products).value,
1845+
(`tasty-core-bootstrapped`/Compile/products).value,
1846+
).flatten
1847+
1848+
val roots = dottyJars.map(_.getAbsolutePath)
1849+
1850+
val managedSources =
1851+
(`stdlib-bootstrapped`/Compile/sourceManaged).value / "scala-library-src"
1852+
val projectRoot = (ThisBuild/baseDirectory).value.toPath
1853+
val stdLibRoot = projectRoot.relativize(managedSources.toPath.normalize())
1854+
val docRootFile = stdLibRoot.resolve("rootdoc.txt")
1855+
1856+
val dottyManagesSources =
1857+
(`stdlib-bootstrapped`/Compile/sourceManaged).value / "dotty-library-src"
1858+
1859+
val dottyLibRoot = projectRoot.relativize(dottyManagesSources.toPath.normalize())
1860+
DefaultGenerationConfig.value
1861+
.add(ProjectName("Scala 3"))
1862+
.add(OutputDir(file("scaladoc/output/scala3").getAbsoluteFile.getAbsolutePath))
1863+
.add(Revision("main"))
1864+
.add(ExternalMappings(List(javaExternalMapping)))
1865+
.add(DocRootContent(docRootFile.toString))
1866+
.add(VersionsDictionaryUrl("https://scala-lang.org/api/versions.json"))
1867+
.add(DocumentSyntheticTypes(true))
1868+
.add(SnippetCompiler(List(
1869+
s"${dottyLibRoot}/scala/quoted=compile",
1870+
s"${dottyLibRoot}/scala/compiletime=compile"
1871+
)))
1872+
.add(SiteRoot("docs"))
1873+
.add(ApiSubdirectory(true))
1874+
.withTargets(roots)
1875+
}
1876+
}

0 commit comments

Comments
 (0)