Skip to content

Commit 585c5e6

Browse files
authored
Merge pull request #11245 from BarkingBad/scala3doc/missing-wildcard-in-hkts
Fix presentation of HKT and TypeLambdas in Scala3doc
2 parents 3c837f9 + 15000f3 commit 585c5e6

File tree

3 files changed

+92
-12
lines changed

3 files changed

+92
-12
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package tests
2+
package hkts
3+
4+
5+
class Case1Variant1[List[_]]
6+
class Case1Variant2[List <: ([_] =>> Any)]
7+
8+
type Case2Variant1 = [A, _] =>> List[A]
9+
type Case2Variant2[A, _] = List[A]
10+
11+
type Case3Variant1 = [_] =>> Int
12+
type Case3Variant2[_] = Int
13+
14+
class A1[X]
15+
class A2[X] extends A1[X]
16+
type Case4Variant1 >: ([X] =>> A2[X]) <: ([X] =>> A1[X])
17+
type Case4Variant2[X] >: A2[X] <: A1[X]
18+
19+
type Case5Variant1 = [X] =>> [Y] =>> (X, Y)
20+
type Case5Variant2[X, Y] = (X, Y)
21+
22+
type Case6Variant1 = [A, B] =>> A => B
23+
type Case6Variant2[A, B] = A => B
24+
25+
class Case7Variant1[List[_] <: Number]
26+
class Case7Variant2[List <: ([_] =>> Number)]
27+
28+
class Case8Variant1[A, List[A] <: Number]
29+
class Case8Variant2[A, List <: ([A] =>> Number)]
30+
31+
type Case9Variant1 <: [X] =>> Option[X]
32+
type Case9Variant2[+X] <: Option[X]
33+
34+
class Case10Variant1[List[_ >: Number]]
35+
class Case10Variant2[List <: ([_ >: Number] =>> Any)]
36+
37+
class Case11Variant1[Map[_, _]]
38+
class Case11Variant2[Map <: ([_, _] =>> Any)]
39+
40+
class Case12Variant1[List[A >: Number]]
41+
class Case12Variant2[List <: ([A >: Number] =>> Any)]
42+
43+
class Case13[List[List[_]]]
44+
45+
trait Case14[C[_]]
46+
class SomeClass extends Case14[List]
47+
48+
49+
def method1[E, T](value: List[_ >: E]): Int = 0
50+
def method2[F[+X] <: Option[X], A](fa: F[A]): A = fa.get
51+
52+
import scala.collection.immutable.ArraySeq
53+
trait SomeTraitWithHKTs[A[_], B[_], C[_], D[_], E[_]]
54+
abstract class Foo[Z]
55+
trait SomeTrait extends SomeTraitWithHKTs[Foo, scala.collection.immutable.ArraySeq, ArraySeq, List, [B] =>> List[B]]
56+
57+
trait A[X] {
58+
type SomeType[X]
59+
def x: SomeType[X]
60+
}
61+
62+
trait B[D] extends A[D]

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ trait ClassLikeSupport:
144144
Some(parseMethod(c, dd.symbol))
145145

146146
case td: TypeDef if !td.symbol.flags.is(Flags.Synthetic) && (!td.symbol.flags.is(Flags.Case) || !td.symbol.flags.is(Flags.Enum)) =>
147-
Some(parseTypeDef(td))
147+
Some(parseTypeDef(c, td))
148148

149149
case vd: ValDef if !isSyntheticField(vd.symbol)
150150
&& (!vd.symbol.flags.is(Flags.Case) || !vd.symbol.flags.is(Flags.Enum))
@@ -292,7 +292,7 @@ trait ClassLikeSupport:
292292

293293
val enumTypes = companion.membersToDocument.collect {
294294
case td: TypeDef if !td.symbol.flags.is(Flags.Synthetic) && td.symbol.flags.is(Flags.Enum) && td.symbol.flags.is(Flags.Case) => td
295-
}.toList.map(parseTypeDef)
295+
}.toList.map(parseTypeDef(classDef, _))
296296

