Skip to content

Commit ccc7657

Browse files
committed
Add scaladoc support for interleaved clauses
1 parent 9766c0f commit ccc7657

File tree

3 files changed

+55
-26
lines changed

3 files changed

+55
-26
lines changed

Diff for: scaladoc-testcases/src/tests/extensionParams.scala

+5
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,8 @@ extension [A <: List[Char]](using String)(using Unit)(a: A)(using Int)(using Num
5252
extension (using String)(using Unit)(a: Animal)(using Int)(using Number)
5353
def f11(b: Any)(c: Any): Any
5454
= ???
55+
def f13(b: Any)[T](c: T): T
56+
= ???
57+
def f14[D](b: D)[T](c: T): T
58+
= ???
59+

Diff for: scaladoc-testcases/src/tests/methodsAndConstructors.scala

+3
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,6 @@ class Methods:
6060
def withImplicitParam2(v: String)(implicit ab: Double, a: Int, b: String): String
6161
= ???
6262

63+
def clauseInterleaving[T](x: T)[U](y: U)(using (T, U)): (T, U)
64+
= ???
65+

Diff for: scaladoc/src/dotty/tools/scaladoc/tasty/ClassLikeSupport.scala

+47-26
Original file line numberDiff line numberDiff line change
@@ -337,45 +337,66 @@ trait ClassLikeSupport:
337337
def parseMethod(
338338
c: ClassDef,
339339
methodSymbol: Symbol,
340-
emptyParamsList: Boolean = false,
341340
paramPrefix: Symbol => String = _ => "",
342341
specificKind: (Kind.Def => Kind) = identity
343342
): Member =
344343
val method = methodSymbol.tree.asInstanceOf[DefDef]
345-
val paramLists: List[TermParamClause] = methodSymbol.nonExtensionTermParamLists
346-
val genericTypes: List[TypeDef] = if (methodSymbol.isClassConstructor) Nil else methodSymbol.nonExtensionLeadingTypeParams
344+
val paramLists = methodSymbol.nonExtensionParamLists
347345

348346
val memberInfo = unwrapMemberInfo(c, methodSymbol)
349347

350-
val basicKind: Kind.Def = Kind.Def(
351-
Right(genericTypes.map(mkTypeArgument(_, memberInfo.genericTypes, memberInfo.contextBounds))) +:
352-
paramLists.zipWithIndex.flatMap { (pList, index) =>
353-
memberInfo.paramLists(index) match
354-
case MemberInfo.EvidenceOnlyParameterList => None
355-
case MemberInfo.RegularParameterList(info) =>
356-
Some(Left(TermParameterList(pList.params.map(
348+
val unshuffledMemberInfoParamLists =
349+
if methodSymbol.isExtensionMethod && methodSymbol.isRightAssoc then
350+
// Taken from RefinedPrinter.scala
351+
val (leadingTyParamss, rest1) = memberInfo.paramLists.span(_.isType)
352+
val (leadingUsing, rest2) = rest1.span(_.isUsing)
353+
val (rightTyParamss, rest3) = rest2.span(_.isType)
354+
val (rightParamss, rest4) = rest3.splitAt(1)
355+
val (leftParamss, rest5) = rest4.splitAt(1)
356+
val (trailingUsing, rest6) = rest5.span(_.isUsing)
357+
if leftParamss.nonEmpty then
358+
// leadingTyParamss ::: leadingUsing ::: leftParamss ::: trailingUsing ::: rightTyParamss ::: rightParamss ::: rest6
359+
// because of takeRight after, this is equivalent to the following:
360+
rightTyParamss ::: rightParamss ::: rest6
361+
else
362+
memberInfo.paramLists // it wasn't a binary operator, after all.
363+
else
364+
memberInfo.paramLists
365+
366+
val croppedUnshuffledMemberInfoParamLists = unshuffledMemberInfoParamLists.takeRight(paramLists.length)
367+
368+
val basicDefKind: Kind.Def = Kind.Def(
369+
paramLists.zip(croppedUnshuffledMemberInfoParamLists).flatMap{
370+
case (_: TermParamClause, MemberInfo.EvidenceOnlyParameterList) => Nil
371+
case (pList: TermParamClause, MemberInfo.RegularParameterList(info)) =>
372+
Some(Left(api.TermParameterList(pList.params.map(
357373
mkParameter(_, paramPrefix, memberInfo = info)), paramListModifier(pList.params)
358374
)))
359-
case _ => assert(false, "memberInfo.termParamLists contains a type parameter list !")
375+
case (TypeParamClause(genericTypeList), MemberInfo.TypeParameterList(memInfoTypes)) =>
376+
Some(Right(genericTypeList.map(mkTypeArgument(_, memInfoTypes, memberInfo.contextBounds))))
377+
case (_,_) =>
378+
assert(false, s"croppedUnshuffledMemberInfoParamLists and SymOps.nonExtensionParamLists disagree on whether this clause is a type or term one")
360379
}
361380
)
362381

363382
val methodKind =
364-
if methodSymbol.isClassConstructor then Kind.Constructor(basicKind)
365-
else if methodSymbol.flags.is(Flags.Implicit) then extractImplicitConversion(method.returnTpt.tpe) match
366-
case Some(conversion) if paramLists.size == 0 || (paramLists.size == 1 && paramLists.head.params.size == 0) =>
367-
Kind.Implicit(basicKind, Some(conversion))
368-
case None if paramLists.size == 1 && paramLists(0).params.size == 1 =>
369-
Kind.Implicit(basicKind, Some(
370-
ImplicitConversion(
371-
paramLists(0).params(0).tpt.tpe.typeSymbol.dri,
372-
method.returnTpt.tpe.typeSymbol.dri
373-
)
374-
))
375-
case _ =>
376-
Kind.Implicit(basicKind, None)
377-
else if methodSymbol.flags.is(Flags.Given) then Kind.Given(basicKind, Some(method.returnTpt.tpe.asSignature), extractImplicitConversion(method.returnTpt.tpe))
378-
else specificKind(basicKind)
383+
if methodSymbol.isClassConstructor then Kind.Constructor(basicDefKind)
384+
else if methodSymbol.flags.is(Flags.Implicit) then
385+
val termParamLists: List[TermParamClause] = methodSymbol.nonExtensionTermParamLists
386+
extractImplicitConversion(method.returnTpt.tpe) match
387+
case Some(conversion) if termParamLists.size == 0 || (termParamLists.size == 1 && termParamLists.head.params.size == 0) =>
388+
Kind.Implicit(basicDefKind, Some(conversion))
389+
case None if termParamLists.size == 1 && termParamLists(0).params.size == 1 =>
390+
Kind.Implicit(basicDefKind, Some(
391+
ImplicitConversion(
392+
termParamLists(0).params(0).tpt.tpe.typeSymbol.dri,
393+
method.returnTpt.tpe.typeSymbol.dri
394+
)
395+
))
396+
case _ =>
397+
Kind.Implicit(basicDefKind, None)
398+
else if methodSymbol.flags.is(Flags.Given) then Kind.Given(basicDefKind, Some(method.returnTpt.tpe.asSignature), extractImplicitConversion(method.returnTpt.tpe))
399+
else specificKind(basicDefKind)
379400

380401
val origin = if !methodSymbol.isOverridden then Origin.RegularlyDefined else
381402
val overriddenSyms = methodSymbol.allOverriddenSymbols.map(_.owner)

0 commit comments

Comments
 (0)