Skip to content

Commit ebccb1f

Browse files
committed
Add scaladoc support for interleaved clauses
1 parent fa55cc6 commit ebccb1f

File tree

3 files changed

+55
-26
lines changed

3 files changed

+55
-26
lines changed

scaladoc-testcases/src/tests/extensionParams.scala

Lines changed: 5 additions & 0 deletions
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+

scaladoc-testcases/src/tests/methodsAndConstructors.scala

Lines changed: 3 additions & 0 deletions
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+

scaladoc/src/dotty/tools/scaladoc/tasty/ClassLikeSupport.scala

Lines changed: 47 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -338,45 +338,66 @@ trait ClassLikeSupport:
338338
def parseMethod(
339339
c: ClassDef,
340340
methodSymbol: Symbol,
341-
emptyParamsList: Boolean = false,
342341
paramPrefix: Symbol => String = _ => "",
343342
specificKind: (Kind.Def => Kind) = identity
344343
): Member =
345344
val method = methodSymbol.tree.asInstanceOf[DefDef]
346-
val paramLists: List[TermParamClause] = methodSymbol.nonExtensionTermParamLists
347-
val genericTypes: List[TypeDef] = if (methodSymbol.isClassConstructor) Nil else methodSymbol.nonExtensionLeadingTypeParams
345+
val paramLists = methodSymbol.nonExtensionParamLists
348346

349347
val memberInfo = unwrapMemberInfo(c, methodSymbol)
350348

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

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

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

0 commit comments

Comments
 (0)