Skip to content

Commit 93f412a

Browse files
authored
Merge pull request #10812 from romanowski/scala3doc/before-m3
Scala3doc/before m3
2 parents e13a99a + 76d33a1 commit 93f412a

13 files changed

+163
-208
lines changed

project/Build.scala

+15-17
Original file line numberDiff line numberDiff line change
@@ -1528,14 +1528,9 @@ object Build {
15281528
def generateDocumentation(targets: String, name: String, outDir: String, ref: String, params: String = "") = Def.taskDyn {
15291529
val projectVersion = version.value
15301530
IO.createDirectory(file(outDir))
1531-
val managedSources =
1532-
(`stdlib-bootstrapped`/Compile/sourceManaged).value / "scala-library-src"
1533-
val projectRoot = (ThisBuild/baseDirectory).value.toPath
1534-
val stdLibRoot = projectRoot.relativize(managedSources.toPath.normalize())
1535-
val scalaSourceLink =
1536-
s"$stdLibRoot=github://scala/scala/v${stdlibVersion(Bootstrapped)}#src/library"
1537-
val sourcesAndRevision = s"-source-links $scalaSourceLink,github://lampepfl/dotty -revision $ref -project-version $projectVersion"
1538-
val cmd = s""" -d $outDir -project "$name" $sourcesAndRevision $params $targets"""
1531+
val sourceLinks = "-source-links:github://lampepfl/dotty "
1532+
val revision = s"-revision $ref -project-version $projectVersion"
1533+
val cmd = s""" -d $outDir -project "$name" $sourceLinks $revision $params $targets"""
15391534
run.in(Compile).toTask(cmd)
15401535
}
15411536

@@ -1575,12 +1570,9 @@ object Build {
15751570
classDirectory.in(Compile).value.getAbsolutePath,
15761571
"scala3doc", "scala3doc/output/self", VersionUtil.gitHash,
15771572
"-siteroot scala3doc/documentation -project-logo scala3doc/documentation/logo.svg " +
1578-
"-external-mappings " + raw".*scala.*" + "::" +
1579-
"scala3doc" + "::" +
1580-
"http://dotty.epfl.ch/api/" + ":::" +
1581-
raw".*java.*" + "::" +
1582-
"javadoc" + "::" +
1583-
"https://docs.oracle.com/javase/8/docs/api/"
1573+
"-external-mappings:" +
1574+
".*scala.*::scala3doc::http://dotty.epfl.ch/api/," +
1575+
".*java.*::javadoc::https://docs.oracle.com/javase/8/docs/api/"
15841576
)
15851577
}.value,
15861578

@@ -1597,6 +1589,12 @@ object Build {
15971589

15981590
val roots = joinProducts(dottyJars)
15991591

1592+
val managedSources =
1593+
(`stdlib-bootstrapped`/Compile/sourceManaged).value / "scala-library-src"
1594+
val projectRoot = (ThisBuild/baseDirectory).value.toPath
1595+
val stdLibRoot = projectRoot.relativize(managedSources.toPath.normalize())
1596+
val docRootFile = stdLibRoot.resolve("rootdoc.txt")
1597+
16001598
if (dottyJars.isEmpty) Def.task { streams.value.log.error("Dotty lib wasn't found") }
16011599
else Def.task{
16021600
IO.write(dest / "versions" / "latest-nightly-base", majorVersion)
@@ -1615,9 +1613,9 @@ object Build {
16151613
"-skip-by-regex:.+\\.internal($|\\..+) " +
16161614
"-skip-by-regex:.+\\.impl($|\\..+) " +
16171615
"-comment-syntax wiki -siteroot scala3doc/scala3-docs -project-logo scala3doc/scala3-docs/logo.svg " +
1618-
"-external-mappings " + raw".*java.*" + "::" +
1619-
"javadoc" + "::" +
1620-
"https://docs.oracle.com/javase/8/docs/api/"
1616+
"-external-mappings:.*java.*::javadoc::https://docs.oracle.com/javase/8/docs/api/ " +
1617+
s"-source-links:$stdLibRoot=github://scala/scala/v${stdlibVersion(Bootstrapped)}#src/library " +
1618+
s"-doc-root-content $docRootFile"
16211619
))
16221620
}.evaluated,
16231621

scala3doc/src/dotty/dokka/DocContext.scala

+4-45
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ extension (r: report.type)
6969
def warn(m: String, f: File)(using CompilerContext): Unit =
7070
r.warning(createMessage(m, f, null), sourcePostionFor(f))
7171

