Skip to content

Commit 8bebec3

Browse files
committed
Refactor ClassLikeSupports' parseMethod
1 parent d61c9aa commit 8bebec3

File tree

4 files changed

+66
-83
lines changed

4 files changed

+66
-83
lines changed

scala3doc-js/src/ux/ux.scala

Lines changed: 0 additions & 52 deletions
This file was deleted.

scala3doc-testcases/src/tests/typeAppliance.scala

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,14 @@ package tests
22
package typeAppliance
33

44
trait AClass[A, B]:
5-
def fun[C]: AClass[A, C]
5+
def funASD[C, D](f: B => C): AClass[A, C]
66

77
trait BClass[A, B] extends AClass[A, B]:
8-
override def fun[C]: BClass[A, C]
8+
override def funASD[X, D](f: B => X): BClass[A, X]
9+
val f: (=> B) => String = _ => "abc"
910

10-
abstract class CClass[B] extends BClass[Int, B]
11+
12+
abstract class CClass[U] extends BClass[Int, U]:
13+
def xdxdkk(n: Int)(b: Int): Int = 1
14+
def isByNameType: String = "xd"
15+
def vararg1(a: A*): C

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

Lines changed: 49 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ trait ClassLikeSupport:
2727
else Kind.Class(Nil, Nil)
2828

2929
private def kindForClasslike(classDef: ClassDef): Kind =
30-
def typeArgs = classDef.getTypeParams.map(mkTypeArgument)
30+
def typeArgs = classDef.getTypeParams.map(mkTypeArgument(_))
3131

3232
def parameterModifier(parameter: Symbol): String =
3333
val fieldSymbol = classDef.symbol.declaredField(parameter.normalizedName)
@@ -170,10 +170,10 @@ trait ClassLikeSupport:
170170
&& (!vd.symbol.flags.is(Flags.Case) || !vd.symbol.flags.is(Flags.Enum))
171171
&& vd.symbol.isGiven =>
172172
val classDef = Some(vd.tpt.tpe).flatMap(_.classSymbol.map(_.tree.asInstanceOf[ClassDef]))
173-
Some(classDef.filter(_.symbol.flags.is(Flags.Module)).fold[Member](parseValDef(vd))(parseGivenClasslike(_)))
173+
Some(classDef.filter(_.symbol.flags.is(Flags.Module)).fold[Member](parseValDef(c, vd))(parseGivenClasslike(_)))
174174

175175
case vd: ValDef if !isSyntheticField(vd.symbol) && (!vd.symbol.flags.is(Flags.Case) || !vd.symbol.flags.is(Flags.Enum)) =>
176-
Some(parseValDef(vd))
176+
Some(parseValDef(c, vd))
177177

178178
case c: ClassDef if c.symbol.owner.memberMethod(c.name).exists(_.flags.is(Flags.Given)) =>
179179
Some(parseGivenClasslike(c))
@@ -299,7 +299,7 @@ trait ClassLikeSupport:
299299

300300
val enumVals = companion.membersToDocument.collect {
301301
case vd: ValDef if !isSyntheticField(vd.symbol) && vd.symbol.flags.is(Flags.Enum) && vd.symbol.flags.is(Flags.Case) => vd
302-
}.toList.map(parseValDef(_))
302+
}.toList.map(parseValDef(classDef, _))
303303

