Skip to content

Fix flattened children graph #11209

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
Jan 26, 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
4 changes: 2 additions & 2 deletions scala3doc-testcases/src/tests/hierarchy.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ package hierarchy
trait A1
trait A2[T]
trait A3[A, B]

trait A4

trait B1 extends A1
trait B2 extends A1 with A2[Int]
Expand All @@ -15,7 +15,7 @@ class C1[A, B, C] extends B1 with B2 with B3

trait D1
trait D2[T, R]
trait D3
trait D3 extends A4

class E1 extends C1[Int, String, Boolean] with D1
class E2 extends C1[Int, Boolean, Any] with D2[Int, Boolean] with D3
2 changes: 1 addition & 1 deletion scala3doc/src/dotty/dokka/model/api/api.scala
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ extension[T] (member: Member)
// TODO rename parent and knownChildren
def allMembers: Seq[Member] = compositeMemberExt.fold(Nil)(_.members)
def parents: Seq[LinkToType] = compositeMemberExt.fold(Nil)(_.parents)
def directParents: Seq[Signature] = compositeMemberExt.fold(Nil)(_.directParents)
def directParents: Seq[LinkToType] = compositeMemberExt.fold(Nil)(_.directParents)
def knownChildren: Seq[LinkToType] = compositeMemberExt.fold(Nil)(_.knownChildren)
def companion: Option[DRI] = compositeMemberExt.fold(None)(_.companion)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ object MemberExtension extends BaseKey[Documentable, MemberExtension]:

