1 /* GenericSignatureParser.java
3 Free Software Foundation
5 This file is part of GNU Classpath.
7 GNU Classpath is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Classpath is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Classpath; see the file COPYING. If not, write to the
19 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 Linking this library statically or dynamically with other modules is
23 making a combined work based on this library. Thus, the terms and
24 conditions of the GNU General Public License cover the whole
27 As a special exception, the copyright holders of this library give you
28 permission to link this library with independent modules to produce an
29 executable, regardless of the license terms of these independent
30 modules, and to copy and distribute the resulting executable under
31 terms of your choice, provided that you also meet, for each linked
32 independent module, the terms and conditions of the license of that
33 module. An independent module is a module which is not derived from
34 or based on this library. If you modify this library, you may extend
35 this exception to your version of the library, but you are not
36 obligated to do so. If you do not wish to do so, delete this
37 exception statement from your version. */
39 package gnu.java.lang.reflect;
41 import java.lang.reflect.*;
42 import java.util.ArrayList;
43 import java.util.Arrays;
45 final class TypeVariableImpl extends TypeImpl implements TypeVariable
47 private GenericDeclaration decl;
48 private Type[] bounds;
51 TypeVariableImpl(GenericDeclaration decl, Type[] bounds, String name)
63 public Type[] getBounds()
66 return (Type[]) bounds.clone();
69 public GenericDeclaration getGenericDeclaration()
74 public String getName()
79 public boolean equals(Object obj)
81 if (obj instanceof TypeVariableImpl)
83 TypeVariableImpl other = (TypeVariableImpl)obj;
84 return decl.equals(other.decl) && name.equals(other.name);
91 return 0x5f4d5156 ^ decl.hashCode() ^ name.hashCode();
94 public String toString()
100 final class ParameterizedTypeImpl extends TypeImpl implements ParameterizedType
102 private String rawTypeName;
103 private ClassLoader loader;
104 private Class rawType;
106 private Type[] typeArgs;
108 ParameterizedTypeImpl(String rawTypeName, ClassLoader loader, Type owner,
111 this.rawTypeName = rawTypeName;
112 this.loader = loader;
114 this.typeArgs = typeArgs;
123 rawType = Class.forName(rawTypeName, false, loader);
125 catch (ClassNotFoundException x)
127 throw new TypeNotPresentException(rawTypeName, x);
130 if (typeArgs == null)
136 typeArgs = new Type[0];
139 owner = resolve(owner);
143 public Type[] getActualTypeArguments()
145 return (Type[]) typeArgs.clone();
148 public Type getRawType()
153 public Type getOwnerType()
158 public boolean equals(Object obj)
160 if (obj instanceof ParameterizedTypeImpl)
162 ParameterizedTypeImpl other = (ParameterizedTypeImpl)obj;
163 return rawType.equals(other.rawType)
164 && ((owner == null && other.owner == null)
165 || owner.equals(other.owner))
166 && Arrays.deepEquals(typeArgs, other.typeArgs);
171 public int hashCode()
173 int h = 0x58158970 ^ rawType.hashCode();
176 h ^= Integer.reverse(owner.hashCode());
178 for (int i = 0; i < typeArgs.length; i++)
180 h ^= Integer.rotateLeft(typeArgs[i].hashCode(), i);
185 public String toString()
187 StringBuilder sb = new StringBuilder();
192 sb.append(rawType.getSimpleName());
196 sb.append(rawTypeName);
198 if (typeArgs.length > 0)
201 for (int i = 0; i < typeArgs.length; i++)
205 if (typeArgs[i] instanceof Class)
207 sb.append(((Class)typeArgs[i]).getName());
211 sb.append(typeArgs[i]);
216 return sb.toString();
220 final class GenericArrayTypeImpl extends TypeImpl implements GenericArrayType
222 private Type componentType;
224 GenericArrayTypeImpl(Type componentType)
226 this.componentType = componentType;
231 componentType = resolve(componentType);
235 public Type getGenericComponentType()
237 return componentType;
240 public boolean equals(Object obj)
242 if (obj instanceof GenericArrayTypeImpl)
244 GenericArrayTypeImpl other = (GenericArrayTypeImpl)obj;
245 return componentType.equals(other.componentType);
250 public int hashCode()
252 return 0x4be37a7f ^ componentType.hashCode();
255 public String toString()
257 return componentType + "[]";
261 final class UnresolvedTypeVariable extends TypeImpl implements Type
263 private GenericDeclaration decl;
266 UnresolvedTypeVariable(GenericDeclaration decl, String name)
274 GenericDeclaration d = decl;
277 for (TypeVariable t : d.getTypeParameters())
279 if (t.getName().equals(name))
286 throw new MalformedParameterizedTypeException();
289 private static GenericDeclaration getParent(GenericDeclaration d)
291 if (d instanceof Class)
293 Method m = ((Class)d).getEnclosingMethod();
298 Constructor c = ((Class)d).getEnclosingConstructor();
303 return ((Class)d).getEnclosingClass();
305 else if (d instanceof Method)
307 return ((Method)d).getDeclaringClass();
309 else if (d instanceof Constructor)
311 return ((Constructor)d).getDeclaringClass();
315 // TODO figure out what this represents
321 final class WildcardTypeImpl extends TypeImpl implements WildcardType
326 WildcardTypeImpl(Type lower, Type upper)
334 upper = resolve(upper);
335 lower = resolve(lower);
339 public Type[] getUpperBounds()
345 return new Type[] { upper };
348 public Type[] getLowerBounds()
354 return new Type[] { lower };
357 public boolean equals(Object obj)
359 if (obj instanceof WildcardTypeImpl)
361 WildcardTypeImpl other = (WildcardTypeImpl)obj;
362 return Arrays.deepEquals(getUpperBounds(), other.getUpperBounds())
363 && Arrays.deepEquals(getLowerBounds(), other.getLowerBounds());
368 public int hashCode()
373 h ^= upper.hashCode();
377 h ^= lower.hashCode();
382 public String toString()
386 return "? super " + lower;
388 if (upper == java.lang.Object.class)
392 return "? extends " + upper;
396 class GenericSignatureParser
398 private ClassLoader loader;
399 private GenericDeclaration container;
400 private String signature;
403 GenericSignatureParser(GenericDeclaration container, ClassLoader loader,
406 this.container = container;
407 this.loader = loader;
408 this.signature = signature;
411 TypeVariable[] readFormalTypeParameters()
414 ArrayList<TypeVariable> params = new ArrayList<TypeVariable>();
417 // TODO should we handle name clashes?
418 params.add(readFormalTypeParameter());
419 } while (peekChar() != '>');
421 TypeVariable[] list = new TypeVariable[params.size()];
422 params.toArray(list);
426 private TypeVariable readFormalTypeParameter()
428 String identifier = readIdentifier();
430 ArrayList<Type> bounds = new ArrayList<Type>();
431 if (peekChar() != ':')
433 bounds.add(readFieldTypeSignature());
435 while (peekChar() == ':')
438 bounds.add(readFieldTypeSignature());
440 Type[] b = new Type[bounds.size()];
442 return new TypeVariableImpl(container, b, identifier);
445 Type readFieldTypeSignature()
450 return readClassTypeSignature();
452 return readArrayTypeSignature();
454 return readTypeVariableSignature();
456 throw new GenericSignatureFormatError();
460 Type readClassTypeSignature()
463 String className = "";
466 String part = readIdentifier();
467 if (peekChar() != '/')
473 className += part + ".";
475 Type[] typeArguments = null;
476 if (peekChar() == '<')
478 typeArguments = readTypeArguments();
480 Type type = new ParameterizedTypeImpl(className, loader, null,
482 while (peekChar() == '.')
485 className += "$" + readIdentifier();
486 typeArguments = null;
487 if (peekChar() == '<')
489 typeArguments = readTypeArguments();
491 type = new ParameterizedTypeImpl(className, loader, type,
498 private Type[] readTypeArguments()
501 ArrayList<Type> list = new ArrayList<Type>();
504 list.add(readTypeArgument());
505 } while ((peekChar() != '>'));
507 Type[] arr = new Type[list.size()];
512 private Type readTypeArgument()
518 return new WildcardTypeImpl(null, readFieldTypeSignature());
523 return new WildcardTypeImpl(readFieldTypeSignature(),
524 java.lang.Object.class);
529 return new WildcardTypeImpl(null, java.lang.Object.class);
533 return readFieldTypeSignature();
537 Type readArrayTypeSignature()
545 return new GenericArrayTypeImpl(readFieldTypeSignature());
548 return boolean[].class;
554 return short[].class;
563 return float[].class;
569 return double[].class;
571 throw new GenericSignatureFormatError();
575 Type readTypeVariableSignature()
578 String identifier = readIdentifier();
580 return new UnresolvedTypeVariable(container, identifier);
583 private String readIdentifier()
591 } while (";:./<>-+*".indexOf(c) == -1);
592 return signature.substring(start, pos);
595 final char peekChar()
597 if (pos == signature.length())
600 return signature.charAt(pos);
603 final char readChar()
605 return signature.charAt(pos++);
608 final void consume(char c)
611 throw new GenericSignatureFormatError();
616 if (pos != signature.length())
617 throw new GenericSignatureFormatError();