Skip to content

Commit 5bd1d92

Browse files
committed
Remove liquid templates from source links generation. Add support for some scaladoc euro-sign parameters
1 parent 5ee1c7e commit 5bd1d92

File tree

3 files changed

+44
-43
lines changed

3 files changed

+44
-43
lines changed

project/Build.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1532,7 +1532,7 @@ object Build {
15321532
val projectRoot = (ThisBuild/baseDirectory).value.toPath
15331533
val stdLibRoot = projectRoot.relativize(managedSources.toPath.normalize())
15341534
val scalaSourceLink =
1535-
s"$stdLibRoot=github://scala/scala/v${stdlibVersion(Bootstrapped)}#src/library"
1535+
s"$stdLibRoot=https://github.com/scala/scala/blob/v${stdlibVersion(Bootstrapped)}/src/library€{FILE_PATH}#L€{FILE_LINE}"
15361536
val sourcesAndRevision = s"-source-links $scalaSourceLink,github://lampepfl/dotty -revision $ref -project-version $projectVersion"
15371537
val cmd = s""" -d $outDir -project "$name" $sourcesAndRevision $params $targets"""
15381538
run.in(Compile).toTask(cmd)

scala3doc/src/dotty/dokka/SourceLinks.scala

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,45 @@ package dotty.dokka
22

33
import java.nio.file.Path
44
import java.nio.file.Paths
5-
import liqp.Template
65
import dotty.dokka.model.api._
76
import dotty.tools.dotc.core.Contexts.Context
7+
import scala.util.matching.Regex
88

9-
def pathToString(p: Path) = p.toString.replace('\\', '/')
9+
def pathToString(p: Path) = "/" + p.toString.replace('\\', '/')
1010

1111
trait SourceLink:
1212
val path: Option[Path] = None
13-
def render(path: Path, operation: String, line: Option[Int]): String
13+
def render(memberName: String, path: Path, operation: String, line: Option[Int]): String
1414

1515
case class PrefixedSourceLink(val myPath: Path, nested: SourceLink) extends SourceLink:
1616
val myPrefix = pathToString(myPath)
1717
override val path = Some(myPath)
18-
override def render(path: Path, operation: String, line: Option[Int]): String =
19-
nested.render(myPath.relativize(path), operation, line)
18+
override def render(memberName: String, path: Path, operation: String, line: Option[Int]): String =
19+
nested.render(memberName, myPath.relativize(path), operation, line)
2020

2121

22-
case class TemplateSourceLink(val urlTemplate: Template) extends SourceLink:
22+
case class TemplateSourceLink(val urlTemplate: String) extends SourceLink:
2323
override val path: Option[Path] = None
24-
override def render(path: Path, operation: String, line: Option[Int]): String =
25-
val config = java.util.HashMap[String, Object]()
26-
config.put("path", pathToString(path))
27-
line.foreach(l => config.put("line", l.toString))
28-
config.put("operation", operation)
24+
override def render(memberName: String, path: Path, operation: String, line: Option[Int]): String =
25+
val mapping = Map(
26+
"\\{\\{ path \\}\\}".r -> pathToString(path),
27+
"\\{\\{ line \\}\\}".r -> line.fold("")(_.toString),
28+
"\\{\\{ ext \\}\\}".r -> Some(
29+
pathToString(path)).filter(_.lastIndexOf(".") == -1).fold("")(p => p.substring(p.lastIndexOf("."))
30+
),
31+
"\\{\\{ path_no_ext \\}\\}".r -> Some(
32+
pathToString(path)).filter(_.lastIndexOf(".") == -1).fold(pathToString(path))(p => p.substring(0, p.lastIndexOf("."))
33+
),
34+
"\\{\\{ name \\}\\}".r -> memberName
35+
)
36+
mapping.foldLeft(urlTemplate) {
37+
case (sourceLink, (regex, value)) => regex.replaceAllIn(sourceLink, Regex.quoteReplacement(value))
38+
}
2939

30-
urlTemplate.render(config)
3140

3241
case class WebBasedSourceLink(prefix: String, revision: String, subPath: String) extends SourceLink:
3342
override val path: Option[Path] = None
34-
override def render(path: Path, operation: String, line: Option[Int]): String =
43+
override def render(memberName: String, path: Path, operation: String, line: Option[Int]): String =
3544
val action = if operation == "view" then "blob" else operation
3645
val linePart = line.fold("")(l => s"#L$l")
3746
s"$prefix/$action/$revision$subPath/$path$linePart"
@@ -40,10 +49,13 @@ object SourceLink:
4049
val SubPath = "([^=]+)=(.+)".r
4150
val KnownProvider = raw"(\w+):\/\/([^\/#]+)\/([^\/#]+)(\/[^\/#]+)?(#.+)?".r
4251
val BrokenKnownProvider = raw"(\w+):\/\/.+".r
43-
val ScalaDocPatten = raw"€\{(TPL_NAME|TPL_NAME|FILE_PATH|FILE_EXT|FILE_LINE|FILE_PATH_EXT)\}".r
52+
val ScalaDocPatten = raw"€\{(TPL_NAME|TPL_OWNER|FILE_PATH|FILE_EXT|FILE_LINE|FILE_PATH_EXT)\}".r
4453
val SupportedScalaDocPatternReplacements = Map(
4554
"€{FILE_PATH_EXT}" -> "{{ path }}",
46-
"€{FILE_LINE}" -> "{{ line }}"
55+
"€{FILE_LINE}" -> "{{ line }}",
56+
"€{TPL_NAME}" -> "{{ name }}",
57+
"€{FILE_EXT}" -> "{{ ext }}",
58+
"€{FILE_PATH}" -> "{{ path_no_ext }}"
4759
)
4860

4961
def githubPrefix(org: String, repo: String) = s"https://github.com/$org/$repo"
@@ -54,10 +66,6 @@ object SourceLink:
5466
private def parseLinkDefinition(s: String): Option[SourceLink] = ???
5567

5668
def parse(string: String, revision: Option[String]): Either[String, SourceLink] =
57-
def asTemplate(template: String) =
58-
try Right(TemplateSourceLink(Template.parse(template))) catch
59-
case e: RuntimeException =>
60-
Left(s"Failed to parse template: ${e.getMessage}")
6169

6270
string match
6371
case KnownProvider(name, organization, repo, rawRevision, rawSubPath) =>
@@ -90,28 +98,28 @@ object SourceLink:
9098
val all = ScalaDocPatten.findAllIn(scaladocSetting)
9199
val (supported, unsupported) = all.partition(SupportedScalaDocPatternReplacements.contains)
92100
if unsupported.nonEmpty then Left(s"Unsupported patterns from scaladoc format are used: ${unsupported.mkString(" ")}")
93-
else asTemplate(supported.foldLeft(string)((template, pattern) =>
94-
template.replace(pattern, SupportedScalaDocPatternReplacements(pattern))))
95-
96-
case template => asTemplate(template)
101+
else Right(TemplateSourceLink(supported.foldLeft(string)((template, pattern) =>
102+
template.replace(pattern, SupportedScalaDocPatternReplacements(pattern)))))
103+
case other =>
104+
Right(TemplateSourceLink(""))
97105

98106

99107
type Operation = "view" | "edit"
100108

101109
case class SourceLinks(links: Seq[SourceLink], projectRoot: Path):
102-
def pathTo(rawPath: Path, line: Option[Int] = None, operation: Operation = "view"): Option[String] =
110+
def pathTo(rawPath: Path, memberName: String = "", line: Option[Int] = None, operation: Operation = "view"): Option[String] =
103111
def resolveRelativePath(path: Path) =
104112
links
105113
.find(_.path.forall(p => path.startsWith(p)))
106-
.map(_.render(path, operation, line))
114+
.map(_.render(memberName, path, operation, line))
107115

108116
if rawPath.isAbsolute then
109117
if rawPath.startsWith(projectRoot) then resolveRelativePath(projectRoot.relativize(rawPath))
110118
else None
111119
else resolveRelativePath(rawPath)
112120

113121
def pathTo(member: Member): Option[String] =
114-
member.sources.flatMap(s => pathTo(Paths.get(s.path), Option(s.lineNumber).map(_ + 1)))
122+
member.sources.flatMap(s => pathTo(Paths.get(s.path), member.name, Option(s.lineNumber).map(_ + 1)))
115123

116124
object SourceLinks:
117125

@@ -130,15 +138,10 @@ object SourceLinks:
130138
| will match https://gitlab.com/$organization/$repository/-/[blob|edit]/$revision[/$subpath]/$filePath[$lineNumber]
131139
| when revision is not provided then requires revision to be specified as argument for scala3doc
132140
| - <scaladoc-template>
133-
| - <template>
134141
|
135142
|<scaladoc-template> is a format for `doc-source-url` parameter scaladoc.
136143
|NOTE: We only supports `€{FILE_PATH_EXT}` and €{FILE_LINE} patterns
137144
|
138-
|<template> is a liqid template string that can accepts follwoing arguments:
139-
| - `operation`: either "view" or "edit"
140-
| - `path`: relative path of file to provide link to
141-
| - `line`: optional parameter that specify line number within a file
142145
|
143146
|
144147
|Template can defined only by subset of sources defined by path prefix represented by `<sub-path>`.

scala3doc/test/dotty/dokka/SourceLinksTests.scala

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ class SourceLinkTest:
1818
testFailure("ala://ma/kota", "known provider")
1919
testFailure("ala=ala=ala://ma/kota", "known provider")
2020
testFailure("ala=ala=ala", "subpath")
21-
testFailure("""{{ ala "ala"}}""", "parse")
22-
testFailure("""€{TPL_NAME}""", "scaladoc")
21+
testFailure("""€{TPL_OWNER}""", "scaladoc")
2322

2423

2524
@Test
@@ -31,7 +30,6 @@ class SourceLinkTest:
3130

3231

3332
Seq(
34-
"""https://github.com/organization/repo/{{ operation | replace: "view", "blob" }}/$revision/{{ path }}{{ line | prepend: "L#"}}""",
3533
"github://lampepfl/dotty",
3634
"gitlab://lampepfl/dotty",
3735
"https://github.com/scala/scala/blob/2.13.x€{FILE_PATH_EXT}#€{FILE_LINE}"
@@ -124,14 +122,14 @@ class SourceLinksTest:
124122
("project/Build.scala", 54, edit) -> "https://gitlab.com/lampepfl/dotty/-/edit/develop/project/Build.scala#L54",
125123
)
126124

127-
testLink(Seq("/{{operation}}/{{path}}#{{line}}"), Some("develop"))(
128-
"project/Build.scala" -> "/view/project/Build.scala#",
129-
("project/Build.scala", 54) -> "/view/project/Build.scala#54",
130-
("project/Build.scala", edit) -> "/edit/project/Build.scala#",
131-
("project/Build.scala", 54, edit) -> "/edit/project/Build.scala#54",
125+
testLink(Seq("€{FILE_PATH}#€{FILE_LINE}"), Some("develop"))(
126+
"project/Build.scala" -> "/project/Build.scala#",
127+
("project/Build.scala", 54) -> "/project/Build.scala#54",
128+
("project/Build.scala", edit) -> "/project/Build.scala#",
129+
("project/Build.scala", 54, edit) -> "/project/Build.scala#54",
132130
)
133131

134-
testLink(Seq("https://github.com/scala/scala/blob/2.13.x/€{FILE_PATH_EXT}#L€{FILE_LINE}"), Some("develop"))(
132+
testLink(Seq("https://github.com/scala/scala/blob/2.13.x€{FILE_PATH_EXT}#L€{FILE_LINE}"), Some("develop"))(
135133
"project/Build.scala" -> "https://github.com/scala/scala/blob/2.13.x/project/Build.scala#L",
136134
("project/Build.scala", 54) -> "https://github.com/scala/scala/blob/2.13.x/project/Build.scala#L54",
137135
("project/Build.scala", edit) -> "https://github.com/scala/scala/blob/2.13.x/project/Build.scala#L",
@@ -151,12 +149,12 @@ class SourceLinksTest:
151149
@Test
152150
def prefixedPaths =
153151
testLink(Seq(
154-
"src/generated=/{{operation}}/{{path}}#{{line}}",
152+
"src/generated=€{FILE_PATH}#€{FILE_LINE}",
155153
"src=gitlab://lampepfl/dotty",
156154
"github://lampepfl/dotty"
157155
), Some("develop"))(
158156
("project/Build.scala", 54, edit) -> "https://github.com/lampepfl/dotty/edit/develop/project/Build.scala#L54",
159157
("src/lib/core.scala", 33, edit) -> "https://gitlab.com/lampepfl/dotty/-/edit/develop/lib/core.scala#L33",
160158
("src/generated.scala", 33, edit) -> "https://gitlab.com/lampepfl/dotty/-/edit/develop/generated.scala#L33",
161-
("src/generated/template.scala", 1, edit) -> "/edit/template.scala#1"
159+
("src/generated/template.scala", 1, edit) -> "/template.scala#1"
162160
)

0 commit comments

Comments
 (0)