Skip to content

Commit

Permalink
Merge pull request #10581 from lrytz/t12867
Browse files Browse the repository at this point in the history
`-doc-source-url` compatibility with 2.12.11
  • Loading branch information
lrytz committed Nov 23, 2023
2 parents 0835d86 + 2fb6b17 commit d4f2056
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 19 deletions.
52 changes: 35 additions & 17 deletions src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala
Original file line number Diff line number Diff line change
Expand Up @@ -318,27 +318,21 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {

if (!settings.docsourceurl.isDefault)
inSource.map { case (file, line) =>
// file path is relative to source root (-sourcepath)
val src = Paths.get(settings.sourcepath.value).toUri
val path = file.file.toPath.toUri
val filePathExt = src.relativize(path)
val rawPath: String = filePathExt.getRawPath
val filePathExt = {
// file path is relative to source root (-sourcepath); use an absolute path otherwise
val sp = settings.sourcepath.value
val fileUri = file.file.toPath.toUri
if (sp.isEmpty) fileUri.getRawPath
else Paths.get(sp).toUri.relativize(fileUri).getRawPath
}
val (filePath, fileExt) =
rawPath.lastIndexOf('.') match {
case -1 => (rawPath, "")
case i => rawPath.splitAt(i)
filePathExt.lastIndexOf('.') match {
case -1 => (filePathExt, "")
case i => filePathExt.splitAt(i)
}
val tplOwner = this.inTemplate.qualifiedName
val tplName = this.name
def substitute(name: String): String = name match {
case FILE_PATH => filePath
case FILE_EXT => fileExt
case FILE_PATH_EXT => filePathExt.toString
case FILE_LINE => line.toString
case TPL_OWNER => tplOwner
case TPL_NAME => tplName
}
val patchedString = tokens.replaceAllIn(settings.docsourceurl.value, m => quoteReplacement(substitute(m.group(1))) )
val patchedString = expandUrl(settings.docsourceurl.value, filePath, fileExt, filePathExt, line, tplOwner, tplName)
new URI(patchedString).toURL
}
else None
Expand Down Expand Up @@ -1068,4 +1062,28 @@ object ModelFactory {
final val FILE_LINE = "FILE_LINE"
final val TPL_OWNER = "TPL_OWNER"
final val TPL_NAME = "TPL_NAME"

val WordChar = raw"(\w)".r

def expandUrl(urlTemplate: String, filePath: String, fileExt: String, filePathExt: String, line: Int, tplOwner: String, tplName: String): String = {
val absolute = filePath.startsWith("/")

def subst(token: String, index: Int): String = {
// If a relative path follows a word character, insert a `/`
def sep: String =
if (index > 0 && !absolute && WordChar.matches(urlTemplate.substring(index-1, index))) "/"
else ""
def dotted: Boolean = index > 0 && urlTemplate(index-1) == '.'

token match {
case FILE_PATH => s"$sep$filePath"
case FILE_EXT => if (dotted) fileExt.stripPrefix(".") else fileExt
case FILE_PATH_EXT => s"$sep$filePathExt"
case FILE_LINE => line.toString
case TPL_OWNER => tplOwner
case TPL_NAME => tplName
}
}
tokens.replaceAllIn(urlTemplate, m => quoteReplacement(subst(m.group(1), m.start)))
}
}
30 changes: 30 additions & 0 deletions test/junit/scala/tools/nsc/doc/html/ModelFactoryTest.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package scala.tools.nsc.doc.html

import org.junit.Assert.assertEquals
import org.junit.Test

import scala.tools.nsc.doc.model.ModelFactory._

class ModelFactoryTest {
def t(expected: String, template: String,
filePath: String = null, fileExt: String = null, line: Int = 0, tplOwner: String = null, tplName: String = null) =
assertEquals(expected, expandUrl(template, filePath, fileExt, filePath + fileExt, line, tplOwner, tplName))

@Test def sourceUrlReplace(): Unit = {
// relative path: insert `/` if path follows a word character
t("/base/p/file.scala", "/base€{FILE_PATH_EXT}", filePath = "p/file", fileExt = ".scala")
t("/base/p/file.scala", "/base/€{FILE_PATH_EXT}", filePath = "p/file", fileExt = ".scala")
t("/base.p/file.scala", "/base.€{FILE_PATH_EXT}", filePath = "p/file", fileExt = ".scala")
t("p/file.scala", "€{FILE_PATH_EXT}", filePath = "p/file", fileExt = ".scala")

t("/base/p/file.scala", "/base€{FILE_PATH_EXT}", filePath = "/p/file", fileExt = ".scala")
t("/base//p/file.scala", "/base/€{FILE_PATH_EXT}", filePath = "/p/file", fileExt = ".scala")

// file extension: don't duplicate `.`
t("/base/p/file.scala", "/base€{FILE_PATH}€{FILE_EXT}", filePath = "p/file", fileExt = ".scala")
t("/base/p/file.scala", "/base/€{FILE_PATH}.€{FILE_EXT}", filePath = "p/file", fileExt = ".scala")
t("p/file.scala", "€{FILE_PATH}.€{FILE_EXT}", filePath = "p/file", fileExt = ".scala")
t("p/file", "€{FILE_PATH}", filePath = "p/file", fileExt = ".scala")
t(".scala", "€{FILE_EXT}", filePath = "", fileExt = ".scala")
}
}
2 changes: 1 addition & 1 deletion test/scaladoc/run/doc-source-url-java.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ object Test extends ScaladocModelTest {

override def model: Option[Universe] = newDocFactory.makeUniverse(Left(List(resourceFile)))

def scaladocSettings = "-doc-source-url file:€{FILE_PATH}@@€{FILE_EXT}@@€{FILE_PATH_EXT}@@€{FILE_LINE}"
def scaladocSettings = "-doc-source-url file:€{FILE_PATH}@@€{FILE_EXT}@@€{FILE_PATH_EXT}@@€{FILE_LINE} -sourcepath ."

def testModel(rootPackage: Package) = {
import access._
Expand Down
2 changes: 1 addition & 1 deletion test/scaladoc/run/doc-source-url.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ object Test extends ScaladocModelTest {

override def model: Option[Universe] = newDocFactory.makeUniverse(Left(List(resourceFile)))

def scaladocSettings = "-doc-source-url file:€{FILE_PATH}@@€{FILE_EXT}@@€{FILE_PATH_EXT}@@€{FILE_LINE}"
def scaladocSettings = "-doc-source-url file:€{FILE_PATH}@@€{FILE_EXT}@@€{FILE_PATH_EXT}@@€{FILE_LINE} -sourcepath ."

def testModel(rootPackage: Package) = {
import access._
Expand Down

0 comments on commit d4f2056

Please sign in to comment.