Skip to content

Commit 6cd9d91

Browse files
committed
Add missing givens, create pages for givens, minor bugfixes
1 parent cda0338 commit 6cd9d91

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,
@@ -111,25 +111,55 @@ trait ClassLikeSupport:
111111
val target = ExtensionTarget(extSym.symbol.name, extSym.tpt.dokkaType.asSignature, extSym.tpt.symbol.dri)
112112
parseMethod(dd.symbol, kind = Kind.Extension(target))
113113
}
114-
114+
// TODO check given methods?
115115
case dd: DefDef if !dd.symbol.isHiddenByVisibility && dd.symbol.isGiven =>
116-
Some(parseMethod(dd.symbol, kind = Kind.Given(getGivenInstance(dd).map(_.asSignature), None))) // TODO check given methods?
116+
Some(dd.symbol.owner.typeMember(dd.name))
117+
.filterNot(_.exists)
118+
.map { _ =>
119+
parseMethod(dd.symbol, kind = Kind.Given(getGivenInstance(dd).map(_.asSignature), None))
120+
}
117121

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

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

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

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

130143
case _ => None
131144
)
132145

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

181-
def getConstructorMethod: Option[DFunction] =
211+
def getConstructorMethod(paramModifierFunc: Option[Symbol => String] = None): Option[DFunction] =
182212
Some(c.constructor.symbol).filter(_.exists).filterNot(_.isHiddenByVisibility).map( d =>
183-
parseMethod(d, constructorWithoutParamLists(c), s => c.getParameterModifier(s))
213+
parseMethod(d, constructorWithoutParamLists(c), paramModifierFunc.getOrElse(s => c.getParameterModifier(s)))
184214
)
185215

186216
def parseClasslike(classDef: ClassDef, signatureOnly: Boolean = false)(using ctx: Context): DClass = classDef match
@@ -238,6 +268,7 @@ trait ClassLikeSupport:
238268
val name = methodKind match
239269
case Kind.Constructor => "this"
240270
case Kind.Given(_, _) => methodSymbol.name.stripPrefix("given_")
271+
case Kind.Extension(_) => methodSymbol.name.stripPrefix("extension_")
241272
case _ => methodSymbol.name
242273

243274
new DFunction(
@@ -333,18 +364,10 @@ trait ClassLikeSupport:
333364
)
334365

335366
def parseValDef(valDef: ValDef): DProperty =
336-
def givenInstance = Some(valDef.symbol.moduleClass)
337-
.filter(_.exists)
338-
.map(_.tree.asInstanceOf[ClassDef])
339-
.flatMap(_.getParents.headOption)
340-
.map(_.dokkaType.asSignature)
341-
342367
def defaultKind = if valDef.symbol.flags.is(Flags.Mutable) then Kind.Var else Kind.Val
343-
val kind =
344-
if valDef.symbol.isGiven then Kind.Given(givenInstance, extractImplicitConversion(valDef.tpt.tpe))
345-
else if valDef.symbol.flags.is(Flags.Implicit) then
368+
val kind = if valDef.symbol.flags.is(Flags.Implicit) then
346369
Kind.Implicit(Kind.Val, extractImplicitConversion(valDef.tpt.tpe))
347-
else defaultKind
370+
else defaultKind
348371

349372
new DProperty(
350373
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(qctx.reflect)(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
@@ -69,7 +69,7 @@ trait SyntheticsSupport:
6969
sym.typeRef.appliedTo(sym.typeParams.map(_.typeRef)).allMembers.iterator.map(_.symbol)
7070
.collect {
7171
case sym if
72-
!sym.is(dotc.core.Flags.ModuleVal) &&
72+
(!sym.is(dotc.core.Flags.ModuleVal) || sym.is(dotc.core.Flags.Given)) &&
7373
!sym.flags.isAllOf(dotc.core.Flags.Enum | dotc.core.Flags.Case | dotc.core.Flags.JavaStatic) =>
7474
sym.asInstanceOf[r.Symbol]
7575
}.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)