Skip to content

Commit a34130f

Browse files
authored
Merge pull request #10745 from lampepfl/scala3doc-overrides-info
Add overrides path hint as a biref comment
2 parents b9f9347 + abea617 commit a34130f

File tree

11 files changed

+85
-57
lines changed

11 files changed

+85
-57
lines changed

scala3doc-testcases/src/tests/givenDRI.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,4 @@ class S:
3131
def a = 3
3232

3333
given R: A[Int] with
34-
def a = 5
34+
def a = 5
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package tests
2+
package overrides
3+
4+
class A:
5+
def defInt: Int = 1
6+
7+
class B extends A:
8+
override def defInt: Int = 2
9+
10+
class C extends B:
11+
override def defInt: Int = 3

scala3doc/src/dotty/dokka/model/api/api.scala

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,15 @@ enum Kind(val name: String){
7171
}
7272

7373
enum Origin:
74-
case InheritedFrom(name: String, dri: DRI)
7574
case ImplicitlyAddedBy(name: String, dri: DRI)
7675
case ExtensionFrom(name: String, dri: DRI)
7776
case ExportedFrom(name: String, dri: Option[DRI])
78-
case DefinedWithin
77+
case Overrides(overridenMembers: Seq[Overriden])
78+
case RegularlyDefined
79+
80+
case class Overriden(name: String, dri: DRI)
81+
82+
case class InheritedFrom(name: String, dri: DRI)
7983

8084
case class Annotation(val dri: DRI, val params: List[Annotation.AnnotationParameter])
8185

@@ -130,7 +134,8 @@ extension[T] (member: Member)
130134

131135
def modifiers: Seq[dotty.dokka.model.api.Modifier] = memberExt.fold(Nil)(_.modifiers)
132136
def kind: Kind = memberExt.fold(Kind.Unknown)(_.kind)
133-
def origin: Origin = memberExt.fold(Origin.DefinedWithin)(_.origin)
137+
def origin: Origin = memberExt.fold(Origin.RegularlyDefined)(_.origin)
138+
def inheritedFrom: Option[InheritedFrom] = memberExt.fold(None)(_.inheritedFrom)
134139
def annotations: List[Annotation] = memberExt.fold(Nil)(_.annotations)
135140
def sources: Option[TastyDocumentableSource] = memberExt.fold(None)(_.sources)
136141
def name = member.getName
@@ -142,7 +147,8 @@ extension[T] (member: Member)
142147
def directParents: Seq[Signature] = compositeMemberExt.fold(Nil)(_.directParents)
143148
def knownChildren: Seq[LinkToType] = compositeMemberExt.fold(Nil)(_.knownChildren)
144149

145-
def membersBy(op: Member => Boolean): (Seq[Member], Seq[Member]) = allMembers.filter(op).partition(_.origin == Origin.DefinedWithin)
150+
def membersBy(op: Member => Boolean): Seq[Member] = allMembers.filter(op)
151+
def membersByWithInheritancePartition(op: Member => Boolean): (Seq[Member], Seq[Member]) = membersBy(op).partition(_.inheritedFrom.isEmpty)
146152

147153

148154
extension (module: DModule)

scala3doc/src/dotty/dokka/model/api/internalExtensions.scala

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ private [model] case class MemberExtension(
2727
annotations: List[Annotation],
2828
signature: Signature,
2929
sources: Option[TastyDocumentableSource] = None,
30-
origin: Origin = Origin.DefinedWithin,
30+
origin: Origin = Origin.RegularlyDefined,
31+
inheritedFrom: Option[InheritedFrom] = None,
3132
graph: HierarchyGraph = HierarchyGraph.empty,
3233
) extends ExtraProperty[Documentable]:
3334
override def getKey = MemberExtension
@@ -67,6 +68,10 @@ extension (member: Member)
6768
val ext = MemberExtension.getFrom(member).getOrElse(MemberExtension.empty).copy(origin = origin)
6869
putInMember(ext)
6970

71+
def withInheritedFrom(inheritedFrom: InheritedFrom): Member =
72+
val ext = MemberExtension.getFrom(member).getOrElse(MemberExtension.empty).copy(inheritedFrom = Some(inheritedFrom))
73+
putInMember(ext)
74+
7075
def withKind(kind: Kind): Member =
7176
val ext = MemberExtension.getFrom(member).getOrElse(MemberExtension.empty).copy(kind = kind)
7277
putInMember(ext)

