diff options
author | Stuart Halloway <stu@thinkrelevance.com> | 2010-05-22 14:28:33 -0400 |
---|---|---|
committer | Stuart Halloway <stu@thinkrelevance.com> | 2010-05-24 10:45:24 -0400 |
commit | 050693123206c0b46c990f17fe127a61bd50edb9 (patch) | |
tree | 5b80cfc032068fccef3135f3e6ac89553cf4a46d | |
parent | a6f755c2ac5873c0286d090c0022d345e3e6c9e3 (diff) |
fix NPE if redefined protocol removes method #333 (Mike Hinchey)
Signed-off-by: Stuart Halloway <stu@thinkrelevance.com>
-rw-r--r-- | src/jvm/clojure/lang/Compiler.java | 11 | ||||
-rw-r--r-- | test/clojure/test_clojure/protocols.clj | 8 |
2 files changed, 16 insertions, 3 deletions
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java index 8ce076d4..2b382989 100644 --- a/src/jvm/clojure/lang/Compiler.java +++ b/src/jvm/clojure/lang/Compiler.java @@ -2816,8 +2816,15 @@ static class InvokeExpr implements Expr{ if(this.protocolOn != null) { IPersistentMap mmap = (IPersistentMap) RT.get(pvar.get(), methodMapKey); - String mname = munge(((Keyword) mmap.valAt(Keyword.intern(fvar.sym))).sym.toString()); - List methods = Reflector.getMethods(protocolOn, args.count() - 1, mname, false); + Keyword mmapVal = (Keyword) mmap.valAt(Keyword.intern(fvar.sym)); + if (mmapVal == null) { + throw new IllegalArgumentException( + "No method of interface: " + protocolOn.getName() + + " found for function: " + fvar.sym + " of protocol: " + pvar.sym + + " (The protocol method may have been defined before and removed.)"); + } + String mname = munge(mmapVal.sym.toString()); + List methods = Reflector.getMethods(protocolOn, args.count() - 1, mname, false); if(methods.size() != 1) throw new IllegalArgumentException( "No single method: " + mname + " of interface: " + protocolOn.getName() + diff --git a/test/clojure/test_clojure/protocols.clj b/test/clojure/test_clojure/protocols.clj index 32dbf812..90de0010 100644 --- a/test/clojure/test_clojure/protocols.clj +++ b/test/clojure/test_clojure/protocols.clj @@ -82,7 +82,13 @@ (let [obj (reify ExampleProtocol (baz [a b] "two-arg baz!"))] (is (= "two-arg baz!" (baz obj nil))) - (is (thrown? AbstractMethodError (baz obj)))))) + (is (thrown? AbstractMethodError (baz obj))))) + (testing "you can redefine a protocol with different methods" + (eval '(defprotocol Elusive (old-method [x]))) + (eval '(defprotocol Elusive (new-method [x]))) + (is (= :new-method (eval '(new-method (reify Elusive (new-method [x] :new-method)))))) + (is (fails-with-cause? IllegalArgumentException #"No method of interface: user\.Elusive found for function: old-method of protocol: Elusive \(The protocol method may have been defined before and removed\.\)" + (eval '(old-method (reify Elusive (new-method [x] :new-method)))))))) (deftype ExtendTestWidget [name]) (deftype HasProtocolInline [] |