Skip to content

Commit 88541a3

Browse files
authored
Merge pull request #10306 from pikinier20/givens-refactor
Scala3doc: Add missing givens, create pages for givens, minor bugfixes
2 parents aac4201 + 6cd9d91 commit 88541a3

File tree

4 files changed

+60
-19
lines changed

4 files changed

+60
-19
lines changed

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

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ trait ClassLikeSupport:
5757

5858
val graph = HierarchyGraph.withEdges(getSupertypesGraph(classDef, LinkToType(selfSiangture, classDef.symbol.dri, kindForClasslike(classDef.symbol))))
5959
val baseExtra = PropertyContainer.Companion.empty()
60-
.plus(ClasslikeExtension(classDef.getConstructorMethod, classDef.getCompanion))
60+
.plus(ClasslikeExtension(classDef.getConstructorMethod(), classDef.getCompanion))
6161
.plus(MemberExtension(
6262
classDef.symbol.getVisibility(),
6363
modifiers,
@@ -112,25 +112,55 @@ trait ClassLikeSupport:
112112
val target = ExtensionTarget(extSym.symbol.name, extSym.tpt.dokkaType.asSignature, extSym.tpt.symbol.dri)
113113
parseMethod(dd.symbol, kind = Kind.Extension(target))
114114
}
115-
115+
// TODO check given methods?
116116
case dd: DefDef if !dd.symbol.isHiddenByVisibility && dd.symbol.isGiven =>
117-
Some(parseMethod(dd.symbol, kind = Kind.Given(getGivenInstance(dd).map(_.asSignature), None))) // TODO check given methods?
117+
Some(dd.symbol.owner.typeMember(dd.name))
118+
.filterNot(_.exists)
119+
.map { _ =>
120+
parseMethod(dd.symbol, kind = Kind.Given(getGivenInstance(dd).map(_.asSignature), None))
121+
}
118122

119123
case dd: DefDef if !dd.symbol.isHiddenByVisibility && !dd.symbol.isGiven && !dd.symbol.isSyntheticFunc && !dd.symbol.isExtensionMethod =>
120124
Some(parseMethod(dd.symbol))
121125

122126
case td: TypeDef if !td.symbol.flags.is(Flags.Synthetic) && (!td.symbol.flags.is(Flags.Case) || !td.symbol.flags.is(Flags.Enum)) =>
123127
Some(parseTypeDef(td))
124128

129+
case vd: ValDef if !isSyntheticField(vd.symbol)
130+
&& (!vd.symbol.flags.is(Flags.Case) || !vd.symbol.flags.is(Flags.Enum))
131+
&& vd.symbol.isGiven =>
132+
val classDef = Some(vd.tpt.tpe).flatMap(_.classSymbol.map(_.tree.asInstanceOf[ClassDef]))
133+
Some(classDef.filter(_.symbol.flags.is(Flags.ModuleClass)).fold[Member](parseValDef(vd))(parseGivenClasslike(_)))
134+
125135
case vd: ValDef if !isSyntheticField(vd.symbol) && (!vd.symbol.flags.is(Flags.Case) || !vd.symbol.flags.is(Flags.Enum)) =>
126136
Some(parseValDef(vd))
127137

138+
case c: ClassDef if c.symbol.owner.method(c.name).exists(_.flags.is(Flags.Given)) =>
139+
Some(parseGivenClasslike(c))
140+
128141
case c: ClassDef if c.symbol.shouldDocumentClasslike && !c.symbol.isGiven =>
129142
Some(parseClasslike(c))
130143

131144
case _ => None
132145
)
133146

