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 20d9c913acca55023ef5d76a32c3d4a51ee6b420cbsberlinimport static com.google.common.base.Preconditions.checkArgument; 21d9c913acca55023ef5d76a32c3d4a51ee6b420cbsberlinimport static com.google.common.base.Preconditions.checkNotNull; 22b7a02b02d81c830d148355c90bc309bcd66fb592sberlin 23b7a02b02d81c830d148355c90bc309bcd66fb592sberlinimport com.google.common.base.Objects; 24b7a02b02d81c830d148355c90bc309bcd66fb592sberlinimport com.google.common.collect.ImmutableMap; 25b7a02b02d81c830d148355c90bc309bcd66fb592sberlinimport com.google.inject.ConfigurationException; 26825f8c1df885b9d7643a9e18e336984f0138edafsamebimport com.google.inject.Key; 27b7a02b02d81c830d148355c90bc309bcd66fb592sberlinimport com.google.inject.TypeLiteral; 28365f83483b550d95bae2f90bc16439d24713a124limpbizkitimport com.google.inject.util.Types; 29b7a02b02d81c830d148355c90bc309bcd66fb592sberlin 303beaaaff52598e849659281fed35dc29a221fac4limpbizkitimport java.io.Serializable; 310bd3bd643f04f955bdb99e66375d4ee23131aa6dlimpbizkitimport java.lang.reflect.Array; 323beaaaff52598e849659281fed35dc29a221fac4limpbizkitimport java.lang.reflect.GenericArrayType; 334f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkitimport java.lang.reflect.GenericDeclaration; 343beaaaff52598e849659281fed35dc29a221fac4limpbizkitimport java.lang.reflect.ParameterizedType; 353beaaaff52598e849659281fed35dc29a221fac4limpbizkitimport java.lang.reflect.Type; 364f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkitimport java.lang.reflect.TypeVariable; 37cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkitimport java.lang.reflect.WildcardType; 383beaaaff52598e849659281fed35dc29a221fac4limpbizkitimport java.util.Arrays; 393beaaaff52598e849659281fed35dc29a221fac4limpbizkitimport java.util.Map; 404f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkitimport java.util.NoSuchElementException; 413beaaaff52598e849659281fed35dc29a221fac4limpbizkit 423beaaaff52598e849659281fed35dc29a221fac4limpbizkit/** 433beaaaff52598e849659281fed35dc29a221fac4limpbizkit * Static methods for working with types that we aren't publishing in the 443beaaaff52598e849659281fed35dc29a221fac4limpbizkit * public {@code Types} API. 453beaaaff52598e849659281fed35dc29a221fac4limpbizkit * 463beaaaff52598e849659281fed35dc29a221fac4limpbizkit * @author jessewilson@google.com (Jesse Wilson) 473beaaaff52598e849659281fed35dc29a221fac4limpbizkit */ 483beaaaff52598e849659281fed35dc29a221fac4limpbizkitpublic class MoreTypes { 49cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit 50cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit public static final Type[] EMPTY_TYPE_ARRAY = new Type[] {}; 51cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit 523beaaaff52598e849659281fed35dc29a221fac4limpbizkit private MoreTypes() {} 533beaaaff52598e849659281fed35dc29a221fac4limpbizkit 543beaaaff52598e849659281fed35dc29a221fac4limpbizkit private static final Map<TypeLiteral<?>, TypeLiteral<?>> PRIMITIVE_TO_WRAPPER 553beaaaff52598e849659281fed35dc29a221fac4limpbizkit = new ImmutableMap.Builder<TypeLiteral<?>, TypeLiteral<?>>() 563beaaaff52598e849659281fed35dc29a221fac4limpbizkit .put(TypeLiteral.get(boolean.class), TypeLiteral.get(Boolean.class)) 573beaaaff52598e849659281fed35dc29a221fac4limpbizkit .put(TypeLiteral.get(byte.class), TypeLiteral.get(Byte.class)) 583beaaaff52598e849659281fed35dc29a221fac4limpbizkit .put(TypeLiteral.get(short.class), TypeLiteral.get(Short.class)) 593beaaaff52598e849659281fed35dc29a221fac4limpbizkit .put(TypeLiteral.get(int.class), TypeLiteral.get(Integer.class)) 603beaaaff52598e849659281fed35dc29a221fac4limpbizkit .put(TypeLiteral.get(long.class), TypeLiteral.get(Long.class)) 613beaaaff52598e849659281fed35dc29a221fac4limpbizkit .put(TypeLiteral.get(float.class), TypeLiteral.get(Float.class)) 623beaaaff52598e849659281fed35dc29a221fac4limpbizkit .put(TypeLiteral.get(double.class), TypeLiteral.get(Double.class)) 633beaaaff52598e849659281fed35dc29a221fac4limpbizkit .put(TypeLiteral.get(char.class), TypeLiteral.get(Character.class)) 643beaaaff52598e849659281fed35dc29a221fac4limpbizkit .put(TypeLiteral.get(void.class), TypeLiteral.get(Void.class)) 653beaaaff52598e849659281fed35dc29a221fac4limpbizkit .build(); 663beaaaff52598e849659281fed35dc29a221fac4limpbizkit 673beaaaff52598e849659281fed35dc29a221fac4limpbizkit /** 68825f8c1df885b9d7643a9e18e336984f0138edafsameb * Returns a key that doesn't hold any references to parent classes. 69825f8c1df885b9d7643a9e18e336984f0138edafsameb * This is necessary for anonymous keys, so ensure we don't hold a ref 70825f8c1df885b9d7643a9e18e336984f0138edafsameb * to the containing module (or class) forever. 71825f8c1df885b9d7643a9e18e336984f0138edafsameb */ 72825f8c1df885b9d7643a9e18e336984f0138edafsameb public static <T> Key<T> canonicalizeKey(Key<T> key) { 73825f8c1df885b9d7643a9e18e336984f0138edafsameb // If we know this isn't a subclass, return as-is. 74825f8c1df885b9d7643a9e18e336984f0138edafsameb // Otherwise, recreate the key to avoid the subclass 75825f8c1df885b9d7643a9e18e336984f0138edafsameb if (key.getClass() == Key.class) { 76825f8c1df885b9d7643a9e18e336984f0138edafsameb return key; 77825f8c1df885b9d7643a9e18e336984f0138edafsameb } else if (key.getAnnotation() != null) { 78825f8c1df885b9d7643a9e18e336984f0138edafsameb return Key.get(key.getTypeLiteral(), key.getAnnotation()); 79825f8c1df885b9d7643a9e18e336984f0138edafsameb } else if (key.getAnnotationType() != null) { 80825f8c1df885b9d7643a9e18e336984f0138edafsameb return Key.get(key.getTypeLiteral(), key.getAnnotationType()); 81825f8c1df885b9d7643a9e18e336984f0138edafsameb } else { 82825f8c1df885b9d7643a9e18e336984f0138edafsameb return Key.get(key.getTypeLiteral()); 83825f8c1df885b9d7643a9e18e336984f0138edafsameb } 84825f8c1df885b9d7643a9e18e336984f0138edafsameb } 85825f8c1df885b9d7643a9e18e336984f0138edafsameb 86825f8c1df885b9d7643a9e18e336984f0138edafsameb /** 87365f83483b550d95bae2f90bc16439d24713a124limpbizkit * Returns an type that's appropriate for use in a key. 88365f83483b550d95bae2f90bc16439d24713a124limpbizkit * 89365f83483b550d95bae2f90bc16439d24713a124limpbizkit * <p>If the raw type of {@code typeLiteral} is a {@code javax.inject.Provider}, this returns a 90365f83483b550d95bae2f90bc16439d24713a124limpbizkit * {@code com.google.inject.Provider} with the same type parameters. 91365f83483b550d95bae2f90bc16439d24713a124limpbizkit * 92365f83483b550d95bae2f90bc16439d24713a124limpbizkit * <p>If the type is a primitive, the corresponding wrapper type will be returned. 934272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit * 944272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit * @throws ConfigurationException if {@code type} contains a type variable 953beaaaff52598e849659281fed35dc29a221fac4limpbizkit */ 96365f83483b550d95bae2f90bc16439d24713a124limpbizkit public static <T> TypeLiteral<T> canonicalizeForKey(TypeLiteral<T> typeLiteral) { 97365f83483b550d95bae2f90bc16439d24713a124limpbizkit Type type = typeLiteral.getType(); 98365f83483b550d95bae2f90bc16439d24713a124limpbizkit if (!isFullySpecified(type)) { 993748e4a0979e6332ab9f0a3601ab5b8e595b7a12sberlin Errors errors = new Errors().keyNotFullySpecified(typeLiteral); 1003748e4a0979e6332ab9f0a3601ab5b8e595b7a12sberlin throw new ConfigurationException(errors.getMessages()); 1014272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit } 1024272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit 103365f83483b550d95bae2f90bc16439d24713a124limpbizkit if (typeLiteral.getRawType() == javax.inject.Provider.class) { 104365f83483b550d95bae2f90bc16439d24713a124limpbizkit ParameterizedType parameterizedType = (ParameterizedType) type; 105365f83483b550d95bae2f90bc16439d24713a124limpbizkit 106365f83483b550d95bae2f90bc16439d24713a124limpbizkit // the following casts are generally unsafe, but com.google.inject.Provider extends 107365f83483b550d95bae2f90bc16439d24713a124limpbizkit // javax.inject.Provider and is covariant 108365f83483b550d95bae2f90bc16439d24713a124limpbizkit @SuppressWarnings("unchecked") 109365f83483b550d95bae2f90bc16439d24713a124limpbizkit TypeLiteral<T> guiceProviderType = (TypeLiteral<T>) TypeLiteral.get( 110365f83483b550d95bae2f90bc16439d24713a124limpbizkit Types.providerOf(parameterizedType.getActualTypeArguments()[0])); 111365f83483b550d95bae2f90bc16439d24713a124limpbizkit return guiceProviderType; 112365f83483b550d95bae2f90bc16439d24713a124limpbizkit } 113365f83483b550d95bae2f90bc16439d24713a124limpbizkit 1143beaaaff52598e849659281fed35dc29a221fac4limpbizkit @SuppressWarnings("unchecked") 115365f83483b550d95bae2f90bc16439d24713a124limpbizkit TypeLiteral<T> wrappedPrimitives = (TypeLiteral<T>) PRIMITIVE_TO_WRAPPER.get(typeLiteral); 116825f8c1df885b9d7643a9e18e336984f0138edafsameb if (wrappedPrimitives != null) { 117825f8c1df885b9d7643a9e18e336984f0138edafsameb return wrappedPrimitives; 118825f8c1df885b9d7643a9e18e336984f0138edafsameb } 119825f8c1df885b9d7643a9e18e336984f0138edafsameb 120825f8c1df885b9d7643a9e18e336984f0138edafsameb // If we know this isn't a subclass, return as-is. 121825f8c1df885b9d7643a9e18e336984f0138edafsameb if (typeLiteral.getClass() == TypeLiteral.class) { 122825f8c1df885b9d7643a9e18e336984f0138edafsameb return typeLiteral; 123825f8c1df885b9d7643a9e18e336984f0138edafsameb } 124825f8c1df885b9d7643a9e18e336984f0138edafsameb 125825f8c1df885b9d7643a9e18e336984f0138edafsameb // recreate the TypeLiteral to avoid anonymous TypeLiterals from holding refs to their 126825f8c1df885b9d7643a9e18e336984f0138edafsameb // surrounding classes. 127825f8c1df885b9d7643a9e18e336984f0138edafsameb @SuppressWarnings("unchecked") 128825f8c1df885b9d7643a9e18e336984f0138edafsameb TypeLiteral<T> recreated = (TypeLiteral<T>) TypeLiteral.get(typeLiteral.getType()); 129825f8c1df885b9d7643a9e18e336984f0138edafsameb return recreated; 1304272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit } 1314272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit 1324272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit /** 1334272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit * Returns true if {@code type} is free from type variables. 1344272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit */ 1354272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit private static boolean isFullySpecified(Type type) { 1364272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit if (type instanceof Class) { 1374272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit return true; 1384272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit 1394272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit } else if (type instanceof CompositeType) { 1404272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit return ((CompositeType) type).isFullySpecified(); 1414272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit 1424272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit } else if (type instanceof TypeVariable){ 1434272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit return false; 1444272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit 1454272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit } else { 1464272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit return ((CompositeType) canonicalize(type)).isFullySpecified(); 1474272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit } 1483beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 1493beaaaff52598e849659281fed35dc29a221fac4limpbizkit 1503beaaaff52598e849659281fed35dc29a221fac4limpbizkit /** 1513beaaaff52598e849659281fed35dc29a221fac4limpbizkit * Returns a type that is functionally equal but not necessarily equal 1523beaaaff52598e849659281fed35dc29a221fac4limpbizkit * according to {@link Object#equals(Object) Object.equals()}. The returned 1533beaaaff52598e849659281fed35dc29a221fac4limpbizkit * type is {@link Serializable}. 1543beaaaff52598e849659281fed35dc29a221fac4limpbizkit */ 1553beaaaff52598e849659281fed35dc29a221fac4limpbizkit public static Type canonicalize(Type type) { 1563ea8095def50d99f8f8a49c0fa6cc25e82217109limpbizkit if (type instanceof Class) { 1573ea8095def50d99f8f8a49c0fa6cc25e82217109limpbizkit Class<?> c = (Class<?>) type; 1583ea8095def50d99f8f8a49c0fa6cc25e82217109limpbizkit return c.isArray() ? new GenericArrayTypeImpl(canonicalize(c.getComponentType())) : c; 1593ea8095def50d99f8f8a49c0fa6cc25e82217109limpbizkit 1603ea8095def50d99f8f8a49c0fa6cc25e82217109limpbizkit } else if (type instanceof CompositeType) { 1613beaaaff52598e849659281fed35dc29a221fac4limpbizkit return type; 1623beaaaff52598e849659281fed35dc29a221fac4limpbizkit 1633beaaaff52598e849659281fed35dc29a221fac4limpbizkit } else if (type instanceof ParameterizedType) { 1643beaaaff52598e849659281fed35dc29a221fac4limpbizkit ParameterizedType p = (ParameterizedType) type; 165cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit return new ParameterizedTypeImpl(p.getOwnerType(), 1663beaaaff52598e849659281fed35dc29a221fac4limpbizkit p.getRawType(), p.getActualTypeArguments()); 1673beaaaff52598e849659281fed35dc29a221fac4limpbizkit 1683beaaaff52598e849659281fed35dc29a221fac4limpbizkit } else if (type instanceof GenericArrayType) { 1693beaaaff52598e849659281fed35dc29a221fac4limpbizkit GenericArrayType g = (GenericArrayType) type; 170cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit return new GenericArrayTypeImpl(g.getGenericComponentType()); 1713beaaaff52598e849659281fed35dc29a221fac4limpbizkit 172cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit } else if (type instanceof WildcardType) { 173cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit WildcardType w = (WildcardType) type; 174cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit return new WildcardTypeImpl(w.getUpperBounds(), w.getLowerBounds()); 1753beaaaff52598e849659281fed35dc29a221fac4limpbizkit 1763beaaaff52598e849659281fed35dc29a221fac4limpbizkit } else { 1773beaaaff52598e849659281fed35dc29a221fac4limpbizkit // type is either serializable as-is or unsupported 1783beaaaff52598e849659281fed35dc29a221fac4limpbizkit return type; 1793beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 1803beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 1813beaaaff52598e849659281fed35dc29a221fac4limpbizkit 1823beaaaff52598e849659281fed35dc29a221fac4limpbizkit public static Class<?> getRawType(Type type) { 1833beaaaff52598e849659281fed35dc29a221fac4limpbizkit if (type instanceof Class<?>) { 1843beaaaff52598e849659281fed35dc29a221fac4limpbizkit // type is a normal class. 1853beaaaff52598e849659281fed35dc29a221fac4limpbizkit return (Class<?>) type; 1863beaaaff52598e849659281fed35dc29a221fac4limpbizkit 1873beaaaff52598e849659281fed35dc29a221fac4limpbizkit } else if (type instanceof ParameterizedType) { 1883beaaaff52598e849659281fed35dc29a221fac4limpbizkit ParameterizedType parameterizedType = (ParameterizedType) type; 1893beaaaff52598e849659281fed35dc29a221fac4limpbizkit 1903beaaaff52598e849659281fed35dc29a221fac4limpbizkit // I'm not exactly sure why getRawType() returns Type instead of Class. 1913beaaaff52598e849659281fed35dc29a221fac4limpbizkit // Neal isn't either but suspects some pathological case related 1923beaaaff52598e849659281fed35dc29a221fac4limpbizkit // to nested classes exists. 1933beaaaff52598e849659281fed35dc29a221fac4limpbizkit Type rawType = parameterizedType.getRawType(); 194cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit checkArgument(rawType instanceof Class, 195cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit "Expected a Class, but <%s> is of type %s", type, type.getClass().getName()); 1963beaaaff52598e849659281fed35dc29a221fac4limpbizkit return (Class<?>) rawType; 1973beaaaff52598e849659281fed35dc29a221fac4limpbizkit 1983beaaaff52598e849659281fed35dc29a221fac4limpbizkit } else if (type instanceof GenericArrayType) { 1990bd3bd643f04f955bdb99e66375d4ee23131aa6dlimpbizkit Type componentType = ((GenericArrayType)type).getGenericComponentType(); 2000bd3bd643f04f955bdb99e66375d4ee23131aa6dlimpbizkit return Array.newInstance(getRawType(componentType), 0).getClass(); 2013beaaaff52598e849659281fed35dc29a221fac4limpbizkit 2024272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit } else if (type instanceof TypeVariable) { 2034272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit // we could use the variable's bounds, but that'll won't work if there are multiple. 2044272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit // having a raw type that's more general than necessary is okay 2054272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit return Object.class; 2064272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit 2073beaaaff52598e849659281fed35dc29a221fac4limpbizkit } else { 208cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit throw new IllegalArgumentException("Expected a Class, ParameterizedType, or " 209cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit + "GenericArrayType, but <" + type + "> is of type " + type.getClass().getName()); 2103beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 2113beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 2123beaaaff52598e849659281fed35dc29a221fac4limpbizkit 2133beaaaff52598e849659281fed35dc29a221fac4limpbizkit /** 2143beaaaff52598e849659281fed35dc29a221fac4limpbizkit * Returns true if {@code a} and {@code b} are equal. 2153beaaaff52598e849659281fed35dc29a221fac4limpbizkit */ 2163beaaaff52598e849659281fed35dc29a221fac4limpbizkit public static boolean equals(Type a, Type b) { 2173beaaaff52598e849659281fed35dc29a221fac4limpbizkit if (a == b) { 2183beaaaff52598e849659281fed35dc29a221fac4limpbizkit // also handles (a == null && b == null) 2193beaaaff52598e849659281fed35dc29a221fac4limpbizkit return true; 2203beaaaff52598e849659281fed35dc29a221fac4limpbizkit 2213beaaaff52598e849659281fed35dc29a221fac4limpbizkit } else if (a instanceof Class) { 2223beaaaff52598e849659281fed35dc29a221fac4limpbizkit // Class already specifies equals(). 2233beaaaff52598e849659281fed35dc29a221fac4limpbizkit return a.equals(b); 2243beaaaff52598e849659281fed35dc29a221fac4limpbizkit 2253beaaaff52598e849659281fed35dc29a221fac4limpbizkit } else if (a instanceof ParameterizedType) { 2263beaaaff52598e849659281fed35dc29a221fac4limpbizkit if (!(b instanceof ParameterizedType)) { 2273beaaaff52598e849659281fed35dc29a221fac4limpbizkit return false; 2283beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 2293beaaaff52598e849659281fed35dc29a221fac4limpbizkit 2304272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit // TODO: save a .clone() call 2313beaaaff52598e849659281fed35dc29a221fac4limpbizkit ParameterizedType pa = (ParameterizedType) a; 2323beaaaff52598e849659281fed35dc29a221fac4limpbizkit ParameterizedType pb = (ParameterizedType) b; 2333beaaaff52598e849659281fed35dc29a221fac4limpbizkit return Objects.equal(pa.getOwnerType(), pb.getOwnerType()) 2343beaaaff52598e849659281fed35dc29a221fac4limpbizkit && pa.getRawType().equals(pb.getRawType()) 2353beaaaff52598e849659281fed35dc29a221fac4limpbizkit && Arrays.equals(pa.getActualTypeArguments(), pb.getActualTypeArguments()); 2363beaaaff52598e849659281fed35dc29a221fac4limpbizkit 2373beaaaff52598e849659281fed35dc29a221fac4limpbizkit } else if (a instanceof GenericArrayType) { 2383beaaaff52598e849659281fed35dc29a221fac4limpbizkit if (!(b instanceof GenericArrayType)) { 2393beaaaff52598e849659281fed35dc29a221fac4limpbizkit return false; 2403beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 2413beaaaff52598e849659281fed35dc29a221fac4limpbizkit 2423beaaaff52598e849659281fed35dc29a221fac4limpbizkit GenericArrayType ga = (GenericArrayType) a; 2433beaaaff52598e849659281fed35dc29a221fac4limpbizkit GenericArrayType gb = (GenericArrayType) b; 2443beaaaff52598e849659281fed35dc29a221fac4limpbizkit return equals(ga.getGenericComponentType(), gb.getGenericComponentType()); 2453beaaaff52598e849659281fed35dc29a221fac4limpbizkit 246cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit } else if (a instanceof WildcardType) { 247cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit if (!(b instanceof WildcardType)) { 248cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit return false; 249cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit } 250cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit 251cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit WildcardType wa = (WildcardType) a; 252cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit WildcardType wb = (WildcardType) b; 253cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit return Arrays.equals(wa.getUpperBounds(), wb.getUpperBounds()) 254cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit && Arrays.equals(wa.getLowerBounds(), wb.getLowerBounds()); 255cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit 2564272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit } else if (a instanceof TypeVariable) { 2574272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit if (!(b instanceof TypeVariable)) { 2584272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit return false; 2594272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit } 2604272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit TypeVariable<?> va = (TypeVariable) a; 2614272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit TypeVariable<?> vb = (TypeVariable) b; 262978ed86a76b3c47e8247f6691586b994bcf13dbcChristian Edward Gruber return va.getGenericDeclaration().equals(vb.getGenericDeclaration()) 2634272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit && va.getName().equals(vb.getName()); 2644272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit 2653beaaaff52598e849659281fed35dc29a221fac4limpbizkit } else { 2664272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit // This isn't a type we support. Could be a generic array type, wildcard type, etc. 2673beaaaff52598e849659281fed35dc29a221fac4limpbizkit return false; 2683beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 2693beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 2703beaaaff52598e849659281fed35dc29a221fac4limpbizkit 2713beaaaff52598e849659281fed35dc29a221fac4limpbizkit private static int hashCodeOrZero(Object o) { 2723beaaaff52598e849659281fed35dc29a221fac4limpbizkit return o != null ? o.hashCode() : 0; 2733beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 2743beaaaff52598e849659281fed35dc29a221fac4limpbizkit 2753ea8095def50d99f8f8a49c0fa6cc25e82217109limpbizkit public static String typeToString(Type type) { 2763ea8095def50d99f8f8a49c0fa6cc25e82217109limpbizkit return type instanceof Class ? ((Class) type).getName() : type.toString(); 2773beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 2783beaaaff52598e849659281fed35dc29a221fac4limpbizkit 279564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit /** 28022de684ae3c7de50d59e1e3ec9a9ba4700483c1eSam Berlin * Returns the generic supertype for {@code type}. For example, given a class {@code IntegerSet}, 28122de684ae3c7de50d59e1e3ec9a9ba4700483c1eSam Berlin * the result for when supertype is {@code Set.class} is {@code Set<Integer>} and the result 28222de684ae3c7de50d59e1e3ec9a9ba4700483c1eSam Berlin * when the supertype is {@code Collection.class} is {@code Collection<Integer>}. 2834f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit */ 2844f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit public static Type getGenericSupertype(Type type, Class<?> rawType, Class<?> toResolve) { 2854f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit if (toResolve == rawType) { 2864f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit return type; 2874f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit } 2884f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit 2894f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit // we skip searching through interfaces if unknown is an interface 2904f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit if (toResolve.isInterface()) { 2914f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit Class[] interfaces = rawType.getInterfaces(); 2924f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit for (int i = 0, length = interfaces.length; i < length; i++) { 2934f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit if (interfaces[i] == toResolve) { 2944f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit return rawType.getGenericInterfaces()[i]; 2954f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit } else if (toResolve.isAssignableFrom(interfaces[i])) { 2964f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit return getGenericSupertype(rawType.getGenericInterfaces()[i], interfaces[i], toResolve); 2974f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit } 2984f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit } 2994f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit } 3004f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit 3014f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit // check our supertypes 3024f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit if (!rawType.isInterface()) { 3034f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit while (rawType != Object.class) { 3044f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit Class<?> rawSupertype = rawType.getSuperclass(); 3054f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit if (rawSupertype == toResolve) { 3064f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit return rawType.getGenericSuperclass(); 3074f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit } else if (toResolve.isAssignableFrom(rawSupertype)) { 3084f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit return getGenericSupertype(rawType.getGenericSuperclass(), rawSupertype, toResolve); 3094f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit } 3104f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit rawType = rawSupertype; 3114f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit } 3124f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit } 3134f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit 3144f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit // we can't resolve this further 3154f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit return toResolve; 3164f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit } 3174f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit 3184f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit public static Type resolveTypeVariable(Type type, Class<?> rawType, TypeVariable unknown) { 3194f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit Class<?> declaredByRaw = declaringClassOf(unknown); 3204f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit 3214f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit // we can't reduce this further 3224f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit if (declaredByRaw == null) { 3234f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit return unknown; 3244f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit } 3254f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit 3264f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit Type declaredBy = getGenericSupertype(type, rawType, declaredByRaw); 3274f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit if (declaredBy instanceof ParameterizedType) { 3284f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit int index = indexOf(declaredByRaw.getTypeParameters(), unknown); 3294f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit return ((ParameterizedType) declaredBy).getActualTypeArguments()[index]; 3304f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit } 3314f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit 3324f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit return unknown; 3334f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit } 3344f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit 3354f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit private static int indexOf(Object[] array, Object toFind) { 3364f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit for (int i = 0; i < array.length; i++) { 3374f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit if (toFind.equals(array[i])) { 3384f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit return i; 3394f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit } 3404f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit } 3414f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit throw new NoSuchElementException(); 3424f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit } 3434f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit 3444f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit /** 3454f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit * Returns the declaring class of {@code typeVariable}, or {@code null} if it was not declared by 3464f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit * a class. 3474f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit */ 3484f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit private static Class<?> declaringClassOf(TypeVariable typeVariable) { 3494f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit GenericDeclaration genericDeclaration = typeVariable.getGenericDeclaration(); 3504f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit return genericDeclaration instanceof Class 3514f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit ? (Class<?>) genericDeclaration 3524f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit : null; 3534f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit } 3544f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit 3554272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit public static class ParameterizedTypeImpl 3564272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit implements ParameterizedType, Serializable, CompositeType { 3573beaaaff52598e849659281fed35dc29a221fac4limpbizkit private final Type ownerType; 3583beaaaff52598e849659281fed35dc29a221fac4limpbizkit private final Type rawType; 3593beaaaff52598e849659281fed35dc29a221fac4limpbizkit private final Type[] typeArguments; 3603beaaaff52598e849659281fed35dc29a221fac4limpbizkit 3613beaaaff52598e849659281fed35dc29a221fac4limpbizkit public ParameterizedTypeImpl(Type ownerType, Type rawType, Type... typeArguments) { 36249f67c0f62bc1748dd32e1d86616085231e974e7limpbizkit // require an owner type if the raw type needs it 36360826c015781b1173c9f98c8c22f63324ede6390bulach ensureOwnerType(ownerType, rawType); 36449f67c0f62bc1748dd32e1d86616085231e974e7limpbizkit 3653beaaaff52598e849659281fed35dc29a221fac4limpbizkit this.ownerType = ownerType == null ? null : canonicalize(ownerType); 3663beaaaff52598e849659281fed35dc29a221fac4limpbizkit this.rawType = canonicalize(rawType); 3673beaaaff52598e849659281fed35dc29a221fac4limpbizkit this.typeArguments = typeArguments.clone(); 3683beaaaff52598e849659281fed35dc29a221fac4limpbizkit for (int t = 0; t < this.typeArguments.length; t++) { 369cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit checkNotNull(this.typeArguments[t], "type parameter"); 370cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit checkNotPrimitive(this.typeArguments[t], "type parameters"); 3713beaaaff52598e849659281fed35dc29a221fac4limpbizkit this.typeArguments[t] = canonicalize(this.typeArguments[t]); 3723beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 3733beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 3743beaaaff52598e849659281fed35dc29a221fac4limpbizkit 3753beaaaff52598e849659281fed35dc29a221fac4limpbizkit public Type[] getActualTypeArguments() { 3763beaaaff52598e849659281fed35dc29a221fac4limpbizkit return typeArguments.clone(); 3773beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 3783beaaaff52598e849659281fed35dc29a221fac4limpbizkit 3793beaaaff52598e849659281fed35dc29a221fac4limpbizkit public Type getRawType() { 3803beaaaff52598e849659281fed35dc29a221fac4limpbizkit return rawType; 3813beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 3823beaaaff52598e849659281fed35dc29a221fac4limpbizkit 3833beaaaff52598e849659281fed35dc29a221fac4limpbizkit public Type getOwnerType() { 3843beaaaff52598e849659281fed35dc29a221fac4limpbizkit return ownerType; 3853beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 3863beaaaff52598e849659281fed35dc29a221fac4limpbizkit 3874272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit public boolean isFullySpecified() { 3884272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit if (ownerType != null && !MoreTypes.isFullySpecified(ownerType)) { 3894272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit return false; 3904272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit } 3914272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit 3924272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit if (!MoreTypes.isFullySpecified(rawType)) { 3934272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit return false; 3944272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit } 3954272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit 3964272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit for (Type type : typeArguments) { 3974272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit if (!MoreTypes.isFullySpecified(type)) { 3984272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit return false; 3994272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit } 4004272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit } 4014272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit 4024272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit return true; 4034272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit } 4044272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit 4053beaaaff52598e849659281fed35dc29a221fac4limpbizkit @Override public boolean equals(Object other) { 4063beaaaff52598e849659281fed35dc29a221fac4limpbizkit return other instanceof ParameterizedType 4073beaaaff52598e849659281fed35dc29a221fac4limpbizkit && MoreTypes.equals(this, (ParameterizedType) other); 4083beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 4093beaaaff52598e849659281fed35dc29a221fac4limpbizkit 4103beaaaff52598e849659281fed35dc29a221fac4limpbizkit @Override public int hashCode() { 4113ea8095def50d99f8f8a49c0fa6cc25e82217109limpbizkit return Arrays.hashCode(typeArguments) 4123ea8095def50d99f8f8a49c0fa6cc25e82217109limpbizkit ^ rawType.hashCode() 4133ea8095def50d99f8f8a49c0fa6cc25e82217109limpbizkit ^ hashCodeOrZero(ownerType); 4143beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 4153beaaaff52598e849659281fed35dc29a221fac4limpbizkit 4163beaaaff52598e849659281fed35dc29a221fac4limpbizkit @Override public String toString() { 4173ea8095def50d99f8f8a49c0fa6cc25e82217109limpbizkit StringBuilder stringBuilder = new StringBuilder(30 * (typeArguments.length + 1)); 4183ea8095def50d99f8f8a49c0fa6cc25e82217109limpbizkit stringBuilder.append(typeToString(rawType)); 4192e8f7f9e9a7f3dbbebf76d3b64b0e668d1eb62casberlin 4202e8f7f9e9a7f3dbbebf76d3b64b0e668d1eb62casberlin if (typeArguments.length == 0) { 4212e8f7f9e9a7f3dbbebf76d3b64b0e668d1eb62casberlin return stringBuilder.toString(); 4222e8f7f9e9a7f3dbbebf76d3b64b0e668d1eb62casberlin } 4232e8f7f9e9a7f3dbbebf76d3b64b0e668d1eb62casberlin 4242e8f7f9e9a7f3dbbebf76d3b64b0e668d1eb62casberlin stringBuilder.append("<").append(typeToString(typeArguments[0])); 4252e8f7f9e9a7f3dbbebf76d3b64b0e668d1eb62casberlin for (int i = 1; i < typeArguments.length; i++) { 4262e8f7f9e9a7f3dbbebf76d3b64b0e668d1eb62casberlin stringBuilder.append(", ").append(typeToString(typeArguments[i])); 4273ea8095def50d99f8f8a49c0fa6cc25e82217109limpbizkit } 4283ea8095def50d99f8f8a49c0fa6cc25e82217109limpbizkit return stringBuilder.append(">").toString(); 4293beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 4303beaaaff52598e849659281fed35dc29a221fac4limpbizkit 43160826c015781b1173c9f98c8c22f63324ede6390bulach private static void ensureOwnerType(Type ownerType, Type rawType) { 43260826c015781b1173c9f98c8c22f63324ede6390bulach if (rawType instanceof Class<?>) { 43360826c015781b1173c9f98c8c22f63324ede6390bulach Class rawTypeAsClass = (Class) rawType; 43460826c015781b1173c9f98c8c22f63324ede6390bulach checkArgument(ownerType != null || rawTypeAsClass.getEnclosingClass() == null, 43560826c015781b1173c9f98c8c22f63324ede6390bulach "No owner type for enclosed %s", rawType); 43660826c015781b1173c9f98c8c22f63324ede6390bulach checkArgument(ownerType == null || rawTypeAsClass.getEnclosingClass() != null, 43760826c015781b1173c9f98c8c22f63324ede6390bulach "Owner type for unenclosed %s", rawType); 43860826c015781b1173c9f98c8c22f63324ede6390bulach } 43960826c015781b1173c9f98c8c22f63324ede6390bulach } 44060826c015781b1173c9f98c8c22f63324ede6390bulach 4413beaaaff52598e849659281fed35dc29a221fac4limpbizkit private static final long serialVersionUID = 0; 4423beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 4433beaaaff52598e849659281fed35dc29a221fac4limpbizkit 4444272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit public static class GenericArrayTypeImpl 4454272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit implements GenericArrayType, Serializable, CompositeType { 4463beaaaff52598e849659281fed35dc29a221fac4limpbizkit private final Type componentType; 4473beaaaff52598e849659281fed35dc29a221fac4limpbizkit 4483beaaaff52598e849659281fed35dc29a221fac4limpbizkit public GenericArrayTypeImpl(Type componentType) { 4493beaaaff52598e849659281fed35dc29a221fac4limpbizkit this.componentType = canonicalize(componentType); 4503beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 4513beaaaff52598e849659281fed35dc29a221fac4limpbizkit 4523beaaaff52598e849659281fed35dc29a221fac4limpbizkit public Type getGenericComponentType() { 4533beaaaff52598e849659281fed35dc29a221fac4limpbizkit return componentType; 4543beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 4553beaaaff52598e849659281fed35dc29a221fac4limpbizkit 4564272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit public boolean isFullySpecified() { 4574272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit return MoreTypes.isFullySpecified(componentType); 4584272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit } 4594272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit 4603beaaaff52598e849659281fed35dc29a221fac4limpbizkit @Override public boolean equals(Object o) { 4613beaaaff52598e849659281fed35dc29a221fac4limpbizkit return o instanceof GenericArrayType 4623beaaaff52598e849659281fed35dc29a221fac4limpbizkit && MoreTypes.equals(this, (GenericArrayType) o); 4633beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 4643beaaaff52598e849659281fed35dc29a221fac4limpbizkit 4653beaaaff52598e849659281fed35dc29a221fac4limpbizkit @Override public int hashCode() { 4663ea8095def50d99f8f8a49c0fa6cc25e82217109limpbizkit return componentType.hashCode(); 4673beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 4683beaaaff52598e849659281fed35dc29a221fac4limpbizkit 4693beaaaff52598e849659281fed35dc29a221fac4limpbizkit @Override public String toString() { 4703ea8095def50d99f8f8a49c0fa6cc25e82217109limpbizkit return typeToString(componentType) + "[]"; 4713beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 4723beaaaff52598e849659281fed35dc29a221fac4limpbizkit 4733beaaaff52598e849659281fed35dc29a221fac4limpbizkit private static final long serialVersionUID = 0; 4743beaaaff52598e849659281fed35dc29a221fac4limpbizkit } 475564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit 476564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit /** 477cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit * The WildcardType interface supports multiple upper bounds and multiple 478cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit * lower bounds. We only support what the Java 6 language needs - at most one 479cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit * bound. If a lower bound is set, the upper bound must be Object.class. 480cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit */ 4814272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit public static class WildcardTypeImpl implements WildcardType, Serializable, CompositeType { 482cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit private final Type upperBound; 483cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit private final Type lowerBound; 484cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit 485cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit public WildcardTypeImpl(Type[] upperBounds, Type[] lowerBounds) { 48659a6042697af2cceb2e3dc7b70246b841903eae6limpbizkit checkArgument(lowerBounds.length <= 1, "Must have at most one lower bound."); 487cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit checkArgument(upperBounds.length == 1, "Must have exactly one upper bound."); 488cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit 489cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit if (lowerBounds.length == 1) { 490cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit checkNotNull(lowerBounds[0], "lowerBound"); 491cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit checkNotPrimitive(lowerBounds[0], "wildcard bounds"); 492cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit checkArgument(upperBounds[0] == Object.class, "bounded both ways"); 493cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit this.lowerBound = canonicalize(lowerBounds[0]); 494cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit this.upperBound = Object.class; 495cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit 496cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit } else { 497cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit checkNotNull(upperBounds[0], "upperBound"); 498cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit checkNotPrimitive(upperBounds[0], "wildcard bounds"); 499cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit this.lowerBound = null; 500cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit this.upperBound = canonicalize(upperBounds[0]); 501cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit } 502cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit } 503cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit 504cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit public Type[] getUpperBounds() { 505cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit return new Type[] { upperBound }; 506cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit } 507cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit 508cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit public Type[] getLowerBounds() { 509cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit return lowerBound != null ? new Type[] { lowerBound } : EMPTY_TYPE_ARRAY; 510cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit } 511cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit 5124272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit public boolean isFullySpecified() { 5134272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit return MoreTypes.isFullySpecified(upperBound) 5144272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit && (lowerBound == null || MoreTypes.isFullySpecified(lowerBound)); 5154272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit } 5164272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit 517cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit @Override public boolean equals(Object other) { 518cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit return other instanceof WildcardType 519cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit && MoreTypes.equals(this, (WildcardType) other); 520cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit } 521cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit 522cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit @Override public int hashCode() { 5233ea8095def50d99f8f8a49c0fa6cc25e82217109limpbizkit // this equals Arrays.hashCode(getLowerBounds()) ^ Arrays.hashCode(getUpperBounds()); 5243ea8095def50d99f8f8a49c0fa6cc25e82217109limpbizkit return (lowerBound != null ? 31 + lowerBound.hashCode() : 1) 5253ea8095def50d99f8f8a49c0fa6cc25e82217109limpbizkit ^ (31 + upperBound.hashCode()); 526cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit } 527cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit 528cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit @Override public String toString() { 5293ea8095def50d99f8f8a49c0fa6cc25e82217109limpbizkit if (lowerBound != null) { 5303ea8095def50d99f8f8a49c0fa6cc25e82217109limpbizkit return "? super " + typeToString(lowerBound); 5313ea8095def50d99f8f8a49c0fa6cc25e82217109limpbizkit } else if (upperBound == Object.class) { 5323ea8095def50d99f8f8a49c0fa6cc25e82217109limpbizkit return "?"; 5333ea8095def50d99f8f8a49c0fa6cc25e82217109limpbizkit } else { 5343ea8095def50d99f8f8a49c0fa6cc25e82217109limpbizkit return "? extends " + typeToString(upperBound); 5353ea8095def50d99f8f8a49c0fa6cc25e82217109limpbizkit } 536cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit } 537cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit 538cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit private static final long serialVersionUID = 0; 539cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit } 540cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit 541cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit private static void checkNotPrimitive(Type type, String use) { 542cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit checkArgument(!(type instanceof Class<?>) || !((Class) type).isPrimitive(), 543cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit "Primitive types are not allowed in %s: %s", use, type); 544cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit } 545cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit 5464272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit /** A type formed from other types, such as arrays, parameterized types or wildcard types */ 5474272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit private interface CompositeType { 5484272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit /** Returns true if there are no type variables in this type. */ 5494272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit boolean isFullySpecified(); 5504272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit } 5513beaaaff52598e849659281fed35dc29a221fac4limpbizkit} 552