72+
def warn(m: String, e: Throwable)(using CompilerContext): Unit =
73+
r.warning(s"$m: ${throwableToString(e)}")
74+
7275
case class NavigationNode(name: String, dri: DRI, nested: Seq[NavigationNode])
7376

7477
case class DocContext(args: Scala3doc.Args, compilerContext: CompilerContext)
@@ -99,51 +102,7 @@ case class DocContext(args: Scala3doc.Args, compilerContext: CompilerContext)
99102
sourceLinks
100103
)(using compilerContext))
101104

102-
def parseDocTool(docTool: String) = docTool match {
103-
case "scaladoc" => Some(DocumentationKind.Scaladoc)
104-
case "scala3doc" => Some(DocumentationKind.Scala3doc)
105-
case "javadoc" => Some(DocumentationKind.Javadoc)
106-
case other => None
107-
}
108-
val externalDocumentationLinks: List[Scala3docExternalDocumentationLink] = args.externalMappings.filter(_.size >= 3).flatMap { mapping =>
109-
val regexStr = mapping(0)
110-
val docTool = mapping(1)
111-
val urlStr = mapping(2)
112-
val packageListUrlStr = if mapping.size > 3 then Some(mapping(3)) else None
113-
val regex = Try(regexStr.r).toOption
114-
val url = Try(URL(urlStr)).toOption
115-
val packageListUrl = Try(packageListUrlStr.map(URL(_)))
116-
.fold(
117-
e => {
118-
logger.warn(s"Wrong packageListUrl parameter in external mapping. Found '$packageListUrlStr'. " +
119-
s"Package list url will be omitted")
120-
None},
121-
res => res
122-
)
123-
124-
val parsedDocTool = parseDocTool(docTool)
125-
val res = if regexStr.isEmpty then
126-
logger.warn(s"Wrong regex parameter in external mapping. Found '$regexStr'. Mapping will be omitted")
127-
None
128-
else if url.isEmpty then
129-
logger.warn(s"Wrong url parameter in external mapping. Found '$urlStr'. Mapping will be omitted")
130-
None
131-
else if parsedDocTool.isEmpty then
132-
logger.warn(s"Wrong doc-tool parameter in external mapping. " +
133-
s"Expected one of: 'scaladoc', 'scala3doc', 'javadoc'. Found:'$docTool'. Mapping will be omitted "
134-
)
135-
None
136-
else
137-
Some(
138-
Scala3docExternalDocumentationLink(
139-
List(regexStr.r),
140-
URL(urlStr),
141-
parsedDocTool.get,
142-
packageListUrlStr.map(URL(_))
143-
)
144-
)
145-
res
146-
}
105+
val externalDocumentationLinks = args.externalMappings
147106

148107
override def getPluginsConfiguration: JList[DokkaConfiguration.PluginConfiguration] =
149108
JNil
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package dotty.dokka
2+
3+
import java.net.URL
4+
import scala.util.matching._
5+
import scala.util.Try
6+
7+
case class ExternalDocLink(
8+
originRegexes: List[Regex],
9+
documentationUrl: URL,
10+
kind: DocumentationKind,
11+
packageListUrl: Option[URL] = None
12+
):
13+
def withPackageList(url: URL): ExternalDocLink = copy(packageListUrl = Some(url))
14+
15+
enum DocumentationKind:
16+
case Javadoc extends DocumentationKind
17+
case Scaladoc extends DocumentationKind
18+
case Scala3doc extends DocumentationKind
19+
20+
object ExternalDocLink:
21+
def parse(mapping: String)(using CompilerContext): Option[ExternalDocLink] =
22+
def fail(msg: String) =
23+
report.warning(s"Unable to parocess external mapping $mapping. $msg")
24+
None
25+
26+
def tryParse[T](descr: String)(op: => T): Option[T] = try Some(op) catch
27+
case e: RuntimeException =>
28+
report.warn(s"Unable to parse $descr", e)
29+
None
30+
31+
def parsePackageList(elements: List[String]) = elements match
32+
case List(urlStr) => tryParse("packageList")(Option(URL(urlStr)))
33+
case Nil => Some(None)
34+
case other => fail(s"Provided multiple package lists: $other")
35+
36+
def doctoolByName(name: String) = name match
37+
case "javadoc" => Some(DocumentationKind.Javadoc)
38+
case "scaladoc" => Some(DocumentationKind.Scaladoc)
39+
case "scala3doc" => Some(DocumentationKind.Scala3doc)
40+
case other => fail(s"Unknown doctool: $other")
41+
42+
43+
mapping.split("::").toList match
44+
case regexStr :: docToolStr :: urlStr :: rest =>
45+
for {
46+
regex <- tryParse("regex")(regexStr.r)
47+
url <- tryParse("url")(URL(urlStr))
48+
doctool <- doctoolByName(docToolStr)
49+
packageList <- parsePackageList(rest)
50+
} yield ExternalDocLink(
51+
List(regex),
52+
url,
53+
doctool,
54+
packageList
55+
)
56+
case _ =>
57+
fail("Accepted format: `regexStr::docToolStr::urlStr[::rest]`")