scala3doc/src/dotty/dokka/tasty/ClassLikeSupport.scala

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ trait ClassLikeSupport:
186186
private def parseInheritedMember(s: Tree): Option[Member] = processTreeOpt(s)(s match
187187
case c: ClassDef if c.symbol.shouldDocumentClasslike && !c.symbol.isGiven => Some(parseClasslike(c, signatureOnly = true))
188188
case other => parseMember(other)
189-
).map(_.withOrigin(Origin.InheritedFrom(s.symbol.owner.normalizedName, s.symbol.owner.dri)))
189+
).map(_.withInheritedFrom(InheritedFrom(s.symbol.owner.normalizedName, s.symbol.owner.dri)))
190190

191191
extension (c: ClassDef)
192192
def membersToDocument = c.body.filterNot(_.symbol.isHiddenByVisibility)
@@ -320,6 +320,20 @@ trait ClassLikeSupport:
320320

321321
val name = method.symbol.normalizedName
322322

323+
val memberExtension = MemberExtension(
324+
methodSymbol.getVisibility(),
325+
methodSymbol.getExtraModifiers(),
326+
methodKind,
327+
methodSymbol.getAnnotations(),
328+
method.returnTpt.dokkaType.asSignature,
329+
methodSymbol.source
330+
)
331+
332+
val memberExtensionWithOrigin =
333+
if methodSymbol.isOverriden then memberExtension.copy(
334+
origin = Origin.Overrides(methodSymbol.allOverriddenSymbols.map(_.owner).map(s => Overriden(s.name, s.dri)).toSeq)
335+
) else memberExtension
336+
323337
new DFunction(
324338
methodSymbol.dri,
325339
name,
@@ -337,14 +351,7 @@ trait ClassLikeSupport:
337351
/*isExpectActual =*/ false,
338352
PropertyContainer.Companion.empty()
339353
plus MethodExtension(paramLists.map(_.size))
340-
plus(MemberExtension(
341-
methodSymbol.getVisibility(),
342-
methodSymbol.getExtraModifiers(),
343-
methodKind,
344-
methodSymbol.getAnnotations(),
345-
method.returnTpt.dokkaType.asSignature,
346-
methodSymbol.source
347-
))
354+
plus(memberExtensionWithOrigin)
348355
)
349356

350357
def parseArgument(argument: ValDef, prefix: Symbol => String, isExtendedSymbol: Boolean = false, isGrouped: Boolean = false): DParameter =

scala3doc/src/dotty/dokka/tasty/SymOps.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ class SymOps[Q <: Quotes](val q: Q):
8484

8585
def isExported: Boolean = sym.flags.is(Flags.Exported)
8686

87+
def isOverriden: Boolean = sym.flags.is(Flags.Override)
88+
8789
def isExtensionMethod: Boolean = sym.flags.is(Flags.ExtensionMethod)
8890

8991
def isLeftAssoc(d: Symbol): Boolean = !d.name.endsWith(":")

scala3doc/src/dotty/dokka/transformers/ImplicitMembersExtensionTransformer.scala

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,14 @@ class ImplicitMembersExtensionTransformer(ctx: DokkaContext) extends Documentabl
4040

