Skip to content

Commit 17d2f45

Browse files
authored
Merge pull request #14125 from dotty-staging/scaladoc-fixes
Scaladoc: Fix filtering extensions. Better support for exports
2 parents c94b333 + 05c41ba commit 17d2f45

File tree

12 files changed

+112
-53
lines changed

12 files changed

+112
-53
lines changed

scaladoc-testcases/src/tests/exports.scala

-23
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package tests
2+
package exports1
3+
4+
class A: //unexpected
5+
def aDefInt: Int
6+
= 1
7+
def aDef1: 1
8+
= 1
9+
val aValInt: Int
10+
= 1
11+
val aVal1: 1
12+
= 1
13+
var aVarInt: Int
14+
= 1
15+
var aVar1: 1
16+
= 1
17+
type HKT[T[_], X] //expected: final type HKT = [T[_], X] =>> HKT[T, X]
18+
= T[X]
19+
type SomeRandomType = (List[_] | Seq[_]) & String //expected: final type SomeRandomType = SomeRandomType
20+
def x[T[_], X](x: X): HKT[T, X]
21+
= ???
22+
def fn[T, U]: T => U
23+
= ???
24+
object Object //expected: val Obj: Object.type
25+
val x: HKT[List, Int]
26+
= ???
27+
class Class(val a: Int, val b: Int) extends Serializable //expected: final type Class = Class
28+
enum Enum: //expected: final type Enum = Enum
29+
case A
30+
case B(i: Int)
31+
case C[T]() extends Enum
32+
33+
object X: //unexpected
34+
def xDefInt: Int
35+
= 1
36+
def xDef1: 1
37+
= 1
38+
val xValInt: Int
39+
= 1
40+
val xVal1: 1
41+
= 1
42+
var xVarInt: Int
43+
= 1
44+
var xVar1: 1
45+
= 1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package tests
2+
package exports2
3+
4+
import exports1._
5+
6+
class B:
7+
val a: A
8+
= new A
9+
export a.{Object => Obj, _}
10+
export X._
11+
def obj: Obj.type
12+
= Obj

scaladoc/resources/dotty_res/scripts/components/DocumentableList.js

+7
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@ class DocumentableList extends Component {
4747
return isElementVisible;
4848
}).length;
4949

50+
findRefs("span.groupHeader", listRef).forEach(h => {
51+
const headerSiblings = this.state.list.getSectionListElementsRefs(h.parentNode).map(ref => this.state.list.toListElement(ref))
52+
const isHeaderVisible = headerSiblings.filter(s => this.state.list.isElementVisible(s, filter)) != 0
53+
54+
this.toggleDisplayStyles(isHeaderVisible, h)
55+
})
56+
5057
this.toggleDisplayStyles(isListVisible, listRef);
5158

5259
return isListVisible;

scaladoc/src/dotty/tools/scaladoc/api.scala

+6-2
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ enum Kind(val name: String):
6464
case Constructor(base: Kind.Def) extends Kind("def")
6565
case Var extends Kind("var")
6666
case Val extends Kind("val")
67-
case Exported(m: Kind.Def) extends Kind("export")
67+
case Exported(base: Kind) extends Kind("export")
6868
case Type(concreate: Boolean, opaque: Boolean, typeParams: Seq[TypeParameter])
6969
extends Kind("type") // should we handle opaque as modifier?
7070
case Given(kind: Def | Class | Val.type, as: Option[Signature], conversion: Option[ImplicitConversion])
@@ -76,7 +76,7 @@ enum Kind(val name: String):
7676
enum Origin:
7777
case ImplicitlyAddedBy(name: String, dri: DRI)
7878
case ExtensionFrom(name: String, dri: DRI)
79-
case ExportedFrom(name: String, dri: Option[DRI])
79+
case ExportedFrom(link: Option[Link])
8080
case Overrides(overriddenMembers: Seq[Overridden])
8181
case RegularlyDefined
8282

@@ -186,8 +186,12 @@ extension[T] (member: Member)
186186
def asLink: LinkToType = LinkToType(member.signature, member.dri, member.kind)
187187
def membersBy(op: Member => Boolean): Seq[Member] = member.members.filter(op)
188188

189+
def withDRI(dri: DRI): Member = member.copy(dri = dri)
190+
189191
def withMembers(newMembers: Seq[Member]): Member = member.copy(members = newMembers)
190192

193+
def withName(name: String): Member = member.copy(name = name)
194+
191195
def updateRecusivly(op: Member => Member): Member =
192196
val newMembers = member.members.map(_.updateRecusivly(op))
193197
op(member).withMembers(newMembers)

scaladoc/src/dotty/tools/scaladoc/renderers/MemberRenderer.scala

