@@ -476,9 +476,14 @@ trait ClassLikeSupport:
476
476
val memberInfo = unwrapMemberInfo(c, methodSymbol)
477
477
478
478
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))
479
+ genericTypes.map(mkTypeArgument(_, memberInfo.genericTypes, memberInfo.contextBounds)),
480
+ paramLists.zipWithIndex.flatMap { (pList, index) =>
481
+ memberInfo.paramLists(index) match
482
+ case EvidenceOnlyParameterList => Nil
483
+ case info : RegularParameterList =>
484
+ Seq (ParametersList (pList.params.map(
485
+ mkParameter(_, paramPrefix, memberInfo = info)), paramListModifier(pList.params)
486
+ ))
482
487
}
483
488
)
484
489
@@ -523,20 +528,30 @@ trait ClassLikeSupport:
523
528
isGrouped
524
529
)
525
530
526
- def mkTypeArgument (argument : TypeDef , memberInfo : Map [String , TypeBounds ] = Map .empty): TypeParameter =
531
+ def mkTypeArgument (
532
+ argument : TypeDef ,
533
+ memberInfo : Map [String , TypeBounds ] = Map .empty,
534
+ contextBounds : Map [String , DSignature ] = Map .empty
535
+ ): TypeParameter =
527
536
val variancePrefix : " +" | " -" | " " =
528
537
if argument.symbol.flags.is(Flags .Covariant ) then " +"
529
538
else if argument.symbol.flags.is(Flags .Contravariant ) then " -"
530
539
else " "
531
540
532
541
val name = argument.symbol.normalizedName
533
542
val normalizedName = if name.matches(" _\\ $\\ d*" ) then " _" else name
543
+ val boundsSignature = memberInfo.get(name).fold(argument.rhs.asSignature)(_.asSignature)
544
+ val signature = contextBounds.get(name) match
545
+ case None => boundsSignature
546
+ case Some (contextBoundsSignature) =>
547
+ boundsSignature ++ DSignature (" : " ) ++ contextBoundsSignature
548
+
534
549
TypeParameter (
535
550
argument.symbol.getAnnotations(),
536
551
variancePrefix,
537
552
normalizedName,
538
553
argument.symbol.dri,
539
- memberInfo.get(name).fold(argument.rhs.asSignature)(_.asSignature)
554
+ signature
540
555
)
541
556
542
557
def parseTypeDef (typeDef : TypeDef ): Member =
@@ -586,7 +601,18 @@ trait ClassLikeSupport:
586
601
deprecated = deprecated
587
602
)
588
603
589
- case class MemberInfo (genericTypes : Map [String , TypeBounds ], paramLists : List [Map [String , TypeRepr ]], res : TypeRepr )
604
+ object EvidenceOnlyParameterList
605
+ type RegularParameterList = Map [String , TypeRepr ]
606
+ type ParameterList = RegularParameterList | EvidenceOnlyParameterList .type
607
+
608
+ case class MemberInfo (
609
+ genericTypes : Map [String , TypeBounds ],
610
+ paramLists : List [ParameterList ],
611
+ res : TypeRepr ,
612
+ contextBounds : Map [String , DSignature ] = Map .empty,
613
+ )
614
+
615
+ def isSyntheticEvidence (name : String ) = name.startsWith(" evidence$" )
590
616
591
617
def unwrapMemberInfo (c : ClassDef , symbol : Symbol ): MemberInfo =
592
618
val baseTypeRepr = memberInfo(c, symbol)
@@ -595,7 +621,35 @@ trait ClassLikeSupport:
595
621
MemberInfo (polyType.paramNames.zip(polyType.paramBounds).toMap, List .empty, polyType.resType)
596
622
597
623
def handleMethodType (memberInfo : MemberInfo , methodType : MethodType ): MemberInfo =
598
- MemberInfo (memberInfo.genericTypes, memberInfo.paramLists ++ List (methodType.paramNames.zip(methodType.paramTypes).toMap), methodType.resType)
624
+ val rawParams = methodType.paramNames.zip(methodType.paramTypes).toMap
625
+ val (evidences, newParams) = rawParams.partition(e => isSyntheticEvidence(e._1))
626
+ val newLists : List [ParameterList ] = if newParams.isEmpty && evidences.nonEmpty
627
+ then memberInfo.paramLists ++ Seq (EvidenceOnlyParameterList )
628
+ else memberInfo.paramLists ++ Seq (newParams)
629
+
630
+ def findParamRefs (t : TypeRepr ): Seq [ParamRef ] = t match
631
+ case paramRef : ParamRef => Seq (paramRef)
632
+ case AppliedType (_, args) => args.flatMap(findParamRefs)
633
+ case MatchType (bound, scrutinee, cases) =>
634
+ findParamRefs(bound) ++ findParamRefs(scrutinee)
635
+ case _ => Nil
636
+
637
+ def nameForRef (ref : ParamRef ): String =
638
+ val PolyType (names, _, _) = ref.binder
639
+ names(ref.paramNum)
640
+
641
+ val contextBounds =
642
+ evidences.collect {
643
+ case (_, AppliedType (tpe, List (typeParam : ParamRef ))) =>
644
+ nameForRef(typeParam) -> tpe.asSignature
645
+ case (_, original) =>
646
+ val typeParam = findParamRefs(original).head // TODO throw nicer error!
647
+ val name = nameForRef(typeParam)
648
+ val signature = Seq (s " ([ $name] =>> " ) ++ original.asSignature ++ Seq (" )" )
649
+ name -> signature
650
+ }
651
+
652
+ MemberInfo (memberInfo.genericTypes, newLists , methodType.resType, contextBounds.toMap)
599
653
600
654
def handleByNameType (memberInfo : MemberInfo , byNameType : ByNameType ): MemberInfo =
601
655
MemberInfo (memberInfo.genericTypes, memberInfo.paramLists, byNameType.underlying)
0 commit comments