Search code examples
clojureclojure-java-interop

Clojure deftype with Type Hints?: Can't find matching method, leave off hints for auto match


I'm getting an IllegalArgumentException: Can't find matching method: render, leave off hints for auto match, but I need the type hints to overload the method. What am I missing...?

(defprotocol LinkRendererProtocol                                                                                                                                                                                                             
  (render                                                                                                                                                                                                                                     
    [this node]                                                                                                                                                                                                                               
    [this node text]                                                                                                                                                                                                                          
    [this node url title text]                                                                                                                                                                                                                
))                                                                                                                                                                                                                                            


(deftype LinkRenderer [handlers]                                                                                                                                                                                                              
  LinkRendererProtocol                                                                                                                                                                                                                        

  (render [this ^AutoLinkNode node]                                                                                                                                                                                                           
    (rendering :auto-link handlers node))                                                                                                                                                                                                     
  (render [this ^ExpLinkNode  node text]                                                                                                                                                                                                      
    (rendering :exp-link handlers node text))                                                                                                                                                                                                 
  (render [this ^ExpImageNode node text]                                                                                                                                                                                                      
    (rendering :exp-image-link handlers node text))                                                                                                                                                                                           
  (render [this ^MailLinkNode node]                                                                                                                                                                                                           
    (rendering :mail-link handlers node))                                                                                                                                                                                                     
  (render [this ^RefLinkNode  node url title text]                                                                                                                                                                                            
    (rendering :ref-link handlers node url title text))                                                                                                                                                                                       
  (render [this ^RefImageNode node url title alt]                                                                                                                                                                                             
    (rendering :ref-image handlers node url title alt))                                                                                                                                                                                       
  (render [this ^WikiLinkNode node]                                                                                                                                                                                                           
    (rendering :wiki-link handlers node)))                                                                                                                                                                                                    

(defn link-renderer                                                                                                                                                                                                                           
  [handlers]                                                                                                                                                                                                                                  
  (LinkRenderer. (merge default-handlers handlers)))     

Solution

  • Protocol methods cannot be type-hinted. Even if they supported type hints, you'd probably need to put them on the protocol method declaration itself.

    If you want your method to be overloaded or simply to have parameter types other than Object, you'll need to declare it as an interface method and implement that interface. You could do that from Clojure (see definterface and gen-interface) or simply include a .java file declaring that interface in your project. (It goes without saying that a method declared in this way would have to be called using interop syntax.)

    Note that overloaded methods are resolved statically, so you cannot use method overloading as a replacement for chained instance? checks.