Skip to content

Fix cast exception while traversing supertypes in Scala3doc #11123

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 15, 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
2 changes: 1 addition & 1 deletion scala3doc-testcases/src/tests/fieldsSignatures.scala
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,4 @@ object Documentation
{
val valInsideDocObject: Nothing
= ???
}
}
29 changes: 16 additions & 13 deletions scala3doc/src/dotty/dokka/tasty/ClassLikeSupport.scala
Original file line number Diff line number Diff line change
Expand Up @@ -61,20 +61,23 @@ trait ClassLikeSupport:
modifiers: Seq[Modifier] = classDef.symbol.getExtraModifiers(),
): Member =

// This Try is here because of problem that code compiles, but at runtime fails claiming
// java.lang.ClassCastException: class dotty.tools.dotc.ast.Trees$DefDef cannot be cast to class dotty.tools.dotc.ast.Trees$TypeDef (dotty.tools.dotc.ast.Trees$DefDef and dotty.tools.dotc.ast.Trees$TypeDef are in unnamed module of loader 'app')
// It is probably bug in Tasty
def hackGetParents(classDef: ClassDef): Option[List[Tree]] = scala.util.Try(classDef.parents).toOption

def getSupertypesGraph(classDef: ClassDef, link: LinkToType): Seq[(LinkToType, LinkToType)] =
def unpackTreeToClassDef(tree: Tree): ClassDef = tree match
case tree: ClassDef => tree
case TypeDef(_, tbt: TypeBoundsTree) => unpackTreeToClassDef(tbt.tpe.typeSymbol.tree)
case TypeDef(_, tt: TypeTree) => unpackTreeToClassDef(tt.tpe.typeSymbol.tree)
case c: Apply =>
c.symbol.owner.tree.symbol.tree match
case tree: ClassDef => tree
case tt: TypeTree => unpackTreeToClassDef(tt.tpe.typeSymbol.tree)

def getSupertypesGraph(classDef: Tree, link: LinkToType): Seq[(LinkToType, LinkToType)] =
val smbl = classDef.symbol
val parents = if smbl.exists then hackGetParents(smbl.tree.asInstanceOf[ClassDef]) else None
parents.fold(Seq())(_.flatMap { case tree =>
val symbol = if tree.symbol.isClassConstructor then tree.symbol.owner else tree.symbol
val superLink = LinkToType(tree.dokkaType.asSignature, symbol.dri, bareClasslikeKind(symbol))
Seq(link -> superLink) ++ getSupertypesGraph(tree.asInstanceOf[ClassDef], superLink)
}
)
val parents = unpackTreeToClassDef(classDef).parents
parents.flatMap { case tree =>
val symbol = if tree.symbol.isClassConstructor then tree.symbol.owner else tree.symbol
val superLink = LinkToType(tree.dokkaType.asSignature, symbol.dri, bareClasslikeKind(symbol))
Seq(link -> superLink) ++ getSupertypesGraph(tree, superLink)
}

val supertypes = getSupertypes(using qctx)(classDef).map {
case (symbol, tpe) =>
Expand Down
30 changes: 15 additions & 15 deletions scala3doc/test/dotty/dokka/diagram/HierarchyTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -52,21 +52,21 @@ class HierarchyTest extends ScaladocTest("hierarchy"):
assertEquals(
Set(
"Object" -> "Any",
// "A1" -> "Object", // These are not applicable beacuase of bug and its workaround
// "A2[Int]" -> "Object", // More info at ClassLikeSupport.scala:37
// "A3[Int, String]" -> "Object",
// "B1" -> "Object",
// "B1" -> "A1",
// "B2" -> "Object",
// "B2" -> "A1",
// "B2" -> "A2[Int]",
// "B3" -> "Object",
// "B3" -> "A2[Int]",
// "B3" -> "A3[Int, String]",
// "C1[Int, Boolean, Any]" -> "Object",
// "C1[Int, Boolean, Any]" -> "B1",
// "C1[Int, Boolean, Any]" -> "B2",
// "C1[Int, Boolean, Any]" -> "B3",
"A1" -> "Object",
"A2[Int]" -> "Object",
"A3[Int, String]" -> "Object",
"B1" -> "Object",
"B1" -> "A1",
"B2" -> "Object",
"B2" -> "A1",
"B2" -> "A2[Int]",
"B3" -> "Object",
"B3" -> "A2[Int]",
"B3" -> "A3[Int, String]",
"C1[Int, Boolean, Any]" -> "Object",
"C1[Int, Boolean, Any]" -> "B1",
"C1[Int, Boolean, Any]" -> "B2",
"C1[Int, Boolean, Any]" -> "B3",
"Object" -> "Matchable",
"Matchable" -> "Any",
"E2" -> "D2[Int, Boolean]",
Expand Down