3131import static com .google .errorprone .util .ASTHelpers .isRecord ;
3232import static com .sun .tools .javac .code .TypeTag .CLASS ;
3333import static com .sun .tools .javac .util .Position .NOPOS ;
34+ import static java .util .Arrays .stream ;
3435import static java .util .stream .Collectors .joining ;
3536
3637import com .google .auto .value .AutoValue ;
3738import com .google .common .annotations .VisibleForTesting ;
3839import com .google .common .base .Joiner ;
3940import com .google .common .base .Objects ;
40- import com .google .common .base .Predicates ;
4141import com .google .common .base .Splitter ;
4242import com .google .common .base .Verify ;
4343import com .google .common .collect .ImmutableList ;
108108import com .sun .tools .javac .util .Position ;
109109import java .io .IOException ;
110110import java .io .UncheckedIOException ;
111- import java .lang .annotation .ElementType ;
112111import java .lang .annotation .Target ;
113112import java .lang .reflect .Method ;
114113import java .net .JarURLConnection ;
129128import java .util .TreeSet ;
130129import java .util .concurrent .atomic .AtomicBoolean ;
131130import java .util .stream .IntStream ;
131+ import java .util .stream .Stream ;
132132import java .util .stream .StreamSupport ;
133133import javax .lang .model .element .Element ;
134134import javax .lang .model .element .ElementKind ;
@@ -1565,25 +1565,28 @@ public static Optional<SuggestedFix> suggestExemptingAnnotation(
15651565 }
15661566 SuggestedFix .Builder builder = SuggestedFix .builder ();
15671567 Type exemptingAnnotationType = state .getTypeFromString (exemptingAnnotation );
1568- ImmutableSet <Tree . Kind > supportedExemptingAnnotationLocationKinds ;
1568+ ImmutableSet <Class <? extends Tree >> supportedExemptingAnnotationLocationTypes ;
15691569 String annotationName ;
15701570
15711571 if (exemptingAnnotationType != null ) {
1572- supportedExemptingAnnotationLocationKinds =
1572+ supportedExemptingAnnotationLocationTypes =
15731573 supportedTreeTypes (exemptingAnnotationType .asElement ());
15741574 annotationName = qualifyType (state , builder , exemptingAnnotationType );
15751575 } else {
15761576 // If we can't resolve the type, fall back to an approximation.
15771577 int idx = exemptingAnnotation .lastIndexOf ('.' );
15781578 Verify .verify (idx > 0 && idx + 1 < exemptingAnnotation .length ());
1579- supportedExemptingAnnotationLocationKinds = TREE_TYPE_UNKNOWN_ANNOTATION ;
1579+ supportedExemptingAnnotationLocationTypes = TREE_TYPE_UNKNOWN_ANNOTATION ;
15801580 annotationName = exemptingAnnotation .substring (idx + 1 );
15811581 builder .addImport (exemptingAnnotation );
15821582 }
15831583 Optional <Tree > exemptingAnnotationLocation =
15841584 stream (where )
1585- .filter (tree -> supportedExemptingAnnotationLocationKinds .contains (tree .getKind ()))
1586- .filter (Predicates .not (SuggestedFixes ::isAnonymousClassTree ))
1585+ .filter (
1586+ tree ->
1587+ supportedExemptingAnnotationLocationTypes .stream ()
1588+ .anyMatch (clazz -> clazz .isInstance (tree ))
1589+ && !isAnonymousClassTree (tree ))
15871590 .findFirst ();
15881591
15891592 return exemptingAnnotationLocation .map (
@@ -1600,37 +1603,31 @@ private static boolean isAnonymousClassTree(Tree t) {
16001603 * <p>These are reasonable for exempting annotations which annotate a block of code, e.g. they
16011604 * don't usually make sense on a variable declaration.
16021605 */
1603- private static final ImmutableSet <Tree .Kind > TREE_TYPE_UNKNOWN_ANNOTATION =
1604- ImmutableSet .of (
1605- Tree .Kind .CLASS ,
1606- Tree .Kind .ENUM ,
1607- Tree .Kind .INTERFACE ,
1608- Tree .Kind .ANNOTATION_TYPE ,
1609- Tree .Kind .METHOD );
1606+ private static final ImmutableSet <Class <? extends Tree >> TREE_TYPE_UNKNOWN_ANNOTATION =
1607+ ImmutableSet .of (ClassTree .class , MethodTree .class );
16101608
16111609 /** Returns true iff {@code suggestExemptingAnnotation()} supports this annotation. */
16121610 public static boolean suggestedExemptingAnnotationSupported (Element exemptingAnnotation ) {
16131611 return !supportedTreeTypes (exemptingAnnotation ).isEmpty ();
16141612 }
16151613
1616- private static ImmutableSet <Tree .Kind > supportedTreeTypes (Element exemptingAnnotation ) {
1614+ private static ImmutableSet <Class <? extends Tree >> supportedTreeTypes (
1615+ Element exemptingAnnotation ) {
16171616 Target targetAnnotation = exemptingAnnotation .getAnnotation (Target .class );
16181617 if (targetAnnotation == null ) {
16191618 // in the absence of further information, we assume the annotation is supported on classes and
16201619 // methods.
16211620 return TREE_TYPE_UNKNOWN_ANNOTATION ;
16221621 }
1623- ImmutableSet .Builder <Tree .Kind > types = ImmutableSet .builder ();
1624- for (ElementType t : targetAnnotation .value ()) {
1625- switch (t ) {
1626- case TYPE ->
1627- types .add (
1628- Tree .Kind .CLASS , Tree .Kind .ENUM , Tree .Kind .INTERFACE , Tree .Kind .ANNOTATION_TYPE );
1629- case METHOD -> types .add (Tree .Kind .METHOD );
1630- default -> {}
1631- }
1632- }
1633- return types .build ();
1622+ return stream (targetAnnotation .value ())
1623+ .flatMap (
1624+ t ->
1625+ switch (t ) {
1626+ case TYPE -> Stream .of (ClassTree .class );
1627+ case METHOD -> Stream .of (MethodTree .class );
1628+ default -> Stream .empty ();
1629+ })
1630+ .collect (toImmutableSet ());
16341631 }
16351632
16361633 /**
0 commit comments