304304
val enumTypes = companion.membersToDocument.collect {
305305
case td: TypeDef if !td.symbol.flags.is(Flags.Synthetic) && td.symbol.flags.is(Flags.Enum) && td.symbol.flags.is(Flags.Case) => td
@@ -334,9 +334,13 @@ trait ClassLikeSupport:
334334
else method.paramss
335335
val genericTypes = if (methodSymbol.isClassConstructor) Nil else method.typeParams
336336

337+
val memberInfo = unwrapMemberInfo(c, methodSymbol)
338+
337339
val basicKind: Kind.Def = Kind.Def(
338-
genericTypes.map(mkTypeArgument),
339-
paramLists.map(pList => ParametersList(pList.map(mkParameter(_, paramPrefix)), if isUsingModifier(pList) then "using " else ""))
340+
genericTypes.map(mkTypeArgument(_, Some(memberInfo.genericTypes))),
341+
paramLists.zipWithIndex.map { (pList, index) =>
342+
ParametersList(pList.map(mkParameter(_, paramPrefix, memberInfo = Some(memberInfo.paramLists(index)))), if isUsingModifier(pList) then "using " else "")
343+
}
340344
)
341345

342346
val methodKind =
@@ -358,12 +362,6 @@ trait ClassLikeSupport:
358362
val origin = if !methodSymbol.isOverriden then Origin.RegularlyDefined else
359363
val overridenSyms = methodSymbol.allOverriddenSymbols.map(_.owner)
360364
Origin.Overrides(overridenSyms.map(s => Overriden(s.name, s.dri)).toSeq)
361-
if(methodSymbol.normalizedName == "fun" && c.symbol.normalizedName == "CClass")
362-
println(method.returnTpt)
363-
println(typeForClass(c).asInstanceOf[dotty.tools.dotc.core.Types.Type]
364-
.memberInfo(methodSymbol.asInstanceOf[dotty.tools.dotc.core.Symbols.Symbol])(using qctx.asInstanceOf[scala.quoted.runtime.impl.QuotesImpl].ctx)
365-
)
366-
367365

368366
mkMember(
369367
method.symbol,
@@ -372,7 +370,7 @@ trait ClassLikeSupport:
372370
methodSymbol.getExtraModifiers(),
373371
methodKind,
374372
methodSymbol.getAnnotations(),
375-
method.returnTpt.dokkaType.asSignature,
373+
memberInfo.res.dokkaType.asSignature,
376374
methodSymbol.source(using qctx),
377375
origin
378376
)
@@ -381,32 +379,33 @@ trait ClassLikeSupport:
381379
def mkParameter(argument: ValDef,
382380
prefix: Symbol => String = _ => "",
383381
isExtendedSymbol: Boolean = false,
384-
isGrouped: Boolean = false) =
382+
isGrouped: Boolean = false,
383+
memberInfo: Option[Map[String, TypeRepr]] = None) =
385384
val inlinePrefix = if argument.symbol.flags.is(Flags.Inline) then "inline " else ""
386-
val name = Option.when(!argument.symbol.flags.is(Flags.Synthetic))(argument.symbol.normalizedName)
387-
385+
val nameIfNotSynthetic = Option.when(!argument.symbol.flags.is(Flags.Synthetic))(argument.symbol.normalizedName)
386+
val name = argument.symbol.normalizedName
388387
Parameter(
389388
argument.symbol.getAnnotations(),
390389
inlinePrefix + prefix(argument.symbol),
391-
name,
390+
nameIfNotSynthetic,
392391
argument.symbol.dri,
393-
argument.tpt.dokkaType.asSignature,
392+
memberInfo.flatMap(_.get(name).map(_.dokkaType.asSignature)).getOrElse(argument.tpt.dokkaType.asSignature),
394393
isExtendedSymbol,
395394
isGrouped
396395
)
397396

398-
def mkTypeArgument(argument: TypeDef): TypeParameter =
397+
def mkTypeArgument(argument: TypeDef, memberInfo: Option[Map[String, TypeBounds]] = None): TypeParameter =
399398
val variancePrefix: "+" | "-" | "" =
400399
if argument.symbol.flags.is(Flags.Covariant) then "+"
401400
else if argument.symbol.flags.is(Flags.Contravariant) then "-"
402401
else ""
403-
402+
val name = argument.symbol.normalizedName
404403
TypeParameter(
405404
argument.symbol.getAnnotations(),
406405
variancePrefix,
407-
argument.symbol.normalizedName,
406+
name,
408407
argument.symbol.dri,
409-
argument.rhs.dokkaType.asSignature
408+
memberInfo.flatMap(_.get(name).map(_.dokkaType.asSignature)).getOrElse(argument.rhs.dokkaType.asSignature)
410409
)
411410

412411
def parseTypeDef(typeDef: TypeDef): Member =
@@ -417,7 +416,7 @@ trait ClassLikeSupport:
417416
}
418417

419418
val (generics, tpeTree) = typeDef.rhs match
420-
case LambdaTypeTree(params, body) => (params.map(mkTypeArgument), body)
419+
case LambdaTypeTree(params, body) => (params.map(mkTypeArgument(_)), body)
421420
case tpe => (Nil, tpe)
422421

423422
mkMember(
@@ -432,8 +431,9 @@ trait ClassLikeSupport:
432431
)
433432
)
434433