scala3doc/src/dotty/dokka/IO.java

+4
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,8 @@ public FileVisitResult visitFile(
4343
public static String read(Path path) throws IOException {
4444
return new String(Files.readAllBytes(path), Charset.defaultCharset());
4545
}
46+
47+
public static String read(String path) throws IOException {
48+
return read(Paths.get(path));
49+
}
4650
}

scala3doc/src/dotty/dokka/Scala3doc.scala

+2-1
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,10 @@ object Scala3doc:
6565
defaultSyntax: CommentSyntax = CommentSyntax.Markdown,
6666
sourceLinks: List[String] = Nil,
6767
revision: Option[String] = None,
68-
externalMappings: List[List[String]] = List.empty,
68+
externalMappings: List[ExternalDocLink] = Nil,
6969
identifiersToSkip: List[String] = Nil,
7070
regexesToSkip: List[String] = Nil,
71+
rootDocPath: Option[String] = None
7172
)
7273

7374
def run(args: Array[String], rootContext: CompilerContext): Reporter =

scala3doc/src/dotty/dokka/Scala3docArgs.scala

+21-8
Original file line numberDiff line numberDiff line change
@@ -25,25 +25,34 @@ class Scala3docArgs extends SettingGroup with CommonScalaSettings:
2525
sourcepath, sourceroot
2626
)
2727

28-
val sourceLinks: Setting[String] =
29-
StringSetting("-source-links", "sources", SourceLinks.usage, "")
28+
val sourceLinks: Setting[List[String]] =
29+
MultiStringSetting("-source-links", "sources", SourceLinks.usage)
3030

3131
val syntax: Setting[String] =
3232
StringSetting("-comment-syntax", "syntax", "Syntax of the comment used", "")
3333

3434
val revision: Setting[String] =
3535
StringSetting("-revision", "revision", "Revision (branch or ref) used to build project project", "")
3636

37-
val externalDocumentationMappings: Setting[String] =
38-
StringSetting("-external-mappings", "external-mappings", "Mapping between regex matching class file and external documentation", "")
37+
val externalDocumentationMappings: Setting[List[String]] =
38+
MultiStringSetting("-external-mappings", "external-mappings",
39+
"Mapping between regexes matching classpath entries and external documentation. " +
40+
"'regex::[scaladoc|scala3doc|javadoc]::path' syntax is used")
41+
42+
val deprecatedSkipPackages: Setting[List[String]] =
43+
MultiStringSetting("-skip-packages", "packages", "Deprecated, please use `-skip-by-id` or `-skip-by-regex`")
3944

4045
val skipById: Setting[List[String]] =
4146
MultiStringSetting("-skip-by-id", "package or class identifier", "Identifiers of packages or top-level classes to skip when generating documentation")
4247

4348
val skipByRegex: Setting[List[String]] =
4449
MultiStringSetting("-skip-by-regex", "regex", "Regexes that match fully qualified names of packages or top-level classes to skip when generating documentation")
4550

46-
def scala3docSpecificSettings: Set[Setting[_]] = Set(sourceLinks, syntax, revision, externalDocumentationMappings, skipById, skipByRegex)
51+
val docRootContent: Setting[String] =
52+
StringSetting("-doc-root-content", "path", "The file from which the root package documentation should be imported.", "")
53+
54+
def scala3docSpecificSettings: Set[Setting[_]] =
55+
Set(sourceLinks, syntax, revision, externalDocumentationMappings, skipById, skipByRegex, deprecatedSkipPackages, docRootContent)
4756

4857
object Scala3docArgs:
4958
def extract(args: List[String], rootCtx: CompilerContext):(Scala3doc.Args, CompilerContext) =
@@ -104,7 +113,8 @@ object Scala3docArgs:
104113
CommentSyntax.default
105114
}
106115
}
107-
val externalMappings = externalDocumentationMappings.get.split(":::").map(_.split("::").toList).toList
116+
val externalMappings =
117+
externalDocumentationMappings.get.flatMap(ExternalDocLink.parse)
108118

