@@ -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