Skip to content

Commit 86c6894

Browse files
jchybFlorian3k
andcommitted
Improve this-type rendering
Co-authored-by: Florian3k <[email protected]>
1 parent 1a6cfc6 commit 86c6894

File tree

7 files changed

+203
-130
lines changed

7 files changed

+203
-130
lines changed

scaladoc-testcases/src/tests/classSignatureTestSource.scala

+3-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ abstract class Documentation[T, A <: Int, B >: String, -X, +Y](c1: String, val c
2626

2727
sealed trait CaseImplementThis(id: Int)
2828

29-
case class IAmACaseClass(x: T, id: Int) extends CaseImplementThis/*<-*/(id)/*->*/
29+
case class IAmACaseClass(x: Documentation.this.T, id: Int) extends CaseImplementThis/*<-*/(id)/*->*/
30+
31+
case class IAmACaseClassWithParam[T](x: Documentation.this.T, id: T)
3032

3133
case object IAmACaseObject extends CaseImplementThis/*<-*/(0)/*->*/
3234

scaladoc-testcases/src/tests/exports1.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ class A: //unexpected
1717
type HKT[T[_], X] //expected: final type HKT = a.HKT
1818
= T[X]
1919
type SomeRandomType = (List[?] | Seq[?]) & String //expected: final type SomeRandomType = a.SomeRandomType
20-
def x[T[_], X](x: X): HKT[T, X] //expected: def x[T[_], X](x: X): A.this.HKT[T, X]
20+
def x[T[_], X](x: X): HKT[T, X]
2121
= ???
2222
def fn[T, U]: T => U
2323
= ???
2424
object Object //expected: val Obj: Object.type
25-
val x: HKT[List, Int] //expected: val x: A.this.HKT[List, Int]
25+
val x: HKT[List, Int]
2626
= ???
2727
class Class(val a: Int, val b: Int) extends Serializable //expected: final type Class = a.Class
2828
enum Enum: //expected: final type Enum = a.Enum
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package tests
2+
package innerClasses
3+
4+
trait A:
5+
def baz: B
6+
= baz2
7+
def baz2: A.this.B //expected: def baz2: B
8+
= baz
9+
type B
10+
class C extends A:
11+
def foo: A.this.B
12+
= ???
13+
def foo2: B
14+
= ???
15+
def bar: B
16+
= ???
17+
18+
class T1:
19+
trait T
20+
class T2:
21+
trait T
22+
class Impl extends T1.this.T //expected: class Impl extends T
23+
// we get rid of the this-type above,
24+
// as ambiguity created by removing this-types is alleviated by links
25+
// (but this can be changed if needed)
+28-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,35 @@
11
package tests
22
package thisType
33

4-
// issue 16024
54

65
class X[Map[_, _[_]]]:
6+
// issue 16024
77
inline def map[F[_]](f: [t] => t => F[t]): Map[this.type, F]
88
= ???
9+
10+
sealed trait Tuple[Y[_]]:
11+
def ++[This >: this.type <: Tuple[Y]](that: Y[Tuple[Y]]): Any
12+
= ???
13+
14+
sealed trait NonEmptyTuple extends Tuple[Option]
15+
//expected: def ++[This >: this.type <: Tuple[Option]](that: Option[Tuple[Option]]): Any
16+
17+
trait Foo[X]:
18+
def foo0[T <: Foo.this.type](x: X): Foo.this.type //expected: def foo0[T <: this.type](x: X): this.type
19+
= bar0[T](x)
20+
def bar0[T <: this.type](x: X): this.type
21+
= foo0[T](x)
22+
23+
sealed abstract class Nested[+H, +T <: (Tuple), A <: Tuple[List]] extends NonEmptyTuple, Foo[Int]:
24+
// ^^^^^^^ TODO fix
25+
//expected: def ++[This >: this.type <: Tuple[Option]](that: Option[Tuple[Option]]): Any
26+
27+
//expected: def foo0[T <: this.type](x: Int): this.type
28+
29+
//expected: def bar0[T <: this.type](x: Int): this.type
30+
31+
def foo1[T <: Foo.this.type]: Nothing
32+
= ???
33+
34+
def foo2[T <: this.type]: Nothing
35+
= ???

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

+44-40
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ trait ClassLikeSupport:
8787
def getSupertypesGraph(link: LinkToType, to: Seq[Tree]): Seq[(LinkToType, LinkToType)] =
8888
to.flatMap { case tree =>
8989
val symbol = if tree.symbol.isClassConstructor then tree.symbol.owner else tree.symbol
90-
val signature = signatureWithName(tree.asSignature(classDef))
90+
val signature = signatureWithName(tree.asSignature(classDef, classDef.symbol))
9191
val superLink = LinkToType(signature, symbol.dri, bareClasslikeKind(symbol))
9292
val nextTo = unpackTreeToClassDef(tree).parents
9393
if symbol.isHiddenByVisibility then getSupertypesGraph(link, nextTo)
@@ -98,16 +98,17 @@ trait ClassLikeSupport:
9898
.filterNot((s, t) => s.isHiddenByVisibility)
9999
.map {
100100
case (symbol, tpe) =>
101-
val signature = signatureWithName(tpe.asSignature(classDef))
101+
val signature = signatureWithName(tpe.asSignature(classDef, classDef.symbol))
102102
LinkToType(signature, symbol.dri, bareClasslikeKind(symbol))
103103
}
104104
val selfType = classDef.self.map { (valdef: ValDef) =>
105105
val symbol = valdef.symbol
106106
val tpe = valdef.tpt.tpe
107-
val signature = signatureWithName(tpe.asSignature(classDef))
107+
val owner = if symbol.exists then symbol.owner else Symbol.noSymbol
108+
val signature = signatureWithName(tpe.asSignature(classDef, owner))
108109
LinkToType(signature, symbol.dri, Kind.Type(false, false, Seq.empty))
109110
}
110-
val selfSignature: DSignature = signatureWithName(typeForClass(classDef).asSignature(classDef))
111+
val selfSignature: DSignature = signatureWithName(typeForClass(classDef).asSignature(classDef, classDef.symbol))
111112

112113
val graph = HierarchyGraph.withEdges(
113114
getSupertypesGraph(LinkToType(selfSignature, classDef.symbol.dri, bareClasslikeKind(classDef.symbol)), unpackTreeToClassDef(classDef).parents)
@@ -188,7 +189,7 @@ trait ClassLikeSupport:
188189
extSym.symbol.normalizedName,
189190
typeParams,
190191
termParams,
191-
extSym.tpt.asSignature(c),
192+
extSym.tpt.asSignature(c, extSym.symbol.owner),
192193
extSym.tpt.symbol.dri,
193194
extSym.symbol.pos.get.start
194195
)
@@ -296,7 +297,7 @@ trait ClassLikeSupport:
296297

297298
def getParentsAsLinkToTypes: List[LinkToType] =
298299
c.getParentsAsTreeSymbolTuples.map {
299-
(tree, symbol) => LinkToType(tree.asSignature(c), symbol.dri, bareClasslikeKind(symbol))
300+
(tree, symbol) => LinkToType(tree.asSignature(c, c.symbol, skipThisTypePrefix = true), symbol.dri, bareClasslikeKind(symbol))
300301
}
301302

302303
def getParentsAsTreeSymbolTuples: List[(Tree, Symbol)] =
@@ -407,7 +408,7 @@ trait ClassLikeSupport:
407408
))
408409
case _ =>
409410
Kind.Implicit(basicDefKind, None)
410-
else if methodSymbol.flags.is(Flags.Given) then Kind.Given(basicDefKind, Some(method.returnTpt.tpe.asSignature(c)), extractImplicitConversion(method.returnTpt.tpe))
411+
else if methodSymbol.flags.is(Flags.Given) then Kind.Given(basicDefKind, Some(method.returnTpt.tpe.asSignature(c, methodSymbol.owner)), extractImplicitConversion(method.returnTpt.tpe))
411412
else specificKind(basicDefKind)
412413