+5-6
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,9 @@ class MemberRenderer(signatureRenderer: SignatureRenderer)(using DocContext) ext
120120
Seq("Implicitly added by ", renderLink(name, dri))
121121
case Origin.ExtensionFrom(name, dri) =>
122122
Seq("Extension method from ", renderLink(name, dri))
123-
case Origin.ExportedFrom(name, dri) =>
124-
val signatureName: TagArg = dri match
125-
case Some(dri: DRI) => renderLink(name, dri)
126-
case None => name
123+
case Origin.ExportedFrom(Some(link)) =>
124+
val signatureName: TagArg = link match
125+
case Link(name, dri) => renderLink(name, dri)
127126
Seq("Exported from ", signatureName)
128127
case _ => Nil
129128
}
@@ -132,7 +131,7 @@ class MemberRenderer(signatureRenderer: SignatureRenderer)(using DocContext) ext
132131
val depStyle = if member.deprecated.isEmpty then "" else "deprecated"
133132
val nameClasses = cls := s"documentableName $depStyle"
134133

135-
val rawBuilder = ScalaSignatureProvider.rawSignature(member, InlineSignatureBuilder())
134+
val rawBuilder = ScalaSignatureProvider.rawSignature(member, InlineSignatureBuilder())()
136135
val inlineBuilder = rawBuilder.asInstanceOf[InlineSignatureBuilder]
137136
val kind :: modifiersRevered = inlineBuilder.preName
138137
val signature = inlineBuilder.names.reverse
@@ -287,7 +286,7 @@ class MemberRenderer(signatureRenderer: SignatureRenderer)(using DocContext) ext
287286
.functionParameters(on.argsLists)
288287
.asInstanceOf[InlineSignatureBuilder].names.reverse
289288
val sig = typeSig ++ Signature(Plain(s"(${on.name}: ")) ++ on.signature ++ Signature(Plain(")")) ++ argsSig
290-
MGroup(span(sig.map(renderElement)), members.sortBy(_.name).toSeq, on.name)
289+
MGroup(span(cls := "groupHeader")(sig.map(renderElement)), members.sortBy(_.name).toSeq, on.name)
291290
}.toSeq
292291

