/** * Calculate the generic signature of a Class. A Class consists of: * * <pre> * class ::= declaration? reference reference* * </pre> * * @param f * @return * @throws Exception */ public String getSignature(Class< ? > c) throws Exception { StringBuilder sb = new StringBuilder(); declaration(sb, c); reference(sb, call(c, "getGenericSuperclass")); for (Object type : (Object[]) call(c, "getGenericInterfaces")) { reference(sb, type); } return sb.toString(); }
/** * Calculate the generic signature of a Class,Method,Field, or Constructor. * * @throws Exception */ public String getSignature(Object c) throws Exception { if (c instanceof Class<?>) return getSignature((Class<?>) c); if (c instanceof Constructor<?>) return getSignature((Constructor<?>) c); if (c instanceof Method) return getSignature((Method) c); if (c instanceof Field) return getSignature((Field) c); throw new IllegalArgumentException(c.toString()); }
Object[] typeParameters = (Object[]) call(gd, "getTypeParameters"); if (typeParameters.length > 0) { sb.append('<'); for (Object tv : typeParameters) { sb.append(call(tv, "getName")); Object[] bounds = (Object[]) call(tv, "getBounds"); if (bounds.length > 0 && isInterface(bounds[0])) { sb.append(':'); reference(sb, bounds[i]);
/** * Verify that the type is an interface. * * @param type * the type to check. * @return true if this is a class that is an interface or a Parameterized * Type that is an interface * @throws Exception */ private boolean isInterface(Object type) throws Exception { if (type instanceof Class) return (((Class< ? >) type).isInterface()); if (isInstance(type.getClass(), "java.lang.reflect.ParameterizedType")) return isInterface(call(type, "getRawType")); return false; }
/** * Calculate the generic signature of a Field. A Field consists of: * * <pre> * constructor ::= reference * </pre> * * @param c * @return * @throws Exception */ public String getSignature(Field f) throws Exception { StringBuilder sb = new StringBuilder(); Object t = call(f, "getGenericType"); reference(sb, t); return sb.toString(); }
/** * Creates the signature for a Parameterized Type. A Parameterized Type has * a raw class and a set of type variables. * * @param sb * @param pt * @throws Exception */ private void parameterizedType(StringBuilder sb, Object pt) throws Exception { Object owner = call(pt, "getOwnerType"); String name = ((Class< ? >) call(pt, "getRawType")).getName().replace('.', '/'); if (owner != null) { if (isInstance(owner.getClass(), "java.lang.reflect.ParameterizedType")) parameterizedType(sb, owner); else sb.append(((Class< ? >) owner).getName().replace('.', '/')); sb.append('.'); int n = name.lastIndexOf('$'); name = name.substring(n + 1); } sb.append(name); sb.append('<'); for (Object parameterType : (Object[]) call(pt, "getActualTypeArguments")) { reference(sb, parameterType); } sb.append('>'); }
reference(sb, map, rover, true); } else if (type == 'L') { String fqnb = rover.upTo("<;."); sb.append(fqnb); body(sb, map, rover); while (rover.peek() == '.') { sb.append(rover.take('.')); sb.append(rover.upTo("<;.")); body(sb, map, rover); name = assign(map, name); sb.append(name); sb.append(rover.take(';'));
/** * Calculate the generic signature of a Class. A Class consists of: * * <pre> * class ::= declaration? reference reference* * </pre> * * @throws Exception */ public String getSignature(Class<?> c) throws Exception { StringBuilder sb = new StringBuilder(); declaration(sb, c); reference(sb, c.getGenericSuperclass()); for (Type type : c.getGenericInterfaces()) { reference(sb, type); } return sb.toString(); }
/** * Normalize a signature to make sure the name of the variables are always * the same. We change the names of the type variables to _n, where n is an * integer. n is incremented for every new name and already used names are * replaced with the _n name. * * @return a normalized signature */ public String normalize(String signature) { StringBuilder sb = new StringBuilder(); Map<String, String> map = new HashMap<>(); Rover rover = new Rover(signature); declare(sb, map, rover); if (rover.peek() == '(') { // method or constructor sb.append(rover.take('(')); while (rover.peek() != ')') { reference(sb, map, rover, true); } sb.append(rover.take(')')); reference(sb, map, rover, true); // return type } else { // field or class reference(sb, map, rover, true); // field type or super class while (!rover.isEOF()) { reference(sb, map, rover, true); // interfaces } } return sb.toString(); }
ParameterizedType pt = (ParameterizedType) t; sb.append('L'); parameterizedType(sb, pt); sb.append(';'); return; GenericArrayType gat = (GenericArrayType) t; sb.append('['); reference(sb, gat.getGenericComponentType()); } else if (t instanceof WildcardType) { WildcardType wt = (WildcardType) t; reference(sb, upper); reference(sb, lower); Class<?> c = (Class<?>) t; if (c.isPrimitive()) { sb.append(primitive(c)); } else { sb.append('L');
/** * Creates the signature for a Parameterized Type. A Parameterized Type has * a raw class and a set of type variables. * * @param sb * @param pt * @throws Exception */ private void parameterizedType(StringBuilder sb, ParameterizedType pt) throws Exception { String name = ((Class<?>) pt.getRawType()).getName() .replace('.', '/'); Type owner = pt.getOwnerType(); if (owner != null) { if (owner instanceof ParameterizedType) parameterizedType(sb, (ParameterizedType) owner); else sb.append(((Class<?>) owner).getName() .replace('.', '/')); sb.append('.'); int n = name.lastIndexOf('$'); name = name.substring(n + 1); } sb.append(name); sb.append('<'); for (Type parameterType : pt.getActualTypeArguments()) { reference(sb, parameterType); } sb.append('>'); }
if (bounds.length > 0 && isInterface(bounds[0])) { sb.append(':'); reference(sb, bound);
/** * Verify that the type is an interface. * * @param type the type to check. * @return true if this is a class that is an interface or a Parameterized * Type that is an interface * @throws Exception */ private boolean isInterface(Type type) throws Exception { if (type instanceof Class) return ((Class<?>) type).isInterface(); if (type instanceof ParameterizedType) return isInterface(((ParameterizedType) type).getRawType()); return false; }
/** * Calculate the generic signature of a Field. A Field consists of: * * <pre> * constructor ::= reference * </pre> * * @throws Exception */ public String getSignature(Field f) throws Exception { StringBuilder sb = new StringBuilder(); Type t = f.getGenericType(); reference(sb, t); return sb.toString(); }
/** * Check if the environment has generics, i.e. later than Java 5 VM. * * @return true if generics are supported * @throws Exception */ public boolean hasGenerics() throws Exception { try { call(Signatures.class, "getGenericSuperClass"); return true; } catch (NoSuchMethodException mnfe) { return false; } }
/** * Creates the signature for a Parameterized Type. A Parameterized Type has * a raw class and a set of type variables. * * @param sb * @param pt * @throws Exception */ private void parameterizedType(StringBuilder sb, Object pt) throws Exception { Object owner = call(pt, "getOwnerType"); String name = ((Class< ? >) call(pt, "getRawType")).getName().replace('.', '/'); if (owner != null) { if (isInstance(owner.getClass(), "java.lang.reflect.ParameterizedType")) parameterizedType(sb, owner); else sb.append(((Class< ? >) owner).getName().replace('.', '/')); sb.append('.'); int n = name.lastIndexOf('$'); name = name.substring(n + 1); } sb.append(name); sb.append('<'); for (Object parameterType : (Object[]) call(pt, "getActualTypeArguments")) { reference(sb, parameterType); } sb.append('>'); }
reference(sb, map, rover, true); } else if (type == 'L') { String fqnb = rover.upTo("<;."); sb.append(fqnb); body(sb, map, rover); while (rover.peek() == '.') { sb.append(rover.take('.')); sb.append(rover.upTo("<;.")); body(sb, map, rover); name = assign(map, name); sb.append(name); sb.append(rover.take(';'));
/** * Calculate the generic signature of a Class. A Class consists of: * * <pre> * class ::= declaration? reference reference* * </pre> * * @throws Exception */ public String getSignature(Class<?> c) throws Exception { StringBuilder sb = new StringBuilder(); declaration(sb, c); reference(sb, c.getGenericSuperclass()); for (Type type : c.getGenericInterfaces()) { reference(sb, type); } return sb.toString(); }