@@ -10,6 +10,7 @@ import scala.quoted._
10
10
import SymOps ._
11
11
import NameNormalizer ._
12
12
import SyntheticsSupport ._
13
+ import dotty .tools .dotc .core .NameKinds
13
14
14
15
trait ClassLikeSupport :
15
16
self : TastyParser =>
@@ -476,9 +477,14 @@ trait ClassLikeSupport:
476
477
val memberInfo = unwrapMemberInfo(c, methodSymbol)
477
478
478
479
val basicKind : Kind .Def = Kind .Def (
479
- genericTypes.map(mkTypeArgument(_, memberInfo.genericTypes)),
480
- paramLists.zipWithIndex.map { (pList, index) =>
481
- ParametersList (pList.params.map(mkParameter(_, paramPrefix, memberInfo = memberInfo.paramLists(index))), paramListModifier(pList.params))
480
+ genericTypes.map(mkTypeArgument(_, memberInfo.genericTypes, memberInfo.contextBounds)),
481
+ paramLists.zipWithIndex.flatMap { (pList, index) =>
482
+ memberInfo.paramLists(index) match
483
+ case EvidenceOnlyParameterList => Nil
484
+ case info : RegularParameterList =>
485
+ Seq (ParametersList (pList.params.map(
486
+ mkParameter(_, paramPrefix, memberInfo = info)), paramListModifier(pList.params)
487
+ ))
482
488
}
483
489
)
484
490
@@ -523,20 +529,30 @@ trait ClassLikeSupport:
523
529
isGrouped
524
530
)
525
531
526
- def mkTypeArgument (argument : TypeDef , memberInfo : Map [String , TypeBounds ] = Map .empty): TypeParameter =
532
+ def mkTypeArgument (
533
+ argument : TypeDef ,
534
+ memberInfo : Map [String , TypeBounds ] = Map .empty,
535
+ contextBounds : Map [String , DSignature ] = Map .empty
536
+ ): TypeParameter =
527
537
val variancePrefix : " +" | " -" | " " =
528
538
if argument.symbol.flags.is(Flags .Covariant ) then " +"
529
539
else if argument.symbol.flags.is(Flags .Contravariant ) then " -"
530
540
else " "
531
541
532
542
val name = argument.symbol.normalizedName
533
543
val normalizedName = if name.matches(" _\\ $\\ d*" ) then " _" else name
544
+ val boundsSignature = memberInfo.get(name).fold(argument.rhs.asSignature)(_.asSignature)
545
+ val signature = contextBounds.get(name) match
546
+ case None => boundsSignature
547
+ case Some (contextBoundsSignature) =>
548
+ boundsSignature ++ DSignature (" : " ) ++ contextBoundsSignature
549
+
534
550
TypeParameter (
535
551
argument.symbol.getAnnotations(),
536
552
variancePrefix,
537
553
normalizedName,
538
554
argument.symbol.dri,
539
- memberInfo.get(name).fold(argument.rhs.asSignature)(_.asSignature)
555
+ signature
540
556
)
541
557
542
558
def parseTypeDef (typeDef : TypeDef ): Member =
@@ -586,16 +602,71 @@ trait ClassLikeSupport:
586
602
deprecated = deprecated
587
603
)
588
604
589
- case class MemberInfo (genericTypes : Map [String , TypeBounds ], paramLists : List [Map [String , TypeRepr ]], res : TypeRepr )
605
+ object EvidenceOnlyParameterList
606
+ type RegularParameterList = Map [String , TypeRepr ]
607
+ type ParameterList = RegularParameterList | EvidenceOnlyParameterList .type
608
+
609
+ case class MemberInfo (
610
+ genericTypes : Map [String , TypeBounds ],
611
+ paramLists : List [ParameterList ],
612
+ res : TypeRepr ,
613
+ contextBounds : Map [String , DSignature ] = Map .empty,
614
+ )
615
+
590
616
591
617
def unwrapMemberInfo (c : ClassDef , symbol : Symbol ): MemberInfo =
592
618
val baseTypeRepr = memberInfo(c, symbol)
593
619
620
+ def isSyntheticEvidence (name : String ) =
621
+ if ! name.startsWith(NameKinds .EvidenceParamName .separator) then false else
622
+ // This assumes that every parameter that starts with `evidence$` and is implicit is generated by compiler to desugar context bound.
623
+ // Howrever, this is just a heuristic, so
624
+ // `def foo[A](evidence$1: ClassTag[A]) = 1`
625
+ // will be documented as
626
+ // `def foo[A: ClassTag] = 1`.
627
+ // Scala spec states that `$` should not be used in names and behaviour may be undefiend in such case.
628
+ // Documenting method slightly different then its definition is withing the 'undefiend behaviour'.
629
+ symbol.paramSymss.flatten.find(_.name == name).exists(_.flags.is(Flags .Implicit ))
630
+
594
631
def handlePolyType (polyType : PolyType ): MemberInfo =
595
632
MemberInfo (polyType.paramNames.zip(polyType.paramBounds).toMap, List .empty, polyType.resType)
596
633
597
634
def handleMethodType (memberInfo : MemberInfo , methodType : MethodType ): MemberInfo =
598
- MemberInfo (memberInfo.genericTypes, memberInfo.paramLists ++ List (methodType.paramNames.zip(methodType.paramTypes).toMap), methodType.resType)
635
+ val rawParams = methodType.paramNames.zip(methodType.paramTypes).toMap
636
+ val (evidences, notEvidences) = rawParams.partition(e => isSyntheticEvidence(e._1))
637
+
638
+
639
+ def findParamRefs (t : TypeRepr ): Seq [ParamRef ] = t match
640
+ case paramRef : ParamRef => Seq (paramRef)
641
+ case AppliedType (_, args) => args.flatMap(findParamRefs)
642
+ case MatchType (bound, scrutinee, cases) =>
643
+ findParamRefs(bound) ++ findParamRefs(scrutinee)
644
+ case _ => Nil
645
+
646
+ def nameForRef (ref : ParamRef ): String =
647
+ val PolyType (names, _, _) = ref.binder
648
+ names(ref.paramNum)
649
+
650
+ val (paramsThatLookLikeContextBounds, contextBounds) =
651
+ evidences.partitionMap {
652
+ case (_, AppliedType (tpe, List (typeParam : ParamRef ))) =>
653
+ Right (nameForRef(typeParam) -> tpe.asSignature)
654
+ case (name, original) =>
655
+ findParamRefs(original) match
656
+ case Nil => Left ((name, original))
657
+ case typeParam :: _ =>
658
+ val name = nameForRef(typeParam)
659
+ val signature = Seq (s " ([ $name] =>> " ) ++ original.asSignature ++ Seq (" )" )
660
+ Right (name -> signature)
661
+ }
662
+
663
+ val newParams = notEvidences ++ paramsThatLookLikeContextBounds
664
+
665
+ val newLists : List [ParameterList ] = if newParams.isEmpty && contextBounds.nonEmpty
666
+ then memberInfo.paramLists ++ Seq (EvidenceOnlyParameterList )
667
+ else memberInfo.paramLists ++ Seq (newParams)
668
+
669
+ MemberInfo (memberInfo.genericTypes, newLists , methodType.resType, contextBounds.toMap)
599
670
600
671
def handleByNameType (memberInfo : MemberInfo , byNameType : ByNameType ): MemberInfo =
601
672
MemberInfo (memberInfo.genericTypes, memberInfo.paramLists, byNameType.underlying)
0 commit comments