case class CompositeMemberExtension(
members : Seq[Member] = Nil,
directParents: Seq[Signature] = Nil,
directParents: Seq[LinkToType] = Nil,
parents: Seq[LinkToType] = Nil,
knownChildren: Seq[LinkToType] = Nil,
companion: Option[DRI] = None,
Expand Down
2 changes: 1 addition & 1 deletion scala3doc/src/dotty/dokka/model/api/membersUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ extension (s: Signature)

extension (m: Member)
def getDirectParentsAsStrings: Seq[String] =
m.directParents.map(_.getName).sorted
m.directParents.map(_.signature.getName).sorted
def getParentsAsStrings: Seq[String] =
m.parents.map(_.signature.getName).sorted
def getKnownChildrenAsStrings: Seq[String] =
Expand Down
19 changes: 13 additions & 6 deletions scala3doc/src/dotty/dokka/tasty/ClassLikeSupport.scala
Original file line number Diff line number Diff line change
Expand Up @@ -88,16 +88,16 @@ trait ClassLikeSupport:
val graph = HierarchyGraph.withEdges(getSupertypesGraph(classDef,
LinkToType(selfSiangture, classDef.symbol.dri, bareClasslikeKind(classDef.symbol))))


val compositeExt =
if signatureOnly then CompositeMemberExtension.empty
else CompositeMemberExtension(
classDef.extractPatchedMembers,
classDef.getParents.map(_.dokkaType.asSignature),
classDef.getParentsAsLinkToTypes,
supertypes,
Nil,
classDef.getCompanion
)

mkMember(
classDef.symbol,
MemberExtension(
Expand Down Expand Up @@ -206,7 +206,7 @@ trait ClassLikeSupport:
Kind.Class(Nil, Nil)

parsedClasslike.withKind(
Kind.Given(cls, givenParents, parentTpe.flatMap(extractImplicitConversion))
Kind.Given(cls, givenParents.map(_.signature), parentTpe.flatMap(extractImplicitConversion))
)
}

Expand Down Expand Up @@ -257,13 +257,20 @@ trait ClassLikeSupport:

}

def getParents: List[Tree] =
def getTreeOfFirstParent: Option[Tree] =
c.getParentsAsTreeSymbolTuples.headOption.map(_._1)

def getParentsAsLinkToTypes: List[LinkToType] =
c.getParentsAsTreeSymbolTuples.map {
(tree, symbol) => LinkToType(tree.dokkaType.asSignature, symbol.dri, bareClasslikeKind(symbol))
}

def getParentsAsTreeSymbolTuples: List[(Tree, Symbol)] =
for
parentTree <- c.parents if isValidPos(parentTree.pos) // We assume here that order is correct
parentSymbol = if parentTree.symbol.isClassConstructor then parentTree.symbol.owner else parentTree.symbol
if parentSymbol != defn.ObjectClass && parentSymbol != defn.AnyClass
yield parentTree

yield (parentTree, parentSymbol)

def getConstructors: List[Symbol] = membersToDocument.collect {
case d: DefDef if d.symbol.isClassConstructor && c.constructor.symbol != d.symbol => d.symbol
Expand Down
36 changes: 18 additions & 18 deletions scala3doc/src/dotty/dokka/tasty/TypesSupport.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,32 @@ trait TypesSupport:
self: TastyParser =>
import qctx.reflect._

def getGivenInstance(method: DefDef): Option[Bound] = {
def getGivenInstance(method: DefDef): Option[Bound] =
def extractTypeSymbol(t: Tree): Option[Symbol] = t match
case tpeTree: TypeTree =>
inner(tpeTree.tpe)
case other => None
case tpeTree: TypeTree =>
inner(tpeTree.tpe)
case other => None

def inner(tpe: TypeRepr): Option[Symbol] = tpe match
case ThisType(tpe) => inner(tpe)
case AnnotatedType(tpe, _) => inner(tpe)
case AppliedType(tpe, _) => inner(tpe)
case tp @ TermRef(qual, typeName) =>
qual match
case _: TypeRepr | _: NoPrefix => Some(tp.termSymbol)
case other => None
case tp @ TypeRef(qual, typeName) =>
qual match
case _: TypeRepr | _: NoPrefix => Some(tp.typeSymbol)
case other => None
case ThisType(tpe) => inner(tpe)
case AnnotatedType(tpe, _) => inner(tpe)
case AppliedType(tpe, _) => inner(tpe)
case tp @ TermRef(qual, typeName) =>
qual match
case _: TypeRepr | _: NoPrefix => Some(tp.termSymbol)
case other => None
case tp @ TypeRef(qual, typeName) =>
qual match
case _: TypeRepr | _: NoPrefix => Some(tp.typeSymbol)
case other => None

val typeSymbol = extractTypeSymbol(method.returnTpt)

typeSymbol.map(_.tree).collect {
case c: ClassDef => c.getParents.headOption
case _ => Some(method.returnTpt)
case c: ClassDef => c.getTreeOfFirstParent
case _ => Some(method.returnTpt)
}.flatten.map(_.dokkaType)
}


given TreeSyntax: AnyRef with
extension (tpeTree: Tree)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,15 @@ class InheritanceInformationTransformer(using context: DocContext) extends Modul
override def apply(original: DModule): DModule =
val subtypes = getSupertypes(original.getPackages.get(0)).groupBy(_._1).transform((k, v) => v.map(_._2))
original.updateMembers { m =>
val st: Seq[LinkToType] = subtypes.getOrElse(m.dri, Nil)
val rootMemberWithBareClasslikeKind = m.asLink.copy(kind = bareClasslikeKind(m.kind))
m.withKnownChildren(st).withNewGraphEdges(st.map(_ -> rootMemberWithBareClasslikeKind))
val edges = getEdges(m.asLink.copy(kind = bareClasslikeKind(m.kind)), subtypes)
val st: Seq[LinkToType] = edges.map(_._1).distinct
m.withKnownChildren(st).withNewGraphEdges(edges)
}

private def getEdges(ltt: LinkToType, subtypes: Map[DRI, Seq[LinkToType]]): Seq[(LinkToType, LinkToType)] =
val st: Seq[LinkToType] = subtypes.getOrElse(ltt.dri, Nil)
st.flatMap(s => Seq(s -> ltt) ++ getEdges(s, subtypes))

private def bareClasslikeKind(kind: Kind): Kind = kind match
case _: Kind.Trait => Kind.Trait(Nil, Nil)
case _: Kind.Class => Kind.Class(Nil, Nil)
Expand All @@ -27,5 +31,5 @@ class InheritanceInformationTransformer(using context: DocContext) extends Modul
private def getSupertypes(c: Member): Seq[(DRI, LinkToType)] =
val selfMapping =
if !c.kind.isInstanceOf[Classlike] then Nil
else c.parents.map(_._2 -> c.asLink)
else c.directParents.map(_._2 -> c.asLink)
c.allMembers.flatMap(getSupertypes) ++ selfMapping
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ object ScalaSignatureProvider:
member.directParents match
case Nil => builder
case extendType :: withTypes =>
val extendPart = builder.text(" extends ").signature(extendType)
withTypes.foldLeft(extendPart)((bdr, tpe) => bdr.text(" with ").signature(tpe))
val extendPart = builder.text(" extends ").signature(extendType.signature)
withTypes.foldLeft(extendPart)((bdr, tpe) => bdr.text(" with ").signature(tpe.signature))

private def givenClassSignature(member: Member, cls: Kind.Class, builder: SignatureBuilder): SignatureBuilder =
val prefixes = builder
Expand Down
13 changes: 8 additions & 5 deletions scala3doc/test/dotty/dokka/diagram/HierarchyTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class HierarchyTest extends ScaladocTest("hierarchy"):
)
}
if (x.getName == "E2") {
assertEquals(List("A1", "A2[Int]", "A3[Int, String]", "Any", "B1", "B2", "B3", "C1[Int, Boolean, Any]", "D2[Int, Boolean]", "D3", "Matchable", "Object"), x.getParentsAsStrings)
assertEquals(List("A1", "A2[Int]", "A3[Int, String]", "A4", "Any", "B1", "B2", "B3", "C1[Int, Boolean, Any]", "D2[Int, Boolean]", "D3", "Matchable", "Object"), x.getParentsAsStrings)
assertEquals(List("C1[Int, Boolean, Any]", "D2[Int, Boolean]", "D3"), x.getDirectParentsAsStrings)
assertEquals(List.empty, x.getKnownChildrenAsStrings)
val graph = MemberExtension.getFrom(x).map(_.graph)
Expand All @@ -55,6 +55,7 @@ class HierarchyTest extends ScaladocTest("hierarchy"):
"A1" -> "Object",
"A2[Int]" -> "Object",
"A3[Int, String]" -> "Object",
"A4" -> "Object",
"B1" -> "Object",
"B1" -> "A1",
"B2" -> "Object",
Expand All @@ -72,6 +73,7 @@ class HierarchyTest extends ScaladocTest("hierarchy"):
"E2" -> "D2[Int, Boolean]",
"E2" -> "D3",
"D2[Int, Boolean]" -> "Object",
"D3" -> "A4",
"D3" -> "Object",
"E2" -> "C1[Int, Boolean, Any]"
),
Expand All @@ -90,11 +92,12 @@ class HierarchyTest extends ScaladocTest("hierarchy"):
"Matchable" -> "Any",
"Object" -> "Any",
"A2[T]" -> "Object",
"B2" -> "A2[T]", // These are not actually true, becuase we lose information about hierarchy in subtypes and their possible mapping to supertypes other that that type itself, e. g. linking to `Object`
"B2" -> "A2[T]",
"B3" -> "A2[T]",
"C1[A, B, C]" -> "A2[T]",
"E1" -> "A2[T]",
"E2" -> "A2[T]"
"C1[A, B, C]" -> "B2",
"C1[A, B, C]" -> "B3",
"E1" -> "C1[A, B, C]",
"E2" -> "C1[A, B, C]"
),
graph.get.edges.map((a, b) => (a.signature.getName, b.signature.getName)).toSet
)
Expand Down