109119
unsupportedSettings.filter(s => s.get != s.default).foreach { s =>
110120
report.warning(s"Setting ${s.name} is currently not supported.")
@@ -114,6 +124,8 @@ object Scala3docArgs:
114124
report.inform(
115125
s"Generating documenation $printableProjectName in $destFile")
116126

127+
if deprecatedSkipPackages.get.nonEmpty then report.warning(deprecatedSkipPackages.description)
128+
117129
val docArgs = Args(
118130
projectName.withDefault("root"),
119131
dirs,
@@ -124,10 +136,11 @@ object Scala3docArgs:
124136
projectVersion.nonDefault,
125137
projectLogo.nonDefault,
126138
parseSyntax,
127-
sourceLinks.nonDefault.fold(Nil)(_.split(",").toList),
139+
sourceLinks.get,
128140
revision.nonDefault,
129141
externalMappings,
130-
skipById.get,
142+
skipById.get ++ deprecatedSkipPackages.get,
131143
skipByRegex.get,
144+
docRootContent.nonDefault
132145
)
133146
(docArgs, newContext)

scala3doc/src/dotty/dokka/ScalaModuleCreator.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import kotlin.coroutines.Continuation
1616

1717
class ScalaModuleProvider(using ctx: DocContext) extends SourceToDocumentableTranslator:
1818
override def invoke(sourceSet: DokkaSourceSet, cxt: DokkaContext, unused: Continuation[? >: DModule]) =
19-
val result = DokkaTastyInspector(new MarkdownParser(_ => null)).result()
19+
val (result, rootDoc) = DokkaTastyInspector(new MarkdownParser(_ => null)).result()
2020
val (rootPck, rest) = result.partition(_.name == "<empty>")
2121
val packageMembers = (rest ++ rootPck.flatMap(_.allMembers)).sortBy(_.name)
2222

@@ -32,7 +32,7 @@ class ScalaModuleProvider(using ctx: DocContext) extends SourceToDocumentableTra
3232
null,
3333
JSet(ctx.sourceSet),
3434
PropertyContainer.Companion.empty()
35-
).withNewMembers(packageMembers).withKind(Kind.RootPackage).asInstanceOf[DPackage]
35+
).withNewMembers(packageMembers).withKind(Kind.RootPackage).withDocs(rootDoc).asInstanceOf[DPackage]
3636

3737
new DModule(
3838
sourceSet.getDisplayName,

scala3doc/src/dotty/dokka/externalDocumentationLinks.scala

-18
This file was deleted.

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

+4
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ extension (member: Member)
7979
val ext = MemberExtension.getFrom(member).getOrElse(MemberExtension.empty).copy(kind = kind)
8080
putInMember(ext)
8181

82+
def withDocs(docs: Option[Comment]): Member =
83+
val ext = MemberExtension.getFrom(member).getOrElse(MemberExtension.empty).copy(rawDoc = docs)
84+
putInMember(ext)
85+
8286
def withMembers(newMembers: Seq[Member]): Member =
8387
val original = member.compositeMemberExt.getOrElse(CompositeMemberExtension())
8488
val newExt = original.copy(members = newMembers)

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

+2-8
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,10 @@ trait BasicSupport:
2929
Annotation(dri, params)
3030

3131
extension (sym: Symbol)
32-
def documentation = sym.docstring match
33-
case Some(docstring) =>
34-
Map(ctx.sourceSet -> parseComment(docstring, sym.tree))
35-
case None =>
36-
Map.empty
37-
38-
def documentation2 = sym.docstring.map(preparseComment(_, sym.tree))
32+
def documentation = sym.docstring.map(parseComment(_, sym.tree))
3933

4034
def source(using Quotes) =
41-
val path = sym.pos.filter(isValidPos(_)).map(_.sourceFile.jpath).filter(_ != null).map(_.toAbsolutePath).map(_.toString)
35+
val path = sym.pos.map(_.sourceFile.jpath).filter(_ != null).map(_.toAbsolutePath).map(_.toString)
4236
path.map(TastyDocumentableSource(_, sym.pos.get.startLine))
4337

4438
def getAnnotations(): List[Annotation] =

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ trait ClassLikeSupport:
465465
placeholderModifier,
466466
ctx.sourceSet.toSet,
467467
/*isExpectActual =*/ false,
468-
PropertyContainer.Companion.empty().plus(member.copy(rawDoc = symbol.documentation2)).plus(compositeExt)
468+
PropertyContainer.Companion.empty().plus(member.copy(rawDoc = symbol.documentation)).plus(compositeExt)
469469
)
470470

471471
private def isUsingModifier(parameters: Seq[ValDef]): Boolean =

0 commit comments

Comments
 (0)