Skip to content

Commit

Permalink
Fix handling of right associative extension methods across scaladoc a…
Browse files Browse the repository at this point in the history
…nd printers (#20467)

Fixes #19925 
The same issue with handling right associative extension methods was
also present in RefinedPrinter and ShortenedTypePrinter, so I fixed
those as well
[Cherry-picked d3df8ca][modified]
  • Loading branch information
WojciechMazur committed Jul 8, 2024
1 parent 710627b commit ebd1ee0
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 3 deletions.
4 changes: 3 additions & 1 deletion compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -936,7 +936,9 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
// - trailingUsing = List(`(using D)`)
// - rest = List(`(g: G)`, `(using H)`)
// we need to swap (rightTyParams ++ rightParam) with (leftParam ++ trailingUsing)
val (leftTyParams, rest1) = tree.paramss.span(isTypeParamClause)
val (leftTyParams, rest1) = tree.paramss match
case fst :: tail if isTypeParamClause(fst) => (List(fst), tail)
case other => (List(), other)
val (leadingUsing, rest2) = rest1.span(isUsingClause)
val (rightTyParams, rest3) = rest2.span(isTypeParamClause)
val (rightParam, rest4) = rest3.splitAt(1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,9 @@ class ShortenedTypePrinter(
if gsym.is(Flags.ExtensionMethod) then
val filteredParams =
if gsym.name.isRightAssocOperatorName then
val (leadingTyParamss, rest1) = paramss.span(isTypeParamClause)
val (leadingTyParamss, rest1) = paramss match
case fst :: tail if isTypeParamClause(fst) => (List(fst), tail)
case other => (List(), other)
val (leadingUsing, rest2) = rest1.span(isUsingClause)
val (rightTyParamss, rest3) = rest2.span(isTypeParamClause)
val (rightParamss, rest4) = rest3.splitAt(1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -683,3 +683,14 @@ class HoverTermSuite extends BaseHoverSuite:
|""".stripMargin,
"""yy: A{type T = Int}""".stripMargin.hover
)

@Test def `right-assoc-extension`: Unit =
check(
"""
|case class Wrap[+T](x: T)
|
|extension [T](a: T)
| def <<*@@:>>[U <: Tuple](b: Wrap[U]): Wrap[T *: U] = Wrap(a *: b.x)
|""".stripMargin,
"extension [T](a: T) def *:[U <: Tuple](b: Wrap[U]): Wrap[T *: U]".hover
)
7 changes: 7 additions & 0 deletions scaladoc-testcases/src/tests/rightAssocExtension.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package tests.rightAssocExtension

case class Wrap[+T](x: T)

extension [T](a: T)
def *:[U <: Tuple](b: Wrap[U]): Wrap[T *: U]
= Wrap(a *: b.x)
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,9 @@ trait ClassLikeSupport:
if methodSymbol.isExtensionMethod && methodSymbol.isRightAssoc then
// Taken from RefinedPrinter.scala
// If you change the names of the clauses below, also change them in right-associative-extension-methods.md
val (leftTyParams, rest1) = memberInfo.paramLists.span(_.isType)
val (leftTyParams, rest1) = memberInfo.paramLists match
case fst :: tail if fst.isType => (List(fst), tail)
case other => (List(), other)
val (leadingUsing, rest2) = rest1.span(_.isUsing)
val (rightTyParams, rest3) = rest2.span(_.isType)
val (rightParam, rest4) = rest3.splitAt(1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,5 @@ class MatchTypeTuple extends SignatureTest("matchTypeTuple", SignatureTest.all)
class InfixTypes extends SignatureTest("infixTypes", SignatureTest.all)

class ExtendsCall extends SignatureTest("extendsCall", SignatureTest.all)

class RightAssocExtension extends SignatureTest("rightAssocExtension", SignatureTest.all)

0 comments on commit ebd1ee0

Please sign in to comment.