summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStuart Halloway <stu@thinkrelevance.com>2010-05-22 14:28:33 -0400
committerStuart Halloway <stu@thinkrelevance.com>2010-05-24 10:45:24 -0400
commit050693123206c0b46c990f17fe127a61bd50edb9 (patch)
tree5b80cfc032068fccef3135f3e6ac89553cf4a46d
parenta6f755c2ac5873c0286d090c0022d345e3e6c9e3 (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.java11
-rw-r--r--test/clojure/test_clojure/protocols.clj8
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 []