@@ -27,7 +27,7 @@ trait ClassLikeSupport:
27
27
else Kind .Class (Nil , Nil )
28
28
29
29
private def kindForClasslike (classDef : ClassDef ): Kind =
30
- def typeArgs = classDef.getTypeParams.map(mkTypeArgument)
30
+ def typeArgs = classDef.getTypeParams.map(mkTypeArgument(_) )
31
31
32
32
def parameterModifier (parameter : Symbol ): String =
33
33
val fieldSymbol = classDef.symbol.declaredField(parameter.normalizedName)
@@ -125,7 +125,7 @@ trait ClassLikeSupport:
125
125
private def isDocumentableExtension (s : Symbol ) =
126
126
! s.isHiddenByVisibility && ! s.isSyntheticFunc && s.isExtensionMethod
127
127
128
- private def parseMember (s : Tree ): Option [Member ] = processTreeOpt(s)(s match
128
+ private def parseMember (c : ClassDef )( s : Tree ): Option [Member ] = processTreeOpt(s)(s match
129
129
case dd : DefDef if isDocumentableExtension(dd.symbol) =>
130
130
dd.symbol.extendedSymbol.map { extSym =>
131
131
val target = ExtensionTarget (
@@ -134,14 +134,14 @@ trait ClassLikeSupport:
134
134
extSym.tpt.symbol.dri,
135
135
extSym.symbol.pos.get.start
136
136
)
137
- parseMethod(dd.symbol,specificKind = Kind .Extension (target, _))
137
+ parseMethod(c, dd.symbol,specificKind = Kind .Extension (target, _))
138
138
}
139
139
// TODO check given methods?
140
140
case dd : DefDef if ! dd.symbol.isHiddenByVisibility && dd.symbol.isGiven =>
141
141
Some (dd.symbol.owner.memberType(dd.name))
142
142
.filterNot(_.exists)
143
143
.map { _ =>
144
- parseMethod(dd.symbol, specificKind =
144
+ parseMethod(c, dd.symbol, specificKind =
145
145
Kind .Given (_, getGivenInstance(dd).map(_.asSignature), None )
146
146
)
147
147
}
@@ -160,11 +160,11 @@ trait ClassLikeSupport:
160
160
case s : Select if s.symbol.isDefDef => s.symbol.dri
161
161
}.orElse(exportedTarget.map(_.qualifier.tpe.typeSymbol.dri))
162
162
163
- Some (parseMethod(dd.symbol, specificKind = Kind .Exported (_))
163
+ Some (parseMethod(c, dd.symbol, specificKind = Kind .Exported (_))
164
164
.withOrigin(Origin .ExportedFrom (s " $instanceName. $functionName" , dri)))
165
165
166
166
case dd : DefDef if ! dd.symbol.isHiddenByVisibility && ! dd.symbol.isGiven && ! dd.symbol.isSyntheticFunc && ! dd.symbol.isExtensionMethod =>
167
- Some (parseMethod(dd.symbol))
167
+ Some (parseMethod(c, dd.symbol))
168
168
169
169
case td : TypeDef if ! td.symbol.flags.is(Flags .Synthetic ) && (! td.symbol.flags.is(Flags .Case ) || ! td.symbol.flags.is(Flags .Enum )) =>
170
170
Some (parseTypeDef(td))
@@ -173,10 +173,10 @@ trait ClassLikeSupport:
173
173
&& (! vd.symbol.flags.is(Flags .Case ) || ! vd.symbol.flags.is(Flags .Enum ))
174
174
&& vd.symbol.isGiven =>
175
175
val classDef = Some (vd.tpt.tpe).flatMap(_.classSymbol.map(_.tree.asInstanceOf [ClassDef ]))
176
- Some (classDef.filter(_.symbol.flags.is(Flags .Module )).fold[Member ](parseValDef(vd))(parseGivenClasslike(_)))
176
+ Some (classDef.filter(_.symbol.flags.is(Flags .Module )).fold[Member ](parseValDef(c, vd))(parseGivenClasslike(_)))
177
177
178
178
case vd : ValDef if ! isSyntheticField(vd.symbol) && (! vd.symbol.flags.is(Flags .Case ) || ! vd.symbol.flags.is(Flags .Enum )) =>
179
- Some (parseValDef(vd))
179
+ Some (parseValDef(c, vd))
180
180
181
181
case c : ClassDef if c.symbol.owner.memberMethod(c.name).exists(_.flags.is(Flags .Given )) =>
182
182
Some (parseGivenClasslike(c))
@@ -210,9 +210,9 @@ trait ClassLikeSupport:
210
210
)
211
211
}
212
212
213
- private def parseInheritedMember (s : Tree ): Option [Member ] = processTreeOpt(s)(s match
213
+ private def parseInheritedMember (c : ClassDef )( s : Tree ): Option [Member ] = processTreeOpt(s)(s match
214
214
case c : ClassDef if c.symbol.shouldDocumentClasslike && ! c.symbol.isGiven => Some (parseClasslike(c, signatureOnly = true ))
215
- case other => parseMember(other)
215
+ case other => parseMember(c)( other)
216
216
).map(_.withInheritedFrom(InheritedFrom (s.symbol.owner.normalizedName, s.symbol.owner.dri)))
217
217
218
218
extension (c : ClassDef )
@@ -228,8 +228,8 @@ trait ClassLikeSupport:
228
228
case dd : DefDef if ! dd.symbol.isClassConstructor && ! (dd.symbol.isSuperBridgeMethod || dd.symbol.isDefaultHelperMethod) => dd
229
229
case other => other
230
230
}
231
- c.membersToDocument.flatMap(parseMember) ++
232
- inherited.flatMap(s => parseInheritedMember(s))
231
+ c.membersToDocument.flatMap(parseMember(c) ) ++
232
+ inherited.flatMap(s => parseInheritedMember(c)( s))
233
233
}
234
234
235
235
/** Extracts members while taking Dotty logic for patching the stdlib into account. */
@@ -240,7 +240,7 @@ trait ClassLikeSupport:
240
240
val ownMemberDRIs = ownMembers.iterator.map(_.name).toSet + " experimental$"
241
241
sym.tree.asInstanceOf [ClassDef ]
242
242
.membersToDocument.filterNot(m => ownMemberDRIs.contains(m.symbol.name))
243
- .flatMap(parseMember)
243
+ .flatMap(parseMember(c) )
244
244
}
245
245
c.symbol.fullName match {
246
246
case " scala.Predef$" =>
@@ -302,7 +302,7 @@ trait ClassLikeSupport:
302
302
303
303
val enumVals = companion.membersToDocument.collect {
304
304
case vd : ValDef if ! isSyntheticField(vd.symbol) && vd.symbol.flags.is(Flags .Enum ) && vd.symbol.flags.is(Flags .Case ) => vd
305
- }.toList.map(parseValDef(_))
305
+ }.toList.map(parseValDef(classDef, _))
306
306
307
307
val enumTypes = companion.membersToDocument.collect {
308
308
case td : TypeDef if ! td.symbol.flags.is(Flags .Synthetic ) && td.symbol.flags.is(Flags .Enum ) && td.symbol.flags.is(Flags .Case ) => td
@@ -321,6 +321,7 @@ trait ClassLikeSupport:
321
321
classlikie.withNewMembers(cases).asInstanceOf [DClass ]
322
322
323
323
def parseMethod (
324
+ c : ClassDef ,
324
325
methodSymbol : Symbol ,
325
326
emptyParamsList : Boolean = false ,
326
327
paramPrefix : Symbol => String = _ => " " ,
@@ -336,9 +337,13 @@ trait ClassLikeSupport:
336
337
else method.paramss
337
338
val genericTypes = if (methodSymbol.isClassConstructor) Nil else method.typeParams
338
339
340
+ val memberInfo = unwrapMemberInfo(c, methodSymbol)
341
+
339
342
val basicKind : Kind .Def = Kind .Def (
340
- genericTypes.map(mkTypeArgument),
341
- paramLists.map(pList => ParametersList (pList.map(mkParameter(_, paramPrefix)), if isUsingModifier(pList) then " using " else " " ))
343
+ genericTypes.map(mkTypeArgument(_, memberInfo.genericTypes)),
344
+ paramLists.zipWithIndex.map { (pList, index) =>
345
+ ParametersList (pList.map(mkParameter(_, paramPrefix, memberInfo = memberInfo.paramLists(index))), if isUsingModifier(pList) then " using " else " " )
346
+ }
342
347
)
343
348
344
349
val methodKind =
@@ -368,7 +373,7 @@ trait ClassLikeSupport:
368
373
methodSymbol.getExtraModifiers(),
369
374
methodKind,
370
375
methodSymbol.getAnnotations(),
371
- method.returnTpt .dokkaType.asSignature,
376
+ memberInfo.res .dokkaType.asSignature,
372
377
methodSymbol.source(using qctx),
373
378
origin
374
379
)
@@ -377,32 +382,33 @@ trait ClassLikeSupport:
377
382
def mkParameter (argument : ValDef ,
378
383
prefix : Symbol => String = _ => " " ,
379
384
isExtendedSymbol : Boolean = false ,
380
- isGrouped : Boolean = false ) =
385
+ isGrouped : Boolean = false ,
386
+ memberInfo : Map [String , TypeRepr ] = Map .empty) =
381
387
val inlinePrefix = if argument.symbol.flags.is(Flags .Inline ) then " inline " else " "
382
- val name = Option .when(! argument.symbol.flags.is(Flags .Synthetic ))(argument.symbol.normalizedName)
383
-
388
+ val nameIfNotSynthetic = Option .when(! argument.symbol.flags.is(Flags .Synthetic ))(argument.symbol.normalizedName)
389
+ val name = argument.symbol.normalizedName
384
390
Parameter (
385
391
argument.symbol.getAnnotations(),
386
392
inlinePrefix + prefix(argument.symbol),
387
- name ,
393
+ nameIfNotSynthetic ,
388
394
argument.symbol.dri,
389
- argument.tpt.dokkaType.asSignature,
395
+ memberInfo.get(name).fold( argument.tpt.dokkaType.asSignature)(_.dokkaType.asSignature) ,
390
396
isExtendedSymbol,
391
397
isGrouped
392
398
)
393
399
394
- def mkTypeArgument (argument : TypeDef ): TypeParameter =
400
+ def mkTypeArgument (argument : TypeDef , memberInfo : Map [ String , TypeBounds ] = Map .empty ): TypeParameter =
395
401
val variancePrefix : " +" | " -" | " " =
396
402
if argument.symbol.flags.is(Flags .Covariant ) then " +"
397
403
else if argument.symbol.flags.is(Flags .Contravariant ) then " -"
398
404
else " "
399
-
405
+ val name = argument.symbol.normalizedName
400
406
TypeParameter (
401
407
argument.symbol.getAnnotations(),
402
408
variancePrefix,
403
- argument.symbol.normalizedName ,
409
+ name ,
404
410
argument.symbol.dri,
405
- argument.rhs.dokkaType.asSignature
411
+ memberInfo.get(name).fold( argument.rhs.dokkaType.asSignature)(_.dokkaType.asSignature)
406
412
)
407
413
408
414
def parseTypeDef (typeDef : TypeDef ): Member =
@@ -413,7 +419,7 @@ trait ClassLikeSupport:
413
419
}
414
420
415
421
val (generics, tpeTree) = typeDef.rhs match
416
- case LambdaTypeTree (params, body) => (params.map(mkTypeArgument), body)
422
+ case LambdaTypeTree (params, body) => (params.map(mkTypeArgument(_) ), body)
417
423
case tpe => (Nil , tpe)
418
424
419
425
mkMember(
@@ -428,8 +434,9 @@ trait ClassLikeSupport:
428
434
)
429
435
)
430
436
431
- def parseValDef (valDef : ValDef ): Member =
437
+ def parseValDef (c : ClassDef , valDef : ValDef ): Member =
432
438
def defaultKind = if valDef.symbol.flags.is(Flags .Mutable ) then Kind .Var else Kind .Val
439
+ val memberInfo = unwrapMemberInfo(c, valDef.symbol)
433
440
val kind = if valDef.symbol.flags.is(Flags .Implicit ) then
434
441
Kind .Implicit (Kind .Val , extractImplicitConversion(valDef.tpt.tpe))
435
442
else defaultKind
@@ -441,7 +448,7 @@ trait ClassLikeSupport:
441
448
valDef.symbol.getExtraModifiers(),
442
449
kind,
443
450
valDef.symbol.getAnnotations(),
444
- valDef.tpt.tpe .dokkaType.asSignature,
451
+ memberInfo.res .dokkaType.asSignature,
445
452
valDef.symbol.source(using qctx)
446
453
)
447
454
)
@@ -472,5 +479,27 @@ trait ClassLikeSupport:
472
479
PropertyContainer .Companion .empty().plus(member.copy(rawDoc = symbol.documentation)).plus(compositeExt)
473
480
)
474
481
482
+ case class MemberInfo (genericTypes : Map [String , TypeBounds ], paramLists : List [Map [String , TypeRepr ]], res : TypeRepr )
483
+
484
+ def unwrapMemberInfo (c : ClassDef , symbol : Symbol ): MemberInfo =
485
+ val baseTypeRepr = memberInfo(c, symbol)
486
+
487
+ def handlePolyType (polyType : PolyType ): MemberInfo =
488
+ MemberInfo (polyType.paramNames.zip(polyType.paramBounds).toMap, List .empty, polyType.resType)
489
+
490
+ def handleMethodType (memberInfo : MemberInfo , methodType : MethodType ): MemberInfo =
491
+ MemberInfo (memberInfo.genericTypes, memberInfo.paramLists ++ List (methodType.paramNames.zip(methodType.paramTypes).toMap), methodType.resType)
492
+
493
+ def handleByNameType (memberInfo : MemberInfo , byNameType : ByNameType ): MemberInfo =
494
+ MemberInfo (memberInfo.genericTypes, memberInfo.paramLists, byNameType.underlying)
495
+
496
+ def recursivelyCalculateMemberInfo (memberInfo : MemberInfo ): MemberInfo = memberInfo.res match
497
+ case p : PolyType => recursivelyCalculateMemberInfo(handlePolyType(p))
498
+ case m : MethodType => recursivelyCalculateMemberInfo(handleMethodType(memberInfo, m))
499
+ case b : ByNameType => handleByNameType(memberInfo, b)
500
+ case _ => memberInfo
501
+
502
+ recursivelyCalculateMemberInfo(MemberInfo (Map .empty, List .empty, baseTypeRepr))
503
+
475
504
private def isUsingModifier (parameters : Seq [ValDef ]): Boolean =
476
505
parameters.size > 0 && parameters(0 ).symbol.flags.is(Flags .Given )
0 commit comments