Skip to content

Commit 3c5502e

Browse files
committed
Handle implicit conversions on generation
1 parent 6c634e5 commit 3c5502e

File tree

1 file changed

+43
-1
lines changed

1 file changed

+43
-1
lines changed

scaladoc/src/dotty/tools/scaladoc/Inkuire.scala

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ object Inkuire {
88

99
def beforeSave(): Unit = {
1010
db = db.copy(
11-
functions = db.functions.sortBy(_.hashCode),
11+
functions = functions.sortBy(_.hashCode),
1212
types = db.types.toSeq.sortBy(_._1.uuid).toMap,
1313
implicitConversions = db.implicitConversions.sortBy(_._1.hashCode)
1414
)
@@ -34,6 +34,48 @@ object Inkuire {
3434
case _ => e
3535
}
3636

37+
def functions: Seq[ExternalSignature] = Inkuire.db.functions.flatMap { func =>
38+
val fromConversions = Inkuire.db.implicitConversions.filter { ic =>
39+
func.signature.receiver.nonEmpty && matchingICTypes(ic._2, func.signature.receiver.get.typ)
40+
}.map { ic =>
41+
func.copy(
42+
signature = func.signature.copy(
43+
receiver = func.signature.receiver.map { rcvr =>
44+
Contravariance(
45+
newReceiver(rcvr.typ, ic._2, ic._1)
46+
)
47+
}
48+
)
49+
)
50+
}
51+
Seq(func) ++ fromConversions
52+
}
53+
.distinct
54+
55+
def matchingICTypes(a: TypeLike, b: TypeLike): Boolean = (a, b) match {
56+
case (a: Type, b: Type) if a.params.size == 0 && b.params.size == 0 && a.itid == b.itid => true
57+
case (a: Type, b: Type) if a.params.size == 1 && b.params.size == 1 && a.itid == b.itid =>
58+
a.params.head.typ.isInstanceOf[Type] && a.params.head.typ.asInstanceOf[Type].isVariable &&
59+
b.params.head.typ.isInstanceOf[Type] && b.params.head.typ.asInstanceOf[Type].isVariable
60+
case _ => false
61+
}
62+
63+
def newReceiver(old: TypeLike, to: TypeLike, from: TypeLike): TypeLike = (old, to) match {
64+
case (a: Type, b: Type) if a.params.size == 0 && b.params.size == 0 && a.itid == b.itid => from
65+
case (a: Type, b: Type) if a.params.size == 1 && b.params.size == 1 && a.itid == b.itid
66+
&& a.params.head.typ.isInstanceOf[Type] && a.params.head.typ.asInstanceOf[Type].isVariable &&
67+
b.params.head.typ.isInstanceOf[Type] && b.params.head.typ.asInstanceOf[Type].isVariable =>
68+
if from.isInstanceOf[Type] && from.asInstanceOf[Type].params.size == 1 && from.asInstanceOf[Type].params.head.typ.isInstanceOf[Type] && from.asInstanceOf[Type].params.head.typ.asInstanceOf[Type].isVariable then
69+
from.asInstanceOf[Type].copy(
70+
params = Seq(Contravariance(a.params.head.typ.asInstanceOf[Type]))
71+
)
72+
else if from.isInstanceOf[Type] && from.asInstanceOf[Type].isVariable then
73+
a.params.head.typ.asInstanceOf[Type]
74+
else
75+
from
76+
case _ => old
77+
}
78+
3779
case class InkuireDb(
3880
functions: Seq[ExternalSignature],
3981
types: Map[ITID, (Type, Seq[Type])],

0 commit comments

Comments
 (0)