Wildcards now supported in TypeLiteral type resolution

git-svn-id: https://google-guice.googlecode.com/svn/trunk@665 d779f126-a31b-0410-b53b-1d3aecad763e
diff --git a/src/com/google/inject/TypeLiteral.java b/src/com/google/inject/TypeLiteral.java
index cdd037f..eb762c8 100644
--- a/src/com/google/inject/TypeLiteral.java
+++ b/src/com/google/inject/TypeLiteral.java
@@ -30,6 +30,7 @@
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 import java.lang.reflect.TypeVariable;
+import java.lang.reflect.WildcardType;
 import java.util.List;
 
 /**
@@ -203,6 +204,24 @@
             ? Types.newParameterizedTypeWithOwner(newOwnerType, original.getRawType(), args)
             : original;
 
+      } else if (toResolve instanceof WildcardType) {
+        WildcardType original = (WildcardType) toResolve;
+        Type[] originalLowerBound = original.getLowerBounds();
+        Type[] originalUpperBound = original.getUpperBounds();
+
+        if (originalLowerBound.length == 1) {
+          Type lowerBound = resolve(originalLowerBound[0]);
+          if (lowerBound != originalLowerBound[0]) {
+            return Types.supertypeOf(lowerBound);
+          }
+        } else if (originalUpperBound.length == 1) {
+          Type upperBound = resolve(originalUpperBound[0]);
+          if (upperBound != originalUpperBound[0]) {
+            return Types.subtypeOf(upperBound);
+          }
+        }
+        return original;
+
       } else {
         return toResolve;
       }
diff --git a/test/com/google/inject/TypeLiteralTypeResolutionTest.java b/test/com/google/inject/TypeLiteralTypeResolutionTest.java
index 76a048d..fa9c1e9 100644
--- a/test/com/google/inject/TypeLiteralTypeResolutionTest.java
+++ b/test/com/google/inject/TypeLiteralTypeResolutionTest.java
@@ -295,6 +295,23 @@
         type.getSupertype(AbstractCollection.class));
   }
 
+  public void testWildcards() throws NoSuchFieldException {
+    TypeLiteral<Parameterized<String>> ofString = new TypeLiteral<Parameterized<String>>() {};
+
+    assertEquals(new TypeLiteral<List<String>>() {}.getType(),
+        ofString.getFieldType(Parameterized.class.getField("t")));
+    assertEquals(new TypeLiteral<List<? extends String>>() {}.getType(),
+        ofString.getFieldType(Parameterized.class.getField("extendsT")));
+    assertEquals(new TypeLiteral<List<? super String>>() {}.getType(),
+        ofString.getFieldType(Parameterized.class.getField("superT")));
+  }
+
+  static class Parameterized<T> {
+    public List<T> t;
+    public List<? extends T> extendsT;
+    public List<? super T> superT;
+  }
+
   // TODO(jessewilson): tests for tricky bounded types like <T extends Collection, Serializable>
   // TODO(jessewilson): tests for wildcard types