4141
val MyDri = c.getDri
4242
def collectApplicableMembers(source: Member): Seq[Member] = source.allMembers.flatMap {
43-
case m @ Member(_, _, _, Kind.Extension(ExtensionTarget(_, _, MyDri, _)), Origin.DefinedWithin) =>
43+
case m @ Member(_, _, _, Kind.Extension(ExtensionTarget(_, _, MyDri, _)), Origin.RegularlyDefined) =>
4444
Seq(m.withOrigin(Origin.ExtensionFrom(source.name, source.dri)).withKind(Kind.Def))
45-
case m @ Member(_, _, _, conversionProvider: ImplicitConversionProvider, Origin.DefinedWithin) =>
45+
case m @ Member(_, _, _, conversionProvider: ImplicitConversionProvider, Origin.RegularlyDefined) =>
4646
conversionProvider.conversion match
4747
case Some(ImplicitConversion(MyDri, to)) =>
4848
classlikeMap.get(to).toSeq.flatMap { owner =>
4949
val newMembers = owner.allMembers.filter(_.origin match
50-
case Origin.DefinedWithin => true
51-
case Origin.InheritedFrom(_, _) => true
50+
case Origin.RegularlyDefined => true
5251
case _ => false
5352
)
5453
newMembers.map(_.withOrigin(Origin.ImplicitlyAddedBy(m.name, m.dri)))

scala3doc/src/dotty/dokka/translators/FilterAttributes.scala

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,34 +19,27 @@ import dotty.dokka.model.api._
1919
import dotty.dokka._
2020

2121
object FilterAttributes:
22-
def attributesFor(documentable: Documentable): Map[String, String] =
23-
val base = visibity(documentable) ++ visibity(documentable) ++ origin(documentable) ++ keywords(documentable)
22+
def attributesFor(m: Member): Map[String, String] =
23+
val base = visibity(m) ++ visibity(m) ++ origin(m) ++ keywords(m) ++ inheritedFrom(m)
2424
base.filter(_._2.nonEmpty)
2525

26-
private def keywords(documentable: Documentable): Map[String, String] = documentable match
27-
case v: Member =>
28-
Map("keywords" -> v.modifiers.map(_.name).mkString(","))
29-
case null =>
30-
Map.empty
31-
32-
33-
private def visibity(documentable: Documentable): Map[String, String] = documentable match
34-
case v: Member =>
35-
Map("visibility" -> v.visibility.name)
36-
case null =>
37-
Map.empty
38-
39-
40-
private def origin(documentable: Documentable): Map[String, String] = documentable match
41-
case v: Member =>
42-
v.origin match
43-
case Origin.InheritedFrom(name, _) => Map("inherited" -> name)
44-
case Origin.ImplicitlyAddedBy(name, _) => Map("implicitly" -> s"by $name")
45-
case Origin.ExtensionFrom(name, _) => Map("extension" -> s"from $name")
46-
case Origin.ExportedFrom(name, _) => Map("export" -> s"from $name")
47-
case _ => Map.empty
48-
case null =>
49-
Map.empty
26+
private def keywords(m: Member): Map[String, String] =
27+
Map("keywords" -> m.modifiers.map(_.name).mkString(","))
28+
29+
30+
private def visibity(m: Member): Map[String, String] =
31+
Map("visibility" -> m.visibility.name)
32+
33+
private def inheritedFrom(m: Member): Map[String, String] = m.inheritedFrom match
34+
case Some(InheritedFrom(name, _)) => Map("inherited" -> name)
35+
case _ => Map.empty
36+
37+
private def origin(m: Member): Map[String, String] = m.origin match
38+
case Origin.ImplicitlyAddedBy(name, _) => Map("implicitly" -> s"by $name")
39+
case Origin.ExtensionFrom(name, _) => Map("extension" -> s"from $name")
40+
case Origin.ExportedFrom(name, _) => Map("export" -> s"from $name")
41+
case _ => Map.empty
42+
5043

5144
def defaultValues = Map(
5245
"inherited" -> "Not inherited",

scala3doc/src/dotty/dokka/translators/ScalaContentBuilder.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,10 @@ class ScalaPageContentBuilder(
492492
case Some(dri: DRI) => SLink(name, dri)
493493
case None => name
494494
Signature("Exported from ", signatureName)
495+
case Origin.Overrides(overridenMembers) =>
496+
def intersperse(xs: Seq[SLink]): Seq[(String | SLink)] =
497+
xs.flatMap(Seq(_, " -> ")).dropRight(1).asInstanceOf[Seq[(String | SLink)]] // dropRight returns `Seq[Object]`
498+
Signature("Definition classes: ").join(Signature(intersperse(overridenMembers.map(SLink(_, _))):_*))
495499
case _ => Nil
496500
}
497501
val styles: Set[Style] = if documentable.deprecated.isDefined then Set(TextStyle.Strikethrough) else Set.empty

scala3doc/src/dotty/dokka/translators/ScalaPageCreator.scala

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class ScalaPageCreator(
4040
page.modified(name, page.getChildren)
4141

4242
private def pagesForMembers(p: Member): Seq[PageNode] =
43-
p.allMembers.filter(_.origin == Origin.DefinedWithin).collect {
43+
p.allMembers.filter(m => m.origin == Origin.RegularlyDefined && m.inheritedFrom.isEmpty).collect {
4444
case f: DFunction => updatePageNameForMember(pageForFunction(f), f)
4545
case c: DClass => updatePageNameForMember(pageForDClass(c), c)
4646
}
@@ -365,14 +365,14 @@ class ScalaPageCreator(
365365
}.toSeq
366366

367367

368-
val (definedMethods, inheritedMethods) = s.membersBy(_.kind == Kind.Def)
369-
val (definedFields, inheritedFiles) = s.membersBy(m => m.kind == Kind.Val || m.kind == Kind.Var)
370-
val (definedClasslikes, inheritedClasslikes) = s.membersBy(m => m.kind.isInstanceOf[Classlike])
371-
val (definedTypes, inheritedTypes) = s.membersBy(_.kind.isInstanceOf[Kind.Type])
372-
val (definedGivens, inheritedGives) = s.membersBy(_.kind.isInstanceOf[Kind.Given])
373-
val (definedExtensions, inheritedExtensions) = s.membersBy(_.kind.isInstanceOf[Kind.Extension])
374-
val exports = s.allMembers.filter(_.kind == Kind.Exported)
375-
val (definedImplicits, inheritedImplicits) = s.membersBy(_.kind.isInstanceOf[Kind.Implicit])
368+
val (definedMethods, inheritedMethods) = s.membersByWithInheritancePartition(_.kind == Kind.Def)
369+
val (definedFields, inheritedFiles) = s.membersByWithInheritancePartition(m => m.kind == Kind.Val || m.kind == Kind.Var)
370+
val (definedClasslikes, inheritedClasslikes) = s.membersByWithInheritancePartition(m => m.kind.isInstanceOf[Classlike])
371+
val (definedTypes, inheritedTypes) = s.membersByWithInheritancePartition(_.kind.isInstanceOf[Kind.Type])
372+
val (definedGivens, inheritedGives) = s.membersByWithInheritancePartition(_.kind.isInstanceOf[Kind.Given])
373+
val (definedExtensions, inheritedExtensions) = s.membersByWithInheritancePartition(_.kind.isInstanceOf[Kind.Extension])
374+
val (definedExports, inheritedExports) = s.membersByWithInheritancePartition(_.kind == Kind.Exported)
375+
val (definedImplicits, inheritedImplicits) = s.membersByWithInheritancePartition(_.kind.isInstanceOf[Kind.Implicit])
376376

377377
b
378378
.contentForComments(s)
@@ -403,13 +403,14 @@ class ScalaPageCreator(
403403
DocumentableGroup(Some("Inherited implicits"), inheritedImplicits)
404404
)
405405
.documentableTab("Exports")(
406-
DocumentableGroup(Some("Defined exports"), exports)
406+
DocumentableGroup(Some("Defined exports"), definedExports),
407+
DocumentableGroup(Some("Inherited exports"), inheritedExports),
407408
)
408409

409410

410411
def contentForEnum(c: DClass) =
411412
b.documentableTab("Enum entries")(
412-
DocumentableGroup(None, c.membersBy(_.kind == Kind.EnumCase)._1) // Enum entries cannot be inherited
413+
DocumentableGroup(None, c.membersBy(_.kind == Kind.EnumCase)) // Enum entries cannot be inherited
413414
)
414415

415416

scala3doc/test/dotty/dokka/linking/DriTest.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,4 @@ abstract class DriTest(testName: String) extends ScaladocTest(testName):
2929
extension (m: DModule) private def collectMembers = m.getPackages.asScala.toList.flatMap(collectFrom)
3030

3131
private def collectFrom(m: Member): Seq[Member] =
32-
m +: m.allMembers.filter(_.origin == Origin.DefinedWithin).flatMap(collectFrom)
32+
m +: m.allMembers.filter(_.origin == Origin.RegularlyDefined).flatMap(collectFrom)

0 commit comments

Comments
 (0)