293292
div(cls := "membersList")(renderTabs(

scaladoc/src/dotty/tools/scaladoc/renderers/Resources.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ trait Resources(using ctx: DocContext) extends Locations, Writer:
145145
case m: Member if m.kind != Kind.RootPackage =>
146146
val descr = m.dri.asFileLocation
147147
def processMember(member: Member): Seq[JSON] =
148-
val signatureBuilder = ScalaSignatureProvider.rawSignature(member, InlineSignatureBuilder()).asInstanceOf[InlineSignatureBuilder]
148+
val signatureBuilder = ScalaSignatureProvider.rawSignature(member, InlineSignatureBuilder())().asInstanceOf[InlineSignatureBuilder]
149149
val sig = Signature(Plain(s"${member.kind.name} "), Plain(member.name)) ++ signatureBuilder.names.reverse
150150
val entry = mkEntry(member.dri, member.name, flattenToText(sig), descr, member.kind.name)
151151
val children = member

scaladoc/src/dotty/tools/scaladoc/tasty/ClassLikeSupport.scala

+27-15
Original file line numberDiff line numberDiff line change
@@ -149,21 +149,23 @@ trait ClassLikeSupport:
149149
}
150150

151151
case dd: DefDef if !dd.symbol.isHiddenByVisibility && dd.symbol.isExported && !dd.symbol.isArtifact =>
152-
val exportedTarget = dd.rhs.collect {
153-
case a: Apply => a.fun.asInstanceOf[Select]
154-
case s: Select => s
152+
dd.rhs.map {
153+
case TypeApply(rhs, _) => rhs
154+
case Apply(TypeApply(rhs, _), _) => rhs
155+
case rhs => rhs
156+
}.map(_.tpe.termSymbol).filter(_.exists).map(_.tree).map {
157+
case v: ValDef if v.symbol.flags.is(Flags.Module) && !v.symbol.flags.is(Flags.Synthetic) =>
158+
v.symbol.owner -> Symbol.newVal(c.symbol, dd.name, v.tpt.tpe, Flags.Final, Symbol.noSymbol).tree
159+
case other => other.symbol.owner -> other
160+
}.flatMap { (originalOwner, tree) =>
161+
parseMember(c)(tree)
162+
.map { m => m
163+
.withDRI(dd.symbol.dri)
164+
.withName(dd.symbol.normalizedName)
165+
.withKind(Kind.Exported(m.kind))
166+
.withOrigin(Origin.ExportedFrom(Some(Link(originalOwner.normalizedName, originalOwner.dri))))
167+
}
155168
}
156-
val functionName = exportedTarget.fold("function")(_.name)
157-
val instanceName = exportedTarget.collect {
158-
case Select(qualifier: Select, _) => qualifier.name
159-
case Select(qualifier: Ident, _) => qualifier.tpe.typeSymbol.normalizedName
160-
}.getOrElse("instance")
161-
val dri = dd.rhs.collect {
162-
case s: Select if s.symbol.isDefDef => s.symbol.dri
163-
}.orElse(exportedTarget.map(_.qualifier.tpe.typeSymbol.dri))
164-
165-
Some(parseMethod(c, dd.symbol, specificKind = Kind.Exported(_))
166-
.withOrigin(Origin.ExportedFrom(s"$instanceName.$functionName", dri)))
167169

168170
case dd: DefDef if !dd.symbol.isHiddenByVisibility && !dd.symbol.isSyntheticFunc && !dd.symbol.isExtensionMethod && !dd.symbol.isArtifact =>
169171
Some(parseMethod(c, dd.symbol))
@@ -423,7 +425,17 @@ trait ClassLikeSupport:
423425
val defaultKind = Kind.Type(!isTreeAbstract(typeDef.rhs), typeDef.symbol.isOpaque, generics).asInstanceOf[Kind.Type]
424426
val kind = if typeDef.symbol.flags.is(Flags.Enum) then Kind.EnumCase(defaultKind)
425427
else defaultKind
426-
mkMember(typeDef.symbol, kind, tpeTree.asSignature)(deprecated = typeDef.symbol.isDeprecated())
428+
429+
if typeDef.symbol.flags.is(Flags.Exported)
430+
then {
431+
val origin = Some(tpeTree).flatMap {
432+
case TypeBoundsTree(l: TypeTree, h: TypeTree) if l.tpe == h.tpe =>
433+
Some(Link(l.tpe.typeSymbol.owner.name, l.tpe.typeSymbol.owner.dri))
434+
case _ => None
435+
}
436+
mkMember(typeDef.symbol, Kind.Exported(kind), tpeTree.asSignature)(deprecated = typeDef.symbol.isDeprecated(), origin = Origin.ExportedFrom(origin))
437+
}
438+
else mkMember(typeDef.symbol, kind, tpeTree.asSignature)(deprecated = typeDef.symbol.isDeprecated())
427439

428440
def parseValDef(c: ClassDef, valDef: ValDef): Member =
429441
def defaultKind = if valDef.symbol.flags.is(Flags.Mutable) then Kind.Var else Kind.Val

scaladoc/src/dotty/tools/scaladoc/tasty/TypesSupport.scala

+2-1
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,8 @@ trait TypesSupport:
305305
private def typeBoundsTreeOfHigherKindedType(using Quotes)(low: reflect.TypeRepr, high: reflect.TypeRepr) =
306306
import reflect._
307307
def regularTypeBounds(low: TypeRepr, high: TypeRepr) =
308-
typeBound(low, low = true) ++ typeBound(high, low = false)
308+
if low == high then keyword(" = ").l ++ inner(low)
309+
else typeBound(low, low = true) ++ typeBound(high, low = false)
309310
high.match
310311
case TypeLambda(params, paramBounds, resType) =>
311312
if resType.typeSymbol == defn.AnyClass then

scaladoc/src/dotty/tools/scaladoc/translators/FilterAttributes.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ object FilterAttributes:
2020
private def origin(m: Member): Map[String, String] = m.origin match
2121
case Origin.ImplicitlyAddedBy(name, _) => Map("implicitly" -> s"by $name")
2222
case Origin.ExtensionFrom(name, _) => Map("extension" -> s"from $name")
23-
case Origin.ExportedFrom(name, _) => Map("export" -> s"from $name")
23+
case Origin.ExportedFrom(Some(link)) => Map("export" -> s"from ${link.name}}")
2424
case _ => Map.empty
2525

2626

scaladoc/src/dotty/tools/scaladoc/translators/ScalaSignatureProvider.scala

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ package dotty.tools.scaladoc
22
package translators
33

44
object ScalaSignatureProvider:
5-
def rawSignature(documentable: Member, builder: SignatureBuilder): SignatureBuilder =
6-
documentable.kind match
5+
def rawSignature(documentable: Member, builder: SignatureBuilder)(kind: Kind = documentable.kind): SignatureBuilder =
6+
kind match
77
case Kind.Extension(_, m) =>
88
extensionSignature(documentable, m, builder)
99
case Kind.Exported(d) =>
10-
methodSignature(documentable, d, builder)
10+
rawSignature(documentable, builder)(d)
1111
case d: Kind.Def =>
1212
methodSignature(documentable, d, builder)
1313
case Kind.Constructor(d) =>
@@ -33,7 +33,7 @@ object ScalaSignatureProvider:
3333
case trt: Kind.Trait =>
3434
traitSignature(documentable, trt, builder)
3535
case Kind.Val | Kind.Var | Kind.Implicit(Kind.Val, _) =>
36-
fieldSignature(documentable, documentable.kind.name, builder)
36+
fieldSignature(documentable, kind.name, builder)
3737
case tpe: Kind.Type =>
3838
typeSignature(tpe, documentable, builder)
3939
case Kind.Package =>

scaladoc/test/dotty/tools/scaladoc/signatures/TranslatableSignaturesTestCases.scala

+2
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,5 @@ class SpecializedSignature extends SignatureTest("specializedSignature", Signatu
8888
class ContextBounds extends SignatureTest("contextBounds", SignatureTest.all)
8989

9090
class FBoundedTypeParameters extends SignatureTest("fboundedTypeParameters", SignatureTest.all)
91+
92+
class Exports extends SignatureTest("exports2", SignatureTest.all, sourceFiles = List("exports1", "exports2"))

0 commit comments

Comments
 (0)