Skip to content

Add sealed keyword to nodes in graphs" #11232

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"))