413414
val origin = if !methodSymbol.isOverridden then Origin.RegularlyDefined else
@@ -423,7 +424,7 @@ trait ClassLikeSupport:
423424
mkMember(
424425
methodSymbol,
425426
methodKind,
426-
method.returnTpt.tpe.asSignature(c),
427+
method.returnTpt.tpe.asSignature(c, methodSymbol),
427428
)(
428429
modifiers = modifiers,
429430
origin = origin,
@@ -437,17 +438,17 @@ trait ClassLikeSupport:
437438
prefix: Symbol => String = _ => "",
438439
isExtendedSymbol: Boolean = false,
439440
isGrouped: Boolean = false,
440-
memberInfo: Map[String, TypeRepr] = Map.empty,
441441
) =
442-
val inlinePrefix = if argument.symbol.flags.is(Flags.Inline) then "inline " else ""
443-
val nameIfNotSynthetic = Option.when(!argument.symbol.flags.is(Flags.Synthetic))(argument.symbol.normalizedName)
444-
val name = argument.symbol.normalizedName
442+
val symbol = argument.symbol
443+
val inlinePrefix = if symbol.flags.is(Flags.Inline) then "inline " else ""
444+
val name = symbol.normalizedName
445+
val nameIfNotSynthetic = Option.when(!symbol.flags.is(Flags.Synthetic))(name)
445446
api.TermParameter(
446-
argument.symbol.getAnnotations(),
447-
inlinePrefix + prefix(argument.symbol),
447+
symbol.getAnnotations(),
448+
inlinePrefix + prefix(symbol),
448449
nameIfNotSynthetic,
449-
argument.symbol.dri,
450-
memberInfo.get(name).fold(argument.tpt.asSignature(classDef))(_.asSignature(classDef)),
450+
symbol.dri,
451+
argument.tpt.asSignature(classDef, symbol.owner),
451452
isExtendedSymbol,
452453
isGrouped
453454
)
@@ -457,30 +458,32 @@ trait ClassLikeSupport:
457458
classDef: ClassDef,
458459
contextBounds: List[TypeRepr] = Nil,
459460
): TypeParameter =
461+
val symbol = argument.symbol
460462
val variancePrefix: "+" | "-" | "" =
461-
if argument.symbol.flags.is(Flags.Covariant) then "+"
462-
else if argument.symbol.flags.is(Flags.Contravariant) then "-"
463+
if symbol.flags.is(Flags.Covariant) then "+"
464+
else if symbol.flags.is(Flags.Contravariant) then "-"
463465
else ""
464466