435-
def parseValDef(valDef: ValDef): Member =
434+
def parseValDef(c: ClassDef, valDef: ValDef): Member =
436435
def defaultKind = if valDef.symbol.flags.is(Flags.Mutable) then Kind.Var else Kind.Val
436+
val memberInfo = unwrapMemberInfo(c, valDef.symbol)
437437
val kind = if valDef.symbol.flags.is(Flags.Implicit) then
438438
Kind.Implicit(Kind.Val, extractImplicitConversion(valDef.tpt.tpe))
439439
else defaultKind
@@ -445,7 +445,7 @@ trait ClassLikeSupport:
445445
valDef.symbol.getExtraModifiers(),
446446
kind,
447447
valDef.symbol.getAnnotations(),
448-
valDef.tpt.tpe.dokkaType.asSignature,
448+
memberInfo.res.dokkaType.asSignature,
449449
valDef.symbol.source(using qctx)
450450
)
451451
)
@@ -476,5 +476,29 @@ trait ClassLikeSupport:
476476
PropertyContainer.Companion.empty().plus(member.copy(rawDoc = symbol.documentation)).plus(compositeExt)
477477
)
478478

479+
case class MemberInfo(genericTypes: Map[String, TypeBounds], paramLists: List[Map[String, TypeRepr]], res: TypeRepr)
480+
481+
def unwrapMemberInfo(c: ClassDef, symbol: Symbol): MemberInfo =
482+
val baseTypeRepr = typeForClass(c).asInstanceOf[dotty.tools.dotc.core.Types.Type]
483+
.memberInfo(symbol.asInstanceOf[dotty.tools.dotc.core.Symbols.Symbol])(using qctx.asInstanceOf[scala.quoted.runtime.impl.QuotesImpl].ctx)
484+
.asInstanceOf[TypeRepr]
485+
486+
def handlePolyType(polyType: PolyType): MemberInfo =
487+
MemberInfo(polyType.paramNames.zip(polyType.paramBounds).toMap, List.empty, polyType.resType)
488+
489+
def handleMethodType(memberInfo: MemberInfo, methodType: MethodType): MemberInfo =
490+
MemberInfo(memberInfo.genericTypes, memberInfo.paramLists ++ List(methodType.paramNames.zip(methodType.paramTypes).toMap), methodType.resType)
491+
492+
def handleByNameType(memberInfo: MemberInfo, byNameType: ByNameType): MemberInfo =
493+
MemberInfo(memberInfo.genericTypes, memberInfo.paramLists, byNameType.underlying)
494+
495+
def recursivelyCalculateMemberInfo(memberInfo: MemberInfo): MemberInfo = memberInfo.res match
496+
case p: PolyType => recursivelyCalculateMemberInfo(handlePolyType(p))
497+
case m: MethodType => recursivelyCalculateMemberInfo(handleMethodType(memberInfo, m))
498+
case b: ByNameType => handleByNameType(memberInfo, b)
499+
case _ => memberInfo
500+
501+
recursivelyCalculateMemberInfo(MemberInfo(Map.empty, List.empty, baseTypeRepr))
502+
479503
private def isUsingModifier(parameters: Seq[ValDef]): Boolean =
480504
parameters.size > 0 && parameters(0).symbol.flags.is(Flags.Given)

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,14 @@ trait TypesSupport:
6868
case List(single) => single
6969
case other => other.reduce((r, e) => r ++ texts(", ") ++ e)
7070

71-
private def isRepeated(tpeAnnotation: Term) =
71+
// weird name fot type-erasure purposes
72+
private def isRepeatedTerm(term: Term) =
7273
// For some reason annotation.tpe.typeSymbol != defn.RepeatedParamClass
7374
// annotation.tpe.typeSymbol prints 'class Repeated' and defn.RepeatedParamClass prints 'class <repeated>'
74-
tpeAnnotation.tpe.typeSymbol.toString == "class Repeated"
75+
term.tpe.typeSymbol.toString == "class Repeated"
76+
77+
private def isRepeatedTypeRepr(typeRepr: TypeRepr) =
78+
typeRepr.typeSymbol.toString == "class <repeated>"
7579

7680
// TODO #23 add support for all types signatures that makes sense
7781
private def inner(tp: TypeRepr): List[JProjection] =
@@ -86,7 +90,9 @@ trait TypesSupport:
8690
case ConstantType(constant) =>
8791
texts(constant.show)
8892
case ThisType(tpe) => inner(tpe)
89-
case AnnotatedType(AppliedType(_, Seq(tpe)), annotation) if isRepeated(annotation) =>
93+
case AnnotatedType(AppliedType(_, Seq(tpe)), annotation) if isRepeatedTerm(annotation) =>
94+
inner(tpe) :+ text("*")
95+
case AppliedType(repeatedClass, Seq(tpe)) if isRepeatedTypeRepr(repeatedClass) =>
9096
inner(tpe) :+ text("*")
9197
case AnnotatedType(tpe, _) =>
9298
inner(tpe)

0 commit comments

Comments
 (0)