Skip to content

Commit 05f7310

Browse files
committed
API pages are not top level
1 parent ec15557 commit 05f7310

File tree

17 files changed

+134
-68
lines changed

17 files changed

+134
-68
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package docs.tests
2+
3+
class Adoc:
4+
def foo = 123
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package resources.tests
2+
3+
class Adoc:
4+
def foo = 123

scaladoc/src/dotty/tools/scaladoc/renderers/HtmlRenderer.scala

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,19 +58,18 @@ class HtmlRenderer(rootPackage: Member, val members: Map[DRI, Member])(using ctx
5858

5959
val hiddenPages: Seq[Page] =
6060
staticSite match
61-
case None =>
62-
Seq(navigablePage.copy( // Add index page that is a copy of api/index.html
63-
link = navigablePage.link.copy(dri = docsRootDRI),
64-
children = Nil
65-
))
61+
case None => Nil
6662
case Some(siteContext) =>
67-
(siteContext.orphanedTemplates :+ siteContext.indexTemplate()).map(templateToPage(_, siteContext))
63+
val actualIndexTemplate = siteContext.indexTemplates() match
64+
case Nil if effectiveMembers.isEmpty => Seq(siteContext.emptyIndexTemplate)
65+
case templates => templates
66+
67+
(siteContext.orphanedTemplates ++ actualIndexTemplate).map(templateToPage(_, siteContext))
6868

6969
/**
7070
* Here we have to retrive index pages from hidden pages and replace fake index pages in navigable page tree.
7171
*/
72-
private def getAllPages: Seq[Page] =
73-
72+
val allPages: Seq[Page] =
7473
def traversePages(page: Page): (Page, Seq[Page]) =
7574
val (newChildren, newPagesToRemove): (Seq[Page], Seq[Page]) = page.children.map(traversePages(_)).foldLeft((Seq[Page](), Seq[Page]())) {
7675
case ((pAcc, ptrAcc), (p, ptr)) => (pAcc :+ p, ptrAcc ++ ptr)
@@ -83,9 +82,22 @@ class HtmlRenderer(rootPackage: Member, val members: Map[DRI, Member])(using ctx
8382

8483
val (newNavigablePage, pagesToRemove) = traversePages(navigablePage)
8584

86-
newNavigablePage +: hiddenPages.filterNot(pagesToRemove.contains)
85+
val all = newNavigablePage +: hiddenPages.filterNot(pagesToRemove.contains)
86+
// We need to check for conflicts only if we have top-level member called blog or docs
87+
val hasPotentialConflict =
88+
rootPackage.members.exists(m => m.name.startsWith("docs") || m.name.startsWith("blog"))
89+
90+
if hasPotentialConflict then
91+
def walk(page: Page): Unit =
92+
if page.link.dri.isStaticFile then
93+
val dest = absolutePath(page.link.dri)
94+
if apiPaths.contains(dest) then
95+
report.error(s"Conflict between static page and API member for $dest")
96+
page.children.foreach(walk)
97+
98+
all.foreach (walk)
8799

88-
val allPages = getAllPages
100+
all
89101

90102
def renderContent(page: Page) = page.content match
91103
case m: Member =>

scaladoc/src/dotty/tools/scaladoc/renderers/Locations.scala

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ val UnresolvedLocationLink = "#"
1919
trait Locations(using ctx: DocContext):
2020
def effectiveMembers: Map[DRI, Member]
2121

22+
// We generate this collection only if there may be a conflict with resources.
23+
// Potentially can be quite big.
24+
lazy val apiPaths = effectiveMembers.keySet.filterNot(_.isStaticFile).map(absolutePath)
25+
2226
var cache = new JHashMap[DRI, Seq[String]]()
2327

2428
// TODO verify if location exisits
@@ -27,17 +31,16 @@ trait Locations(using ctx: DocContext):
2731
case null =>
2832
val path = dri match
2933
case `docsRootDRI` => List("docs", "index")
30-
case `apiPageDRI` => List("api", "index")
34+
case `apiPageDRI` =>
35+
if ctx.staticSiteContext.fold(false)(_.hasIndexFile) then List("api", "index") else List("index")
3136
case dri if dri.isStaticFile =>
3237
Paths.get(dri.location).iterator.asScala.map(_.toString).toList
3338
case dri =>
3439
val loc = dri.location
35-
val fqn = loc.split(Array('.')).toList match
40+
loc.split(Array('.')).toList match
3641
case "<empty>" :: Nil => "_empty_" :: Nil
3742
case "<empty>" :: tail => "_empty_" :: tail
3843
case other => other
39-
40-
Seq("api") ++ fqn
4144
cache.put(dri, path)
4245
path
4346
case cached => cached

scaladoc/src/dotty/tools/scaladoc/renderers/Resources.scala

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -171,19 +171,23 @@ trait Resources(using ctx: DocContext) extends Locations, Writer:
171171
)
172172

173173
def renderResource(resource: Resource): Seq[String] =
174-
resource match
175-
case Resource.Text(path, content) =>
176-
Seq(write(path, content))
177-
case Resource.Classpath(path, name) =>
178-
getClass.getClassLoader.getResourceAsStream(name) match
179-
case null =>
180-
report.error(s"Unable to find $name on classpath")
181-
Nil
182-
case is =>
183-
try Seq(copy(is, path)) finally is.close()
184-
case Resource.File(path, file) =>
185-
Seq(copy(file, path))
186-
case Resource.URL(url) =>
187-
Nil
188-
case Resource.URLToCopy(url, dest) =>
189-
Seq(copy(new URL(url).openStream(), dest))
174+
if resource.path.endsWith(".html") && apiPaths.contains(resource.path) then
175+
report.error(s"Conflict between resource and API member for ${resource.path}")
176+
Nil
177+
else
178+
resource match
179+
case Resource.Text(path, content) =>
180+
Seq(write(path, content))
181+
case Resource.Classpath(path, name) =>
182+
getClass.getClassLoader.getResourceAsStream(name) match
183+
case null =>
184+
report.error(s"Unable to find $name on classpath")
185+
Nil
186+
case is =>
187+
try Seq(copy(is, path)) finally is.close()
188+
case Resource.File(path, file) =>
189+
Seq(copy(file, path))
190+
case Resource.URL(url) =>
191+
Nil
192+
case Resource.URLToCopy(url, dest) =>
193+
Seq(copy(new URL(url).openStream(), dest))

scaladoc/src/dotty/tools/scaladoc/site/StaticSiteContext.scala

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,21 @@ class StaticSiteContext(
1919

2020
var memberLinkResolver: String => Option[DRI] = _ => None
2121

22-
def indexTemplate(): LoadedTemplate =
22+
private def indexFiles =
2323
val files = List(new File(root, "index.html"), new File(root, "index.md")).filter { _.exists() }
2424

2525
if files.size > 1 then
2626
val msg = s"ERROR: Multiple root index pages found: ${files.map(_.getAbsolutePath)}"
2727
report.error(msg)
28+
files
2829

29-
files.flatMap(loadTemplate(_, isBlog = false)).headOption.getOrElse {
30-
val fakeFile = new File(root, "index.html")
31-
LoadedTemplate(emptyTemplate(fakeFile, "index"), List.empty, fakeFile)
32-
}
30+
def hasIndexFile = indexFiles.nonEmpty
31+
32+
def emptyIndexTemplate =
33+
val fakeFile = new File(root, "index.html")
34+
LoadedTemplate(emptyTemplate(fakeFile, "index"), List.empty, fakeFile)
35+
36+
def indexTemplates(): Seq[LoadedTemplate] = indexFiles.flatMap(loadTemplate(_, isBlog = false))
3337

3438
lazy val layouts: Map[String, TemplateFile] =
3539
val layoutRoot = new File(root, "_layouts")
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Trying to override a api page!
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<html><body>I am causing conflicts!</body></html>

scaladoc/test/dotty/tools/scaladoc/BaseHtmlTest.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@ class BaseHtmlTest:
4141

4242
finally IO.delete(dest.toFile)
4343

44-
val testDocPath = Paths.get(BuildInfo.testDocumentationRoot)
45-
4644
class DocumentContext(d: Document, path: Path):
4745
import collection.JavaConverters._
4846

scaladoc/test/dotty/tools/scaladoc/ExternalLocationProviderIntegrationTest.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ abstract class ExternalLocationProviderIntegrationTest(
6060
)
6161

6262
override def runTest = afterRendering {
63-
val output = summon[DocContext].args.output.toPath.resolve("api")
63+
val output = summon[DocContext].args.output.toPath
6464
val linksBuilder = List.newBuilder[String]
6565

6666
def processFile(path: Path): Unit =
@@ -72,7 +72,6 @@ abstract class ExternalLocationProviderIntegrationTest(
7272
linksBuilder ++= hrefValues
7373
}
7474

75-
println(output)
7675
IO.foreachFileIn(output, processFile)
7776
val links = linksBuilder.result
7877
val errors = expectedLinks.flatMap(expect => Option.when(!links.contains(expect))(expect))

scaladoc/test/dotty/tools/scaladoc/RaportingTest.scala

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class ReportingTest:
4444
finally Files.delete(notTasty)
4545

4646
@Test
47-
def verbosePrintsDokkaMessage =
47+
def testSuccessfulDocsGeneration =
4848
val ctx = testContext
4949
ctx.setSetting(ctx.settings.verbose, true)
5050
checkReportedDiagnostics(ctx = ctx){ diag =>
@@ -53,3 +53,35 @@ class ReportingTest:
5353

5454
assertMessagesAbout(diag.infoMsgs)("generation completed successfully")
5555
}
56+
57+
@Test
58+
def testErrorInCaseOfAssetShadowing =
59+
val ctx = testContext
60+
ctx.setSetting(ctx.settings.verbose, true)
61+
val docsRoot = testDocPath.resolve("conflicts-resources").toString
62+
checkReportedDiagnostics(_.copy(
63+
docsRoot = Some(docsRoot),
64+
tastyFiles = tastyFiles("tests", rootPck = "resources")
65+
)){ diag =>
66+
assertNoWarning(diag)
67+
val Seq(msg) = diag.errorMsgs.map(_.toLowerCase)
68+
Seq("conflict","api", "resource", "resources/tests/adoc.html").foreach(word =>
69+
Assert.assertTrue(s"Error message: $msg should contains $word", msg.contains(word)))
70+
}
71+
72+
@Test
73+
def testErrorInCaseOfDocsShadowing =
74+
val ctx = testContext
75+
ctx.setSetting(ctx.settings.verbose, true)
76+
val docsRoot = testDocPath.resolve("conflicts-pages").toString
77+
checkReportedDiagnostics(_.copy(
78+
docsRoot = Some(docsRoot),
79+
tastyFiles = tastyFiles("tests", rootPck = "docs")
80+
)){ diag =>
81+
assertNoWarning(diag)
82+
val Seq(msg) = diag.errorMsgs.map(_.toLowerCase)
83+
Seq("conflict","api", "static", "page", "docs/tests/adoc.html")
84+
.foreach( word =>
85+
Assert.assertTrue(s"Error message: $msg should contains $word", msg.contains(word))
86+
)
87+
}

scaladoc/test/dotty/tools/scaladoc/signatures/AbstractMemberSignaturesTest.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class AbstractMembers extends ScaladocTest("abstractmembersignatures"):
2626
}
2727

2828
private def signaturesFromDocumentation()(using DocContext): Map[String, List[(String, String)]] =
29-
val output = summon[DocContext].args.output.toPath.resolve("api")
29+
val output = summon[DocContext].args.output.toPath
3030
val signatures = List.newBuilder[(String, (String, String))]
3131
def processFile(path: Path): Unit =
3232
val document = Jsoup.parse(IO.read(path))

scaladoc/test/dotty/tools/scaladoc/signatures/SignatureTest.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ abstract class SignatureTest(
104104
}
105105

106106
private def signaturesFromDocumentation()(using DocContext): Seq[String] =
107-
val output = summon[DocContext].args.output.toPath.resolve("api")
107+
val output = summon[DocContext].args.output.toPath
108108
val signatures = List.newBuilder[String]
109109

110110
def processFile(path: Path): Unit = if filterFunc(path) then

scaladoc/test/dotty/tools/scaladoc/site/NavigationTest.scala

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,17 @@ class NavigationTest extends BaseHtmlTest:
3030
)),
3131
NavMenuTestEntry("Adoc", "Adoc.html", Seq()),
3232
NavMenuTestEntry("API", "../api/index.html", Seq(
33-
NavMenuTestEntry("tests.site", "../api/tests/site.html", Seq(
34-
NavMenuTestEntry("BrokenLink", "../api/tests/site/BrokenLink.html", Nil),
35-
NavMenuTestEntry("BrokenLinkWiki", "../api/tests/site/BrokenLinkWiki.html", Nil),
36-
NavMenuTestEntry("OtherPackageLink", "../api/tests/site/OtherPackageLink.html", Nil),
37-
NavMenuTestEntry("OtherPackageLinkWiki", "../api/tests/site/OtherPackageLinkWiki.html", Nil),
38-
NavMenuTestEntry("SamePackageLink", "../api/tests/site/SamePackageLink.html", Nil),
39-
NavMenuTestEntry("SamePackageLinkWiki", "../api/tests/site/SamePackageLinkWiki.html", Nil),
40-
NavMenuTestEntry("SomeClass", "../api/tests/site/SomeClass.html", Nil)
33+
NavMenuTestEntry("tests.site", "../tests/site.html", Seq(
34+
NavMenuTestEntry("BrokenLink", "../tests/site/BrokenLink.html", Nil),
35+
NavMenuTestEntry("BrokenLinkWiki", "../tests/site/BrokenLinkWiki.html", Nil),
36+
NavMenuTestEntry("OtherPackageLink", "../tests/site/OtherPackageLink.html", Nil),
37+
NavMenuTestEntry("OtherPackageLinkWiki", "../tests/site/OtherPackageLinkWiki.html", Nil),
38+
NavMenuTestEntry("SamePackageLink", "../tests/site/SamePackageLink.html", Nil),
39+
NavMenuTestEntry("SamePackageLinkWiki", "../tests/site/SamePackageLinkWiki.html", Nil),
40+
NavMenuTestEntry("SomeClass", "../tests/site/SomeClass.html", Nil)
4141
)),
42-
NavMenuTestEntry("tests.site.some.other", "../api/tests/site/some/other.html", Seq(
43-
NavMenuTestEntry("SomeOtherPackage", "../api/tests/site/some/other/SomeOtherPackage.html", Nil),
42+
NavMenuTestEntry("tests.site.some.other", "../tests/site/some/other.html", Seq(
43+
NavMenuTestEntry("SomeOtherPackage", "../tests/site/some/other/SomeOtherPackage.html", Nil),
4444
))
4545
)),
4646
))

scaladoc/test/dotty/tools/scaladoc/site/SiteGeneratationTest.scala

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,19 @@ class SiteGeneratationTest extends BaseHtmlTest:
4545

4646
def testApiPages(
4747
mainTitle: String = "API",
48-
parents: Seq[String] = Seq(projectName))(using ProjectContext) =
49-
checkFile("api/index.html")(
48+
parents: Seq[String] = Seq(projectName),
49+
hasToplevelIndexIndex: Boolean = true)(using ProjectContext) =
50+
checkFile((if hasToplevelIndexIndex then "api/" else "" )+ "index.html")(
5051
title = mainTitle,
5152
header = projectName,
5253
parents = parents
5354
)
54-
checkFile("api/tests/site.html")(
55+
checkFile("tests/site.html")(
5556
title = "tests.site",
5657
header = "tests.site",
5758
parents = parents :+ mainTitle
5859
)
59-
checkFile("api/tests/site/SomeClass.html")(
60+
checkFile("tests/site/SomeClass.html")(
6061
title = "SomeClass",
6162
header = "SomeClass",
6263
parents = parents ++ Seq(mainTitle, "tests.site")
@@ -70,12 +71,12 @@ class SiteGeneratationTest extends BaseHtmlTest:
7071
testApiPages()
7172

7273
withHtmlFile("docs/Adoc.html"){ content =>
73-
content.assertAttr("p a","href", "../api/tests/site/SomeClass.html")
74+
content.assertAttr("p a","href", "../tests/site/SomeClass.html")
7475
}
7576

76-
withHtmlFile("api/tests/site/SomeClass.html"){ content =>
77+
withHtmlFile("tests/site/SomeClass.html"){ content =>
7778
content.assertAttr(".breadcrumbs a","href",
78-
"../../../docs/index.html", "../../index.html", "../site.html", "SomeClass.html"
79+
"../../docs/index.html", "../../api/index.html", "../site.html", "SomeClass.html"
7980
)
8081
}
8182
}
@@ -84,18 +85,18 @@ class SiteGeneratationTest extends BaseHtmlTest:
8485
def noGlobalIndexTest() = withGeneratedSite(testDocPath.resolve("noGlobalIndex")){
8586
testDocPages()
8687
testDocIndexPage()
87-
testApiPages()
88+
testApiPages(hasToplevelIndexIndex = false)
8889
}
8990

9091
@Test
9192
def noIndexesTest() = withGeneratedSite(testDocPath.resolve("noIndexes")){
9293
testDocPages()
93-
testApiPages()
94+
testApiPages(hasToplevelIndexIndex = false)
9495
}
9596

9697
@Test
9798
def noExistingDocs() = withGeneratedSite(testDocPath.resolve("noExisting")){
98-
testApiPages(mainTitle = projectName, parents = Nil)
99+
testApiPages(mainTitle = projectName, parents = Nil, hasToplevelIndexIndex = false)
99100
}
100101

101102
@Test

scaladoc/test/dotty/tools/scaladoc/tasty/comments/IntegrationTest.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ abstract class BaseIntegrationTest(pck: String) extends BaseHtmlTest:
1818
"", "" // each represent a link
1919
)
2020

21-
withHtmlFile(s"api/tests/$pck/BrokenLinks.html")(checkUnresolved)
21+
withHtmlFile(s"tests/$pck/BrokenLinks.html")(checkUnresolved)
2222
val otherPackagePath = "../commonlinks/SomeOtherPackage.html"
23-
withHtmlFile(s"api/tests/$pck/OtherPackageLink.html")(checkDocLinks(otherPackagePath))
23+
withHtmlFile(s"tests/$pck/OtherPackageLink.html")(checkDocLinks(otherPackagePath))
2424
// OtherPackageMembers - does not work, TODO?
25-
withHtmlFile(s"api/tests/$pck/SamePackageLink.html")(checkDocLinks("SomeClass.html"))
25+
withHtmlFile(s"tests/$pck/SamePackageLink.html")(checkDocLinks("SomeClass.html"))
2626
// SamePackageMembers - does not work, TODO?
2727
}
2828

scaladoc/test/dotty/tools/scaladoc/testUtils.scala

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import dotty.tools.dotc.interfaces.Diagnostic.{ERROR, INFO, WARNING}
77
import dotty.tools.scaladoc.test.BuildInfo
88
import org.junit.Assert._
99
import java.io.File
10+
import java.nio.file.Paths
1011

1112

1213
case class ReportedDiagnostics(errors: List[Diagnostic], warnings: List[Diagnostic], infos: List[Diagnostic]):
@@ -57,14 +58,14 @@ def testArgs(files: Seq[File] = Nil, dest: File = new File("notUsed")) = Scalado
5758
docsRoot = Some(""),
5859
)
5960

60-
def testContext =
61+
def testContext =
6162
val ctx = (new ContextBase).initialCtx.fresh.setReporter(new TestReporter)
6263
ctx.setSetting(ctx.settings.usejavacp, true)
6364
ctx
6465

6566
def testDocContext(files: Seq[File] = Nil) = DocContext(testArgs(files), testContext)
6667

67-
def tastyFiles(name: String, allowEmpty: Boolean = false) =
68+
def tastyFiles(name: String, allowEmpty: Boolean = false, rootPck: String = "tests") =
6869
def listFilesSafe(dir: File) = Option(dir.listFiles).getOrElse {
6970
throw AssertionError(s"$dir not found. The test name is incorrect or scaladoc-testcases were not recompiled.")
7071
}
@@ -73,7 +74,9 @@ def tastyFiles(name: String, allowEmpty: Boolean = false) =
7374
case f if f.getName endsWith ".tasty" => f :: Nil
7475
case _ => Nil
7576
}
76-
val files = BuildInfo.test_testcasesOutputDir.flatMap(p => collectFiles(File(s"$p/tests/$name")))
77+
val outputDir = BuildInfo.test_testcasesOutputDir
78+
val files = outputDir.flatMap(p => collectFiles(File(s"$p/$rootPck/$name")))
7779
assert(files.nonEmpty || allowEmpty)
7880
files.toSeq
7981

82+
def testDocPath = Paths.get(BuildInfo.testDocumentationRoot)

0 commit comments

Comments
 (0)