Types.java revision 7dd252788645e940eada959bdde927426e2531c9
17dd252788645e940eada959bdde927426e2531c9Paul Duffin/* 27dd252788645e940eada959bdde927426e2531c9Paul Duffin * Copyright (C) 2011 The Guava Authors 37dd252788645e940eada959bdde927426e2531c9Paul Duffin * 47dd252788645e940eada959bdde927426e2531c9Paul Duffin * Licensed under the Apache License, Version 2.0 (the "License"); 57dd252788645e940eada959bdde927426e2531c9Paul Duffin * you may not use this file except in compliance with the License. 67dd252788645e940eada959bdde927426e2531c9Paul Duffin * You may obtain a copy of the License at 77dd252788645e940eada959bdde927426e2531c9Paul Duffin * 87dd252788645e940eada959bdde927426e2531c9Paul Duffin * http://www.apache.org/licenses/LICENSE-2.0 97dd252788645e940eada959bdde927426e2531c9Paul Duffin * 107dd252788645e940eada959bdde927426e2531c9Paul Duffin * Unless required by applicable law or agreed to in writing, software 117dd252788645e940eada959bdde927426e2531c9Paul Duffin * distributed under the License is distributed on an "AS IS" BASIS, 127dd252788645e940eada959bdde927426e2531c9Paul Duffin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137dd252788645e940eada959bdde927426e2531c9Paul Duffin * See the License for the specific language governing permissions and 147dd252788645e940eada959bdde927426e2531c9Paul Duffin * limitations under the License. 157dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 167dd252788645e940eada959bdde927426e2531c9Paul Duffin 177dd252788645e940eada959bdde927426e2531c9Paul Duffinpackage com.google.common.reflect; 187dd252788645e940eada959bdde927426e2531c9Paul Duffin 197dd252788645e940eada959bdde927426e2531c9Paul Duffinimport static com.google.common.base.Preconditions.checkArgument; 207dd252788645e940eada959bdde927426e2531c9Paul Duffinimport static com.google.common.base.Preconditions.checkNotNull; 217dd252788645e940eada959bdde927426e2531c9Paul Duffinimport static com.google.common.collect.Iterables.transform; 227dd252788645e940eada959bdde927426e2531c9Paul Duffin 237dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.annotations.VisibleForTesting; 247dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.base.Function; 257dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.base.Joiner; 267dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.base.Objects; 277dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.base.Predicates; 287dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.ImmutableList; 297dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.Iterables; 307dd252788645e940eada959bdde927426e2531c9Paul Duffin 317dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.io.Serializable; 327dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.lang.reflect.Array; 337dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.lang.reflect.GenericArrayType; 347dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.lang.reflect.GenericDeclaration; 357dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.lang.reflect.ParameterizedType; 367dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.lang.reflect.Type; 377dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.lang.reflect.TypeVariable; 387dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.lang.reflect.WildcardType; 397dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Arrays; 407dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Collection; 417dd252788645e940eada959bdde927426e2531c9Paul Duffin 427dd252788645e940eada959bdde927426e2531c9Paul Duffinimport javax.annotation.Nullable; 437dd252788645e940eada959bdde927426e2531c9Paul Duffin 447dd252788645e940eada959bdde927426e2531c9Paul Duffin/** 457dd252788645e940eada959bdde927426e2531c9Paul Duffin * Utilities for working with {@link Type}. 467dd252788645e940eada959bdde927426e2531c9Paul Duffin * 477dd252788645e940eada959bdde927426e2531c9Paul Duffin * @author Ben Yu 487dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 497dd252788645e940eada959bdde927426e2531c9Paul Duffinfinal class Types { 507dd252788645e940eada959bdde927426e2531c9Paul Duffin 517dd252788645e940eada959bdde927426e2531c9Paul Duffin /** Class#toString without the "class " and "interface " prefixes */ 527dd252788645e940eada959bdde927426e2531c9Paul Duffin private static final Function<Type, String> TYPE_TO_STRING = new Function<Type, String>() { 537dd252788645e940eada959bdde927426e2531c9Paul Duffin public String apply(Type from) { 547dd252788645e940eada959bdde927426e2531c9Paul Duffin return Types.toString(from); 557dd252788645e940eada959bdde927426e2531c9Paul Duffin } 567dd252788645e940eada959bdde927426e2531c9Paul Duffin }; 577dd252788645e940eada959bdde927426e2531c9Paul Duffin 587dd252788645e940eada959bdde927426e2531c9Paul Duffin private static final Joiner COMMA_JOINER = Joiner.on(", ").useForNull("null"); 597dd252788645e940eada959bdde927426e2531c9Paul Duffin 607dd252788645e940eada959bdde927426e2531c9Paul Duffin /** Returns the array type of {@code componentType}. */ 617dd252788645e940eada959bdde927426e2531c9Paul Duffin static Type newArrayType(Type componentType) { 627dd252788645e940eada959bdde927426e2531c9Paul Duffin if (componentType instanceof WildcardType) { 637dd252788645e940eada959bdde927426e2531c9Paul Duffin WildcardType wildcard = (WildcardType) componentType; 647dd252788645e940eada959bdde927426e2531c9Paul Duffin Type[] lowerBounds = wildcard.getLowerBounds(); 657dd252788645e940eada959bdde927426e2531c9Paul Duffin checkArgument(lowerBounds.length <= 1, "Wildcard cannot have more than one lower bounds."); 667dd252788645e940eada959bdde927426e2531c9Paul Duffin if (lowerBounds.length == 1) { 677dd252788645e940eada959bdde927426e2531c9Paul Duffin return supertypeOf(newArrayType(lowerBounds[0])); 687dd252788645e940eada959bdde927426e2531c9Paul Duffin } else { 697dd252788645e940eada959bdde927426e2531c9Paul Duffin Type[] upperBounds = wildcard.getUpperBounds(); 707dd252788645e940eada959bdde927426e2531c9Paul Duffin checkArgument(upperBounds.length == 1, "Wildcard should have only one upper bound."); 717dd252788645e940eada959bdde927426e2531c9Paul Duffin return subtypeOf(newArrayType(upperBounds[0])); 727dd252788645e940eada959bdde927426e2531c9Paul Duffin } 737dd252788645e940eada959bdde927426e2531c9Paul Duffin } 747dd252788645e940eada959bdde927426e2531c9Paul Duffin return JavaVersion.CURRENT.newArrayType(componentType); 757dd252788645e940eada959bdde927426e2531c9Paul Duffin } 767dd252788645e940eada959bdde927426e2531c9Paul Duffin 777dd252788645e940eada959bdde927426e2531c9Paul Duffin /** 787dd252788645e940eada959bdde927426e2531c9Paul Duffin * Returns a type where {@code rawType} is parameterized by 797dd252788645e940eada959bdde927426e2531c9Paul Duffin * {@code arguments} and is owned by {@code ownerType}. 807dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 817dd252788645e940eada959bdde927426e2531c9Paul Duffin static ParameterizedType newParameterizedTypeWithOwner(@Nullable Type ownerType, 827dd252788645e940eada959bdde927426e2531c9Paul Duffin Class<?> rawType, Type... arguments) { 837dd252788645e940eada959bdde927426e2531c9Paul Duffin if (ownerType == null) { 847dd252788645e940eada959bdde927426e2531c9Paul Duffin return newParameterizedType(rawType, arguments); 857dd252788645e940eada959bdde927426e2531c9Paul Duffin } 867dd252788645e940eada959bdde927426e2531c9Paul Duffin // ParameterizedTypeImpl constructor already checks, but we want to throw NPE before IAE 877dd252788645e940eada959bdde927426e2531c9Paul Duffin checkNotNull(arguments); 887dd252788645e940eada959bdde927426e2531c9Paul Duffin checkArgument(rawType.getEnclosingClass() != null, "Owner type for unenclosed %s", rawType); 897dd252788645e940eada959bdde927426e2531c9Paul Duffin return new ParameterizedTypeImpl(ownerType, rawType, arguments); 907dd252788645e940eada959bdde927426e2531c9Paul Duffin } 917dd252788645e940eada959bdde927426e2531c9Paul Duffin 927dd252788645e940eada959bdde927426e2531c9Paul Duffin /** 937dd252788645e940eada959bdde927426e2531c9Paul Duffin * Returns a type where {@code rawType} is parameterized by 947dd252788645e940eada959bdde927426e2531c9Paul Duffin * {@code arguments}. 957dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 967dd252788645e940eada959bdde927426e2531c9Paul Duffin static ParameterizedType newParameterizedType(Class<?> rawType, Type... arguments) { 977dd252788645e940eada959bdde927426e2531c9Paul Duffin return new ParameterizedTypeImpl(ClassOwnership.JVM_BEHAVIOR.getOwnerType(rawType), rawType, 987dd252788645e940eada959bdde927426e2531c9Paul Duffin arguments); 997dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1007dd252788645e940eada959bdde927426e2531c9Paul Duffin 1017dd252788645e940eada959bdde927426e2531c9Paul Duffin /** Decides what owner type to use for constructing {@link ParameterizedType} from a raw class. */ 1027dd252788645e940eada959bdde927426e2531c9Paul Duffin private enum ClassOwnership { 1037dd252788645e940eada959bdde927426e2531c9Paul Duffin 1047dd252788645e940eada959bdde927426e2531c9Paul Duffin OWNED_BY_ENCLOSING_CLASS { 1057dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 1067dd252788645e940eada959bdde927426e2531c9Paul Duffin @Nullable 1077dd252788645e940eada959bdde927426e2531c9Paul Duffin Class<?> getOwnerType(Class<?> rawType) { 1087dd252788645e940eada959bdde927426e2531c9Paul Duffin return rawType.getEnclosingClass(); 1097dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1107dd252788645e940eada959bdde927426e2531c9Paul Duffin }, 1117dd252788645e940eada959bdde927426e2531c9Paul Duffin LOCAL_CLASS_HAS_NO_OWNER { 1127dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 1137dd252788645e940eada959bdde927426e2531c9Paul Duffin @Nullable 1147dd252788645e940eada959bdde927426e2531c9Paul Duffin Class<?> getOwnerType(Class<?> rawType) { 1157dd252788645e940eada959bdde927426e2531c9Paul Duffin if (rawType.isLocalClass()) { 1167dd252788645e940eada959bdde927426e2531c9Paul Duffin return null; 1177dd252788645e940eada959bdde927426e2531c9Paul Duffin } else { 1187dd252788645e940eada959bdde927426e2531c9Paul Duffin return rawType.getEnclosingClass(); 1197dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1207dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1217dd252788645e940eada959bdde927426e2531c9Paul Duffin }; 1227dd252788645e940eada959bdde927426e2531c9Paul Duffin 1237dd252788645e940eada959bdde927426e2531c9Paul Duffin @Nullable 1247dd252788645e940eada959bdde927426e2531c9Paul Duffin abstract Class<?> getOwnerType(Class<?> rawType); 1257dd252788645e940eada959bdde927426e2531c9Paul Duffin 1267dd252788645e940eada959bdde927426e2531c9Paul Duffin static final ClassOwnership JVM_BEHAVIOR = detectJvmBehavior(); 1277dd252788645e940eada959bdde927426e2531c9Paul Duffin 1287dd252788645e940eada959bdde927426e2531c9Paul Duffin private static ClassOwnership detectJvmBehavior() { 1297dd252788645e940eada959bdde927426e2531c9Paul Duffin class LocalClass<T> {} 1307dd252788645e940eada959bdde927426e2531c9Paul Duffin Class<?> subclass = new LocalClass<String>() {}.getClass(); 1317dd252788645e940eada959bdde927426e2531c9Paul Duffin ParameterizedType parameterizedType = (ParameterizedType) subclass.getGenericSuperclass(); 1327dd252788645e940eada959bdde927426e2531c9Paul Duffin for (ClassOwnership behavior : ClassOwnership.values()) { 1337dd252788645e940eada959bdde927426e2531c9Paul Duffin if (behavior.getOwnerType(LocalClass.class) == parameterizedType.getOwnerType()) { 1347dd252788645e940eada959bdde927426e2531c9Paul Duffin return behavior; 1357dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1367dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1377dd252788645e940eada959bdde927426e2531c9Paul Duffin throw new AssertionError(); 1387dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1397dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1407dd252788645e940eada959bdde927426e2531c9Paul Duffin 1417dd252788645e940eada959bdde927426e2531c9Paul Duffin /** 1427dd252788645e940eada959bdde927426e2531c9Paul Duffin * Returns a new {@link TypeVariable} that belongs to {@code declaration} with 1437dd252788645e940eada959bdde927426e2531c9Paul Duffin * {@code name} and {@code bounds}. 1447dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 1457dd252788645e940eada959bdde927426e2531c9Paul Duffin static <D extends GenericDeclaration> TypeVariable<D> newTypeVariable(D declaration, String name, 1467dd252788645e940eada959bdde927426e2531c9Paul Duffin Type... bounds) { 1477dd252788645e940eada959bdde927426e2531c9Paul Duffin return new TypeVariableImpl<D>(declaration, name, 1487dd252788645e940eada959bdde927426e2531c9Paul Duffin (bounds.length == 0) ? new Type[] { Object.class } : bounds); 1497dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1507dd252788645e940eada959bdde927426e2531c9Paul Duffin 1517dd252788645e940eada959bdde927426e2531c9Paul Duffin /** Returns a new {@link WildcardType} with {@code upperBound}. */ 1527dd252788645e940eada959bdde927426e2531c9Paul Duffin @VisibleForTesting 1537dd252788645e940eada959bdde927426e2531c9Paul Duffin static WildcardType subtypeOf(Type upperBound) { 1547dd252788645e940eada959bdde927426e2531c9Paul Duffin return new WildcardTypeImpl(new Type[0], new Type[] { upperBound }); 1557dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1567dd252788645e940eada959bdde927426e2531c9Paul Duffin 1577dd252788645e940eada959bdde927426e2531c9Paul Duffin /** Returns a new {@link WildcardType} with {@code lowerBound}. */ 1587dd252788645e940eada959bdde927426e2531c9Paul Duffin @VisibleForTesting 1597dd252788645e940eada959bdde927426e2531c9Paul Duffin static WildcardType supertypeOf(Type lowerBound) { 1607dd252788645e940eada959bdde927426e2531c9Paul Duffin return new WildcardTypeImpl(new Type[] { lowerBound }, new Type[] { Object.class }); 1617dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1627dd252788645e940eada959bdde927426e2531c9Paul Duffin 1637dd252788645e940eada959bdde927426e2531c9Paul Duffin /** 1647dd252788645e940eada959bdde927426e2531c9Paul Duffin * Returns human readable string representation of {@code type}. 1657dd252788645e940eada959bdde927426e2531c9Paul Duffin * <ul> 1667dd252788645e940eada959bdde927426e2531c9Paul Duffin * <li> For array type {@code Foo[]}, {@code "com.mypackage.Foo[]"} are 1677dd252788645e940eada959bdde927426e2531c9Paul Duffin * returned. 1687dd252788645e940eada959bdde927426e2531c9Paul Duffin * <li> For any class, {@code theClass.getName()} are returned. 1697dd252788645e940eada959bdde927426e2531c9Paul Duffin * <li> For all other types, {@code type.toString()} are returned. 1707dd252788645e940eada959bdde927426e2531c9Paul Duffin * </ul> 1717dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 1727dd252788645e940eada959bdde927426e2531c9Paul Duffin static String toString(Type type) { 1737dd252788645e940eada959bdde927426e2531c9Paul Duffin return (type instanceof Class) ? ((Class<?>) type).getName() : type.toString(); 1747dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1757dd252788645e940eada959bdde927426e2531c9Paul Duffin 1767dd252788645e940eada959bdde927426e2531c9Paul Duffin @Nullable 1777dd252788645e940eada959bdde927426e2531c9Paul Duffin static Type getComponentType(Type type) { 1787dd252788645e940eada959bdde927426e2531c9Paul Duffin checkNotNull(type); 1797dd252788645e940eada959bdde927426e2531c9Paul Duffin if (type instanceof Class) { 1807dd252788645e940eada959bdde927426e2531c9Paul Duffin return ((Class<?>) type).getComponentType(); 1817dd252788645e940eada959bdde927426e2531c9Paul Duffin } else if (type instanceof GenericArrayType) { 1827dd252788645e940eada959bdde927426e2531c9Paul Duffin return ((GenericArrayType) type).getGenericComponentType(); 1837dd252788645e940eada959bdde927426e2531c9Paul Duffin } else if (type instanceof WildcardType) { 1847dd252788645e940eada959bdde927426e2531c9Paul Duffin return subtypeOfComponentType(((WildcardType) type).getUpperBounds()); 1857dd252788645e940eada959bdde927426e2531c9Paul Duffin } else if (type instanceof TypeVariable) { 1867dd252788645e940eada959bdde927426e2531c9Paul Duffin return subtypeOfComponentType(((TypeVariable<?>) type).getBounds()); 1877dd252788645e940eada959bdde927426e2531c9Paul Duffin } else { 1887dd252788645e940eada959bdde927426e2531c9Paul Duffin return null; 1897dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1907dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1917dd252788645e940eada959bdde927426e2531c9Paul Duffin 1927dd252788645e940eada959bdde927426e2531c9Paul Duffin /** 1937dd252788645e940eada959bdde927426e2531c9Paul Duffin * Returns {@code ? extends X} if any of {@code bounds} is a subtype of {@code X[]}; or null 1947dd252788645e940eada959bdde927426e2531c9Paul Duffin * otherwise. 1957dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 1967dd252788645e940eada959bdde927426e2531c9Paul Duffin @Nullable 1977dd252788645e940eada959bdde927426e2531c9Paul Duffin private static Type subtypeOfComponentType(Type[] bounds) { 1987dd252788645e940eada959bdde927426e2531c9Paul Duffin for (Type bound : bounds) { 1997dd252788645e940eada959bdde927426e2531c9Paul Duffin Type componentType = getComponentType(bound); 2007dd252788645e940eada959bdde927426e2531c9Paul Duffin if (componentType != null) { 2017dd252788645e940eada959bdde927426e2531c9Paul Duffin // Only the first bound can be a class or array. 2027dd252788645e940eada959bdde927426e2531c9Paul Duffin // Bounds after the first can only be interfaces. 2037dd252788645e940eada959bdde927426e2531c9Paul Duffin if (componentType instanceof Class) { 2047dd252788645e940eada959bdde927426e2531c9Paul Duffin Class<?> componentClass = (Class<?>) componentType; 2057dd252788645e940eada959bdde927426e2531c9Paul Duffin if (componentClass.isPrimitive()) { 2067dd252788645e940eada959bdde927426e2531c9Paul Duffin return componentClass; 2077dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2087dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2097dd252788645e940eada959bdde927426e2531c9Paul Duffin return subtypeOf(componentType); 2107dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2117dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2127dd252788645e940eada959bdde927426e2531c9Paul Duffin return null; 2137dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2147dd252788645e940eada959bdde927426e2531c9Paul Duffin 2157dd252788645e940eada959bdde927426e2531c9Paul Duffin static boolean containsTypeVariable(@Nullable Type type) { 2167dd252788645e940eada959bdde927426e2531c9Paul Duffin if (type instanceof TypeVariable) { 2177dd252788645e940eada959bdde927426e2531c9Paul Duffin return true; 2187dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2197dd252788645e940eada959bdde927426e2531c9Paul Duffin if (type instanceof GenericArrayType) { 2207dd252788645e940eada959bdde927426e2531c9Paul Duffin return containsTypeVariable(((GenericArrayType) type).getGenericComponentType()); 2217dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2227dd252788645e940eada959bdde927426e2531c9Paul Duffin if (type instanceof ParameterizedType) { 2237dd252788645e940eada959bdde927426e2531c9Paul Duffin return containsTypeVariable(((ParameterizedType) type).getActualTypeArguments()); 2247dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2257dd252788645e940eada959bdde927426e2531c9Paul Duffin if (type instanceof WildcardType) { 2267dd252788645e940eada959bdde927426e2531c9Paul Duffin WildcardType wildcard = (WildcardType) type; 2277dd252788645e940eada959bdde927426e2531c9Paul Duffin return containsTypeVariable(wildcard.getUpperBounds()) 2287dd252788645e940eada959bdde927426e2531c9Paul Duffin || containsTypeVariable(wildcard.getLowerBounds()); 2297dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2307dd252788645e940eada959bdde927426e2531c9Paul Duffin return false; 2317dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2327dd252788645e940eada959bdde927426e2531c9Paul Duffin 2337dd252788645e940eada959bdde927426e2531c9Paul Duffin private static boolean containsTypeVariable(Type[] types) { 2347dd252788645e940eada959bdde927426e2531c9Paul Duffin for (Type paramType : types) { 2357dd252788645e940eada959bdde927426e2531c9Paul Duffin if (containsTypeVariable(paramType)) { 2367dd252788645e940eada959bdde927426e2531c9Paul Duffin return true; 2377dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2387dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2397dd252788645e940eada959bdde927426e2531c9Paul Duffin return false; 2407dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2417dd252788645e940eada959bdde927426e2531c9Paul Duffin 2427dd252788645e940eada959bdde927426e2531c9Paul Duffin private static final class GenericArrayTypeImpl implements GenericArrayType, Serializable { 2437dd252788645e940eada959bdde927426e2531c9Paul Duffin 2447dd252788645e940eada959bdde927426e2531c9Paul Duffin private final Type componentType; 2457dd252788645e940eada959bdde927426e2531c9Paul Duffin 2467dd252788645e940eada959bdde927426e2531c9Paul Duffin GenericArrayTypeImpl(Type componentType) { 2477dd252788645e940eada959bdde927426e2531c9Paul Duffin this.componentType = JavaVersion.CURRENT.usedInGenericType(componentType); 2487dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2497dd252788645e940eada959bdde927426e2531c9Paul Duffin 2507dd252788645e940eada959bdde927426e2531c9Paul Duffin public Type getGenericComponentType() { 2517dd252788645e940eada959bdde927426e2531c9Paul Duffin return componentType; 2527dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2537dd252788645e940eada959bdde927426e2531c9Paul Duffin 2547dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 2557dd252788645e940eada959bdde927426e2531c9Paul Duffin public String toString() { 2567dd252788645e940eada959bdde927426e2531c9Paul Duffin return Types.toString(componentType) + "[]"; 2577dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2587dd252788645e940eada959bdde927426e2531c9Paul Duffin 2597dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 2607dd252788645e940eada959bdde927426e2531c9Paul Duffin public int hashCode() { 2617dd252788645e940eada959bdde927426e2531c9Paul Duffin return componentType.hashCode(); 2627dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2637dd252788645e940eada959bdde927426e2531c9Paul Duffin 2647dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 2657dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean equals(Object obj) { 2667dd252788645e940eada959bdde927426e2531c9Paul Duffin if (obj instanceof GenericArrayType) { 2677dd252788645e940eada959bdde927426e2531c9Paul Duffin GenericArrayType that = (GenericArrayType) obj; 2687dd252788645e940eada959bdde927426e2531c9Paul Duffin return Objects.equal(getGenericComponentType(), that.getGenericComponentType()); 2697dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2707dd252788645e940eada959bdde927426e2531c9Paul Duffin return false; 2717dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2727dd252788645e940eada959bdde927426e2531c9Paul Duffin 2737dd252788645e940eada959bdde927426e2531c9Paul Duffin private static final long serialVersionUID = 0; 2747dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2757dd252788645e940eada959bdde927426e2531c9Paul Duffin 2767dd252788645e940eada959bdde927426e2531c9Paul Duffin private static final class ParameterizedTypeImpl implements ParameterizedType, Serializable { 2777dd252788645e940eada959bdde927426e2531c9Paul Duffin 2787dd252788645e940eada959bdde927426e2531c9Paul Duffin private final Type ownerType; 2797dd252788645e940eada959bdde927426e2531c9Paul Duffin private final ImmutableList<Type> argumentsList; 2807dd252788645e940eada959bdde927426e2531c9Paul Duffin private final Class<?> rawType; 2817dd252788645e940eada959bdde927426e2531c9Paul Duffin 2827dd252788645e940eada959bdde927426e2531c9Paul Duffin ParameterizedTypeImpl(@Nullable Type ownerType, Class<?> rawType, Type[] typeArguments) { 2837dd252788645e940eada959bdde927426e2531c9Paul Duffin checkNotNull(rawType); 2847dd252788645e940eada959bdde927426e2531c9Paul Duffin checkArgument(typeArguments.length == rawType.getTypeParameters().length); 2857dd252788645e940eada959bdde927426e2531c9Paul Duffin disallowPrimitiveType(typeArguments, "type parameter"); 2867dd252788645e940eada959bdde927426e2531c9Paul Duffin this.ownerType = ownerType; 2877dd252788645e940eada959bdde927426e2531c9Paul Duffin this.rawType = rawType; 2887dd252788645e940eada959bdde927426e2531c9Paul Duffin this.argumentsList = JavaVersion.CURRENT.usedInGenericType(typeArguments); 2897dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2907dd252788645e940eada959bdde927426e2531c9Paul Duffin 2917dd252788645e940eada959bdde927426e2531c9Paul Duffin public Type[] getActualTypeArguments() { 2927dd252788645e940eada959bdde927426e2531c9Paul Duffin return toArray(argumentsList); 2937dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2947dd252788645e940eada959bdde927426e2531c9Paul Duffin 2957dd252788645e940eada959bdde927426e2531c9Paul Duffin public Type getRawType() { 2967dd252788645e940eada959bdde927426e2531c9Paul Duffin return rawType; 2977dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2987dd252788645e940eada959bdde927426e2531c9Paul Duffin 2997dd252788645e940eada959bdde927426e2531c9Paul Duffin public Type getOwnerType() { 3007dd252788645e940eada959bdde927426e2531c9Paul Duffin return ownerType; 3017dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3027dd252788645e940eada959bdde927426e2531c9Paul Duffin 3037dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 3047dd252788645e940eada959bdde927426e2531c9Paul Duffin public String toString() { 3057dd252788645e940eada959bdde927426e2531c9Paul Duffin StringBuilder builder = new StringBuilder(); 3067dd252788645e940eada959bdde927426e2531c9Paul Duffin if (ownerType != null) { 3077dd252788645e940eada959bdde927426e2531c9Paul Duffin builder.append(Types.toString(ownerType)).append('.'); 3087dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3097dd252788645e940eada959bdde927426e2531c9Paul Duffin builder.append(rawType.getName()).append('<') 3107dd252788645e940eada959bdde927426e2531c9Paul Duffin .append(COMMA_JOINER.join(transform(argumentsList, TYPE_TO_STRING))).append('>'); 3117dd252788645e940eada959bdde927426e2531c9Paul Duffin return builder.toString(); 3127dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3137dd252788645e940eada959bdde927426e2531c9Paul Duffin 3147dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 3157dd252788645e940eada959bdde927426e2531c9Paul Duffin public int hashCode() { 3167dd252788645e940eada959bdde927426e2531c9Paul Duffin return (ownerType == null ? 0 : ownerType.hashCode()) ^ argumentsList.hashCode() 3177dd252788645e940eada959bdde927426e2531c9Paul Duffin ^ rawType.hashCode(); 3187dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3197dd252788645e940eada959bdde927426e2531c9Paul Duffin 3207dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 3217dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean equals(Object other) { 3227dd252788645e940eada959bdde927426e2531c9Paul Duffin if (!(other instanceof ParameterizedType)) { 3237dd252788645e940eada959bdde927426e2531c9Paul Duffin return false; 3247dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3257dd252788645e940eada959bdde927426e2531c9Paul Duffin ParameterizedType that = (ParameterizedType) other; 3267dd252788645e940eada959bdde927426e2531c9Paul Duffin return getRawType().equals(that.getRawType()) 3277dd252788645e940eada959bdde927426e2531c9Paul Duffin && Objects.equal(getOwnerType(), that.getOwnerType()) 3287dd252788645e940eada959bdde927426e2531c9Paul Duffin && Arrays.equals(getActualTypeArguments(), that.getActualTypeArguments()); 3297dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3307dd252788645e940eada959bdde927426e2531c9Paul Duffin 3317dd252788645e940eada959bdde927426e2531c9Paul Duffin private static final long serialVersionUID = 0; 3327dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3337dd252788645e940eada959bdde927426e2531c9Paul Duffin 3347dd252788645e940eada959bdde927426e2531c9Paul Duffin private static final class TypeVariableImpl<D extends GenericDeclaration> implements 3357dd252788645e940eada959bdde927426e2531c9Paul Duffin TypeVariable<D> { 3367dd252788645e940eada959bdde927426e2531c9Paul Duffin 3377dd252788645e940eada959bdde927426e2531c9Paul Duffin private final D genericDeclaration; 3387dd252788645e940eada959bdde927426e2531c9Paul Duffin private final String name; 3397dd252788645e940eada959bdde927426e2531c9Paul Duffin private final ImmutableList<Type> bounds; 3407dd252788645e940eada959bdde927426e2531c9Paul Duffin 3417dd252788645e940eada959bdde927426e2531c9Paul Duffin TypeVariableImpl(D genericDeclaration, String name, Type[] bounds) { 3427dd252788645e940eada959bdde927426e2531c9Paul Duffin disallowPrimitiveType(bounds, "bound for type variable"); 3437dd252788645e940eada959bdde927426e2531c9Paul Duffin this.genericDeclaration = checkNotNull(genericDeclaration); 3447dd252788645e940eada959bdde927426e2531c9Paul Duffin this.name = checkNotNull(name); 3457dd252788645e940eada959bdde927426e2531c9Paul Duffin this.bounds = ImmutableList.copyOf(bounds); 3467dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3477dd252788645e940eada959bdde927426e2531c9Paul Duffin 3487dd252788645e940eada959bdde927426e2531c9Paul Duffin public Type[] getBounds() { 3497dd252788645e940eada959bdde927426e2531c9Paul Duffin return toArray(bounds); 3507dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3517dd252788645e940eada959bdde927426e2531c9Paul Duffin 3527dd252788645e940eada959bdde927426e2531c9Paul Duffin public D getGenericDeclaration() { 3537dd252788645e940eada959bdde927426e2531c9Paul Duffin return genericDeclaration; 3547dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3557dd252788645e940eada959bdde927426e2531c9Paul Duffin 3567dd252788645e940eada959bdde927426e2531c9Paul Duffin public String getName() { 3577dd252788645e940eada959bdde927426e2531c9Paul Duffin return name; 3587dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3597dd252788645e940eada959bdde927426e2531c9Paul Duffin 3607dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 3617dd252788645e940eada959bdde927426e2531c9Paul Duffin public String toString() { 3627dd252788645e940eada959bdde927426e2531c9Paul Duffin return name; 3637dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3647dd252788645e940eada959bdde927426e2531c9Paul Duffin 3657dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 3667dd252788645e940eada959bdde927426e2531c9Paul Duffin public int hashCode() { 3677dd252788645e940eada959bdde927426e2531c9Paul Duffin return genericDeclaration.hashCode() ^ name.hashCode(); 3687dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3697dd252788645e940eada959bdde927426e2531c9Paul Duffin 3707dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 3717dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean equals(Object obj) { 3727dd252788645e940eada959bdde927426e2531c9Paul Duffin if (obj instanceof TypeVariable) { 3737dd252788645e940eada959bdde927426e2531c9Paul Duffin TypeVariable<?> that = (TypeVariable<?>) obj; 3747dd252788645e940eada959bdde927426e2531c9Paul Duffin return name.equals(that.getName()) 3757dd252788645e940eada959bdde927426e2531c9Paul Duffin && genericDeclaration.equals(that.getGenericDeclaration()); 3767dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3777dd252788645e940eada959bdde927426e2531c9Paul Duffin return false; 3787dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3797dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3807dd252788645e940eada959bdde927426e2531c9Paul Duffin 3817dd252788645e940eada959bdde927426e2531c9Paul Duffin static final class WildcardTypeImpl implements WildcardType, Serializable { 3827dd252788645e940eada959bdde927426e2531c9Paul Duffin 3837dd252788645e940eada959bdde927426e2531c9Paul Duffin private final ImmutableList<Type> lowerBounds; 3847dd252788645e940eada959bdde927426e2531c9Paul Duffin private final ImmutableList<Type> upperBounds; 3857dd252788645e940eada959bdde927426e2531c9Paul Duffin 3867dd252788645e940eada959bdde927426e2531c9Paul Duffin WildcardTypeImpl(Type[] lowerBounds, Type[] upperBounds) { 3877dd252788645e940eada959bdde927426e2531c9Paul Duffin disallowPrimitiveType(lowerBounds, "lower bound for wildcard"); 3887dd252788645e940eada959bdde927426e2531c9Paul Duffin disallowPrimitiveType(upperBounds, "upper bound for wildcard"); 3897dd252788645e940eada959bdde927426e2531c9Paul Duffin this.lowerBounds = JavaVersion.CURRENT.usedInGenericType(lowerBounds); 3907dd252788645e940eada959bdde927426e2531c9Paul Duffin this.upperBounds = JavaVersion.CURRENT.usedInGenericType(upperBounds); 3917dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3927dd252788645e940eada959bdde927426e2531c9Paul Duffin 3937dd252788645e940eada959bdde927426e2531c9Paul Duffin public Type[] getLowerBounds() { 3947dd252788645e940eada959bdde927426e2531c9Paul Duffin return toArray(lowerBounds); 3957dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3967dd252788645e940eada959bdde927426e2531c9Paul Duffin 3977dd252788645e940eada959bdde927426e2531c9Paul Duffin public Type[] getUpperBounds() { 3987dd252788645e940eada959bdde927426e2531c9Paul Duffin return toArray(upperBounds); 3997dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4007dd252788645e940eada959bdde927426e2531c9Paul Duffin 4017dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 4027dd252788645e940eada959bdde927426e2531c9Paul Duffin public boolean equals(Object obj) { 4037dd252788645e940eada959bdde927426e2531c9Paul Duffin if (obj instanceof WildcardType) { 4047dd252788645e940eada959bdde927426e2531c9Paul Duffin WildcardType that = (WildcardType) obj; 4057dd252788645e940eada959bdde927426e2531c9Paul Duffin return lowerBounds.equals(Arrays.asList(that.getLowerBounds())) 4067dd252788645e940eada959bdde927426e2531c9Paul Duffin && upperBounds.equals(Arrays.asList(that.getUpperBounds())); 4077dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4087dd252788645e940eada959bdde927426e2531c9Paul Duffin return false; 4097dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4107dd252788645e940eada959bdde927426e2531c9Paul Duffin 4117dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 4127dd252788645e940eada959bdde927426e2531c9Paul Duffin public int hashCode() { 4137dd252788645e940eada959bdde927426e2531c9Paul Duffin return lowerBounds.hashCode() ^ upperBounds.hashCode(); 4147dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4157dd252788645e940eada959bdde927426e2531c9Paul Duffin 4167dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 4177dd252788645e940eada959bdde927426e2531c9Paul Duffin public String toString() { 4187dd252788645e940eada959bdde927426e2531c9Paul Duffin StringBuilder builder = new StringBuilder("?"); 4197dd252788645e940eada959bdde927426e2531c9Paul Duffin for (Type lowerBound : lowerBounds) { 4207dd252788645e940eada959bdde927426e2531c9Paul Duffin builder.append(" super ").append(Types.toString(lowerBound)); 4217dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4227dd252788645e940eada959bdde927426e2531c9Paul Duffin for (Type upperBound : filterUpperBounds(upperBounds)) { 4237dd252788645e940eada959bdde927426e2531c9Paul Duffin builder.append(" extends ").append(Types.toString(upperBound)); 4247dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4257dd252788645e940eada959bdde927426e2531c9Paul Duffin return builder.toString(); 4267dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4277dd252788645e940eada959bdde927426e2531c9Paul Duffin 4287dd252788645e940eada959bdde927426e2531c9Paul Duffin private static final long serialVersionUID = 0; 4297dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4307dd252788645e940eada959bdde927426e2531c9Paul Duffin 4317dd252788645e940eada959bdde927426e2531c9Paul Duffin private static Type[] toArray(Collection<Type> types) { 4327dd252788645e940eada959bdde927426e2531c9Paul Duffin return types.toArray(new Type[types.size()]); 4337dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4347dd252788645e940eada959bdde927426e2531c9Paul Duffin 4357dd252788645e940eada959bdde927426e2531c9Paul Duffin private static Iterable<Type> filterUpperBounds(Iterable<Type> bounds) { 4367dd252788645e940eada959bdde927426e2531c9Paul Duffin return Iterables.filter(bounds, Predicates.not(Predicates.<Type> equalTo(Object.class))); 4377dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4387dd252788645e940eada959bdde927426e2531c9Paul Duffin 4397dd252788645e940eada959bdde927426e2531c9Paul Duffin private static void disallowPrimitiveType(Type[] types, String usedAs) { 4407dd252788645e940eada959bdde927426e2531c9Paul Duffin for (Type type : types) { 4417dd252788645e940eada959bdde927426e2531c9Paul Duffin if (type instanceof Class) { 4427dd252788645e940eada959bdde927426e2531c9Paul Duffin Class<?> cls = (Class<?>) type; 4437dd252788645e940eada959bdde927426e2531c9Paul Duffin checkArgument(!cls.isPrimitive(), "Primitive type '%s' used as %s", cls, usedAs); 4447dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4457dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4467dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4477dd252788645e940eada959bdde927426e2531c9Paul Duffin 4487dd252788645e940eada959bdde927426e2531c9Paul Duffin /** Returns the {@code Class} object of arrays with {@code componentType}. */ 4497dd252788645e940eada959bdde927426e2531c9Paul Duffin static Class<?> getArrayClass(Class<?> componentType) { 4507dd252788645e940eada959bdde927426e2531c9Paul Duffin // TODO(user): This is not the most efficient way to handle generic 4517dd252788645e940eada959bdde927426e2531c9Paul Duffin // arrays, but is there another way to extract the array class in a 4527dd252788645e940eada959bdde927426e2531c9Paul Duffin // non-hacky way (i.e. using String value class names- "[L...")? 4537dd252788645e940eada959bdde927426e2531c9Paul Duffin return Array.newInstance(componentType, 0).getClass(); 4547dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4557dd252788645e940eada959bdde927426e2531c9Paul Duffin 4567dd252788645e940eada959bdde927426e2531c9Paul Duffin // TODO(benyu): Once we are on Java 7, delete this abstraction 4577dd252788645e940eada959bdde927426e2531c9Paul Duffin enum JavaVersion { 4587dd252788645e940eada959bdde927426e2531c9Paul Duffin 4597dd252788645e940eada959bdde927426e2531c9Paul Duffin JAVA6 { 4607dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 4617dd252788645e940eada959bdde927426e2531c9Paul Duffin GenericArrayType newArrayType(Type componentType) { 4627dd252788645e940eada959bdde927426e2531c9Paul Duffin return new GenericArrayTypeImpl(componentType); 4637dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4647dd252788645e940eada959bdde927426e2531c9Paul Duffin 4657dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 4667dd252788645e940eada959bdde927426e2531c9Paul Duffin Type usedInGenericType(Type type) { 4677dd252788645e940eada959bdde927426e2531c9Paul Duffin checkNotNull(type); 4687dd252788645e940eada959bdde927426e2531c9Paul Duffin if (type instanceof Class) { 4697dd252788645e940eada959bdde927426e2531c9Paul Duffin Class<?> cls = (Class<?>) type; 4707dd252788645e940eada959bdde927426e2531c9Paul Duffin if (cls.isArray()) { 4717dd252788645e940eada959bdde927426e2531c9Paul Duffin return new GenericArrayTypeImpl(cls.getComponentType()); 4727dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4737dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4747dd252788645e940eada959bdde927426e2531c9Paul Duffin return type; 4757dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4767dd252788645e940eada959bdde927426e2531c9Paul Duffin }, 4777dd252788645e940eada959bdde927426e2531c9Paul Duffin JAVA7 { 4787dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 4797dd252788645e940eada959bdde927426e2531c9Paul Duffin Type newArrayType(Type componentType) { 4807dd252788645e940eada959bdde927426e2531c9Paul Duffin if (componentType instanceof Class) { 4817dd252788645e940eada959bdde927426e2531c9Paul Duffin return getArrayClass((Class<?>) componentType); 4827dd252788645e940eada959bdde927426e2531c9Paul Duffin } else { 4837dd252788645e940eada959bdde927426e2531c9Paul Duffin return new GenericArrayTypeImpl(componentType); 4847dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4857dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4867dd252788645e940eada959bdde927426e2531c9Paul Duffin 4877dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 4887dd252788645e940eada959bdde927426e2531c9Paul Duffin Type usedInGenericType(Type type) { 4897dd252788645e940eada959bdde927426e2531c9Paul Duffin return checkNotNull(type); 4907dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4917dd252788645e940eada959bdde927426e2531c9Paul Duffin }; 4927dd252788645e940eada959bdde927426e2531c9Paul Duffin 4937dd252788645e940eada959bdde927426e2531c9Paul Duffin static final JavaVersion CURRENT = (new TypeCapture<int[]>() {}.capture() instanceof Class) ? JAVA7 4947dd252788645e940eada959bdde927426e2531c9Paul Duffin : JAVA6; 4957dd252788645e940eada959bdde927426e2531c9Paul Duffin 4967dd252788645e940eada959bdde927426e2531c9Paul Duffin abstract Type newArrayType(Type componentType); 4977dd252788645e940eada959bdde927426e2531c9Paul Duffin 4987dd252788645e940eada959bdde927426e2531c9Paul Duffin abstract Type usedInGenericType(Type type); 4997dd252788645e940eada959bdde927426e2531c9Paul Duffin 5007dd252788645e940eada959bdde927426e2531c9Paul Duffin final ImmutableList<Type> usedInGenericType(Type[] types) { 5017dd252788645e940eada959bdde927426e2531c9Paul Duffin ImmutableList.Builder<Type> builder = ImmutableList.builder(); 5027dd252788645e940eada959bdde927426e2531c9Paul Duffin for (Type type : types) { 5037dd252788645e940eada959bdde927426e2531c9Paul Duffin builder.add(usedInGenericType(type)); 5047dd252788645e940eada959bdde927426e2531c9Paul Duffin } 5057dd252788645e940eada959bdde927426e2531c9Paul Duffin return builder.build(); 5067dd252788645e940eada959bdde927426e2531c9Paul Duffin } 5077dd252788645e940eada959bdde927426e2531c9Paul Duffin } 5087dd252788645e940eada959bdde927426e2531c9Paul Duffin 5097dd252788645e940eada959bdde927426e2531c9Paul Duffin private Types() {} 5107dd252788645e940eada959bdde927426e2531c9Paul Duffin} 511