From 65d3d9bc121880dc21a3233fd01854467866f3ac Mon Sep 17 00:00:00 2001 From: Amirouche Boubekki Date: Sun, 30 Sep 2012 21:48:58 +0200 Subject: [PATCH 1/3] use of iteritems to retrieve key and value --- jnius/jnius_export_class.pxi | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/jnius/jnius_export_class.pxi b/jnius/jnius_export_class.pxi index d652727..1a4d2e0 100644 --- a/jnius/jnius_export_class.pxi +++ b/jnius/jnius_export_class.pxi @@ -728,9 +728,8 @@ cdef class JavaMultipleMethod(object): else: methods = self.static_methods - for signature in methods: + for signature, jm in methods.iteritems(): sign_ret, sign_args = parse_definition(signature) - jm = methods[signature] if jm.is_varargs: args_ = args[:len(sign_args) - 1] + (args[len(sign_args) - 1:],) else: From c58de98b8ae045c6508e8c2d709a0c5c84b3439e Mon Sep 17 00:00:00 2001 From: Amirouche Boubekki Date: Sun, 30 Sep 2012 21:50:19 +0200 Subject: [PATCH 2/3] no need to recompute return and args definition --- jnius/jnius_export_class.pxi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jnius/jnius_export_class.pxi b/jnius/jnius_export_class.pxi index 1a4d2e0..2c0e276 100644 --- a/jnius/jnius_export_class.pxi +++ b/jnius/jnius_export_class.pxi @@ -729,7 +729,7 @@ cdef class JavaMultipleMethod(object): methods = self.static_methods for signature, jm in methods.iteritems(): - sign_ret, sign_args = parse_definition(signature) + sign_ret, sign_args = jm.definition_return, jm.definition_args if jm.is_varargs: args_ = args[:len(sign_args) - 1] + (args[len(sign_args) - 1:],) else: From b8ee0f8ab5c3f2621d332878bc02611d068e01ec Mon Sep 17 00:00:00 2001 From: Amirouche Boubekki Date: Sun, 30 Sep 2012 22:39:38 +0200 Subject: [PATCH 3/3] fix method resolution when they are varargs --- Makefile | 1 + jnius/jnius_export_class.pxi | 2 +- jnius/jnius_utils.pxi | 40 +++++++++++++++++------- tests/org/jnius/MultipleMethods.java | 32 +++++++++++++++++++ tests/test_method_multiple_signatures.py | 28 +++++++++++++++++ 5 files changed, 90 insertions(+), 13 deletions(-) create mode 100644 tests/org/jnius/MultipleMethods.java diff --git a/Makefile b/Makefile index bf4a09a..61a237b 100644 --- a/Makefile +++ b/Makefile @@ -9,4 +9,5 @@ html: tests: build_ext cd tests && javac org/jnius/HelloWorld.java cd tests && javac org/jnius/BasicsTest.java + cd tests && javac org/jnius/MultipleMethods.java cd tests && env PYTHONPATH=..:$(PYTHONPATH) nosetests -v diff --git a/jnius/jnius_export_class.pxi b/jnius/jnius_export_class.pxi index 2c0e276..3bad086 100644 --- a/jnius/jnius_export_class.pxi +++ b/jnius/jnius_export_class.pxi @@ -735,7 +735,7 @@ cdef class JavaMultipleMethod(object): else: args_ = args - score = calculate_score(sign_args, args_) + score = calculate_score(sign_args, args_, jm.is_varargs) if score <= 0: continue diff --git a/jnius/jnius_utils.pxi b/jnius/jnius_utils.pxi index 04fba92..d5d5726 100644 --- a/jnius/jnius_utils.pxi +++ b/jnius/jnius_utils.pxi @@ -85,16 +85,28 @@ cdef bytes lookup_java_object_name(JNIEnv *j_env, jobject j_obj): return name.replace('.', '/') -cdef int calculate_score(sign_args, args) except *: +cdef int calculate_score(sign_args, args, is_varargs=False) except *: cdef int index cdef int score = 0 cdef bytes r cdef JavaClass jc - if len(args) != len(sign_args): + if len(args) != len(sign_args) and not is_varargs: + # if the number of arguments expected is not the same + # as the number of arguments the method gets + # it can not be the method we are looking for except + # if the method has varargs aka. it takes + # an undefined number of arguments return -1 - - score += 10 + elif len(args) == len(sign_args) and not is_varargs: + # if the method has the good number of arguments and + # the method doesn't take varargs increment the score + # so that it takes precedence over a method with the same + # signature and varargs e.g. + # (Integer, Integer) takes precedence over (Integer, Integer, Integer...) + # and + # (Integer, Integer, Integer) takes precedence over (Integer, Integer, Integer...) + score += 10 for index in range(len(sign_args)): r = sign_args[index] @@ -193,12 +205,16 @@ cdef int calculate_score(sign_args, args) except *: return -1 # calculate the score for our subarray - subscore = calculate_score([r[1:]] * len(arg), arg) - if subscore == -1: - return -1 - - # look like the array is matching, accept it. - score += 10 - continue - + if len(arg) > 0: + # if there are supplemantal arguments we compute the score + subscore = calculate_score([r[1:]] * len(arg), arg) + if subscore == -1: + return -1 + # the supplemental arguments match the varargs arguments + score += 10 + continue + # else if there is no supplemental arguments + # it might be the good method but there may be + # a method with a better signature so we don't + # change this method score return score diff --git a/tests/org/jnius/MultipleMethods.java b/tests/org/jnius/MultipleMethods.java new file mode 100644 index 0000000..982a22f --- /dev/null +++ b/tests/org/jnius/MultipleMethods.java @@ -0,0 +1,32 @@ +package org.jnius; + +public class MultipleMethods { + + public static String resolve() { + return "resolved no args"; + } + + public static String resolve(String i) { + return "resolved one arg"; + } + + public static String resolve(String i, String j) { + return "resolved two args"; + } + + public static String resolve(String i, String j, int k) { + return "resolved two string and an integer"; + } + + public static String resolve(String i, String j, int k, int l) { + return "resolved two string and two integers"; + } + + public static String resolve(String i, String j, int... integers) { + return "resolved two args and varargs"; + } + + public static String resolve(int... integers) { + return "resolved varargs"; + } +} diff --git a/tests/test_method_multiple_signatures.py b/tests/test_method_multiple_signatures.py index e740189..b13db57 100644 --- a/tests/test_method_multiple_signatures.py +++ b/tests/test_method_multiple_signatures.py @@ -16,3 +16,31 @@ class MultipleSignature(unittest.TestCase): self.assertEquals(s.getBytes('utf8'), [104, 101, 108, 108, 111]) self.assertEquals(s.indexOf(ord('e')), 1) self.assertEquals(s.indexOf(ord('e'), 2), -1) + + def test_multiple_methods_no_args(self): + MultipleMethods = autoclass('org.jnius.MultipleMethods') + self.assertEqual(MultipleMethods.resolve(), 'resolved no args') + + def test_multiple_methods_one_arg(self): + MultipleMethods = autoclass('org.jnius.MultipleMethods') + self.assertEqual(MultipleMethods.resolve('arg'), 'resolved one arg') + + def test_multiple_methods_two_args(self): + MultipleMethods = autoclass('org.jnius.MultipleMethods') + self.assertEqual(MultipleMethods.resolve('one', 'two'), 'resolved two args') + + def test_multiple_methods_two_string_and_an_integer(self): + MultipleMethods = autoclass('org.jnius.MultipleMethods') + self.assertEqual(MultipleMethods.resolve('one', 'two', 1), 'resolved two string and an integer') + + def test_multiple_methods_two_string_and_two_integers(self): + MultipleMethods = autoclass('org.jnius.MultipleMethods') + self.assertEqual(MultipleMethods.resolve('one', 'two', 1, 2), 'resolved two string and two integers') + + def test_multiple_methods_varargs(self): + MultipleMethods = autoclass('org.jnius.MultipleMethods') + self.assertEqual(MultipleMethods.resolve(1, 2, 3), 'resolved varargs') + + def test_multiple_methods_two_args_and_varargs(self): + MultipleMethods = autoclass('org.jnius.MultipleMethods') + self.assertEqual(MultipleMethods.resolve('one', 'two', 1, 2, 3), 'resolved two args and varargs')