141bc85288590d19c50f299372f942aa27677d77ccrazyboblee/**
241bc85288590d19c50f299372f942aa27677d77ccrazyboblee * Copyright (C) 2006 Google Inc.
341bc85288590d19c50f299372f942aa27677d77ccrazyboblee *
441bc85288590d19c50f299372f942aa27677d77ccrazyboblee * Licensed under the Apache License, Version 2.0 (the "License");
541bc85288590d19c50f299372f942aa27677d77ccrazyboblee * you may not use this file except in compliance with the License.
641bc85288590d19c50f299372f942aa27677d77ccrazyboblee * You may obtain a copy of the License at
741bc85288590d19c50f299372f942aa27677d77ccrazyboblee *
841bc85288590d19c50f299372f942aa27677d77ccrazyboblee * http://www.apache.org/licenses/LICENSE-2.0
941bc85288590d19c50f299372f942aa27677d77ccrazyboblee *
1041bc85288590d19c50f299372f942aa27677d77ccrazyboblee * Unless required by applicable law or agreed to in writing, software
1141bc85288590d19c50f299372f942aa27677d77ccrazyboblee * distributed under the License is distributed on an "AS IS" BASIS,
1241bc85288590d19c50f299372f942aa27677d77ccrazyboblee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1341bc85288590d19c50f299372f942aa27677d77ccrazyboblee * See the License for the specific language governing permissions and
1441bc85288590d19c50f299372f942aa27677d77ccrazyboblee * limitations under the License.
1541bc85288590d19c50f299372f942aa27677d77ccrazyboblee */
1641bc85288590d19c50f299372f942aa27677d77ccrazyboblee
1741bc85288590d19c50f299372f942aa27677d77ccrazybobleepackage com.google.inject;
1841bc85288590d19c50f299372f942aa27677d77ccrazyboblee
19d9c913acca55023ef5d76a32c3d4a51ee6b420cbsberlinimport static com.google.common.base.Preconditions.checkArgument;
20d9c913acca55023ef5d76a32c3d4a51ee6b420cbsberlinimport static com.google.common.base.Preconditions.checkNotNull;
21b7a02b02d81c830d148355c90bc309bcd66fb592sberlinimport static com.google.inject.internal.MoreTypes.canonicalize;
22b7a02b02d81c830d148355c90bc309bcd66fb592sberlin
23b7a02b02d81c830d148355c90bc309bcd66fb592sberlinimport com.google.common.collect.ImmutableList;
24b7a02b02d81c830d148355c90bc309bcd66fb592sberlinimport com.google.inject.internal.MoreTypes;
253beaaaff52598e849659281fed35dc29a221fac4limpbizkitimport com.google.inject.util.Types;
26b7a02b02d81c830d148355c90bc309bcd66fb592sberlin
274f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkitimport java.lang.reflect.Constructor;
284f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkitimport java.lang.reflect.Field;
294f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkitimport java.lang.reflect.GenericArrayType;
304f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkitimport java.lang.reflect.Member;
314f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkitimport java.lang.reflect.Method;
3241bc85288590d19c50f299372f942aa27677d77ccrazybobleeimport java.lang.reflect.ParameterizedType;
33a99dca76dc81e4a7c45a5d2d7d875b040f51abdckevinbimport java.lang.reflect.Type;
344f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkitimport java.lang.reflect.TypeVariable;
358d13d41fadf5b304288f4dedf2435fb518209366limpbizkitimport java.lang.reflect.WildcardType;
364f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkitimport java.util.List;
3741bc85288590d19c50f299372f942aa27677d77ccrazyboblee
3841bc85288590d19c50f299372f942aa27677d77ccrazyboblee/**
39235d068516b98fcbf9c6f1a05bcbd9d3e97a71d5crazyboblee * Represents a generic type {@code T}. Java doesn't yet provide a way to
40e3adfd619abae820b90951f383ec7a271a62c0b0crazyboblee * represent generic types, so this class does. Forces clients to create a
41a99dca76dc81e4a7c45a5d2d7d875b040f51abdckevinb * subclass of this class which enables retrieval the type information even at
42a99dca76dc81e4a7c45a5d2d7d875b040f51abdckevinb * runtime.
43e3adfd619abae820b90951f383ec7a271a62c0b0crazyboblee *
44a99dca76dc81e4a7c45a5d2d7d875b040f51abdckevinb * <p>For example, to create a type literal for {@code List<String>}, you can
45a99dca76dc81e4a7c45a5d2d7d875b040f51abdckevinb * create an empty anonymous inner class:
46e3adfd619abae820b90951f383ec7a271a62c0b0crazyboblee *
47a99dca76dc81e4a7c45a5d2d7d875b040f51abdckevinb * <p>
48a99dca76dc81e4a7c45a5d2d7d875b040f51abdckevinb * {@code TypeLiteral<List<String>> list = new TypeLiteral<List<String>>() {};}
4941bc85288590d19c50f299372f942aa27677d77ccrazyboblee *
50a2b241d8bb2ba429d7601f2af2415130ae453656limpbizkit * <p>Along with modeling generic types, this class can resolve type parameters.
51a2b241d8bb2ba429d7601f2af2415130ae453656limpbizkit * For example, to figure out what type {@code keySet()} returns on a {@code
52a2b241d8bb2ba429d7601f2af2415130ae453656limpbizkit * Map<Integer, String>}, use this code:<pre>   {@code
53a2b241d8bb2ba429d7601f2af2415130ae453656limpbizkit *
54a2b241d8bb2ba429d7601f2af2415130ae453656limpbizkit *   TypeLiteral<Map<Integer, String>> mapType
55a2b241d8bb2ba429d7601f2af2415130ae453656limpbizkit *       = new TypeLiteral<Map<Integer, String>>() {};
56a2b241d8bb2ba429d7601f2af2415130ae453656limpbizkit *   TypeLiteral<?> keySetType
57a2b241d8bb2ba429d7601f2af2415130ae453656limpbizkit *       = mapType.getReturnType(Map.class.getMethod("keySet"));
58a2b241d8bb2ba429d7601f2af2415130ae453656limpbizkit *   System.out.println(keySetType); // prints "Set<Integer>"}</pre>
5941bc85288590d19c50f299372f942aa27677d77ccrazyboblee *
6041bc85288590d19c50f299372f942aa27677d77ccrazyboblee * @author crazybob@google.com (Bob Lee)
610de5e3ec3c7a2816a418206d5f27c9bd5a1b75aalimpbizkit * @author jessewilson@google.com (Jesse Wilson)
6241bc85288590d19c50f299372f942aa27677d77ccrazyboblee */
638c4c71cf6b0d4fcaee49ac6f95acca6ffa78536elimpbizkitpublic class TypeLiteral<T> {
6441bc85288590d19c50f299372f942aa27677d77ccrazyboblee
6541bc85288590d19c50f299372f942aa27677d77ccrazyboblee  final Class<? super T> rawType;
6641bc85288590d19c50f299372f942aa27677d77ccrazyboblee  final Type type;
671b54d6a560517b057c66c29f3700d8b10bc7bfadcrazyboblee  final int hashCode;
6841bc85288590d19c50f299372f942aa27677d77ccrazyboblee
6941bc85288590d19c50f299372f942aa27677d77ccrazyboblee  /**
700baa9fcb9ddf853e9bbf8b71c5f1167051c366e0crazyboblee   * Constructs a new type literal. Derives represented class from type
7141bc85288590d19c50f299372f942aa27677d77ccrazyboblee   * parameter.
7241bc85288590d19c50f299372f942aa27677d77ccrazyboblee   *
7341bc85288590d19c50f299372f942aa27677d77ccrazyboblee   * <p>Clients create an empty anonymous subclass. Doing so embeds the type
74a99dca76dc81e4a7c45a5d2d7d875b040f51abdckevinb   * parameter in the anonymous class's type hierarchy so we can reconstitute it
75a99dca76dc81e4a7c45a5d2d7d875b040f51abdckevinb   * at runtime despite erasure.
7641bc85288590d19c50f299372f942aa27677d77ccrazyboblee   */
77a99dca76dc81e4a7c45a5d2d7d875b040f51abdckevinb  @SuppressWarnings("unchecked")
780baa9fcb9ddf853e9bbf8b71c5f1167051c366e0crazyboblee  protected TypeLiteral() {
7941bc85288590d19c50f299372f942aa27677d77ccrazyboblee    this.type = getSuperclassTypeParameter(getClass());
803beaaaff52598e849659281fed35dc29a221fac4limpbizkit    this.rawType = (Class<? super T>) MoreTypes.getRawType(type);
813ea8095def50d99f8f8a49c0fa6cc25e82217109limpbizkit    this.hashCode = type.hashCode();
8241bc85288590d19c50f299372f942aa27677d77ccrazyboblee  }
8341bc85288590d19c50f299372f942aa27677d77ccrazyboblee
8441bc85288590d19c50f299372f942aa27677d77ccrazyboblee  /**
850baa9fcb9ddf853e9bbf8b71c5f1167051c366e0crazyboblee   * Unsafe. Constructs a type literal manually.
8641bc85288590d19c50f299372f942aa27677d77ccrazyboblee   */
87a99dca76dc81e4a7c45a5d2d7d875b040f51abdckevinb  @SuppressWarnings("unchecked")
881b54d6a560517b057c66c29f3700d8b10bc7bfadcrazyboblee  TypeLiteral(Type type) {
891601ae5cc3d7931d4ce4b78e0b493acdd6132ff1kevinb    this.type = canonicalize(checkNotNull(type, "type"));
903beaaaff52598e849659281fed35dc29a221fac4limpbizkit    this.rawType = (Class<? super T>) MoreTypes.getRawType(this.type);
913ea8095def50d99f8f8a49c0fa6cc25e82217109limpbizkit    this.hashCode = this.type.hashCode();
9241bc85288590d19c50f299372f942aa27677d77ccrazyboblee  }
9341bc85288590d19c50f299372f942aa27677d77ccrazyboblee
9441bc85288590d19c50f299372f942aa27677d77ccrazyboblee  /**
954272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit   * Returns the type from super class's type parameter in {@link MoreTypes#canonicalize(Type)
964272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit   * canonical form}.
9741bc85288590d19c50f299372f942aa27677d77ccrazyboblee   */
9841bc85288590d19c50f299372f942aa27677d77ccrazyboblee  static Type getSuperclassTypeParameter(Class<?> subclass) {
9941bc85288590d19c50f299372f942aa27677d77ccrazyboblee    Type superclass = subclass.getGenericSuperclass();
10041bc85288590d19c50f299372f942aa27677d77ccrazyboblee    if (superclass instanceof Class) {
10141bc85288590d19c50f299372f942aa27677d77ccrazyboblee      throw new RuntimeException("Missing type parameter.");
10241bc85288590d19c50f299372f942aa27677d77ccrazyboblee    }
103f530b2542e7a93416b392f598c90b018d0f38991limpbizkit    ParameterizedType parameterized = (ParameterizedType) superclass;
104f530b2542e7a93416b392f598c90b018d0f38991limpbizkit    return canonicalize(parameterized.getActualTypeArguments()[0]);
10541bc85288590d19c50f299372f942aa27677d77ccrazyboblee  }
10641bc85288590d19c50f299372f942aa27677d77ccrazyboblee
10741bc85288590d19c50f299372f942aa27677d77ccrazyboblee  /**
1080baa9fcb9ddf853e9bbf8b71c5f1167051c366e0crazyboblee   * Gets type literal from super class's type parameter.
10941bc85288590d19c50f299372f942aa27677d77ccrazyboblee   */
1100baa9fcb9ddf853e9bbf8b71c5f1167051c366e0crazyboblee  static TypeLiteral<?> fromSuperclassTypeParameter(Class<?> subclass) {
111eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    return new TypeLiteral<Object>(getSuperclassTypeParameter(subclass));
11241bc85288590d19c50f299372f942aa27677d77ccrazyboblee  }
11341bc85288590d19c50f299372f942aa27677d77ccrazyboblee
11441bc85288590d19c50f299372f942aa27677d77ccrazyboblee  /**
1154272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit   * Returns the raw (non-generic) type for this type.
116b92a84ed99fd17a1b5d239431d9c6c670b5702e8limpbizkit   *
117b92a84ed99fd17a1b5d239431d9c6c670b5702e8limpbizkit   * @since 2.0
11841bc85288590d19c50f299372f942aa27677d77ccrazyboblee   */
1194272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit  public final Class<? super T> getRawType() {
12041bc85288590d19c50f299372f942aa27677d77ccrazyboblee    return rawType;
12141bc85288590d19c50f299372f942aa27677d77ccrazyboblee  }
12241bc85288590d19c50f299372f942aa27677d77ccrazyboblee
12341bc85288590d19c50f299372f942aa27677d77ccrazyboblee  /**
12441bc85288590d19c50f299372f942aa27677d77ccrazyboblee   * Gets underlying {@code Type} instance.
12541bc85288590d19c50f299372f942aa27677d77ccrazyboblee   */
126eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit  public final Type getType() {
12741bc85288590d19c50f299372f942aa27677d77ccrazyboblee    return type;
12841bc85288590d19c50f299372f942aa27677d77ccrazyboblee  }
12941bc85288590d19c50f299372f942aa27677d77ccrazyboblee
130552472f747583ca0c217b6f0ca8819c58556e540crazyboblee  /**
131552472f747583ca0c217b6f0ca8819c58556e540crazyboblee   * Gets the type of this type's provider.
132552472f747583ca0c217b6f0ca8819c58556e540crazyboblee   */
133552472f747583ca0c217b6f0ca8819c58556e540crazyboblee  @SuppressWarnings("unchecked")
134eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit  final TypeLiteral<Provider<T>> providerType() {
135552472f747583ca0c217b6f0ca8819c58556e540crazyboblee    // This cast is safe and wouldn't generate a warning if Type had a type
136552472f747583ca0c217b6f0ca8819c58556e540crazyboblee    // parameter.
1373beaaaff52598e849659281fed35dc29a221fac4limpbizkit    return (TypeLiteral<Provider<T>>) get(Types.providerOf(getType()));
138552472f747583ca0c217b6f0ca8819c58556e540crazyboblee  }
139552472f747583ca0c217b6f0ca8819c58556e540crazyboblee
140eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit  @Override public final int hashCode() {
1411b54d6a560517b057c66c29f3700d8b10bc7bfadcrazyboblee    return this.hashCode;
14241bc85288590d19c50f299372f942aa27677d77ccrazyboblee  }
14341bc85288590d19c50f299372f942aa27677d77ccrazyboblee
144eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit  @Override public final boolean equals(Object o) {
145eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    return o instanceof TypeLiteral<?>
1463beaaaff52598e849659281fed35dc29a221fac4limpbizkit        && MoreTypes.equals(type, ((TypeLiteral) o).type);
14741bc85288590d19c50f299372f942aa27677d77ccrazyboblee  }
14841bc85288590d19c50f299372f942aa27677d77ccrazyboblee
149eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit  @Override public final String toString() {
1503ea8095def50d99f8f8a49c0fa6cc25e82217109limpbizkit    return MoreTypes.typeToString(type);
15141bc85288590d19c50f299372f942aa27677d77ccrazyboblee  }
15241bc85288590d19c50f299372f942aa27677d77ccrazyboblee
15341bc85288590d19c50f299372f942aa27677d77ccrazyboblee  /**
1540baa9fcb9ddf853e9bbf8b71c5f1167051c366e0crazyboblee   * Gets type literal for the given {@code Type} instance.
15541bc85288590d19c50f299372f942aa27677d77ccrazyboblee   */
1560baa9fcb9ddf853e9bbf8b71c5f1167051c366e0crazyboblee  public static TypeLiteral<?> get(Type type) {
157eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    return new TypeLiteral<Object>(type);
15841bc85288590d19c50f299372f942aa27677d77ccrazyboblee  }
15941bc85288590d19c50f299372f942aa27677d77ccrazyboblee
16041bc85288590d19c50f299372f942aa27677d77ccrazyboblee  /**
1610baa9fcb9ddf853e9bbf8b71c5f1167051c366e0crazyboblee   * Gets type literal for the given {@code Class} instance.
16241bc85288590d19c50f299372f942aa27677d77ccrazyboblee   */
1630baa9fcb9ddf853e9bbf8b71c5f1167051c366e0crazyboblee  public static <T> TypeLiteral<T> get(Class<T> type) {
164eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    return new TypeLiteral<T>(type);
16541bc85288590d19c50f299372f942aa27677d77ccrazyboblee  }
1664f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit
1674f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit
1684f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit  /** Returns an immutable list of the resolved types. */
1694272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit  private List<TypeLiteral<?>> resolveAll(Type[] types) {
1704272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit    TypeLiteral<?>[] result = new TypeLiteral<?>[types.length];
1714f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit    for (int t = 0; t < types.length; t++) {
1724f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit      result[t] = resolve(types[t]);
1734f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit    }
1745221c15e183cb7029a305766d137d909f77e8941sberlin    return ImmutableList.copyOf(result);
1754f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit  }
1764f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit
1774f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit  /**
1784f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit   * Resolves known type parameters in {@code toResolve} and returns the result.
1794f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit   */
1804272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit  TypeLiteral<?> resolve(Type toResolve) {
1814272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit    return TypeLiteral.get(resolveType(toResolve));
1824272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit  }
1834272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit
1844272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit  Type resolveType(Type toResolve) {
1854272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit    // this implementation is made a little more complicated in an attempt to avoid object-creation
1864f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit    while (true) {
1874f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit      if (toResolve instanceof TypeVariable) {
1884f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit        TypeVariable original = (TypeVariable) toResolve;
1894f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit        toResolve = MoreTypes.resolveTypeVariable(type, rawType, original);
1904f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit        if (toResolve == original) {
1914f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit          return toResolve;
1924f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit        }
1934f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit
1944f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit      } else if (toResolve instanceof GenericArrayType) {
1954f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit        GenericArrayType original = (GenericArrayType) toResolve;
1964f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit        Type componentType = original.getGenericComponentType();
1974272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit        Type newComponentType = resolveType(componentType);
1984f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit        return componentType == newComponentType
1994f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit            ? original
2004f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit            : Types.arrayOf(newComponentType);
2014f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit
2024f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit      } else if (toResolve instanceof ParameterizedType) {
2034f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit        ParameterizedType original = (ParameterizedType) toResolve;
2044f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit        Type ownerType = original.getOwnerType();
2054272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit        Type newOwnerType = resolveType(ownerType);
2064f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit        boolean changed = newOwnerType != ownerType;
2074f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit
2084f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit        Type[] args = original.getActualTypeArguments();
2094f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit        for (int t = 0, length = args.length; t < length; t++) {
2104272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit          Type resolvedTypeArgument = resolveType(args[t]);
2114f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit          if (resolvedTypeArgument != args[t]) {
2124f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit            if (!changed) {
2134f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit              args = args.clone();
2144f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit              changed = true;
2154f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit            }
2164f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit            args[t] = resolvedTypeArgument;
2174f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit          }
2184f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit        }
2194f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit
2204f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit        return changed
2214f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit            ? Types.newParameterizedTypeWithOwner(newOwnerType, original.getRawType(), args)
2224f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit            : original;
2234f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit
2248d13d41fadf5b304288f4dedf2435fb518209366limpbizkit      } else if (toResolve instanceof WildcardType) {
2258d13d41fadf5b304288f4dedf2435fb518209366limpbizkit        WildcardType original = (WildcardType) toResolve;
2268d13d41fadf5b304288f4dedf2435fb518209366limpbizkit        Type[] originalLowerBound = original.getLowerBounds();
2278d13d41fadf5b304288f4dedf2435fb518209366limpbizkit        Type[] originalUpperBound = original.getUpperBounds();
2288d13d41fadf5b304288f4dedf2435fb518209366limpbizkit
2298d13d41fadf5b304288f4dedf2435fb518209366limpbizkit        if (originalLowerBound.length == 1) {
2304272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit          Type lowerBound = resolveType(originalLowerBound[0]);
2318d13d41fadf5b304288f4dedf2435fb518209366limpbizkit          if (lowerBound != originalLowerBound[0]) {
2328d13d41fadf5b304288f4dedf2435fb518209366limpbizkit            return Types.supertypeOf(lowerBound);
2338d13d41fadf5b304288f4dedf2435fb518209366limpbizkit          }
2348d13d41fadf5b304288f4dedf2435fb518209366limpbizkit        } else if (originalUpperBound.length == 1) {
2354272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit          Type upperBound = resolveType(originalUpperBound[0]);
2368d13d41fadf5b304288f4dedf2435fb518209366limpbizkit          if (upperBound != originalUpperBound[0]) {
2378d13d41fadf5b304288f4dedf2435fb518209366limpbizkit            return Types.subtypeOf(upperBound);
2388d13d41fadf5b304288f4dedf2435fb518209366limpbizkit          }
2398d13d41fadf5b304288f4dedf2435fb518209366limpbizkit        }
2408d13d41fadf5b304288f4dedf2435fb518209366limpbizkit        return original;
2418d13d41fadf5b304288f4dedf2435fb518209366limpbizkit
2424f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit      } else {
2434f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit        return toResolve;
2444f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit      }
2454f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit    }
2464f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit  }
2474f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit
2484f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit  /**
2494f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit   * Returns the generic form of {@code supertype}. For example, if this is {@code
2504f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit   * ArrayList<String>}, this returns {@code Iterable<String>} given the input {@code
2514f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit   * Iterable.class}.
2524f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit   *
2534f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit   * @param supertype a superclass of, or interface implemented by, this.
254c489adf4671b41765698d167e13960d998190c5elimpbizkit   * @since 2.0
2554f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit   */
2564272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit  public TypeLiteral<?> getSupertype(Class<?> supertype) {
2574f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit    checkArgument(supertype.isAssignableFrom(rawType),
2584f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit        "%s is not a supertype of %s", supertype, this.type);
2594f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit    return resolve(MoreTypes.getGenericSupertype(type, rawType, supertype));
2604f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit  }
2614f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit
2624f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit  /**
2634f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit   * Returns the resolved generic type of {@code field}.
2644f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit   *
2654f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit   * @param field a field defined by this or any superclass.
266c489adf4671b41765698d167e13960d998190c5elimpbizkit   * @since 2.0
2674f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit   */
2684272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit  public TypeLiteral<?> getFieldType(Field field) {
2694f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit    checkArgument(field.getDeclaringClass().isAssignableFrom(rawType),
2704f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit        "%s is not defined by a supertype of %s", field, type);
2714f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit    return resolve(field.getGenericType());
2724f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit  }
2734f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit
2744f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit  /**
2754f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit   * Returns the resolved generic parameter types of {@code methodOrConstructor}.
2764f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit   *
2774f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit   * @param methodOrConstructor a method or constructor defined by this or any supertype.
278c489adf4671b41765698d167e13960d998190c5elimpbizkit   * @since 2.0
2794f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit   */
2804272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit  public List<TypeLiteral<?>> getParameterTypes(Member methodOrConstructor) {
2814f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit    Type[] genericParameterTypes;
2824f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit
2834f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit    if (methodOrConstructor instanceof Method) {
2844f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit      Method method = (Method) methodOrConstructor;
2854f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit      checkArgument(method.getDeclaringClass().isAssignableFrom(rawType),
2864f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit          "%s is not defined by a supertype of %s", method, type);
2874f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit      genericParameterTypes = method.getGenericParameterTypes();
2884f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit
2894f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit    } else if (methodOrConstructor instanceof Constructor) {
2905ae41eb77073b47e75c2dcf3766137f2352fbaf9limpbizkit      Constructor<?> constructor = (Constructor<?>) methodOrConstructor;
2914f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit      checkArgument(constructor.getDeclaringClass().isAssignableFrom(rawType),
2924f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit          "%s does not construct a supertype of %s", constructor, type);
2934f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit      genericParameterTypes = constructor.getGenericParameterTypes();
2944f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit
2954f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit    } else {
2964f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit      throw new IllegalArgumentException("Not a method or a constructor: " + methodOrConstructor);
2974f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit    }
2984f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit
2994f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit    return resolveAll(genericParameterTypes);
3004f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit  }
3014f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit
3024f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit  /**
3034f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit   * Returns the resolved generic exception types thrown by {@code constructor}.
3044f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit   *
3054f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit   * @param methodOrConstructor a method or constructor defined by this or any supertype.
306c489adf4671b41765698d167e13960d998190c5elimpbizkit   * @since 2.0
3074f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit   */
3084272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit  public List<TypeLiteral<?>> getExceptionTypes(Member methodOrConstructor) {
3094f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit    Type[] genericExceptionTypes;
3104f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit
3114f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit    if (methodOrConstructor instanceof Method) {
3124f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit      Method method = (Method) methodOrConstructor;
3134f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit      checkArgument(method.getDeclaringClass().isAssignableFrom(rawType),
3144f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit          "%s is not defined by a supertype of %s", method, type);
3154f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit      genericExceptionTypes = method.getGenericExceptionTypes();
3164f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit
3174f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit    } else if (methodOrConstructor instanceof Constructor) {
3184f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit      Constructor<?> constructor = (Constructor<?>) methodOrConstructor;
3194f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit      checkArgument(constructor.getDeclaringClass().isAssignableFrom(rawType),
3204f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit          "%s does not construct a supertype of %s", constructor, type);
3214f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit      genericExceptionTypes = constructor.getGenericExceptionTypes();
3224f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit
3234f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit    } else {
3244f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit      throw new IllegalArgumentException("Not a method or a constructor: " + methodOrConstructor);
3254f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit    }
3264f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit
3274f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit    return resolveAll(genericExceptionTypes);
3284f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit  }
3294f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit
3304f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit  /**
3314f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit   * Returns the resolved generic return type of {@code method}.
3324f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit   *
3334f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit   * @param method a method defined by this or any supertype.
334c489adf4671b41765698d167e13960d998190c5elimpbizkit   * @since 2.0
3354f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit   */
3364272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit  public TypeLiteral<?> getReturnType(Method method) {
3374f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit    checkArgument(method.getDeclaringClass().isAssignableFrom(rawType),
3384f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit        "%s is not defined by a supertype of %s", method, type);
3394f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit    return resolve(method.getGenericReturnType());
3404f5d1f7f1b88b7ee0aef7e70fc70ce824b6ceb22limpbizkit  }
34141bc85288590d19c50f299372f942aa27677d77ccrazyboblee}
342