diff options
7 files changed, 145 insertions, 34 deletions
diff --git a/luni/src/main/java/java/lang/reflect/AccessibleObject.java b/luni/src/main/java/java/lang/reflect/AccessibleObject.java index 83763a2..6803a46 100644 --- a/luni/src/main/java/java/lang/reflect/AccessibleObject.java +++ b/luni/src/main/java/java/lang/reflect/AccessibleObject.java @@ -245,10 +245,10 @@ public class AccessibleObject implements AnnotatedElement { StringBuilder result = new StringBuilder(); if (types.length != 0) { - result.append(types[0].getCanonicalName()); + result.append(types[0].getName()); for (int i = 1; i < types.length; i++) { result.append(','); - result.append(types[i].getCanonicalName()); + result.append(types[i].getName()); } } @@ -348,26 +348,6 @@ public class AccessibleObject implements AnnotatedElement { * * @throws NullPointerException if any of the arguments is null */ - void appendArrayType(StringBuilder sb, Class[] objs) { - if (objs.length > 0) { - appendArrayType(sb, objs[0]); - for (int i = 1; i < objs.length; i++) { - sb.append(','); - appendArrayType(sb, objs[i]); - } - } - } - - /** - * Appends names of the specified array classes to the buffer. The array - * elements may represent a simple type, a reference type or an array type. - * Output format: java.lang.Object[], java.io.File, void - * - * @param sb buffer - * @param objs array of classes to print the names - * - * @throws NullPointerException if any of the arguments is null - */ void appendArrayGenericType(StringBuilder sb, Type[] objs) { if (objs.length > 0) { appendGenericType(sb, objs[0]); diff --git a/luni/src/main/java/java/lang/reflect/Constructor.java b/luni/src/main/java/java/lang/reflect/Constructor.java index f511687..2a29822 100644 --- a/luni/src/main/java/java/lang/reflect/Constructor.java +++ b/luni/src/main/java/java/lang/reflect/Constructor.java @@ -144,7 +144,7 @@ public final class Constructor<T> extends AccessibleObject implements GenericDec for (int i = 0; i < formalTypeParameters.length; i++) { appendGenericType(sb, formalTypeParameters[i]); if (i < formalTypeParameters.length - 1) { - sb.append(", "); + sb.append(","); } } sb.append("> "); diff --git a/luni/src/main/java/java/lang/reflect/Field.java b/luni/src/main/java/java/lang/reflect/Field.java index d7898b9..1d2726c 100644 --- a/luni/src/main/java/java/lang/reflect/Field.java +++ b/luni/src/main/java/java/lang/reflect/Field.java @@ -32,7 +32,6 @@ package java.lang.reflect; -import dalvik.system.VMStack; import java.lang.annotation.Annotation; import org.apache.harmony.kernel.vm.StringUtils; import org.apache.harmony.luni.lang.reflect.GenericSignatureParser; @@ -838,7 +837,7 @@ public final class Field extends AccessibleObject implements Member { if (result.length() != 0) { result.append(' '); } - result.append(type.getName()); + appendArrayType(result, type); result.append(' '); result.append(declaringClass.getName()); result.append('.'); diff --git a/luni/src/main/java/java/lang/reflect/Method.java b/luni/src/main/java/java/lang/reflect/Method.java index 68fe219..2e2c03f 100644 --- a/luni/src/main/java/java/lang/reflect/Method.java +++ b/luni/src/main/java/java/lang/reflect/Method.java @@ -175,7 +175,7 @@ public final class Method extends AccessibleObject implements GenericDeclaration for (int i = 0; i < formalTypeParameters.length; i++) { appendGenericType(sb, formalTypeParameters[i]); if (i < formalTypeParameters.length - 1) { - sb.append(", "); + sb.append(","); } } sb.append("> "); @@ -185,7 +185,7 @@ public final class Method extends AccessibleObject implements GenericDeclaration sb.append(' '); // append method name appendArrayType(sb, getDeclaringClass()); - sb.append("."+getName()); + sb.append(".").append(getName()); // append parameters sb.append('('); appendArrayGenericType(sb, diff --git a/luni/src/main/java/java/lang/reflect/WildcardType.java b/luni/src/main/java/java/lang/reflect/WildcardType.java index affd526..31e1023 100644 --- a/luni/src/main/java/java/lang/reflect/WildcardType.java +++ b/luni/src/main/java/java/lang/reflect/WildcardType.java @@ -18,12 +18,21 @@ package java.lang.reflect; /** - * This interface represents a wildcard type, such as the simple wildcard - * {@code '?'}, the upper bounded wildcard {@code '? extends Closeable'}, the - * multiple upper bounded wildcard {@code '? extends Closeable & Flushable'} or - * the lower bounded wildcard {@code '? super OutputStream'}. + * A pattern type, such as the upper bounded wildcard {@code + * ? extends Closeable} or the lower bounded wildcard {@code ? super String}. * - * @since 1.5 + * <p>Although this interface permits an arbitrary number of upper and lower + * bounds, all wildcard types of Java language programs are in one of two forms: + * <ol> + * <li><strong>No lower bound and one upper bound.</strong> Such types are + * written like {@code ? extends java.lang.Number}. When the upper bound is + * {@code java.lang.Object}, the {@code extends java.lang.Object} suffix is + * optional: {@code Set<?>} is shorthand for {@code + * Set<? extends java.lang.Object>}. + * <li><strong>One lower bound and an upper bound of {@code + * java.lang.Object}.</strong> Such types are written like {@code + * ? super java.lang.String}. + * </ol> */ public interface WildcardType extends Type { /** diff --git a/luni/src/main/java/org/apache/harmony/luni/lang/reflect/ImplForWildcard.java b/luni/src/main/java/org/apache/harmony/luni/lang/reflect/ImplForWildcard.java index 3d60a0e..b0605f2 100644 --- a/luni/src/main/java/org/apache/harmony/luni/lang/reflect/ImplForWildcard.java +++ b/luni/src/main/java/org/apache/harmony/luni/lang/reflect/ImplForWildcard.java @@ -59,7 +59,8 @@ public final class ImplForWildcard implements WildcardType { @Override public String toString() { StringBuilder sb = new StringBuilder("?"); - if (extendsBound.length() > 0) { + if ((extendsBound.length() == 1 && extendsBound.getResolvedTypes()[0] != Object.class) + || extendsBound.length() > 1) { sb.append(" extends ").append(extendsBound); } else if (superBound.length() > 0) { sb.append(" super ").append(superBound); diff --git a/luni/src/test/java/libcore/java/lang/reflect/ReflectionTest.java b/luni/src/test/java/libcore/java/lang/reflect/ReflectionTest.java index 19092c5..80c76e6 100644 --- a/luni/src/test/java/libcore/java/lang/reflect/ReflectionTest.java +++ b/luni/src/test/java/libcore/java/lang/reflect/ReflectionTest.java @@ -16,19 +16,141 @@ package libcore.java.lang.reflect; +import java.io.Serializable; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.RandomAccess; +import java.util.Set; import junit.framework.TestCase; public final class ReflectionTest extends TestCase { + String classA = "libcore.java.lang.reflect.ReflectionTest$A"; + String classB = "libcore.java.lang.reflect.ReflectionTest$B"; + String classC = "libcore.java.lang.reflect.ReflectionTest$C"; + /** * http://code.google.com/p/android/issues/detail?id=6636 */ public void testGenericSuperclassToString() throws Exception { - assertEquals("java.util.ArrayList<libcore.java.lang.reflect.ReflectionTest$A>", + assertEquals("java.util.ArrayList<" + classA + ">", AList.class.getGenericSuperclass().toString()); } + public void testFieldToString() throws Exception { + Field fieldOne = C.class.getDeclaredField("fieldOne"); + String fieldOneRaw = "public static " + classA + " " + classC + ".fieldOne"; + assertEquals(fieldOneRaw, fieldOne.toString()); + assertEquals(fieldOneRaw, fieldOne.toGenericString()); + + Field fieldTwo = C.class.getDeclaredField("fieldTwo"); + assertEquals("transient volatile java.util.Map " + classC + ".fieldTwo", + fieldTwo.toString()); + assertEquals("transient volatile java.util.Map<" + classA + ", java.lang.String> " + + classC + ".fieldTwo", fieldTwo.toGenericString()); + + Field fieldThree = C.class.getDeclaredField("fieldThree"); + String fieldThreeRaw = "java.lang.Object[] " + classC + ".fieldThree"; + assertEquals(fieldThreeRaw, fieldThree.toString()); + String fieldThreeGeneric = "K[] " + classC + ".fieldThree"; + assertEquals(fieldThreeGeneric, fieldThree.toGenericString()); + + Field fieldFour = C.class.getDeclaredField("fieldFour"); + String fieldFourRaw = "java.util.Map " + classC + ".fieldFour"; + assertEquals(fieldFourRaw, fieldFour.toString()); + String fieldFourGeneric = "java.util.Map<? super java.lang.Integer, java.lang.Integer[]> " + + classC + ".fieldFour"; + assertEquals(fieldFourGeneric, fieldFour.toGenericString()); + } + + public void testConstructorToString() throws Exception { + Constructor constructorOne = C.class.getDeclaredConstructor(A.class); + String constructorOneRaw = classC + "(" + classA + ") throws " + classB; + assertEquals(constructorOneRaw, constructorOne.toString()); + assertEquals(constructorOneRaw, constructorOne.toGenericString()); + + Constructor constructorTwo = C.class.getDeclaredConstructor(Map.class, Object.class); + String constructorTwoRaw = "protected " + classC + "(java.util.Map,java.lang.Object)"; + assertEquals(constructorTwoRaw, constructorTwo.toString()); + String constructorTwoGeneric = "protected <T1> " + classC + + "(java.util.Map<? super " + classA + ", T1>,K)"; + assertEquals(constructorTwoGeneric, constructorTwo.toGenericString()); + } + + public void testMethodToString() throws Exception { + Method methodOne = C.class.getDeclaredMethod("methodOne", A.class, C.class); + String methodOneRaw = "protected final synchronized " + classA + " " + + classC + ".methodOne(" + classA + "," + classC + ") throws " + classB; + assertEquals(methodOneRaw, methodOne.toString()); + assertEquals(methodOneRaw, methodOne.toGenericString()); + + Method methodTwo = C.class.getDeclaredMethod("methodTwo", List.class); + String methodTwoRaw = "public abstract java.util.Map " + + classC + ".methodTwo(java.util.List)"; + assertEquals(methodTwoRaw, methodTwo.toString()); + String methodTwoGeneric = "public abstract java.util.Map<" + classA + ", java.lang.String> " + + classC + ".methodTwo(java.util.List<" + classA + ">)"; + assertEquals(methodTwoGeneric, methodTwo.toGenericString()); + + Method methodThree = C.class.getDeclaredMethod("methodThree", A.class, Set.class); + String methodThreeRaw = "private static java.util.Map " + + classC + ".methodThree(" + classA + ",java.util.Set)"; + assertEquals(methodThreeRaw, methodThree.toString()); + String methodThreeGeneric = "private static <T1,T2> java.util.Map<T1, ?> " + + classC + ".methodThree(T1,java.util.Set<? super T2>)"; + assertEquals(methodThreeGeneric, methodThree.toGenericString()); + + Method methodFour = C.class.getDeclaredMethod("methodFour", Set.class); + String methodFourRaw = "public java.lang.Comparable " + classC + ".methodFour(java.util.Set)"; + assertEquals(methodFourRaw, methodFour.toString()); + String methodFourGeneric = "public <T> T " + classC + ".methodFour(java.util.Set<T>)"; + assertEquals(methodFourGeneric, methodFour.toGenericString()); + } + + public void testTypeVariableWithMultipleBounds() throws Exception { + TypeVariable t = C.class.getDeclaredMethod("methodFour", Set.class).getTypeParameters()[0]; + assertEquals("T", t.toString()); + + Type[] bounds = t.getBounds(); + ParameterizedType comparableT = (ParameterizedType) bounds[0]; + assertEquals(Comparable.class, comparableT.getRawType()); + assertEquals("T", ((TypeVariable) comparableT.getActualTypeArguments()[0]).getName()); + assertEquals(3, bounds.length); + assertEquals(Serializable.class, bounds[1]); + assertEquals(RandomAccess.class, bounds[2]); + } + static class A {} static class AList extends ArrayList<A> {} + + static class B extends Exception {} + + public static abstract class C<K> { + public static A fieldOne; + transient volatile Map<A, String> fieldTwo; + K[] fieldThree; + Map<? super Integer, Integer[]> fieldFour; + + C(A a) throws B {} + protected <T1 extends A> C(Map<? super A, T1> a, K s) {} + + protected final synchronized A methodOne(A parameterOne, C parameterTwo) throws B { + return null; + } + public abstract Map<A, String> methodTwo(List<A> onlyParameter); + @Deprecated /** this annotation is used because it has runtime retention */ + private static <T1 extends A, T2> Map<T1, ?> methodThree(T1 t, Set<? super T2> t2s) { + return null; + } + public <T extends Comparable<T> & Serializable & RandomAccess> T methodFour(Set<T> t) { + return null; + } + } } |