mirror of
https://github.com/jlengrand/error-prone-support.git
synced 2026-03-10 08:11:25 +00:00
Compare commits
43 Commits
nkooij/moc
...
sschroever
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
62d144550d | ||
|
|
d014fed400 | ||
|
|
1357f60fbc | ||
|
|
03abbbf99c | ||
|
|
9b845782c2 | ||
|
|
08ce33fb19 | ||
|
|
182724bc8e | ||
|
|
e9d361713a | ||
|
|
b754880556 | ||
|
|
affd5c7b93 | ||
|
|
d86611e66a | ||
|
|
2d6100a679 | ||
|
|
912797a55a | ||
|
|
d097f31124 | ||
|
|
eb05582f79 | ||
|
|
964fc35b71 | ||
|
|
ddc05bf88c | ||
|
|
24afa6a755 | ||
|
|
8e97121bdf | ||
|
|
567c81a93d | ||
|
|
c0bfac7b4c | ||
|
|
28138f35eb | ||
|
|
a9b691b856 | ||
|
|
acfe87fbc4 | ||
|
|
091a6eee7a | ||
|
|
3c06e3ead3 | ||
|
|
3ecab2f4b9 | ||
|
|
4b3e79667d | ||
|
|
6505535525 | ||
|
|
e48bbf3a44 | ||
|
|
3391468746 | ||
|
|
10172c426d | ||
|
|
f2737b4fe9 | ||
|
|
f9a1c82d68 | ||
|
|
cbc886d0c2 | ||
|
|
e4e3aded84 | ||
|
|
e84d0e1059 | ||
|
|
5e763d06d0 | ||
|
|
ec05456c96 | ||
|
|
f53c47b56f | ||
|
|
8a4c6e1209 | ||
|
|
89033e2216 | ||
|
|
4dc955a976 |
@@ -11,10 +11,11 @@ install:
|
||||
script:
|
||||
# We run the build twice: once against the original Error Prone release,
|
||||
# using only Error Prone checks available on Maven Central, and once against
|
||||
# the Picnic Error Prone fork, additionally enabling Error Prone checks
|
||||
# available from other artifact repositories.
|
||||
# the Picnic Error Prone fork, additionally enabling all checks defined in
|
||||
# this project and any Error Prone checks available only from other artifact
|
||||
# repositories.
|
||||
- ./mvnw clean install
|
||||
- ./mvnw clean install -Perror-prone-fork -Pnon-maven-central -s settings.xml
|
||||
- ./mvnw clean install -Perror-prone-fork -Pnon-maven-central -Pself-check -s settings.xml
|
||||
# XXX: Enable SonarCloud once we "go public".
|
||||
# ./mvnw jacoco:prepare-agent surefire:test jacoco:report sonar:sonar
|
||||
- ./mvnw jacoco:prepare-agent surefire:test jacoco:report
|
||||
|
||||
@@ -47,6 +47,10 @@
|
||||
`annotationProcessorPaths` configuration below. -->
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>refaster-support</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
@@ -102,6 +106,11 @@
|
||||
<artifactId>swagger-annotations</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.servlet</groupId>
|
||||
<artifactId>jakarta.servlet-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
@@ -196,12 +205,28 @@
|
||||
<artifactId>refaster-resource-compiler</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</path>
|
||||
<path>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>refaster-support</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
<compilerArgs combine.children="append">
|
||||
<arg>-Xplugin:RefasterRuleResourceCompiler</arg>
|
||||
</compilerArgs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<configuration>
|
||||
<ignoredUnusedDeclaredDependencies>
|
||||
<!-- XXX: Figure out why the plugin thinks this
|
||||
dependency is unused. -->
|
||||
<ignoredUnusedDeclaredDependency>${project.groupId}:refaster-support</ignoredUnusedDeclaredDependency>
|
||||
</ignoredUnusedDeclaredDependencies>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.matchers.Matchers.isType;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.BugPattern.LinkType;
|
||||
import com.google.errorprone.BugPattern.SeverityLevel;
|
||||
import com.google.errorprone.BugPattern.StandardTags;
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
import com.google.errorprone.bugpatterns.BugChecker.AnnotationTreeMatcher;
|
||||
import com.google.errorprone.fixes.SuggestedFix;
|
||||
import com.google.errorprone.matchers.Description;
|
||||
import com.google.errorprone.matchers.Matcher;
|
||||
import com.google.errorprone.util.ASTHelpers;
|
||||
import com.sun.source.tree.AnnotationTree;
|
||||
import com.sun.source.tree.ClassTree;
|
||||
import com.sun.source.tree.MethodTree;
|
||||
import com.sun.source.tree.Tree;
|
||||
import com.sun.tools.javac.code.Symbol;
|
||||
import java.util.Map;
|
||||
import javax.lang.model.element.AnnotationValue;
|
||||
|
||||
/** A {@link BugChecker} which flags ambiguous {@code @JsonCreator}s in enums. */
|
||||
@AutoService(BugChecker.class)
|
||||
@BugPattern(
|
||||
name = "AmbiguousJsonCreator",
|
||||
summary = "`JsonCreator.Mode` should be set for single-argument creators",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.WARNING,
|
||||
tags = StandardTags.LIKELY_ERROR)
|
||||
public final class AmbiguousJsonCreatorCheck extends BugChecker implements AnnotationTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Matcher<AnnotationTree> IS_JSON_CREATOR_ANNOTATION =
|
||||
isType("com.fasterxml.jackson.annotation.JsonCreator");
|
||||
|
||||
@Override
|
||||
public Description matchAnnotation(AnnotationTree tree, VisitorState state) {
|
||||
if (!IS_JSON_CREATOR_ANNOTATION.matches(tree, state)) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
ClassTree clazz = state.findEnclosing(ClassTree.class);
|
||||
if (clazz == null || clazz.getKind() != Tree.Kind.ENUM) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
MethodTree method = state.findEnclosing(MethodTree.class);
|
||||
if (method == null || method.getParameters().size() != 1) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
boolean customMode =
|
||||
ASTHelpers.getAnnotationMirror(tree).getElementValues().entrySet().stream()
|
||||
.filter(entry -> entry.getKey().getSimpleName().contentEquals("mode"))
|
||||
.map(Map.Entry::getValue)
|
||||
.map(AnnotationValue::getValue)
|
||||
.filter(Symbol.VarSymbol.class::isInstance)
|
||||
.map(Symbol.VarSymbol.class::cast)
|
||||
.anyMatch(varSymbol -> !varSymbol.getSimpleName().contentEquals("DEFAULT"));
|
||||
|
||||
return customMode
|
||||
? Description.NO_MATCH
|
||||
: describeMatch(
|
||||
tree, SuggestedFix.replace(tree, "@JsonCreator(mode = JsonCreator.Mode.DELEGATING)"));
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,6 @@ import com.google.auto.service.AutoService;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.BugPattern.LinkType;
|
||||
import com.google.errorprone.BugPattern.ProvidesFix;
|
||||
import com.google.errorprone.BugPattern.SeverityLevel;
|
||||
import com.google.errorprone.BugPattern.StandardTags;
|
||||
import com.google.errorprone.VisitorState;
|
||||
@@ -31,8 +30,7 @@ import java.util.List;
|
||||
summary = "Omit `@Autowired` on a class' sole constructor, as it is redundant",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.SUGGESTION,
|
||||
tags = StandardTags.SIMPLIFICATION,
|
||||
providesFix = ProvidesFix.REQUIRES_HUMAN_ATTENTION)
|
||||
tags = StandardTags.SIMPLIFICATION)
|
||||
public final class AutowiredConstructorCheck extends BugChecker implements ClassTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final MultiMatcher<Tree, AnnotationTree> AUTOWIRED_ANNOTATION =
|
||||
|
||||
@@ -4,7 +4,6 @@ import com.google.auto.service.AutoService;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.BugPattern.LinkType;
|
||||
import com.google.errorprone.BugPattern.ProvidesFix;
|
||||
import com.google.errorprone.BugPattern.SeverityLevel;
|
||||
import com.google.errorprone.BugPattern.StandardTags;
|
||||
import com.google.errorprone.VisitorState;
|
||||
@@ -33,8 +32,7 @@ import java.util.regex.Pattern;
|
||||
summary = "Omit redundant syntax from annotation declarations",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.SUGGESTION,
|
||||
tags = StandardTags.SIMPLIFICATION,
|
||||
providesFix = ProvidesFix.REQUIRES_HUMAN_ATTENTION)
|
||||
tags = StandardTags.SIMPLIFICATION)
|
||||
public final class CanonicalAnnotationSyntaxCheck extends BugChecker
|
||||
implements AnnotationTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -28,11 +28,10 @@ import com.sun.tools.javac.code.Symbol.MethodSymbol;
|
||||
summary = "Empty method can likely be deleted",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.SUGGESTION,
|
||||
tags = StandardTags.SIMPLIFICATION,
|
||||
providesFix = BugPattern.ProvidesFix.REQUIRES_HUMAN_ATTENTION)
|
||||
tags = StandardTags.SIMPLIFICATION)
|
||||
public final class EmptyMethodCheck extends BugChecker implements MethodTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Matcher<Tree> HAS_PERMITTED_ANNOTATION =
|
||||
private static final Matcher<Tree> PERMITTED_ANNOTATION =
|
||||
annotations(
|
||||
AT_LEAST_ONE,
|
||||
anyOf(isType("java.lang.Override"), isType("org.aspectj.lang.annotation.Pointcut")));
|
||||
@@ -42,7 +41,7 @@ public final class EmptyMethodCheck extends BugChecker implements MethodTreeMatc
|
||||
if (tree.getBody() == null
|
||||
|| !tree.getBody().getStatements().isEmpty()
|
||||
|| ASTHelpers.containsComments(tree, state)
|
||||
|| HAS_PERMITTED_ANNOTATION.matches(tree, state)) {
|
||||
|| PERMITTED_ANNOTATION.matches(tree, state)) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
import static com.google.common.collect.ImmutableSetMultimap.toImmutableSetMultimap;
|
||||
import static com.google.errorprone.matchers.method.MethodMatchers.staticMethod;
|
||||
import static java.util.stream.Collectors.collectingAndThen;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSetMultimap;
|
||||
import com.google.common.collect.Multimaps;
|
||||
import com.google.common.collect.Ordering;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.BugPattern.LinkType;
|
||||
import com.google.errorprone.BugPattern.SeverityLevel;
|
||||
import com.google.errorprone.BugPattern.StandardTags;
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
import com.google.errorprone.bugpatterns.BugChecker.MethodInvocationTreeMatcher;
|
||||
import com.google.errorprone.matchers.Description;
|
||||
import com.google.errorprone.matchers.Matcher;
|
||||
import com.google.errorprone.util.ASTHelpers;
|
||||
import com.sun.source.tree.ExpressionTree;
|
||||
import com.sun.source.tree.MethodInvocationTree;
|
||||
import com.sun.tools.javac.code.Symbol;
|
||||
import com.sun.tools.javac.code.Type;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* A {@link BugChecker} which flags {@link Ordering#explicit(Object, Object[])}} invocations listing
|
||||
* a subset of an enum type's values.
|
||||
*/
|
||||
@AutoService(BugChecker.class)
|
||||
@BugPattern(
|
||||
name = "ExplicitEnumOrdering",
|
||||
summary = "Make sure `Ordering#explicit` lists all of an enum's values",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.WARNING,
|
||||
tags = StandardTags.FRAGILE_CODE)
|
||||
public final class ExplicitEnumOrderingCheck extends BugChecker
|
||||
implements MethodInvocationTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Matcher<ExpressionTree> EXPLICIT_ORDERING =
|
||||
staticMethod().onClass(Ordering.class.getName()).named("explicit");
|
||||
|
||||
@Override
|
||||
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
|
||||
if (!EXPLICIT_ORDERING.matches(tree, state)) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
ImmutableSet<String> missingEnumValues = getMissingEnumValues(tree.getArguments());
|
||||
if (missingEnumValues.isEmpty()) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
return buildDescription(tree)
|
||||
.setMessage(
|
||||
String.format(
|
||||
"Explicit ordering lacks some enum values: %s",
|
||||
String.join(", ", missingEnumValues)))
|
||||
.build();
|
||||
}
|
||||
|
||||
private static ImmutableSet<String> getMissingEnumValues(
|
||||
List<? extends ExpressionTree> expressions) {
|
||||
return expressions.stream()
|
||||
.map(ASTHelpers::getSymbol)
|
||||
.filter(Symbol::isEnum)
|
||||
.collect(
|
||||
collectingAndThen(
|
||||
toImmutableSetMultimap(Symbol::asType, Symbol::toString),
|
||||
ExplicitEnumOrderingCheck::getMissingEnumValues));
|
||||
}
|
||||
|
||||
private static ImmutableSet<String> getMissingEnumValues(
|
||||
ImmutableSetMultimap<Type, String> valuesByType) {
|
||||
return Multimaps.asMap(valuesByType).entrySet().stream()
|
||||
.flatMap(e -> getMissingEnumValues(e.getKey(), e.getValue()))
|
||||
.collect(toImmutableSet());
|
||||
}
|
||||
|
||||
private static Stream<String> getMissingEnumValues(Type enumType, Set<String> values) {
|
||||
Symbol.TypeSymbol typeSymbol = enumType.asElement();
|
||||
return Sets.difference(ASTHelpers.enumValues(typeSymbol), values).stream()
|
||||
.map(v -> String.format("%s.%s", typeSymbol.getSimpleName(), v));
|
||||
}
|
||||
}
|
||||
@@ -43,15 +43,15 @@ public final class JUnitMethodDeclarationCheck extends BugChecker implements Met
|
||||
private static final String TEST_PREFIX = "test";
|
||||
private static final ImmutableSet<Modifier> ILLEGAL_MODIFIERS =
|
||||
ImmutableSet.of(Modifier.PRIVATE, Modifier.PROTECTED, Modifier.PUBLIC);
|
||||
private static final MultiMatcher<MethodTree, AnnotationTree> IS_OVERRIDE_METHOD =
|
||||
private static final MultiMatcher<MethodTree, AnnotationTree> OVERRIDE_METHOD =
|
||||
annotations(AT_LEAST_ONE, isType("java.lang.Override"));
|
||||
private static final MultiMatcher<MethodTree, AnnotationTree> IS_TEST_METHOD =
|
||||
private static final MultiMatcher<MethodTree, AnnotationTree> TEST_METHOD =
|
||||
annotations(
|
||||
AT_LEAST_ONE,
|
||||
anyOf(
|
||||
isType("org.junit.jupiter.api.Test"),
|
||||
hasMetaAnnotation("org.junit.jupiter.api.TestTemplate")));
|
||||
private static final MultiMatcher<MethodTree, AnnotationTree> IS_SETUP_OR_TEARDOWN_METHOD =
|
||||
private static final MultiMatcher<MethodTree, AnnotationTree> SETUP_OR_TEARDOWN_METHOD =
|
||||
annotations(
|
||||
AT_LEAST_ONE,
|
||||
anyOf(
|
||||
@@ -64,12 +64,12 @@ public final class JUnitMethodDeclarationCheck extends BugChecker implements Met
|
||||
public Description matchMethod(MethodTree tree, VisitorState state) {
|
||||
// XXX: Perhaps we should also skip analysis of non-`private` non-`final` methods in abstract
|
||||
// classes?
|
||||
if (IS_OVERRIDE_METHOD.matches(tree, state)) {
|
||||
if (OVERRIDE_METHOD.matches(tree, state)) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
boolean isTestMethod = IS_TEST_METHOD.matches(tree, state);
|
||||
if (!isTestMethod && !IS_SETUP_OR_TEARDOWN_METHOD.matches(tree, state)) {
|
||||
boolean isTestMethod = TEST_METHOD.matches(tree, state);
|
||||
if (!isTestMethod && !SETUP_OR_TEARDOWN_METHOD.matches(tree, state)) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ public final class JUnitMethodDeclarationCheck extends BugChecker implements Met
|
||||
private static Matcher<AnnotationTree> hasMetaAnnotation(String annotationClassName) {
|
||||
TypePredicate typePredicate = hasAnnotation(annotationClassName);
|
||||
return (tree, state) -> {
|
||||
Symbol sym = ASTHelpers.getDeclaredSymbol(tree);
|
||||
Symbol sym = ASTHelpers.getSymbol(tree);
|
||||
return sym != null && typePredicate.apply(sym.type, state);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static java.util.Comparator.comparing;
|
||||
import static java.util.Comparator.naturalOrder;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
|
||||
@@ -9,7 +10,6 @@ import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.BugPattern.LinkType;
|
||||
import com.google.errorprone.BugPattern.ProvidesFix;
|
||||
import com.google.errorprone.BugPattern.SeverityLevel;
|
||||
import com.google.errorprone.BugPattern.StandardTags;
|
||||
import com.google.errorprone.ErrorProneFlags;
|
||||
@@ -32,7 +32,6 @@ import com.sun.source.tree.Tree.Kind;
|
||||
import com.sun.source.util.TreeScanner;
|
||||
import com.sun.tools.javac.code.Symtab;
|
||||
import com.sun.tools.javac.code.Type;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -51,8 +50,7 @@ import java.util.stream.Stream;
|
||||
summary = "Where possible, sort annotation array attributes lexicographically",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.SUGGESTION,
|
||||
tags = StandardTags.STYLE,
|
||||
providesFix = ProvidesFix.REQUIRES_HUMAN_ATTENTION)
|
||||
tags = StandardTags.STYLE)
|
||||
public final class LexicographicalAnnotationAttributeListingCheck extends BugChecker
|
||||
implements AnnotationTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
@@ -155,7 +153,7 @@ public final class LexicographicalAnnotationAttributeListingCheck extends BugChe
|
||||
// XXX: Perhaps we should use `Collator` with `.setStrength(Collator.PRIMARY)` and
|
||||
// `getCollationKey`. Not clear whether that's worth the hassle at this point.
|
||||
return ImmutableList.sortedCopyOf(
|
||||
Comparator.comparing(
|
||||
comparing(
|
||||
e -> getStructure(e, state),
|
||||
Comparators.lexicographical(
|
||||
Comparators.lexicographical(
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
import static java.util.Comparator.comparing;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Streams;
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.BugPattern.LinkType;
|
||||
import com.google.errorprone.BugPattern.SeverityLevel;
|
||||
import com.google.errorprone.BugPattern.StandardTags;
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
import com.google.errorprone.bugpatterns.BugChecker.MethodTreeMatcher;
|
||||
import com.google.errorprone.fixes.Fix;
|
||||
import com.google.errorprone.fixes.SuggestedFix;
|
||||
import com.google.errorprone.matchers.Description;
|
||||
import com.sun.source.tree.AnnotationTree;
|
||||
import com.sun.source.tree.MethodTree;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* A {@link BugChecker} that flags annotations that are not lexicographically sorted.
|
||||
*
|
||||
* <p>The idea behind this checker is that maintaining a sorted sequence simplifies conflict
|
||||
* resolution, and can even avoid it if two branches add the same annotation.
|
||||
*/
|
||||
@AutoService(BugChecker.class)
|
||||
@BugPattern(
|
||||
name = "LexicographicalAnnotationListing",
|
||||
summary = "Sort annotations lexicographically where possible",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.SUGGESTION,
|
||||
tags = StandardTags.STYLE)
|
||||
public final class LexicographicalAnnotationListingCheck extends BugChecker
|
||||
implements MethodTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public Description matchMethod(MethodTree tree, VisitorState state) {
|
||||
List<? extends AnnotationTree> originalOrdering = tree.getModifiers().getAnnotations();
|
||||
if (originalOrdering.size() < 2) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
ImmutableList<? extends AnnotationTree> sortedAnnotations = sort(originalOrdering, state);
|
||||
if (originalOrdering.equals(sortedAnnotations)) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
Optional<Fix> fix = tryFixOrdering(originalOrdering, sortedAnnotations, state);
|
||||
|
||||
Description.Builder description = buildDescription(tree);
|
||||
fix.ifPresent(description::addFix);
|
||||
return description.build();
|
||||
}
|
||||
|
||||
private static ImmutableList<? extends AnnotationTree> sort(
|
||||
List<? extends AnnotationTree> annotations, VisitorState state) {
|
||||
return annotations.stream()
|
||||
.sorted(comparing(annotation -> Util.treeToString(annotation, state)))
|
||||
.collect(toImmutableList());
|
||||
}
|
||||
|
||||
private static Optional<Fix> tryFixOrdering(
|
||||
List<? extends AnnotationTree> originalAnnotations,
|
||||
ImmutableList<? extends AnnotationTree> sortedAnnotations,
|
||||
VisitorState state) {
|
||||
return Streams.zip(
|
||||
originalAnnotations.stream(),
|
||||
sortedAnnotations.stream(),
|
||||
(original, replacement) ->
|
||||
SuggestedFix.builder().replace(original, Util.treeToString(replacement, state)))
|
||||
.reduce(SuggestedFix.Builder::merge)
|
||||
.map(SuggestedFix.Builder::build);
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,6 @@ import com.google.common.base.VerifyException;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.BugPattern.LinkType;
|
||||
import com.google.errorprone.BugPattern.ProvidesFix;
|
||||
import com.google.errorprone.BugPattern.SeverityLevel;
|
||||
import com.google.errorprone.BugPattern.StandardTags;
|
||||
import com.google.errorprone.VisitorState;
|
||||
@@ -48,14 +47,15 @@ import javax.lang.model.element.Name;
|
||||
// black-and-white. Maybe we can more closely approximate it?
|
||||
// XXX: With Java 9's introduction of `Predicate.not`, we could write many lambda expressions to
|
||||
// `not(some::reference)`.
|
||||
// XXX: This check is extremely inefficient due to its reliance on `SuggestedFixes.compilesWithFix`.
|
||||
// Palantir's `LambdaMethodReference` check seems to suffer a similar issue at this time.
|
||||
@AutoService(BugChecker.class)
|
||||
@BugPattern(
|
||||
name = "MethodReferenceUsage",
|
||||
summary = "Prefer method references over lambda expressions",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.SUGGESTION,
|
||||
tags = StandardTags.STYLE,
|
||||
providesFix = ProvidesFix.REQUIRES_HUMAN_ATTENTION)
|
||||
tags = StandardTags.STYLE)
|
||||
public final class MethodReferenceUsageCheck extends BugChecker
|
||||
implements LambdaExpressionTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
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 com.google.auto.service.AutoService;
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.BugPattern.LinkType;
|
||||
import com.google.errorprone.BugPattern.SeverityLevel;
|
||||
import com.google.errorprone.BugPattern.StandardTags;
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
import com.google.errorprone.bugpatterns.BugChecker.ClassTreeMatcher;
|
||||
import com.google.errorprone.matchers.Description;
|
||||
import com.google.errorprone.matchers.MultiMatcher;
|
||||
import com.google.errorprone.util.ASTHelpers;
|
||||
import com.sun.source.tree.AnnotationTree;
|
||||
import com.sun.source.tree.ClassTree;
|
||||
import com.sun.source.tree.MethodTree;
|
||||
import com.sun.source.tree.Tree;
|
||||
|
||||
/** A {@link BugChecker} that flags likely missing Refaster annotations. */
|
||||
@AutoService(BugChecker.class)
|
||||
@BugPattern(
|
||||
name = "MissingRefasterAnnotation",
|
||||
summary = "The Refaster template contains a method without any Refaster annotations",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.WARNING,
|
||||
tags = StandardTags.LIKELY_ERROR)
|
||||
public final class MissingRefasterAnnotationCheck extends BugChecker implements ClassTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final MultiMatcher<Tree, AnnotationTree> REFASTER_ANNOTATION =
|
||||
annotations(
|
||||
AT_LEAST_ONE,
|
||||
anyOf(
|
||||
isType("com.google.errorprone.refaster.annotation.Placeholder"),
|
||||
isType("com.google.errorprone.refaster.annotation.BeforeTemplate"),
|
||||
isType("com.google.errorprone.refaster.annotation.AfterTemplate")));
|
||||
|
||||
@Override
|
||||
public Description matchClass(ClassTree tree, VisitorState state) {
|
||||
long methodTypes =
|
||||
tree.getMembers().stream()
|
||||
.filter(member -> member.getKind() == Tree.Kind.METHOD)
|
||||
.map(MethodTree.class::cast)
|
||||
.filter(method -> !ASTHelpers.isGeneratedConstructor(method))
|
||||
.map(method -> REFASTER_ANNOTATION.matches(method, state))
|
||||
.distinct()
|
||||
.count();
|
||||
|
||||
return methodTypes < 2 ? Description.NO_MATCH : buildDescription(tree).build();
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,6 @@ import com.google.auto.service.AutoService;
|
||||
import com.google.common.base.VerifyException;
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.BugPattern.LinkType;
|
||||
import com.google.errorprone.BugPattern.ProvidesFix;
|
||||
import com.google.errorprone.BugPattern.SeverityLevel;
|
||||
import com.google.errorprone.BugPattern.StandardTags;
|
||||
import com.google.errorprone.VisitorState;
|
||||
@@ -47,12 +46,11 @@ import java.util.function.Function;
|
||||
+ " of the provided function",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.WARNING,
|
||||
tags = StandardTags.PERFORMANCE,
|
||||
providesFix = ProvidesFix.REQUIRES_HUMAN_ATTENTION)
|
||||
tags = StandardTags.PERFORMANCE)
|
||||
public final class PrimitiveComparisonCheck extends BugChecker
|
||||
implements MethodInvocationTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Matcher<ExpressionTree> STATIC_COMPARISION_METHOD =
|
||||
private static final Matcher<ExpressionTree> STATIC_COMPARISON_METHOD =
|
||||
anyOf(
|
||||
staticMethod()
|
||||
.onClass(Comparator.class.getName())
|
||||
@@ -61,7 +59,7 @@ public final class PrimitiveComparisonCheck extends BugChecker
|
||||
.onClass(Comparator.class.getName())
|
||||
.named("comparing")
|
||||
.withParameters(Function.class.getName()));
|
||||
private static final Matcher<ExpressionTree> INSTANCE_COMPARISION_METHOD =
|
||||
private static final Matcher<ExpressionTree> INSTANCE_COMPARISON_METHOD =
|
||||
anyOf(
|
||||
instanceMethod()
|
||||
.onDescendantOf(Comparator.class.getName())
|
||||
@@ -73,8 +71,8 @@ public final class PrimitiveComparisonCheck extends BugChecker
|
||||
|
||||
@Override
|
||||
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
|
||||
boolean isStatic = STATIC_COMPARISION_METHOD.matches(tree, state);
|
||||
if (!isStatic && !INSTANCE_COMPARISION_METHOD.matches(tree, state)) {
|
||||
boolean isStatic = STATIC_COMPARISON_METHOD.matches(tree, state);
|
||||
if (!isStatic && !INSTANCE_COMPARISON_METHOD.matches(tree, state)) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.matchers.Matchers.allOf;
|
||||
import static com.google.errorprone.matchers.Matchers.anyOf;
|
||||
import static com.google.errorprone.matchers.Matchers.isNonNull;
|
||||
import static com.google.errorprone.matchers.Matchers.isNonNullUsingDataflow;
|
||||
import static com.google.errorprone.matchers.Matchers.isSameType;
|
||||
import static com.google.errorprone.matchers.Matchers.isSubtypeOf;
|
||||
import static com.google.errorprone.matchers.Matchers.not;
|
||||
@@ -13,7 +13,6 @@ import com.google.auto.service.AutoService;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.BugPattern.LinkType;
|
||||
import com.google.errorprone.BugPattern.ProvidesFix;
|
||||
import com.google.errorprone.BugPattern.SeverityLevel;
|
||||
import com.google.errorprone.BugPattern.StandardTags;
|
||||
import com.google.errorprone.ErrorProneFlags;
|
||||
@@ -50,8 +49,7 @@ import java.util.Optional;
|
||||
summary = "Avoid redundant string conversions when possible",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.SUGGESTION,
|
||||
tags = StandardTags.SIMPLIFICATION,
|
||||
providesFix = ProvidesFix.REQUIRES_HUMAN_ATTENTION)
|
||||
tags = StandardTags.SIMPLIFICATION)
|
||||
public final class RedundantStringConversionCheck extends BugChecker
|
||||
implements BinaryTreeMatcher, CompoundAssignmentTreeMatcher, MethodInvocationTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
@@ -66,7 +64,8 @@ public final class RedundantStringConversionCheck extends BugChecker
|
||||
private static final Matcher<ExpressionTree> MARKER = isSubtypeOf("org.slf4j.Marker");
|
||||
private static final Matcher<ExpressionTree> STRING = isSameType(String.class);
|
||||
private static final Matcher<ExpressionTree> THROWABLE = isSubtypeOf(Throwable.class);
|
||||
private static final Matcher<ExpressionTree> NON_NULL_STRING = allOf(STRING, isNonNull());
|
||||
private static final Matcher<ExpressionTree> NON_NULL_STRING =
|
||||
allOf(STRING, isNonNullUsingDataflow());
|
||||
private static final Matcher<ExpressionTree> NOT_FORMATTABLE =
|
||||
not(isSubtypeOf(Formattable.class));
|
||||
private static final Matcher<ExpressionTree> WELL_KNOWN_STRING_CONVERSION_METHODS =
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.matchers.method.MethodMatchers.staticMethod;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.BugPattern.LinkType;
|
||||
import com.google.errorprone.BugPattern.SeverityLevel;
|
||||
import com.google.errorprone.BugPattern.StandardTags;
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
import com.google.errorprone.bugpatterns.BugChecker.MethodInvocationTreeMatcher;
|
||||
import com.google.errorprone.fixes.SuggestedFix;
|
||||
import com.google.errorprone.matchers.Description;
|
||||
import com.google.errorprone.matchers.Matcher;
|
||||
import com.google.errorprone.refaster.Refaster;
|
||||
import com.sun.source.tree.ExpressionTree;
|
||||
import com.sun.source.tree.MethodInvocationTree;
|
||||
|
||||
/**
|
||||
* A {@link BugChecker} which flags unnecessary {@link Refaster#anyOf(Object[])} usages.
|
||||
*
|
||||
* <p>Note that this logic can't be implemented as a Refaster template, as the {@link Refaster}
|
||||
* class is treated specially.
|
||||
*/
|
||||
@AutoService(BugChecker.class)
|
||||
@BugPattern(
|
||||
name = "RefasterAnyOfUsage",
|
||||
summary = "`Refaster#anyOf` should be passed at least two parameters",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.SUGGESTION,
|
||||
tags = StandardTags.SIMPLIFICATION)
|
||||
public final class RefasterAnyOfUsageCheck extends BugChecker
|
||||
implements MethodInvocationTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Matcher<ExpressionTree> REFASTER_ANY_OF =
|
||||
staticMethod().onClass(Refaster.class.getName()).named("anyOf");
|
||||
|
||||
@Override
|
||||
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
|
||||
if (REFASTER_ANY_OF.matches(tree, state)) {
|
||||
switch (tree.getArguments().size()) {
|
||||
case 0:
|
||||
// We can't safely fix this case; dropping the expression may produce non-compilable code.
|
||||
return describeMatch(tree);
|
||||
case 1:
|
||||
return describeMatch(
|
||||
tree,
|
||||
SuggestedFix.replace(tree, Util.treeToString(tree.getArguments().get(0), state)));
|
||||
default:
|
||||
/* Handled below. */
|
||||
}
|
||||
}
|
||||
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
}
|
||||
@@ -2,21 +2,24 @@ package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
import static com.google.common.collect.ImmutableRangeSet.toImmutableRangeSet;
|
||||
import static java.util.Objects.requireNonNullElseGet;
|
||||
import static java.util.function.Predicate.not;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.ImmutableCollection;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableListMultimap;
|
||||
import com.google.common.collect.ImmutableRangeSet;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Range;
|
||||
import com.google.common.collect.RangeSet;
|
||||
import com.google.common.collect.TreeRangeSet;
|
||||
import com.google.common.reflect.ClassPath;
|
||||
import com.google.common.reflect.ClassPath.ResourceInfo;
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.BugPattern.LinkType;
|
||||
import com.google.errorprone.BugPattern.ProvidesFix;
|
||||
import com.google.errorprone.BugPattern.SeverityLevel;
|
||||
import com.google.errorprone.BugPattern.StandardTags;
|
||||
import com.google.errorprone.CodeTransformer;
|
||||
@@ -40,8 +43,8 @@ import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@@ -59,12 +62,15 @@ import java.util.stream.Stream;
|
||||
summary = "Write idiomatic code when possible",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.SUGGESTION,
|
||||
tags = StandardTags.SIMPLIFICATION,
|
||||
providesFix = ProvidesFix.REQUIRES_HUMAN_ATTENTION)
|
||||
tags = StandardTags.SIMPLIFICATION)
|
||||
public final class RefasterCheck extends BugChecker implements CompilationUnitTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final String REFASTER_TEMPLATE_SUFFIX = ".refaster";
|
||||
private static final String INCLUDED_TEMPLATES_PATTERN_FLAG = "Refaster:NamePattern";
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@VisibleForTesting
|
||||
static final Supplier<ImmutableListMultimap<String, CodeTransformer>> ALL_CODE_TRANSFORMERS =
|
||||
Suppliers.memoize(RefasterCheck::loadAllCodeTransformers);
|
||||
|
||||
private final CodeTransformer codeTransformer;
|
||||
|
||||
@@ -79,20 +85,21 @@ public final class RefasterCheck extends BugChecker implements CompilationUnitTr
|
||||
* @param flags Any provided command line flags.
|
||||
*/
|
||||
public RefasterCheck(ErrorProneFlags flags) {
|
||||
codeTransformer = createCompositeCodeTransformer(flags, loadAllCodeTransformers());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
RefasterCheck(
|
||||
ErrorProneFlags flags, ImmutableListMultimap<String, CodeTransformer> allTransformers) {
|
||||
codeTransformer = createCompositeCodeTransformer(flags, allTransformers);
|
||||
codeTransformer = createCompositeCodeTransformer(flags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState state) {
|
||||
/* First, collect all matches. */
|
||||
List<Description> matches = new ArrayList<>();
|
||||
codeTransformer.apply(state.getPath(), new SubContext(state.context), matches::add);
|
||||
try {
|
||||
codeTransformer.apply(state.getPath(), new SubContext(state.context), matches::add);
|
||||
} catch (LinkageError e) {
|
||||
// XXX: This `try/catch` block handles the issue described and resolved in
|
||||
// https://github.com/google/error-prone/pull/2456. Drop this block once that change is
|
||||
// released.
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
/* Then apply them. */
|
||||
applyMatches(matches, ((JCCompilationUnit) tree).endPositions, state);
|
||||
|
||||
@@ -143,6 +150,7 @@ public final class RefasterCheck extends BugChecker implements CompilationUnitTr
|
||||
Description description, EndPosTable endPositions) {
|
||||
return getReplacements(description, endPositions)
|
||||
.map(Replacement::range)
|
||||
.filter(not(Range::isEmpty))
|
||||
.collect(toImmutableRangeSet());
|
||||
}
|
||||
|
||||
@@ -151,8 +159,8 @@ public final class RefasterCheck extends BugChecker implements CompilationUnitTr
|
||||
return description.fixes.stream().flatMap(fix -> fix.getReplacements(endPositions).stream());
|
||||
}
|
||||
|
||||
private static CodeTransformer createCompositeCodeTransformer(
|
||||
ErrorProneFlags flags, ImmutableListMultimap<String, CodeTransformer> allTransformers) {
|
||||
private static CodeTransformer createCompositeCodeTransformer(ErrorProneFlags flags) {
|
||||
ImmutableListMultimap<String, CodeTransformer> allTransformers = ALL_CODE_TRANSFORMERS.get();
|
||||
return CompositeCodeTransformer.compose(
|
||||
flags
|
||||
.get(INCLUDED_TEMPLATES_PATTERN_FLAG)
|
||||
@@ -169,8 +177,7 @@ public final class RefasterCheck extends BugChecker implements CompilationUnitTr
|
||||
.collect(toImmutableList());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static ImmutableListMultimap<String, CodeTransformer> loadAllCodeTransformers() {
|
||||
private static ImmutableListMultimap<String, CodeTransformer> loadAllCodeTransformers() {
|
||||
ImmutableListMultimap.Builder<String, CodeTransformer> transformers =
|
||||
ImmutableListMultimap.builder();
|
||||
|
||||
@@ -188,8 +195,8 @@ public final class RefasterCheck extends BugChecker implements CompilationUnitTr
|
||||
private static ImmutableSet<ResourceInfo> getClassPathResources() {
|
||||
try {
|
||||
return ClassPath.from(
|
||||
Objects.requireNonNullElseGet(
|
||||
RefasterCheck.class.getClassLoader(), () -> ClassLoader.getSystemClassLoader()))
|
||||
requireNonNullElseGet(
|
||||
RefasterCheck.class.getClassLoader(), ClassLoader::getSystemClassLoader))
|
||||
.getResources();
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Failed to scan classpath for resources", e);
|
||||
@@ -211,7 +218,9 @@ public final class RefasterCheck extends BugChecker implements CompilationUnitTr
|
||||
private static Optional<CodeTransformer> loadCodeTransformer(ResourceInfo resource) {
|
||||
try (InputStream in = resource.url().openStream();
|
||||
ObjectInputStream ois = new ObjectInputStream(in)) {
|
||||
return Optional.of((CodeTransformer) ois.readObject());
|
||||
@SuppressWarnings("BanSerializableRead" /* Part of the Refaster API. */)
|
||||
CodeTransformer codeTransformer = (CodeTransformer) ois.readObject();
|
||||
return Optional.of(codeTransformer);
|
||||
} catch (NoSuchElementException e) {
|
||||
/* For some reason we can't load the resource. Skip it. */
|
||||
// XXX: Should we log this?
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.matchers.ChildMultiMatcher.MatchType.ALL;
|
||||
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.isSameType;
|
||||
import static com.google.errorprone.matchers.Matchers.isSubtypeOf;
|
||||
import static com.google.errorprone.matchers.Matchers.isType;
|
||||
import static com.google.errorprone.matchers.Matchers.methodHasParameters;
|
||||
import static com.google.errorprone.matchers.Matchers.not;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.BugPattern.LinkType;
|
||||
import com.google.errorprone.BugPattern.SeverityLevel;
|
||||
import com.google.errorprone.BugPattern.StandardTags;
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
import com.google.errorprone.bugpatterns.BugChecker.MethodTreeMatcher;
|
||||
import com.google.errorprone.matchers.Description;
|
||||
import com.google.errorprone.matchers.Matcher;
|
||||
import com.sun.source.tree.MethodTree;
|
||||
import com.sun.source.tree.Tree;
|
||||
|
||||
/**
|
||||
* A {@link BugChecker} which flags {@code @RequestMapping} methods that have one or more parameters
|
||||
* that appear to lack a relevant annotation.
|
||||
*
|
||||
* <p>Matched mappings are {@code @{Delete,Get,Patch,Post,Put,Request}Mapping}.
|
||||
*/
|
||||
@AutoService(BugChecker.class)
|
||||
@BugPattern(
|
||||
name = "RequestMappingAnnotation",
|
||||
summary = "Make sure all `@RequestMapping` method parameters are annotated",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.WARNING,
|
||||
tags = StandardTags.LIKELY_ERROR)
|
||||
public final class RequestMappingAnnotationCheck extends BugChecker implements MethodTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final String ANN_PACKAGE_PREFIX = "org.springframework.web.bind.annotation.";
|
||||
// XXX: Generalize this logic to fully support Spring meta-annotations, then update the class
|
||||
// documentation.
|
||||
private static final Matcher<Tree> HAS_MAPPING_ANNOTATION =
|
||||
annotations(
|
||||
AT_LEAST_ONE,
|
||||
anyOf(
|
||||
isType(ANN_PACKAGE_PREFIX + "DeleteMapping"),
|
||||
isType(ANN_PACKAGE_PREFIX + "GetMapping"),
|
||||
isType(ANN_PACKAGE_PREFIX + "PatchMapping"),
|
||||
isType(ANN_PACKAGE_PREFIX + "PostMapping"),
|
||||
isType(ANN_PACKAGE_PREFIX + "PutMapping"),
|
||||
isType(ANN_PACKAGE_PREFIX + "RequestMapping")));
|
||||
// XXX: Add other parameters as necessary. See
|
||||
// https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-ann-arguments.
|
||||
private static final Matcher<MethodTree> LACKS_PARAMETER_ANNOTATION =
|
||||
not(
|
||||
methodHasParameters(
|
||||
ALL,
|
||||
anyOf(
|
||||
annotations(
|
||||
AT_LEAST_ONE,
|
||||
anyOf(
|
||||
isType(ANN_PACKAGE_PREFIX + "PathVariable"),
|
||||
isType(ANN_PACKAGE_PREFIX + "RequestBody"),
|
||||
isType(ANN_PACKAGE_PREFIX + "RequestHeader"),
|
||||
isType(ANN_PACKAGE_PREFIX + "RequestParam"))),
|
||||
isSameType("java.io.InputStream"),
|
||||
isSameType("javax.servlet.http.HttpServletRequest"),
|
||||
isSameType("javax.servlet.http.HttpServletResponse"),
|
||||
isSameType("org.springframework.http.HttpMethod"),
|
||||
isSubtypeOf("org.springframework.web.context.request.WebRequest"))));
|
||||
|
||||
@Override
|
||||
public Description matchMethod(MethodTree tree, VisitorState state) {
|
||||
// XXX: Auto-add `@RequestParam` where applicable.
|
||||
// XXX: What about the `PurchasingProposerRequestParams` in POM? Implies `@RequestBody`?
|
||||
// (Documentation doesn't mention this, IIUC.)
|
||||
return HAS_MAPPING_ANNOTATION.matches(tree, state)
|
||||
&& LACKS_PARAMETER_ANNOTATION.matches(tree, state)
|
||||
? buildDescription(tree)
|
||||
.setMessage(
|
||||
"Not all parameters of this request mapping method are annotated; this may be a mistake. "
|
||||
+ "If the unannotated parameters represent query string parameters, annotate them with `@RequestParam`.")
|
||||
.build()
|
||||
: Description.NO_MATCH;
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,6 @@ import com.google.auto.service.AutoService;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.BugPattern.LinkType;
|
||||
import com.google.errorprone.BugPattern.ProvidesFix;
|
||||
import com.google.errorprone.BugPattern.SeverityLevel;
|
||||
import com.google.errorprone.BugPattern.StandardTags;
|
||||
import com.google.errorprone.VisitorState;
|
||||
@@ -36,8 +35,7 @@ import java.util.Optional;
|
||||
summary = "Make sure SLF4J log statements contain proper placeholders with matching arguments",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.WARNING,
|
||||
tags = StandardTags.LIKELY_ERROR,
|
||||
providesFix = ProvidesFix.REQUIRES_HUMAN_ATTENTION)
|
||||
tags = StandardTags.LIKELY_ERROR)
|
||||
public final class Slf4jLogStatementCheck extends BugChecker
|
||||
implements MethodInvocationTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -10,7 +10,6 @@ import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.BugPattern.LinkType;
|
||||
import com.google.errorprone.BugPattern.ProvidesFix;
|
||||
import com.google.errorprone.BugPattern.SeverityLevel;
|
||||
import com.google.errorprone.BugPattern.StandardTags;
|
||||
import com.google.errorprone.VisitorState;
|
||||
@@ -38,8 +37,7 @@ import java.util.Optional;
|
||||
"Prefer the conciseness of `@{Get,Put,Post,Delete,Patch}Mapping` over `@RequestMapping`",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.SUGGESTION,
|
||||
tags = StandardTags.SIMPLIFICATION,
|
||||
providesFix = ProvidesFix.REQUIRES_HUMAN_ATTENTION)
|
||||
tags = StandardTags.SIMPLIFICATION)
|
||||
public final class SpringMvcAnnotationCheck extends BugChecker implements AnnotationTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final String ANN_PACKAGE_PREFIX = "org.springframework.web.bind.annotation.";
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
@@ -20,7 +22,6 @@ import com.google.errorprone.matchers.Description;
|
||||
import com.sun.source.tree.MemberSelectTree;
|
||||
import com.sun.source.tree.MethodInvocationTree;
|
||||
import com.sun.source.tree.Tree;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
/** A {@link BugChecker} which flags methods that can and should be statically imported. */
|
||||
@@ -44,8 +45,7 @@ import java.util.Optional;
|
||||
summary = "Method should be statically imported",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.SUGGESTION,
|
||||
tags = StandardTags.SIMPLIFICATION,
|
||||
providesFix = BugPattern.ProvidesFix.REQUIRES_HUMAN_ATTENTION)
|
||||
tags = StandardTags.SIMPLIFICATION)
|
||||
public final class StaticImportCheck extends BugChecker implements MemberSelectTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -141,8 +141,7 @@ public final class StaticImportCheck extends BugChecker implements MemberSelectT
|
||||
|
||||
private static boolean isCandidate(VisitorState state) {
|
||||
Tree parentTree =
|
||||
Objects.requireNonNull(
|
||||
state.getPath().getParentPath(), "MemberSelectTree lacks enclosing node")
|
||||
requireNonNull(state.getPath().getParentPath(), "MemberSelectTree lacks enclosing node")
|
||||
.getLeaf();
|
||||
switch (parentTree.getKind()) {
|
||||
case IMPORT:
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.matchers.Matchers.anyOf;
|
||||
import static com.google.errorprone.matchers.Matchers.instanceMethod;
|
||||
import static com.google.errorprone.matchers.Matchers.staticMethod;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.BugPattern.LinkType;
|
||||
import com.google.errorprone.BugPattern.SeverityLevel;
|
||||
import com.google.errorprone.BugPattern.StandardTags;
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
import com.google.errorprone.bugpatterns.BugChecker.MethodInvocationTreeMatcher;
|
||||
import com.google.errorprone.matchers.Description;
|
||||
import com.google.errorprone.matchers.Matcher;
|
||||
import com.sun.source.tree.ExpressionTree;
|
||||
import com.sun.source.tree.MethodInvocationTree;
|
||||
import java.time.Clock;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
|
||||
/** A {@link BugChecker} which flags illegal time-zone related operations. */
|
||||
@AutoService(BugChecker.class)
|
||||
@BugPattern(
|
||||
name = "TimeZoneUsage",
|
||||
summary =
|
||||
"Derive the current time from an existing `Clock` Spring bean, and don't rely on a `Clock`'s time zone",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.WARNING,
|
||||
tags = StandardTags.FRAGILE_CODE)
|
||||
public final class TimeZoneUsageCheck extends BugChecker implements MethodInvocationTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Matcher<ExpressionTree> BANNED_TIME_METHOD =
|
||||
anyOf(
|
||||
instanceMethod().onDescendantOf(Clock.class.getName()).namedAnyOf("getZone", "withZone"),
|
||||
staticMethod()
|
||||
.onClass(Clock.class.getName())
|
||||
.namedAnyOf(
|
||||
"system",
|
||||
"systemDefaultZone",
|
||||
"systemUTC",
|
||||
"tickMillis",
|
||||
"tickMinutes",
|
||||
"tickSeconds"),
|
||||
staticMethod()
|
||||
.onClassAny(
|
||||
LocalDate.class.getName(),
|
||||
LocalDateTime.class.getName(),
|
||||
LocalTime.class.getName())
|
||||
.named("now"),
|
||||
staticMethod().onClassAny(Instant.class.getName()).named("now").withParameters());
|
||||
|
||||
@Override
|
||||
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
|
||||
return BANNED_TIME_METHOD.matches(tree, state)
|
||||
? buildDescription(tree).build()
|
||||
: Description.NO_MATCH;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,4 @@
|
||||
/** Picnic Error Prone Contrib checks. */
|
||||
@CheckReturnValue
|
||||
@ParametersAreNonnullByDefault
|
||||
@com.google.errorprone.annotations.CheckReturnValue
|
||||
@javax.annotation.ParametersAreNonnullByDefault
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import com.google.errorprone.annotations.CheckReturnValue;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.google.errorprone.refaster.ImportPolicy;
|
||||
import com.google.errorprone.refaster.Refaster;
|
||||
import com.google.errorprone.refaster.annotation.AfterTemplate;
|
||||
import com.google.errorprone.refaster.annotation.BeforeTemplate;
|
||||
import com.google.errorprone.refaster.annotation.NotMatches;
|
||||
import com.google.errorprone.refaster.annotation.Repeated;
|
||||
import com.google.errorprone.refaster.annotation.UseImportPolicy;
|
||||
import java.util.ArrayList;
|
||||
@@ -51,6 +52,7 @@ import org.assertj.core.api.ObjectEnumerableAssert;
|
||||
import org.assertj.core.api.OptionalDoubleAssert;
|
||||
import org.assertj.core.api.OptionalIntAssert;
|
||||
import org.assertj.core.api.OptionalLongAssert;
|
||||
import tech.picnic.errorprone.refaster.util.IsArray;
|
||||
|
||||
/** Refaster templates related to AssertJ expressions and statements. */
|
||||
// XXX: Most `AbstractIntegerAssert` rules can also be applied for other primitive types. Generate
|
||||
@@ -338,8 +340,14 @@ final class AssertJTemplates {
|
||||
ImmutableList.of(element),
|
||||
Arrays.asList(element),
|
||||
ImmutableSet.of(element),
|
||||
ImmutableMultiset.of(element))),
|
||||
iterAssert.containsExactlyInAnyOrder(element));
|
||||
ImmutableMultiset.of(element))));
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings("unchecked")
|
||||
ObjectEnumerableAssert<?, S> before2(
|
||||
ObjectEnumerableAssert<?, S> iterAssert, @NotMatches(IsArray.class) T element) {
|
||||
return iterAssert.containsExactlyInAnyOrder(element);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -352,13 +360,12 @@ final class AssertJTemplates {
|
||||
static final class ObjectEnumerableContainsOneDistinctElement<S, T extends S> {
|
||||
@BeforeTemplate
|
||||
ObjectEnumerableAssert<?, S> before(ObjectEnumerableAssert<?, S> iterAssert, T element) {
|
||||
return Refaster.anyOf(
|
||||
iterAssert.hasSameElementsAs(
|
||||
Refaster.anyOf(
|
||||
ImmutableList.of(element),
|
||||
Arrays.asList(element),
|
||||
ImmutableSet.of(element),
|
||||
ImmutableMultiset.of(element))));
|
||||
return iterAssert.hasSameElementsAs(
|
||||
Refaster.anyOf(
|
||||
ImmutableList.of(element),
|
||||
Arrays.asList(element),
|
||||
ImmutableSet.of(element),
|
||||
ImmutableMultiset.of(element)));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -371,13 +378,12 @@ final class AssertJTemplates {
|
||||
static final class ObjectEnumerableIsSubsetOfOneElement<S, T extends S> {
|
||||
@BeforeTemplate
|
||||
ObjectEnumerableAssert<?, S> before(ObjectEnumerableAssert<?, S> iterAssert, T element) {
|
||||
return Refaster.anyOf(
|
||||
iterAssert.isSubsetOf(
|
||||
Refaster.anyOf(
|
||||
ImmutableList.of(element),
|
||||
Arrays.asList(element),
|
||||
ImmutableSet.of(element),
|
||||
ImmutableMultiset.of(element))));
|
||||
return iterAssert.isSubsetOf(
|
||||
Refaster.anyOf(
|
||||
ImmutableList.of(element),
|
||||
Arrays.asList(element),
|
||||
ImmutableSet.of(element),
|
||||
ImmutableMultiset.of(element)));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -395,8 +401,8 @@ final class AssertJTemplates {
|
||||
@BeforeTemplate
|
||||
void before(Iterable<E> iterable) {
|
||||
Refaster.anyOf(
|
||||
assertThat(iterable).hasSize(0),
|
||||
assertThat(iterable.iterator().hasNext()).isFalse(),
|
||||
assertThat(Iterables.size(iterable)).isEqualTo(0),
|
||||
assertThat(Iterables.size(iterable)).isEqualTo(0L),
|
||||
assertThat(Iterables.size(iterable)).isNotPositive());
|
||||
}
|
||||
@@ -405,7 +411,6 @@ final class AssertJTemplates {
|
||||
void before(Collection<E> iterable) {
|
||||
Refaster.anyOf(
|
||||
assertThat(iterable.isEmpty()).isTrue(),
|
||||
assertThat(iterable.size()).isEqualTo(0),
|
||||
assertThat(iterable.size()).isEqualTo(0L),
|
||||
assertThat(iterable.size()).isNotPositive());
|
||||
}
|
||||
@@ -602,8 +607,8 @@ final class AssertJTemplates {
|
||||
@BeforeTemplate
|
||||
void before(Map<K, V> map) {
|
||||
Refaster.anyOf(
|
||||
assertThat(map).hasSize(0),
|
||||
assertThat(map.isEmpty()).isTrue(),
|
||||
assertThat(map.size()).isEqualTo(0),
|
||||
assertThat(map.size()).isEqualTo(0L),
|
||||
assertThat(map.size()).isNotPositive());
|
||||
}
|
||||
@@ -775,18 +780,21 @@ final class AssertJTemplates {
|
||||
// XXX: This rule assumes the `collector` doesn't completely discard certain values.
|
||||
static final class AssertThatStreamContainsAnyOfVarArgs<S, T extends S, U extends T> {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings("AssertThatStreamContainsAnyOf" /* Varargs converted to array. */)
|
||||
IterableAssert<T> before(
|
||||
Stream<S> stream, Collector<S, ?, ? extends Iterable<T>> collector, @Repeated U elements) {
|
||||
return assertThat(stream.collect(collector)).containsAnyOf(Refaster.asVarargs(elements));
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings("AssertThatStreamContainsAnyOf" /* Varargs converted to array. */)
|
||||
ListAssert<T> before2(
|
||||
Stream<S> stream, Collector<S, ?, ? extends List<T>> collector, @Repeated U elements) {
|
||||
return assertThat(stream.collect(collector)).containsAnyOf(Refaster.asVarargs(elements));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@SuppressWarnings("ObjectEnumerableContainsOneElement" /* Not a true singleton. */)
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, @Repeated U elements) {
|
||||
return assertThat(stream).containsAnyOf(elements);
|
||||
@@ -838,12 +846,14 @@ final class AssertJTemplates {
|
||||
// XXX: This rule assumes the `collector` doesn't completely discard certain values.
|
||||
static final class AssertThatStreamContainsVarArgs<S, T extends S, U extends T> {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings("AssertThatStreamContains" /* Varargs converted to array. */)
|
||||
IterableAssert<T> before(
|
||||
Stream<S> stream, Collector<S, ?, ? extends Iterable<T>> collector, @Repeated U elements) {
|
||||
return assertThat(stream.collect(collector)).contains(Refaster.asVarargs(elements));
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings("AssertThatStreamContains" /* Varargs converted to array. */)
|
||||
ListAssert<T> before2(
|
||||
Stream<S> stream, Collector<S, ?, ? extends List<T>> collector, @Repeated U elements) {
|
||||
return assertThat(stream.collect(collector)).contains(Refaster.asVarargs(elements));
|
||||
@@ -889,6 +899,7 @@ final class AssertJTemplates {
|
||||
// XXX: This rule assumes the `collector` doesn't completely discard certain values.
|
||||
static final class AssertThatStreamContainsExactlyVarargs<S, T extends S, U extends T> {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings("AssertThatStreamContainsExactly" /* Varargs converted to array. */)
|
||||
ListAssert<T> before(
|
||||
Stream<S> stream, Collector<S, ?, ? extends List<T>> collector, @Repeated U elements) {
|
||||
return assertThat(stream.collect(collector)).containsExactly(Refaster.asVarargs(elements));
|
||||
@@ -947,6 +958,7 @@ final class AssertJTemplates {
|
||||
// XXX: This rule assumes the `collector` doesn't completely discard certain values.
|
||||
static final class AssertThatStreamContainsExactlyInAnyOrderVarArgs<S, T extends S, U extends T> {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings("AssertThatStreamContainsExactlyInAnyOrder" /* Varargs converted to array. */)
|
||||
ListAssert<T> before(
|
||||
Stream<S> stream, Collector<S, ?, ? extends List<T>> collector, @Repeated U elements) {
|
||||
return assertThat(stream.collect(collector))
|
||||
@@ -954,6 +966,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings("AssertThatStreamContainsExactlyInAnyOrder" /* Varargs converted to array. */)
|
||||
IterableAssert<T> before2(
|
||||
Stream<S> stream, Collector<S, ?, ? extends Multiset<T>> collector, @Repeated U elements) {
|
||||
return assertThat(stream.collect(collector))
|
||||
@@ -961,6 +974,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@SuppressWarnings("ObjectEnumerableContainsExactlyOneElement" /* Not a true singleton. */)
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, @Repeated U elements) {
|
||||
return assertThat(stream).containsExactlyInAnyOrder(elements);
|
||||
@@ -991,12 +1005,14 @@ final class AssertJTemplates {
|
||||
// XXX: This rule assumes the `collector` doesn't completely discard certain values.
|
||||
static final class AssertThatStreamContainsSequenceVarArgs<S, T extends S, U extends T> {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings("AssertThatStreamContainsSequence" /* Varargs converted to array. */)
|
||||
ListAssert<T> before(
|
||||
Stream<S> stream, Collector<S, ?, ? extends List<T>> collector, @Repeated U elements) {
|
||||
return assertThat(stream.collect(collector)).containsSequence(Refaster.asVarargs(elements));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@SuppressWarnings("ObjectEnumerableContainsOneElement" /* Not a true singleton. */)
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, @Repeated U elements) {
|
||||
return assertThat(stream).containsSequence(elements);
|
||||
@@ -1027,6 +1043,7 @@ final class AssertJTemplates {
|
||||
// XXX: This rule assumes the `collector` doesn't completely discard certain values.
|
||||
static final class AssertThatStreamContainsSubsequenceVarArgs<S, T extends S, U extends T> {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings("AssertThatStreamContainsSubsequence" /* Varargs converted to array. */)
|
||||
ListAssert<T> before(
|
||||
Stream<S> stream, Collector<S, ?, ? extends List<T>> collector, @Repeated U elements) {
|
||||
return assertThat(stream.collect(collector))
|
||||
@@ -1034,6 +1051,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@SuppressWarnings("ObjectEnumerableContainsOneElement" /* Not a true singleton. */)
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, @Repeated U elements) {
|
||||
return assertThat(stream).containsSubsequence(elements);
|
||||
@@ -1085,12 +1103,14 @@ final class AssertJTemplates {
|
||||
// XXX: This rule assumes the `collector` doesn't completely discard certain values.
|
||||
static final class AssertThatStreamDoesNotContainVarArgs<S, T extends S, U extends T> {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings("AssertThatStreamDoesNotContain" /* Varargs converted to array. */)
|
||||
IterableAssert<T> before(
|
||||
Stream<S> stream, Collector<S, ?, ? extends Iterable<T>> collector, @Repeated U elements) {
|
||||
return assertThat(stream.collect(collector)).doesNotContain(Refaster.asVarargs(elements));
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings("AssertThatStreamDoesNotContain" /* Varargs converted to array. */)
|
||||
ListAssert<T> before2(
|
||||
Stream<S> stream, Collector<S, ?, ? extends List<T>> collector, @Repeated U elements) {
|
||||
return assertThat(stream.collect(collector)).doesNotContain(Refaster.asVarargs(elements));
|
||||
@@ -1127,6 +1147,7 @@ final class AssertJTemplates {
|
||||
// XXX: This rule assumes the `collector` doesn't completely discard certain values.
|
||||
static final class AssertThatStreamDoesNotContainSequenceVarArgs<S, T extends S, U extends T> {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings("AssertThatStreamDoesNotContainSequence" /* Varargs converted to array. */)
|
||||
ListAssert<T> before(
|
||||
Stream<S> stream, Collector<S, ?, ? extends List<T>> collector, @Repeated U elements) {
|
||||
return assertThat(stream.collect(collector))
|
||||
@@ -1134,6 +1155,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@SuppressWarnings("ObjectEnumerableDoesNotContainOneElement" /* Not a true singleton. */)
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, @Repeated U elements) {
|
||||
return assertThat(stream).doesNotContainSequence(elements);
|
||||
@@ -1185,12 +1207,14 @@ final class AssertJTemplates {
|
||||
// XXX: This rule assumes the `collector` doesn't completely discard certain values.
|
||||
static final class AssertThatStreamContainsOnlyVarArgs<S, T extends S, U extends T> {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings("AssertThatStreamContainsOnly" /* Varargs converted to array. */)
|
||||
IterableAssert<T> before(
|
||||
Stream<S> stream, Collector<S, ?, ? extends Iterable<T>> collector, @Repeated U elements) {
|
||||
return assertThat(stream.collect(collector)).containsOnly(Refaster.asVarargs(elements));
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings("AssertThatStreamContainsOnly" /* Varargs converted to array. */)
|
||||
ListAssert<T> before2(
|
||||
Stream<S> stream, Collector<S, ?, ? extends List<T>> collector, @Repeated U elements) {
|
||||
return assertThat(stream.collect(collector)).containsOnly(Refaster.asVarargs(elements));
|
||||
@@ -1239,12 +1263,14 @@ final class AssertJTemplates {
|
||||
// XXX: This rule assumes the `collector` doesn't completely discard certain values.
|
||||
static final class AssertThatStreamIsSubsetOfVarArgs<S, T extends S, U extends T> {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings("AssertThatStreamIsSubsetOf" /* Varargs converted to array. */)
|
||||
IterableAssert<T> before(
|
||||
Stream<S> stream, Collector<S, ?, ? extends Iterable<T>> collector, @Repeated U elements) {
|
||||
return assertThat(stream.collect(collector)).isSubsetOf(Refaster.asVarargs(elements));
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings("AssertThatStreamIsSubsetOf" /* Varargs converted to array. */)
|
||||
ListAssert<T> before2(
|
||||
Stream<S> stream, Collector<S, ?, ? extends List<T>> collector, @Repeated U elements) {
|
||||
return assertThat(stream.collect(collector)).isSubsetOf(Refaster.asVarargs(elements));
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkElementIndex;
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
import static com.google.common.collect.Sets.toImmutableEnumSet;
|
||||
import static java.util.Objects.checkIndex;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
@@ -38,12 +39,12 @@ final class AssortedTemplates {
|
||||
static final class CheckIndex {
|
||||
@BeforeTemplate
|
||||
int before(int index, int size) {
|
||||
return Preconditions.checkElementIndex(index, size);
|
||||
return checkElementIndex(index, size);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
int after(int index, int size) {
|
||||
return Objects.checkIndex(index, size);
|
||||
return checkIndex(index, size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,14 +63,14 @@ final class AssortedTemplates {
|
||||
}
|
||||
|
||||
static final class MapGetOrNull<K, V, L> {
|
||||
@Nullable
|
||||
@BeforeTemplate
|
||||
@Nullable
|
||||
V before(Map<K, V> map, L key) {
|
||||
return map.getOrDefault(key, null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@AfterTemplate
|
||||
@Nullable
|
||||
V after(Map<K, V> map, L key) {
|
||||
return map.get(key);
|
||||
}
|
||||
@@ -107,8 +108,8 @@ final class AssortedTemplates {
|
||||
Streams.stream(iterator).findAny().orElse(defaultValue));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@AfterTemplate
|
||||
@Nullable
|
||||
T after(Iterator<T> iterator, T defaultValue) {
|
||||
return Iterators.getNext(iterator, defaultValue);
|
||||
}
|
||||
@@ -256,11 +257,6 @@ final class AssortedTemplates {
|
||||
//
|
||||
// @BeforeTemplate
|
||||
// void before(Supplier<T> supplier) {
|
||||
// anyStatement(supplier::get);
|
||||
// }
|
||||
//
|
||||
// @BeforeTemplate
|
||||
// void before2(Supplier<T> supplier) {
|
||||
// anyStatement(() -> supplier.get());
|
||||
// }
|
||||
//
|
||||
|
||||
@@ -10,11 +10,13 @@ import com.google.errorprone.refaster.annotation.AlsoNegation;
|
||||
import com.google.errorprone.refaster.annotation.BeforeTemplate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.NavigableSet;
|
||||
import java.util.Optional;
|
||||
import java.util.Queue;
|
||||
import java.util.SortedSet;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/** Refaster templates related to expressions dealing with (arbitrary) collections. */
|
||||
@@ -37,6 +39,11 @@ final class CollectionTemplates {
|
||||
Iterables.isEmpty(collection));
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
boolean before(ImmutableCollection<T> collection) {
|
||||
return collection.asList().isEmpty();
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@AlsoNegation
|
||||
boolean after(Collection<T> collection) {
|
||||
@@ -51,6 +58,11 @@ final class CollectionTemplates {
|
||||
return Iterables.size(collection);
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
int before(ImmutableCollection<T> collection) {
|
||||
return collection.asList().size();
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
int after(Collection<T> collection) {
|
||||
return collection.size();
|
||||
@@ -146,8 +158,10 @@ final class CollectionTemplates {
|
||||
}
|
||||
|
||||
/** Prefer {@link ArrayList#ArrayList(Collection)} over the Guava alternative. */
|
||||
// XXX: Drop this template if we adopt `baseline-error-prone`.
|
||||
static final class NewArrayListFromCollection<T> {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings("PreferCollectionConstructors")
|
||||
ArrayList<T> before(Collection<T> collection) {
|
||||
return Lists.newArrayList(collection);
|
||||
}
|
||||
@@ -175,16 +189,6 @@ final class CollectionTemplates {
|
||||
* Don't call {@link ImmutableCollection#asList()} if the result is going to be streamed; stream
|
||||
* directly.
|
||||
*/
|
||||
// XXX: Similar rules could be implemented for the following variants:
|
||||
// collection.asList().contains(null);
|
||||
// collection.asList().isEmpty();
|
||||
// collection.asList().iterator();
|
||||
// collection.asList().parallelStream();
|
||||
// collection.asList().size();
|
||||
// collection.asList().toArray();
|
||||
// collection.asList().toArray(Object[]::new);
|
||||
// collection.asList().toArray(new Object[0]);
|
||||
// collection.asList().toString();
|
||||
static final class ImmutableCollectionAsListToStream<T> {
|
||||
@BeforeTemplate
|
||||
Stream<T> before(ImmutableCollection<T> collection) {
|
||||
@@ -197,6 +201,121 @@ final class CollectionTemplates {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't call {@link ImmutableCollection#asList()} if {@link Collection#contains(Object)} is
|
||||
* called on the result; call it directly.
|
||||
*/
|
||||
static final class ImmutableCollectionContains<T, S> {
|
||||
@BeforeTemplate
|
||||
boolean before(ImmutableCollection<T> collection, S elem) {
|
||||
return collection.asList().contains(elem);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
boolean after(ImmutableCollection<T> collection, S elem) {
|
||||
return collection.contains(elem);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't call {@link ImmutableCollection#asList()} if {@link ImmutableCollection#parallelStream()}
|
||||
* is called on the result; call it directly.
|
||||
*/
|
||||
static final class ImmutableCollectionParallelStream<T> {
|
||||
@BeforeTemplate
|
||||
Stream<T> before(ImmutableCollection<T> collection) {
|
||||
return collection.asList().parallelStream();
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Stream<T> after(ImmutableCollection<T> collection) {
|
||||
return collection.parallelStream();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't call {@link ImmutableCollection#asList()} if {@link ImmutableCollection#toString()} is
|
||||
* called on the result; call it directly.
|
||||
*/
|
||||
static final class ImmutableCollectionToString<T> {
|
||||
@BeforeTemplate
|
||||
String before(ImmutableCollection<T> collection) {
|
||||
return collection.asList().toString();
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
String after(ImmutableCollection<T> collection) {
|
||||
return collection.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/** Prefer calling {@link Collection#toArray()} over more contrived alternatives. */
|
||||
static final class CollectionToArray<T> {
|
||||
@BeforeTemplate
|
||||
Object[] before(Collection<T> collection, int size) {
|
||||
return Refaster.anyOf(
|
||||
collection.toArray(new Object[size]), collection.toArray(Object[]::new));
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
Object[] before(ImmutableCollection<T> collection) {
|
||||
return collection.asList().toArray();
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Object[] after(Collection<T> collection) {
|
||||
return collection.toArray();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't call {@link ImmutableCollection#asList()} if {@link
|
||||
* ImmutableCollection#toArray(Object[])}` is called on the result; call it directly.
|
||||
*/
|
||||
static final class ImmutableCollectionToArrayWithArray<T, S> {
|
||||
@BeforeTemplate
|
||||
Object[] before(ImmutableCollection<T> collection, S[] array) {
|
||||
return collection.asList().toArray(array);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Object[] after(ImmutableCollection<T> collection, S[] array) {
|
||||
return collection.toArray(array);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't call {@link ImmutableCollection#asList()} if {@link
|
||||
* ImmutableCollection#toArray(IntFunction)}} is called on the result; call it directly.
|
||||
*/
|
||||
static final class ImmutableCollectionToArrayWithGenerator<T, S> {
|
||||
@BeforeTemplate
|
||||
S[] before(ImmutableCollection<T> collection, IntFunction<S[]> generator) {
|
||||
return collection.asList().toArray(generator);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
S[] after(ImmutableCollection<T> collection, IntFunction<S[]> generator) {
|
||||
return collection.toArray(generator);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't call {@link ImmutableCollection#asList()} if {@link ImmutableCollection#iterator()} is
|
||||
* called on the result; call it directly.
|
||||
*/
|
||||
static final class ImmutableCollectionIterator<T> {
|
||||
@BeforeTemplate
|
||||
Iterator<T> before(ImmutableCollection<T> collection) {
|
||||
return collection.asList().iterator();
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Iterator<T> after(ImmutableCollection<T> collection) {
|
||||
return collection.iterator();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't use the ternary operator to extract the first element of a possibly-empty {@link
|
||||
* Collection} as an {@link Optional}.
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static java.util.Comparator.comparing;
|
||||
import static java.util.Comparator.comparingDouble;
|
||||
import static java.util.Comparator.comparingInt;
|
||||
import static java.util.Comparator.comparingLong;
|
||||
import static java.util.Comparator.naturalOrder;
|
||||
import static java.util.Comparator.reverseOrder;
|
||||
import static java.util.function.Function.identity;
|
||||
|
||||
@@ -29,14 +34,13 @@ final class ComparatorTemplates {
|
||||
@BeforeTemplate
|
||||
Comparator<T> before() {
|
||||
return Refaster.anyOf(
|
||||
Comparator.comparing(Refaster.anyOf(identity(), v -> v)),
|
||||
Comparator.<T>reverseOrder().reversed());
|
||||
comparing(Refaster.anyOf(identity(), v -> v)), Comparator.<T>reverseOrder().reversed());
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
Comparator<T> after() {
|
||||
return Comparator.naturalOrder();
|
||||
return naturalOrder();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +62,7 @@ final class ComparatorTemplates {
|
||||
// XXX: Drop the `Refaster.anyOf` if/when we decide to rewrite one to the other.
|
||||
@BeforeTemplate
|
||||
Comparator<T> before(Comparator<T> cmp) {
|
||||
return Comparator.comparing(Refaster.anyOf(identity(), v -> v), cmp);
|
||||
return comparing(Refaster.anyOf(identity(), v -> v), cmp);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -72,7 +76,7 @@ final class ComparatorTemplates {
|
||||
static final class ThenComparing<S, T extends Comparable<? super T>> {
|
||||
@BeforeTemplate
|
||||
Comparator<S> before(Comparator<S> cmp, Function<? super S, ? extends T> function) {
|
||||
return cmp.thenComparing(Comparator.comparing(function));
|
||||
return cmp.thenComparing(comparing(function));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -85,7 +89,7 @@ final class ComparatorTemplates {
|
||||
static final class ThenComparingReversed<S, T extends Comparable<? super T>> {
|
||||
@BeforeTemplate
|
||||
Comparator<S> before(Comparator<S> cmp, Function<? super S, ? extends T> function) {
|
||||
return cmp.thenComparing(Comparator.comparing(function).reversed());
|
||||
return cmp.thenComparing(comparing(function).reversed());
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -100,7 +104,7 @@ final class ComparatorTemplates {
|
||||
@BeforeTemplate
|
||||
Comparator<S> before(
|
||||
Comparator<S> cmp, Function<? super S, ? extends T> function, Comparator<? super T> cmp2) {
|
||||
return cmp.thenComparing(Comparator.comparing(function, cmp2));
|
||||
return cmp.thenComparing(comparing(function, cmp2));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -115,7 +119,7 @@ final class ComparatorTemplates {
|
||||
@BeforeTemplate
|
||||
Comparator<S> before(
|
||||
Comparator<S> cmp, Function<? super S, ? extends T> function, Comparator<? super T> cmp2) {
|
||||
return cmp.thenComparing(Comparator.comparing(function, cmp2).reversed());
|
||||
return cmp.thenComparing(comparing(function, cmp2).reversed());
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -129,7 +133,7 @@ final class ComparatorTemplates {
|
||||
static final class ThenComparingDouble<T> {
|
||||
@BeforeTemplate
|
||||
Comparator<T> before(Comparator<T> cmp, ToDoubleFunction<? super T> function) {
|
||||
return cmp.thenComparing(Comparator.comparingDouble(function));
|
||||
return cmp.thenComparing(comparingDouble(function));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -142,7 +146,7 @@ final class ComparatorTemplates {
|
||||
static final class ThenComparingInt<T> {
|
||||
@BeforeTemplate
|
||||
Comparator<T> before(Comparator<T> cmp, ToIntFunction<? super T> function) {
|
||||
return cmp.thenComparing(Comparator.comparingInt(function));
|
||||
return cmp.thenComparing(comparingInt(function));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -155,7 +159,7 @@ final class ComparatorTemplates {
|
||||
static final class ThenComparingLong<T> {
|
||||
@BeforeTemplate
|
||||
Comparator<T> before(Comparator<T> cmp, ToLongFunction<? super T> function) {
|
||||
return cmp.thenComparing(Comparator.comparingLong(function));
|
||||
return cmp.thenComparing(comparingLong(function));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -178,7 +182,7 @@ final class ComparatorTemplates {
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
Comparator<T> after(Comparator<T> cmp) {
|
||||
return cmp.thenComparing(Comparator.naturalOrder());
|
||||
return cmp.thenComparing(naturalOrder());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -233,10 +233,7 @@ final class DoubleStreamTemplates {
|
||||
static final class DoubleStreamAllMatch {
|
||||
@BeforeTemplate
|
||||
boolean before(DoubleStream stream, DoublePredicate predicate) {
|
||||
return Refaster.anyOf(
|
||||
stream.noneMatch(predicate.negate()),
|
||||
!stream.anyMatch(predicate.negate()),
|
||||
stream.filter(predicate.negate()).findAny().isEmpty());
|
||||
return stream.noneMatch(predicate.negate());
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -251,10 +248,7 @@ final class DoubleStreamTemplates {
|
||||
|
||||
@BeforeTemplate
|
||||
boolean before(DoubleStream stream) {
|
||||
return Refaster.anyOf(
|
||||
stream.noneMatch(e -> !test(e)),
|
||||
!stream.anyMatch(e -> !test(e)),
|
||||
stream.filter(e -> !test(e)).findAny().isEmpty());
|
||||
return stream.noneMatch(e -> !test(e));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
|
||||
@@ -4,7 +4,6 @@ import com.google.errorprone.refaster.Refaster;
|
||||
import com.google.errorprone.refaster.annotation.AfterTemplate;
|
||||
import com.google.errorprone.refaster.annotation.AlsoNegation;
|
||||
import com.google.errorprone.refaster.annotation.BeforeTemplate;
|
||||
import com.google.errorprone.refaster.annotation.NoAutoboxing;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@@ -12,26 +11,9 @@ import java.util.function.Predicate;
|
||||
final class EqualityTemplates {
|
||||
private EqualityTemplates() {}
|
||||
|
||||
/** Prefer primitive/reference-based quality for primitives and enums. */
|
||||
static final class PrimitiveOrReferenceEquality {
|
||||
@NoAutoboxing
|
||||
@BeforeTemplate
|
||||
boolean before(boolean a, boolean b) {
|
||||
return Objects.equals(a, b);
|
||||
}
|
||||
|
||||
@NoAutoboxing
|
||||
@BeforeTemplate
|
||||
boolean before(long a, long b) {
|
||||
return Objects.equals(a, b);
|
||||
}
|
||||
|
||||
@NoAutoboxing
|
||||
@BeforeTemplate
|
||||
boolean before(double a, double b) {
|
||||
return Objects.equals(a, b);
|
||||
}
|
||||
|
||||
/** Prefer reference-based quality for enums. */
|
||||
// Primitive value comparisons are not listed, because Error Prone flags those out of the box.
|
||||
static final class PrimitiveOrReferenceEquality<T extends Enum<T>> {
|
||||
/**
|
||||
* Enums can be compared by reference. It is safe to do so even in the face of refactorings,
|
||||
* because if the type is ever converted to a non-enum, then Error-Prone will complain about any
|
||||
@@ -40,13 +22,13 @@ final class EqualityTemplates {
|
||||
// XXX: This Refaster rule is the topic of https://github.com/google/error-prone/issues/559. We
|
||||
// work around the issue by selecting the "largest replacements". See RefasterCheck.
|
||||
@BeforeTemplate
|
||||
<T extends Enum<T>> boolean before(T a, T b) {
|
||||
boolean before(T a, T b) {
|
||||
return Refaster.anyOf(a.equals(b), Objects.equals(a, b));
|
||||
}
|
||||
|
||||
@AlsoNegation
|
||||
@AfterTemplate
|
||||
boolean after(boolean a, boolean b) {
|
||||
@AlsoNegation
|
||||
boolean after(T a, T b) {
|
||||
return a == b;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,10 +56,7 @@ final class ImmutableListMultimapTemplates {
|
||||
static final class EmptyImmutableListMultimap<K, V> {
|
||||
@BeforeTemplate
|
||||
ImmutableMultimap<K, V> before() {
|
||||
return Refaster.anyOf(
|
||||
ImmutableListMultimap.<K, V>builder().build(),
|
||||
ImmutableMultimap.<K, V>builder().build(),
|
||||
ImmutableMultimap.of());
|
||||
return Refaster.anyOf(ImmutableListMultimap.<K, V>builder().build(), ImmutableMultimap.of());
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -80,7 +77,6 @@ final class ImmutableListMultimapTemplates {
|
||||
ImmutableMultimap<K, V> before(K key, V value) {
|
||||
return Refaster.anyOf(
|
||||
ImmutableListMultimap.<K, V>builder().put(key, value).build(),
|
||||
ImmutableMultimap.<K, V>builder().put(key, value).build(),
|
||||
ImmutableMultimap.of(key, value));
|
||||
}
|
||||
|
||||
@@ -99,9 +95,8 @@ final class ImmutableListMultimapTemplates {
|
||||
ImmutableMultimap<K, V> before(Map.Entry<? extends K, ? extends V> entry) {
|
||||
return Refaster.anyOf(
|
||||
ImmutableListMultimap.<K, V>builder().put(entry).build(),
|
||||
Stream.of(entry).collect(toImmutableListMultimap(Map.Entry::getKey, Map.Entry::getValue)),
|
||||
ImmutableMultimap.<K, V>builder().put(entry).build(),
|
||||
ImmutableMultimap.of(entry.getKey(), entry.getValue()));
|
||||
Stream.of(entry)
|
||||
.collect(toImmutableListMultimap(Map.Entry::getKey, Map.Entry::getValue)));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -118,8 +113,7 @@ final class ImmutableListMultimapTemplates {
|
||||
ImmutableListMultimap.copyOf(iterable.entries()),
|
||||
ImmutableListMultimap.<K, V>builder().putAll(iterable).build(),
|
||||
ImmutableMultimap.copyOf(iterable),
|
||||
ImmutableMultimap.copyOf(iterable.entries()),
|
||||
ImmutableMultimap.<K, V>builder().putAll(iterable).build());
|
||||
ImmutableMultimap.copyOf(iterable.entries()));
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
@@ -129,7 +123,6 @@ final class ImmutableListMultimapTemplates {
|
||||
ImmutableListMultimap.<K, V>builder().putAll(iterable).build(),
|
||||
Streams.stream(iterable)
|
||||
.collect(toImmutableListMultimap(Map.Entry::getKey, Map.Entry::getValue)),
|
||||
ImmutableMultimap.<K, V>builder().putAll(iterable).build(),
|
||||
ImmutableMultimap.copyOf(iterable));
|
||||
}
|
||||
|
||||
|
||||
@@ -76,13 +76,11 @@ final class ImmutableListTemplates {
|
||||
* Prefer {@link ImmutableList#copyOf(Iterable)} and variants over more contrived alternatives.
|
||||
*/
|
||||
static final class IterableToImmutableList<T> {
|
||||
// XXX: Drop the inner `Refaster.anyOf` if/when we introduce a rule to choose between one and
|
||||
// the other.
|
||||
@BeforeTemplate
|
||||
ImmutableList<T> before(T[] iterable) {
|
||||
return Refaster.anyOf(
|
||||
ImmutableList.<T>builder().add(iterable).build(),
|
||||
Refaster.anyOf(Stream.of(iterable), Arrays.stream(iterable)).collect(toImmutableList()));
|
||||
Arrays.stream(iterable).collect(toImmutableList()));
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
@@ -120,7 +118,6 @@ final class ImmutableListTemplates {
|
||||
ImmutableList<T> before(Stream<T> stream) {
|
||||
return Refaster.anyOf(
|
||||
ImmutableList.copyOf(stream.iterator()),
|
||||
ImmutableList.copyOf(stream::iterator),
|
||||
stream.collect(collectingAndThen(toList(), ImmutableList::copyOf)));
|
||||
}
|
||||
|
||||
|
||||
@@ -54,14 +54,11 @@ final class ImmutableMultisetTemplates {
|
||||
* alternatives.
|
||||
*/
|
||||
static final class IterableToImmutableMultiset<T> {
|
||||
// XXX: Drop the inner `Refaster.anyOf` if/when we introduce a rule to choose between one and
|
||||
// the other.
|
||||
@BeforeTemplate
|
||||
ImmutableMultiset<T> before(T[] iterable) {
|
||||
return Refaster.anyOf(
|
||||
ImmutableMultiset.<T>builder().add(iterable).build(),
|
||||
Refaster.anyOf(Stream.of(iterable), Arrays.stream(iterable))
|
||||
.collect(toImmutableMultiset()));
|
||||
Arrays.stream(iterable).collect(toImmutableMultiset()));
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
@@ -95,7 +92,6 @@ final class ImmutableMultisetTemplates {
|
||||
ImmutableMultiset<T> before(Stream<T> stream) {
|
||||
return Refaster.anyOf(
|
||||
ImmutableMultiset.copyOf(stream.iterator()),
|
||||
ImmutableMultiset.copyOf(stream::iterator),
|
||||
stream.collect(collectingAndThen(toList(), ImmutableMultiset::copyOf)));
|
||||
}
|
||||
|
||||
|
||||
@@ -72,13 +72,11 @@ final class ImmutableSetTemplates {
|
||||
|
||||
/** Prefer {@link ImmutableSet#copyOf(Iterable)} and variants over more contrived alternatives. */
|
||||
static final class IterableToImmutableSet<T> {
|
||||
// XXX: Drop the inner `Refaster.anyOf` if/when we introduce a rule to choose between one and
|
||||
// the other.
|
||||
@BeforeTemplate
|
||||
ImmutableSet<T> before(T[] iterable) {
|
||||
return Refaster.anyOf(
|
||||
ImmutableSet.<T>builder().add(iterable).build(),
|
||||
Refaster.anyOf(Stream.of(iterable), Arrays.stream(iterable)).collect(toImmutableSet()));
|
||||
Arrays.stream(iterable).collect(toImmutableSet()));
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
@@ -116,7 +114,6 @@ final class ImmutableSetTemplates {
|
||||
ImmutableSet<T> before(Stream<T> stream) {
|
||||
return Refaster.anyOf(
|
||||
ImmutableSet.copyOf(stream.iterator()),
|
||||
ImmutableSet.copyOf(stream::iterator),
|
||||
stream.distinct().collect(toImmutableSet()),
|
||||
stream.collect(collectingAndThen(toList(), ImmutableSet::copyOf)),
|
||||
stream.collect(collectingAndThen(toSet(), ImmutableSet::copyOf)));
|
||||
|
||||
@@ -92,14 +92,11 @@ final class ImmutableSortedMultisetTemplates {
|
||||
// XXX: There's also a variant with a custom Comparator. (And some special cases with
|
||||
// `reverseOrder`.) Worth the hassle?
|
||||
static final class IterableToImmutableSortedMultiset<T extends Comparable<? super T>> {
|
||||
// XXX: Drop the inner `Refaster.anyOf` if/when we introduce a rule to choose between one and
|
||||
// the other.
|
||||
@BeforeTemplate
|
||||
ImmutableMultiset<T> before(T[] iterable) {
|
||||
return Refaster.anyOf(
|
||||
ImmutableSortedMultiset.<T>naturalOrder().add(iterable).build(),
|
||||
Refaster.anyOf(Stream.of(iterable), Arrays.stream(iterable))
|
||||
.collect(toImmutableSortedMultiset(naturalOrder())));
|
||||
Arrays.stream(iterable).collect(toImmutableSortedMultiset(naturalOrder())));
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
@@ -139,7 +136,6 @@ final class ImmutableSortedMultisetTemplates {
|
||||
ImmutableSortedMultiset<T> before(Stream<T> stream) {
|
||||
return Refaster.anyOf(
|
||||
ImmutableSortedMultiset.copyOf(stream.iterator()),
|
||||
ImmutableSortedMultiset.copyOf(stream::iterator),
|
||||
stream.collect(collectingAndThen(toList(), ImmutableSortedMultiset::copyOf)));
|
||||
}
|
||||
|
||||
|
||||
@@ -90,14 +90,11 @@ final class ImmutableSortedSetTemplates {
|
||||
// XXX: There's also a variant with a custom Comparator. (And some special cases with
|
||||
// `reverseOrder`.) Worth the hassle?
|
||||
static final class IterableToImmutableSortedSet<T extends Comparable<? super T>> {
|
||||
// XXX: Drop the inner `Refaster.anyOf` if/when we introduce a rule to choose between one and
|
||||
// the other.
|
||||
@BeforeTemplate
|
||||
ImmutableSet<T> before(T[] iterable) {
|
||||
return Refaster.anyOf(
|
||||
ImmutableSortedSet.<T>naturalOrder().add(iterable).build(),
|
||||
Refaster.anyOf(Stream.of(iterable), Arrays.stream(iterable))
|
||||
.collect(toImmutableSortedSet(naturalOrder())));
|
||||
Arrays.stream(iterable).collect(toImmutableSortedSet(naturalOrder())));
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
@@ -139,7 +136,6 @@ final class ImmutableSortedSetTemplates {
|
||||
ImmutableSortedSet<T> before(Stream<T> stream) {
|
||||
return Refaster.anyOf(
|
||||
ImmutableSortedSet.copyOf(stream.iterator()),
|
||||
ImmutableSortedSet.copyOf(stream::iterator),
|
||||
stream.collect(collectingAndThen(toList(), ImmutableSortedSet::copyOf)));
|
||||
}
|
||||
|
||||
|
||||
@@ -246,10 +246,7 @@ final class IntStreamTemplates {
|
||||
static final class IntStreamAllMatch {
|
||||
@BeforeTemplate
|
||||
boolean before(IntStream stream, IntPredicate predicate) {
|
||||
return Refaster.anyOf(
|
||||
stream.noneMatch(predicate.negate()),
|
||||
!stream.anyMatch(predicate.negate()),
|
||||
stream.filter(predicate.negate()).findAny().isEmpty());
|
||||
return stream.noneMatch(predicate.negate());
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -264,10 +261,7 @@ final class IntStreamTemplates {
|
||||
|
||||
@BeforeTemplate
|
||||
boolean before(IntStream stream) {
|
||||
return Refaster.anyOf(
|
||||
stream.noneMatch(e -> !test(e)),
|
||||
!stream.anyMatch(e -> !test(e)),
|
||||
stream.filter(e -> !test(e)).findAny().isEmpty());
|
||||
return stream.noneMatch(e -> !test(e));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
|
||||
@@ -246,10 +246,7 @@ final class LongStreamTemplates {
|
||||
static final class LongStreamAllMatch {
|
||||
@BeforeTemplate
|
||||
boolean before(LongStream stream, LongPredicate predicate) {
|
||||
return Refaster.anyOf(
|
||||
stream.noneMatch(predicate.negate()),
|
||||
!stream.anyMatch(predicate.negate()),
|
||||
stream.filter(predicate.negate()).findAny().isEmpty());
|
||||
return stream.noneMatch(predicate.negate());
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -264,10 +261,7 @@ final class LongStreamTemplates {
|
||||
|
||||
@BeforeTemplate
|
||||
boolean before(LongStream stream) {
|
||||
return Refaster.anyOf(
|
||||
stream.noneMatch(e -> !test(e)),
|
||||
!stream.anyMatch(e -> !test(e)),
|
||||
stream.filter(e -> !test(e)).findAny().isEmpty());
|
||||
return stream.noneMatch(e -> !test(e));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static java.util.Comparator.comparing;
|
||||
import static java.util.Comparator.naturalOrder;
|
||||
import static java.util.Map.Entry.comparingByKey;
|
||||
import static java.util.Map.Entry.comparingByValue;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.errorprone.refaster.ImportPolicy;
|
||||
import com.google.errorprone.refaster.Refaster;
|
||||
@@ -42,15 +47,13 @@ final class MapEntryTemplates {
|
||||
static final class MapEntryComparingByKey<K extends Comparable<? super K>, V> {
|
||||
@BeforeTemplate
|
||||
Comparator<Map.Entry<K, V>> before() {
|
||||
return Refaster.anyOf(
|
||||
Comparator.comparing(Map.Entry::getKey),
|
||||
Map.Entry.comparingByKey(Comparator.naturalOrder()));
|
||||
return Refaster.anyOf(comparing(Map.Entry::getKey), comparingByKey(naturalOrder()));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
Comparator<Map.Entry<K, V>> after() {
|
||||
return Map.Entry.comparingByKey();
|
||||
return comparingByKey();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,13 +61,13 @@ final class MapEntryTemplates {
|
||||
static final class MapEntryComparingByKeyWithCustomComparator<K, V> {
|
||||
@BeforeTemplate
|
||||
Comparator<Map.Entry<K, V>> before(Comparator<? super K> cmp) {
|
||||
return Comparator.comparing(Map.Entry::getKey, cmp);
|
||||
return comparing(Map.Entry::getKey, cmp);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
Comparator<Map.Entry<K, V>> after(Comparator<? super K> cmp) {
|
||||
return Map.Entry.comparingByKey(cmp);
|
||||
return comparingByKey(cmp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,15 +76,13 @@ final class MapEntryTemplates {
|
||||
static final class MapEntryComparingByValue<K, V extends Comparable<? super V>> {
|
||||
@BeforeTemplate
|
||||
Comparator<Map.Entry<K, V>> before() {
|
||||
return Refaster.anyOf(
|
||||
Comparator.comparing(Map.Entry::getValue),
|
||||
Map.Entry.comparingByValue(Comparator.naturalOrder()));
|
||||
return Refaster.anyOf(comparing(Map.Entry::getValue), comparingByValue(naturalOrder()));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
Comparator<Map.Entry<K, V>> after() {
|
||||
return Map.Entry.comparingByValue();
|
||||
return comparingByValue();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,13 +90,13 @@ final class MapEntryTemplates {
|
||||
static final class MapEntryComparingByValueWithCustomComparator<K, V> {
|
||||
@BeforeTemplate
|
||||
Comparator<Map.Entry<K, V>> before(Comparator<? super V> cmp) {
|
||||
return Comparator.comparing(Map.Entry::getValue, cmp);
|
||||
return comparing(Map.Entry::getValue, cmp);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
Comparator<Map.Entry<K, V>> after(Comparator<? super V> cmp) {
|
||||
return Map.Entry.comparingByValue(cmp);
|
||||
return comparingByValue(cmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static java.util.Objects.requireNonNullElse;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.google.errorprone.refaster.ImportPolicy;
|
||||
import com.google.errorprone.refaster.annotation.AfterTemplate;
|
||||
@@ -24,7 +26,7 @@ final class NullTemplates {
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
T after(T first, T second) {
|
||||
return Objects.requireNonNullElse(first, second);
|
||||
return requireNonNullElse(first, second);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,10 +20,10 @@ final class OptionalTemplates {
|
||||
private OptionalTemplates() {}
|
||||
|
||||
static final class OptionalOfNullable<T> {
|
||||
@BeforeTemplate
|
||||
// XXX: Refaster should be smart enough to also rewrite occurrences in which there are
|
||||
// parentheses around the null check, but that's currently not the case. Try to fix that.
|
||||
// XXX: This is a special case of `TernaryOperatorOptionalNegativeFiltering`.
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings("TernaryOperatorOptionalNegativeFiltering" /* Special case. */)
|
||||
Optional<T> before(T object) {
|
||||
return object == null ? Optional.empty() : Optional.of(object);
|
||||
}
|
||||
@@ -167,6 +167,7 @@ final class OptionalTemplates {
|
||||
*/
|
||||
abstract static class MapOptionalToBoolean<T> {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings("OptionalOrElseMethodInvocation")
|
||||
boolean before(Optional<T> optional, Function<? super T, Boolean> predicate) {
|
||||
return optional.map(predicate).orElse(Refaster.anyOf(false, Boolean.FALSE));
|
||||
}
|
||||
@@ -317,6 +318,7 @@ final class OptionalTemplates {
|
||||
/** Prefer {@link Optional#or(Supplier)} over more verbose alternatives. */
|
||||
abstract static class OptionalOrOtherOptional<T> {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings("OptionalOrElseGetValue")
|
||||
Optional<T> before(Optional<T> optional1, Optional<T> optional2) {
|
||||
// XXX: Note that rewriting the first and third variant will change the code's behavior if
|
||||
// `optional2` has side-effects.
|
||||
|
||||
@@ -77,7 +77,7 @@ final class ReactorTemplates {
|
||||
static final class MonoErrorSupplier<T, E extends Throwable> {
|
||||
@BeforeTemplate
|
||||
Mono<T> before(Supplier<E> supplier) {
|
||||
return Refaster.anyOf(Mono.error(supplier::get), Mono.error(() -> supplier.get()));
|
||||
return Mono.error(() -> supplier.get());
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -94,7 +94,7 @@ final class ReactorTemplates {
|
||||
static final class FluxErrorSupplier<T, E extends Throwable> {
|
||||
@BeforeTemplate
|
||||
Flux<T> before(Supplier<E> supplier) {
|
||||
return Refaster.anyOf(Flux.error(supplier::get), Flux.error(() -> supplier.get()));
|
||||
return Flux.error(() -> supplier.get());
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.google.errorprone.refaster.annotation.BeforeTemplate;
|
||||
import com.google.errorprone.refaster.annotation.MayOptionallyUse;
|
||||
import com.google.errorprone.refaster.annotation.Placeholder;
|
||||
import com.google.errorprone.refaster.annotation.UseImportPolicy;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
@@ -23,19 +24,6 @@ import java.util.stream.Stream;
|
||||
final class StreamTemplates {
|
||||
private StreamTemplates() {}
|
||||
|
||||
/** Prefer {@link Stream#empty()} over less clear alternatives. */
|
||||
static final class EmptyStream<T> {
|
||||
@BeforeTemplate
|
||||
Stream<T> before() {
|
||||
return Stream.of();
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Stream<T> after() {
|
||||
return Stream.empty();
|
||||
}
|
||||
}
|
||||
|
||||
/** Prefer {@link Stream#ofNullable(Object)} over more contrived alternatives. */
|
||||
static final class StreamOfNullable<T> {
|
||||
@BeforeTemplate
|
||||
@@ -50,6 +38,22 @@ final class StreamTemplates {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link Arrays#stream(Object[])} over {@link Stream#of(Object[])}, as the former is
|
||||
* clearer.
|
||||
*/
|
||||
static final class StreamOfArray<T> {
|
||||
@BeforeTemplate
|
||||
Stream<T> before(T[] array) {
|
||||
return Stream.of(array);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Stream<T> after(T[] array) {
|
||||
return Arrays.stream(array);
|
||||
}
|
||||
}
|
||||
|
||||
/** Don't unnecessarily call {@link Streams#concat(Stream...)}. */
|
||||
static final class ConcatOneStream<T> {
|
||||
@BeforeTemplate
|
||||
@@ -277,10 +281,7 @@ final class StreamTemplates {
|
||||
static final class StreamAllMatch<T> {
|
||||
@BeforeTemplate
|
||||
boolean before(Stream<T> stream, Predicate<? super T> predicate) {
|
||||
return Refaster.anyOf(
|
||||
stream.noneMatch(Refaster.anyOf(not(predicate), predicate.negate())),
|
||||
!stream.anyMatch(Refaster.anyOf(not(predicate), predicate.negate())),
|
||||
stream.filter(Refaster.anyOf(not(predicate), predicate.negate())).findAny().isEmpty());
|
||||
return stream.noneMatch(Refaster.anyOf(not(predicate), predicate.negate()));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -295,10 +296,7 @@ final class StreamTemplates {
|
||||
|
||||
@BeforeTemplate
|
||||
boolean before(Stream<T> stream) {
|
||||
return Refaster.anyOf(
|
||||
stream.noneMatch(e -> !test(e)),
|
||||
!stream.anyMatch(e -> !test(e)),
|
||||
stream.filter(e -> !test(e)).findAny().isEmpty());
|
||||
return stream.noneMatch(e -> !test(e));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
@@ -10,11 +11,9 @@ import com.google.errorprone.refaster.Refaster;
|
||||
import com.google.errorprone.refaster.annotation.AfterTemplate;
|
||||
import com.google.errorprone.refaster.annotation.AlsoNegation;
|
||||
import com.google.errorprone.refaster.annotation.BeforeTemplate;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/** Refaster templates related to expressions dealing with {@link String}s. */
|
||||
// XXX: Should we prefer `s -> !s.isEmpty()` or `not(String::isEmpty)`?
|
||||
@@ -82,12 +81,10 @@ final class StringTemplates {
|
||||
// XXX: Joiner#join(@Nullable Object first, @Nullable Object second, Object... rest) isn't
|
||||
// rewritten.
|
||||
static final class JoinStrings {
|
||||
// XXX: Drop the inner `Refaster.anyOf` if/when we decide to rewrite one to the other.
|
||||
@BeforeTemplate
|
||||
String before(String delimiter, CharSequence[] elements) {
|
||||
return Refaster.anyOf(
|
||||
Joiner.on(delimiter).join(elements),
|
||||
Refaster.anyOf(Stream.of(elements), Arrays.stream(elements)).collect(joining(delimiter)));
|
||||
Joiner.on(delimiter).join(elements), Arrays.stream(elements).collect(joining(delimiter)));
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
@@ -125,7 +122,7 @@ final class StringTemplates {
|
||||
static final class Utf8EncodedLength {
|
||||
@BeforeTemplate
|
||||
int before(String str) {
|
||||
return str.getBytes(StandardCharsets.UTF_8).length;
|
||||
return str.getBytes(UTF_8).length;
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
|
||||
@@ -16,6 +16,7 @@ import static org.testng.Assert.assertThrows;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.errorprone.annotations.DoNotCall;
|
||||
import com.google.errorprone.refaster.ImportPolicy;
|
||||
import com.google.errorprone.refaster.annotation.AfterTemplate;
|
||||
import com.google.errorprone.refaster.annotation.BeforeTemplate;
|
||||
@@ -81,6 +82,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@DoNotCall
|
||||
void after() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@@ -43,10 +43,10 @@ final class TimeTemplates {
|
||||
static final class UtcConstant {
|
||||
@BeforeTemplate
|
||||
ZoneId before() {
|
||||
// `ZoneId.of("Z")` is not listed, because Error Prone flags it out of the box.
|
||||
return Refaster.anyOf(
|
||||
ZoneId.of("GMT"),
|
||||
ZoneId.of("UTC"),
|
||||
ZoneId.of("Z"),
|
||||
ZoneId.of("+0"),
|
||||
ZoneId.of("-0"),
|
||||
ZoneOffset.UTC.normalized(),
|
||||
@@ -62,11 +62,13 @@ final class TimeTemplates {
|
||||
/** Use {@link Clock#systemUTC()} when possible. */
|
||||
static final class UtcClock {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings("TimeZoneUsage")
|
||||
Clock before() {
|
||||
return Clock.system(ZoneOffset.UTC);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@SuppressWarnings("TimeZoneUsage")
|
||||
Clock after() {
|
||||
return Clock.systemUTC();
|
||||
}
|
||||
@@ -96,8 +98,8 @@ final class TimeTemplates {
|
||||
return a.compareTo(b) < 0;
|
||||
}
|
||||
|
||||
@AlsoNegation
|
||||
@AfterTemplate
|
||||
@AlsoNegation
|
||||
boolean after(Instant a, Instant b) {
|
||||
return a.isBefore(b);
|
||||
}
|
||||
@@ -113,8 +115,8 @@ final class TimeTemplates {
|
||||
return a.compareTo(b) > 0;
|
||||
}
|
||||
|
||||
@AlsoNegation
|
||||
@AfterTemplate
|
||||
@AlsoNegation
|
||||
boolean after(Instant a, Instant b) {
|
||||
return a.isAfter(b);
|
||||
}
|
||||
@@ -162,8 +164,8 @@ final class TimeTemplates {
|
||||
return a.compareTo(b) < 0;
|
||||
}
|
||||
|
||||
@AlsoNegation
|
||||
@AfterTemplate
|
||||
@AlsoNegation
|
||||
boolean after(ChronoLocalDate a, ChronoLocalDate b) {
|
||||
return a.isBefore(b);
|
||||
}
|
||||
@@ -179,8 +181,8 @@ final class TimeTemplates {
|
||||
return a.compareTo(b) > 0;
|
||||
}
|
||||
|
||||
@AlsoNegation
|
||||
@AfterTemplate
|
||||
@AlsoNegation
|
||||
boolean after(ChronoLocalDate a, ChronoLocalDate b) {
|
||||
return a.isAfter(b);
|
||||
}
|
||||
@@ -196,8 +198,8 @@ final class TimeTemplates {
|
||||
return a.compareTo(b) < 0;
|
||||
}
|
||||
|
||||
@AlsoNegation
|
||||
@AfterTemplate
|
||||
@AlsoNegation
|
||||
boolean after(ChronoLocalDateTime<?> a, ChronoLocalDateTime<?> b) {
|
||||
return a.isBefore(b);
|
||||
}
|
||||
@@ -213,8 +215,8 @@ final class TimeTemplates {
|
||||
return a.compareTo(b) > 0;
|
||||
}
|
||||
|
||||
@AlsoNegation
|
||||
@AfterTemplate
|
||||
@AlsoNegation
|
||||
boolean after(ChronoLocalDateTime<?> a, ChronoLocalDateTime<?> b) {
|
||||
return a.isAfter(b);
|
||||
}
|
||||
@@ -230,8 +232,8 @@ final class TimeTemplates {
|
||||
return a.compareTo(b) < 0;
|
||||
}
|
||||
|
||||
@AlsoNegation
|
||||
@AfterTemplate
|
||||
@AlsoNegation
|
||||
boolean after(ChronoZonedDateTime<?> a, ChronoZonedDateTime<?> b) {
|
||||
return a.isBefore(b);
|
||||
}
|
||||
@@ -247,8 +249,8 @@ final class TimeTemplates {
|
||||
return a.compareTo(b) > 0;
|
||||
}
|
||||
|
||||
@AlsoNegation
|
||||
@AfterTemplate
|
||||
@AlsoNegation
|
||||
boolean after(ChronoZonedDateTime<?> a, ChronoZonedDateTime<?> b) {
|
||||
return a.isAfter(b);
|
||||
}
|
||||
@@ -264,8 +266,8 @@ final class TimeTemplates {
|
||||
return a.compareTo(b) < 0;
|
||||
}
|
||||
|
||||
@AlsoNegation
|
||||
@AfterTemplate
|
||||
@AlsoNegation
|
||||
boolean after(OffsetDateTime a, OffsetDateTime b) {
|
||||
return a.isBefore(b);
|
||||
}
|
||||
@@ -281,8 +283,8 @@ final class TimeTemplates {
|
||||
return a.compareTo(b) > 0;
|
||||
}
|
||||
|
||||
@AlsoNegation
|
||||
@AfterTemplate
|
||||
@AlsoNegation
|
||||
boolean after(OffsetDateTime a, OffsetDateTime b) {
|
||||
return a.isAfter(b);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
/** Picnic Refaster templates. */
|
||||
@CheckReturnValue
|
||||
@ParametersAreNonnullByDefault
|
||||
@com.google.errorprone.annotations.CheckReturnValue
|
||||
@javax.annotation.ParametersAreNonnullByDefault
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import com.google.errorprone.annotations.CheckReturnValue;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.common.base.Predicates.containsPattern;
|
||||
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
final class AmbiguousJsonCreatorCheckTest {
|
||||
private final CompilationTestHelper compilationTestHelper =
|
||||
CompilationTestHelper.newInstance(AmbiguousJsonCreatorCheck.class, getClass())
|
||||
.expectErrorMessage(
|
||||
"X",
|
||||
containsPattern("`JsonCreator.Mode` should be set for single-argument creators"));
|
||||
private final BugCheckerRefactoringTestHelper refactoringTestHelper =
|
||||
BugCheckerRefactoringTestHelper.newInstance(AmbiguousJsonCreatorCheck.class, getClass());
|
||||
|
||||
@Test
|
||||
void identification() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"Container.java",
|
||||
"import com.fasterxml.jackson.annotation.JsonCreator;",
|
||||
"import com.fasterxml.jackson.annotation.JsonValue;",
|
||||
"",
|
||||
"interface Container {",
|
||||
" enum A {",
|
||||
" FOO(1);",
|
||||
"",
|
||||
" private final int i;",
|
||||
"",
|
||||
" A(int i) {",
|
||||
" this.i = i;",
|
||||
" }",
|
||||
"",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" @JsonCreator",
|
||||
" public static A of(int i) {",
|
||||
" return FOO;",
|
||||
" }",
|
||||
" }",
|
||||
"",
|
||||
" enum B {",
|
||||
" FOO(1);",
|
||||
"",
|
||||
" private final int i;",
|
||||
"",
|
||||
" B(int i) {",
|
||||
" this.i = i;",
|
||||
" }",
|
||||
"",
|
||||
" @JsonCreator(mode = JsonCreator.Mode.DELEGATING)",
|
||||
" public static B of(int i) {",
|
||||
" return FOO;",
|
||||
" }",
|
||||
" }",
|
||||
"",
|
||||
" enum C {",
|
||||
" FOO(1, \"s\");",
|
||||
"",
|
||||
" @JsonValue private final int i;",
|
||||
" private final String s;",
|
||||
"",
|
||||
" C(int i, String s) {",
|
||||
" this.i = i;",
|
||||
" this.s = s;",
|
||||
" }",
|
||||
"",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" @JsonCreator",
|
||||
" public static C of(int i) {",
|
||||
" return FOO;",
|
||||
" }",
|
||||
" }",
|
||||
"",
|
||||
" enum D {",
|
||||
" FOO(1, \"s\");",
|
||||
"",
|
||||
" private final int i;",
|
||||
" private final String s;",
|
||||
"",
|
||||
" D(int i, String s) {",
|
||||
" this.i = i;",
|
||||
" this.s = s;",
|
||||
" }",
|
||||
"",
|
||||
" @JsonCreator",
|
||||
" public static D of(int i, String s) {",
|
||||
" return FOO;",
|
||||
" }",
|
||||
" }",
|
||||
"",
|
||||
" enum E {",
|
||||
" FOO;",
|
||||
"",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" @JsonCreator",
|
||||
" public static E of(String s) {",
|
||||
" return FOO;",
|
||||
" }",
|
||||
" }",
|
||||
"",
|
||||
" class F {",
|
||||
" private final String s;",
|
||||
"",
|
||||
" F(String s) {",
|
||||
" this.s = s;",
|
||||
" }",
|
||||
"",
|
||||
" @JsonCreator",
|
||||
" public static F of(String s) {",
|
||||
" return new F(s);",
|
||||
" }",
|
||||
" }",
|
||||
"",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
void replacement() {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/A.java",
|
||||
"import com.fasterxml.jackson.annotation.JsonCreator;",
|
||||
"",
|
||||
"enum A {",
|
||||
" FOO;",
|
||||
"",
|
||||
" @JsonCreator",
|
||||
" public static A of(String s) {",
|
||||
" return FOO;",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"out/A.java",
|
||||
"import com.fasterxml.jackson.annotation.JsonCreator;",
|
||||
"",
|
||||
"enum A {",
|
||||
" FOO;",
|
||||
"",
|
||||
" @JsonCreator(mode = JsonCreator.Mode.DELEGATING)",
|
||||
" public static A of(String s) {",
|
||||
" return FOO;",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(BugCheckerRefactoringTestHelper.TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
@@ -8,14 +8,14 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
public final class AnnotationAttributeMatcherTest {
|
||||
@Test
|
||||
public void testWithoutListings() {
|
||||
void withoutListings() {
|
||||
AnnotationAttributeMatcher matcher =
|
||||
AnnotationAttributeMatcher.create(Optional.empty(), ImmutableList.of());
|
||||
assertThat(matcher.matches("foo", "bar")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithSingleFullAnnotationWhitelist() {
|
||||
void withSingleFullAnnotationWhitelist() {
|
||||
AnnotationAttributeMatcher matcher =
|
||||
AnnotationAttributeMatcher.create(Optional.of(ImmutableList.of("foo")), ImmutableList.of());
|
||||
assertThat(matcher.matches("foo", "bar")).isTrue();
|
||||
@@ -24,7 +24,7 @@ public final class AnnotationAttributeMatcherTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithSingleAnnotationAttributeWhitelist() {
|
||||
void withSingleAnnotationAttributeWhitelist() {
|
||||
AnnotationAttributeMatcher matcher =
|
||||
AnnotationAttributeMatcher.create(
|
||||
Optional.of(ImmutableList.of("foo#bar")), ImmutableList.of());
|
||||
@@ -34,7 +34,7 @@ public final class AnnotationAttributeMatcherTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithSingleFullAnnotationBlacklist() {
|
||||
void withSingleFullAnnotationBlacklist() {
|
||||
AnnotationAttributeMatcher matcher =
|
||||
AnnotationAttributeMatcher.create(Optional.empty(), ImmutableList.of("foo"));
|
||||
assertThat(matcher.matches("foo", "bar")).isFalse();
|
||||
@@ -43,7 +43,7 @@ public final class AnnotationAttributeMatcherTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithSingleAnnotationAttributeBlacklist() {
|
||||
void withSingleAnnotationAttributeBlacklist() {
|
||||
AnnotationAttributeMatcher matcher =
|
||||
AnnotationAttributeMatcher.create(Optional.empty(), ImmutableList.of("foo#bar"));
|
||||
assertThat(matcher.matches("foo", "bar")).isFalse();
|
||||
@@ -52,7 +52,7 @@ public final class AnnotationAttributeMatcherTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithComplicatedConfiguration() {
|
||||
void withComplicatedConfiguration() {
|
||||
AnnotationAttributeMatcher matcher =
|
||||
AnnotationAttributeMatcher.create(
|
||||
Optional.of(ImmutableList.of("foo", "bar", "baz", "baz#1", "baz#2", "quux#1")),
|
||||
|
||||
@@ -9,10 +9,10 @@ public final class AutowiredConstructorCheckTest {
|
||||
private final CompilationTestHelper compilationTestHelper =
|
||||
CompilationTestHelper.newInstance(AutowiredConstructorCheck.class, getClass());
|
||||
private final BugCheckerRefactoringTestHelper refactoringTestHelper =
|
||||
BugCheckerRefactoringTestHelper.newInstance(new AutowiredConstructorCheck(), getClass());
|
||||
BugCheckerRefactoringTestHelper.newInstance(AutowiredConstructorCheck.class, getClass());
|
||||
|
||||
@Test
|
||||
public void testIdentification() {
|
||||
void identification() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"Container.java",
|
||||
@@ -62,7 +62,7 @@ public final class AutowiredConstructorCheckTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplacement() {
|
||||
void replacement() {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/Container.java",
|
||||
|
||||
@@ -9,10 +9,10 @@ public final class CanonicalAnnotationSyntaxCheckTest {
|
||||
private final CompilationTestHelper compilationTestHelper =
|
||||
CompilationTestHelper.newInstance(CanonicalAnnotationSyntaxCheck.class, getClass());
|
||||
private final BugCheckerRefactoringTestHelper refactoringTestHelper =
|
||||
BugCheckerRefactoringTestHelper.newInstance(new CanonicalAnnotationSyntaxCheck(), getClass());
|
||||
BugCheckerRefactoringTestHelper.newInstance(CanonicalAnnotationSyntaxCheck.class, getClass());
|
||||
|
||||
@Test
|
||||
public void testIdentification() {
|
||||
void identification() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"pkg/A.java",
|
||||
@@ -85,7 +85,7 @@ public final class CanonicalAnnotationSyntaxCheckTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplacement() {
|
||||
void replacement() {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/pkg/A.java",
|
||||
|
||||
@@ -9,10 +9,10 @@ public final class EmptyMethodCheckTest {
|
||||
private final CompilationTestHelper compilationTestHelper =
|
||||
CompilationTestHelper.newInstance(EmptyMethodCheck.class, getClass());
|
||||
private final BugCheckerRefactoringTestHelper refactoringTestHelper =
|
||||
BugCheckerRefactoringTestHelper.newInstance(new EmptyMethodCheck(), getClass());
|
||||
BugCheckerRefactoringTestHelper.newInstance(EmptyMethodCheck.class, getClass());
|
||||
|
||||
@Test
|
||||
public void testIdentification() {
|
||||
void identification() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
@@ -64,7 +64,7 @@ public final class EmptyMethodCheckTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplacement() {
|
||||
void replacement() {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/A.java",
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
final class ExplicitEnumOrderingCheckTest {
|
||||
private final CompilationTestHelper compilationTestHelper =
|
||||
CompilationTestHelper.newInstance(ExplicitEnumOrderingCheck.class, getClass());
|
||||
|
||||
@Test
|
||||
void Identification() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"import static java.lang.annotation.RetentionPolicy.SOURCE;",
|
||||
"import static java.lang.annotation.RetentionPolicy.CLASS;",
|
||||
"import static java.lang.annotation.RetentionPolicy.RUNTIME;",
|
||||
"import static java.time.chrono.IsoEra.BCE;",
|
||||
"import static java.time.chrono.IsoEra.CE;",
|
||||
"",
|
||||
"import com.google.common.collect.Ordering;",
|
||||
"import com.google.common.collect.ImmutableList;",
|
||||
"import java.lang.annotation.RetentionPolicy;",
|
||||
"import java.time.chrono.IsoEra;",
|
||||
"",
|
||||
"class A {",
|
||||
" {",
|
||||
" // The `List`-accepting overload is currently ignored.",
|
||||
" Ordering.explicit(ImmutableList.of(RetentionPolicy.SOURCE, RetentionPolicy.CLASS));",
|
||||
"",
|
||||
" Ordering.explicit(IsoEra.BCE, IsoEra.CE);",
|
||||
" // BUG: Diagnostic contains: IsoEra.CE",
|
||||
" Ordering.explicit(IsoEra.BCE);",
|
||||
" // BUG: Diagnostic contains: IsoEra.BCE",
|
||||
" Ordering.explicit(IsoEra.CE);",
|
||||
"",
|
||||
" Ordering.explicit(RetentionPolicy.SOURCE, RetentionPolicy.CLASS, RetentionPolicy.RUNTIME);",
|
||||
" // BUG: Diagnostic contains: RetentionPolicy.CLASS, RetentionPolicy.RUNTIME",
|
||||
" Ordering.explicit(RetentionPolicy.SOURCE);",
|
||||
" // BUG: Diagnostic contains: RetentionPolicy.SOURCE, RetentionPolicy.RUNTIME",
|
||||
" Ordering.explicit(RetentionPolicy.CLASS);",
|
||||
" // BUG: Diagnostic contains: RetentionPolicy.SOURCE, RetentionPolicy.CLASS",
|
||||
" Ordering.explicit(RetentionPolicy.RUNTIME);",
|
||||
" // BUG: Diagnostic contains: RetentionPolicy.RUNTIME",
|
||||
" Ordering.explicit(RetentionPolicy.SOURCE, RetentionPolicy.CLASS);",
|
||||
" // BUG: Diagnostic contains: RetentionPolicy.CLASS",
|
||||
" Ordering.explicit(RetentionPolicy.SOURCE, RetentionPolicy.RUNTIME);",
|
||||
" // BUG: Diagnostic contains: RetentionPolicy.SOURCE",
|
||||
" Ordering.explicit(RetentionPolicy.CLASS, RetentionPolicy.RUNTIME);",
|
||||
"",
|
||||
" Ordering.explicit(BCE, CE);",
|
||||
" // BUG: Diagnostic contains: IsoEra.CE",
|
||||
" Ordering.explicit(BCE);",
|
||||
" // BUG: Diagnostic contains: IsoEra.BCE",
|
||||
" Ordering.explicit(CE);",
|
||||
"",
|
||||
" Ordering.explicit(SOURCE, CLASS, RUNTIME);",
|
||||
" // BUG: Diagnostic contains: RetentionPolicy.CLASS, RetentionPolicy.RUNTIME",
|
||||
" Ordering.explicit(SOURCE);",
|
||||
" // BUG: Diagnostic contains: RetentionPolicy.SOURCE, RetentionPolicy.RUNTIME",
|
||||
" Ordering.explicit(CLASS);",
|
||||
" // BUG: Diagnostic contains: RetentionPolicy.SOURCE, RetentionPolicy.CLASS",
|
||||
" Ordering.explicit(RUNTIME);",
|
||||
" // BUG: Diagnostic contains: RetentionPolicy.RUNTIME",
|
||||
" Ordering.explicit(SOURCE, CLASS);",
|
||||
" // BUG: Diagnostic contains: RetentionPolicy.CLASS",
|
||||
" Ordering.explicit(SOURCE, RUNTIME);",
|
||||
" // BUG: Diagnostic contains: RetentionPolicy.SOURCE",
|
||||
" Ordering.explicit(CLASS, RUNTIME);",
|
||||
"",
|
||||
" Ordering.explicit(RetentionPolicy.SOURCE, BCE, RetentionPolicy.CLASS, CE, RUNTIME);",
|
||||
" Ordering.explicit(SOURCE, IsoEra.BCE, CLASS, IsoEra.CE, RetentionPolicy.RUNTIME);",
|
||||
" // BUG: Diagnostic contains: RetentionPolicy.CLASS",
|
||||
" Ordering.explicit(RetentionPolicy.SOURCE, BCE, CE, RUNTIME);",
|
||||
" // BUG: Diagnostic contains: RetentionPolicy.CLASS",
|
||||
" Ordering.explicit(IsoEra.BCE, SOURCE, IsoEra.CE, RetentionPolicy.RUNTIME);",
|
||||
" // BUG: Diagnostic contains: IsoEra.CE, RetentionPolicy.RUNTIME",
|
||||
" Ordering.explicit(IsoEra.BCE, SOURCE, RetentionPolicy.CLASS);",
|
||||
" // BUG: Diagnostic contains: RetentionPolicy.SOURCE, IsoEra.BCE",
|
||||
" Ordering.explicit(CLASS, RUNTIME, CE);",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
}
|
||||
@@ -9,10 +9,10 @@ public final class JUnitMethodDeclarationCheckTest {
|
||||
private final CompilationTestHelper compilationTestHelper =
|
||||
CompilationTestHelper.newInstance(JUnitMethodDeclarationCheck.class, getClass());
|
||||
private final BugCheckerRefactoringTestHelper refactoringTestHelper =
|
||||
BugCheckerRefactoringTestHelper.newInstance(new JUnitMethodDeclarationCheck(), getClass());
|
||||
BugCheckerRefactoringTestHelper.newInstance(JUnitMethodDeclarationCheck.class, getClass());
|
||||
|
||||
@Test
|
||||
public void testIdentification() {
|
||||
void identification() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
@@ -91,7 +91,7 @@ public final class JUnitMethodDeclarationCheckTest {
|
||||
"import org.junit.jupiter.api.Test;",
|
||||
"import org.junit.jupiter.params.ParameterizedTest;",
|
||||
"",
|
||||
"final class B extends A {",
|
||||
"class B extends A {",
|
||||
" @Override @BeforeAll void setUp1() {}",
|
||||
" @Override @BeforeAll public void setUp2() {}",
|
||||
" @Override @BeforeAll protected void setUp3() {}",
|
||||
@@ -127,7 +127,7 @@ public final class JUnitMethodDeclarationCheckTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplacement() {
|
||||
void replacement() {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/A.java",
|
||||
|
||||
@@ -19,10 +19,10 @@ public final class LexicographicalAnnotationAttributeListingCheckTest {
|
||||
"-XepOpt:LexicographicalAnnotationAttributeListing:Excludes=pkg.A.Bar#value"));
|
||||
private final BugCheckerRefactoringTestHelper refactoringTestHelper =
|
||||
BugCheckerRefactoringTestHelper.newInstance(
|
||||
new LexicographicalAnnotationAttributeListingCheck(), getClass());
|
||||
LexicographicalAnnotationAttributeListingCheck.class, getClass());
|
||||
|
||||
@Test
|
||||
public void testIdentification() {
|
||||
void identification() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
@@ -105,7 +105,7 @@ public final class LexicographicalAnnotationAttributeListingCheckTest {
|
||||
// introduced. Avoiding that might make the code too complex. Instead, users can have the
|
||||
// `CanonicalAnnotationSyntaxCheck` correct the situation in a subsequent run.
|
||||
@Test
|
||||
public void testReplacement() {
|
||||
void replacement() {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/A.java",
|
||||
@@ -161,7 +161,7 @@ public final class LexicographicalAnnotationAttributeListingCheckTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFiltering() {
|
||||
void filtering() {
|
||||
/* Some violations are not flagged because they are not in- or excluded. */
|
||||
restrictedCompilationTestHelper
|
||||
.addSourceLines(
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.common.base.Predicates.containsPattern;
|
||||
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public final class LexicographicalAnnotationListingCheckTest {
|
||||
private final CompilationTestHelper compilationTestHelper =
|
||||
CompilationTestHelper.newInstance(LexicographicalAnnotationListingCheck.class, getClass())
|
||||
.expectErrorMessage(
|
||||
"X", containsPattern("Sort annotations lexicographically where possible"));
|
||||
private final BugCheckerRefactoringTestHelper refactoringTestHelper =
|
||||
BugCheckerRefactoringTestHelper.newInstance(
|
||||
LexicographicalAnnotationListingCheck.class, getClass());
|
||||
|
||||
@Test
|
||||
void identification() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"import java.lang.annotation.Repeatable;",
|
||||
"",
|
||||
"interface A {",
|
||||
" @Repeatable(Foos.class)",
|
||||
" @interface Foo {",
|
||||
" String[] value() default {};",
|
||||
" int[] ints() default {};",
|
||||
" Bar[] anns() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @interface Bar {",
|
||||
" String[] value() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @interface Baz {",
|
||||
" String[] str() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @interface Foos {",
|
||||
" Foo[] value();",
|
||||
" }",
|
||||
"",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" @Foo @Bar A unsortedSimpleCase();",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" @Foo() @Bar() A unsortedWithParens();",
|
||||
" @Foo() A onlyOneAnnotation();",
|
||||
" @Bar @Foo() A sortedAnnotationsOneWithParens();",
|
||||
"",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" @Foo @Baz @Bar A threeUnsortedAnnotationsSameInitialLetter();",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" @Bar @Foo() @Baz A firstOrderedWithTwoUnsortedAnnotations();",
|
||||
" @Bar @Baz @Foo() A threeSortedAnnotations();",
|
||||
"",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" @Foo({\"b\"}) @Bar({\"a\"}) A unsortedWithStringAttributes();",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" @Baz(str = {\"a\", \"b\"}) @Foo(ints = {1, 0}) @Bar A unsortedWithAttributes();",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" @Bar @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")}) @Baz A unsortedWithNestedBar();",
|
||||
" @Bar @Baz @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")}) A sortedWithNestedBar();",
|
||||
"",
|
||||
" @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")}) @Foo(ints = {1, 2}) @Foo({\"b\"}) A sortedRepeatableAnnotation();",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")}) @Bar @Foo(ints = {1, 2}) A unsortedRepeatableAnnotation();",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
void replacement() {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/A.java",
|
||||
"import java.lang.annotation.Repeatable;",
|
||||
"interface A {",
|
||||
" @Repeatable(Foos.class)",
|
||||
" @interface Foo {",
|
||||
" String[] value() default {};",
|
||||
" int[] ints() default {};",
|
||||
" Bar[] anns() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @interface Bar {",
|
||||
" String[] value() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @interface Baz {",
|
||||
" String[] str() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @interface Foos {",
|
||||
" Foo[] value();",
|
||||
" }",
|
||||
"",
|
||||
" @Bar A singleAnnotation();",
|
||||
" @Bar @Foo A sortedAnnotations();",
|
||||
" @Foo @Bar A unsortedAnnotations();",
|
||||
" @Foo() @Baz() @Bar A unsortedAnnotationsWithSomeParens();",
|
||||
"",
|
||||
" @Bar @Baz(str = {\"a\", \"b\"}) @Foo() A unsortedAnnotationsOneContainingAttributes();",
|
||||
" @Baz(str = {\"a\", \"b\"}) @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")}) @Bar({\"b\"}) A unsortedAnnotationsWithAttributes();",
|
||||
"",
|
||||
" @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")}) @Foo(ints = {1, 2}) @Foo({\"b\"}) A sortedRepeatableAnnotation();",
|
||||
" @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")}) @Bar @Foo(ints = {1, 2}) A unsortedRepeatableAnnotation();",
|
||||
"",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"out/A.java",
|
||||
"import java.lang.annotation.Repeatable;",
|
||||
"interface A {",
|
||||
" @Repeatable(Foos.class)",
|
||||
" @interface Foo {",
|
||||
" String[] value() default {};",
|
||||
" int[] ints() default {};",
|
||||
" Bar[] anns() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @interface Bar {",
|
||||
" String[] value() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @interface Baz {",
|
||||
" String[] str() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @interface Foos {",
|
||||
" Foo[] value();",
|
||||
" }",
|
||||
" @Bar A singleAnnotation();",
|
||||
" @Bar @Foo A sortedAnnotations();",
|
||||
" @Bar @Foo A unsortedAnnotations();",
|
||||
" @Bar @Baz() @Foo() A unsortedAnnotationsWithSomeParens();",
|
||||
"",
|
||||
" @Bar @Baz(str = {\"a\", \"b\"}) @Foo() A unsortedAnnotationsOneContainingAttributes();",
|
||||
" @Bar({\"b\"}) @Baz(str = {\"a\", \"b\"}) @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")}) A unsortedAnnotationsWithAttributes();",
|
||||
"",
|
||||
" @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")}) @Foo(ints = {1, 2}) @Foo({\"b\"}) A sortedRepeatableAnnotation();",
|
||||
" @Bar @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")}) @Foo(ints = {1, 2}) A unsortedRepeatableAnnotation();",
|
||||
"",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
@@ -47,7 +47,7 @@ public final class MethodMatcherFactoryTest {
|
||||
CompilationTestHelper.newInstance(MatchedMethodsFlagger.class, getClass());
|
||||
|
||||
@Test
|
||||
public void testCreateWithMalformedSignatures() {
|
||||
void createWithMalformedSignatures() {
|
||||
MethodMatcherFactory factory = new MethodMatcherFactory();
|
||||
assertThatThrownBy(() -> factory.create(ImmutableList.of("foo.bar")))
|
||||
.isInstanceOf(IllegalArgumentException.class);
|
||||
@@ -60,7 +60,7 @@ public final class MethodMatcherFactoryTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatcher() {
|
||||
void matcher() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"com/example/A.java",
|
||||
|
||||
@@ -9,10 +9,10 @@ public final class MethodReferenceUsageCheckTest {
|
||||
private final CompilationTestHelper compilationTestHelper =
|
||||
CompilationTestHelper.newInstance(MethodReferenceUsageCheck.class, getClass());
|
||||
private final BugCheckerRefactoringTestHelper refactoringTestHelper =
|
||||
BugCheckerRefactoringTestHelper.newInstance(new MethodReferenceUsageCheck(), getClass());
|
||||
BugCheckerRefactoringTestHelper.newInstance(MethodReferenceUsageCheck.class, getClass());
|
||||
|
||||
@Test
|
||||
public void testIdentification() {
|
||||
void identification() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
@@ -201,7 +201,7 @@ public final class MethodReferenceUsageCheckTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplacement() {
|
||||
void replacement() {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/A.java",
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.common.base.Predicates.containsPattern;
|
||||
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public final class MissingRefasterAnnotationCheckTest {
|
||||
private final CompilationTestHelper compilationTestHelper =
|
||||
CompilationTestHelper.newInstance(MissingRefasterAnnotationCheck.class, getClass())
|
||||
.expectErrorMessage(
|
||||
"X",
|
||||
containsPattern(
|
||||
"The Refaster template contains a method without any Refaster annotations"));
|
||||
|
||||
@Test
|
||||
void identification() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"import com.google.errorprone.refaster.annotation.AfterTemplate;",
|
||||
"import com.google.errorprone.refaster.annotation.AlsoNegation;",
|
||||
"import com.google.errorprone.refaster.annotation.BeforeTemplate;",
|
||||
"import java.util.Map;",
|
||||
"",
|
||||
"class A {",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" static final class MethodLacksBeforeTemplateAnnotation {",
|
||||
" @BeforeTemplate",
|
||||
" boolean before1(String string) {",
|
||||
" return string.equals(\"\");",
|
||||
" }",
|
||||
"",
|
||||
" // @BeforeTemplate is missing",
|
||||
" boolean before2(String string) {",
|
||||
" return string.length() == 0;",
|
||||
" }",
|
||||
"",
|
||||
" @AfterTemplate",
|
||||
" @AlsoNegation",
|
||||
" boolean after(String string) {",
|
||||
" return string.isEmpty();",
|
||||
" }",
|
||||
" }",
|
||||
"",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" static final class MethodLacksAfterTemplateAnnotation {",
|
||||
" @BeforeTemplate",
|
||||
" boolean before(String string) {",
|
||||
" return string.equals(\"\");",
|
||||
" }",
|
||||
"",
|
||||
" // @AfterTemplate is missing",
|
||||
" boolean after(String string) {",
|
||||
" return string.isEmpty();",
|
||||
" }",
|
||||
" }",
|
||||
"",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" abstract class MethodLacksPlaceholderAnnotation<K, V> {",
|
||||
" // @Placeholder is missing",
|
||||
" abstract V function(K key);",
|
||||
"",
|
||||
" @BeforeTemplate",
|
||||
" void before(Map<K, V> map, K key) {",
|
||||
" if (!map.containsKey(key)) {",
|
||||
" map.put(key, function(key));",
|
||||
" }",
|
||||
" }",
|
||||
"",
|
||||
" @AfterTemplate",
|
||||
" void after(Map<K, V> map, K key) {",
|
||||
" map.computeIfAbsent(key, k -> function(k));",
|
||||
" }",
|
||||
" }",
|
||||
"",
|
||||
" static final class ValidRefasterTemplate {",
|
||||
" @BeforeTemplate",
|
||||
" void unusedPureFunctionCall(Object o) {",
|
||||
" o.toString();",
|
||||
" }",
|
||||
" }",
|
||||
"",
|
||||
" static final class NotARefasterTemplate {",
|
||||
" @Override",
|
||||
" public String toString() {",
|
||||
" return \"This is not a Refaster template\";",
|
||||
" }",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ public final class PrimitiveComparisonCheckTest {
|
||||
private final CompilationTestHelper compilationTestHelper =
|
||||
CompilationTestHelper.newInstance(PrimitiveComparisonCheck.class, getClass());
|
||||
private final BugCheckerRefactoringTestHelper refactoringTestHelper =
|
||||
BugCheckerRefactoringTestHelper.newInstance(new PrimitiveComparisonCheck(), getClass());
|
||||
BugCheckerRefactoringTestHelper.newInstance(PrimitiveComparisonCheck.class, getClass());
|
||||
|
||||
// XXX: There are no tests for multiple replacements within the same expression:
|
||||
// - Error Prone doesn't currently support this, it seems.
|
||||
@@ -19,7 +19,7 @@ public final class PrimitiveComparisonCheckTest {
|
||||
|
||||
// The logic for `char` and `short` is exactly analogous to the `byte` case.
|
||||
@Test
|
||||
public void testByteComparison() {
|
||||
void byteComparison() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
@@ -108,7 +108,7 @@ public final class PrimitiveComparisonCheckTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntComparison() {
|
||||
void intComparison() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
@@ -201,7 +201,7 @@ public final class PrimitiveComparisonCheckTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLongComparison() {
|
||||
void longComparison() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
@@ -278,7 +278,7 @@ public final class PrimitiveComparisonCheckTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFloatComparison() {
|
||||
void floatComparison() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
@@ -335,7 +335,7 @@ public final class PrimitiveComparisonCheckTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoubleComparison() {
|
||||
void doubleComparison() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
@@ -396,7 +396,7 @@ public final class PrimitiveComparisonCheckTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringComparison() {
|
||||
void stringComparison() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
@@ -429,7 +429,7 @@ public final class PrimitiveComparisonCheckTest {
|
||||
// XXX: If the explicit `<A, BoxedPrimitive>` generic type information was necessary, then this
|
||||
// replacement drops too much information.
|
||||
@Test
|
||||
public void testReplacementWithPrimitiveVariants() {
|
||||
void replacementWithPrimitiveVariants() {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/A.java",
|
||||
@@ -483,7 +483,7 @@ public final class PrimitiveComparisonCheckTest {
|
||||
// XXX: If the explicit `<A>` generic type information was necessary, then this replacement drops
|
||||
// too much information.
|
||||
@Test
|
||||
public void testReplacementWithBoxedVariants() {
|
||||
void replacementWithBoxedVariants() {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/A.java",
|
||||
@@ -535,7 +535,7 @@ public final class PrimitiveComparisonCheckTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplacementWithPrimitiveVariantsUsingStaticImports() {
|
||||
void replacementWithPrimitiveVariantsUsingStaticImports() {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/A.java",
|
||||
@@ -574,7 +574,7 @@ public final class PrimitiveComparisonCheckTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplacementWithBoxedVariantsUsingStaticImports() {
|
||||
void replacementWithBoxedVariantsUsingStaticImports() {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/A.java",
|
||||
@@ -615,7 +615,7 @@ public final class PrimitiveComparisonCheckTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplacementWithPrimitiveVariantsInComplexSyntacticalContext() {
|
||||
void replacementWithPrimitiveVariantsInComplexSyntacticalContext() {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/A.java",
|
||||
@@ -647,7 +647,7 @@ public final class PrimitiveComparisonCheckTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplacementWithBoxedVariantsInComplexSyntacticalContext() {
|
||||
void replacementWithBoxedVariantsInComplexSyntacticalContext() {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/A.java",
|
||||
|
||||
@@ -18,10 +18,10 @@ public final class RedundantStringConversionCheckTest {
|
||||
ImmutableList.of(
|
||||
"-XepOpt:RedundantStringConversion:ExtraConversionMethods=java.lang.Enum#name(),A#name(),A.B#toString(int)"));
|
||||
private final BugCheckerRefactoringTestHelper refactoringTestHelper =
|
||||
BugCheckerRefactoringTestHelper.newInstance(new RedundantStringConversionCheck(), getClass());
|
||||
BugCheckerRefactoringTestHelper.newInstance(RedundantStringConversionCheck.class, getClass());
|
||||
|
||||
@Test
|
||||
public void testIdentificationOfIdentityTransformation() {
|
||||
void identificationOfIdentityTransformation() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
@@ -44,7 +44,7 @@ public final class RedundantStringConversionCheckTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIdentificationWithinMutatingAssignment() {
|
||||
void identificationWithinMutatingAssignment() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
@@ -100,7 +100,7 @@ public final class RedundantStringConversionCheckTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIdentificationWithinBinaryOperation() {
|
||||
void identificationWithinBinaryOperation() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
@@ -186,7 +186,7 @@ public final class RedundantStringConversionCheckTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIdentificationWithinStringBuilderMethod() {
|
||||
void identificationWithinStringBuilderMethod() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
@@ -235,7 +235,7 @@ public final class RedundantStringConversionCheckTest {
|
||||
|
||||
// XXX: Also test the other formatter methods.
|
||||
@Test
|
||||
public void testIdentificationWithinFormatterMethod() {
|
||||
void identificationWithinFormatterMethod() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
@@ -280,7 +280,7 @@ public final class RedundantStringConversionCheckTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIdentificationWithinGuavaGuardMethod() {
|
||||
void identificationWithinGuavaGuardMethod() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
@@ -340,7 +340,7 @@ public final class RedundantStringConversionCheckTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIdentificationWithinSlf4jLoggerMethod() {
|
||||
void identificationWithinSlf4jLoggerMethod() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
@@ -395,7 +395,7 @@ public final class RedundantStringConversionCheckTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIdentificationOfCustomConversionMethod() {
|
||||
void identificationOfCustomConversionMethod() {
|
||||
customizedCompilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
@@ -486,7 +486,7 @@ public final class RedundantStringConversionCheckTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplacement() {
|
||||
void replacement() {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/A.java",
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public final class RefasterAnyOfUsageCheckTest {
|
||||
private final CompilationTestHelper compilationTestHelper =
|
||||
CompilationTestHelper.newInstance(RefasterAnyOfUsageCheck.class, getClass());
|
||||
private final BugCheckerRefactoringTestHelper refactoringTestHelper =
|
||||
BugCheckerRefactoringTestHelper.newInstance(RefasterAnyOfUsageCheck.class, getClass());
|
||||
|
||||
@Test
|
||||
void identification() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"import com.google.errorprone.refaster.Refaster;",
|
||||
"import com.google.errorprone.refaster.annotation.BeforeTemplate;",
|
||||
"",
|
||||
"class A {",
|
||||
" @BeforeTemplate",
|
||||
" String before(String str) {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Refaster.anyOf();",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" return Refaster.anyOf(str);",
|
||||
" }",
|
||||
"",
|
||||
" @BeforeTemplate",
|
||||
" Object before2(String str, Object obj) {",
|
||||
" return Refaster.anyOf(str, obj);",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
void replacement() {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/A.java",
|
||||
"import com.google.errorprone.refaster.Refaster;",
|
||||
"import com.google.errorprone.refaster.annotation.BeforeTemplate;",
|
||||
"",
|
||||
"class A {",
|
||||
" @BeforeTemplate",
|
||||
" String before(String str) {",
|
||||
" Refaster.anyOf();",
|
||||
" return Refaster.anyOf(str);",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"out/A.java",
|
||||
"import com.google.errorprone.refaster.Refaster;",
|
||||
"import com.google.errorprone.refaster.annotation.BeforeTemplate;",
|
||||
"",
|
||||
"class A {",
|
||||
" @BeforeTemplate",
|
||||
" String before(String str) {",
|
||||
" Refaster.anyOf();",
|
||||
" return str;",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
@@ -5,15 +5,12 @@ import static java.util.function.Function.identity;
|
||||
import static java.util.function.Predicate.not;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatCode;
|
||||
import static org.junit.jupiter.params.provider.Arguments.arguments;
|
||||
|
||||
import com.google.common.collect.ImmutableListMultimap;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSetMultimap;
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;
|
||||
import com.google.errorprone.CodeTransformer;
|
||||
import com.google.errorprone.ErrorProneFlags;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -77,9 +74,6 @@ public final class RefasterCheckTest {
|
||||
*/
|
||||
private static final Pattern TEMPLATE_FQCN_TRIM_FOR_GROUP_NAME =
|
||||
Pattern.compile(".*\\.|Templates\\$.*");
|
||||
/** All Refaster templates on the classpath, indexed by their name. */
|
||||
private static final ImmutableListMultimap<String, CodeTransformer> ALL_CODE_TRANSFORMERS =
|
||||
RefasterCheck.loadAllCodeTransformers();
|
||||
/**
|
||||
* A mapping from template group names to associated template names.
|
||||
*
|
||||
@@ -87,7 +81,7 @@ public final class RefasterCheckTest {
|
||||
* templates, while the keys correspond to the associated top-level "aggregator" classes.
|
||||
*/
|
||||
private static final ImmutableSetMultimap<String, String> TEMPLATES_BY_GROUP =
|
||||
indexTemplateNamesByGroup(ALL_CODE_TRANSFORMERS.keySet());
|
||||
indexTemplateNamesByGroup(RefasterCheck.ALL_CODE_TRANSFORMERS.get().keySet());
|
||||
|
||||
/** Returns every known template group name as a parameterized test argument. */
|
||||
@SuppressWarnings("UnusedMethod" /* Used as a `@MethodSource`. */)
|
||||
@@ -104,7 +98,7 @@ public final class RefasterCheckTest {
|
||||
// XXX: Drop the filter once we have added tests for AssertJ!
|
||||
return TEMPLATES_BY_GROUP.entries().stream()
|
||||
.filter(e -> !"AssertJ".equals(e.getKey()))
|
||||
.map(e -> Arguments.of(e.getKey(), e.getValue()));
|
||||
.map(e -> arguments(e.getKey(), e.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -112,10 +106,10 @@ public final class RefasterCheckTest {
|
||||
* for all of the {@link #TEMPLATE_GROUPS}.
|
||||
*
|
||||
* <p>This test is just as much about ensuring that {@link #TEMPLATE_GROUPS} is exhaustive, so
|
||||
* that in turn {@link #testReplacement}'s coverage is exhaustive.
|
||||
* that in turn {@link #replacement}'s coverage is exhaustive.
|
||||
*/
|
||||
@Test
|
||||
public void testLoadAllCodeTransformers() {
|
||||
void loadAllCodeTransformers() {
|
||||
assertThat(TEMPLATES_BY_GROUP.keySet()).hasSameElementsAs(TEMPLATE_GROUPS);
|
||||
}
|
||||
|
||||
@@ -123,9 +117,9 @@ public final class RefasterCheckTest {
|
||||
* Verifies for each of the {@link #TEMPLATE_GROUPS} that the associated code transformers have
|
||||
* the desired effect.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("templateGroupsUnderTest")
|
||||
public void testReplacement(String group) {
|
||||
@ParameterizedTest
|
||||
void replacement(String group) {
|
||||
verifyRefactoring(group, namePattern(group));
|
||||
}
|
||||
|
||||
@@ -136,9 +130,9 @@ public final class RefasterCheckTest {
|
||||
* com.google.errorprone.refaster.Refaster#anyOf} branches are tested. Idem for {@link
|
||||
* com.google.errorprone.refaster.annotation.BeforeTemplate} methods in case there are multiple .
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("templatesUnderTest")
|
||||
public void testCoverage(String group, String template) {
|
||||
@ParameterizedTest
|
||||
void coverage(String group, String template) {
|
||||
assertThatCode(() -> verifyRefactoring(group, namePattern(group, template)))
|
||||
.withFailMessage(
|
||||
"Template %s does not affect the tests for group %s; is it tested?", template, group)
|
||||
@@ -171,10 +165,7 @@ public final class RefasterCheckTest {
|
||||
|
||||
private BugCheckerRefactoringTestHelper createRestrictedRefactoringTestHelper(
|
||||
String namePattern) {
|
||||
return BugCheckerRefactoringTestHelper.newInstance(
|
||||
new RefasterCheck(
|
||||
ErrorProneFlags.fromMap(ImmutableMap.of("Refaster:NamePattern", namePattern)),
|
||||
ALL_CODE_TRANSFORMERS),
|
||||
getClass());
|
||||
return BugCheckerRefactoringTestHelper.newInstance(RefasterCheck.class, getClass())
|
||||
.setArgs("-XepOpt:Refaster:NamePattern=" + namePattern);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public final class RequestMappingAnnotationCheckTest {
|
||||
private final CompilationTestHelper compilationTestHelper =
|
||||
CompilationTestHelper.newInstance(RequestMappingAnnotationCheck.class, getClass());
|
||||
|
||||
@Test
|
||||
void identification() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"import java.io.InputStream;",
|
||||
"import javax.servlet.http.HttpServletRequest;",
|
||||
"import javax.servlet.http.HttpServletResponse;",
|
||||
"import org.springframework.http.HttpMethod;",
|
||||
"import org.springframework.web.bind.annotation.DeleteMapping;",
|
||||
"import org.springframework.web.bind.annotation.GetMapping;",
|
||||
"import org.springframework.web.bind.annotation.PatchMapping;",
|
||||
"import org.springframework.web.bind.annotation.PathVariable;",
|
||||
"import org.springframework.web.bind.annotation.PostMapping;",
|
||||
"import org.springframework.web.bind.annotation.PutMapping;",
|
||||
"import org.springframework.web.bind.annotation.RequestBody;",
|
||||
"import org.springframework.web.bind.annotation.RequestHeader;",
|
||||
"import org.springframework.web.bind.annotation.RequestMapping;",
|
||||
"import org.springframework.web.bind.annotation.RequestMethod;",
|
||||
"import org.springframework.web.bind.annotation.RequestParam;",
|
||||
"import org.springframework.web.context.request.WebRequest;",
|
||||
"",
|
||||
"interface A {",
|
||||
" A noMapping();",
|
||||
" A noMapping(String param);",
|
||||
" @DeleteMapping A properNoParameters();",
|
||||
" @GetMapping A properPathVariable(@PathVariable String param);",
|
||||
" @PatchMapping A properRequestBody(@RequestBody String body);",
|
||||
" @PostMapping A properRequestHeader(@RequestHeader String header);",
|
||||
" @PutMapping A properRequestParam(@RequestParam String param);",
|
||||
" @RequestMapping A properInputStream(InputStream input);",
|
||||
" @RequestMapping A properHttpServletRequest(HttpServletRequest request);",
|
||||
" @RequestMapping A properHttpServletResponse(HttpServletResponse response);",
|
||||
" @RequestMapping A properHttpMethod(HttpMethod method);",
|
||||
" @RequestMapping A properWebRequest(WebRequest request);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @DeleteMapping A delete(String param);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @GetMapping A get(String param);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @PatchMapping A patch(String param);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @PostMapping A post(String param);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @PutMapping A put(String param);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @RequestMapping A requestMultiple(String param, String param2);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @RequestMapping A requestFirstParamViolation(String param, @PathVariable String param2);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @RequestMapping A requestSecondParamViolation(@RequestBody String param, String param2);",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
}
|
||||
@@ -9,10 +9,10 @@ public final class Slf4jLogStatementCheckTest {
|
||||
private final CompilationTestHelper compilationTestHelper =
|
||||
CompilationTestHelper.newInstance(Slf4jLogStatementCheck.class, getClass());
|
||||
private final BugCheckerRefactoringTestHelper refactoringTestHelper =
|
||||
BugCheckerRefactoringTestHelper.newInstance(new Slf4jLogStatementCheck(), getClass());
|
||||
BugCheckerRefactoringTestHelper.newInstance(Slf4jLogStatementCheck.class, getClass());
|
||||
|
||||
@Test
|
||||
public void testIdentification() {
|
||||
void identification() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
@@ -92,7 +92,7 @@ public final class Slf4jLogStatementCheckTest {
|
||||
|
||||
// XXX: Drop what's unused.
|
||||
@Test
|
||||
public void testReplacement() {
|
||||
void replacement() {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/A.java",
|
||||
|
||||
@@ -9,10 +9,10 @@ public final class SpringMvcAnnotationCheckTest {
|
||||
private final CompilationTestHelper compilationTestHelper =
|
||||
CompilationTestHelper.newInstance(SpringMvcAnnotationCheck.class, getClass());
|
||||
private final BugCheckerRefactoringTestHelper refactoringTestHelper =
|
||||
BugCheckerRefactoringTestHelper.newInstance(new SpringMvcAnnotationCheck(), getClass());
|
||||
BugCheckerRefactoringTestHelper.newInstance(SpringMvcAnnotationCheck.class, getClass());
|
||||
|
||||
@Test
|
||||
public void testIdentification() {
|
||||
void identification() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
@@ -59,7 +59,7 @@ public final class SpringMvcAnnotationCheckTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplacement() {
|
||||
void replacement() {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/A.java",
|
||||
|
||||
@@ -10,16 +10,16 @@ public final class StaticImportCheckTest {
|
||||
private final CompilationTestHelper compilationTestHelper =
|
||||
CompilationTestHelper.newInstance(StaticImportCheck.class, getClass());
|
||||
private final BugCheckerRefactoringTestHelper refactoringTestHelper =
|
||||
BugCheckerRefactoringTestHelper.newInstance(new StaticImportCheck(), getClass());
|
||||
BugCheckerRefactoringTestHelper.newInstance(StaticImportCheck.class, getClass());
|
||||
|
||||
@Test
|
||||
public void testCandidateMethodsAreNotRedundant() {
|
||||
void candidateMethodsAreNotRedundant() {
|
||||
assertThat(StaticImportCheck.STATIC_IMPORT_CANDIDATE_METHODS.keySet())
|
||||
.doesNotContainAnyElementsOf(StaticImportCheck.STATIC_IMPORT_CANDIDATE_CLASSES);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIdentification() {
|
||||
void identification() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
@@ -77,7 +77,7 @@ public final class StaticImportCheckTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplacement() {
|
||||
void replacement() {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/A.java",
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.common.base.Predicates.containsPattern;
|
||||
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public final class TimeZoneUsageCheckTest {
|
||||
private final CompilationTestHelper compilationHelper =
|
||||
CompilationTestHelper.newInstance(TimeZoneUsageCheck.class, getClass())
|
||||
.expectErrorMessage(
|
||||
"X",
|
||||
containsPattern(
|
||||
"Derive the current time from an existing `Clock` Spring bean, and don't rely on a `Clock`'s time zone"));
|
||||
|
||||
@Test
|
||||
void identification() {
|
||||
compilationHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"import static java.time.ZoneOffset.UTC;",
|
||||
"",
|
||||
"import java.time.Clock;",
|
||||
"import java.time.Duration;",
|
||||
"import java.time.Instant;",
|
||||
"import java.time.LocalDate;",
|
||||
"import java.time.LocalDateTime;",
|
||||
"import java.time.LocalTime;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Clock clock = Clock.fixed(Instant.EPOCH, UTC);",
|
||||
" clock.instant();",
|
||||
" clock.millis();",
|
||||
" Clock.offset(clock, Duration.ZERO);",
|
||||
" Clock.tick(clock, Duration.ZERO);",
|
||||
"",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" Clock.systemUTC();",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" Clock.systemDefaultZone();",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" Clock.system(UTC);",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" Clock.tickMillis(UTC);",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" Clock.tickMinutes(UTC);",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" Clock.tickSeconds(UTC);",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" clock.getZone();",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" clock.withZone(UTC);",
|
||||
"",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" Instant.now();",
|
||||
" // This is equivalent to `clock.instant()`, which is fine.",
|
||||
" Instant.now(clock);",
|
||||
"",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" LocalDate.now();",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" LocalDate.now(clock);",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" LocalDate.now(UTC);",
|
||||
"",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" LocalDateTime.now();",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" LocalDateTime.now(clock);",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" LocalDateTime.now(UTC);",
|
||||
"",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" LocalTime.now();",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" LocalTime.now(clock);",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" LocalTime.now(UTC);",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import com.google.common.collect.ImmutableSortedSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Optional;
|
||||
import java.util.TreeSet;
|
||||
@@ -25,11 +26,12 @@ final class CollectionTemplatesTest implements RefasterTemplateTestCase {
|
||||
ImmutableSet.of(4).size() != 0,
|
||||
ImmutableSet.of(5).size() > 0,
|
||||
ImmutableSet.of(6).size() >= 1,
|
||||
Iterables.isEmpty(ImmutableSet.of(7)));
|
||||
Iterables.isEmpty(ImmutableSet.of(7)),
|
||||
ImmutableSet.of(8).asList().isEmpty());
|
||||
}
|
||||
|
||||
int testCollectionSize() {
|
||||
return Iterables.size(ImmutableSet.of());
|
||||
ImmutableSet<Integer> testCollectionSize() {
|
||||
return ImmutableSet.of(Iterables.size(ImmutableSet.of(1)), ImmutableSet.of(2).asList().size());
|
||||
}
|
||||
|
||||
boolean testCollectionAddAllToCollectionExpression() {
|
||||
@@ -64,7 +66,7 @@ final class CollectionTemplatesTest implements RefasterTemplateTestCase {
|
||||
return Lists.newArrayList(ImmutableList.of("foo"));
|
||||
}
|
||||
|
||||
Stream<Integer> testImmutableCollectionAsListToStream() {
|
||||
Stream<Integer> testImmutableCollectionStream() {
|
||||
return ImmutableSet.of(1).asList().stream();
|
||||
}
|
||||
|
||||
@@ -72,6 +74,37 @@ final class CollectionTemplatesTest implements RefasterTemplateTestCase {
|
||||
return ImmutableList.copyOf(ImmutableSet.of(1));
|
||||
}
|
||||
|
||||
boolean testImmutableCollectionContains() {
|
||||
return ImmutableSet.of(1).asList().contains("foo");
|
||||
}
|
||||
|
||||
Stream<Integer> testImmutableCollectionParallelStream() {
|
||||
return ImmutableSet.of(1).asList().parallelStream();
|
||||
}
|
||||
|
||||
String testImmutableCollectionToString() {
|
||||
return ImmutableSet.of(1).asList().toString();
|
||||
}
|
||||
|
||||
ImmutableSet<Object[]> testCollectionToArray() {
|
||||
return ImmutableSet.of(
|
||||
ImmutableSet.of(1).toArray(new Object[1]),
|
||||
ImmutableSet.of(2).toArray(Object[]::new),
|
||||
ImmutableSet.of(3).asList().toArray());
|
||||
}
|
||||
|
||||
Integer[] testImmutableCollectionToArrayWithArray() {
|
||||
return ImmutableSet.of(1).asList().toArray(new Integer[0]);
|
||||
}
|
||||
|
||||
Integer[] testImmutableCollectionToArrayWithGenerator() {
|
||||
return ImmutableSet.of(1).asList().toArray(Integer[]::new);
|
||||
}
|
||||
|
||||
Iterator<Integer> testImmutableCollectionIterator() {
|
||||
return ImmutableSet.of(1).asList().iterator();
|
||||
}
|
||||
|
||||
ImmutableSet<Optional<Integer>> testOptionalFirstCollectionElement() {
|
||||
return ImmutableSet.of(
|
||||
ImmutableSet.of(0).stream().findAny(),
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.google.common.collect.ImmutableSortedSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Optional;
|
||||
import java.util.TreeSet;
|
||||
@@ -25,11 +26,12 @@ final class CollectionTemplatesTest implements RefasterTemplateTestCase {
|
||||
!ImmutableSet.of(4).isEmpty(),
|
||||
!ImmutableSet.of(5).isEmpty(),
|
||||
!ImmutableSet.of(6).isEmpty(),
|
||||
ImmutableSet.of(7).isEmpty());
|
||||
ImmutableSet.of(7).isEmpty(),
|
||||
ImmutableSet.of(8).isEmpty());
|
||||
}
|
||||
|
||||
int testCollectionSize() {
|
||||
return ImmutableSet.of().size();
|
||||
ImmutableSet<Integer> testCollectionSize() {
|
||||
return ImmutableSet.of(ImmutableSet.of(1).size(), ImmutableSet.of(2).size());
|
||||
}
|
||||
|
||||
boolean testCollectionAddAllToCollectionExpression() {
|
||||
@@ -56,7 +58,7 @@ final class CollectionTemplatesTest implements RefasterTemplateTestCase {
|
||||
return new ArrayList<>(ImmutableList.of("foo"));
|
||||
}
|
||||
|
||||
Stream<Integer> testImmutableCollectionAsListToStream() {
|
||||
Stream<Integer> testImmutableCollectionStream() {
|
||||
return ImmutableSet.of(1).stream();
|
||||
}
|
||||
|
||||
@@ -64,6 +66,35 @@ final class CollectionTemplatesTest implements RefasterTemplateTestCase {
|
||||
return ImmutableSet.of(1).asList();
|
||||
}
|
||||
|
||||
boolean testImmutableCollectionContains() {
|
||||
return ImmutableSet.of(1).contains("foo");
|
||||
}
|
||||
|
||||
Stream<Integer> testImmutableCollectionParallelStream() {
|
||||
return ImmutableSet.of(1).parallelStream();
|
||||
}
|
||||
|
||||
String testImmutableCollectionToString() {
|
||||
return ImmutableSet.of(1).toString();
|
||||
}
|
||||
|
||||
ImmutableSet<Object[]> testCollectionToArray() {
|
||||
return ImmutableSet.of(
|
||||
ImmutableSet.of(1).toArray(), ImmutableSet.of(2).toArray(), ImmutableSet.of(3).toArray());
|
||||
}
|
||||
|
||||
Integer[] testImmutableCollectionToArrayWithArray() {
|
||||
return ImmutableSet.of(1).toArray(new Integer[0]);
|
||||
}
|
||||
|
||||
Integer[] testImmutableCollectionToArrayWithGenerator() {
|
||||
return ImmutableSet.of(1).toArray(Integer[]::new);
|
||||
}
|
||||
|
||||
Iterator<Integer> testImmutableCollectionIterator() {
|
||||
return ImmutableSet.of(1).iterator();
|
||||
}
|
||||
|
||||
ImmutableSet<Optional<Integer>> testOptionalFirstCollectionElement() {
|
||||
return ImmutableSet.of(
|
||||
ImmutableSet.of(0).stream().findFirst(),
|
||||
|
||||
@@ -83,18 +83,12 @@ final class DoubleStreamTemplatesTest implements RefasterTemplateTestCase {
|
||||
DoubleStream.of(2).filter(n -> n > 2).findAny().isPresent());
|
||||
}
|
||||
|
||||
ImmutableSet<Boolean> testDoubleStreamAllMatch() {
|
||||
boolean testDoubleStreamAllMatch() {
|
||||
DoublePredicate pred = i -> i > 0;
|
||||
return ImmutableSet.of(
|
||||
DoubleStream.of(1).noneMatch(pred.negate()),
|
||||
!DoubleStream.of(2).anyMatch(pred.negate()),
|
||||
DoubleStream.of(3).filter(pred.negate()).findAny().isEmpty());
|
||||
return DoubleStream.of(1).noneMatch(pred.negate());
|
||||
}
|
||||
|
||||
ImmutableSet<Boolean> testDoubleStreamAllMatch2() {
|
||||
return ImmutableSet.of(
|
||||
DoubleStream.of(1).noneMatch(n -> !(n > 1)),
|
||||
!DoubleStream.of(2).anyMatch(n -> !(n > 2)),
|
||||
DoubleStream.of(3).filter(n -> !(n > 3)).findAny().isEmpty());
|
||||
boolean testDoubleStreamAllMatch2() {
|
||||
return DoubleStream.of(1).noneMatch(n -> !(n > 1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,18 +82,12 @@ final class DoubleStreamTemplatesTest implements RefasterTemplateTestCase {
|
||||
DoubleStream.of(1).anyMatch(n -> n > 1), DoubleStream.of(2).anyMatch(n -> n > 2));
|
||||
}
|
||||
|
||||
ImmutableSet<Boolean> testDoubleStreamAllMatch() {
|
||||
boolean testDoubleStreamAllMatch() {
|
||||
DoublePredicate pred = i -> i > 0;
|
||||
return ImmutableSet.of(
|
||||
DoubleStream.of(1).allMatch(pred),
|
||||
DoubleStream.of(2).allMatch(pred),
|
||||
DoubleStream.of(3).allMatch(pred));
|
||||
return DoubleStream.of(1).allMatch(pred);
|
||||
}
|
||||
|
||||
ImmutableSet<Boolean> testDoubleStreamAllMatch2() {
|
||||
return ImmutableSet.of(
|
||||
DoubleStream.of(1).allMatch(n -> n > 1),
|
||||
DoubleStream.of(2).allMatch(n -> n > 2),
|
||||
DoubleStream.of(3).allMatch(n -> n > 3));
|
||||
boolean testDoubleStreamAllMatch2() {
|
||||
return DoubleStream.of(1).allMatch(n -> n > 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,38 +7,15 @@ import java.util.Objects;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
final class EqualityTemplatesTest implements RefasterTemplateTestCase {
|
||||
@Override
|
||||
public ImmutableSet<?> elidedTypesAndStaticImports() {
|
||||
return ImmutableSet.of(Objects.class);
|
||||
}
|
||||
|
||||
ImmutableSet<Boolean> testPrimitiveOrReferenceEquality() {
|
||||
return ImmutableSet.of(
|
||||
Objects.equals(true, false),
|
||||
Objects.equals((byte) 0, (byte) 1),
|
||||
Objects.equals((short) 0, (short) 1),
|
||||
Objects.equals(0, 1),
|
||||
Objects.equals(0L, 1L),
|
||||
Objects.equals(0F, 1F),
|
||||
Objects.equals(0.0, 1.0),
|
||||
Objects.equals(Boolean.TRUE, Boolean.FALSE),
|
||||
Objects.equals(Byte.valueOf((byte) 0), Byte.valueOf((byte) 1)),
|
||||
Objects.equals(Short.valueOf((short) 0), Short.valueOf((short) 1)),
|
||||
Objects.equals(Integer.valueOf(0), Integer.valueOf(1)),
|
||||
Objects.equals(Long.valueOf(0L), Long.valueOf(1L)),
|
||||
Objects.equals(Float.valueOf(0F), Float.valueOf(1F)),
|
||||
Objects.equals(Double.valueOf(0.0), Double.valueOf(1.0)),
|
||||
RoundingMode.UP.equals(RoundingMode.DOWN),
|
||||
Objects.equals(RoundingMode.UP, RoundingMode.DOWN),
|
||||
!Objects.equals(true, false),
|
||||
!Objects.equals((byte) 0, (byte) 1),
|
||||
!Objects.equals((short) 0, (short) 1),
|
||||
!Objects.equals(0, 1),
|
||||
!Objects.equals(0L, 1L),
|
||||
!Objects.equals(0F, 1F),
|
||||
!Objects.equals(0.0, 1.0),
|
||||
!Objects.equals(Boolean.TRUE, Boolean.FALSE),
|
||||
!Objects.equals(Byte.valueOf((byte) 0), Byte.valueOf((byte) 1)),
|
||||
!Objects.equals(Short.valueOf((short) 0), Short.valueOf((short) 1)),
|
||||
!Objects.equals(Integer.valueOf(0), Integer.valueOf(1)),
|
||||
!Objects.equals(Long.valueOf(0L), Long.valueOf(1L)),
|
||||
!Objects.equals(Float.valueOf(0F), Float.valueOf(1F)),
|
||||
!Objects.equals(Double.valueOf(0.0), Double.valueOf(1.0)),
|
||||
!RoundingMode.UP.equals(RoundingMode.DOWN),
|
||||
!Objects.equals(RoundingMode.UP, RoundingMode.DOWN));
|
||||
}
|
||||
|
||||
@@ -7,38 +7,15 @@ import java.util.Objects;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
final class EqualityTemplatesTest implements RefasterTemplateTestCase {
|
||||
@Override
|
||||
public ImmutableSet<?> elidedTypesAndStaticImports() {
|
||||
return ImmutableSet.of(Objects.class);
|
||||
}
|
||||
|
||||
ImmutableSet<Boolean> testPrimitiveOrReferenceEquality() {
|
||||
return ImmutableSet.of(
|
||||
true == false,
|
||||
(byte) 0 == (byte) 1,
|
||||
(short) 0 == (short) 1,
|
||||
0 == 1,
|
||||
0L == 1L,
|
||||
0F == 1F,
|
||||
0.0 == 1.0,
|
||||
Objects.equals(Boolean.TRUE, Boolean.FALSE),
|
||||
Objects.equals(Byte.valueOf((byte) 0), Byte.valueOf((byte) 1)),
|
||||
Objects.equals(Short.valueOf((short) 0), Short.valueOf((short) 1)),
|
||||
Objects.equals(Integer.valueOf(0), Integer.valueOf(1)),
|
||||
Objects.equals(Long.valueOf(0L), Long.valueOf(1L)),
|
||||
Objects.equals(Float.valueOf(0F), Float.valueOf(1F)),
|
||||
Objects.equals(Double.valueOf(0.0), Double.valueOf(1.0)),
|
||||
RoundingMode.UP == RoundingMode.DOWN,
|
||||
RoundingMode.UP == RoundingMode.DOWN,
|
||||
true != false,
|
||||
(byte) 0 != (byte) 1,
|
||||
(short) 0 != (short) 1,
|
||||
0 != 1,
|
||||
0L != 1L,
|
||||
0F != 1F,
|
||||
0.0 != 1.0,
|
||||
!Objects.equals(Boolean.TRUE, Boolean.FALSE),
|
||||
!Objects.equals(Byte.valueOf((byte) 0), Byte.valueOf((byte) 1)),
|
||||
!Objects.equals(Short.valueOf((short) 0), Short.valueOf((short) 1)),
|
||||
!Objects.equals(Integer.valueOf(0), Integer.valueOf(1)),
|
||||
!Objects.equals(Long.valueOf(0L), Long.valueOf(1L)),
|
||||
!Objects.equals(Float.valueOf(0F), Float.valueOf(1F)),
|
||||
!Objects.equals(Double.valueOf(0.0), Double.valueOf(1.0)),
|
||||
RoundingMode.UP != RoundingMode.DOWN,
|
||||
RoundingMode.UP != RoundingMode.DOWN);
|
||||
}
|
||||
|
||||
@@ -33,25 +33,20 @@ final class ImmutableListMultimapTemplatesTest implements RefasterTemplateTestCa
|
||||
|
||||
ImmutableSet<ImmutableMultimap<String, Integer>> testEmptyImmutableListMultimap() {
|
||||
return ImmutableSet.of(
|
||||
ImmutableListMultimap.<String, Integer>builder().build(),
|
||||
ImmutableMultimap.<String, Integer>builder().build(),
|
||||
ImmutableMultimap.of());
|
||||
ImmutableListMultimap.<String, Integer>builder().build(), ImmutableMultimap.of());
|
||||
}
|
||||
|
||||
ImmutableSet<ImmutableMultimap<String, Integer>> testPairToImmutableListMultimap() {
|
||||
return ImmutableSet.of(
|
||||
ImmutableListMultimap.<String, Integer>builder().put("foo", 1).build(),
|
||||
ImmutableMultimap.<String, Integer>builder().put("bar", 2).build(),
|
||||
ImmutableMultimap.of("baz", 3));
|
||||
ImmutableMultimap.of("bar", 2));
|
||||
}
|
||||
|
||||
ImmutableList<ImmutableMultimap<String, Integer>> testEntryToImmutableListMultimap() {
|
||||
return ImmutableList.of(
|
||||
ImmutableListMultimap.<String, Integer>builder().put(Map.entry("foo", 1)).build(),
|
||||
Stream.of(Map.entry("foo", 1))
|
||||
.collect(toImmutableListMultimap(Map.Entry::getKey, Map.Entry::getValue)),
|
||||
ImmutableMultimap.<String, Integer>builder().put(Map.entry("foo", 1)).build(),
|
||||
ImmutableMultimap.of(Map.entry("foo", 1).getKey(), Map.entry("foo", 1).getValue()));
|
||||
.collect(toImmutableListMultimap(Map.Entry::getKey, Map.Entry::getValue)));
|
||||
}
|
||||
|
||||
ImmutableList<ImmutableMultimap<String, Integer>> testIterableToImmutableListMultimap() {
|
||||
@@ -69,12 +64,6 @@ final class ImmutableListMultimapTemplatesTest implements RefasterTemplateTestCa
|
||||
.collect(toImmutableListMultimap(Map.Entry::getKey, Map.Entry::getValue)),
|
||||
ImmutableMultimap.copyOf(ImmutableListMultimap.of("foo", 1)),
|
||||
ImmutableMultimap.copyOf(ImmutableListMultimap.of("foo", 1).entries()),
|
||||
ImmutableMultimap.<String, Integer>builder()
|
||||
.putAll(ImmutableListMultimap.of("foo", 1))
|
||||
.build(),
|
||||
ImmutableMultimap.<String, Integer>builder()
|
||||
.putAll(ImmutableListMultimap.of("foo", 1).entries())
|
||||
.build(),
|
||||
ImmutableMultimap.copyOf(Iterables.cycle(Map.entry("foo", 1))));
|
||||
}
|
||||
|
||||
|
||||
@@ -32,21 +32,15 @@ final class ImmutableListMultimapTemplatesTest implements RefasterTemplateTestCa
|
||||
}
|
||||
|
||||
ImmutableSet<ImmutableMultimap<String, Integer>> testEmptyImmutableListMultimap() {
|
||||
return ImmutableSet.of(
|
||||
ImmutableListMultimap.of(), ImmutableListMultimap.of(), ImmutableListMultimap.of());
|
||||
return ImmutableSet.of(ImmutableListMultimap.of(), ImmutableListMultimap.of());
|
||||
}
|
||||
|
||||
ImmutableSet<ImmutableMultimap<String, Integer>> testPairToImmutableListMultimap() {
|
||||
return ImmutableSet.of(
|
||||
ImmutableListMultimap.of("foo", 1),
|
||||
ImmutableListMultimap.of("bar", 2),
|
||||
ImmutableListMultimap.of("baz", 3));
|
||||
return ImmutableSet.of(ImmutableListMultimap.of("foo", 1), ImmutableListMultimap.of("bar", 2));
|
||||
}
|
||||
|
||||
ImmutableList<ImmutableMultimap<String, Integer>> testEntryToImmutableListMultimap() {
|
||||
return ImmutableList.of(
|
||||
ImmutableListMultimap.of(Map.entry("foo", 1).getKey(), Map.entry("foo", 1).getValue()),
|
||||
ImmutableListMultimap.of(Map.entry("foo", 1).getKey(), Map.entry("foo", 1).getValue()),
|
||||
ImmutableListMultimap.of(Map.entry("foo", 1).getKey(), Map.entry("foo", 1).getValue()),
|
||||
ImmutableListMultimap.of(Map.entry("foo", 1).getKey(), Map.entry("foo", 1).getValue()));
|
||||
}
|
||||
@@ -60,8 +54,6 @@ final class ImmutableListMultimapTemplatesTest implements RefasterTemplateTestCa
|
||||
ImmutableListMultimap.copyOf(Iterables.cycle(Map.entry("foo", 1))),
|
||||
ImmutableListMultimap.copyOf(ImmutableListMultimap.of("foo", 1)),
|
||||
ImmutableListMultimap.copyOf(ImmutableListMultimap.of("foo", 1)),
|
||||
ImmutableListMultimap.copyOf(ImmutableListMultimap.of("foo", 1)),
|
||||
ImmutableListMultimap.copyOf(ImmutableListMultimap.of("foo", 1).entries()),
|
||||
ImmutableListMultimap.copyOf(Iterables.cycle(Map.entry("foo", 1))));
|
||||
}
|
||||
|
||||
|
||||
@@ -50,15 +50,13 @@ final class ImmutableListTemplatesTest implements RefasterTemplateTestCase {
|
||||
ImmutableList.<Integer>builder().addAll(ImmutableList.of(5)::iterator).build(),
|
||||
ImmutableList.<Integer>builder().addAll(ImmutableList.of(6).iterator()).build(),
|
||||
ImmutableList.<Integer>builder().add(new Integer[] {7}).build(),
|
||||
Stream.of(new Integer[] {8}).collect(toImmutableList()),
|
||||
Arrays.stream(new Integer[] {9}).collect(toImmutableList()));
|
||||
Arrays.stream(new Integer[] {8}).collect(toImmutableList()));
|
||||
}
|
||||
|
||||
ImmutableSet<ImmutableList<Integer>> testStreamToImmutableList() {
|
||||
return ImmutableSet.of(
|
||||
ImmutableList.copyOf(Stream.of(1).iterator()),
|
||||
ImmutableList.copyOf(Stream.of(2).iterator()),
|
||||
Stream.of(3).collect(collectingAndThen(toList(), ImmutableList::copyOf)));
|
||||
Stream.of(2).collect(collectingAndThen(toList(), ImmutableList::copyOf)));
|
||||
}
|
||||
|
||||
ImmutableList<Integer> testImmutableListAsList() {
|
||||
|
||||
@@ -49,15 +49,12 @@ final class ImmutableListTemplatesTest implements RefasterTemplateTestCase {
|
||||
ImmutableList.copyOf(ImmutableList.of(5)::iterator),
|
||||
ImmutableList.copyOf(ImmutableList.of(6).iterator()),
|
||||
ImmutableList.copyOf(new Integer[] {7}),
|
||||
ImmutableList.copyOf(new Integer[] {8}),
|
||||
ImmutableList.copyOf(new Integer[] {9}));
|
||||
ImmutableList.copyOf(new Integer[] {8}));
|
||||
}
|
||||
|
||||
ImmutableSet<ImmutableList<Integer>> testStreamToImmutableList() {
|
||||
return ImmutableSet.of(
|
||||
Stream.of(1).collect(toImmutableList()),
|
||||
Stream.of(2).collect(toImmutableList()),
|
||||
Stream.of(3).collect(toImmutableList()));
|
||||
Stream.of(1).collect(toImmutableList()), Stream.of(2).collect(toImmutableList()));
|
||||
}
|
||||
|
||||
ImmutableList<Integer> testImmutableListAsList() {
|
||||
|
||||
@@ -36,15 +36,13 @@ final class ImmutableMultisetTemplatesTest implements RefasterTemplateTestCase {
|
||||
ImmutableMultiset.<Integer>builder().addAll(ImmutableMultiset.of(5)::iterator).build(),
|
||||
ImmutableMultiset.<Integer>builder().addAll(ImmutableMultiset.of(6).iterator()).build(),
|
||||
ImmutableMultiset.<Integer>builder().add(new Integer[] {7}).build(),
|
||||
Stream.of(new Integer[] {8}).collect(toImmutableMultiset()),
|
||||
Arrays.stream(new Integer[] {9}).collect(toImmutableMultiset()));
|
||||
Arrays.stream(new Integer[] {8}).collect(toImmutableMultiset()));
|
||||
}
|
||||
|
||||
ImmutableSet<ImmutableMultiset<Integer>> testStreamToImmutableMultiset() {
|
||||
return ImmutableSet.of(
|
||||
ImmutableMultiset.copyOf(Stream.of(1).iterator()),
|
||||
ImmutableMultiset.copyOf(Stream.of(2)::iterator),
|
||||
Stream.of(3).collect(collectingAndThen(toList(), ImmutableMultiset::copyOf)));
|
||||
Stream.of(2).collect(collectingAndThen(toList(), ImmutableMultiset::copyOf)));
|
||||
}
|
||||
|
||||
ImmutableMultiset<Integer> testImmutableMultisetCopyOfImmutableMultiset() {
|
||||
|
||||
@@ -34,15 +34,12 @@ final class ImmutableMultisetTemplatesTest implements RefasterTemplateTestCase {
|
||||
ImmutableMultiset.copyOf(ImmutableMultiset.of(5)::iterator),
|
||||
ImmutableMultiset.copyOf(ImmutableMultiset.of(6).iterator()),
|
||||
ImmutableMultiset.copyOf(new Integer[] {7}),
|
||||
ImmutableMultiset.copyOf(new Integer[] {8}),
|
||||
ImmutableMultiset.copyOf(new Integer[] {9}));
|
||||
ImmutableMultiset.copyOf(new Integer[] {8}));
|
||||
}
|
||||
|
||||
ImmutableSet<ImmutableMultiset<Integer>> testStreamToImmutableMultiset() {
|
||||
return ImmutableSet.of(
|
||||
Stream.of(1).collect(toImmutableMultiset()),
|
||||
Stream.of(2).collect(toImmutableMultiset()),
|
||||
Stream.of(3).collect(toImmutableMultiset()));
|
||||
Stream.of(1).collect(toImmutableMultiset()), Stream.of(2).collect(toImmutableMultiset()));
|
||||
}
|
||||
|
||||
ImmutableMultiset<Integer> testImmutableMultisetCopyOfImmutableMultiset() {
|
||||
|
||||
@@ -48,17 +48,15 @@ final class ImmutableSetTemplatesTest implements RefasterTemplateTestCase {
|
||||
ImmutableSet.<Integer>builder().addAll(ImmutableSet.of(5)::iterator).build(),
|
||||
ImmutableSet.<Integer>builder().addAll(ImmutableSet.of(6).iterator()).build(),
|
||||
ImmutableSet.<Integer>builder().add(new Integer[] {7}).build(),
|
||||
Stream.of(new Integer[] {8}).collect(toImmutableSet()),
|
||||
Arrays.stream(new Integer[] {9}).collect(toImmutableSet()));
|
||||
Arrays.stream(new Integer[] {8}).collect(toImmutableSet()));
|
||||
}
|
||||
|
||||
ImmutableSet<ImmutableSet<Integer>> testStreamToImmutableSet() {
|
||||
return ImmutableSet.of(
|
||||
ImmutableSet.copyOf(Stream.of(1).iterator()),
|
||||
ImmutableSet.copyOf(Stream.of(2)::iterator),
|
||||
Stream.of(3).distinct().collect(toImmutableSet()),
|
||||
Stream.of(4).collect(collectingAndThen(toList(), ImmutableSet::copyOf)),
|
||||
Stream.of(5).collect(collectingAndThen(toSet(), ImmutableSet::copyOf)));
|
||||
Stream.of(2).distinct().collect(toImmutableSet()),
|
||||
Stream.of(3).collect(collectingAndThen(toList(), ImmutableSet::copyOf)),
|
||||
Stream.of(4).collect(collectingAndThen(toSet(), ImmutableSet::copyOf)));
|
||||
}
|
||||
|
||||
ImmutableSet<Integer> testImmutableSetCopyOfImmutableSet() {
|
||||
|
||||
@@ -47,8 +47,7 @@ final class ImmutableSetTemplatesTest implements RefasterTemplateTestCase {
|
||||
ImmutableSet.copyOf(ImmutableSet.of(5)::iterator),
|
||||
ImmutableSet.copyOf(ImmutableSet.of(6).iterator()),
|
||||
ImmutableSet.copyOf(new Integer[] {7}),
|
||||
ImmutableSet.copyOf(new Integer[] {8}),
|
||||
ImmutableSet.copyOf(new Integer[] {9}));
|
||||
ImmutableSet.copyOf(new Integer[] {8}));
|
||||
}
|
||||
|
||||
ImmutableSet<ImmutableSet<Integer>> testStreamToImmutableSet() {
|
||||
@@ -56,8 +55,7 @@ final class ImmutableSetTemplatesTest implements RefasterTemplateTestCase {
|
||||
Stream.of(1).collect(toImmutableSet()),
|
||||
Stream.of(2).collect(toImmutableSet()),
|
||||
Stream.of(3).collect(toImmutableSet()),
|
||||
Stream.of(4).collect(toImmutableSet()),
|
||||
Stream.of(5).collect(toImmutableSet()));
|
||||
Stream.of(4).collect(toImmutableSet()));
|
||||
}
|
||||
|
||||
ImmutableSet<Integer> testImmutableSetCopyOfImmutableSet() {
|
||||
|
||||
@@ -55,14 +55,12 @@ final class ImmutableSortedMultisetTemplatesTest implements RefasterTemplateTest
|
||||
.addAll(ImmutableMultiset.of(8).iterator())
|
||||
.build(),
|
||||
ImmutableSortedMultiset.<Integer>naturalOrder().add(new Integer[] {9}).build(),
|
||||
Stream.of(new Integer[] {10}).collect(toImmutableSortedMultiset(naturalOrder())),
|
||||
Arrays.stream(new Integer[] {11}).collect(toImmutableSortedMultiset(naturalOrder())));
|
||||
Arrays.stream(new Integer[] {10}).collect(toImmutableSortedMultiset(naturalOrder())));
|
||||
}
|
||||
|
||||
ImmutableSet<ImmutableSortedMultiset<Integer>> testStreamToImmutableSortedMultiset() {
|
||||
return ImmutableSet.of(
|
||||
ImmutableSortedMultiset.copyOf(Stream.of(1).iterator()),
|
||||
ImmutableSortedMultiset.copyOf(Stream.of(2)::iterator),
|
||||
Stream.of(3).collect(collectingAndThen(toList(), ImmutableSortedMultiset::copyOf)));
|
||||
Stream.of(2).collect(collectingAndThen(toList(), ImmutableSortedMultiset::copyOf)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,14 +47,12 @@ final class ImmutableSortedMultisetTemplatesTest implements RefasterTemplateTest
|
||||
ImmutableSortedMultiset.copyOf(ImmutableMultiset.of(7)::iterator),
|
||||
ImmutableSortedMultiset.copyOf(ImmutableMultiset.of(8).iterator()),
|
||||
ImmutableSortedMultiset.copyOf(new Integer[] {9}),
|
||||
ImmutableSortedMultiset.copyOf(new Integer[] {10}),
|
||||
ImmutableSortedMultiset.copyOf(new Integer[] {11}));
|
||||
ImmutableSortedMultiset.copyOf(new Integer[] {10}));
|
||||
}
|
||||
|
||||
ImmutableSet<ImmutableSortedMultiset<Integer>> testStreamToImmutableSortedMultiset() {
|
||||
return ImmutableSet.of(
|
||||
Stream.of(1).collect(toImmutableSortedMultiset(naturalOrder())),
|
||||
Stream.of(2).collect(toImmutableSortedMultiset(naturalOrder())),
|
||||
Stream.of(3).collect(toImmutableSortedMultiset(naturalOrder())));
|
||||
Stream.of(2).collect(toImmutableSortedMultiset(naturalOrder())));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,14 +50,12 @@ final class ImmutableSortedSetTemplatesTest implements RefasterTemplateTestCase
|
||||
ImmutableSortedSet.<Integer>naturalOrder().addAll(ImmutableSet.of(7)::iterator).build(),
|
||||
ImmutableSortedSet.<Integer>naturalOrder().addAll(ImmutableSet.of(8).iterator()).build(),
|
||||
ImmutableSortedSet.<Integer>naturalOrder().add(new Integer[] {9}).build(),
|
||||
Stream.of(new Integer[] {10}).collect(toImmutableSortedSet(naturalOrder())),
|
||||
Arrays.stream(new Integer[] {11}).collect(toImmutableSortedSet(naturalOrder())));
|
||||
Arrays.stream(new Integer[] {10}).collect(toImmutableSortedSet(naturalOrder())));
|
||||
}
|
||||
|
||||
ImmutableSet<ImmutableSortedSet<Integer>> testStreamToImmutableSortedSet() {
|
||||
return ImmutableSet.of(
|
||||
ImmutableSortedSet.copyOf(Stream.of(1).iterator()),
|
||||
ImmutableSortedSet.copyOf(Stream.of(2)::iterator),
|
||||
Stream.of(3).collect(collectingAndThen(toList(), ImmutableSortedSet::copyOf)));
|
||||
Stream.of(2).collect(collectingAndThen(toList(), ImmutableSortedSet::copyOf)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,14 +47,12 @@ final class ImmutableSortedSetTemplatesTest implements RefasterTemplateTestCase
|
||||
ImmutableSortedSet.copyOf(ImmutableSet.of(7)::iterator),
|
||||
ImmutableSortedSet.copyOf(ImmutableSet.of(8).iterator()),
|
||||
ImmutableSortedSet.copyOf(new Integer[] {9}),
|
||||
ImmutableSortedSet.copyOf(new Integer[] {10}),
|
||||
ImmutableSortedSet.copyOf(new Integer[] {11}));
|
||||
ImmutableSortedSet.copyOf(new Integer[] {10}));
|
||||
}
|
||||
|
||||
ImmutableSet<ImmutableSortedSet<Integer>> testStreamToImmutableSortedSet() {
|
||||
return ImmutableSet.of(
|
||||
Stream.of(1).collect(toImmutableSortedSet(naturalOrder())),
|
||||
Stream.of(2).collect(toImmutableSortedSet(naturalOrder())),
|
||||
Stream.of(3).collect(toImmutableSortedSet(naturalOrder())));
|
||||
Stream.of(2).collect(toImmutableSortedSet(naturalOrder())));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,18 +87,12 @@ final class IntStreamTemplatesTest implements RefasterTemplateTestCase {
|
||||
IntStream.of(2).filter(n -> n > 2).findAny().isPresent());
|
||||
}
|
||||
|
||||
ImmutableSet<Boolean> testIntStreamAllMatch() {
|
||||
boolean testIntStreamAllMatch() {
|
||||
IntPredicate pred = i -> i > 0;
|
||||
return ImmutableSet.of(
|
||||
IntStream.of(1).noneMatch(pred.negate()),
|
||||
!IntStream.of(2).anyMatch(pred.negate()),
|
||||
IntStream.of(3).filter(pred.negate()).findAny().isEmpty());
|
||||
return IntStream.of(1).noneMatch(pred.negate());
|
||||
}
|
||||
|
||||
ImmutableSet<Boolean> testIntStreamAllMatch2() {
|
||||
return ImmutableSet.of(
|
||||
IntStream.of(1).noneMatch(n -> !(n > 1)),
|
||||
!IntStream.of(2).anyMatch(n -> !(n > 2)),
|
||||
IntStream.of(3).filter(n -> !(n > 3)).findAny().isEmpty());
|
||||
boolean testIntStreamAllMatch2() {
|
||||
return IntStream.of(1).noneMatch(n -> !(n > 1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,18 +86,12 @@ final class IntStreamTemplatesTest implements RefasterTemplateTestCase {
|
||||
IntStream.of(1).anyMatch(n -> n > 1), IntStream.of(2).anyMatch(n -> n > 2));
|
||||
}
|
||||
|
||||
ImmutableSet<Boolean> testIntStreamAllMatch() {
|
||||
boolean testIntStreamAllMatch() {
|
||||
IntPredicate pred = i -> i > 0;
|
||||
return ImmutableSet.of(
|
||||
IntStream.of(1).allMatch(pred),
|
||||
IntStream.of(2).allMatch(pred),
|
||||
IntStream.of(3).allMatch(pred));
|
||||
return IntStream.of(1).allMatch(pred);
|
||||
}
|
||||
|
||||
ImmutableSet<Boolean> testIntStreamAllMatch2() {
|
||||
return ImmutableSet.of(
|
||||
IntStream.of(1).allMatch(n -> n > 1),
|
||||
IntStream.of(2).allMatch(n -> n > 2),
|
||||
IntStream.of(3).allMatch(n -> n > 3));
|
||||
boolean testIntStreamAllMatch2() {
|
||||
return IntStream.of(1).allMatch(n -> n > 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,18 +87,12 @@ final class LongStreamTemplatesTest implements RefasterTemplateTestCase {
|
||||
LongStream.of(2).filter(n -> n > 2).findAny().isPresent());
|
||||
}
|
||||
|
||||
ImmutableSet<Boolean> testLongStreamAllMatch() {
|
||||
boolean testLongStreamAllMatch() {
|
||||
LongPredicate pred = i -> i > 0;
|
||||
return ImmutableSet.of(
|
||||
LongStream.of(1).noneMatch(pred.negate()),
|
||||
!LongStream.of(2).anyMatch(pred.negate()),
|
||||
LongStream.of(3).filter(pred.negate()).findAny().isEmpty());
|
||||
return LongStream.of(1).noneMatch(pred.negate());
|
||||
}
|
||||
|
||||
ImmutableSet<Boolean> testLongStreamAllMatch2() {
|
||||
return ImmutableSet.of(
|
||||
LongStream.of(1).noneMatch(n -> !(n > 1)),
|
||||
!LongStream.of(2).anyMatch(n -> !(n > 2)),
|
||||
LongStream.of(3).filter(n -> !(n > 3)).findAny().isEmpty());
|
||||
boolean testLongStreamAllMatch2() {
|
||||
return LongStream.of(1).noneMatch(n -> !(n > 1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,18 +86,12 @@ final class LongStreamTemplatesTest implements RefasterTemplateTestCase {
|
||||
LongStream.of(1).anyMatch(n -> n > 1), LongStream.of(2).anyMatch(n -> n > 2));
|
||||
}
|
||||
|
||||
ImmutableSet<Boolean> testLongStreamAllMatch() {
|
||||
boolean testLongStreamAllMatch() {
|
||||
LongPredicate pred = i -> i > 0;
|
||||
return ImmutableSet.of(
|
||||
LongStream.of(1).allMatch(pred),
|
||||
LongStream.of(2).allMatch(pred),
|
||||
LongStream.of(3).allMatch(pred));
|
||||
return LongStream.of(1).allMatch(pred);
|
||||
}
|
||||
|
||||
ImmutableSet<Boolean> testLongStreamAllMatch2() {
|
||||
return ImmutableSet.of(
|
||||
LongStream.of(1).allMatch(n -> n > 1),
|
||||
LongStream.of(2).allMatch(n -> n > 2),
|
||||
LongStream.of(3).allMatch(n -> n > 3));
|
||||
boolean testLongStreamAllMatch2() {
|
||||
return LongStream.of(1).allMatch(n -> n > 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,16 +24,12 @@ final class ReactorTemplatesTest implements RefasterTemplateTestCase {
|
||||
return Flux.defer(() -> Flux.error(new IllegalStateException()));
|
||||
}
|
||||
|
||||
ImmutableSet<Mono<Void>> testMonoErrorSupplier() {
|
||||
return ImmutableSet.of(
|
||||
Mono.error(((Supplier<RuntimeException>) null)::get),
|
||||
Mono.error(() -> ((Supplier<RuntimeException>) null).get()));
|
||||
Mono<Void> testMonoErrorSupplier() {
|
||||
return Mono.error(() -> ((Supplier<RuntimeException>) null).get());
|
||||
}
|
||||
|
||||
ImmutableSet<Flux<Void>> testFluxErrorSupplier() {
|
||||
return ImmutableSet.of(
|
||||
Flux.error(((Supplier<RuntimeException>) null)::get),
|
||||
Flux.error(() -> ((Supplier<RuntimeException>) null).get()));
|
||||
Flux<Void> testFluxErrorSupplier() {
|
||||
return Flux.error(() -> ((Supplier<RuntimeException>) null).get());
|
||||
}
|
||||
|
||||
Mono<String> testMonoThenReturn() {
|
||||
|
||||
@@ -26,16 +26,12 @@ final class ReactorTemplatesTest implements RefasterTemplateTestCase {
|
||||
return Flux.error(() -> new IllegalStateException());
|
||||
}
|
||||
|
||||
ImmutableSet<Mono<Void>> testMonoErrorSupplier() {
|
||||
return ImmutableSet.of(
|
||||
Mono.error(((Supplier<RuntimeException>) null)),
|
||||
Mono.error(((Supplier<RuntimeException>) null)));
|
||||
Mono<Void> testMonoErrorSupplier() {
|
||||
return Mono.error(((Supplier<RuntimeException>) null));
|
||||
}
|
||||
|
||||
ImmutableSet<Flux<Void>> testFluxErrorSupplier() {
|
||||
return ImmutableSet.of(
|
||||
Flux.error(((Supplier<RuntimeException>) null)),
|
||||
Flux.error(((Supplier<RuntimeException>) null)));
|
||||
Flux<Void> testFluxErrorSupplier() {
|
||||
return Flux.error(((Supplier<RuntimeException>) null));
|
||||
}
|
||||
|
||||
Mono<String> testMonoThenReturn() {
|
||||
|
||||
@@ -17,15 +17,15 @@ final class StreamTemplatesTest implements RefasterTemplateTestCase {
|
||||
return ImmutableSet.of(Objects.class, Streams.class, not(null), reverseOrder());
|
||||
}
|
||||
|
||||
Stream<String> testEmptyStream() {
|
||||
return Stream.of();
|
||||
}
|
||||
|
||||
ImmutableSet<Stream<String>> testStreamOfNullable() {
|
||||
return ImmutableSet.of(
|
||||
Stream.of("a").filter(Objects::nonNull), Optional.ofNullable("b").stream());
|
||||
}
|
||||
|
||||
Stream<String> testStreamOfArray() {
|
||||
return Stream.of(new String[] {"foo", "bar"});
|
||||
}
|
||||
|
||||
Stream<Integer> testConcatOneStream() {
|
||||
return Streams.concat(Stream.of(1));
|
||||
}
|
||||
@@ -114,20 +114,10 @@ final class StreamTemplatesTest implements RefasterTemplateTestCase {
|
||||
Predicate<String> pred = String::isBlank;
|
||||
return ImmutableSet.of(
|
||||
Stream.of("foo").noneMatch(not(String::isBlank)),
|
||||
Stream.of("bar").noneMatch(pred.negate()),
|
||||
!Stream.of("baz").anyMatch(not(s -> s.length() > 1)),
|
||||
!Stream.of("qux").anyMatch(pred.negate()),
|
||||
Stream.of("quux").filter(not(String::isEmpty)).findAny().isEmpty(),
|
||||
Stream.of("quuz").filter(pred.negate()).findAny().isEmpty(),
|
||||
Stream.of(Boolean.TRUE).noneMatch(b -> !b),
|
||||
!Stream.of(Boolean.TRUE).anyMatch(b -> !b),
|
||||
Stream.of(Boolean.TRUE).filter(b -> !b).findAny().isEmpty());
|
||||
Stream.of("bar").noneMatch(pred.negate()));
|
||||
}
|
||||
|
||||
ImmutableSet<Boolean> testStreamAllMatch2() {
|
||||
return ImmutableSet.of(
|
||||
Stream.of("foo").noneMatch(s -> !s.isBlank()),
|
||||
!Stream.of("bar").anyMatch(s -> !s.isEmpty()),
|
||||
Stream.of("baz").filter(s -> !s.isBlank()).findAny().isEmpty());
|
||||
boolean testStreamAllMatch2() {
|
||||
return Stream.of("foo").noneMatch(s -> !s.isBlank());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import static java.util.function.Predicate.not;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Streams;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
@@ -18,14 +19,14 @@ final class StreamTemplatesTest implements RefasterTemplateTestCase {
|
||||
return ImmutableSet.of(Objects.class, Streams.class, not(null), reverseOrder());
|
||||
}
|
||||
|
||||
Stream<String> testEmptyStream() {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
ImmutableSet<Stream<String>> testStreamOfNullable() {
|
||||
return ImmutableSet.of(Stream.ofNullable("a"), Stream.ofNullable("b"));
|
||||
}
|
||||
|
||||
Stream<String> testStreamOfArray() {
|
||||
return Arrays.stream(new String[] {"foo", "bar"});
|
||||
}
|
||||
|
||||
Stream<Integer> testConcatOneStream() {
|
||||
return Stream.of(1);
|
||||
}
|
||||
@@ -112,21 +113,10 @@ final class StreamTemplatesTest implements RefasterTemplateTestCase {
|
||||
ImmutableSet<Boolean> testStreamAllMatch() {
|
||||
Predicate<String> pred = String::isBlank;
|
||||
return ImmutableSet.of(
|
||||
Stream.of("foo").allMatch(String::isBlank),
|
||||
Stream.of("bar").allMatch(pred),
|
||||
Stream.of("baz").allMatch(s -> s.length() > 1),
|
||||
Stream.of("qux").allMatch(pred),
|
||||
Stream.of("quux").allMatch(String::isEmpty),
|
||||
Stream.of("quuz").allMatch(pred),
|
||||
Stream.of(Boolean.TRUE).allMatch(b -> b),
|
||||
Stream.of(Boolean.TRUE).allMatch(b -> b),
|
||||
Stream.of(Boolean.TRUE).allMatch(b -> b));
|
||||
Stream.of("foo").allMatch(String::isBlank), Stream.of("bar").allMatch(pred));
|
||||
}
|
||||
|
||||
ImmutableSet<Boolean> testStreamAllMatch2() {
|
||||
return ImmutableSet.of(
|
||||
Stream.of("foo").allMatch(s -> s.isBlank()),
|
||||
Stream.of("bar").allMatch(s -> s.isEmpty()),
|
||||
Stream.of("baz").allMatch(s -> s.isBlank()));
|
||||
boolean testStreamAllMatch2() {
|
||||
return Stream.of("foo").allMatch(s -> s.isBlank());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
@@ -8,7 +9,6 @@ import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Streams;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
@@ -17,7 +17,7 @@ final class StringTemplatesTest implements RefasterTemplateTestCase {
|
||||
@Override
|
||||
public ImmutableSet<?> elidedTypesAndStaticImports() {
|
||||
return ImmutableSet.of(
|
||||
Arrays.class, Joiner.class, StandardCharsets.class, Stream.class, Streams.class, joining());
|
||||
Arrays.class, Joiner.class, Stream.class, Streams.class, joining(), UTF_8);
|
||||
}
|
||||
|
||||
ImmutableSet<Boolean> testStringIsEmpty() {
|
||||
@@ -51,12 +51,11 @@ final class StringTemplatesTest implements RefasterTemplateTestCase {
|
||||
ImmutableSet<String> testJoinStrings() {
|
||||
return ImmutableSet.of(
|
||||
Joiner.on("a").join(new String[] {"foo", "bar"}),
|
||||
Joiner.on("b").join(new CharSequence[] {"baz", "qux"}),
|
||||
Stream.of(new String[] {"foo", "bar"}).collect(joining("c")),
|
||||
Arrays.stream(new CharSequence[] {"baz", "qux"}).collect(joining("d")),
|
||||
Joiner.on("e").join(ImmutableList.of("foo", "bar")),
|
||||
Streams.stream(Iterables.cycle(ImmutableList.of("foo", "bar"))).collect(joining("f")),
|
||||
ImmutableList.of("baz", "qux").stream().collect(joining("g")));
|
||||
Joiner.on("b").join(new CharSequence[] {"foo", "bar"}),
|
||||
Arrays.stream(new String[] {"foo", "bar"}).collect(joining("c")),
|
||||
Joiner.on("d").join(ImmutableList.of("foo", "bar")),
|
||||
Streams.stream(Iterables.cycle(ImmutableList.of("foo", "bar"))).collect(joining("e")),
|
||||
ImmutableList.of("foo", "bar").stream().collect(joining("f")));
|
||||
}
|
||||
|
||||
String testSubstringRemainder() {
|
||||
@@ -64,6 +63,6 @@ final class StringTemplatesTest implements RefasterTemplateTestCase {
|
||||
}
|
||||
|
||||
int testUtf8EncodedLength() {
|
||||
return "foo".getBytes(StandardCharsets.UTF_8).length;
|
||||
return "foo".getBytes(UTF_8).length;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
@@ -9,7 +10,6 @@ import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Streams;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
@@ -18,7 +18,7 @@ final class StringTemplatesTest implements RefasterTemplateTestCase {
|
||||
@Override
|
||||
public ImmutableSet<?> elidedTypesAndStaticImports() {
|
||||
return ImmutableSet.of(
|
||||
Arrays.class, Joiner.class, StandardCharsets.class, Stream.class, Streams.class, joining());
|
||||
Arrays.class, Joiner.class, Stream.class, Streams.class, joining(), UTF_8);
|
||||
}
|
||||
|
||||
ImmutableSet<Boolean> testStringIsEmpty() {
|
||||
@@ -51,12 +51,11 @@ final class StringTemplatesTest implements RefasterTemplateTestCase {
|
||||
ImmutableSet<String> testJoinStrings() {
|
||||
return ImmutableSet.of(
|
||||
String.join("a", new String[] {"foo", "bar"}),
|
||||
String.join("b", new CharSequence[] {"baz", "qux"}),
|
||||
String.join("b", new CharSequence[] {"foo", "bar"}),
|
||||
String.join("c", new String[] {"foo", "bar"}),
|
||||
String.join("d", new CharSequence[] {"baz", "qux"}),
|
||||
String.join("e", ImmutableList.of("foo", "bar")),
|
||||
String.join("f", Iterables.cycle(ImmutableList.of("foo", "bar"))),
|
||||
String.join("g", ImmutableList.of("baz", "qux")));
|
||||
String.join("d", ImmutableList.of("foo", "bar")),
|
||||
String.join("e", Iterables.cycle(ImmutableList.of("foo", "bar"))),
|
||||
String.join("f", ImmutableList.of("foo", "bar")));
|
||||
}
|
||||
|
||||
String testSubstringRemainder() {
|
||||
|
||||
@@ -28,7 +28,6 @@ final class TimeTemplatesTest implements RefasterTemplateTestCase {
|
||||
return ImmutableSet.of(
|
||||
ZoneId.of("GMT"),
|
||||
ZoneId.of("UTC"),
|
||||
ZoneId.of("Z"),
|
||||
ZoneId.of("+0"),
|
||||
ZoneId.of("-0"),
|
||||
ZoneOffset.UTC,
|
||||
|
||||
@@ -31,7 +31,6 @@ final class TimeTemplatesTest implements RefasterTemplateTestCase {
|
||||
ZoneOffset.UTC,
|
||||
ZoneOffset.UTC,
|
||||
ZoneOffset.UTC,
|
||||
ZoneOffset.UTC,
|
||||
ZoneOffset.UTC);
|
||||
}
|
||||
|
||||
|
||||
324
pom.xml
324
pom.xml
@@ -17,7 +17,7 @@
|
||||
</organization>
|
||||
<licenses>
|
||||
<license>
|
||||
<name>MIT License</name>
|
||||
<name>MIT</name>
|
||||
<url>https://opensource.org/licenses/mit-license.php</url>
|
||||
<distribution>repo</distribution>
|
||||
</license>
|
||||
@@ -35,6 +35,7 @@
|
||||
<modules>
|
||||
<module>error-prone-contrib</module>
|
||||
<module>refaster-resource-compiler</module>
|
||||
<module>refaster-support</module>
|
||||
</modules>
|
||||
|
||||
<scm>
|
||||
@@ -73,10 +74,7 @@
|
||||
-XX:TieredStopAtLevel=1
|
||||
<!-- We cap memory usage. This is especially relevant on Travis CI,
|
||||
but locally this should also be more than enough. -->
|
||||
<!-- XXX: RefasterCheckTest` requires more memory, so here we use
|
||||
more than in other projects. Review how to reconcile this. (Extra
|
||||
property?) -->
|
||||
-Xmx1024m
|
||||
-Xmx512m
|
||||
<!-- This argument cannot be set through Surefire's
|
||||
'systemPropertyVariables' configuration setting. Setting the file
|
||||
encoding is necessary because forked unit test invocations
|
||||
@@ -99,9 +97,10 @@
|
||||
build number. When building locally, this number is obviously absent.
|
||||
So we provide a default value. -->
|
||||
<build.number>LOCAL</build.number>
|
||||
<!-- Property using which additional Error Prone flags can be
|
||||
specified. Used by the `patch` profile to enable patching. -->
|
||||
<error-prone.args />
|
||||
<!-- Properties using which additional Error Prone flags can be
|
||||
specified. Used by the `patch` and `self-check` profiles. -->
|
||||
<error-prone.patch-args />
|
||||
<error-prone.self-check-args />
|
||||
<!-- The Maven `groupId` under which Error Prone dependencies are
|
||||
published. By default we use an official Error Prone release. This
|
||||
property allows the `error-prone-fork` profile below to build the
|
||||
@@ -111,15 +110,27 @@
|
||||
<!-- Dependency and plugin versions that are referenced in more than
|
||||
one place. We use these to keep dependencies in sync. Version numbers
|
||||
that need to be referenced only once should *not* be listed here. -->
|
||||
<version.auto-service>1.0-rc7</version.auto-service>
|
||||
<version.error-prone>2.4.0</version.error-prone>
|
||||
<version.auto-service>1.0</version.auto-service>
|
||||
<version.error-prone>${version.error-prone-orig}</version.error-prone>
|
||||
<version.error-prone-fork>v${version.error-prone-orig}-picnic-1</version.error-prone-fork>
|
||||
<version.error-prone-orig>2.8.0</version.error-prone-orig>
|
||||
<version.error-prone-slf4j>0.1.4</version.error-prone-slf4j>
|
||||
<version.findbugs-format-string>3.0.0</version.findbugs-format-string>
|
||||
<version.guava-beta-checker>1.0</version.guava-beta-checker>
|
||||
<version.jdk>11</version.jdk>
|
||||
<version.maven>3.6.3</version.maven>
|
||||
<version.mockito>3.7.0</version.mockito>
|
||||
<version.mockito>3.11.2</version.mockito>
|
||||
<version.nopen-checker>1.0.1</version.nopen-checker>
|
||||
<version.nullaway>0.8.0</version.nullaway>
|
||||
<version.nullaway>0.9.1</version.nullaway>
|
||||
<!-- XXX: Two other dependencies are potentially of interest:
|
||||
`com.palantir.assertj-automation:assertj-refaster-rules` and
|
||||
`com.palantir.baseline:baseline-refaster-rules` contain Refaster rules
|
||||
which aren't currently applied. We should use
|
||||
`RefasterRuleBuilderScanner` to convert those to `.refaster` files so
|
||||
that we can pick them up. (But in case of `baseline-refaster-rules`
|
||||
perhaps we can simply incorporate all of them.) -->
|
||||
<version.palantir-assertj-automation>0.2.1</version.palantir-assertj-automation>
|
||||
<version.palantir-baseline>4.7.0</version.palantir-baseline>
|
||||
<version.surefire>2.22.2</version.surefire>
|
||||
</properties>
|
||||
|
||||
@@ -155,17 +166,22 @@
|
||||
<artifactId>refaster-resource-compiler</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>refaster-support</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson</groupId>
|
||||
<artifactId>jackson-bom</artifactId>
|
||||
<version>2.12.1</version>
|
||||
<version>2.12.4</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.auto</groupId>
|
||||
<artifactId>auto-common</artifactId>
|
||||
<version>0.11</version>
|
||||
<version>1.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.auto.service</groupId>
|
||||
@@ -175,7 +191,14 @@
|
||||
<dependency>
|
||||
<groupId>com.google.auto.value</groupId>
|
||||
<artifactId>auto-value-annotations</artifactId>
|
||||
<version>1.7.4</version>
|
||||
<version>1.8.2</version>
|
||||
</dependency>
|
||||
<!-- Specified as a workaround for
|
||||
https://github.com/mojohaus/versions-maven-plugin/issues/244. -->
|
||||
<dependency>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>jFormatString</artifactId>
|
||||
<version>${version.findbugs-format-string}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
@@ -197,7 +220,7 @@
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava-bom</artifactId>
|
||||
<version>30.1-jre</version>
|
||||
<version>30.1.1-jre</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -215,6 +238,20 @@
|
||||
</dependency>
|
||||
<!-- Specified as a workaround for
|
||||
https://github.com/mojohaus/versions-maven-plugin/issues/244. -->
|
||||
<dependency>
|
||||
<groupId>com.palantir.assertj-automation</groupId>
|
||||
<artifactId>assertj-error-prone</artifactId>
|
||||
<version>${version.palantir-assertj-automation}</version>
|
||||
</dependency>
|
||||
<!-- Specified as a workaround for
|
||||
https://github.com/mojohaus/versions-maven-plugin/issues/244. -->
|
||||
<dependency>
|
||||
<groupId>com.palantir.baseline</groupId>
|
||||
<artifactId>baseline-error-prone</artifactId>
|
||||
<version>${version.palantir-baseline}</version>
|
||||
</dependency>
|
||||
<!-- Specified as a workaround for
|
||||
https://github.com/mojohaus/versions-maven-plugin/issues/244. -->
|
||||
<dependency>
|
||||
<groupId>com.uber.nullaway</groupId>
|
||||
<artifactId>nullaway</artifactId>
|
||||
@@ -223,14 +260,14 @@
|
||||
<dependency>
|
||||
<groupId>io.projectreactor</groupId>
|
||||
<artifactId>reactor-bom</artifactId>
|
||||
<version>2020.0.3</version>
|
||||
<version>2020.0.9</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.reactivex.rxjava2</groupId>
|
||||
<artifactId>rxjava</artifactId>
|
||||
<version>2.2.20</version>
|
||||
<version>2.2.21</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.swagger</groupId>
|
||||
@@ -240,7 +277,12 @@
|
||||
<dependency>
|
||||
<groupId>io.swagger.core.v3</groupId>
|
||||
<artifactId>swagger-annotations</artifactId>
|
||||
<version>2.1.6</version>
|
||||
<version>2.1.10</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.servlet</groupId>
|
||||
<artifactId>jakarta.servlet-api</artifactId>
|
||||
<version>4.0.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
@@ -257,22 +299,22 @@
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13.1</version>
|
||||
<version>4.13.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
<version>1.9.6</version>
|
||||
<version>1.9.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>3.18.1</version>
|
||||
<version>3.20.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.checkerframework</groupId>
|
||||
<artifactId>checker-qual</artifactId>
|
||||
<version>3.9.1</version>
|
||||
<version>3.16.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
@@ -282,7 +324,7 @@
|
||||
<dependency>
|
||||
<groupId>org.junit</groupId>
|
||||
<artifactId>junit-bom</artifactId>
|
||||
<version>5.7.0</version>
|
||||
<version>5.7.2</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -299,19 +341,19 @@
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.30</version>
|
||||
<version>1.7.32</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>5.3.3</version>
|
||||
<version>5.3.9</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testng</groupId>
|
||||
<artifactId>testng</artifactId>
|
||||
<version>7.3.0</version>
|
||||
<version>7.4.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
@@ -327,7 +369,7 @@
|
||||
<plugin>
|
||||
<groupId>com.github.ekryd.sortpom</groupId>
|
||||
<artifactId>sortpom-maven-plugin</artifactId>
|
||||
<version>2.12.0</version>
|
||||
<version>3.0.0</version>
|
||||
<configuration>
|
||||
<createBackupFile>false</createBackupFile>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
@@ -335,6 +377,7 @@
|
||||
<nrOfIndentSpace>4</nrOfIndentSpace>
|
||||
<predefinedSortOrder>recommended_2008_06</predefinedSortOrder>
|
||||
<sortDependencies>groupId,artifactId</sortDependencies>
|
||||
<sortDependencyExclusions>groupId,artifactId</sortDependencyExclusions>
|
||||
<sortModules>true</sortModules>
|
||||
<sortPlugins>groupId,artifactId</sortPlugins>
|
||||
<sortProperties>true</sortProperties>
|
||||
@@ -424,7 +467,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<version>3.1.1</version>
|
||||
<version>3.1.2</version>
|
||||
<configuration>
|
||||
<checkstyleRules>
|
||||
<!-- We only enable rules that are not enforced by
|
||||
@@ -495,19 +538,12 @@
|
||||
<property name="ignoreSetter" value="true" />
|
||||
<property name="setterCanReturnItsClass" value="true" />
|
||||
</module>
|
||||
<module name="IllegalIdentifierName" />
|
||||
<module name="IllegalImport">
|
||||
<property name="illegalClasses" value="com.google.api.client.util.Preconditions">
|
||||
<!-- Instead, please use
|
||||
`com.google.common.base.Preconditions`. -->
|
||||
</property>
|
||||
<property name="illegalClasses" value="com.mongodb.lang.Nullable">
|
||||
<!-- Instead, please use
|
||||
`javax.annotation.Nullable`. -->
|
||||
</property>
|
||||
<property name="illegalClasses" value="com.nimbusds.jose.util.StandardCharset">
|
||||
<!-- Instead, please use
|
||||
`java.nio.charset.StandardCharsets`. -->
|
||||
</property>
|
||||
<property name="illegalClasses" value="io.micrometer.core.lang.Nullable">
|
||||
<!-- Instead, please use
|
||||
`javax.annotation.Nullable`. -->
|
||||
@@ -516,11 +552,6 @@
|
||||
<!-- Instead, please use
|
||||
`com.google.errorprone.annotations.Immutable`. -->
|
||||
</property>
|
||||
<property name="illegalClasses" value="javax.xml.bind.DatatypeConverter" />
|
||||
<property name="illegalClasses" value="org.assertj.core.util.Preconditions">
|
||||
<!-- Instead, please use
|
||||
`com.google.common.base.Preconditions`. -->
|
||||
</property>
|
||||
<property name="illegalClasses" value="org.jetbrains.annotations.VisibleForTesting">
|
||||
<!-- Instead, please use
|
||||
`com.google.common.annotations.VisibleForTesting`. -->
|
||||
@@ -561,7 +592,23 @@
|
||||
this config can be merged into the one
|
||||
above. See
|
||||
https://github.com/checkstyle/checkstyle/issues/4954. -->
|
||||
<property name="illegalClasses" value="org\.testng\.AssertJUnit(\..*?)?" />
|
||||
<property name="illegalClasses" value="com\.google\.api\.client\.util\.Preconditions(\..*?)?">
|
||||
<!-- Instead, please use
|
||||
`com.google.common.base.Preconditions`. -->
|
||||
</property>
|
||||
<property name="illegalClasses" value="com\.nimbusds\.jose\.util\.StandardCharset(\..*?)?">
|
||||
<!-- Instead, please use
|
||||
`java.nio.charset.StandardCharsets`. -->
|
||||
</property>
|
||||
<property name="illegalClasses" value="javax\.xml\.bind\.DatatypeConverter(\..*?)?" />
|
||||
<property name="illegalClasses" value="org\.assertj\.core\.util\.Preconditions(\..*?)?">
|
||||
<!-- Instead, please use
|
||||
`com.google.common.base.Preconditions`. -->
|
||||
</property>
|
||||
<property name="illegalClasses" value="org\.junit\.jupiter\.api\.Assertions(\..*?)?">
|
||||
<!-- Instead, please use
|
||||
`org.assertj.core.api.Assertions`. -->
|
||||
</property>
|
||||
<property name="illegalClasses" value="org\.springframework\.stereotype\.(Component|Controller|Service)">
|
||||
<!-- We don't use Spring's
|
||||
component scanning, so `@Component`
|
||||
@@ -569,6 +616,14 @@
|
||||
Instead of `@Controller` use
|
||||
`@RestController`. -->
|
||||
</property>
|
||||
<property name="illegalClasses" value="org\.springframework\.util\.Assert(\..*?)?">
|
||||
<!-- Instead, please use
|
||||
`com.google.common.base.Preconditions`. -->
|
||||
</property>
|
||||
<property name="illegalClasses" value="org\.testng\.AssertJUnit(\..*?)?">
|
||||
<!-- Instead, please use
|
||||
`com.google.common.base.Preconditions`. -->
|
||||
</property>
|
||||
<property name="regexp" value="true" />
|
||||
</module>
|
||||
<module name="IllegalCatch" />
|
||||
@@ -620,7 +675,7 @@
|
||||
<dependency>
|
||||
<groupId>com.puppycrawl.tools</groupId>
|
||||
<artifactId>checkstyle</artifactId>
|
||||
<version>8.39</version>
|
||||
<version>8.41.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
@@ -704,7 +759,18 @@
|
||||
</requireMavenVersion>
|
||||
<requirePluginVersions />
|
||||
<requireSameVersionsReactor />
|
||||
<requireUpperBoundDeps />
|
||||
<requireUpperBoundDeps>
|
||||
<excludes>
|
||||
<!-- XXX:
|
||||
`com.google.errorprone:error_prone_test_helpers`
|
||||
pulls in a more recent version of Truth
|
||||
than
|
||||
`com.google.testing.compile:compile-testing`,
|
||||
but the latter is incompatible with said
|
||||
never version. -->
|
||||
<exclude>com.google.truth:truth</exclude>
|
||||
</excludes>
|
||||
</requireUpperBoundDeps>
|
||||
</rules>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
@@ -726,7 +792,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
<version>1.6</version>
|
||||
<version>3.0.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>sign-artifacts</id>
|
||||
@@ -770,7 +836,14 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0</version>
|
||||
<configuration>
|
||||
<!-- All relevant doclint checks are performed during
|
||||
the compilation phase; no need to recheck during
|
||||
Javadoc generation. -->
|
||||
<doclint>none</doclint>
|
||||
<source>${version.jdk}</source>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>generate-javadoc-jar</id>
|
||||
@@ -910,6 +983,7 @@
|
||||
BSD-3-Clause
|
||||
| 3-Clause BSD License
|
||||
| BSD 3-clause
|
||||
| Eclipse Distribution License (New BSD License)
|
||||
| New BSD License
|
||||
</licenseMerge>
|
||||
<licenseMerge>
|
||||
@@ -932,6 +1006,7 @@
|
||||
<licenseMerge>
|
||||
<!-- -->
|
||||
EPL-2.0
|
||||
| Eclipse Public License - v 2.0
|
||||
| Eclipse Public License v2.0
|
||||
</licenseMerge>
|
||||
<licenseMerge>
|
||||
@@ -975,7 +1050,7 @@
|
||||
<plugin>
|
||||
<groupId>org.gaul</groupId>
|
||||
<artifactId>modernizer-maven-plugin</artifactId>
|
||||
<version>2.1.0</version>
|
||||
<version>2.2.0</version>
|
||||
<configuration>
|
||||
<exclusionPatterns>
|
||||
<!-- The plugin suggests replacing Guava's
|
||||
@@ -1007,14 +1082,14 @@
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>0.8.6</version>
|
||||
<version>0.8.7</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.pitest</groupId>
|
||||
<artifactId>pitest-maven</artifactId>
|
||||
<version>1.6.2</version>
|
||||
<version>1.6.7</version>
|
||||
<configuration>
|
||||
<!-- Use multple threads to speed things up. Extend
|
||||
<!-- Use multiple threads to speed things up. Extend
|
||||
timeouts to prevent false positives as a result of
|
||||
contention. -->
|
||||
<threads>4</threads>
|
||||
@@ -1025,7 +1100,7 @@
|
||||
<dependency>
|
||||
<groupId>org.pitest</groupId>
|
||||
<artifactId>pitest-junit5-plugin</artifactId>
|
||||
<version>0.12</version>
|
||||
<version>0.14</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
@@ -1040,7 +1115,7 @@
|
||||
<plugin>
|
||||
<groupId>org.sonarsource.scanner.maven</groupId>
|
||||
<artifactId>sonar-maven-plugin</artifactId>
|
||||
<version>3.8.0.2131</version>
|
||||
<version>3.9.0.2155</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
@@ -1061,7 +1136,7 @@
|
||||
<id>error-prone-fork</id>
|
||||
<properties>
|
||||
<groupId.error-prone>com.github.PicnicSupermarket.error-prone</groupId.error-prone>
|
||||
<version.error-prone>v2.4.0-picnic-3</version.error-prone>
|
||||
<version.error-prone>${version.error-prone-fork}</version.error-prone>
|
||||
</properties>
|
||||
<dependencyManagement>
|
||||
<!-- Even when we directly depend on the Picnic Error Prone
|
||||
@@ -1072,7 +1147,7 @@
|
||||
<dependency>
|
||||
<groupId>com.google.errorprone</groupId>
|
||||
<artifactId>error_prone_annotations</artifactId>
|
||||
<version>2.4.0</version>
|
||||
<version>${version.error-prone-orig}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
@@ -1081,21 +1156,11 @@
|
||||
<!-- Error Prone checks which are not availabe from Maven Central;
|
||||
these are therefore not enabled by default. -->
|
||||
<id>non-maven-central</id>
|
||||
<!-- XXX: Two other dependencies are potentially of interest:
|
||||
`com.palantir.assertj-automation:assertj-refaster-rules` and
|
||||
`com.palantir.baseline:baseline-refaster-rules` contain Refaster
|
||||
rules which aren't currently applied. We should use
|
||||
`RefasterRuleBuilderScanner` to convert those to `.refaster` files
|
||||
so that we can pick them up. (But in case of
|
||||
`baseline-refaster-rules` perhaps we can simply incorporate all of
|
||||
them.) -->
|
||||
<properties>
|
||||
<version.palantir-assertj-automation>0.2.1</version.palantir-assertj-automation>
|
||||
<version.palantir-baseline>3.63.3</version.palantir-baseline>
|
||||
<version.reactor-error-prone>0.1.4</version.reactor-error-prone>
|
||||
</properties>
|
||||
<dependencyManagement>
|
||||
<!-- All these dependencies are specified as a workaround for
|
||||
<!-- Specified as a workaround for
|
||||
https://github.com/mojohaus/versions-maven-plugin/issues/244. -->
|
||||
<dependencies>
|
||||
<dependency>
|
||||
@@ -1103,16 +1168,6 @@
|
||||
<artifactId>reactor-error-prone</artifactId>
|
||||
<version>${version.reactor-error-prone}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.palantir.assertj-automation</groupId>
|
||||
<artifactId>assertj-error-prone</artifactId>
|
||||
<version>${version.palantir-assertj-automation}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.palantir.baseline</groupId>
|
||||
<artifactId>baseline-error-prone</artifactId>
|
||||
<version>${version.palantir-baseline}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
<build>
|
||||
@@ -1127,22 +1182,39 @@
|
||||
<artifactId>reactor-error-prone</artifactId>
|
||||
<version>${version.reactor-error-prone}</version>
|
||||
</path>
|
||||
<!-- XXX: Before enabling these checks we'll
|
||||
need to resolve some violations. Some of the
|
||||
checks will need to be disabled; check how to
|
||||
best do this, given that this configuration is
|
||||
defined in an optional profile.
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<!-- Applies the Error Prone checks defined by this project to the
|
||||
code base itself. Assumes that a prior build has already installed
|
||||
the project in the local Maven repository. -->
|
||||
<id>self-check</id>
|
||||
<properties>
|
||||
<!-- XXX: `MethodReferenceUsage` is an extremely expensive
|
||||
check due to its use of `SuggestedFixes.compilesWithFix`. Maybe
|
||||
we should drop it altogether? -->
|
||||
<!-- XXX: Find a way to assert that test code (both inline
|
||||
`BugChecker` test code and the Refaster test files) does not
|
||||
exhibit anti-patterns other than those associated with the
|
||||
check/template under test. Ideally all test cases are realistic. -->
|
||||
<error-prone.self-check-args>-Xep:MethodReferenceUsage:OFF</error-prone.self-check-args>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<annotationProcessorPaths combine.children="append">
|
||||
<path>
|
||||
<groupId>com.palantir.assertj-automation</groupId>
|
||||
<artifactId>assertj-error-prone</artifactId>
|
||||
<version>${version.palantir-assertj-automation}</version>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>error-prone-contrib</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</path>
|
||||
<path>
|
||||
<groupId>com.palantir.baseline</groupId>
|
||||
<artifactId>baseline-error-prone</artifactId>
|
||||
<version>${version.palantir-baseline}</version>
|
||||
</path>
|
||||
-->
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
@@ -1284,11 +1356,24 @@
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<annotationProcessorPaths combine.children="append">
|
||||
<path>
|
||||
<groupId>${groupId.error-prone}</groupId>
|
||||
<artifactId>error_prone_annotations</artifactId>
|
||||
<version>${version.error-prone}</version>
|
||||
</path>
|
||||
<path>
|
||||
<groupId>${groupId.error-prone}</groupId>
|
||||
<artifactId>error_prone_core</artifactId>
|
||||
<version>${version.error-prone}</version>
|
||||
</path>
|
||||
<!-- This is a dependency of some Error Prone
|
||||
plugins, but for licensing reasons it is not
|
||||
packaged with the artifact. -->
|
||||
<path>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>jFormatString</artifactId>
|
||||
<version>${version.findbugs-format-string}</version>
|
||||
</path>
|
||||
<path>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava-beta-checker</artifactId>
|
||||
@@ -1299,6 +1384,20 @@
|
||||
<artifactId>nopen-checker</artifactId>
|
||||
<version>${version.nopen-checker}</version>
|
||||
</path>
|
||||
<!-- XXX: Before enabling these plugins we'll
|
||||
need to resolve some violations. Some of the
|
||||
checks will need to be disabled.
|
||||
<path>
|
||||
<groupId>com.palantir.assertj-automation</groupId>
|
||||
<artifactId>assertj-error-prone</artifactId>
|
||||
<version>${version.palantir-assertj-automation}</version>
|
||||
</path>
|
||||
-->
|
||||
<path>
|
||||
<groupId>com.palantir.baseline</groupId>
|
||||
<artifactId>baseline-error-prone</artifactId>
|
||||
<version>${version.palantir-baseline}</version>
|
||||
</path>
|
||||
<path>
|
||||
<groupId>com.uber.nullaway</groupId>
|
||||
<artifactId>nullaway</artifactId>
|
||||
@@ -1336,16 +1435,47 @@
|
||||
-Xep:BetaApi:OFF
|
||||
<!-- We don't target JDK 7. -->
|
||||
-Xep:Java7ApiChecker:OFF
|
||||
<!-- Too many false positives for now. See
|
||||
https://github.com/google/error-prone/issues/1610 and
|
||||
https://github.com/google/error-prone/issues/1646. -->
|
||||
-Xep:JdkObsolete:OFF
|
||||
<!-- We don't target Android. -->
|
||||
-Xep:StaticOrDefaultInterfaceMethod:OFF
|
||||
<!--
|
||||
Flags for `baseline-error-prone`.
|
||||
-->
|
||||
<!-- We prefer to name loggers name `LOG`,
|
||||
rather than `log`. -->
|
||||
-Xep:ConsistentLoggerName:OFF
|
||||
<!-- XXX: This check discourages use of
|
||||
parallel streams, which is good, but also
|
||||
suggests a Palantir alternative. Consider
|
||||
introducing a similar but less opinionated
|
||||
check. -->
|
||||
-Xep:DangerousParallelStreamUsage:OFF
|
||||
<!-- Nice idea, but too expensive due to
|
||||
(recursive) invocation of
|
||||
`SuggestedFixes.compilesWithFix`. -->
|
||||
-Xep:LambdaMethodReference:OFF
|
||||
<!-- We don't use Palantir's `safe-logging`
|
||||
library. -->
|
||||
-Xep:PreferSafeLoggingPreconditions:OFF
|
||||
<!-- We don't use Palantir's `safe-logging`
|
||||
library. -->
|
||||
-Xep:Slf4jLogsafeArgs:OFF
|
||||
<!-- XXX: This check suggests prefixing
|
||||
unused parameters with an underscore.
|
||||
Discuss this idea within the team. -->
|
||||
-Xep:StrictUnusedVariable:OFF
|
||||
<!-- Ideally `@VisibleForTesting` members
|
||||
are package-private, but there are
|
||||
reasonable exceptions. -->
|
||||
-Xep:VisibleForTestingPackagePrivate:OFF
|
||||
<!--
|
||||
Flags for `nullaway`.
|
||||
-->
|
||||
-XepOpt:NullAway:AnnotatedPackages=tech.picnic
|
||||
-XepOpt:NullAway:AssertsEnabled=true
|
||||
-XepOpt:NullAway:CheckOptionalEmptiness=true
|
||||
<!-- Append additional custom arguments. -->
|
||||
${error-prone.args}
|
||||
${error-prone.patch-args}
|
||||
${error-prone.self-check-args}
|
||||
</arg>
|
||||
<!-- The Error Prone plugin makes certain
|
||||
assumptions about the state of the AST at the
|
||||
@@ -1371,7 +1501,7 @@
|
||||
</property>
|
||||
</activation>
|
||||
<properties>
|
||||
<error-prone.args>-XepPatchChecks:${error-prone.patch-checks} -XepPatchLocation:IN_PLACE</error-prone.args>
|
||||
<error-prone.patch-args>-XepPatchChecks:${error-prone.patch-checks} -XepPatchLocation:IN_PLACE</error-prone.patch-args>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
@@ -1494,7 +1624,7 @@
|
||||
compiler. The following `add-exports` arguments are not necessary
|
||||
for the code to compile because `com.google.errorprone:javac` is on
|
||||
the classpath. In fact, enabling this profile when building with
|
||||
Maven on the command line with cause a build failure, because these
|
||||
Maven on the command line will cause a build failure, because these
|
||||
flags are incompatible with the `release` flag. This profile exists
|
||||
solely to be enabled within an IDE: without them IntelliJ IDEA
|
||||
reports compilation errors. -->
|
||||
|
||||
@@ -14,6 +14,11 @@
|
||||
<description>Java Compiler Plugin which identifies and compiles Refaster templates, storing them as resource files on the classpath.</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${groupId.error-prone}</groupId>
|
||||
<artifactId>error_prone_annotations</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${groupId.error-prone}</groupId>
|
||||
<artifactId>error_prone_check_api</artifactId>
|
||||
@@ -27,6 +32,11 @@
|
||||
<artifactId>auto-service-annotations</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>jsr305</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.errorprone</groupId>
|
||||
<artifactId>javac</artifactId>
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
/** A {@code javac} plugin which compiles Refaster templates once their Java code is compiled. */
|
||||
@com.google.errorprone.annotations.CheckReturnValue
|
||||
@javax.annotation.ParametersAreNonnullByDefault
|
||||
package tech.picnic.errorprone.refaster.plugin;
|
||||
70
refaster-support/pom.xml
Normal file
70
refaster-support/pom.xml
Normal file
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>refaster-support</artifactId>
|
||||
|
||||
<name>Picnic :: Error Prone Support :: Refaster Support</name>
|
||||
<description>Helper utilities for use with Refaster templates.</description>
|
||||
|
||||
<dependencies>
|
||||
<!-- This dependency is listed out-of-order so as not to confuse the
|
||||
`maven-dependency-plugin` when the `error-prone-fork` profile is
|
||||
enabled: the `error_prone_annotation` dependency pulls in the
|
||||
non-forked `error_prone_annotations` artifact through a dependency on
|
||||
Guava. -->
|
||||
<?SORTPOM IGNORE?>
|
||||
<dependency>
|
||||
<groupId>${groupId.error-prone}</groupId>
|
||||
<artifactId>error_prone_annotations</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<?SORTPOM RESUME?>
|
||||
<dependency>
|
||||
<groupId>${groupId.error-prone}</groupId>
|
||||
<artifactId>error_prone_annotation</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${groupId.error-prone}</groupId>
|
||||
<artifactId>error_prone_check_api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${groupId.error-prone}</groupId>
|
||||
<artifactId>error_prone_core</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${groupId.error-prone}</groupId>
|
||||
<artifactId>error_prone_test_helpers</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>jsr305</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.errorprone</groupId>
|
||||
<artifactId>javac</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user