diff options
author | Jeroen Frijters <jeroen@sumatra.nl> | 2005-09-30 09:12:01 +0000 |
---|---|---|
committer | Jeroen Frijters <jeroen@sumatra.nl> | 2005-09-30 09:12:01 +0000 |
commit | 67a508c431ce02998ed7a95274a5fa59ffc7307d (patch) | |
tree | 36365f57457ef2589e082be6ce388dfa1b3a55d1 | |
parent | a82dcadc3a145ec55585e78b78fc3d031fa4753c (diff) | |
download | classpath-67a508c431ce02998ed7a95274a5fa59ffc7307d.tar.gz |
2005-09-30 Jeroen Frijters <jeroen@frijters.net>
* gnu/java/lang/reflect/FieldSignatureParser.java: New file.
* gnu/java/lang/reflect/ClassSignatureParser.java,
gnu/java/lang/reflect/GenericSignatureParser.java,
gnu/java/lang/reflect/MethodSignatureParser.java:
Finished implementation.
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | gnu/java/lang/reflect/ClassSignatureParser.java | 6 | ||||
-rw-r--r-- | gnu/java/lang/reflect/FieldSignatureParser.java | 103 | ||||
-rw-r--r-- | gnu/java/lang/reflect/GenericSignatureParser.java | 327 | ||||
-rw-r--r-- | gnu/java/lang/reflect/MethodSignatureParser.java | 17 |
5 files changed, 406 insertions, 55 deletions
@@ -1,3 +1,11 @@ +2005-09-30 Jeroen Frijters <jeroen@frijters.net> + + * gnu/java/lang/reflect/FieldSignatureParser.java: New file. + * gnu/java/lang/reflect/ClassSignatureParser.java, + gnu/java/lang/reflect/GenericSignatureParser.java, + gnu/java/lang/reflect/MethodSignatureParser.java: + Finished implementation. + 2005-09-28 Andrew John Hughes <gnu_andrew@member.fsf.org> * gnu/java/awt/peer/qt/QtGraphics.java: diff --git a/gnu/java/lang/reflect/ClassSignatureParser.java b/gnu/java/lang/reflect/ClassSignatureParser.java index d7ec3b476..31f28385f 100644 --- a/gnu/java/lang/reflect/ClassSignatureParser.java +++ b/gnu/java/lang/reflect/ClassSignatureParser.java @@ -1,4 +1,4 @@ -/* Class.java -- Representation of a Java class. +/* ClassSignatureParser.java Copyright (C) 2005 Free Software Foundation @@ -69,20 +69,24 @@ public class ClassSignatureParser extends GenericSignatureParser } interfaceTypes = new Type[interfaces.size()]; interfaces.toArray(interfaceTypes); + end(); } public TypeVariable[] getTypeParameters() { + TypeImpl.resolve(typeParameters); return typeParameters; } public Type getSuperclassType() { + superclassType = TypeImpl.resolve(superclassType); return superclassType; } public Type[] getInterfaceTypes() { + TypeImpl.resolve(interfaceTypes); return interfaceTypes; } } diff --git a/gnu/java/lang/reflect/FieldSignatureParser.java b/gnu/java/lang/reflect/FieldSignatureParser.java new file mode 100644 index 000000000..16622d33f --- /dev/null +++ b/gnu/java/lang/reflect/FieldSignatureParser.java @@ -0,0 +1,103 @@ +/* FieldSignatureParser.java + Copyright (C) 2005 + Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.lang.reflect; + +import java.lang.reflect.GenericSignatureFormatError; +import java.lang.reflect.Type; + +public final class FieldSignatureParser extends GenericSignatureParser +{ + private Type type; + + public FieldSignatureParser(Class container, String signature) + { + super(container, container.getClassLoader(), signature); + + switch (peekChar()) + { + case 'L': + case '[': + case 'T': + type = readFieldTypeSignature(); + break; + case 'Z': + consume('Z'); + type = boolean.class; + break; + case 'B': + consume('B'); + type = byte.class; + break; + case 'S': + consume('S'); + type = short.class; + break; + case 'C': + consume('C'); + type = char.class; + break; + case 'I': + consume('I'); + type = int.class; + break; + case 'F': + consume('F'); + type = float.class; + break; + case 'J': + consume('J'); + type = long.class; + break; + case 'D': + consume('D'); + type = double.class; + break; + default: + throw new GenericSignatureFormatError(); + } + + end(); + } + + public Type getFieldType() + { + type = TypeImpl.resolve(type); + return type; + } +} diff --git a/gnu/java/lang/reflect/GenericSignatureParser.java b/gnu/java/lang/reflect/GenericSignatureParser.java index 1ad5790a7..b3ee3662c 100644 --- a/gnu/java/lang/reflect/GenericSignatureParser.java +++ b/gnu/java/lang/reflect/GenericSignatureParser.java @@ -1,4 +1,4 @@ -/* Class.java -- Representation of a Java class. +/* GenericSignatureParser.java Copyright (C) 2005 Free Software Foundation @@ -40,16 +40,31 @@ package gnu.java.lang.reflect; import java.lang.reflect.*; import java.util.ArrayList; +import java.util.Arrays; -class TypeImpl implements Type +abstract class TypeImpl implements Type { - Type resolve() + abstract Type resolve(); + + static void resolve(Type[] types) { - return this; + for (int i = 0; i < types.length; i++) + { + types[i] = resolve(types[i]); + } + } + + static Type resolve(Type type) + { + if (type instanceof TypeImpl) + { + type = ((TypeImpl) type).resolve(); + } + return type; } } -class TypeVariableImpl extends TypeImpl implements TypeVariable +final class TypeVariableImpl extends TypeImpl implements TypeVariable { private GenericDeclaration decl; private Type[] bounds; @@ -62,8 +77,14 @@ class TypeVariableImpl extends TypeImpl implements TypeVariable this.name = name; } + Type resolve() + { + return this; + } + public Type[] getBounds() { + resolve(bounds); return bounds.clone(); } @@ -77,31 +98,72 @@ class TypeVariableImpl extends TypeImpl implements TypeVariable return name; } - // TODO implement equals/hashCode + public boolean equals(Object obj) + { + if (obj instanceof TypeVariableImpl) + { + TypeVariableImpl other = (TypeVariableImpl)obj; + return decl.equals(other.decl) && name.equals(other.name); + } + return false; + } + + public int hashCode() + { + return 0x5f4d5156 ^ decl.hashCode() ^ name.hashCode(); + } + + public String toString() + { + return name; + } } -class ParameterizedTypeImpl extends TypeImpl implements ParameterizedType +final class ParameterizedTypeImpl extends TypeImpl implements ParameterizedType { - private Type rawType; + private String rawTypeName; + private ClassLoader loader; + private Class rawType; private Type owner; private Type[] typeArgs; - ParameterizedTypeImpl(Type rawType, Type owner, Type[] typeArgs) + ParameterizedTypeImpl(String rawTypeName, ClassLoader loader, Type owner, + Type[] typeArgs) { - this.rawType = rawType; + this.rawTypeName = rawTypeName; + this.loader = loader; this.owner = owner; this.typeArgs = typeArgs; } - public Type[] getActualTypeArguments() + Type resolve() { - for (int i = 0; i < typeArgs.length; i++) + if (rawType == null) + { + try + { + rawType = Class.forName(rawTypeName, false, loader); + } + catch (ClassNotFoundException x) + { + throw new TypeNotPresentException(rawTypeName, x); + } + } + if (typeArgs == null) { - if (typeArgs[i] instanceof TypeImpl) + if (owner == null) { - typeArgs[i] = ((TypeImpl)typeArgs[i]).resolve(); + return rawType; } + typeArgs = new Type[0]; } + resolve(typeArgs); + owner = resolve(owner); + return this; + } + + public Type[] getActualTypeArguments() + { return typeArgs.clone(); } @@ -115,10 +177,69 @@ class ParameterizedTypeImpl extends TypeImpl implements ParameterizedType return owner; } - // TODO implement equals/hashCode + public boolean equals(Object obj) + { + if (obj instanceof ParameterizedTypeImpl) + { + ParameterizedTypeImpl other = (ParameterizedTypeImpl)obj; + return rawType.equals(other.rawType) + && ((owner == null && other.owner == null) + || owner.equals(other.owner)) + && Arrays.deepEquals(typeArgs, other.typeArgs); + } + return false; + } + + public int hashCode() + { + int h = 0x58158970 ^ rawType.hashCode(); + if (owner != null) + { + h ^= Integer.reverse(owner.hashCode()); + } + for (int i = 0; i < typeArgs.length; i++) + { + h ^= Integer.rotateLeft(typeArgs[i].hashCode(), i); + } + return h; + } + + public String toString() + { + StringBuilder sb = new StringBuilder(); + if (owner != null) + { + sb.append(owner); + sb.append('.'); + sb.append(rawType.getSimpleName()); + } + else + { + sb.append(rawTypeName); + } + if (typeArgs.length > 0) + { + sb.append('<'); + for (int i = 0; i < typeArgs.length; i++) + { + if (i > 0) + sb.append(", "); + if (typeArgs[i] instanceof Class) + { + sb.append(((Class)typeArgs[i]).getName()); + } + else + { + sb.append(typeArgs[i]); + } + } + sb.append('>'); + } + return sb.toString(); + } } -class GenericArrayTypeImpl extends TypeImpl implements GenericArrayType +final class GenericArrayTypeImpl extends TypeImpl implements GenericArrayType { private Type componentType; @@ -127,15 +248,39 @@ class GenericArrayTypeImpl extends TypeImpl implements GenericArrayType this.componentType = componentType; } + Type resolve() + { + componentType = resolve(componentType); + return this; + } + public Type getGenericComponentType() { return componentType; } - // TODO implement equals/hashCode + public boolean equals(Object obj) + { + if (obj instanceof GenericArrayTypeImpl) + { + GenericArrayTypeImpl other = (GenericArrayTypeImpl)obj; + return componentType.equals(other.componentType); + } + return false; + } + + public int hashCode() + { + return 0x4be37a7f ^ componentType.hashCode(); + } + + public String toString() + { + return componentType + "[]"; + } } -class UnresolvedTypeVariable extends TypeImpl implements Type +final class UnresolvedTypeVariable extends TypeImpl implements Type { private GenericDeclaration decl; private String name; @@ -195,6 +340,81 @@ class UnresolvedTypeVariable extends TypeImpl implements Type } } +final class WildcardTypeImpl extends TypeImpl implements WildcardType +{ + private Type lower; + private Type upper; + + WildcardTypeImpl(Type lower, Type upper) + { + this.lower = lower; + this.upper = upper; + } + + Type resolve() + { + upper = resolve(upper); + lower = resolve(lower); + return this; + } + + public Type[] getUpperBounds() + { + if (upper == null) + { + return new Type[0]; + } + return new Type[] { upper }; + } + + public Type[] getLowerBounds() + { + if (lower == null) + { + return new Type[0]; + } + return new Type[] { lower }; + } + + public boolean equals(Object obj) + { + if (obj instanceof WildcardTypeImpl) + { + WildcardTypeImpl other = (WildcardTypeImpl)obj; + return Arrays.deepEquals(getUpperBounds(), other.getUpperBounds()) + && Arrays.deepEquals(getLowerBounds(), other.getLowerBounds()); + } + return false; + } + + public int hashCode() + { + int h = 0x75d074fd; + if (upper != null) + { + h ^= upper.hashCode(); + } + if (lower != null) + { + h ^= lower.hashCode(); + } + return h; + } + + public String toString() + { + if (lower != null) + { + return "? super " + lower; + } + if (upper == java.lang.Object.class) + { + return "?"; + } + return "? extends " + upper; + } +} + class GenericSignatureParser { private ClassLoader loader; @@ -202,7 +422,8 @@ class GenericSignatureParser private String signature; private int pos; - GenericSignatureParser(GenericDeclaration container, ClassLoader loader, String signature) + GenericSignatureParser(GenericDeclaration container, ClassLoader loader, + String signature) { this.container = container; this.loader = loader; @@ -233,16 +454,14 @@ class GenericSignatureParser { bounds.add(readFieldTypeSignature()); } - else - { - bounds.add(java.lang.Object.class); - } while (peekChar() == ':') { consume(':'); bounds.add(readFieldTypeSignature()); } - return new TypeVariableImpl(container, bounds.toArray(new Type[bounds.size()]), identifier); + Type[] b = new Type[bounds.size()]; + bounds.toArray(b); + return new TypeVariableImpl(container, b, identifier); } Type readFieldTypeSignature() @@ -260,18 +479,6 @@ class GenericSignatureParser } } - private Class resolveClass(String className) - { - try - { - return Class.forName(className, false, loader); - } - catch (ClassNotFoundException x) - { - throw new TypeNotPresentException(className, x); - } - } - Type readClassTypeSignature() { consume('L'); @@ -292,24 +499,22 @@ class GenericSignatureParser { typeArguments = readTypeArguments(); } + Type type = new ParameterizedTypeImpl(className, loader, null, + typeArguments); while (peekChar() == '.') { consume('.'); - // TODO - readIdentifier(); + className += "$" + readIdentifier(); + typeArguments = null; if (peekChar() == '<') { - // TODO - readTypeArguments(); + typeArguments = readTypeArguments(); } + type = new ParameterizedTypeImpl(className, loader, type, + typeArguments); } consume(';'); - if (typeArguments == null || typeArguments.length == 0) - { - return resolveClass(className); - } - // TODO get the owner - return new ParameterizedTypeImpl(resolveClass(className), null, typeArguments); + return type; } private Type[] readTypeArguments() @@ -329,17 +534,21 @@ class GenericSignatureParser private Type readTypeArgument() { char c = peekChar(); - if (c == '+' || c == '-') + if (c == '+') { - readChar(); - // FIXME add wildcard indicator - return readFieldTypeSignature(); + consume('+'); + return new WildcardTypeImpl(null, readFieldTypeSignature()); + } + else if (c == '-') + { + consume('-'); + return new WildcardTypeImpl(readFieldTypeSignature(), + java.lang.Object.class); } else if (c == '*') { - // FIXME what does this mean? consume('*'); - return java.lang.Object.class; + return new WildcardTypeImpl(null, java.lang.Object.class); } else { @@ -357,20 +566,28 @@ class GenericSignatureParser case 'T': return new GenericArrayTypeImpl(readFieldTypeSignature()); case 'Z': + consume('Z'); return boolean[].class; case 'B': + consume('B'); return byte[].class; case 'S': + consume('S'); return short[].class; case 'C': + consume('C'); return char[].class; case 'I': + consume('I'); return int[].class; case 'F': + consume('F'); return float[].class; case 'J': + consume('J'); return long[].class; case 'D': + consume('D'); return double[].class; default: throw new GenericSignatureFormatError(); @@ -415,4 +632,10 @@ class GenericSignatureParser if (readChar() != c) throw new GenericSignatureFormatError(); } + + final void end() + { + if (pos != signature.length()) + throw new GenericSignatureFormatError(); + } } diff --git a/gnu/java/lang/reflect/MethodSignatureParser.java b/gnu/java/lang/reflect/MethodSignatureParser.java index 10949cc84..50f98e299 100644 --- a/gnu/java/lang/reflect/MethodSignatureParser.java +++ b/gnu/java/lang/reflect/MethodSignatureParser.java @@ -1,4 +1,4 @@ -/* Class.java -- Representation of a Java class. +/* MethodSignatureParser.java Copyright (C) 2005 Free Software Foundation @@ -58,7 +58,8 @@ public class MethodSignatureParser extends GenericSignatureParser this(method, method.getDeclaringClass().getClassLoader(), signature); } - private MethodSignatureParser(GenericDeclaration wrapper, ClassLoader loader, String signature) + private MethodSignatureParser(GenericDeclaration wrapper, + ClassLoader loader, String signature) { super(wrapper, loader, signature); @@ -66,6 +67,10 @@ public class MethodSignatureParser extends GenericSignatureParser { typeParameters = readFormalTypeParameters(); } + else + { + typeParameters = new TypeVariable[0]; + } consume('('); ArrayList<Type> args = new ArrayList<Type>(); while (peekChar() != ')') @@ -91,25 +96,30 @@ public class MethodSignatureParser extends GenericSignatureParser } this.throwsSigs = new Type[throwsSigs.size()]; throwsSigs.toArray(this.throwsSigs); + end(); } public TypeVariable[] getTypeParameters() { + TypeImpl.resolve(typeParameters); return typeParameters; } public Type[] getGenericParameterTypes() { + TypeImpl.resolve(argTypes); return argTypes; } public Type getGenericReturnType() { + retType = TypeImpl.resolve(retType); return retType; } public Type[] getGenericExceptionTypes() { + TypeImpl.resolve(throwsSigs); return throwsSigs; } @@ -147,6 +157,9 @@ public class MethodSignatureParser extends GenericSignatureParser case 'D': consume('D'); return double.class; + case 'V': + consume('V'); + return void.class; default: throw new GenericSignatureFormatError(); } |