diff --git a/error-prone-contrib/src/main/java/tech/picnic/errorprone/bugpatterns/util/MoreASTHelpers.java b/error-prone-contrib/src/main/java/tech/picnic/errorprone/bugpatterns/util/MoreASTHelpers.java
index 86251762219..1659478d324 100644
--- a/error-prone-contrib/src/main/java/tech/picnic/errorprone/bugpatterns/util/MoreASTHelpers.java
+++ b/error-prone-contrib/src/main/java/tech/picnic/errorprone/bugpatterns/util/MoreASTHelpers.java
@@ -1,32 +1,34 @@
package tech.picnic.errorprone.bugpatterns.util;
+import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.ImmutableList.toImmutableList;
import com.google.common.collect.ImmutableList;
import com.google.errorprone.VisitorState;
import com.sun.source.tree.ClassTree;
import com.sun.source.tree.MethodTree;
-import com.sun.source.tree.Tree;
/**
- * A set of helper methods for working with the AST.
+ * A collection of helper methods for working with the AST.
*
- *
These helper methods are additions to the ones from {@link
+ *
These methods are additions to the ones found in {@link
* com.google.errorprone.util.ASTHelpers}.
*/
public final class MoreASTHelpers {
private MoreASTHelpers() {}
/**
- * Finds methods with the given name in the enclosing class.
+ * Finds methods with the specified name in given the {@link VisitorState}'s current enclosing
+ * class.
*
* @param methodName The method name to search for.
- * @param state A {@link VisitorState} describing the context in which the given {@link Tree} is
- * to be found.
+ * @param state The {@link VisitorState} from which to derive the enclosing class of interest.
* @return The {@link MethodTree}s of the methods with the given name in the enclosing class.
*/
- public static ImmutableList findMethods(String methodName, VisitorState state) {
- return state.findEnclosing(ClassTree.class).getMembers().stream()
+ public static ImmutableList findMethods(CharSequence methodName, VisitorState state) {
+ ClassTree clazz = state.findEnclosing(ClassTree.class);
+ checkArgument(clazz != null, "Visited node is not enclosed by a class");
+ return clazz.getMembers().stream()
.filter(MethodTree.class::isInstance)
.map(MethodTree.class::cast)
.filter(method -> method.getName().contentEquals(methodName))
@@ -34,14 +36,14 @@ public static ImmutableList findMethods(String methodName, VisitorSt
}
/**
- * Determines if there are any methods with the given name in the enclosing class.
+ * Determines whether there are any methods with the specified name in given the {@link
+ * VisitorState}'s current enclosing class.
*
* @param methodName The method name to search for.
- * @param state A {@link VisitorState} describing the context in which the given {@link Tree} is
- * to be found.
+ * @param state The {@link VisitorState} from which to derive the enclosing class of interest.
* @return Whether there are any methods with the given name in the enclosing class.
*/
- public static boolean isMethodInEnclosingClass(String methodName, VisitorState state) {
+ public static boolean isMethodInEnclosingClass(CharSequence methodName, VisitorState state) {
return !findMethods(methodName, state).isEmpty();
}
}
diff --git a/error-prone-contrib/src/main/java/tech/picnic/errorprone/bugpatterns/util/MoreJUnitMatchers.java b/error-prone-contrib/src/main/java/tech/picnic/errorprone/bugpatterns/util/MoreJUnitMatchers.java
index 732a9454535..276b1c00a6d 100644
--- a/error-prone-contrib/src/main/java/tech/picnic/errorprone/bugpatterns/util/MoreJUnitMatchers.java
+++ b/error-prone-contrib/src/main/java/tech/picnic/errorprone/bugpatterns/util/MoreJUnitMatchers.java
@@ -1,27 +1,26 @@
package tech.picnic.errorprone.bugpatterns.util;
+import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.errorprone.matchers.ChildMultiMatcher.MatchType.AT_LEAST_ONE;
import static com.google.errorprone.matchers.Matchers.annotations;
import static com.google.errorprone.matchers.Matchers.anyOf;
import static com.google.errorprone.matchers.Matchers.isType;
import static tech.picnic.errorprone.bugpatterns.util.MoreMatchers.hasMetaAnnotation;
-import com.google.common.collect.Iterables;
+import com.google.common.collect.ImmutableSet;
+import com.google.errorprone.matchers.AnnotationMatcherUtils;
import com.google.errorprone.matchers.Matcher;
import com.google.errorprone.matchers.MultiMatcher;
import com.google.errorprone.util.ASTHelpers;
import com.sun.source.tree.AnnotationTree;
-import com.sun.source.tree.AssignmentTree;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.MethodTree;
-import com.sun.tools.javac.code.Type;
-import java.util.Optional;
-import javax.lang.model.type.TypeKind;
+import com.sun.source.tree.NewArrayTree;
/**
- * A set of JUnit-specific helper methods and {@link Matcher Matchers}.
+ * A collection of JUnit-specific helper methods and {@link Matcher}s.
*
- * These helper methods are additions to the ones from {@link
+ *
These constants and methods are additions to the ones found in {@link
* com.google.errorprone.matchers.JUnitMatchers}.
*/
public final class MoreJUnitMatchers {
@@ -32,7 +31,6 @@ public final class MoreJUnitMatchers {
anyOf(
isType("org.junit.jupiter.api.Test"),
hasMetaAnnotation("org.junit.jupiter.api.TestTemplate")));
-
/** Matches JUnit setup and teardown methods. */
public static final MultiMatcher SETUP_OR_TEARDOWN_METHOD =
annotations(
@@ -42,7 +40,6 @@ public final class MoreJUnitMatchers {
isType("org.junit.jupiter.api.AfterEach"),
isType("org.junit.jupiter.api.BeforeAll"),
isType("org.junit.jupiter.api.BeforeEach")));
-
/**
* Matches methods that have a {@link org.junit.jupiter.params.provider.MethodSource} annotation.
*/
@@ -52,22 +49,25 @@ public final class MoreJUnitMatchers {
private MoreJUnitMatchers() {}
/**
- * Extracts the name of the JUnit factory method from a {@link
+ * Returns the names of the JUnit value factory methods specified by the given {@link
* org.junit.jupiter.params.provider.MethodSource} annotation.
*
- * @param methodSourceAnnotation The {@link org.junit.jupiter.params.provider.MethodSource}
- * annotation to extract a method name from.
- * @return The name of the factory method referred to in the annotation. Alternatively, {@link
- * Optional#empty()} if there is more than one.
+ * @param methodSourceAnnotation The annotation from which to extract value factory method names.
+ * @return One or more value factory names.
*/
- public static Optional extractSingleFactoryMethodName(
- AnnotationTree methodSourceAnnotation) {
- ExpressionTree attributeExpression =
- ((AssignmentTree) Iterables.getOnlyElement(methodSourceAnnotation.getArguments()))
- .getExpression();
- Type attributeType = ASTHelpers.getType(attributeExpression);
- return attributeType.getKind() == TypeKind.ARRAY
- ? Optional.empty()
- : Optional.of(attributeType.stringValue());
+ static ImmutableSet getMethodSourceFactoryNames(
+ AnnotationTree methodSourceAnnotation, MethodTree method) {
+ ExpressionTree value = AnnotationMatcherUtils.getArgument(methodSourceAnnotation, "value");
+
+ if (!(value instanceof NewArrayTree)) {
+ return ImmutableSet.of(ASTHelpers.constValue(value, String.class));
+ }
+
+ NewArrayTree arrayTree = (NewArrayTree) value;
+ return arrayTree.getInitializers().isEmpty()
+ ? ImmutableSet.of(method.getName().toString())
+ : arrayTree.getInitializers().stream()
+ .map(name -> ASTHelpers.constValue(name, String.class))
+ .collect(toImmutableSet());
}
}
diff --git a/error-prone-contrib/src/main/java/tech/picnic/errorprone/bugpatterns/util/MoreMatchers.java b/error-prone-contrib/src/main/java/tech/picnic/errorprone/bugpatterns/util/MoreMatchers.java
index ad835aa23dd..49748d9127c 100644
--- a/error-prone-contrib/src/main/java/tech/picnic/errorprone/bugpatterns/util/MoreMatchers.java
+++ b/error-prone-contrib/src/main/java/tech/picnic/errorprone/bugpatterns/util/MoreMatchers.java
@@ -8,24 +8,27 @@
import com.sun.tools.javac.code.Symbol;
/**
- * A collection of methods to enhance the use of {@link Matcher}s.
+ * A collection of general-purpose {@link Matcher}s.
*
- * These methods are additions to the ones from {@link Matchers}.
+ *
These methods are additions to the ones found in {@link Matchers}.
*/
public final class MoreMatchers {
private MoreMatchers() {}
/**
- * Determines whether a tree has a meta annotation of the given class name. This includes
- * annotations inherited from superclasses due to {@link java.lang.annotation.Inherited}.
+ * Returns a {@link Matcher} that determines whether a given tree has a meta annotation of the
+ * specified type.
*
- * @param The type of the tree.
- * @param annotationClass The binary class name of the annotation (e.g. "
- * org.jspecify.nullness.Nullable", or "some.package.OuterClassName$InnerClassName")
+ * This includes annotations inherited from superclasses due to {@link
+ * java.lang.annotation.Inherited}.
+ *
+ * @param The type of tree to match against.
+ * @param annotationType The binary type name of the annotation (e.g.
+ * "org.jspecify.nullness.Nullable", or "some.package.OuterClassName$InnerClassName")
* @return A {@link Matcher} that matches trees with the specified meta annotation.
*/
- public static Matcher hasMetaAnnotation(String annotationClass) {
- TypePredicate typePredicate = hasAnnotation(annotationClass);
+ public static Matcher hasMetaAnnotation(String annotationType) {
+ TypePredicate typePredicate = hasAnnotation(annotationType);
return (tree, state) -> {
Symbol sym = ASTHelpers.getSymbol(tree);
return sym != null && typePredicate.apply(sym.type, state);