2323import com.google.common.collect.ImmutableList;
2424import com.google.common.collect.Iterables;
2525import com.google.testing.compile.CompilationRule;
26+ import java.util.ArrayList;
27+ import java.util.LinkedList;
2628import java.util.List;
29+ import java.util.Map;
30+ import java.util.NavigableMap;
31+ import java.util.RandomAccess;
2732import java.util.SortedMap;
33+ import javax.lang.model.element.ExecutableElement;
2834import javax.lang.model.element.TypeElement;
2935import javax.lang.model.type.TypeKind;
3036import javax.lang.model.type.TypeMirror;
@@ -148,9 +154,81 @@ public void isTypeOf_arrayType() {
148154 .isTrue();
149155 }
150156
157+ @Test
158+ // ArrayList is a list because its parent implements List (checking interface and direct ancestry)
159+ public void isTypeOf_listLineage() {
160+ TypeMirror type =
161+ typeUtils.getDeclaredType(
162+ getTypeElementFor(ArrayList.class), getTypeElementFor(String.class).asType());
163+ assertWithMessage("Mirror:\t" + type + "\nClass:\t" + ArrayList.class.getCanonicalName())
164+ .that(MoreTypes.isTypeOf(ArrayList.class, type))
165+ .isTrue();
166+ assertWithMessage("Mirror:\t" + type + "\nClass:\t" + List.class.getCanonicalName())
167+ .that(MoreTypes.isTypeOf(List.class, type))
168+ .isTrue();
169+ assertWithMessage("Mirror:\t" + type + "\nClass:\t" + String.class.getCanonicalName())
170+ .that(MoreTypes.isTypeOf(String.class, type))
171+ .isFalse();
172+ assertWithMessage("Mirror:\t" + type + "\nClass:\t" + LinkedList.class.getCanonicalName())
173+ .that(MoreTypes.isTypeOf(LinkedList.class, type))
174+ .isFalse();
175+
176+ type = typeUtils.getArrayType(type); // ArrayList<String>[]
177+ assertWithMessage("Mirror:\t" + type + "\nClass:\t" + ArrayList[].class.getCanonicalName())
178+ .that(MoreTypes.isTypeOf(ArrayList[].class, type))
179+ .isTrue();
180+ assertWithMessage("Mirror:\t" + type + "\nClass:\t" + List[].class.getCanonicalName())
181+ .that(MoreTypes.isTypeOf(List[].class, type))
182+ .isTrue();
183+ assertWithMessage("Mirror:\t" + type + "\nClass:\t" + LinkedList[].class.getCanonicalName())
184+ .that(MoreTypes.isTypeOf(LinkedList[].class, type))
185+ .isFalse();
186+ }
187+
188+ @Test
189+ // NavigableMap implements SortedMap and SortedMap implements Map (checking interface ancestry)
190+ public void isTypeOf_mapLineage() {
191+ TypeMirror type = getTypeElementFor(SortedMap.class).asType();
192+ assertWithMessage("Mirror:\t" + type + "\nClass:\t" + SortedMap.class.getCanonicalName())
193+ .that(MoreTypes.isTypeOf(SortedMap.class, type))
194+ .isTrue();
195+ assertWithMessage("Mirror:\t" + type + "\nClass:\t" + Map.class.getCanonicalName())
196+ .that(MoreTypes.isTypeOf(Map.class, type))
197+ .isTrue();
198+ assertWithMessage("Mirror:\t" + type + "\nClass:\t" + NavigableMap.class.getCanonicalName())
199+ .that(MoreTypes.isTypeOf(NavigableMap.class, type))
200+ .isFalse();
201+
202+ // Testing ancestor that is not a direct parent
203+ type = getTypeElementFor(NavigableMap.class).asType();
204+ assertWithMessage("Mirror:\t" + type + "\nClass:\t" + Map.class.getCanonicalName())
205+ .that(MoreTypes.isTypeOf(Map.class, type))
206+ .isTrue();
207+ }
208+
209+ @Test
210+ public void isTypeOf_wildcardCapture() {
211+ TypeMirror type =
212+ typeUtils.getWildcardType(
213+ getTypeElementFor(SortedMap.class).asType(), null); // ? extends SortedMap
214+ assertWithMessage("Mirror:\t" + type + "\nClass:\t" + SortedMap.class.getCanonicalName())
215+ .that(MoreTypes.isTypeOf(SortedMap.class, type))
216+ .isTrue();
217+ assertWithMessage("Mirror:\t" + type + "\nClass:\t" + Map.class.getCanonicalName())
218+ .that(MoreTypes.isTypeOf(Map.class, type))
219+ .isTrue();
220+ assertWithMessage("Mirror:\t" + type + "\nClass:\t" + NavigableMap.class.getCanonicalName())
221+ .that(MoreTypes.isTypeOf(NavigableMap.class, type))
222+ .isFalse();
223+ }
224+
151225 private interface TestType {
152226 @SuppressWarnings("unused")
153227 <T extends SortedMap<Number, String>> T method0();
228+
229+ @SuppressWarnings("unused")
230+ <RANDOM_ACCESS_LIST extends List<?> & RandomAccess> void method1(
231+ RANDOM_ACCESS_LIST randomAccessList);
154232 }
155233
156234 @Test
@@ -167,13 +245,49 @@ public void isTypeOf_declaredType() {
167245 .isFalse();
168246 }
169247
248+ @Test
249+ public void isTypeOf_typeParameterCapture() {
250+ assertTrue(MoreTypes.isType(getTypeElementFor(TestType.class).asType()));
251+
252+ // Getting the type parameter of method0
253+ ExecutableElement executableElement =
254+ MoreElements.asExecutable(getTypeElementFor(TestType.class).getEnclosedElements().get(0));
255+ TypeMirror type = Iterables.getOnlyElement(executableElement.getTypeParameters()).asType();
256+
257+ assertWithMessage("Mirror:\t" + type + "\nClass:\t" + SortedMap.class.getCanonicalName())
258+ .that(MoreTypes.isTypeOf(SortedMap.class, type))
259+ .isTrue();
260+ assertWithMessage("Mirror:\t" + type + "\nClass:\t" + Map.class.getCanonicalName())
261+ .that(MoreTypes.isTypeOf(Map.class, type))
262+ .isTrue();
263+ assertWithMessage("Mirror:\t" + type + "\nClass:\t" + NavigableMap.class.getCanonicalName())
264+ .that(MoreTypes.isTypeOf(NavigableMap.class, type))
265+ .isFalse();
266+
267+ // Getting parameter type of method1 and checking for intersection type
268+ executableElement =
269+ MoreElements.asExecutable(getTypeElementFor(TestType.class).getEnclosedElements().get(1));
270+ type = Iterables.getOnlyElement(executableElement.getParameters()).asType();
271+
272+ assertWithMessage("Mirror:\t" + type + "\nClass:\t" + List.class.getCanonicalName())
273+ .that(MoreTypes.isTypeOf(List.class, type))
274+ .isTrue();
275+ assertWithMessage("Mirror:\t" + type + "\nClass:\t" + RandomAccess.class.getCanonicalName())
276+ .that(MoreTypes.isTypeOf(RandomAccess.class, type))
277+ .isTrue();
278+ assertWithMessage("Mirror:\t" + type + "\nClass:\t" + ArrayList.class.getCanonicalName())
279+ .that(MoreTypes.isTypeOf(ArrayList.class, type))
280+ .isFalse();
281+ }
282+
170283 @Test
171284 public void isTypeOf_fail() {
172- TypeMirror methodType =
173- Iterables.getOnlyElement(getTypeElementFor(TestType.class).getEnclosedElements()).asType();
174- assertFalse(MoreTypes.isType(methodType));
285+ assertFalse(
286+ MoreTypes.isType(getTypeElementFor(TestType.class).getEnclosedElements().get(0).asType()));
287+ TypeMirror method1Type =
288+ getTypeElementFor(TestType.class).getEnclosedElements().get(1).asType();
175289 try {
176- MoreTypes.isTypeOf(List.class, methodType );
290+ MoreTypes.isTypeOf(List.class, method1Type );
177291 fail();
178292 } catch (IllegalArgumentException expected) {
179293 }
0 commit comments