465-
val name = argument.symbol.normalizedName
467+
val name = symbol.normalizedName
466468
val normalizedName = if name.matches("_\\$\\d*") then "_" else name
467-
val boundsSignature = argument.rhs.asSignature(classDef)
469+
val boundsSignature = argument.rhs.asSignature(classDef, symbol.owner)
468470
val signature = boundsSignature ++ contextBounds.flatMap(tr =>
469471
val wrap = tr match
470472
case _: TypeLambda => true
471473
case _ => false
472-
Plain(" : ") +: inParens(tr.asSignature(classDef), wrap)
474+
Plain(" : ") +: inParens(tr.asSignature(classDef, symbol.owner), wrap)
473475
)
474476

475477
TypeParameter(
476-
argument.symbol.getAnnotations(),
478+
symbol.getAnnotations(),
477479
variancePrefix,
478480
normalizedName,
479-
argument.symbol.dri,
481+
symbol.dri,
480482
signature
481483
)
482484

483485
def parseTypeDef(typeDef: TypeDef, classDef: ClassDef): Member =
486+
val symbol = typeDef.symbol
484487
def isTreeAbstract(typ: Tree): Boolean = typ match {
485488
case TypeBoundsTree(_, _) => true
486489
case LambdaTypeTree(params, body) => isTreeAbstract(body)
@@ -490,43 +493,44 @@ trait ClassLikeSupport:
490493
case LambdaTypeTree(params, body) => (params.map(mkTypeArgument(_, classDef)), body)
491494
case tpe => (Nil, tpe)
492495

493-
val defaultKind = Kind.Type(!isTreeAbstract(typeDef.rhs), typeDef.symbol.isOpaque, generics).asInstanceOf[Kind.Type]
494-
val kind = if typeDef.symbol.flags.is(Flags.Enum) then Kind.EnumCase(defaultKind)
496+
val defaultKind = Kind.Type(!isTreeAbstract(typeDef.rhs), symbol.isOpaque, generics).asInstanceOf[Kind.Type]
497+
val kind = if symbol.flags.is(Flags.Enum) then Kind.EnumCase(defaultKind)
495498
else defaultKind
496499

497-
if typeDef.symbol.flags.is(Flags.Exported)
500+
if symbol.flags.is(Flags.Exported)
498501
then {
499502
val origin = Some(tpeTree).flatMap {
500503
case TypeBoundsTree(l: TypeTree, h: TypeTree) if l.tpe == h.tpe =>
501504
Some(Link(l.tpe.typeSymbol.owner.name, l.tpe.typeSymbol.owner.dri))
502505
case _ => None
503506
}
504-
mkMember(typeDef.symbol, Kind.Exported(kind), tpeTree.asSignature(classDef))(
505-
deprecated = typeDef.symbol.isDeprecated(),
507+
mkMember(symbol, Kind.Exported(kind), tpeTree.asSignature(classDef, symbol.owner))(
508+
deprecated = symbol.isDeprecated(),
506509
origin = Origin.ExportedFrom(origin),
507-
experimental = typeDef.symbol.isExperimental()
510+
experimental = symbol.isExperimental()
508511
)
509512
}
510-
else mkMember(typeDef.symbol, kind, tpeTree.asSignature(classDef))(deprecated = typeDef.symbol.isDeprecated())
513+
else mkMember(symbol, kind, tpeTree.asSignature(classDef, symbol.owner))(deprecated = symbol.isDeprecated())
511514

512515
def parseValDef(c: ClassDef, valDef: ValDef): Member =
513-
def defaultKind = if valDef.symbol.flags.is(Flags.Mutable) then Kind.Var else Kind.Val
514-
val sig = valDef.tpt.tpe.asSignature(c)
515-
val kind = if valDef.symbol.flags.is(Flags.Implicit) then Kind.Implicit(Kind.Val, extractImplicitConversion(valDef.tpt.tpe))
516-
else if valDef.symbol.flags.is(Flags.Given) then Kind.Given(Kind.Val, Some(sig), extractImplicitConversion(valDef.tpt.tpe))
517-
else if valDef.symbol.flags.is(Flags.Enum) then Kind.EnumCase(Kind.Val)
516+
val symbol = valDef.symbol
517+
def defaultKind = if symbol.flags.is(Flags.Mutable) then Kind.Var else Kind.Val
518+
val sig = valDef.tpt.tpe.asSignature(c, symbol.owner)
519+
val kind = if symbol.flags.is(Flags.Implicit) then Kind.Implicit(Kind.Val, extractImplicitConversion(valDef.tpt.tpe))
520+
else if symbol.flags.is(Flags.Given) then Kind.Given(Kind.Val, Some(sig), extractImplicitConversion(valDef.tpt.tpe))
521+
else if symbol.flags.is(Flags.Enum) then Kind.EnumCase(Kind.Val)
518522
else defaultKind
519523

520524
val modifiers = kind match
521-
case _: Kind.Given => valDef.symbol
525+
case _: Kind.Given => symbol
522526
.getExtraModifiers()
523527
.filterNot(m => m == Modifier.Lazy || m == Modifier.Final)
524-
case _ => valDef.symbol.getExtraModifiers()
528+
case _ => symbol.getExtraModifiers()
525529

526-
mkMember(valDef.symbol, kind, sig)(
530+
mkMember(symbol, kind, sig)(
527531
modifiers = modifiers,
528-
deprecated = valDef.symbol.isDeprecated(),
529-
experimental = valDef.symbol.isExperimental()
532+
deprecated = symbol.isDeprecated(),
533+
experimental = symbol.isExperimental()
530534
)
531535

532536
def mkMember(symbol: Symbol, kind: Kind, signature: DSignature)(

0 commit comments

Comments
 (0)