Avoid getDeclarationAndTypeAttributes in ClassAndMethod

Use NullnessAnnotations.fromAnnotationsOn directly instead, which implements
the same logic of checking method return types, and handling both declaration
and type annotation forms of nullness annotations.

This is pre-work for unknown commit.

PiperOrigin-RevId: 852768269
diff --git a/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/AbstractNullnessPropagationTransfer.java b/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/AbstractNullnessPropagationTransfer.java
index 43f11cb..4be1236 100644
--- a/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/AbstractNullnessPropagationTransfer.java
+++ b/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/AbstractNullnessPropagationTransfer.java
@@ -307,7 +307,7 @@
      * if I'm careful to give it its correct Nullness instead of hardcoding it to NONNULL as the
      * current code does. To avoid problems, we return a RegularTransferResult when possible.
      */
-    if (tryGetMethodSymbol(node.getTree(), null).isBoolean) {
+    if (tryGetMethodSymbol(node.getTree(), null).isBoolean()) {
       ResultingStore thenStore = updateStore(input.getThenStore(), thenUpdates, bothUpdates);
       ResultingStore elseStore = updateStore(input.getElseStore(), elseUpdates, bothUpdates);
       return conditionalResult(
diff --git a/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/MethodInfo.java b/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/MethodInfo.java
index ee64578..20817f4 100644
--- a/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/MethodInfo.java
+++ b/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/MethodInfo.java
@@ -16,8 +16,7 @@
 
 package com.google.errorprone.dataflow.nullnesspropagation;
 
-import com.google.common.collect.ImmutableList;
-import javax.lang.model.element.AnnotationMirror;
+import java.util.Optional;
 
 /** Represents a Java method. Used for custom predicates to match non-null-returning methods. */
 public interface MethodInfo {
@@ -25,7 +24,7 @@
 
   String method();
 
-  ImmutableList<AnnotationMirror> annotations();
+  Optional<Nullness> nullnessFromDirectAnnotations();
 
   boolean isStatic();
 
diff --git a/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/NullnessPropagationTransfer.java b/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/NullnessPropagationTransfer.java
index c7c895c..e837b17 100644
--- a/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/NullnessPropagationTransfer.java
+++ b/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/NullnessPropagationTransfer.java
@@ -17,7 +17,6 @@
 package com.google.errorprone.dataflow.nullnesspropagation;
 
 import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.collect.ImmutableList.toImmutableList;
 import static com.google.common.collect.Iterables.getOnlyElement;
 import static com.google.errorprone.dataflow.nullnesspropagation.Nullness.BOTTOM;
 import static com.google.errorprone.dataflow.nullnesspropagation.Nullness.NONNULL;
@@ -32,7 +31,6 @@
 import com.google.common.base.Preconditions;
 import com.google.common.base.Strings;
 import com.google.common.base.Verify;
-import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.ImmutableSetMultimap;
 import com.google.common.io.Files;
@@ -44,7 +42,6 @@
 import com.google.errorprone.dataflow.AccessPathValues;
 import com.google.errorprone.dataflow.nullnesspropagation.inference.InferredNullability;
 import com.google.errorprone.dataflow.nullnesspropagation.inference.NullnessQualifierInference;
-import com.google.errorprone.util.MoreAnnotations;
 import com.sun.source.tree.BlockTree;
 import com.sun.source.tree.ClassTree;
 import com.sun.source.tree.CompilationUnitTree;
@@ -202,8 +199,7 @@
     @Override
     public boolean test(MethodInfo methodInfo) {
       // Any method explicitly annotated is trusted to behave as advertised.
-      Optional<Nullness> fromAnnotations =
-          NullnessAnnotations.fromAnnotationMirrors(methodInfo.annotations());
+      Optional<Nullness> fromAnnotations = methodInfo.nullnessFromDirectAnnotations();
       if (fromAnnotations.isPresent()) {
         return fromAnnotations.get() == NONNULL;
       }
@@ -568,7 +564,7 @@
   Nullness visitMethodInvocation(
       MethodInvocationNode node, Updates thenUpdates, Updates elseUpdates, Updates bothUpdates) {
     ClassAndMethod callee = tryGetMethodSymbol(node.getTree(), Types.instance(context));
-    if (callee != null && !callee.isStatic) {
+    if (callee != null && !callee.isStatic()) {
       setNonnullIfTrackable(bothUpdates, node.getTarget().getReceiver());
     }
     setUnconditionalArgumentNullness(bothUpdates, node.getArguments(), callee);
@@ -771,8 +767,7 @@
     if (callee == null) {
       return defaultAssumption;
     }
-    Optional<Nullness> declaredNullness =
-        NullnessAnnotations.fromAnnotationMirrors(callee.annotations);
+    Optional<Nullness> declaredNullness = callee.nullnessFromDirectAnnotations();
     if (declaredNullness.isPresent()) {
       return declaredNullness.get();
     }
@@ -782,7 +777,7 @@
     }
 
     Nullness assumedNullness = methodReturnsNonNull.test(callee) ? NONNULL : NULLABLE;
-    if (!callee.isGenericResult) {
+    if (!callee.isGenericResult()) {
       // We only care about inference results for methods that return a type variable.
       return assumedNullness;
     }
@@ -973,50 +968,13 @@
     }
   }
 
-  static final class ClassAndMethod implements Member, MethodInfo {
-    final String clazz;
-    final String method;
-    final ImmutableList<AnnotationMirror> annotations;
-    final boolean isStatic;
-    final boolean isPrimitive;
-    final boolean isBoolean;
-    final boolean isGenericResult;
-    final boolean isNonNullReturning;
-
-    private ClassAndMethod(
-        String clazz,
-        String method,
-        ImmutableList<AnnotationMirror> annotations,
-        boolean isStatic,
-        boolean isPrimitive,
-        boolean isBoolean,
-        boolean isGenericResult,
-        boolean isNonNullReturning) {
-      this.clazz = clazz;
-      this.method = method;
-      this.annotations = annotations;
-      this.isStatic = isStatic;
-      this.isPrimitive = isPrimitive;
-      this.isBoolean = isBoolean;
-      this.isGenericResult = isGenericResult;
-      this.isNonNullReturning = isNonNullReturning;
-    }
+  static final record ClassAndMethod(
+      MethodSymbol methodSymbol, ClassSymbol classSymbol, @Nullable Types types)
+      implements Member, MethodInfo {
 
     static ClassAndMethod make(MethodSymbol methodSymbol, @Nullable Types types) {
-      // TODO(b/71812955): consider just wrapping methodSymbol instead of copying everything out.
-      ImmutableList<AnnotationMirror> annotations =
-          MoreAnnotations.getDeclarationAndTypeAttributes(methodSymbol).collect(toImmutableList());
-
       ClassSymbol clazzSymbol = (ClassSymbol) methodSymbol.owner;
-      return new ClassAndMethod(
-          clazzSymbol.getQualifiedName().toString(),
-          methodSymbol.getSimpleName().toString(),
-          annotations,
-          methodSymbol.isStatic(),
-          methodSymbol.getReturnType().isPrimitive(),
-          methodSymbol.getReturnType().getTag() == BOOLEAN,
-          hasGenericResult(methodSymbol),
-          knownNonNullMethod(methodSymbol, clazzSymbol, types));
+      return new ClassAndMethod(methodSymbol, clazzSymbol, types);
     }
 
     /**
@@ -1055,36 +1013,44 @@
 
     @Override
     public boolean isStatic() {
-      return isStatic;
+      return methodSymbol.isStatic();
     }
 
     MemberName name() {
-      return new MemberName(this.clazz, this.method);
+      return new MemberName(clazz(), method());
     }
 
     @Override
     public String clazz() {
-      return clazz;
+      return classSymbol.getQualifiedName().toString();
     }
 
     @Override
     public String method() {
-      return method;
+      return methodSymbol.getSimpleName().toString();
     }
 
     @Override
-    public ImmutableList<AnnotationMirror> annotations() {
-      return annotations;
+    public Optional<Nullness> nullnessFromDirectAnnotations() {
+      return NullnessAnnotations.fromAnnotationsOn(methodSymbol);
     }
 
     @Override
     public boolean isPrimitive() {
-      return isPrimitive;
+      return methodSymbol.getReturnType().isPrimitive();
     }
 
     @Override
     public boolean isKnownNonNullReturning() {
-      return isNonNullReturning;
+      return knownNonNullMethod(methodSymbol, classSymbol, types);
+    }
+
+    public boolean isGenericResult() {
+      return hasGenericResult(methodSymbol);
+    }
+
+    public boolean isBoolean() {
+      return methodSymbol.getReturnType().hasTag(BOOLEAN);
     }
   }
 
diff --git a/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/TrustingNullnessPropagation.java b/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/TrustingNullnessPropagation.java
index 8eb5537..8702d95 100644
--- a/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/TrustingNullnessPropagation.java
+++ b/check_api/src/main/java/com/google/errorprone/dataflow/nullnesspropagation/TrustingNullnessPropagation.java
@@ -73,8 +73,7 @@
 
     @Override
     public boolean apply(MethodInfo input) {
-      return NullnessAnnotations.fromAnnotationMirrors(input.annotations()).orElse(Nullness.NONNULL)
-          == Nullness.NONNULL;
+      return input.nullnessFromDirectAnnotations().orElse(Nullness.NONNULL) == Nullness.NONNULL;
     }
   }
 }