Skip to content
Permalink
Browse files

Fix virtual method bug. Fixes #445, Fixes #441

  • Loading branch information...
Thrameos committed May 25, 2019
1 parent 49a0e61 commit 71cb9c416916d8f48560a4789c7b104ddb1b37b0
@@ -1,6 +1,7 @@
MANIFEST
*~
/test/classes/
/test/jars/
*/build*/

# Byte-compiled / optimized / DLL files
0 jpype/_core.py 100755 → 100644
No changes.
0 jpype/_jclass.py 100755 → 100644
No changes.
@@ -18,6 +18,7 @@

from . import _jclass
from . import _jcustomizer
from . import _jtypes

JOverride = _jclass.JOverride

@@ -59,33 +60,20 @@ def __delitem__(self, i):
@JOverride(sticky=True)
def addAll(self, v):
if isPythonSequence(v):
r = False
for i in v:
r = self.add(i) or r
return r
else:
return self._addAll(v)
v = _jclass.JClass('java.util.Arrays').asList(v)
return self._addAll(v)

@JOverride(sticky=True)
def removeAll(self, v):
if isPythonSequence(v):
r = False
for i in v:
r = self.remove(i) or r
return r
else:
return self._removeAll(v)
v = _jclass.JClass('java.util.Arrays').asList(v)
return self._removeAll(v)

@JOverride(sticky=True)
def retainAll(self, v):
if isPythonSequence(v):
r = _jclass.JClass("java.util.ArrayList")(len(v))
for i in v:
r.add(i)
else:
r = v

return self._retainAll(r)
v = _jclass.JClass('java.util.Arrays').asList(v)
return self._retainAll(v)


@_jcustomizer.JImplementationFor('java.util.List')
@@ -95,8 +83,6 @@ class _JList(object):
This customizer adds the Python list operator to function on classes
that implement the Java List interface.
"""
# def __jclass_init__(cls):
# type.__setattr__(cls, 'addAll', _JList.addAll)

def __getitem__(self, ndx):
if isinstance(ndx, slice):
@@ -114,37 +100,37 @@ def __getitem__(self, ndx):

def __setitem__(self, ndx, v):
if isinstance(ndx, slice):
start = ndx.start
stop = ndx.stop
if start < 0:
start = self.size() + start
if stop < 0:
stop = self.size() + stop
for i in range(start, stop):
self.remove(start)
if isinstance(v, collections.Sequence):
ndx = start
for i in v:
self.add(ndx, i)
ndx += 1
if isPythonSequence(v):
v = _jclass.JClass('java.util.Arrays').asList(v)
self[ndx.start:ndx.stop].clear()
self.addAll(start, v)
else:
if ndx < 0:
ndx = self.size() + ndx
self.set(ndx, v)

def __delitem__(self, ndx):
if isinstance(ndx, slice):
self[ndx.start:ndx.stop].clear()
elif hasattr(ndx, '__index__'):
return self.remove(_jtypes.JInt(ndx))
else:
raise TypeError("Incorrect arguments to del")

@JOverride(sticky=True)
def addAll(self, v, v2=None):
if isPythonSequence(v):
r = False
if v2 is not None: # assume form (int, values)
for i in range(len(v2)):
r = r or self.add(v + i, v2[i])
else:
for i in v:
r = self.add(i) or r
return r
def addAll(self, *args):
if len(args) == 1:
v = args[0]
if isPythonSequence(v):
v = _jclass.JClass('java.util.Arrays').asList(v)
self._addAll(v)
elif len(args) == 2 and hasattr(args[0], '__index__'):
v = args[1]
if isPythonSequence(v):
v = _jclass.JClass('java.util.Arrays').asList(v)
self._addAll(args[0], v)
else:
return self._addAll(v)
raise TypeError("Incorrect arguments to addAll")


def isPythonMapping(v):
0 jpype/_jexception.py 100755 → 100644
No changes.
@@ -193,6 +193,7 @@ class JPJavaFrame
// Void
void CallStaticVoidMethodA(jclass a0, jmethodID a1, jvalue* a2);
void CallVoidMethodA(jobject a0, jmethodID a1, jvalue* a2);
void CallNonvirtualVoidMethodA(jobject a0, jclass a1, jmethodID a2, jvalue* a3);
void CallVoidMethod(jobject a0, jmethodID a1);

// Bool
@@ -147,6 +147,7 @@ class JPMethodOverload
bool m_IsConstructor;
OverloadList m_MoreSpecificOverloads;
bool m_Ordered;
bool m_IsAbstract;
} ;

#endif // _JPMETHODOVERLOAD_H_
5 native/common/jp_booleantype.cpp 100755 → 100644
@@ -148,7 +148,10 @@ JPPyObject JPBooleanType::invoke(JPJavaFrame& frame, jobject obj, jclass clazz,
jvalue v;
{
JPPyCallRelease call;
field(v) = frame.CallNonvirtualBooleanMethodA(obj, clazz, mth, val);
if (clazz == NULL)
field(v) = frame.CallBooleanMethodA(obj, mth, val);
else
field(v) = frame.CallNonvirtualBooleanMethodA(obj, clazz, mth, val);
}
return convertToPythonObject(v);
}
5 native/common/jp_bytetype.cpp 100755 → 100644
@@ -168,7 +168,10 @@ JPPyObject JPByteType::invoke(JPJavaFrame& frame, jobject obj, jclass clazz, jme
jvalue v;
{
JPPyCallRelease call;
field(v) = frame.CallNonvirtualByteMethodA(obj, clazz, mth, val);
if (clazz == NULL)
field(v) = frame.CallByteMethodA(obj, mth, val);
else
field(v) = frame.CallNonvirtualByteMethodA(obj, clazz, mth, val);
}
return convertToPythonObject(v);
}
5 native/common/jp_chartype.cpp 100755 → 100644
@@ -143,7 +143,10 @@ JPPyObject JPCharType::invoke(JPJavaFrame& frame, jobject obj, jclass clazz, jme
jvalue v;
{
JPPyCallRelease call;
field(v) = frame.CallNonvirtualCharMethodA(obj, clazz, mth, val);
if (clazz == NULL)
field(v) = frame.CallCharMethodA(obj, mth, val);
else
field(v) = frame.CallNonvirtualCharMethodA(obj, clazz, mth, val);
}
return convertToPythonObject(v);
}
@@ -155,15 +155,18 @@ JPPyObject JPClass::invokeStatic(JPJavaFrame& frame, jclass claz, jmethodID mth,
JP_TRACE_OUT;
}

JPPyObject JPClass::invoke(JPJavaFrame& frame, jobject claz, jclass clazz, jmethodID mth, jvalue* val)
JPPyObject JPClass::invoke(JPJavaFrame& frame, jobject obj, jclass clazz, jmethodID mth, jvalue* val)
{
JP_TRACE_IN("JPClass::invoke");
jvalue v;

// Call method
{
JPPyCallRelease call;
v.l = frame.CallNonvirtualObjectMethodA(claz, clazz, mth, val);
if (clazz == NULL)
v.l = frame.CallObjectMethodA(obj, mth, val);
else
v.l = frame.CallNonvirtualObjectMethodA(obj, clazz, mth, val);
}

// Get the return type
5 native/common/jp_doubletype.cpp 100755 → 100644
@@ -152,7 +152,10 @@ JPPyObject JPDoubleType::invoke(JPJavaFrame& frame, jobject obj, jclass clazz, j
jvalue v;
{
JPPyCallRelease call;
field(v) = frame.CallNonvirtualDoubleMethodA(obj, clazz, mth, val);
if (clazz == NULL)
field(v) = frame.CallDoubleMethodA(obj, mth, val);
else
field(v) = frame.CallNonvirtualDoubleMethodA(obj, clazz, mth, val);
}
return convertToPythonObject(v);
}
@@ -1312,6 +1312,12 @@ void JPJavaFrame::CallVoidMethodA(jobject a0, jmethodID a1, jvalue* a2)
env->functions->CallVoidMethodA(env, a0, a1, a2);
}

void JPJavaFrame::CallNonvirtualVoidMethodA(jobject a0, jclass a1, jmethodID a2, jvalue* a3)
{
JPCall call(*this, "CallVoidMethodA");
env->functions->CallNonvirtualVoidMethodA(env, a0, a1, a2, a3);
}

void JPJavaFrame::CallVoidMethod(jobject a0, jmethodID a1)
{
JPCall call(*this, "CallVoidMethod");
0 native/common/jp_exception.cpp 100755 → 100644
No changes.
5 native/common/jp_floattype.cpp 100755 → 100644
@@ -163,7 +163,10 @@ JPPyObject JPFloatType::invoke(JPJavaFrame& frame, jobject obj, jclass clazz, jm
jvalue v;
{
JPPyCallRelease call;
field(v) = frame.CallNonvirtualFloatMethodA(obj, clazz, mth, val);
if (clazz == NULL)
field(v) = frame.CallFloatMethodA(obj, mth, val);
else
field(v) = frame.CallNonvirtualFloatMethodA(obj, clazz, mth, val);
}
return convertToPythonObject(v);
}
5 native/common/jp_inttype.cpp 100755 → 100644
@@ -148,7 +148,10 @@ JPPyObject JPIntType::invoke(JPJavaFrame& frame, jobject obj, jclass clazz, jmet
jvalue v;
{
JPPyCallRelease call;
field(v) = frame.CallNonvirtualIntMethodA(obj, clazz, mth, val);
if (clazz == NULL)
field(v) = frame.CallIntMethodA(obj, mth, val);
else
field(v) = frame.CallNonvirtualIntMethodA(obj, clazz, mth, val);
}
return convertToPythonObject(v);
}
5 native/common/jp_longtype.cpp 100755 → 100644
@@ -147,7 +147,10 @@ JPPyObject JPLongType::invoke(JPJavaFrame& frame, jobject obj, jclass clazz, jme
jvalue v;
{
JPPyCallRelease call;
field(v) = frame.CallNonvirtualLongMethodA(obj, clazz, mth, val);
if (clazz == NULL)
field(v) = frame.CallLongMethodA(obj, mth, val);
else
field(v) = frame.CallNonvirtualLongMethodA(obj, clazz, mth, val);
}
return convertToPythonObject(v);
}
4 native/common/jp_method.cpp 100755 → 100644
@@ -216,7 +216,7 @@ JPMatch JPMethod::findOverload(JPPyObjectVector& arg, bool callInstance)
{
ss << "\t" << (*it)->toString() << std::endl;
}
JP_RAISE_RUNTIME_ERROR(ss.str());
JP_RAISE_TYPE_ERROR(ss.str());
JP_TRACE(ss.str());
}

@@ -244,7 +244,7 @@ JPMatch JPMethod::findOverload(JPPyObjectVector& arg, bool callInstance)
ss << "\t" << current->toString();
ss << std::endl;
}
JP_RAISE_RUNTIME_ERROR(ss.str());
JP_RAISE_TYPE_ERROR(ss.str());
}
return bestMatch;
JP_TRACE_OUT;
@@ -26,6 +26,7 @@ JPMethodOverload::JPMethodOverload(JPClass* claz, jobject mth) : m_Method(mth)
m_IsStatic = JPJni::isMemberStatic(mth);
m_IsFinal = JPJni::isMemberFinal(mth);
m_IsVarArgs = JPJni::isMethodVarArgs(mth);
m_IsAbstract = JPJni::isMemberAbstract(mth);

// Method ID
m_MethodID = frame.FromReflectedMethod(m_Method.get());
@@ -266,7 +267,9 @@ JPPyObject JPMethodOverload::invoke(JPMatch& match, JPPyObjectVector& arg)
{
JPValue* selfObj = JPPythonEnv::getJavaValue(arg[0]);
jobject c = selfObj->getJavaObject();
jclass clazz = m_Class->getJavaClass();
jclass clazz = NULL;
if (!m_IsAbstract)
clazz = m_Class->getJavaClass();
return retType->invoke(frame, c, clazz, m_MethodID, &v[0]);
}
JP_TRACE_OUT;
No changes.
5 native/common/jp_shorttype.cpp 100755 → 100644
@@ -150,7 +150,10 @@ JPPyObject JPShortType::invoke(JPJavaFrame& frame, jobject obj, jclass clazz, jm
jvalue v;
{
JPPyCallRelease call;
field(v) = frame.CallNonvirtualShortMethodA(obj, clazz, mth, val);
if (clazz == NULL)
field(v) = frame.CallShortMethodA(obj, mth, val);
else
field(v) = frame.CallNonvirtualShortMethodA(obj, clazz, mth, val);
}
return convertToPythonObject(v);
}
@@ -65,11 +65,14 @@ JPPyObject JPVoidType::invokeStatic(JPJavaFrame& frame, jclass claz, jmethodID m
return JPPyObject::getNone();
}

JPPyObject JPVoidType::invoke(JPJavaFrame& frame, jobject claz, jclass clazz, jmethodID mth, jvalue* val)
JPPyObject JPVoidType::invoke(JPJavaFrame& frame, jobject obj, jclass clazz, jmethodID mth, jvalue* val)
{
{
JPPyCallRelease call;
frame.CallVoidMethodA(claz, mth, val);
if (clazz == NULL)
frame.CallVoidMethodA(obj, mth, val);
else
frame.CallNonvirtualVoidMethodA(obj, clazz, mth, val);
}
return JPPyObject::getNone();
}
0 native/python/jp_pythontypes.cpp 100755 → 100644
No changes.
@@ -145,7 +145,6 @@ PyObject* PyJPMethod::__call__(PyJPMethod* self, PyObject* args, PyObject* kwarg

void PyJPMethod::__dealloc__(PyJPMethod* self)
{
JP_TRACE_IN("PyJPMethod::__dealloc__");
if (self->m_Instance != NULL)
{
JP_TRACE_PY("method dealloc (dec)", self->m_Instance);
@@ -154,7 +153,6 @@ void PyJPMethod::__dealloc__(PyJPMethod* self)
self->m_Instance = NULL;
self->m_Method = NULL;
Py_TYPE(self)->tp_free(self);
JP_TRACE_OUT;
}

PyObject* PyJPMethod::__str__(PyJPMethod* self)
@@ -30,6 +30,7 @@ dist.javadoc.dir=${dist.dir}/javadoc
endorsed.classpath=
excludes=
file.reference.native-java=../../native/java
file.reference.test-harness=../../test/harness
includes=**
jar.compress=false
javac.classpath=
@@ -39,8 +40,8 @@ javac.deprecation=false
javac.external.vm=true
javac.processorpath=\
${javac.classpath}
javac.source=1.7
javac.target=1.7
javac.source=1.8
javac.target=1.8
javac.test.classpath=\
${javac.classpath}:\
${build.classes.dir}
@@ -72,4 +73,5 @@ run.test.classpath=\
${build.test.classes.dir}
source.encoding=UTF-8
src.java.dir=${file.reference.native-java}
test.harness.dir=${file.reference.test-harness}
test.src.dir=test
@@ -8,6 +8,7 @@
<root id="src.java.dir" name="Source Packages"/>
</source-roots>
<test-roots>
<root id="test.harness.dir" name="Harness Packages"/>
<root id="test.src.dir"/>
</test-roots>
</data>

0 comments on commit 71cb9c4

Please sign in to comment.
You can’t perform that action at this time.