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 /* FIXME[GENERICS]: Remove cast */
64 public Type
[] getBounds()
67 return (Type
[]) bounds
.clone();
70 public GenericDeclaration
getGenericDeclaration()
75 public String
getName()
80 public boolean equals(Object obj
)
82 if (obj
instanceof TypeVariableImpl
)
84 TypeVariableImpl other
= (TypeVariableImpl
)obj
;
85 return decl
.equals(other
.decl
) && name
.equals(other
.name
);
92 return 0x5f4d5156 ^ decl
.hashCode() ^ name
.hashCode();
95 public String
toString()
101 final class ParameterizedTypeImpl
extends TypeImpl
implements ParameterizedType
103 private String rawTypeName
;
104 private ClassLoader loader
;
105 private Class rawType
;
107 private Type
[] typeArgs
;
109 ParameterizedTypeImpl(String rawTypeName
, ClassLoader loader
, Type owner
,
112 this.rawTypeName
= rawTypeName
;
113 this.loader
= loader
;
115 this.typeArgs
= typeArgs
;
124 rawType
= Class
.forName(rawTypeName
, false, loader
);
126 catch (ClassNotFoundException x
)
128 throw new TypeNotPresentException(rawTypeName
, x
);
131 if (typeArgs
== null)
137 typeArgs
= new Type
[0];
140 owner
= resolve(owner
);
144 /* FIXME[GENERICS]: Remove cast */
145 public Type
[] getActualTypeArguments()
147 return (Type
[]) typeArgs
.clone();
150 public Type
getRawType()
155 public Type
getOwnerType()
160 public boolean equals(Object obj
)
162 if (obj
instanceof ParameterizedTypeImpl
)
164 ParameterizedTypeImpl other
= (ParameterizedTypeImpl
)obj
;
165 return rawType
.equals(other
.rawType
)
166 && ((owner
== null && other
.owner
== null)
167 || owner
.equals(other
.owner
))
168 && Arrays
.deepEquals(typeArgs
, other
.typeArgs
);
173 public int hashCode()
175 int h
= 0x58158970 ^ rawType
.hashCode();
178 h ^
= Integer
.reverse(owner
.hashCode());
180 for (int i
= 0; i
< typeArgs
.length
; i
++)
182 h ^
= Integer
.rotateLeft(typeArgs
[i
].hashCode(), i
);
187 public String
toString()
189 StringBuilder sb
= new StringBuilder();
194 sb
.append(rawType
.getSimpleName());
198 sb
.append(rawTypeName
);
200 if (typeArgs
.length
> 0)
203 for (int i
= 0; i
< typeArgs
.length
; i
++)
207 if (typeArgs
[i
] instanceof Class
)
209 sb
.append(((Class
)typeArgs
[i
]).getName());
213 sb
.append(typeArgs
[i
]);
218 return sb
.toString();
222 final class GenericArrayTypeImpl
extends TypeImpl
implements GenericArrayType
224 private Type componentType
;
226 GenericArrayTypeImpl(Type componentType
)
228 this.componentType
= componentType
;
233 componentType
= resolve(componentType
);
237 public Type
getGenericComponentType()
239 return componentType
;
242 public boolean equals(Object obj
)
244 if (obj
instanceof GenericArrayTypeImpl
)
246 GenericArrayTypeImpl other
= (GenericArrayTypeImpl
)obj
;
247 return componentType
.equals(other
.componentType
);
252 public int hashCode()
254 return 0x4be37a7f ^ componentType
.hashCode();
257 public String
toString()
259 return componentType
+ "[]";
263 final class UnresolvedTypeVariable
extends TypeImpl
implements Type
265 private GenericDeclaration decl
;
268 UnresolvedTypeVariable(GenericDeclaration decl
, String name
)
276 GenericDeclaration d
= decl
;
279 TypeVariable
[] vars
= d
.getTypeParameters();
280 for (int a
= 0; a
< vars
.length
; ++a
)
282 if (vars
[a
].getName().equals(name
))
289 throw new MalformedParameterizedTypeException();
292 private static GenericDeclaration
getParent(GenericDeclaration d
)
294 if (d
instanceof Class
)
296 Method m
= ((Class
)d
).getEnclosingMethod();
301 Constructor c
= ((Class
)d
).getEnclosingConstructor();
306 return ((Class
)d
).getEnclosingClass();
308 else if (d
instanceof Method
)
310 return ((Method
)d
).getDeclaringClass();
312 else if (d
instanceof Constructor
)
314 return ((Constructor
)d
).getDeclaringClass();
318 // TODO figure out what this represents
324 final class WildcardTypeImpl
extends TypeImpl
implements WildcardType
329 WildcardTypeImpl(Type lower
, Type upper
)
337 upper
= resolve(upper
);
338 lower
= resolve(lower
);
342 public Type
[] getUpperBounds()
348 return new Type
[] { upper
};
351 public Type
[] getLowerBounds()
357 return new Type
[] { lower
};
360 public boolean equals(Object obj
)
362 if (obj
instanceof WildcardTypeImpl
)
364 WildcardTypeImpl other
= (WildcardTypeImpl
)obj
;
365 return Arrays
.deepEquals(getUpperBounds(), other
.getUpperBounds())
366 && Arrays
.deepEquals(getLowerBounds(), other
.getLowerBounds());
371 public int hashCode()
376 h ^
= upper
.hashCode();
380 h ^
= lower
.hashCode();
385 public String
toString()
389 return "? super " + lower
;
391 if (upper
== java
.lang
.Object
.class)
395 return "? extends " + upper
;
399 class GenericSignatureParser
401 private ClassLoader loader
;
402 private GenericDeclaration container
;
403 private String signature
;
406 GenericSignatureParser(GenericDeclaration container
, ClassLoader loader
,
409 this.container
= container
;
410 this.loader
= loader
;
411 this.signature
= signature
;
414 TypeVariable
[] readFormalTypeParameters()
417 ArrayList params
= new ArrayList();
420 // TODO should we handle name clashes?
421 params
.add(readFormalTypeParameter());
422 } while (peekChar() != '>');
424 TypeVariable
[] list
= new TypeVariable
[params
.size()];
425 params
.toArray(list
);
429 private TypeVariable
readFormalTypeParameter()
431 String identifier
= readIdentifier();
433 ArrayList bounds
= new ArrayList();
434 if (peekChar() != ':')
436 bounds
.add(readFieldTypeSignature());
438 while (peekChar() == ':')
441 bounds
.add(readFieldTypeSignature());
443 Type
[] b
= new Type
[bounds
.size()];
445 return new TypeVariableImpl(container
, b
, identifier
);
448 Type
readFieldTypeSignature()
453 return readClassTypeSignature();
455 return readArrayTypeSignature();
457 return readTypeVariableSignature();
459 throw new GenericSignatureFormatError();
463 Type
readClassTypeSignature()
466 String className
= "";
469 String part
= readIdentifier();
470 if (peekChar() != '/')
476 className
+= part
+ ".";
478 Type
[] typeArguments
= null;
479 if (peekChar() == '<')
481 typeArguments
= readTypeArguments();
483 Type type
= new ParameterizedTypeImpl(className
, loader
, null,
485 while (peekChar() == '.')
488 className
+= "$" + readIdentifier();
489 typeArguments
= null;
490 if (peekChar() == '<')
492 typeArguments
= readTypeArguments();
494 type
= new ParameterizedTypeImpl(className
, loader
, type
,
501 private Type
[] readTypeArguments()
504 ArrayList list
= new ArrayList();
507 list
.add(readTypeArgument());
508 } while ((peekChar() != '>'));
510 Type
[] arr
= new Type
[list
.size()];
515 private Type
readTypeArgument()
521 return new WildcardTypeImpl(null, readFieldTypeSignature());
526 return new WildcardTypeImpl(readFieldTypeSignature(),
527 java
.lang
.Object
.class);
532 return new WildcardTypeImpl(null, java
.lang
.Object
.class);
536 return readFieldTypeSignature();
540 Type
readArrayTypeSignature()
548 return new GenericArrayTypeImpl(readFieldTypeSignature());
551 return boolean[].class;
557 return short[].class;
566 return float[].class;
572 return double[].class;
574 throw new GenericSignatureFormatError();
578 Type
readTypeVariableSignature()
581 String identifier
= readIdentifier();
583 return new UnresolvedTypeVariable(container
, identifier
);
586 private String
readIdentifier()
594 } while (";:./<>-+*".indexOf(c
) == -1);
595 return signature
.substring(start
, pos
);
598 final char peekChar()
600 if (pos
== signature
.length())
603 return signature
.charAt(pos
);
606 final char readChar()
608 return signature
.charAt(pos
++);
611 final void consume(char c
)
614 throw new GenericSignatureFormatError();
619 if (pos
!= signature
.length())
620 throw new GenericSignatureFormatError();