Hi,

I finished the generics signature parsing support code. Next up,
changing the vm\reference reflection classes to make use of it.

Regards,
Jeroen

2005-09-30  Jeroen Frijters  <[EMAIL PROTECTED]>

        * 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.
Index: gnu/java/lang/reflect/ClassSignatureParser.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/gnu/java/lang/reflect/Attic/ClassSignatureParser.java,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 ClassSignatureParser.java
--- gnu/java/lang/reflect/ClassSignatureParser.java     26 Sep 2005 11:43:40 
-0000      1.1.2.1
+++ gnu/java/lang/reflect/ClassSignatureParser.java     28 Sep 2005 10:37:32 
-0000
@@ -1,4 +1,4 @@
-/* Class.java -- Representation of a Java class.
+/* ClassSignatureParser.java
    Copyright (C) 2005
    Free Software Foundation
 
@@ -69,20 +69,24 @@
         }
         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;
     }
 }
Index: gnu/java/lang/reflect/FieldSignatureParser.java
===================================================================
RCS file: gnu/java/lang/reflect/FieldSignatureParser.java
diff -N gnu/java/lang/reflect/FieldSignatureParser.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gnu/java/lang/reflect/FieldSignatureParser.java     28 Sep 2005 10:49:13 
-0000
@@ -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;
+    }
+}
Index: gnu/java/lang/reflect/GenericSignatureParser.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/gnu/java/lang/reflect/Attic/GenericSignatureParser.java,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 GenericSignatureParser.java
--- gnu/java/lang/reflect/GenericSignatureParser.java   26 Sep 2005 11:43:40 
-0000      1.1.2.1
+++ gnu/java/lang/reflect/GenericSignatureParser.java   30 Sep 2005 08:56:37 
-0000
@@ -1,4 +1,4 @@
-/* Class.java -- Representation of a Java class.
+/* GenericSignatureParser.java
    Copyright (C) 2005
    Free Software Foundation
 
@@ -40,16 +40,31 @@
 
 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 @@
         this.name = name;
     }
 
+    Type resolve()
+    {
+        return this;
+    }
+
     public Type[] getBounds()
     {
+        resolve(bounds);
         return bounds.clone();
     }
 
@@ -77,31 +98,72 @@
         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 @@
         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 @@
         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 @@
     }
 }
 
+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 @@
     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 @@
         {
             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 @@
         }
     }
 
-    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 @@
         {
             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 @@
     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 @@
             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();
@@ -413,6 +630,12 @@
     final void consume(char c)
     {
         if (readChar() != c)
+            throw new GenericSignatureFormatError();
+    }
+
+    final void end()
+    {
+        if (pos != signature.length())
             throw new GenericSignatureFormatError();
     }
 }
Index: gnu/java/lang/reflect/MethodSignatureParser.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/gnu/java/lang/reflect/Attic/MethodSignatureParser.java,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 MethodSignatureParser.java
--- gnu/java/lang/reflect/MethodSignatureParser.java    26 Sep 2005 11:43:40 
-0000      1.1.2.1
+++ gnu/java/lang/reflect/MethodSignatureParser.java    28 Sep 2005 10:37:23 
-0000
@@ -1,4 +1,4 @@
-/* Class.java -- Representation of a Java class.
+/* MethodSignatureParser.java
    Copyright (C) 2005
    Free Software Foundation
 
@@ -58,7 +58,8 @@
         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 @@
         {
             typeParameters = readFormalTypeParameters();
         }
+        else
+        {
+            typeParameters = new TypeVariable[0];
+        }
         consume('(');
         ArrayList<Type> args = new ArrayList<Type>();
         while (peekChar() != ')')
@@ -91,25 +96,30 @@
         }
         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 @@
             case 'D':
                 consume('D');
                 return double.class;
+            case 'V':
+                consume('V');
+                return void.class;
             default:
                 throw new GenericSignatureFormatError();
         }
_______________________________________________
Classpath-patches mailing list
Classpath-patches@gnu.org
http://lists.gnu.org/mailman/listinfo/classpath-patches

Reply via email to