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 + "\n Class:\t " + ArrayList .class .getCanonicalName ())
164+ .that (MoreTypes .isTypeOf (ArrayList .class , type ))
165+ .isTrue ();
166+ assertWithMessage ("Mirror:\t " + type + "\n Class:\t " + List .class .getCanonicalName ())
167+ .that (MoreTypes .isTypeOf (List .class , type ))
168+ .isTrue ();
169+ assertWithMessage ("Mirror:\t " + type + "\n Class:\t " + String .class .getCanonicalName ())
170+ .that (MoreTypes .isTypeOf (String .class , type ))
171+ .isFalse ();
172+ assertWithMessage ("Mirror:\t " + type + "\n Class:\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 + "\n Class:\t " + ArrayList [].class .getCanonicalName ())
178+ .that (MoreTypes .isTypeOf (ArrayList [].class , type ))
179+ .isTrue ();
180+ assertWithMessage ("Mirror:\t " + type + "\n Class:\t " + List [].class .getCanonicalName ())
181+ .that (MoreTypes .isTypeOf (List [].class , type ))
182+ .isTrue ();
183+ assertWithMessage ("Mirror:\t " + type + "\n Class:\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 + "\n Class:\t " + SortedMap .class .getCanonicalName ())
193+ .that (MoreTypes .isTypeOf (SortedMap .class , type ))
194+ .isTrue ();
195+ assertWithMessage ("Mirror:\t " + type + "\n Class:\t " + Map .class .getCanonicalName ())
196+ .that (MoreTypes .isTypeOf (Map .class , type ))
197+ .isTrue ();
198+ assertWithMessage ("Mirror:\t " + type + "\n Class:\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 + "\n Class:\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 + "\n Class:\t " + SortedMap .class .getCanonicalName ())
215+ .that (MoreTypes .isTypeOf (SortedMap .class , type ))
216+ .isTrue ();
217+ assertWithMessage ("Mirror:\t " + type + "\n Class:\t " + Map .class .getCanonicalName ())
218+ .that (MoreTypes .isTypeOf (Map .class , type ))
219+ .isTrue ();
220+ assertWithMessage ("Mirror:\t " + type + "\n Class:\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 + "\n Class:\t " + SortedMap .class .getCanonicalName ())
258+ .that (MoreTypes .isTypeOf (SortedMap .class , type ))
259+ .isTrue ();
260+ assertWithMessage ("Mirror:\t " + type + "\n Class:\t " + Map .class .getCanonicalName ())
261+ .that (MoreTypes .isTypeOf (Map .class , type ))
262+ .isTrue ();
263+ assertWithMessage ("Mirror:\t " + type + "\n Class:\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 + "\n Class:\t " + List .class .getCanonicalName ())
273+ .that (MoreTypes .isTypeOf (List .class , type ))
274+ .isTrue ();
275+ assertWithMessage ("Mirror:\t " + type + "\n Class:\t " + RandomAccess .class .getCanonicalName ())
276+ .that (MoreTypes .isTypeOf (RandomAccess .class , type ))
277+ .isTrue ();
278+ assertWithMessage ("Mirror:\t " + type + "\n Class:\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