Merge pull request #36 from amirouche/method-resolutions-fixes

Method resolutions fixes for the case where there are varargs
This commit is contained in:
Gabriel Pettier 2012-09-30 14:04:28 -07:00
commit 08a9d7888d
5 changed files with 92 additions and 16 deletions

View File

@ -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

View File

@ -728,15 +728,14 @@ cdef class JavaMultipleMethod(object):
else:
methods = self.static_methods
for signature in methods:
sign_ret, sign_args = parse_definition(signature)
jm = methods[signature]
for signature, jm in methods.iteritems():
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:
args_ = args
score = calculate_score(sign_args, args_)
score = calculate_score(sign_args, args_, jm.is_varargs)
if score <= 0:
continue

View File

@ -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

View File

@ -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";
}
}

View File

@ -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')