21
21
import static javax .lang .model .type .TypeKind .ARRAY ;
22
22
import static javax .lang .model .type .TypeKind .DECLARED ;
23
23
import static javax .lang .model .type .TypeKind .EXECUTABLE ;
24
+ import static javax .lang .model .type .TypeKind .INTERSECTION ;
24
25
import static javax .lang .model .type .TypeKind .TYPEVAR ;
25
26
import static javax .lang .model .type .TypeKind .WILDCARD ;
26
27
27
28
import com .google .common .base .Equivalence ;
28
29
import com .google .common .base .Objects ;
29
30
import com .google .common .base .Optional ;
30
31
import com .google .common .base .Predicate ;
31
- import com .google .common .base .Throwables ;
32
32
import com .google .common .collect .FluentIterable ;
33
33
import com .google .common .collect .ImmutableList ;
34
34
import com .google .common .collect .ImmutableSet ;
35
- import java .lang .reflect .Method ;
36
35
import java .util .HashSet ;
37
36
import java .util .Iterator ;
38
37
import java .util .List ;
48
47
import javax .lang .model .type .DeclaredType ;
49
48
import javax .lang .model .type .ErrorType ;
50
49
import javax .lang .model .type .ExecutableType ;
50
+ import javax .lang .model .type .IntersectionType ;
51
51
import javax .lang .model .type .NoType ;
52
52
import javax .lang .model .type .NullType ;
53
53
import javax .lang .model .type .PrimitiveType ;
@@ -224,6 +224,15 @@ && equalLists(a.getThrownTypes(), b.getThrownTypes(), p.visiting)
224
224
return false ;
225
225
}
226
226
227
+ @ Override
228
+ public Boolean visitIntersection (IntersectionType a , EqualVisitorParam p ) {
229
+ if (p .type .getKind ().equals (INTERSECTION )) {
230
+ IntersectionType b = (IntersectionType ) p .type ;
231
+ return equalLists (a .getBounds (), b .getBounds (), p .visiting );
232
+ }
233
+ return false ;
234
+ }
235
+
227
236
@ Override
228
237
public Boolean visitTypeVariable (TypeVariable a , EqualVisitorParam p ) {
229
238
if (p .type .getKind ().equals (TYPEVAR )) {
@@ -286,23 +295,6 @@ private Set<ComparedElements> visitingSetPlus(
286
295
}
287
296
}
288
297
289
- private static final Class <?> INTERSECTION_TYPE ;
290
- private static final Method GET_BOUNDS ;
291
-
292
- static {
293
- Class <?> c ;
294
- Method m ;
295
- try {
296
- c = Class .forName ("javax.lang.model.type.IntersectionType" );
297
- m = c .getMethod ("getBounds" );
298
- } catch (Exception e ) {
299
- c = null ;
300
- m = null ;
301
- }
302
- INTERSECTION_TYPE = c ;
303
- GET_BOUNDS = m ;
304
- }
305
-
306
298
private static boolean equal (TypeMirror a , TypeMirror b , Set <ComparedElements > visiting ) {
307
299
// TypeMirror.equals is not guaranteed to return true for types that are equal, but we can
308
300
// assume that if it does return true then the types are equal. This check also avoids getting
@@ -317,13 +309,6 @@ private static boolean equal(TypeMirror a, TypeMirror b, Set<ComparedElements> v
317
309
EqualVisitorParam p = new EqualVisitorParam ();
318
310
p .type = b ;
319
311
p .visiting = visiting ;
320
- if (INTERSECTION_TYPE != null ) {
321
- if (isIntersectionType (a )) {
322
- return equalIntersectionTypes (a , b , visiting );
323
- } else if (isIntersectionType (b )) {
324
- return false ;
325
- }
326
- }
327
312
return (a == b ) || (a != null && b != null && a .accept (EqualVisitor .INSTANCE , p ));
328
313
}
329
314
@@ -343,34 +328,6 @@ private static TypeMirror enclosingType(DeclaredType t) {
343
328
return enclosing ;
344
329
}
345
330
346
- private static boolean isIntersectionType (TypeMirror t ) {
347
- return t != null && t .getKind ().name ().equals ("INTERSECTION" );
348
- }
349
-
350
- // The representation of an intersection type, as in <T extends Number & Comparable<T>>, changed
351
- // between Java 7 and Java 8. In Java 7 it was modeled as a fake DeclaredType, and our logic
352
- // for DeclaredType does the right thing. In Java 8 it is modeled as a new type IntersectionType.
353
- // In order for our code to run on Java 7 (and Java 6) we can't even mention IntersectionType,
354
- // so we can't override visitIntersectionType(IntersectionType). Instead, we discover through
355
- // reflection whether IntersectionType exists, and if it does we extract the bounds of the
356
- // intersection ((Number, Comparable<T>) in the example) and compare them directly.
357
- @ SuppressWarnings ("unchecked" )
358
- private static boolean equalIntersectionTypes (
359
- TypeMirror a , TypeMirror b , Set <ComparedElements > visiting ) {
360
- if (!isIntersectionType (b )) {
361
- return false ;
362
- }
363
- List <? extends TypeMirror > aBounds ;
364
- List <? extends TypeMirror > bBounds ;
365
- try {
366
- aBounds = (List <? extends TypeMirror >) GET_BOUNDS .invoke (a );
367
- bBounds = (List <? extends TypeMirror >) GET_BOUNDS .invoke (b );
368
- } catch (Exception e ) {
369
- throw Throwables .propagate (e );
370
- }
371
- return equalLists (aBounds , bBounds , visiting );
372
- }
373
-
374
331
private static boolean equalLists (
375
332
List <? extends TypeMirror > a , List <? extends TypeMirror > b , Set <ComparedElements > visiting ) {
376
333
int size = a .size ();
@@ -595,8 +552,8 @@ public static ImmutableSet<TypeElement> asTypeElements(Iterable<? extends TypeMi
595
552
}
596
553
597
554
/**
598
- * Returns a {@link ArrayType} if the {@link TypeMirror} represents a primitive array or throws an
599
- * {@link IllegalArgumentException}.
555
+ * Returns a {@link ArrayType} if the {@link TypeMirror} represents an array or throws an {@link
556
+ * IllegalArgumentException}.
600
557
*/
601
558
public static ArrayType asArray (TypeMirror maybeArrayType ) {
602
559
return maybeArrayType .accept (ArrayTypeVisitor .INSTANCE , null );
@@ -606,7 +563,7 @@ private static final class ArrayTypeVisitor extends CastingTypeVisitor<ArrayType
606
563
private static final ArrayTypeVisitor INSTANCE = new ArrayTypeVisitor ();
607
564
608
565
ArrayTypeVisitor () {
609
- super ("primitive array" );
566
+ super ("array" );
610
567
}
611
568
612
569
@ Override
@@ -678,6 +635,27 @@ public ExecutableType visitExecutable(ExecutableType type, Void ignore) {
678
635
}
679
636
}
680
637
638
+ /**
639
+ * Returns an {@link IntersectionType} if the {@link TypeMirror} represents an intersection-type
640
+ * or throws an {@link IllegalArgumentException}.
641
+ */
642
+ public static IntersectionType asIntersection (TypeMirror maybeIntersectionType ) {
643
+ return maybeIntersectionType .accept (IntersectionTypeVisitor .INSTANCE , null );
644
+ }
645
+
646
+ private static final class IntersectionTypeVisitor extends CastingTypeVisitor <IntersectionType > {
647
+ private static final IntersectionTypeVisitor INSTANCE = new IntersectionTypeVisitor ();
648
+
649
+ IntersectionTypeVisitor () {
650
+ super ("intersection type" );
651
+ }
652
+
653
+ @ Override
654
+ public IntersectionType visitIntersection (IntersectionType type , Void ignore ) {
655
+ return type ;
656
+ }
657
+ }
658
+
681
659
/**
682
660
* Returns a {@link NoType} if the {@link TypeMirror} represents an non-type such as void, or
683
661
* package, etc. or throws an {@link IllegalArgumentException}.
@@ -742,7 +720,7 @@ public PrimitiveType visitPrimitive(PrimitiveType type, Void ignore) {
742
720
}
743
721
744
722
//
745
- // visitUnionType would go here, but it is a 1.7 API.
723
+ // visitUnionType would go here, but isn't relevant for annotation processors
746
724
//
747
725
748
726
/**
0 commit comments