From: <cg...@us...> - 2007-10-08 06:56:51
|
Revision: 3582 http://jython.svn.sourceforge.net/jython/?rev=3582&view=rev Author: cgroves Date: 2007-10-07 23:56:46 -0700 (Sun, 07 Oct 2007) Log Message: ----------- Allow methods to be exposed under more than one name in the dict. Since this is yet another difference between exposed types and methods, go ahead and break the annotation out into ExposedMethod and ExposedType though I don't particular care for those names. Modified Paths: -------------- branches/exposed_annotation/src/org/python/core/PyNone.java branches/exposed_annotation/src/org/python/core/PyString.java branches/exposed_annotation/src/org/python/core/PyType.java branches/exposed_annotation/src/org/python/expose/MethodExposer.java branches/exposed_annotation/src/org/python/expose/TypeExposer.java branches/exposed_annotation/tests/java/org/python/expose/MethodExposerTest.java branches/exposed_annotation/tests/java/org/python/expose/SimpleExposed.java branches/exposed_annotation/tests/java/org/python/expose/TypeExposerTest.java Added Paths: ----------- branches/exposed_annotation/src/org/python/expose/ExposedMethod.java branches/exposed_annotation/src/org/python/expose/ExposedType.java Removed Paths: ------------- branches/exposed_annotation/src/org/python/expose/Exposed.java Modified: branches/exposed_annotation/src/org/python/core/PyNone.java =================================================================== --- branches/exposed_annotation/src/org/python/core/PyNone.java 2007-10-08 06:01:12 UTC (rev 3581) +++ branches/exposed_annotation/src/org/python/core/PyNone.java 2007-10-08 06:56:46 UTC (rev 3582) @@ -3,12 +3,12 @@ import java.io.Serializable; -import org.python.expose.Exposed; +import org.python.expose.ExposedType; /** * A class representing the singleton None object, */ -@Exposed(name="NoneType") +@ExposedType(name="NoneType") public class PyNone extends PyObject implements Serializable { @@ -26,7 +26,7 @@ return NoneType___nonzero__(); } - @Exposed + @ExposedType final boolean NoneType___nonzero__() { return false; } @@ -44,7 +44,7 @@ return NoneType_toString(); } - @Exposed(name="__repr__") + @ExposedType(name="__repr__") final String NoneType_toString() { return "None"; } Modified: branches/exposed_annotation/src/org/python/core/PyString.java =================================================================== --- branches/exposed_annotation/src/org/python/core/PyString.java 2007-10-08 06:01:12 UTC (rev 3581) +++ branches/exposed_annotation/src/org/python/core/PyString.java 2007-10-08 06:56:46 UTC (rev 3582) @@ -1,7 +1,7 @@ /// Copyright (c) Corporation for National Research Initiatives package org.python.core; -import org.python.expose.Exposed; +import org.python.expose.ExposedMethod; /** * A builtin python string. @@ -2780,7 +2780,7 @@ return str_count(sub, start, end); } - @Exposed(defaults={"Py.ZERO", "str___len__"}) + @ExposedMethod(defaults={"Py.ZERO", "str___len__"}) final int str_count(String sub, int start, int end) { int[] indices = translateIndices(start, end); int n = sub.length(); Modified: branches/exposed_annotation/src/org/python/core/PyType.java =================================================================== --- branches/exposed_annotation/src/org/python/core/PyType.java 2007-10-08 06:01:12 UTC (rev 3581) +++ branches/exposed_annotation/src/org/python/core/PyType.java 2007-10-08 06:56:46 UTC (rev 3582) @@ -10,7 +10,7 @@ import java.util.Iterator; import java.util.List; -import org.python.expose.Exposed; +import org.python.expose.ExposedType; import org.python.expose.TypeBuilder; import org.python.expose.TypeExposer; @@ -1179,7 +1179,7 @@ String name = null; String[] exposed_methods = null; TypeBuilder tb = null; - if(c.getAnnotation(Exposed.class) != null) { + if(c.getAnnotation(ExposedType.class) != null) { tb = new TypeExposer(c).makeBuilder(); name = tb.getName(); base = PyObject.class; Deleted: branches/exposed_annotation/src/org/python/expose/Exposed.java =================================================================== --- branches/exposed_annotation/src/org/python/expose/Exposed.java 2007-10-08 06:01:12 UTC (rev 3581) +++ branches/exposed_annotation/src/org/python/expose/Exposed.java 2007-10-08 06:56:46 UTC (rev 3582) @@ -1,25 +0,0 @@ -package org.python.expose; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * Indicates a given method or class should be made visible to Python code. - */ -@Retention(RetentionPolicy.RUNTIME) -public @interface Exposed { - - /** - * @return the name to expose this item as. Defaults to the actual name of - * the item. - */ - String name() default ""; - - /** - * @return default arguments for a method. Starts at the number of arguments - - * defaults.length - */ - String[] defaults() default {}; - - MethodType type() default MethodType.NORMAL; -} Added: branches/exposed_annotation/src/org/python/expose/ExposedMethod.java =================================================================== --- branches/exposed_annotation/src/org/python/expose/ExposedMethod.java (rev 0) +++ branches/exposed_annotation/src/org/python/expose/ExposedMethod.java 2007-10-08 06:56:46 UTC (rev 3582) @@ -0,0 +1,30 @@ +package org.python.expose; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Indicates a method should be exposed to Python code. + * + */ +@Retention(RetentionPolicy.RUNTIME) +public @interface ExposedMethod { + + /** + * @return the names to expose this method as. Defaults to just actual name + * of the method. + */ + String[] names() default {}; + + /** + * @return default arguments. Starts at the number of arguments - + * defaults.length + */ + String[] defaults() default {}; + + /** + * @return - how to expose this method. See {@link MethodType} for the + * options. + */ + MethodType type() default MethodType.NORMAL; +} Copied: branches/exposed_annotation/src/org/python/expose/ExposedType.java (from rev 3581, branches/exposed_annotation/src/org/python/expose/Exposed.java) =================================================================== --- branches/exposed_annotation/src/org/python/expose/ExposedType.java (rev 0) +++ branches/exposed_annotation/src/org/python/expose/ExposedType.java 2007-10-08 06:56:46 UTC (rev 3582) @@ -0,0 +1,18 @@ +package org.python.expose; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Indicates a given class should be made visible to Python code as a builtin + * type. + */ +@Retention(RetentionPolicy.RUNTIME) +public @interface ExposedType { + + /** + * @return the name to expose this item as. Defaults to the actual name of + * the class. + */ + String name() default ""; +} Modified: branches/exposed_annotation/src/org/python/expose/MethodExposer.java =================================================================== --- branches/exposed_annotation/src/org/python/expose/MethodExposer.java 2007-10-08 06:01:12 UTC (rev 3581) +++ branches/exposed_annotation/src/org/python/expose/MethodExposer.java 2007-10-08 06:56:46 UTC (rev 3582) @@ -7,8 +7,8 @@ import org.python.core.PyBuiltinMethodNarrow; /** - * Generates a class to call a given method with the {@link Exposed} annotation - * as a method on a builtin Python type. + * Generates a class to call a given method with the {@link ExposedMethod} + * annotation as a method on a builtin Python type. */ public class MethodExposer extends Exposer { @@ -16,9 +16,10 @@ super(PyBuiltinMethodNarrow.class, method.getDeclaringClass().getName() + "$exposed_" + method.getName()); this.method = method; - exp = method.getAnnotation(Exposed.class); + exp = method.getAnnotation(ExposedMethod.class); if(exp == null) { - throw new IllegalArgumentException(method + " doesn't have the @Exposed annotation"); + throw new IllegalArgumentException(method + + " doesn't have the @ExposedMethod annotation"); } } @@ -36,20 +37,20 @@ return method.getDeclaringClass(); } - public String getName() { - String name = exp.name(); - if(name.equals("")) { - name = method.getName(); + public String[] getNames() { + String[] names = exp.names(); + if(names.length == 0) { + String name = method.getName(); if(name.startsWith(prefix)) { - return name.substring(prefix.length()); + name = name.substring(prefix.length()); } - return name; + return new String[] {name}; } - return name; + return names; } protected void generate() { - generateNoArgConstructor(); + generateNamedConstructor(); generateFullConstructor(); generateBind(); generateCall(); @@ -64,10 +65,10 @@ endConstructor(); } - private void generateNoArgConstructor() { - startConstructor(); + private void generateNamedConstructor() { + startConstructor(STRING); mv.visitVarInsn(ALOAD, 0); - mv.visitLdcInsn(getName()); + mv.visitVarInsn(ALOAD, 1); mv.visitLdcInsn(method.getParameterTypes().length + 1); mv.visitLdcInsn(method.getParameterTypes().length + 1); superConstructor(STRING, INT, INT); @@ -129,7 +130,7 @@ endMethod(); } - private Exposed exp; + private ExposedMethod exp; private Method method; Modified: branches/exposed_annotation/src/org/python/expose/TypeExposer.java =================================================================== --- branches/exposed_annotation/src/org/python/expose/TypeExposer.java 2007-10-08 06:01:12 UTC (rev 3581) +++ branches/exposed_annotation/src/org/python/expose/TypeExposer.java 2007-10-08 06:56:46 UTC (rev 3582) @@ -13,14 +13,14 @@ /** * Generates a subclass of TypeBuilder to expose a class with the - * {@link Exposed} annotation as a builtin Python type. + * {@link ExposedType} annotation as a builtin Python type. */ public class TypeExposer extends Exposer { public TypeExposer(Class<?> cls) { super(BaseTypeBuilder.class, getExposedName(cls)); this.cls = cls; - exp = cls.getAnnotation(Exposed.class); + exp = cls.getAnnotation(ExposedType.class); if(exp == null) { throw new IllegalArgumentException(cls + " doesn't have the @Exposed annotation"); } @@ -55,7 +55,7 @@ public List<Method> findMethods() { List<Method> exposedMethods = new ArrayList<Method>(); for(Method m : cls.getMethods()) { - if(m.getAnnotation(Exposed.class) != null) { + if(m.getAnnotation(ExposedMethod.class) != null) { exposedMethods.add(m); } } @@ -76,17 +76,27 @@ mv.visitLdcInsn(getName()); mv.visitLdcInsn(Type.getType(cls)); List<Method> methods = findMethods(); - mv.visitLdcInsn(methods.size()); + List<MethodExposer> exposers = new ArrayList<MethodExposer>(methods.size()); + int numNames = 0; + for(Method method : methods) { + MethodExposer me = new MethodExposer(method, getName() + "_"); + exposers.add(me); + numNames += me.getNames().length; + } + mv.visitLdcInsn(numNames); mv.visitTypeInsn(ANEWARRAY, BUILTIN_FUNCTION.getInternalName()); mv.visitVarInsn(ASTORE, 1); - for(int i = 0; i < methods.size(); i++) { - mv.visitVarInsn(ALOAD, 1); - MethodExposer me = new MethodExposer(methods.get(i)); - mv.visitLdcInsn(i); - mv.visitTypeInsn(NEW, me.getInternalName()); - mv.visitInsn(DUP); - callConstructor(me.getGeneratedType()); - mv.visitInsn(AASTORE); + int i = 0; + for(MethodExposer exposer : exposers) { + for(int j = 0; j < exposer.getNames().length; j++) { + mv.visitVarInsn(ALOAD, 1); + mv.visitLdcInsn(i++); + mv.visitTypeInsn(NEW, exposer.getInternalName()); + mv.visitInsn(DUP); + mv.visitLdcInsn(exposer.getNames()[j]); + callConstructor(exposer.getGeneratedType(), STRING); + mv.visitInsn(AASTORE); + } } mv.visitVarInsn(ALOAD, 1); superConstructor(STRING, CLASS, ABUILTIN_FUNCTION); @@ -125,7 +135,7 @@ private String name; } - private Exposed exp; + private ExposedType exp; private Class cls; } Modified: branches/exposed_annotation/tests/java/org/python/expose/MethodExposerTest.java =================================================================== --- branches/exposed_annotation/tests/java/org/python/expose/MethodExposerTest.java 2007-10-08 06:01:12 UTC (rev 3581) +++ branches/exposed_annotation/tests/java/org/python/expose/MethodExposerTest.java 2007-10-08 06:56:46 UTC (rev 3582) @@ -18,18 +18,21 @@ public PyBuiltinFunction createBound(MethodExposer me) throws Exception { Class descriptor = me.load(new BytecodeLoader.Loader()); - PyBuiltinMethod instance = (PyBuiltinMethod)descriptor.newInstance(); - return instance.bind(new SimpleExposed()); + return instantiate(descriptor, me.getNames()[0]).bind(new SimpleExposed()); } + + public PyBuiltinFunction instantiate(Class descriptor, String name) throws Exception { + return (PyBuiltinFunction)descriptor.getConstructor(String.class).newInstance(name); + } public void testSimpleMethod() throws Exception { MethodExposer mp = new MethodExposer(SimpleExposed.class.getMethod("simple_method")); - assertEquals("simple_method", mp.getName()); + assertEquals("simple_method", mp.getNames()[0]); assertEquals(SimpleExposed.class, mp.getMethodClass()); assertEquals("org/python/expose/SimpleExposed$exposed_simple_method", mp.getInternalName()); assertEquals("org.python.expose.SimpleExposed$exposed_simple_method", mp.getClassName()); Class descriptor = mp.load(new BytecodeLoader.Loader()); - PyBuiltinMethod instance = (PyBuiltinMethod)descriptor.newInstance(); + PyBuiltinFunction instance = instantiate(descriptor, "simple_method"); assertSame("simple_method", instance.__getattr__("__name__").toString()); SimpleExposed simpleExposed = new SimpleExposed(); PyBuiltinFunction bound = instance.bind(simpleExposed); @@ -41,7 +44,7 @@ public void testPrefixing() throws Exception { MethodExposer mp = new MethodExposer(SimpleExposed.class.getMethod("simpleexposed_prefixed"), "simpleexposed_"); - assertEquals("prefixed", mp.getName()); + assertEquals("prefixed", mp.getNames()[0]); } public void testStringReturn() throws Exception { Modified: branches/exposed_annotation/tests/java/org/python/expose/SimpleExposed.java =================================================================== --- branches/exposed_annotation/tests/java/org/python/expose/SimpleExposed.java 2007-10-08 06:01:12 UTC (rev 3581) +++ branches/exposed_annotation/tests/java/org/python/expose/SimpleExposed.java 2007-10-08 06:56:46 UTC (rev 3582) @@ -3,43 +3,43 @@ import org.python.core.Py; import org.python.core.PyObject; -@Exposed(name = "simpleexposed") +@ExposedType(name = "simpleexposed") public class SimpleExposed extends PyObject { public void method() {} public int timesCalled; - @Exposed + @ExposedMethod public void simple_method() { timesCalled++; } - @Exposed + @ExposedMethod public void simpleexposed_prefixed() {} - @Exposed + @ExposedMethod public boolean __nonzero__() { return false; } - @Exposed(name = "__repr__") + @ExposedMethod(names = {"__repr__", "__str__"}) public String toString() { return TO_STRING_RETURN; } - - @Exposed + + @ExposedMethod public void takesArgument(PyObject arg) { assert arg == Py.None; } - - @Exposed(type=MethodType.BINARY) + + @ExposedMethod(type = MethodType.BINARY) public PyObject __add__(PyObject arg) { if(arg == Py.False) { return Py.One; } return null; } - + public static final String TO_STRING_RETURN = "A simple test class"; } \ No newline at end of file Modified: branches/exposed_annotation/tests/java/org/python/expose/TypeExposerTest.java =================================================================== --- branches/exposed_annotation/tests/java/org/python/expose/TypeExposerTest.java 2007-10-08 06:01:12 UTC (rev 3581) +++ branches/exposed_annotation/tests/java/org/python/expose/TypeExposerTest.java 2007-10-08 06:56:46 UTC (rev 3582) @@ -26,8 +26,7 @@ public void testGetName() { assertEquals("simpleexposed", new TypeExposer(SimpleExposed.class).getName()); - assertEquals("somethingcompletelydifferent", - new TypeExposer(Rename.class).getName()); + assertEquals("somethingcompletelydifferent", new TypeExposer(Rename.class).getName()); } public void testNoExposed() { @@ -43,10 +42,12 @@ assertEquals(SimpleExposed.class, t.getTypeClass()); assertNotNull(t.getDict().__finditem__("simple_method")); assertNotNull(t.getDict().__finditem__("prefixed")); + assertNotNull(t.getDict().__finditem__("__str__")); + assertNotNull(t.getDict().__finditem__("__repr__")); } public class Unexposed {} - @Exposed(name = "somethingcompletelydifferent") + @ExposedType(name = "somethingcompletelydifferent") public class Rename {} } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |