[Jython-checkins] jython: Sort all methods in PyJavaType in the right order. See #2391
darjus.loktevic
jython-checkins at python.org
Wed Jan 13 00:57:21 EST 2016
https://hg.python.org/jython/rev/ac294f546003
changeset: 7873:ac294f546003
user: Jaime Saiz <jsaiz at sciops.esa.int>
date: Wed Jan 13 16:55:29 2016 +1100
summary:
Sort all methods in PyJavaType in the right order. See #2391
files:
ACKNOWLEDGMENTS | 1 +
src/org/python/core/PyJavaType.java | 79 ++++++++++
tests/java/javatests/DoubleHolder.java | 17 ++
tests/java/javatests/Issue2391AttrOrderTest.java | 20 ++
tests/java/javatests/NumberHolder.java | 7 +
5 files changed, 124 insertions(+), 0 deletions(-)
diff --git a/ACKNOWLEDGMENTS b/ACKNOWLEDGMENTS
--- a/ACKNOWLEDGMENTS
+++ b/ACKNOWLEDGMENTS
@@ -172,6 +172,7 @@
Eli Oxman
Robert Patrick
Kevin Edwards
+ Jaime Saiz
Local Variables:
mode: indented-text
diff --git a/src/org/python/core/PyJavaType.java b/src/org/python/core/PyJavaType.java
--- a/src/org/python/core/PyJavaType.java
+++ b/src/org/python/core/PyJavaType.java
@@ -15,8 +15,10 @@
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.Comparator;
import java.util.Enumeration;
import java.util.EventListener;
import java.util.HashMap;
@@ -26,6 +28,7 @@
import java.util.Map;
import java.util.Queue;
import java.util.Set;
+import java.util.Stack;
import org.python.core.util.StringUtil;
import org.python.util.Generic;
@@ -297,6 +300,9 @@
methods = allMethods.toArray(new Method[allMethods.size()]);
}
+ /* make sure we "sort" all methods so they resolve in the right order. See #2391 for details */
+ Arrays.sort(methods, new MethodComparator(new ClassComparator()));
+
boolean isInAwt = name.startsWith("java.awt.") && name.indexOf('.', 9) == -1;
for (Method meth : methods) {
if (!declaredOnMember(baseClass, meth) || ignore(meth)) {
@@ -996,6 +1002,79 @@
return Collections.unmodifiableMap(postProxies);
}
+ private class ClassComparator implements Comparator<Class<?>> {
+
+ public int compare(Class<?> c1, Class<?> c2) {
+ if (c1.equals(c2)) {
+ return 0;
+ } else if (c1.isAssignableFrom(c2)) {
+ return -1;
+ } else if (c2.isAssignableFrom(c1)) {
+ return 1;
+ }
+
+ String s1 = hierarchyName(c1);
+ String s2 = hierarchyName(c2);
+ return s1.compareTo(s2);
+ }
+
+ private String hierarchyName(Class<?> c) {
+ Stack<String> nameStack = new Stack<String>();
+ StringBuilder namesBuilder = new StringBuilder();
+ do {
+ nameStack.push(c.getSimpleName());
+ c = c.getSuperclass();
+ } while (c != null);
+
+ for (String name: nameStack) {
+ namesBuilder.append(name);
+ }
+
+ return namesBuilder.toString();
+ }
+ }
+
+ private class MethodComparator implements Comparator<Method> {
+
+ private ClassComparator classComparator;
+
+ public MethodComparator(ClassComparator classComparator) {
+ this.classComparator = classComparator;
+ }
+
+ public int compare(Method m1, Method m2) {
+ int result = m1.getName().compareTo(m2.getName());
+
+ if (result != 0) {
+ return result;
+ }
+
+ Class<?>[] p1 = m1.getParameterTypes();
+ Class<?>[] p2 = m2.getParameterTypes();
+
+ int n1 = p1.length;
+ int n2 = p2.length;
+
+ result = n1 - n2;
+
+ if (result != 0) {
+ return result;
+ }
+
+ result = classComparator.compare(m1.getDeclaringClass(), m2.getDeclaringClass());
+
+ if (result != 0) {
+ return result;
+ }
+
+ if (n1 == 0) {
+ return classComparator.compare(m1.getReturnType(), m2.getReturnType());
+ } else if (n1 == 1) {
+ return classComparator.compare(p1[0], p2[0]);
+ }
+ return result;
+ }
+ }
/* Traverseproc implementation */
@Override
diff --git a/tests/java/javatests/DoubleHolder.java b/tests/java/javatests/DoubleHolder.java
new file mode 100644
--- /dev/null
+++ b/tests/java/javatests/DoubleHolder.java
@@ -0,0 +1,17 @@
+package javatests;
+
+/* Part of Issue2391 test */
+
+public class DoubleHolder implements NumberHolder {
+
+ private Double number = 0.0;
+
+ @Override
+ public Double getNumber() {
+ return number;
+ }
+
+ public void setNumber(Double number) {
+ this.number = number;
+ }
+}
diff --git a/tests/java/javatests/Issue2391AttrOrderTest.java b/tests/java/javatests/Issue2391AttrOrderTest.java
new file mode 100644
--- /dev/null
+++ b/tests/java/javatests/Issue2391AttrOrderTest.java
@@ -0,0 +1,20 @@
+package javatests;
+
+
+import org.junit.Test;
+import org.python.util.PythonInterpreter;
+
+import static org.junit.Assert.assertEquals;
+
+public class Issue2391AttrOrderTest {
+
+ @Test
+ public void testAttribute() {
+ PythonInterpreter interpreter = new PythonInterpreter();
+ interpreter.exec("from " + getClass().getPackage().getName() + " import DoubleHolder");
+ interpreter.exec("d = DoubleHolder()");
+ assertEquals("0.0", interpreter.eval("d.number").toString());
+ interpreter.exec("d.number = 3.0");
+ assertEquals("3.0", interpreter.eval("d.number").toString());
+ }
+}
diff --git a/tests/java/javatests/NumberHolder.java b/tests/java/javatests/NumberHolder.java
new file mode 100644
--- /dev/null
+++ b/tests/java/javatests/NumberHolder.java
@@ -0,0 +1,7 @@
+package javatests;
+
+/* Part of Issue2391 test */
+
+public interface NumberHolder {
+ Number getNumber();
+}
--
Repository URL: https://hg.python.org/jython
More information about the Jython-checkins
mailing list