297297
val enumNested = companion.membersToDocument.collect {
298298
case c: ClassDef if c.symbol.flags.is(Flags.Case) && c.symbol.flags.is(Flags.Enum) => processTree(c)(parseClasslike(c))
@@ -378,22 +378,23 @@ trait ClassLikeSupport:
378378
if argument.symbol.flags.is(Flags.Covariant) then "+"
379379
else if argument.symbol.flags.is(Flags.Contravariant) then "-"
380380
else ""
381+
381382
val name = argument.symbol.normalizedName
383+
val normalizedName = if name.matches("_\\$\\d*") then "_" else name
382384
TypeParameter(
383385
argument.symbol.getAnnotations(),
384386
variancePrefix,
385-
name,
387+
normalizedName,
386388
argument.symbol.dri,
387389
memberInfo.get(name).fold(argument.rhs.asSignature)(_.asSignature)
388390
)
389391

390-
def parseTypeDef(typeDef: TypeDef): Member =
392+
def parseTypeDef(c: ClassDef, typeDef: TypeDef): Member =
391393
def isTreeAbstract(typ: Tree): Boolean = typ match {
392394
case TypeBoundsTree(_, _) => true
393395
case LambdaTypeTree(params, body) => isTreeAbstract(body)
394396
case _ => false
395397
}
396-
397398
val (generics, tpeTree) = typeDef.rhs match
398399
case LambdaTypeTree(params, body) => (params.map(mkTypeArgument(_)), body)
399400
case tpe => (Nil, tpe)

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

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ trait TypesSupport:
4040
extension (tpeTree: Tree)
4141
def asSignature: DocSignature =
4242
tpeTree match
43-
case TypeBoundsTree(low, high) => typeBound(low.tpe, low = true) ++ typeBound(high.tpe, low = false)
44-
case tpeTree: TypeTree => inner(tpeTree.tpe)
43+
case TypeBoundsTree(low, high) => typeBoundsTreeOfHigherKindedType(low.tpe, high.tpe)
44+
case tpeTree: TypeTree => inner(tpeTree.tpe)
4545
case term: Term => inner(term.tpe)
4646

4747
given TypeSyntax: AnyRef with
@@ -95,9 +95,10 @@ trait TypesSupport:
9595
case AnnotatedType(tpe, _) =>
9696
inner(tpe)
9797
case tl @ TypeLambda(params, paramBounds, resType) =>
98-
// println(params)
99-
// println(paramBounds)
100-
texts("[") ++ commas(params.zip(paramBounds).map( (name, typ) => texts(s"${name}") ++ inner(typ) )) ++ texts("]")
98+
texts("[") ++ commas(params.zip(paramBounds).map { (name, typ) =>
99+
val normalizedName = if name.matches("_\\$\\d*") then "_" else name
100+
texts(normalizedName) ++ inner(typ)
101+
}) ++ texts("]")
101102
++ texts(" =>> ")
102103
++ inner(resType)
103104

@@ -184,7 +185,10 @@ trait TypesSupport:
184185
Nil
185186
case args =>
186187
texts("(") ++ commas(args.map(inner)) ++ texts(")")
187-
else inner(tpe) ++ texts("[") ++ commas(typeList.map(inner)) ++ texts("]")
188+
else inner(tpe) ++ texts("[") ++ commas(typeList.map { t => t match
189+
case _: TypeBounds => texts("_") ++ inner(t)
190+
case _ => inner(t)
191+
}) ++ texts("]")
188192

189193
case tp @ TypeRef(qual, typeName) =>
190194
qual match {
@@ -238,7 +242,7 @@ trait TypesSupport:
238242
// case _ => throw Exception("No match for type in conversion to Reference. This should not happen, please open an issue. " + tp)
239243
case TypeBounds(low, hi) =>
240244
if(low == hi) texts(" = ") ++ inner(low)
241-
else typeBound(low, low = true) ++ typeBound(hi, low = false)
245+
else typeBoundsTreeOfHigherKindedType(low, hi)
242246

243247
case NoPrefix() => Nil
244248

@@ -267,3 +271,16 @@ trait TypesSupport:
267271
case _ => Nil
268272
}
269273

274+
private def typeBoundsTreeOfHigherKindedType(low: TypeRepr, high: TypeRepr) =
275+
def regularTypeBounds(low: TypeRepr, high: TypeRepr) =
276+
typeBound(low, low = true) ++ typeBound(high, low = false)
277+
high.match
278+
case TypeLambda(params, paramBounds, resType) =>
279+
if resType.typeSymbol == defn.AnyClass then
280+
texts("[") ++ commas(params.zip(paramBounds).map { (name, typ) =>
281+
val normalizedName = if name.matches("_\\$\\d*") then "_" else name
282+
texts(normalizedName) ++ inner(typ)
283+
}) ++ texts("]")
284+
else
285+
regularTypeBounds(low, high)
286+
case _ => regularTypeBounds(low, high)

0 commit comments

Comments
 (0)