diff --git a/scaladoc-testcases/src/tests/sealedClasses.scala b/scaladoc-testcases/src/tests/sealedClasses.scala new file mode 100644 index 000000000000..4a5b2b3c8154 --- /dev/null +++ b/scaladoc-testcases/src/tests/sealedClasses.scala @@ -0,0 +1,24 @@ +package tests +package sealedClasses + +sealed trait A + +sealed trait B1 extends A +case class B2(a: Int) extends A +case object B3 extends A +class B4 extends A +object B4 extends A +object B5 extends A +case class B6(a: Int) extends A +case object B6 extends A + +sealed trait C1 extends B1 +case class C2(a: Int) extends B1 +case object C3 extends B1 +class C4 extends B1 +object C4 extends B1 +object C5 extends B1 +case class C6(a: Int) extends B1 +case object C6 extends B1 +sealed trait C7 extends B1 + diff --git a/scaladoc-testcases/src/tests/shadowingDRI.scala b/scaladoc-testcases/src/tests/shadowingDRI.scala index 0cdc2b2ce719..4d96f02c110b 100644 --- a/scaladoc-testcases/src/tests/shadowingDRI.scala +++ b/scaladoc-testcases/src/tests/shadowingDRI.scala @@ -7,4 +7,4 @@ class S: class R: def findThisDeclaration = 1 - given R: A[B] with {} \ No newline at end of file + given R: A[B] with {} diff --git a/scaladoc/src/dotty/tools/scaladoc/ScalaModuleCreator.scala b/scaladoc/src/dotty/tools/scaladoc/ScalaModuleCreator.scala index fbf7d02a2c3d..eda96db893a3 100644 --- a/scaladoc/src/dotty/tools/scaladoc/ScalaModuleCreator.scala +++ b/scaladoc/src/dotty/tools/scaladoc/ScalaModuleCreator.scala @@ -1,6 +1,6 @@ package dotty.tools.scaladoc -import dotty.tools.scaladoc.tasty.DokkaTastyInspector +import dotty.tools.scaladoc.tasty.ScaladocTastyInspector import collection.JavaConverters._ import transformers._ @@ -8,7 +8,7 @@ case class Module(rootPackage: Member, members: Map[DRI, Member]) object ScalaModuleProvider: def mkModule()(using ctx: DocContext): Module = - val (result, rootDoc) = DokkaTastyInspector().result() + val (result, rootDoc) = ScaladocTastyInspector().result() val (rootPck, rest) = result.partition(_.name == "API") val packageMembers = (rest ++ rootPck.flatMap(_.members)) .filter(p => p.members.nonEmpty || p.docs.nonEmpty).sortBy(_.name) @@ -22,6 +22,7 @@ object ScalaModuleProvider: val transformers = List( ImplicitMembersExtensionTransformer(), - InheritanceInformationTransformer() + InheritanceInformationTransformer(), + SealedMarksGraphTransformer() ) transformers.foldLeft(original)((module, transformer) => transformer.apply(module)) diff --git a/scaladoc/src/dotty/tools/scaladoc/api.scala b/scaladoc/src/dotty/tools/scaladoc/api.scala index 06e6fe2e7adc..76b6b777e9b1 100644 --- a/scaladoc/src/dotty/tools/scaladoc/api.scala +++ b/scaladoc/src/dotty/tools/scaladoc/api.scala @@ -126,8 +126,9 @@ extension (s: Signature) def join(a: Signature): Signature = s ++ a case class LinkToType(signature: Signature, dri: DRI, kind: Kind) -case class HierarchyGraph(edges: Seq[(LinkToType, LinkToType)]): - private def vertecies: Seq[LinkToType] = edges.flatten((a, b) => Seq(a, b)).distinct + +case class HierarchyGraph(edges: Seq[(LinkToType, LinkToType)], sealedNodes: Set[LinkToType] = Set.empty): + def vertecies: Seq[LinkToType] = edges.flatten((a, b) => Seq(a, b)).distinct def verteciesWithId: Map[LinkToType, Int] = vertecies.zipWithIndex.toMap def +(edge: (LinkToType, LinkToType)): HierarchyGraph = HierarchyGraph((edges :+ edge).distinct) def ++(edges: Seq[(LinkToType, LinkToType)]): HierarchyGraph = edges.foldLeft(this) { @@ -137,7 +138,6 @@ object HierarchyGraph: def empty = HierarchyGraph(Seq.empty) def withEdges(edges: Seq[(LinkToType, LinkToType)]) = HierarchyGraph.empty ++ edges - case class Member( name: String, dri: DRI, diff --git a/scaladoc/src/dotty/tools/scaladoc/renderers/DotDiagramBuilder.scala b/scaladoc/src/dotty/tools/scaladoc/renderers/DotDiagramBuilder.scala index 4a680bc62ca2..e8845dabcfb2 100644 --- a/scaladoc/src/dotty/tools/scaladoc/renderers/DotDiagramBuilder.scala +++ b/scaladoc/src/dotty/tools/scaladoc/renderers/DotDiagramBuilder.scala @@ -5,7 +5,7 @@ import util.HTML._ object DotDiagramBuilder: def build(diagram: HierarchyGraph, renderer: SignatureRenderer)(using DocContext): String = - def getStyle(vertex: LinkToType) = vertex.kind match + def getStyle(kind: Kind) = kind match case _ : Kind.Class => "fill: #45AD7D;" case Kind.Object => "fill: #285577;" case _ : Kind.Trait => "fill: #1CAACF;" @@ -14,8 +14,9 @@ object DotDiagramBuilder: case other => report.error(s"unexpected value: $other") val vWithId = diagram.verteciesWithId + val sealedNodes = diagram.sealedNodes val vertecies = vWithId.map { (vertex, id) => - s"""node${id} [id=node${id}, label="${getHtmlLabel(vertex, renderer)}", style="${getStyle(vertex)}"];\n""" + s"""node${id} [id=node${id}, label="${getHtmlLabel(vertex, renderer, sealedNodes)}", style="${getStyle(vertex.kind)}"];\n""" }.mkString val edges = diagram.edges.map { (from, to) => @@ -29,8 +30,9 @@ object DotDiagramBuilder: |} |""".stripMargin - private def getHtmlLabel(vertex: LinkToType, renderer: SignatureRenderer): String = + private def getHtmlLabel(vertex: LinkToType, renderer: SignatureRenderer, sealedNodes: Set[LinkToType]): String = span(style := "color: #FFFFFF;")( + if sealedNodes.contains(vertex) then "sealed " else "", vertex.kind.name, " ", vertex.signature.map(renderer.renderElementWith(_)) diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/ClassLikeSupport.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/ClassLikeSupport.scala index e45c5b067095..f824538d5f4b 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/ClassLikeSupport.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/ClassLikeSupport.scala @@ -48,7 +48,6 @@ trait ClassLikeSupport: signatureOnly: Boolean = false, modifiers: Seq[Modifier] = classDef.symbol.getExtraModifiers(), ): Member = - def unpackTreeToClassDef(tree: Tree): ClassDef = tree match case tree: ClassDef => tree case TypeDef(_, tbt: TypeBoundsTree) => unpackTreeToClassDef(tbt.tpe.typeSymbol.tree) @@ -73,14 +72,15 @@ trait ClassLikeSupport: } val selfSiangture: DSignature = typeForClass(classDef).asSignature - val graph = HierarchyGraph.withEdges(getSupertypesGraph(classDef, - LinkToType(selfSiangture, classDef.symbol.dri, bareClasslikeKind(classDef.symbol)))) + val graph = HierarchyGraph.withEdges( + getSupertypesGraph(classDef, LinkToType(selfSiangture, classDef.symbol.dri, bareClasslikeKind(classDef.symbol))) + ) val baseMember = mkMember(classDef.symbol, kindForClasslike(classDef), selfSiangture)( - modifiers = modifiers, - graph = graph, - deprecated = classDef.symbol.isDeprecated() - ) + modifiers = modifiers, + graph = graph, + deprecated = classDef.symbol.isDeprecated() + ) if signatureOnly then baseMember else baseMember.copy( members = classDef.extractPatchedMembers, diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/TastyParser.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/TastyParser.scala index adf710ca1dfb..47a98c3a430f 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/TastyParser.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/TastyParser.scala @@ -21,7 +21,7 @@ import java.nio.file.Files * * Delegates most of the work to [[TastyParser]] [[dotty.tools.scaladoc.tasty.TastyParser]]. */ -case class DokkaTastyInspector()(using ctx: DocContext) extends DocTastyInspector: +case class ScaladocTastyInspector()(using ctx: DocContext) extends DocTastyInspector: private val topLevels = Seq.newBuilder[(String, Member)] private var rootDoc: Option[Comment] = None @@ -137,7 +137,7 @@ case class DokkaTastyInspector()(using ctx: DocContext) extends DocTastyInspecto /** Parses a single Tasty compilation unit. */ case class TastyParser( qctx: Quotes, - inspector: DokkaTastyInspector, + inspector: ScaladocTastyInspector, )( isSkipped: qctx.reflect.Symbol => Boolean )( diff --git a/scaladoc/src/dotty/tools/scaladoc/transformers/SealedMarksGraphTransformer.scala b/scaladoc/src/dotty/tools/scaladoc/transformers/SealedMarksGraphTransformer.scala new file mode 100644 index 000000000000..e40e8c795821 --- /dev/null +++ b/scaladoc/src/dotty/tools/scaladoc/transformers/SealedMarksGraphTransformer.scala @@ -0,0 +1,16 @@ +package dotty.tools.scaladoc +package transformers + + +class SealedMarksGraphTransformer(using context: DocContext) extends (Module => Module): + override def apply(original: Module): Module = + val sealedRelations = getSealedRelations(original.rootPackage) + original.updateMembers { m => + m.copy(graph = m.graph.copy(sealedNodes = m.graph.vertecies.filter { v => + sealedRelations.contains(v.dri) + }.toSet)) + } + + private def getSealedRelations(c: Member): Set[DRI] = + val selfMapping = if c.modifiers.contains(Modifier.Sealed) then Set(c.dri) else Set.empty + selfMapping ++ c.members.flatMap(getSealedRelations) diff --git a/scaladoc/src/scala/tasty/inspector/DocTastyInspector.scala b/scaladoc/src/scala/tasty/inspector/DocTastyInspector.scala index 963c1dfc3550..d908c2646f59 100644 --- a/scaladoc/src/scala/tasty/inspector/DocTastyInspector.scala +++ b/scaladoc/src/scala/tasty/inspector/DocTastyInspector.scala @@ -6,4 +6,4 @@ abstract class DocTastyInspector extends OldTastyInspector: def inspectFilesInDocContext( classpath: List[String], filePaths: List[String])( - using Context): Unit = inspectFilesInContext(classpath, filePaths) \ No newline at end of file + using Context): Unit = inspectFilesInContext(classpath, filePaths) diff --git a/scaladoc/test/dotty/dokka/BaseHtmlTest.scala b/scaladoc/test/dotty/tools/scaladoc/BaseHtmlTest.scala similarity index 100% rename from scaladoc/test/dotty/dokka/BaseHtmlTest.scala rename to scaladoc/test/dotty/tools/scaladoc/BaseHtmlTest.scala diff --git a/scaladoc/test/dotty/dokka/ExternalLocationProviderIntegrationTest.scala b/scaladoc/test/dotty/tools/scaladoc/ExternalLocationProviderIntegrationTest.scala similarity index 100% rename from scaladoc/test/dotty/dokka/ExternalLocationProviderIntegrationTest.scala rename to scaladoc/test/dotty/tools/scaladoc/ExternalLocationProviderIntegrationTest.scala diff --git a/scaladoc/test/dotty/dokka/RaportingTest.scala b/scaladoc/test/dotty/tools/scaladoc/RaportingTest.scala similarity index 99% rename from scaladoc/test/dotty/dokka/RaportingTest.scala rename to scaladoc/test/dotty/tools/scaladoc/RaportingTest.scala index e84417b3850a..88f9b7c0f3f3 100644 --- a/scaladoc/test/dotty/dokka/RaportingTest.scala +++ b/scaladoc/test/dotty/tools/scaladoc/RaportingTest.scala @@ -57,4 +57,4 @@ class ReportingTest: assertNoErrors(diag) assertMessagesAbout(diag.infoMsgs)("generation completed successfully") - } \ No newline at end of file + } diff --git a/scaladoc/test/dotty/dokka/ScaladocTest.scala b/scaladoc/test/dotty/tools/scaladoc/ScaladocTest.scala similarity index 94% rename from scaladoc/test/dotty/dokka/ScaladocTest.scala rename to scaladoc/test/dotty/tools/scaladoc/ScaladocTest.scala index 17db7310ec62..8d7574adf13d 100644 --- a/scaladoc/test/dotty/dokka/ScaladocTest.scala +++ b/scaladoc/test/dotty/tools/scaladoc/ScaladocTest.scala @@ -13,7 +13,7 @@ abstract class ScaladocTest(val name: String): def withModule(op: DocContext ?=> Module => Unit) = - given DocContext = testDocContext + given DocContext = testDocContext(tastyFiles(name)) op(ScalaModuleProvider.mkModule()) private def getTempDir() : TemporaryFolder = diff --git a/scaladoc/test/dotty/dokka/SignatureTest.scala b/scaladoc/test/dotty/tools/scaladoc/SignatureTest.scala similarity index 100% rename from scaladoc/test/dotty/dokka/SignatureTest.scala rename to scaladoc/test/dotty/tools/scaladoc/SignatureTest.scala diff --git a/scaladoc/test/dotty/dokka/SignatureTestCases.scala b/scaladoc/test/dotty/tools/scaladoc/SignatureTestCases.scala similarity index 100% rename from scaladoc/test/dotty/dokka/SignatureTestCases.scala rename to scaladoc/test/dotty/tools/scaladoc/SignatureTestCases.scala diff --git a/scaladoc/test/dotty/dokka/SourceLinksTests.scala b/scaladoc/test/dotty/tools/scaladoc/SourceLinksTests.scala similarity index 100% rename from scaladoc/test/dotty/dokka/SourceLinksTests.scala rename to scaladoc/test/dotty/tools/scaladoc/SourceLinksTests.scala diff --git a/scaladoc/test/dotty/dokka/diagram/HierarchyTest.scala b/scaladoc/test/dotty/tools/scaladoc/diagram/HierarchyTest.scala similarity index 99% rename from scaladoc/test/dotty/dokka/diagram/HierarchyTest.scala rename to scaladoc/test/dotty/tools/scaladoc/diagram/HierarchyTest.scala index 5a02b9515994..bd37d814300c 100644 --- a/scaladoc/test/dotty/dokka/diagram/HierarchyTest.scala +++ b/scaladoc/test/dotty/tools/scaladoc/diagram/HierarchyTest.scala @@ -95,7 +95,3 @@ class HierarchyTest extends ScaladocTest("hierarchy"): x.graph.edges.map((a, b) => (a.signature.getName, b.signature.getName)).toSet ) case _ => - - - - diff --git a/scaladoc/test/dotty/tools/scaladoc/diagram/SealedHierarchyTest.scala b/scaladoc/test/dotty/tools/scaladoc/diagram/SealedHierarchyTest.scala new file mode 100644 index 000000000000..288f8b665c2b --- /dev/null +++ b/scaladoc/test/dotty/tools/scaladoc/diagram/SealedHierarchyTest.scala @@ -0,0 +1,30 @@ +package dotty.tools.scaladoc +package diagram + +import dotty.tools.scaladoc.ScaladocTest +import scala.jdk.CollectionConverters.{ListHasAsScala, SeqHasAsJava} +import org.junit.Assert.{assertSame, assertTrue, assertEquals} + +class SealedHierarchyTest extends ScaladocTest("sealedClasses"): + override def runTest = withModule(_.visitMembers(checkMember)) + + def checkMember(x: Member) = x.name match + case "A" => + assertEquals(4, x.graph.sealedNodes.size) + assertEquals( + Set("A", "B1", "C1", "C7"), + x.graph.sealedNodes.map(_.signature.getName) + ) + case "B1" => + assertEquals(4, x.graph.sealedNodes.size) + assertEquals( + Set("A", "B1", "C1", "C7"), + x.graph.sealedNodes.map(_.signature.getName) + ) + case "C1" => + assertEquals(3, x.graph.sealedNodes.size) + assertEquals( + Set("A", "B1", "C1"), + x.graph.sealedNodes.map(_.signature.getName) + ) + case _ => diff --git a/scaladoc/test/dotty/dokka/linking/DriTest.scala b/scaladoc/test/dotty/tools/scaladoc/linking/DriTest.scala similarity index 100% rename from scaladoc/test/dotty/dokka/linking/DriTest.scala rename to scaladoc/test/dotty/tools/scaladoc/linking/DriTest.scala diff --git a/scaladoc/test/dotty/dokka/linking/DriTestCases.scala b/scaladoc/test/dotty/tools/scaladoc/linking/DriTestCases.scala similarity index 100% rename from scaladoc/test/dotty/dokka/linking/DriTestCases.scala rename to scaladoc/test/dotty/tools/scaladoc/linking/DriTestCases.scala diff --git a/scaladoc/test/dotty/dokka/renderers/HtmlTagsTest.scala b/scaladoc/test/dotty/tools/scaladoc/renderers/HtmlTagsTest.scala similarity index 100% rename from scaladoc/test/dotty/dokka/renderers/HtmlTagsTest.scala rename to scaladoc/test/dotty/tools/scaladoc/renderers/HtmlTagsTest.scala diff --git a/scaladoc/test/dotty/dokka/renderers/LocationTests.scala b/scaladoc/test/dotty/tools/scaladoc/renderers/LocationTests.scala similarity index 96% rename from scaladoc/test/dotty/dokka/renderers/LocationTests.scala rename to scaladoc/test/dotty/tools/scaladoc/renderers/LocationTests.scala index ea1f0d925cec..6317cc7bfd08 100644 --- a/scaladoc/test/dotty/dokka/renderers/LocationTests.scala +++ b/scaladoc/test/dotty/tools/scaladoc/renderers/LocationTests.scala @@ -6,7 +6,7 @@ import org.junit.Assert.{assertSame, assertTrue, assertEquals} import dotty.tools.scaladoc.util.HTML._ class LocationTests: - given DocContext = testDocContext + given DocContext = testDocContext() object locations extends Locations: val members = Map.empty @@ -36,4 +36,4 @@ class LocationTests: assertEquals( "../../annotation", path("api/scala/annotation/meta/beanGetter", "api/scala/annotation"), - ) \ No newline at end of file + ) diff --git a/scaladoc/test/dotty/dokka/site/NavigationTest.scala b/scaladoc/test/dotty/tools/scaladoc/site/NavigationTest.scala similarity index 100% rename from scaladoc/test/dotty/dokka/site/NavigationTest.scala rename to scaladoc/test/dotty/tools/scaladoc/site/NavigationTest.scala diff --git a/scaladoc/test/dotty/dokka/site/SiteGeneratationTest.scala b/scaladoc/test/dotty/tools/scaladoc/site/SiteGeneratationTest.scala similarity index 100% rename from scaladoc/test/dotty/dokka/site/SiteGeneratationTest.scala rename to scaladoc/test/dotty/tools/scaladoc/site/SiteGeneratationTest.scala diff --git a/scaladoc/test/dotty/dokka/site/StaticSiteContextTest.scala b/scaladoc/test/dotty/tools/scaladoc/site/StaticSiteContextTest.scala similarity index 100% rename from scaladoc/test/dotty/dokka/site/StaticSiteContextTest.scala rename to scaladoc/test/dotty/tools/scaladoc/site/StaticSiteContextTest.scala diff --git a/scaladoc/test/dotty/dokka/site/TemplateFileTests.scala b/scaladoc/test/dotty/tools/scaladoc/site/TemplateFileTests.scala similarity index 100% rename from scaladoc/test/dotty/dokka/site/TemplateFileTests.scala rename to scaladoc/test/dotty/tools/scaladoc/site/TemplateFileTests.scala diff --git a/scaladoc/test/dotty/dokka/tasty/comments/CommentExpanderTests.scala b/scaladoc/test/dotty/tools/scaladoc/tasty/comments/CommentExpanderTests.scala similarity index 100% rename from scaladoc/test/dotty/dokka/tasty/comments/CommentExpanderTests.scala rename to scaladoc/test/dotty/tools/scaladoc/tasty/comments/CommentExpanderTests.scala diff --git a/scaladoc/test/dotty/dokka/tasty/comments/DocFlexmarkParserTests.scala b/scaladoc/test/dotty/tools/scaladoc/tasty/comments/DocFlexmarkParserTests.scala similarity index 100% rename from scaladoc/test/dotty/dokka/tasty/comments/DocFlexmarkParserTests.scala rename to scaladoc/test/dotty/tools/scaladoc/tasty/comments/DocFlexmarkParserTests.scala diff --git a/scaladoc/test/dotty/dokka/tasty/comments/IntegrationTest.scala b/scaladoc/test/dotty/tools/scaladoc/tasty/comments/IntegrationTest.scala similarity index 100% rename from scaladoc/test/dotty/dokka/tasty/comments/IntegrationTest.scala rename to scaladoc/test/dotty/tools/scaladoc/tasty/comments/IntegrationTest.scala diff --git a/scaladoc/test/dotty/dokka/tasty/comments/MemberLookupTests.scala b/scaladoc/test/dotty/tools/scaladoc/tasty/comments/MemberLookupTests.scala similarity index 100% rename from scaladoc/test/dotty/dokka/tasty/comments/MemberLookupTests.scala rename to scaladoc/test/dotty/tools/scaladoc/tasty/comments/MemberLookupTests.scala diff --git a/scaladoc/test/dotty/dokka/tasty/comments/QueryParserTests.scala b/scaladoc/test/dotty/tools/scaladoc/tasty/comments/QueryParserTests.scala similarity index 100% rename from scaladoc/test/dotty/dokka/tasty/comments/QueryParserTests.scala rename to scaladoc/test/dotty/tools/scaladoc/tasty/comments/QueryParserTests.scala diff --git a/scaladoc/test/dotty/dokka/tasty/util/TestUtils.scala b/scaladoc/test/dotty/tools/scaladoc/tasty/util/TestUtils.scala similarity index 100% rename from scaladoc/test/dotty/dokka/tasty/util/TestUtils.scala rename to scaladoc/test/dotty/tools/scaladoc/tasty/util/TestUtils.scala diff --git a/scaladoc/test/dotty/dokka/testUtils.scala b/scaladoc/test/dotty/tools/scaladoc/testUtils.scala similarity index 96% rename from scaladoc/test/dotty/dokka/testUtils.scala rename to scaladoc/test/dotty/tools/scaladoc/testUtils.scala index 6c1ce1049121..4bab27fb1b70 100644 --- a/scaladoc/test/dotty/dokka/testUtils.scala +++ b/scaladoc/test/dotty/tools/scaladoc/testUtils.scala @@ -58,7 +58,7 @@ def testArgs(files: Seq[File] = Nil, dest: File = new File("notUsed")) = Scalado def testContext = (new ContextBase).initialCtx.fresh.setReporter(new TestReporter) -def testDocContext = DocContext(testArgs(), testContext) +def testDocContext(files: Seq[File] = Nil) = DocContext(testArgs(files), testContext) def tastyFiles(name: String) = def listFilesSafe(dir: File) = Option(dir.listFiles).getOrElse { @@ -69,4 +69,4 @@ def tastyFiles(name: String) = case f if f.getName endsWith ".tasty" => f :: Nil case _ => Nil } - collectFiles(File(s"${BuildInfo.test_testcasesOutputDir}/tests/$name")) \ No newline at end of file + collectFiles(File(s"${BuildInfo.test_testcasesOutputDir}/tests/$name")) diff --git a/scaladoc/test/dotty/dokka/util/JSONTest.scala b/scaladoc/test/dotty/tools/scaladoc/util/JSONTest.scala similarity index 100% rename from scaladoc/test/dotty/dokka/util/JSONTest.scala rename to scaladoc/test/dotty/tools/scaladoc/util/JSONTest.scala