From: <cg...@us...> - 2008-12-01 01:00:40
|
Revision: 5666 http://jython.svn.sourceforge.net/jython/?rev=5666&view=rev Author: cgroves Date: 2008-12-01 01:00:37 +0000 (Mon, 01 Dec 2008) Log Message: ----------- Replace fillDict with init which encapsulates all the differences between PyType and PyJavaType initialization. Have bootstrap types use init as well to remove the duplication of type builder initialization. Include interfaces and superclasses in the mro of wrapped Java types. Modified Paths: -------------- branches/newstyle-java-types/src/org/python/core/PyJavaType.java branches/newstyle-java-types/src/org/python/core/PyType.java Modified: branches/newstyle-java-types/src/org/python/core/PyJavaType.java =================================================================== --- branches/newstyle-java-types/src/org/python/core/PyJavaType.java 2008-12-01 00:38:14 UTC (rev 5665) +++ branches/newstyle-java-types/src/org/python/core/PyJavaType.java 2008-12-01 01:00:37 UTC (rev 5666) @@ -11,6 +11,8 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; + import org.python.core.util.StringUtil; import org.python.expose.ExposeAsSuperclass; import org.python.util.Generic; @@ -37,15 +39,56 @@ } @Override - protected void fillDict() { + protected void init() { + name = underlying_class.getName(); + // Strip the java fully qualified class name from Py classes in core + if (name.startsWith("org.python.core.Py")) { + name = name.substring("org.python.core.Py".length()).toLowerCase(); + } dict = new PyStringMap(); - Class<?> base = underlying_class.getSuperclass(); + Class<?> baseClass = underlying_class.getSuperclass(); + if (PyObject.class.isAssignableFrom(underlying_class)) { + // Non-exposed subclasses of PyObject use a simple linear mro to PyObject that ignores + // their interfaces + computeLinearMro(baseClass); + } else { + // Wrapped Java types fill in their mro first using their base class and then all of + // their interfaces. + if (baseClass == null) { + base = PyType.fromClass(PyObject.class); + } else { + base = PyType.fromClass(baseClass); + } + bases = new PyObject[1 + underlying_class.getInterfaces().length]; + bases[0] = base; + for (int i = 1; i < bases.length; i++) { + bases[i] = PyType.fromClass(underlying_class.getInterfaces()[i - 1]); + } + Set<PyObject> seen = Generic.set(); + List<PyObject> mros = Generic.list(); + mros.add(this); + for (PyObject obj : bases) { + for (PyObject mroObj : ((PyType)obj).mro) { + if (seen.add(mroObj)) { + mros.add(mroObj); + } + } + } + mro = mros.toArray(new PyObject[mros.size()]); + } + // PyReflected* can't call or access anything from non-public classes that aren't in + // org.python.core + if (!Modifier.isPublic(underlying_class.getModifiers()) && + !name.startsWith("org.python.core")) { + return; + } + // Add methods and determine bean properties declared on this class Map<String, PyBeanProperty> props = Generic.map(); Map<String, PyBeanEvent> events = Generic.map(); for (Method meth : underlying_class.getMethods()) { - if (!declaredOnMember(base, meth) || ignore(meth)) { + if (!declaredOnMember(baseClass, meth) || ignore(meth)) { continue; } String methname = meth.getName(); @@ -75,7 +118,7 @@ ename = ename.substring(idot + 1); } ename = normalize(StringUtil.decapitalize(ename)); - events.put(ename, new PyBeanEvent(name, eventClass, meth)); + events.put(ename, new PyBeanEvent(ename, eventClass, meth)); continue; } @@ -118,7 +161,7 @@ // Add fields declared on this type for (Field field : underlying_class.getFields()) { - if (!declaredOnMember(base, field)) { + if (!declaredOnMember(baseClass, field)) { continue; } String fldname = field.getName(); @@ -219,7 +262,7 @@ throw Py.JavaError(exc); } } - if (base != Object.class) { + if (baseClass != Object.class) { has_set = getDescrMethod(underlying_class, "__set__", OO) != null || getDescrMethod(underlying_class, "_doset", OO) != null; has_delete = getDescrMethod(underlying_class, "__delete__", PyObject.class) != null Modified: branches/newstyle-java-types/src/org/python/core/PyType.java =================================================================== --- branches/newstyle-java-types/src/org/python/core/PyType.java 2008-12-01 00:38:14 UTC (rev 5665) +++ branches/newstyle-java-types/src/org/python/core/PyType.java 2008-12-01 01:00:37 UTC (rev 5666) @@ -333,36 +333,55 @@ return newobj; } - protected void fillDict() { + /** + * Called on builtin types after underlying_class has been set on them. Should fill in dict, + * name, mro, base and bases from the class. + */ + protected void init() { + if (underlying_class == PyObject.class) { + mro = new PyType[] {this}; + } else { + Class<?> baseClass; + if (!Py.BOOTSTRAP_TYPES.contains(underlying_class)) { + baseClass = classToBuilder.get(underlying_class).getBase(); + } else { + baseClass = PyObject.class; + } + if (baseClass == Object.class) { + baseClass = underlying_class.getSuperclass(); + } + computeLinearMro(baseClass); + } if (Py.BOOTSTRAP_TYPES.contains(underlying_class)) { + // init will be called again from addBuilder which also removes underlying_class from + // BOOTSTRAP_TYPES return; } - dict = classToBuilder.get(underlying_class).getDict(this); + TypeBuilder builder = classToBuilder.get(underlying_class); + name = builder.getName(); + dict = builder.getDict(this); + setIsBaseType(builder.getIsBaseType()); instantiable = dict.__finditem__("__new__") != null; fillHasSetAndDelete(); } + /** + * Fills the base and bases of this type with the type of baseClass as sets its mro to this type + * followed by the mro of baseClass. + */ + protected void computeLinearMro(Class<?> baseClass) { + base = PyType.fromClass(baseClass); + mro = new PyType[base.mro.length + 1]; + System.arraycopy(base.mro, 0, mro, 1, base.mro.length); + mro[0] = this; + bases = new PyObject[] {base}; + } + private void fillHasSetAndDelete() { has_set = lookup("__set__") != null; has_delete = lookup("__delete__") != null; } - private static void fillInMRO(PyType type, Class<?> base) { - if (type.underlying_class == PyObject.class) { - type.mro = new PyType[] {type}; - return; - } - if (base == null) { - base = PyObject.class; - } - PyType baseType = fromClass(base); - type.mro = new PyType[baseType.mro.length + 1]; - System.arraycopy(baseType.mro, 0, type.mro, 1, baseType.mro.length); - type.mro[0] = type; - type.base = baseType; - type.bases = new PyObject[] {baseType}; - } - public PyObject getStatic() { PyType cur = this; while (cur.underlying_class == null) { @@ -951,16 +970,7 @@ } // The types in Py.BOOTSTRAP_TYPES are initialized before their builders are assigned, // so do the work of addFromClass & fillFromClass after the fact - PyType objType = fromClass(builder.getTypeClass()); - objType.name = builder.getName(); - objType.dict = builder.getDict(objType); - objType.setIsBaseType(builder.getIsBaseType()); - Class<?> base = builder.getBase(); - if (base == Object.class) { - base = forClass.getSuperclass(); - } - fillInMRO(objType, base); - objType.instantiable = objType.dict.__finditem__("__new__") != null; + fromClass(builder.getTypeClass()).init(); } } @@ -970,29 +980,14 @@ class_to_type.put(c, exposedAs); return exposedAs; } - Class<?> base = null; - boolean isBaseType = true; - String name = null; - TypeBuilder tb = getBuilder(c); - if (tb != null) { - name = tb.getName(); - isBaseType = tb.getIsBaseType(); - if (!tb.getBase().equals(Object.class)) { - base = tb.getBase(); - } - } - PyType type = class_to_type.get(c); - if (type == null) { - type = createType(c, base, name, isBaseType); - } - return type; + return createType(c); } private static TypeBuilder getBuilder(Class<?> c) { return classToBuilder == null ? null : classToBuilder.get(c); } - private static PyType createType(Class<?> c, Class<?> base, String name, boolean isBaseType) { + private static PyType createType(Class<?> c) { PyType newtype; if (c == PyType.class) { newtype = new PyType(false); @@ -1009,28 +1004,9 @@ } class_to_type.put(c, newtype); - if (base == null) { - base = c.getSuperclass(); - } newtype.underlying_class = c; - if (name == null) { - name = c.getName(); - // Strip the java fully qualified class name (specifically remove org.python.core.Py or - // fallback to stripping to the last dot) - if (name.startsWith("org.python.core.Py")) { - name = name.substring("org.python.core.Py".length()).toLowerCase(); - } else if(newtype.getProxyType() == null) { - int lastDot = name.lastIndexOf('.'); - if (lastDot != -1) { - name = name.substring(lastDot + 1); - } - } - } - newtype.name = name; newtype.builtin = true; - newtype.setIsBaseType(isBaseType); - fillInMRO(newtype, base); // basic mro, base, bases - newtype.fillDict(); + newtype.init(); return newtype; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |