Reputation: 651
In working to annotate clojang, I'm having some trouble with protocol methods that call overloaded Java methods. I've narrowed the problem down to the following minimal tricky case from 'clojang.jinterface.otp.nodes
:
(ns clojang.jinterface.otp.nodes
(:require [clojure.core.typed :as t :refer [ann ann-protocol]]
[clojure.core.typed.utils :refer [defprotocol]])
(:import [com.ericsson.otp.erlang OtpTransport]
[java.net InetAddress])
(:refer-clojure :exclude [defprotocol]))
(ann-protocol AbstractNodeObject
create-transport
(t/IFn [AbstractNodeObject InetAddress int -> (t/Nilable OtpTransport)]
[AbstractNodeObject String int -> (t/Nilable OtpTransport)]))
(defprotocol AbstractNodeObject
(create-transport [this addr port-num]
"Create instance of ``OtpTransport``."))
(extend-type AbstractNode
AbstractNodeObject
(create-transport [this addr port-num]
(.createTransport this addr port-num)))
Per the JInterface Javadocs, AbstractNode.createTransport
can take a java.lang.String
or a java.net.InetAddress
as addr
. While I believe I've annotated this correctly in the ann-protocol
form, core.typed
complains about the implementation (on the last line in the example). I suspect I can somehow fix this using t/inst
, but have yet to sort out the exact incantation.
I know I could add the type hint, ^String
or ^InetAddress
to the arglist (on the second to last line of the example) and remove the other clause from the corresponding t/IFn
form above, but how can I tell core.typed
that either type is viable?
Upvotes: 2
Views: 100
Reputation: 651
After a brief discussion with Ambrose on IRC, the solution we've reached is to branch on (string? addr)
as follows:
(create-transport [this addr port-num]
(if (string? addr)
(.createTransport this ^String addr port-num)
(.createTransport this ^InetAddress addr port-num)))
and to replace the IFn
annotation with:
[AbstractNodeObject (t/U String InetAddress) int -> (t/Nilable OtpTransport)]
Upvotes: 2