summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeroen Frijters <jeroen@sumatra.nl>2005-09-30 09:12:01 +0000
committerJeroen Frijters <jeroen@sumatra.nl>2005-09-30 09:12:01 +0000
commit67a508c431ce02998ed7a95274a5fa59ffc7307d (patch)
tree36365f57457ef2589e082be6ce388dfa1b3a55d1
parenta82dcadc3a145ec55585e78b78fc3d031fa4753c (diff)
downloadclasspath-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--ChangeLog8
-rw-r--r--gnu/java/lang/reflect/ClassSignatureParser.java6
-rw-r--r--gnu/java/lang/reflect/FieldSignatureParser.java103
-rw-r--r--gnu/java/lang/reflect/GenericSignatureParser.java327
-rw-r--r--gnu/java/lang/reflect/MethodSignatureParser.java17
5 files changed, 406 insertions, 55 deletions
diff --git a/ChangeLog b/ChangeLog
index 7f9d77b3c..bb0a2dae1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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();
}