MoreTypes.java revision 564053fc876faf8325bb0d11e009c650bfaa588b
13beaaaff52598e849659281fed35dc29a221fac4limpbizkit/** 23beaaaff52598e849659281fed35dc29a221fac4limpbizkit * Copyright (C) 2008 Google Inc. 33beaaaff52598e849659281fed35dc29a221fac4limpbizkit * 43beaaaff52598e849659281fed35dc29a221fac4limpbizkit * Licensed under the Apache License, Version 2.0 (the "License"); 53beaaaff52598e849659281fed35dc29a221fac4limpbizkit * you may not use this file except in compliance with the License. 63beaaaff52598e849659281fed35dc29a221fac4limpbizkit * You may obtain a copy of the License at 73beaaaff52598e849659281fed35dc29a221fac4limpbizkit * 83beaaaff52598e849659281fed35dc29a221fac4limpbizkit * http://www.apache.org/licenses/LICENSE-2.0 93beaaaff52598e849659281fed35dc29a221fac4limpbizkit * 103beaaaff52598e849659281fed35dc29a221fac4limpbizkit * Unless required by applicable law or agreed to in writing, software 113beaaaff52598e849659281fed35dc29a221fac4limpbizkit * distributed under the License is distributed on an "AS IS" BASIS, 123beaaaff52598e849659281fed35dc29a221fac4limpbizkit * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133beaaaff52598e849659281fed35dc29a221fac4limpbizkit * See the License for the specific language governing permissions and 143beaaaff52598e849659281fed35dc29a221fac4limpbizkit * limitations under the License. 153beaaaff52598e849659281fed35dc29a221fac4limpbizkit */ 163beaaaff52598e849659281fed35dc29a221fac4limpbizkit 173beaaaff52598e849659281fed35dc29a221fac4limpbizkit 183beaaaff52598e849659281fed35dc29a221fac4limpbizkitpackage com.google.inject.internal; 193beaaaff52598e849659281fed35dc29a221fac4limpbizkit 203beaaaff52598e849659281fed35dc29a221fac4limpbizkitimport com.google.common.base.Objects; 2149f67c0f62bc1748dd32e1d86616085231e974e7limpbizkitimport static com.google.common.base.Preconditions.checkArgument; 22564053fc876faf8325bb0d11e009c650bfaa588blimpbizkitimport static com.google.common.base.Preconditions.checkNotNull; 233beaaaff52598e849659281fed35dc29a221fac4limpbizkitimport com.google.common.collect.ImmutableMap; 243beaaaff52598e849659281fed35dc29a221fac4limpbizkitimport com.google.inject.TypeLiteral; 253beaaaff52598e849659281fed35dc29a221fac4limpbizkitimport com.google.inject.util.Types; 263beaaaff52598e849659281fed35dc29a221fac4limpbizkitimport java.io.Serializable; 27564053fc876faf8325bb0d11e009c650bfaa588blimpbizkitimport java.lang.reflect.Constructor; 28564053fc876faf8325bb0d11e009c650bfaa588blimpbizkitimport java.lang.reflect.Field; 293beaaaff52598e849659281fed35dc29a221fac4limpbizkitimport java.lang.reflect.GenericArrayType; 30564053fc876faf8325bb0d11e009c650bfaa588blimpbizkitimport java.lang.reflect.Member; 31564053fc876faf8325bb0d11e009c650bfaa588blimpbizkitimport java.lang.reflect.Method; 323beaaaff52598e849659281fed35dc29a221fac4limpbizkitimport java.lang.reflect.ParameterizedType; 333beaaaff52598e849659281fed35dc29a221fac4limpbizkitimport java.lang.reflect.Type; 343beaaaff52598e849659281fed35dc29a221fac4limpbizkitimport java.util.Arrays; 353beaaaff52598e849659281fed35dc29a221fac4limpbizkitimport java.util.Map; 363beaaaff52598e849659281fed35dc29a221fac4limpbizkit 373beaaaff52598e849659281fed35dc29a221fac4limpbizkit/** 383beaaaff52598e849659281fed35dc29a221fac4limpbizkit * Static methods for working with types that we aren't publishing in the 393beaaaff52598e849659281fed35dc29a221fac4limpbizkit * public {@code Types} API. 403beaaaff52598e849659281fed35dc29a221fac4limpbizkit * 413beaaaff52598e849659281fed35dc29a221fac4limpbizkit * @author jessewilson@google.com (Jesse Wilson) 423beaaaff52598e849659281fed35dc29a221fac4limpbizkit */ 433beaaaff52598e849659281fed35dc29a221fac4limpbizkitpublic class MoreTypes { 443beaaaff52598e849659281fed35dc29a221fac4limpbizkit private MoreTypes() {} 453beaaaff52598e849659281fed35dc29a221fac4limpbizkit 463beaaaff52598e849659281fed35dc29a221fac4limpbizkit private static final Map<TypeLiteral<?>, TypeLiteral<?>> PRIMITIVE_TO_WRAPPER 473beaaaff52598e849659281fed35dc29a221fac4limpbizkit = new ImmutableMap.Builder<TypeLiteral<?>, TypeLiteral<?>>() 483beaaaff52598e849659281fed35dc29a221fac4limpbizkit .put(TypeLiteral.get(boolean.class), TypeLiteral.get(Boolean.class)) 493beaaaff52598e849659281fed35dc29a221fac4limpbizkit .put(TypeLiteral.get(byte.class), TypeLiteral.get(Byte.class)) 503beaaaff52598e849659281fed35dc29a221fac4limpbizkit .put(TypeLiteral.get(short.class), TypeLiteral.get(Short.class)) 513beaaaff52598e849659281fed35dc29a221fac4limpbizkit .put(TypeLiteral.get(int.class), TypeLiteral.get(Integer.class)) 523beaaaff52598e849659281fed35dc29a221fac4limpbizkit .put(TypeLiteral.get(long.class), TypeLiteral.get(Long.class)) 533beaaaff52598e849659281fed35dc29a221fac4limpbizkit .put(TypeLiteral.get(float.class), TypeLiteral.get(Float.class)) 543beaaaff52598e849659281fed35dc29a221fac4limpbizkit .put(TypeLiteral.get(double.class), TypeLiteral.get(Double.class)) 553beaaaff52598e849659281fed35dc29a221fac4limpbizkit .put(TypeLiteral.get(char.class), TypeLiteral.get(Character.class)) 563beaaaff52598e849659281fed35dc29a221fac4limpbizkit .put(TypeLiteral.get(void.class), TypeLiteral.get(Void.class)) 573beaaaff52598e849659281fed35dc29a221fac4limpbizkit .build(); 583beaaaff52598e849659281fed35dc29a221fac4limpbizkit 593beaaaff52598e849659281fed35dc29a221fac4limpbizkit /** 603beaaaff52598e849659281fed35dc29a221fac4limpbizkit * Returns an equivalent (but not necessarily equal) type literal that is 613beaaaff52598e849659281fed35dc29a221fac4limpbizkit * free of primitive types. Type literals of primitives will return the 623beaaaff52598e849659281fed35dc29a221fac4limpbizkit * corresponding wrapper types. 633beaaaff52598e849659281fed35dc29a221fac4limpbizkit */ 643beaaaff52598e849659281fed35dc29a221fac4limpbizkit public static <T> TypeLiteral<T> wrapPrimitives(TypeLiteral<T> typeLiteral) { 653beaaaff52598e849659281fed35dc29a221fac4limpbizkit @SuppressWarnings("unchecked") 663beaaaff52598e849659281fed35dc29a221fac4limpbizkit TypeLiteral<T> wrappedPrimitives = (TypeLiteral<T>) PRIMITIVE_TO_WRAPPER.get(typeLiteral); 673beaaaff52598e849659281fed35dc29a221fac4limpbizkit return wrappedPrimitives != null 683beaaaff52598e849659281fed35dc29a221fac4limpbizkit ? wrappedPrimitives 693beaaaff52598e849659281fed35dc29a221fac4limpbizkit : typeLiteral; 703beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 713beaaaff52598e849659281fed35dc29a221fac4limpbizkit 723beaaaff52598e849659281fed35dc29a221fac4limpbizkit /** 733beaaaff52598e849659281fed35dc29a221fac4limpbizkit * Returns a type that is functionally equal but not necessarily equal 743beaaaff52598e849659281fed35dc29a221fac4limpbizkit * according to {@link Object#equals(Object) Object.equals()}. The returned 753beaaaff52598e849659281fed35dc29a221fac4limpbizkit * type is {@link Serializable}. 763beaaaff52598e849659281fed35dc29a221fac4limpbizkit */ 773beaaaff52598e849659281fed35dc29a221fac4limpbizkit public static Type canonicalize(Type type) { 783beaaaff52598e849659281fed35dc29a221fac4limpbizkit if (type instanceof ParameterizedTypeImpl 793beaaaff52598e849659281fed35dc29a221fac4limpbizkit || type instanceof GenericArrayTypeImpl) { 803beaaaff52598e849659281fed35dc29a221fac4limpbizkit return type; 813beaaaff52598e849659281fed35dc29a221fac4limpbizkit 823beaaaff52598e849659281fed35dc29a221fac4limpbizkit } else if (type instanceof ParameterizedType) { 833beaaaff52598e849659281fed35dc29a221fac4limpbizkit ParameterizedType p = (ParameterizedType) type; 843beaaaff52598e849659281fed35dc29a221fac4limpbizkit return Types.newParameterizedTypeWithOwner(p.getOwnerType(), 853beaaaff52598e849659281fed35dc29a221fac4limpbizkit p.getRawType(), p.getActualTypeArguments()); 863beaaaff52598e849659281fed35dc29a221fac4limpbizkit 873beaaaff52598e849659281fed35dc29a221fac4limpbizkit } else if (type instanceof GenericArrayType) { 883beaaaff52598e849659281fed35dc29a221fac4limpbizkit GenericArrayType g = (GenericArrayType) type; 893beaaaff52598e849659281fed35dc29a221fac4limpbizkit return Types.arrayOf(g.getGenericComponentType()); 903beaaaff52598e849659281fed35dc29a221fac4limpbizkit 913beaaaff52598e849659281fed35dc29a221fac4limpbizkit } else if (type instanceof Class<?> && ((Class<?>) type).isArray()) { 923beaaaff52598e849659281fed35dc29a221fac4limpbizkit Class<?> c = (Class<?>) type; 933beaaaff52598e849659281fed35dc29a221fac4limpbizkit return Types.arrayOf(c.getComponentType()); 943beaaaff52598e849659281fed35dc29a221fac4limpbizkit 953beaaaff52598e849659281fed35dc29a221fac4limpbizkit } else { 963beaaaff52598e849659281fed35dc29a221fac4limpbizkit // type is either serializable as-is or unsupported 973beaaaff52598e849659281fed35dc29a221fac4limpbizkit return type; 983beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 993beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 1003beaaaff52598e849659281fed35dc29a221fac4limpbizkit 101564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit /** 102564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit * Returns a type that's functionally equal but not necessarily equal 103564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit * according to {@link Object#equals(Object) Object.equals}. The returned 104564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit * member is {@link Serializable}. 105564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit */ 106564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit public static Member canonicalize(Member member) { 107564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit return member instanceof MemberImpl 108564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit ? member 109564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit : new MemberImpl(member); 110564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit } 111564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit 1123beaaaff52598e849659281fed35dc29a221fac4limpbizkit public static Class<?> getRawType(Type type) { 1133beaaaff52598e849659281fed35dc29a221fac4limpbizkit if (type instanceof Class<?>) { 1143beaaaff52598e849659281fed35dc29a221fac4limpbizkit // type is a normal class. 1153beaaaff52598e849659281fed35dc29a221fac4limpbizkit return (Class<?>) type; 1163beaaaff52598e849659281fed35dc29a221fac4limpbizkit 1173beaaaff52598e849659281fed35dc29a221fac4limpbizkit } else if (type instanceof ParameterizedType) { 1183beaaaff52598e849659281fed35dc29a221fac4limpbizkit ParameterizedType parameterizedType = (ParameterizedType) type; 1193beaaaff52598e849659281fed35dc29a221fac4limpbizkit 1203beaaaff52598e849659281fed35dc29a221fac4limpbizkit // I'm not exactly sure why getRawType() returns Type instead of Class. 1213beaaaff52598e849659281fed35dc29a221fac4limpbizkit // Neal isn't either but suspects some pathological case related 1223beaaaff52598e849659281fed35dc29a221fac4limpbizkit // to nested classes exists. 1233beaaaff52598e849659281fed35dc29a221fac4limpbizkit Type rawType = parameterizedType.getRawType(); 1243beaaaff52598e849659281fed35dc29a221fac4limpbizkit if (!(rawType instanceof Class<?>)) { 1253beaaaff52598e849659281fed35dc29a221fac4limpbizkit throw unexpectedType(rawType, Class.class); 1263beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 1273beaaaff52598e849659281fed35dc29a221fac4limpbizkit return (Class<?>) rawType; 1283beaaaff52598e849659281fed35dc29a221fac4limpbizkit 1293beaaaff52598e849659281fed35dc29a221fac4limpbizkit } else if (type instanceof GenericArrayType) { 1303beaaaff52598e849659281fed35dc29a221fac4limpbizkit // TODO: Is this sufficient? 1313beaaaff52598e849659281fed35dc29a221fac4limpbizkit return Object[].class; 1323beaaaff52598e849659281fed35dc29a221fac4limpbizkit 1333beaaaff52598e849659281fed35dc29a221fac4limpbizkit } else { 1343beaaaff52598e849659281fed35dc29a221fac4limpbizkit // type is a parameterized type. 1353beaaaff52598e849659281fed35dc29a221fac4limpbizkit throw unexpectedType(type, ParameterizedType.class); 1363beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 1373beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 1383beaaaff52598e849659281fed35dc29a221fac4limpbizkit 1393beaaaff52598e849659281fed35dc29a221fac4limpbizkit private static AssertionError unexpectedType(Type type, Class<?> expected) { 1403beaaaff52598e849659281fed35dc29a221fac4limpbizkit return new AssertionError( 1413beaaaff52598e849659281fed35dc29a221fac4limpbizkit "Unexpected type. Expected: " + expected.getName() 1423beaaaff52598e849659281fed35dc29a221fac4limpbizkit + ", got: " + type.getClass().getName() 1433beaaaff52598e849659281fed35dc29a221fac4limpbizkit + ", for type literal: " + type.toString() + "."); 1443beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 1453beaaaff52598e849659281fed35dc29a221fac4limpbizkit 1463beaaaff52598e849659281fed35dc29a221fac4limpbizkit /** 1473beaaaff52598e849659281fed35dc29a221fac4limpbizkit * Returns true if {@code a} and {@code b} are equal. 1483beaaaff52598e849659281fed35dc29a221fac4limpbizkit */ 1493beaaaff52598e849659281fed35dc29a221fac4limpbizkit public static boolean equals(Type a, Type b) { 1503beaaaff52598e849659281fed35dc29a221fac4limpbizkit if (a == b) { 1513beaaaff52598e849659281fed35dc29a221fac4limpbizkit // also handles (a == null && b == null) 1523beaaaff52598e849659281fed35dc29a221fac4limpbizkit return true; 1533beaaaff52598e849659281fed35dc29a221fac4limpbizkit 1543beaaaff52598e849659281fed35dc29a221fac4limpbizkit } else if (a instanceof Class) { 1553beaaaff52598e849659281fed35dc29a221fac4limpbizkit // Class already specifies equals(). 1563beaaaff52598e849659281fed35dc29a221fac4limpbizkit return a.equals(b); 1573beaaaff52598e849659281fed35dc29a221fac4limpbizkit 1583beaaaff52598e849659281fed35dc29a221fac4limpbizkit } else if (a instanceof ParameterizedType) { 1593beaaaff52598e849659281fed35dc29a221fac4limpbizkit if (!(b instanceof ParameterizedType)) { 1603beaaaff52598e849659281fed35dc29a221fac4limpbizkit return false; 1613beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 1623beaaaff52598e849659281fed35dc29a221fac4limpbizkit 1633beaaaff52598e849659281fed35dc29a221fac4limpbizkit ParameterizedType pa = (ParameterizedType) a; 1643beaaaff52598e849659281fed35dc29a221fac4limpbizkit ParameterizedType pb = (ParameterizedType) b; 1653beaaaff52598e849659281fed35dc29a221fac4limpbizkit return Objects.equal(pa.getOwnerType(), pb.getOwnerType()) 1663beaaaff52598e849659281fed35dc29a221fac4limpbizkit && pa.getRawType().equals(pb.getRawType()) 1673beaaaff52598e849659281fed35dc29a221fac4limpbizkit && Arrays.equals(pa.getActualTypeArguments(), pb.getActualTypeArguments()); 1683beaaaff52598e849659281fed35dc29a221fac4limpbizkit 1693beaaaff52598e849659281fed35dc29a221fac4limpbizkit } else if (a instanceof GenericArrayType) { 1703beaaaff52598e849659281fed35dc29a221fac4limpbizkit if (!(b instanceof GenericArrayType)) { 1713beaaaff52598e849659281fed35dc29a221fac4limpbizkit return false; 1723beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 1733beaaaff52598e849659281fed35dc29a221fac4limpbizkit 1743beaaaff52598e849659281fed35dc29a221fac4limpbizkit GenericArrayType ga = (GenericArrayType) a; 1753beaaaff52598e849659281fed35dc29a221fac4limpbizkit GenericArrayType gb = (GenericArrayType) b; 1763beaaaff52598e849659281fed35dc29a221fac4limpbizkit return equals(ga.getGenericComponentType(), gb.getGenericComponentType()); 1773beaaaff52598e849659281fed35dc29a221fac4limpbizkit 1783beaaaff52598e849659281fed35dc29a221fac4limpbizkit } else { 1793beaaaff52598e849659281fed35dc29a221fac4limpbizkit // This isn't a type we support. Could be a generic array type, wildcard 1803beaaaff52598e849659281fed35dc29a221fac4limpbizkit // type, etc. 1813beaaaff52598e849659281fed35dc29a221fac4limpbizkit return false; 1823beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 1833beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 1843beaaaff52598e849659281fed35dc29a221fac4limpbizkit 1853beaaaff52598e849659281fed35dc29a221fac4limpbizkit /** 1863beaaaff52598e849659281fed35dc29a221fac4limpbizkit * Returns the hashCode of {@code type}. 1873beaaaff52598e849659281fed35dc29a221fac4limpbizkit */ 1883beaaaff52598e849659281fed35dc29a221fac4limpbizkit public static int hashCode(Type type) { 1893beaaaff52598e849659281fed35dc29a221fac4limpbizkit if (type instanceof Class) { 1903beaaaff52598e849659281fed35dc29a221fac4limpbizkit // Class specifies hashCode(). 1913beaaaff52598e849659281fed35dc29a221fac4limpbizkit return type.hashCode(); 1923beaaaff52598e849659281fed35dc29a221fac4limpbizkit 1933beaaaff52598e849659281fed35dc29a221fac4limpbizkit } else if (type instanceof ParameterizedType) { 1943beaaaff52598e849659281fed35dc29a221fac4limpbizkit ParameterizedType p = (ParameterizedType) type; 1953beaaaff52598e849659281fed35dc29a221fac4limpbizkit return Arrays.hashCode(p.getActualTypeArguments()) 1963beaaaff52598e849659281fed35dc29a221fac4limpbizkit ^ p.getRawType().hashCode() 1973beaaaff52598e849659281fed35dc29a221fac4limpbizkit ^ hashCodeOrZero(p.getOwnerType()); 1983beaaaff52598e849659281fed35dc29a221fac4limpbizkit 1993beaaaff52598e849659281fed35dc29a221fac4limpbizkit } else if (type instanceof GenericArrayType) { 2003beaaaff52598e849659281fed35dc29a221fac4limpbizkit return hashCode(((GenericArrayType) type).getGenericComponentType()); 2013beaaaff52598e849659281fed35dc29a221fac4limpbizkit 2023beaaaff52598e849659281fed35dc29a221fac4limpbizkit } else { 2033beaaaff52598e849659281fed35dc29a221fac4limpbizkit // This isn't a type we support. Could be a generic array type, wildcard type, etc. 2043beaaaff52598e849659281fed35dc29a221fac4limpbizkit return hashCodeOrZero(type); 2053beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 2063beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 2073beaaaff52598e849659281fed35dc29a221fac4limpbizkit 2083beaaaff52598e849659281fed35dc29a221fac4limpbizkit private static int hashCodeOrZero(Object o) { 2093beaaaff52598e849659281fed35dc29a221fac4limpbizkit return o != null ? o.hashCode() : 0; 2103beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 2113beaaaff52598e849659281fed35dc29a221fac4limpbizkit 2123beaaaff52598e849659281fed35dc29a221fac4limpbizkit public static String toString(Type type) { 2133beaaaff52598e849659281fed35dc29a221fac4limpbizkit if (type instanceof Class<?>) { 2143beaaaff52598e849659281fed35dc29a221fac4limpbizkit return ((Class) type).getName(); 2153beaaaff52598e849659281fed35dc29a221fac4limpbizkit 2163beaaaff52598e849659281fed35dc29a221fac4limpbizkit } else if (type instanceof ParameterizedType) { 2173beaaaff52598e849659281fed35dc29a221fac4limpbizkit ParameterizedType parameterizedType = (ParameterizedType) type; 2183beaaaff52598e849659281fed35dc29a221fac4limpbizkit Type[] arguments = parameterizedType.getActualTypeArguments(); 2193beaaaff52598e849659281fed35dc29a221fac4limpbizkit Type ownerType = parameterizedType.getOwnerType(); 2203beaaaff52598e849659281fed35dc29a221fac4limpbizkit StringBuilder stringBuilder = new StringBuilder(); 2213beaaaff52598e849659281fed35dc29a221fac4limpbizkit if (ownerType != null) { 2223beaaaff52598e849659281fed35dc29a221fac4limpbizkit stringBuilder.append(toString(ownerType)).append("."); 2233beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 2243beaaaff52598e849659281fed35dc29a221fac4limpbizkit stringBuilder.append(toString(parameterizedType.getRawType())) 2253beaaaff52598e849659281fed35dc29a221fac4limpbizkit .append("<") 2263beaaaff52598e849659281fed35dc29a221fac4limpbizkit .append(toString(arguments[0])); 2273beaaaff52598e849659281fed35dc29a221fac4limpbizkit for (int i = 1; i < arguments.length; i++) { 2283beaaaff52598e849659281fed35dc29a221fac4limpbizkit stringBuilder.append(", ").append(toString(arguments[i])); 2293beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 2303beaaaff52598e849659281fed35dc29a221fac4limpbizkit return stringBuilder.append(">").toString(); 2313beaaaff52598e849659281fed35dc29a221fac4limpbizkit 2323beaaaff52598e849659281fed35dc29a221fac4limpbizkit } else if (type instanceof GenericArrayType) { 2333beaaaff52598e849659281fed35dc29a221fac4limpbizkit return toString(((GenericArrayType) type).getGenericComponentType()) + "[]"; 2343beaaaff52598e849659281fed35dc29a221fac4limpbizkit 2353beaaaff52598e849659281fed35dc29a221fac4limpbizkit } else { 2363beaaaff52598e849659281fed35dc29a221fac4limpbizkit return type.toString(); 2373beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 2383beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 2393beaaaff52598e849659281fed35dc29a221fac4limpbizkit 240564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit /** 241564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit * Returns {@code Field.class}, {@code Method.class} or {@code Constructor.class}. 242564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit */ 243564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit public static Class<? extends Member> memberType(Member member) { 244564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit checkNotNull(member, "member"); 245564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit 246564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit if (member instanceof MemberImpl) { 247564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit return ((MemberImpl) member).memberType; 248564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit 249564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit } else if (member instanceof Field) { 250564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit return Field.class; 251564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit 252564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit } else if (member instanceof Method) { 253564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit return Method.class; 254564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit 255564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit } else if (member instanceof Constructor) { 256564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit return Constructor.class; 257564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit 258564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit } else { 259564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit throw new IllegalArgumentException( 260564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit "Unsupported implementation class for Member, " + member.getClass()); 261564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit } 262564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit } 263564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit 264564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit public static String memberKey(Member member) { 265564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit checkNotNull(member, "member"); 266564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit 267564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit if (member instanceof MemberImpl) { 268564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit return ((MemberImpl) member).memberKey; 269564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit 270564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit } else if (member instanceof Field) { 271564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit return member.getName(); 272564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit 273564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit } else if (member instanceof Method) { 274564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit return member.getName() + org.objectweb.asm.Type.getMethodDescriptor((Method) member); 275564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit 276564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit } else if (member instanceof Constructor) { 277564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit StringBuilder sb = new StringBuilder().append("<init>("); 278564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit for (Class param : ((Constructor) member).getParameterTypes()) { 279564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit sb.append(org.objectweb.asm.Type.getDescriptor(param)); 280564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit } 281564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit return sb.append(")V").toString(); 282564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit 283564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit } else { 284564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit throw new IllegalArgumentException( 285564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit "Unsupported implementation class for Member, " + member.getClass()); 286564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit } 287564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit } 288564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit 2893beaaaff52598e849659281fed35dc29a221fac4limpbizkit public static class ParameterizedTypeImpl implements ParameterizedType, Serializable { 2903beaaaff52598e849659281fed35dc29a221fac4limpbizkit private final Type ownerType; 2913beaaaff52598e849659281fed35dc29a221fac4limpbizkit private final Type rawType; 2923beaaaff52598e849659281fed35dc29a221fac4limpbizkit private final Type[] typeArguments; 2933beaaaff52598e849659281fed35dc29a221fac4limpbizkit 2943beaaaff52598e849659281fed35dc29a221fac4limpbizkit public ParameterizedTypeImpl(Type ownerType, Type rawType, Type... typeArguments) { 29549f67c0f62bc1748dd32e1d86616085231e974e7limpbizkit // require an owner type if the raw type needs it 29649f67c0f62bc1748dd32e1d86616085231e974e7limpbizkit if (rawType instanceof Class<?>) { 29749f67c0f62bc1748dd32e1d86616085231e974e7limpbizkit Class rawTypeAsClass = (Class) rawType; 29849f67c0f62bc1748dd32e1d86616085231e974e7limpbizkit checkArgument(ownerType != null || rawTypeAsClass.getEnclosingClass() == null, 29949f67c0f62bc1748dd32e1d86616085231e974e7limpbizkit "No owner type for enclosed %s", rawType); 30049f67c0f62bc1748dd32e1d86616085231e974e7limpbizkit checkArgument(ownerType == null || rawTypeAsClass.getEnclosingClass() != null, 30149f67c0f62bc1748dd32e1d86616085231e974e7limpbizkit "Owner type for unenclosed %s", rawType); 30249f67c0f62bc1748dd32e1d86616085231e974e7limpbizkit } 30349f67c0f62bc1748dd32e1d86616085231e974e7limpbizkit 3043beaaaff52598e849659281fed35dc29a221fac4limpbizkit this.ownerType = ownerType == null ? null : canonicalize(ownerType); 3053beaaaff52598e849659281fed35dc29a221fac4limpbizkit this.rawType = canonicalize(rawType); 3063beaaaff52598e849659281fed35dc29a221fac4limpbizkit this.typeArguments = typeArguments.clone(); 3073beaaaff52598e849659281fed35dc29a221fac4limpbizkit for (int t = 0; t < this.typeArguments.length; t++) { 30849f67c0f62bc1748dd32e1d86616085231e974e7limpbizkit checkArgument(!(this.typeArguments[t] instanceof Class<?>) 3093beaaaff52598e849659281fed35dc29a221fac4limpbizkit || !((Class) this.typeArguments[t]).isPrimitive(), 3103beaaaff52598e849659281fed35dc29a221fac4limpbizkit "Parameterized types may not have primitive arguments: %s", this.typeArguments[t]); 3113beaaaff52598e849659281fed35dc29a221fac4limpbizkit this.typeArguments[t] = canonicalize(this.typeArguments[t]); 3123beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 3133beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 3143beaaaff52598e849659281fed35dc29a221fac4limpbizkit 3153beaaaff52598e849659281fed35dc29a221fac4limpbizkit public Type[] getActualTypeArguments() { 3163beaaaff52598e849659281fed35dc29a221fac4limpbizkit return typeArguments.clone(); 3173beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 3183beaaaff52598e849659281fed35dc29a221fac4limpbizkit 3193beaaaff52598e849659281fed35dc29a221fac4limpbizkit public Type getRawType() { 3203beaaaff52598e849659281fed35dc29a221fac4limpbizkit return rawType; 3213beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 3223beaaaff52598e849659281fed35dc29a221fac4limpbizkit 3233beaaaff52598e849659281fed35dc29a221fac4limpbizkit public Type getOwnerType() { 3243beaaaff52598e849659281fed35dc29a221fac4limpbizkit return ownerType; 3253beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 3263beaaaff52598e849659281fed35dc29a221fac4limpbizkit 3273beaaaff52598e849659281fed35dc29a221fac4limpbizkit @Override public boolean equals(Object other) { 3283beaaaff52598e849659281fed35dc29a221fac4limpbizkit return other instanceof ParameterizedType 3293beaaaff52598e849659281fed35dc29a221fac4limpbizkit && MoreTypes.equals(this, (ParameterizedType) other); 3303beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 3313beaaaff52598e849659281fed35dc29a221fac4limpbizkit 3323beaaaff52598e849659281fed35dc29a221fac4limpbizkit @Override public int hashCode() { 3333beaaaff52598e849659281fed35dc29a221fac4limpbizkit return MoreTypes.hashCode(this); 3343beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 3353beaaaff52598e849659281fed35dc29a221fac4limpbizkit 3363beaaaff52598e849659281fed35dc29a221fac4limpbizkit @Override public String toString() { 3373beaaaff52598e849659281fed35dc29a221fac4limpbizkit return MoreTypes.toString(this); 3383beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 3393beaaaff52598e849659281fed35dc29a221fac4limpbizkit 3403beaaaff52598e849659281fed35dc29a221fac4limpbizkit private static final long serialVersionUID = 0; 3413beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 3423beaaaff52598e849659281fed35dc29a221fac4limpbizkit 3433beaaaff52598e849659281fed35dc29a221fac4limpbizkit public static class GenericArrayTypeImpl implements GenericArrayType, Serializable { 3443beaaaff52598e849659281fed35dc29a221fac4limpbizkit private final Type componentType; 3453beaaaff52598e849659281fed35dc29a221fac4limpbizkit 3463beaaaff52598e849659281fed35dc29a221fac4limpbizkit public GenericArrayTypeImpl(Type componentType) { 3473beaaaff52598e849659281fed35dc29a221fac4limpbizkit this.componentType = canonicalize(componentType); 3483beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 3493beaaaff52598e849659281fed35dc29a221fac4limpbizkit 3503beaaaff52598e849659281fed35dc29a221fac4limpbizkit public Type getGenericComponentType() { 3513beaaaff52598e849659281fed35dc29a221fac4limpbizkit return componentType; 3523beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 3533beaaaff52598e849659281fed35dc29a221fac4limpbizkit 3543beaaaff52598e849659281fed35dc29a221fac4limpbizkit @Override public boolean equals(Object o) { 3553beaaaff52598e849659281fed35dc29a221fac4limpbizkit return o instanceof GenericArrayType 3563beaaaff52598e849659281fed35dc29a221fac4limpbizkit && MoreTypes.equals(this, (GenericArrayType) o); 3573beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 3583beaaaff52598e849659281fed35dc29a221fac4limpbizkit 3593beaaaff52598e849659281fed35dc29a221fac4limpbizkit @Override public int hashCode() { 3603beaaaff52598e849659281fed35dc29a221fac4limpbizkit return MoreTypes.hashCode(this); 3613beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 3623beaaaff52598e849659281fed35dc29a221fac4limpbizkit 3633beaaaff52598e849659281fed35dc29a221fac4limpbizkit @Override public String toString() { 3643beaaaff52598e849659281fed35dc29a221fac4limpbizkit return MoreTypes.toString(this); 3653beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 3663beaaaff52598e849659281fed35dc29a221fac4limpbizkit 3673beaaaff52598e849659281fed35dc29a221fac4limpbizkit private static final long serialVersionUID = 0; 3683beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 369564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit 370564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit /** 371564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit * We cannot serialize the built-in Java member classes, which prevents us from using Members in 372564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit * our exception types. We workaround this with this serializable implementation. It includes all 373564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit * of the API methods, plus everything we use for line numbers and messaging. 374564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit */ 375564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit public static class MemberImpl implements Member, Serializable { 376564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit private final Class<?> declaringClass; 377564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit private final String name; 378564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit private final int modifiers; 379564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit private final boolean synthetic; 380564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit private final Class<? extends Member> memberType; 381564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit private final String memberKey; 382564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit 383564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit private MemberImpl(Member member) { 384564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit this.declaringClass = member.getDeclaringClass(); 385564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit this.name = member.getName(); 386564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit this.modifiers = member.getModifiers(); 387564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit this.synthetic = member.isSynthetic(); 388564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit this.memberType = memberType(member); 389564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit this.memberKey = memberKey(member); 390564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit } 391564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit 392564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit public Class getDeclaringClass() { 393564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit return declaringClass; 394564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit } 395564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit 396564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit public String getName() { 397564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit return name; 398564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit } 399564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit 400564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit public int getModifiers() { 401564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit return modifiers; 402564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit } 403564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit 404564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit public boolean isSynthetic() { 405564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit return synthetic; 406564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit } 407564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit 408564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit @Override public String toString() { 409564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit if (memberType == Method.class) { 410564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit return "method " + getDeclaringClass().getName() + "." + getName() + "()"; 411564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit } else if (memberType == Field.class) { 412564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit return "field " + getDeclaringClass().getName() + "." + getName(); 413564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit } else if (memberType == Constructor.class) { 414564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit return "constructor " + getDeclaringClass().getName() + "()"; 415564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit } else { 416564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit throw new AssertionError(); 417564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit } 418564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit } 419564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit } 4203beaaaff52598e849659281fed35dc29a221fac4limpbizkit} 421