Skip to content

Commit

Permalink
Merge pull request #11232 from BarkingBad/scala3doc/sealed-classes
Browse files Browse the repository at this point in the history
Add sealed keyword to nodes in graphs"
  • Loading branch information
BarkingBad committed Feb 9, 2021
2 parents 585c5e6 + 2b86d82 commit ef48716
Show file tree
Hide file tree
Showing 34 changed files with 99 additions and 30 deletions.
24 changes: 24 additions & 0 deletions scaladoc-testcases/src/tests/sealedClasses.scala
Original file line number Diff line number Diff line change
@@ -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

2 changes: 1 addition & 1 deletion scaladoc-testcases/src/tests/shadowingDRI.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ class S:
class R:
def findThisDeclaration = 1

given R: A[B] with {}
given R: A[B] with {}
7 changes: 4 additions & 3 deletions scaladoc/src/dotty/tools/scaladoc/ScalaModuleCreator.scala
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package dotty.tools.scaladoc

import dotty.tools.scaladoc.tasty.DokkaTastyInspector
import dotty.tools.scaladoc.tasty.ScaladocTastyInspector
import collection.JavaConverters._
import transformers._

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)
Expand All @@ -22,6 +22,7 @@ object ScalaModuleProvider:

val transformers = List(
ImplicitMembersExtensionTransformer(),
InheritanceInformationTransformer()
InheritanceInformationTransformer(),
SealedMarksGraphTransformer()
)
transformers.foldLeft(original)((module, transformer) => transformer.apply(module))
6 changes: 3 additions & 3 deletions scaladoc/src/dotty/tools/scaladoc/api.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;"
Expand All @@ -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) =>
Expand All @@ -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(_))
Expand Down
14 changes: 7 additions & 7 deletions scaladoc/src/dotty/tools/scaladoc/tasty/ClassLikeSupport.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions scaladoc/src/dotty/tools/scaladoc/tasty/TastyParser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
)(
Expand Down
Original file line number Diff line number Diff line change
@@ -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)
2 changes: 1 addition & 1 deletion scaladoc/src/scala/tasty/inspector/DocTastyInspector.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ abstract class DocTastyInspector extends OldTastyInspector:
def inspectFilesInDocContext(
classpath: List[String],
filePaths: List[String])(
using Context): Unit = inspectFilesInContext(classpath, filePaths)
using Context): Unit = inspectFilesInContext(classpath, filePaths)
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,4 @@ class ReportingTest:
assertNoErrors(diag)

assertMessagesAbout(diag.infoMsgs)("generation completed successfully")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,3 @@ class HierarchyTest extends ScaladocTest("hierarchy"):
x.graph.edges.map((a, b) => (a.signature.getName, b.signature.getName)).toSet
)
case _ =>




Original file line number Diff line number Diff line change
@@ -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 _ =>
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -36,4 +36,4 @@ class LocationTests:
assertEquals(
"../../annotation",
path("api/scala/annotation/meta/beanGetter", "api/scala/annotation"),
)
)
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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"))
collectFiles(File(s"${BuildInfo.test_testcasesOutputDir}/tests/$name"))

0 comments on commit ef48716

Please sign in to comment.