147+
private def parseGivenClasslike(c: ClassDef): Member = {
148+
val parsedClasslike = parseClasslike(c)
149+
val parentTpe = c.parents(0) match {
150+
case t: TypeTree => Some(t.tpe)
151+
case _ => None
152+
}
153+
val modifiedClasslikeExtension = ClasslikeExtension.getFrom(parsedClasslike).map(_.copy(
154+
constructor = c.getConstructorMethod(Some(_ => "using "))
155+
)
156+
).get
157+
parsedClasslike.withNewExtras(
158+
parsedClasslike.getExtra.plus(modifiedClasslikeExtension)
159+
).withKind(
160+
Kind.Given(parsedClasslike.directParents.headOption, parentTpe.flatMap(extractImplicitConversion))
161+
)
162+
}
163+
134164
private def parseInheritedMember(s: Tree): Option[Member] = processTreeOpt(s)(s match
135165
case c: ClassDef if c.symbol.shouldDocumentClasslike && !c.symbol.isGiven => Some(parseClasslike(c, signatureOnly = true))
136166
case other => parseMember(other)
@@ -179,9 +209,9 @@ trait ClassLikeSupport:
179209
.filterNot(_.isHiddenByVisibility)
180210
.map(_.dri)
181211

182-
def getConstructorMethod: Option[DFunction] =
212+
def getConstructorMethod(paramModifierFunc: Option[Symbol => String] = None): Option[DFunction] =
183213
Some(c.constructor.symbol).filter(_.exists).filterNot(_.isHiddenByVisibility).map( d =>
184-
parseMethod(d, constructorWithoutParamLists(c), s => c.getParameterModifier(s))
214+
parseMethod(d, constructorWithoutParamLists(c), paramModifierFunc.getOrElse(s => c.getParameterModifier(s)))
185215
)
186216

187217
def parseClasslike(classDef: ClassDef, signatureOnly: Boolean = false)(using ctx: Context): DClass = classDef match
@@ -239,6 +269,7 @@ trait ClassLikeSupport:
239269
val name = methodKind match
240270
case Kind.Constructor => "this"
241271
case Kind.Given(_, _) => methodSymbol.name.stripPrefix("given_")
272+
case Kind.Extension(_) => methodSymbol.name.stripPrefix("extension_")
242273
case _ => methodSymbol.name
243274

244275
new DFunction(
@@ -336,18 +367,10 @@ trait ClassLikeSupport:
336367
)
337368

338369
def parseValDef(valDef: ValDef): DProperty =
339-
def givenInstance = Some(valDef.symbol.moduleClass)
340-
.filter(_.exists)
341-
.map(_.tree.asInstanceOf[ClassDef])
342-
.flatMap(_.getParents.headOption)
343-
.map(_.dokkaType.asSignature)
344-
345370
def defaultKind = if valDef.symbol.flags.is(Flags.Mutable) then Kind.Var else Kind.Val
346-
val kind =
347-
if valDef.symbol.isGiven then Kind.Given(givenInstance, extractImplicitConversion(valDef.tpt.tpe))
348-
else if valDef.symbol.flags.is(Flags.Implicit) then
371+
val kind = if valDef.symbol.flags.is(Flags.Implicit) then
349372
Kind.Implicit(Kind.Val, extractImplicitConversion(valDef.tpt.tpe))
350-
else defaultKind
373+
else defaultKind
351374

352375
new DProperty(
353376
valDef.symbol.dri,

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ trait SyntheticsSupport:
3838
def getAllMembers: List[Symbol] = hackGetAllMembers(using qctx)(s)
3939

4040
def isSyntheticField(c: Symbol) =
41-
c.flags.is(Flags.CaseAccessor) || c.flags.is(Flags.Object)
41+
c.flags.is(Flags.CaseAccessor) || (c.flags.is(Flags.Object) && !c.flags.is(Flags.Given))
4242

4343
def isValidPos(pos: Position) =
4444
pos.exists && pos.start != pos.end
@@ -71,7 +71,7 @@ trait SyntheticsSupport:
7171
sym.typeRef.appliedTo(sym.typeParams.map(_.typeRef)).allMembers.iterator.map(_.symbol)
7272
.collect {
7373
case sym if
74-
!sym.is(dotc.core.Flags.ModuleVal) &&
74+
(!sym.is(dotc.core.Flags.ModuleVal) || sym.is(dotc.core.Flags.Given)) &&
7575
!sym.flags.isAllOf(dotc.core.Flags.Enum | dotc.core.Flags.Case | dotc.core.Flags.JavaStatic) =>
7676
sym.asInstanceOf[Symbol]
7777
}.toList

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ class ImplicitMembersExtensionTransformer(ctx: DokkaContext) extends Documentabl
1717

1818
def expandMember(outerMembers: Seq[Member])(c: Member): Member =
1919
val companion = c match
20-
case classlike: DClass => ClasslikeExtension.getFrom(classlike).flatMap(_.companion).map(classlikeMap)
20+
case classlike: DClass => ClasslikeExtension.getFrom(classlike).flatMap(_.companion).flatMap(classlikeMap.get)
2121
case _ => None
2222

2323
val allParents = c.parents.flatMap(p => classlikeMap.get(p.dri))
2424

2525
val parentCompanions = allParents.flatMap {
26-
case cls: DClasslike => ClasslikeExtension.getFrom(cls).flatMap(_.companion).map(classlikeMap)
26+
case cls: DClasslike => ClasslikeExtension.getFrom(cls).flatMap(_.companion).flatMap(classlikeMap.get)
2727
case _ => None
2828
}
2929

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ object ScalaSignatureProvider:
4949
methodSignature(method, builder)
5050
case enumEntry: DClass if enumEntry.kind == Kind.EnumCase =>
5151
enumEntrySignature(enumEntry, builder)
52+
case givenClazz: DClass if givenClazz.kind.isInstanceOf[Kind.Given] =>
53+
givenClassSignature(givenClazz, builder)
5254
case clazz: DClass =>
5355
classSignature(clazz, builder)
5456
case enumProperty: DProperty if enumProperty.kind == Kind.EnumCase =>
@@ -98,6 +100,22 @@ object ScalaSignatureProvider:
98100
val extendPart = builder.text(" extends ").signature(extendType)
99101
withTypes.foldLeft(extendPart)((bdr, tpe) => bdr.text(" with ").signature(tpe))
100102

103+
private def givenClassSignature(clazz: DClass, builder: SignatureBuilder): SignatureBuilder =
104+
val ext = clazz.get(ClasslikeExtension)
105+
val prefixes = builder
106+
.modifiersAndVisibility(clazz, "given")
107+
.name(clazz.getName, clazz.getDri)
108+
.generics(clazz)
109+
110+
val withGenerics = ext.constructor.toSeq.foldLeft(prefixes){ (bdr, elem) =>
111+
bdr.functionParameters(elem)
112+
}
113+
clazz.kind match
114+
case Kind.Given(Some(instance), _) => withGenerics
115+
.text(" as ")
116+
.signature(instance)
117+
case _ => withGenerics
118+
101119
private def classSignature(clazz: DClass, builder: SignatureBuilder): SignatureBuilder =
102120
val ext = clazz.get(ClasslikeExtension)
103121
val prefixes = builder

0 commit comments

Comments
 (0)