mirror of
https://github.com/jlengrand/error-prone-support.git
synced 2026-03-10 15:49:33 +00:00
Compare commits
85 Commits
rossendrij
...
sschroever
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
689eac7c8d | ||
|
|
7c3abaec21 | ||
|
|
d260112bed | ||
|
|
a074e2fdd6 | ||
|
|
f06d4e41cf | ||
|
|
cf7bb657fa | ||
|
|
8277b43955 | ||
|
|
691f2c8311 | ||
|
|
362518b0f4 | ||
|
|
b9a3840e25 | ||
|
|
14d8bddbec | ||
|
|
6c7a0b81ea | ||
|
|
3a3825f7ba | ||
|
|
31e54cc990 | ||
|
|
775a2688ca | ||
|
|
3d854a0cc5 | ||
|
|
6ee013da58 | ||
|
|
962d18dcb5 | ||
|
|
aab308a190 | ||
|
|
009bd5d0d7 | ||
|
|
8e57f64e31 | ||
|
|
53e81f3611 | ||
|
|
8745105251 | ||
|
|
3eb3c20b1d | ||
|
|
121618f277 | ||
|
|
5cf4194168 | ||
|
|
c434cd318c | ||
|
|
22aa9cb213 | ||
|
|
3edc483e7c | ||
|
|
fff5d7b329 | ||
|
|
4ca80952ab | ||
|
|
8cecb8bf30 | ||
|
|
a937bf0ddf | ||
|
|
0b71c2b576 | ||
|
|
239d38d69f | ||
|
|
ab57aa5eb6 | ||
|
|
49267337cb | ||
|
|
c201fe1fd2 | ||
|
|
fb20b6f93d | ||
|
|
9264c25b57 | ||
|
|
ca628eef6c | ||
|
|
62168dcd4b | ||
|
|
96a82eaf85 | ||
|
|
0c615b4c15 | ||
|
|
6304130ae3 | ||
|
|
1674e99ba4 | ||
|
|
75bbc8e5b5 | ||
|
|
fe3ed2be63 | ||
|
|
f36350f3ba | ||
|
|
4888ad3aaf | ||
|
|
9daf73f148 | ||
|
|
b08ca514c1 | ||
|
|
4eed7dd0e8 | ||
|
|
618c62e7a5 | ||
|
|
b46f075ddf | ||
|
|
64436ff9b6 | ||
|
|
e028077f1e | ||
|
|
5aa386b5ba | ||
|
|
a480fe908d | ||
|
|
b2316c744c | ||
|
|
9334babfe8 | ||
|
|
b6632d393b | ||
|
|
53d191ff4f | ||
|
|
b8ddf3ac20 | ||
|
|
e859c2774f | ||
|
|
1cb4ce97ae | ||
|
|
92fe96286f | ||
|
|
d7531abceb | ||
|
|
cc7074a62f | ||
|
|
91922454b6 | ||
|
|
eaa98c985c | ||
|
|
94908d6a37 | ||
|
|
e8d9221424 | ||
|
|
fea8f5b2c0 | ||
|
|
2199accedc | ||
|
|
83670aeddf | ||
|
|
e8977bea67 | ||
|
|
0d051064bb | ||
|
|
06913b6a5b | ||
|
|
d2bbee3ed9 | ||
|
|
793a70c29b | ||
|
|
63b4fae185 | ||
|
|
73f8f056b4 | ||
|
|
c1638066cd | ||
|
|
08e99fb54e |
@@ -276,10 +276,6 @@ Refaster's expressiveness:
|
||||
to be lost. In such a case don't statically import the method, so that the
|
||||
generic type information can be retained. (There may be cases where generic
|
||||
type information should even be _added_. Find an example.)
|
||||
- Upon application of a template Refaster can throw a _No binding for
|
||||
Key{identifier=someAfterTemplateParam}_ exception. When this happens the
|
||||
template is invalid. Instead perform this check at compile time, such that
|
||||
such malformed templates cannot be defined in the first place.
|
||||
- Provide a way to express "match if (not) annotated (with _X_)". See #1 for a
|
||||
motivating example.
|
||||
- Provide a way to place match constraints on compile time constants. For
|
||||
|
||||
@@ -39,9 +39,14 @@
|
||||
<artifactId>error_prone_test_helpers</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- XXX: dubious. -->
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>refaster-resource-compiler</artifactId>
|
||||
<artifactId>plexus-compiler-javac-caching</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>refaster-compiler</artifactId>
|
||||
<!-- This dependency is declared only as a hint to Maven that
|
||||
compilation depends on it; see the `maven-compiler-plugin`'s
|
||||
`annotationProcessorPaths` configuration below. -->
|
||||
@@ -56,6 +61,11 @@
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.auto</groupId>
|
||||
<artifactId>auto-common</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.auto.service</groupId>
|
||||
<artifactId>auto-service-annotations</artifactId>
|
||||
@@ -76,6 +86,11 @@
|
||||
<artifactId>guava</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.newrelic.agent.java</groupId>
|
||||
<artifactId>newrelic-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.projectreactor</groupId>
|
||||
<artifactId>reactor-core</artifactId>
|
||||
@@ -126,11 +141,6 @@
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-library</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
@@ -161,26 +171,11 @@
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webflux</artifactId>
|
||||
@@ -202,7 +197,7 @@
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.coveo</groupId>
|
||||
<groupId>com.spotify.fmt</groupId>
|
||||
<artifactId>fmt-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<additionalSourceDirectories>
|
||||
@@ -217,7 +212,7 @@
|
||||
<annotationProcessorPaths combine.children="append">
|
||||
<path>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>refaster-resource-compiler</artifactId>
|
||||
<artifactId>refaster-compiler</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</path>
|
||||
<path>
|
||||
@@ -227,7 +222,7 @@
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
<compilerArgs combine.children="append">
|
||||
<arg>-Xplugin:RefasterRuleResourceCompiler</arg>
|
||||
<arg>-Xplugin:RefasterRuleCompiler</arg>
|
||||
</compilerArgs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.BugPattern.LinkType.NONE;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.LIKELY_ERROR;
|
||||
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;
|
||||
@@ -27,9 +27,9 @@ import javax.lang.model.element.AnnotationValue;
|
||||
@BugPattern(
|
||||
name = "AmbiguousJsonCreator",
|
||||
summary = "`JsonCreator.Mode` should be set for single-argument creators",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.WARNING,
|
||||
tags = StandardTags.LIKELY_ERROR)
|
||||
linkType = NONE,
|
||||
severity = WARNING,
|
||||
tags = 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 =
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.BugPattern.LinkType.NONE;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.SIMPLIFICATION;
|
||||
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.isType;
|
||||
@@ -7,9 +10,6 @@ import static com.google.errorprone.matchers.Matchers.isType;
|
||||
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.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;
|
||||
@@ -28,9 +28,9 @@ import java.util.List;
|
||||
@BugPattern(
|
||||
name = "AutowiredConstructor",
|
||||
summary = "Omit `@Autowired` on a class' sole constructor, as it is redundant",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.SUGGESTION,
|
||||
tags = StandardTags.SIMPLIFICATION)
|
||||
linkType = NONE,
|
||||
severity = SUGGESTION,
|
||||
tags = SIMPLIFICATION)
|
||||
public final class AutowiredConstructorCheck extends BugChecker implements ClassTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final MultiMatcher<Tree, AnnotationTree> AUTOWIRED_ANNOTATION =
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.BugPattern.LinkType.NONE;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.SIMPLIFICATION;
|
||||
|
||||
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.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;
|
||||
@@ -30,9 +31,9 @@ import java.util.regex.Pattern;
|
||||
@BugPattern(
|
||||
name = "CanonicalAnnotationSyntax",
|
||||
summary = "Omit redundant syntax from annotation declarations",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.SUGGESTION,
|
||||
tags = StandardTags.SIMPLIFICATION)
|
||||
linkType = NONE,
|
||||
severity = SUGGESTION,
|
||||
tags = SIMPLIFICATION)
|
||||
public final class CanonicalAnnotationSyntaxCheck extends BugChecker
|
||||
implements AnnotationTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import com.google.common.hash.Hashing;
|
||||
import com.google.common.reflect.ClassPath;
|
||||
import java.io.IOException;
|
||||
|
||||
final class CodeTransformers {
|
||||
// XXX: Use.
|
||||
private static void foo(ClassPath.ResourceInfo resource) {
|
||||
try {
|
||||
resource.asByteSource().hash(Hashing.murmur3_32_fixed(0)).toString();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.BugPattern.LinkType.NONE;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.SIMPLIFICATION;
|
||||
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;
|
||||
@@ -7,9 +10,6 @@ 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.MethodTreeMatcher;
|
||||
@@ -28,9 +28,9 @@ import java.util.Optional;
|
||||
@BugPattern(
|
||||
name = "EmptyMethod",
|
||||
summary = "Empty method can likely be deleted",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.SUGGESTION,
|
||||
tags = StandardTags.SIMPLIFICATION)
|
||||
linkType = NONE,
|
||||
severity = SUGGESTION,
|
||||
tags = SIMPLIFICATION)
|
||||
public final class EmptyMethodCheck extends BugChecker implements MethodTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Matcher<Tree> PERMITTED_ANNOTATION =
|
||||
|
||||
@@ -2,6 +2,9 @@ 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.BugPattern.LinkType.NONE;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.FRAGILE_CODE;
|
||||
import static com.google.errorprone.matchers.method.MethodMatchers.staticMethod;
|
||||
import static java.util.stream.Collectors.collectingAndThen;
|
||||
|
||||
@@ -12,9 +15,6 @@ 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;
|
||||
@@ -37,9 +37,9 @@ import java.util.stream.Stream;
|
||||
@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)
|
||||
linkType = NONE,
|
||||
severity = WARNING,
|
||||
tags = FRAGILE_CODE)
|
||||
public final class ExplicitEnumOrderingCheck extends BugChecker
|
||||
implements MethodInvocationTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.BugPattern.LinkType.NONE;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.ERROR;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.LIKELY_ERROR;
|
||||
import static com.google.errorprone.matchers.method.MethodMatchers.instanceMethod;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
import com.google.errorprone.bugpatterns.BugChecker.MemberReferenceTreeMatcher;
|
||||
import com.google.errorprone.bugpatterns.BugChecker.MethodInvocationTreeMatcher;
|
||||
import com.google.errorprone.fixes.SuggestedFix;
|
||||
import com.google.errorprone.fixes.SuggestedFixes;
|
||||
import com.google.errorprone.matchers.Description;
|
||||
import com.google.errorprone.matchers.Matcher;
|
||||
import com.sun.source.tree.ExpressionTree;
|
||||
import com.sun.source.tree.MemberReferenceTree;
|
||||
import com.sun.source.tree.MethodInvocationTree;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
/**
|
||||
* A {@link BugChecker} which flags usages of {@link Flux#flatMap(Function)} and {@link
|
||||
* Flux#flatMapSequential(Function)}.
|
||||
*
|
||||
* <p>{@link Flux#flatMap(Function)} and {@link Flux#flatMapSequential(Function)} eagerly perform up
|
||||
* to {@link reactor.util.concurrent.Queues#SMALL_BUFFER_SIZE} subscriptions. Additionally, the
|
||||
* former interleaves values as they are emitted, yielding nondeterministic results. In most cases
|
||||
* {@link Flux#concatMap(Function)} should be preferred, as it produces consistent results and
|
||||
* avoids potentially saturating the thread pool on which subscription happens. If {@code
|
||||
* concatMap}'s single-subscription semantics are undesirable one should invoke a {@code flatMap} or
|
||||
* {@code flatMapSequential} overload with an explicit concurrency level.
|
||||
*
|
||||
* <p>NB: The rarely-used overload {@link Flux#flatMap(Function, Function, Supplier)} is not flagged
|
||||
* by this check because there is no clear alternative to point to.
|
||||
*/
|
||||
@AutoService(BugChecker.class)
|
||||
@BugPattern(
|
||||
name = "FluxFlatMapUsage",
|
||||
summary =
|
||||
"`Flux#flatMap` and `Flux#flatMapSequential` have subtle semantics; "
|
||||
+ "please use `Flux#concatMap` or explicitly specify the desired amount of concurrency",
|
||||
linkType = NONE,
|
||||
severity = ERROR,
|
||||
tags = LIKELY_ERROR)
|
||||
public final class FluxFlatMapUsageCheck extends BugChecker
|
||||
implements MethodInvocationTreeMatcher, MemberReferenceTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final String MAX_CONCURRENCY_ARG_NAME = "MAX_CONCURRENCY";
|
||||
private static final Matcher<ExpressionTree> FLUX_FLATMAP =
|
||||
instanceMethod()
|
||||
.onDescendantOf("reactor.core.publisher.Flux")
|
||||
.namedAnyOf("flatMap", "flatMapSequential")
|
||||
.withParameters(Function.class.getName());
|
||||
|
||||
@Override
|
||||
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
|
||||
if (!FLUX_FLATMAP.matches(tree, state)) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
return buildDescription(tree)
|
||||
.addFix(SuggestedFixes.renameMethodInvocation(tree, "concatMap", state))
|
||||
.addFix(
|
||||
SuggestedFix.builder()
|
||||
.postfixWith(
|
||||
Iterables.getOnlyElement(tree.getArguments()), ", " + MAX_CONCURRENCY_ARG_NAME)
|
||||
.build())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Description matchMemberReference(MemberReferenceTree tree, VisitorState state) {
|
||||
if (!FLUX_FLATMAP.matches(tree, state)) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
// Method references are expected to occur very infrequently; generating both variants of
|
||||
// suggested fixes is not worth the trouble.
|
||||
return describeMatch(tree);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.BugPattern.LinkType.NONE;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.SIMPLIFICATION;
|
||||
import static com.google.errorprone.matchers.Matchers.allOf;
|
||||
import static com.google.errorprone.matchers.Matchers.anyMethod;
|
||||
import static com.google.errorprone.matchers.Matchers.anyOf;
|
||||
@@ -10,9 +13,6 @@ import static java.util.stream.Collectors.joining;
|
||||
|
||||
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;
|
||||
@@ -50,9 +50,9 @@ import java.util.Optional;
|
||||
@BugPattern(
|
||||
name = "FormatStringConcatenation",
|
||||
summary = "Defer string concatenation to the invoked method",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.WARNING,
|
||||
tags = StandardTags.SIMPLIFICATION)
|
||||
linkType = NONE,
|
||||
severity = WARNING,
|
||||
tags = SIMPLIFICATION)
|
||||
public final class FormatStringConcatenationCheck extends BugChecker
|
||||
implements MethodInvocationTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
import static com.google.errorprone.BugPattern.LinkType.NONE;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.SIMPLIFICATION;
|
||||
import static com.google.errorprone.matchers.Matchers.anyOf;
|
||||
import static com.google.errorprone.matchers.Matchers.staticMethod;
|
||||
import static com.google.errorprone.suppliers.Suppliers.OBJECT_TYPE;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.google.common.primitives.Primitives;
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
import com.google.errorprone.bugpatterns.BugChecker.MethodInvocationTreeMatcher;
|
||||
import com.google.errorprone.bugpatterns.TypesWithUndefinedEquality;
|
||||
import com.google.errorprone.fixes.SuggestedFix;
|
||||
import com.google.errorprone.fixes.SuggestedFixes;
|
||||
import com.google.errorprone.matchers.Description;
|
||||
import com.google.errorprone.matchers.Matcher;
|
||||
import com.google.errorprone.util.ASTHelpers;
|
||||
import com.google.errorprone.util.ASTHelpers.TargetType;
|
||||
import com.sun.source.tree.ExpressionTree;
|
||||
import com.sun.source.tree.MethodInvocationTree;
|
||||
import com.sun.tools.javac.code.Type;
|
||||
import com.sun.tools.javac.code.Types;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/** A {@link BugChecker} that flags redundant identity conversions. */
|
||||
// XXX: Consider detecting cases where a flagged expression is passed to a method, and where removal
|
||||
// of the identify conversion would cause a different method overload to be selected. Depending on
|
||||
// the target method such a modification may change the code's semantics or performance.
|
||||
@AutoService(BugChecker.class)
|
||||
@BugPattern(
|
||||
name = "IdentityConversion",
|
||||
summary = "Avoid or clarify identity conversions",
|
||||
linkType = NONE,
|
||||
severity = WARNING,
|
||||
tags = SIMPLIFICATION)
|
||||
public final class IdentityConversionCheck extends BugChecker
|
||||
implements MethodInvocationTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Matcher<ExpressionTree> IS_CONVERSION_METHOD =
|
||||
anyOf(
|
||||
staticMethod()
|
||||
.onClassAny(
|
||||
"com.google.common.collect.ImmutableBiMap",
|
||||
"com.google.common.collect.ImmutableList",
|
||||
"com.google.common.collect.ImmutableListMultimap",
|
||||
"com.google.common.collect.ImmutableMap",
|
||||
"com.google.common.collect.ImmutableMultimap",
|
||||
"com.google.common.collect.ImmutableMultiset",
|
||||
"com.google.common.collect.ImmutableRangeMap",
|
||||
"com.google.common.collect.ImmutableRangeSet",
|
||||
"com.google.common.collect.ImmutableSet",
|
||||
"com.google.common.collect.ImmutableSetMultimap",
|
||||
"com.google.common.collect.ImmutableTable")
|
||||
.named("copyOf"),
|
||||
staticMethod()
|
||||
.onClassAny(
|
||||
Primitives.allWrapperTypes().stream()
|
||||
.map(Class::getName)
|
||||
.collect(toImmutableSet()))
|
||||
.named("valueOf"),
|
||||
staticMethod().onClass(String.class.getName()).named("valueOf"),
|
||||
staticMethod().onClass("reactor.adapter.rxjava.RxJava2Adapter"),
|
||||
staticMethod()
|
||||
.onClass("reactor.core.publisher.Flux")
|
||||
.namedAnyOf("concat", "firstWithSignal", "from", "merge"),
|
||||
staticMethod().onClass("reactor.core.publisher.Mono").namedAnyOf("from", "fromDirect"));
|
||||
|
||||
@Override
|
||||
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
|
||||
List<? extends ExpressionTree> arguments = tree.getArguments();
|
||||
if (arguments.size() != 1 || !IS_CONVERSION_METHOD.matches(tree, state)) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
ExpressionTree sourceTree = arguments.get(0);
|
||||
Type sourceType = ASTHelpers.getType(sourceTree);
|
||||
Type resultType = ASTHelpers.getType(tree);
|
||||
TargetType targetType = ASTHelpers.targetType(state);
|
||||
if (sourceType == null || resultType == null || targetType == null) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
if (!state.getTypes().isSameType(sourceType, resultType)
|
||||
&& !isConvertibleWithWellDefinedEquality(sourceType, targetType.type(), state)) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
return buildDescription(tree)
|
||||
.setMessage(
|
||||
"This method invocation appears redundant; remove it or suppress this warning and "
|
||||
+ "add a comment explaining its purpose")
|
||||
.addFix(SuggestedFix.replace(tree, Util.treeToString(sourceTree, state)))
|
||||
.addFix(SuggestedFixes.addSuppressWarnings(state, canonicalName()))
|
||||
.build();
|
||||
}
|
||||
|
||||
private static boolean isConvertibleWithWellDefinedEquality(
|
||||
Type sourceType, Type targetType, VisitorState state) {
|
||||
Types types = state.getTypes();
|
||||
return !types.isSameType(targetType, OBJECT_TYPE.get(state))
|
||||
&& types.isConvertible(sourceType, targetType)
|
||||
&& Arrays.stream(TypesWithUndefinedEquality.values())
|
||||
.noneMatch(b -> b.matchesType(sourceType, state) || b.matchesType(targetType, state));
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,17 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.BugPattern.LinkType.NONE;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.SIMPLIFICATION;
|
||||
import static com.google.errorprone.matchers.ChildMultiMatcher.MatchType.AT_LEAST_ONE;
|
||||
import static com.google.errorprone.matchers.Matchers.allOf;
|
||||
import static com.google.errorprone.matchers.Matchers.annotations;
|
||||
import static com.google.errorprone.matchers.Matchers.anyOf;
|
||||
import static com.google.errorprone.matchers.Matchers.enclosingClass;
|
||||
import static com.google.errorprone.matchers.Matchers.hasModifier;
|
||||
import static com.google.errorprone.matchers.Matchers.isType;
|
||||
import static java.util.function.Predicate.not;
|
||||
import static tech.picnic.errorprone.bugpatterns.JavaKeywords.isReservedKeyword;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
@@ -16,14 +23,19 @@ import com.google.errorprone.fixes.SuggestedFix;
|
||||
import com.google.errorprone.fixes.SuggestedFixes;
|
||||
import com.google.errorprone.matchers.Description;
|
||||
import com.google.errorprone.matchers.Matcher;
|
||||
import com.google.errorprone.matchers.Matchers;
|
||||
import com.google.errorprone.matchers.MultiMatcher;
|
||||
import com.google.errorprone.predicates.TypePredicate;
|
||||
import com.google.errorprone.util.ASTHelpers;
|
||||
import com.sun.source.tree.AnnotationTree;
|
||||
import com.sun.source.tree.ClassTree;
|
||||
import com.sun.source.tree.ImportTree;
|
||||
import com.sun.source.tree.MethodTree;
|
||||
import com.sun.source.tree.Tree;
|
||||
import com.sun.tools.javac.code.Symbol;
|
||||
import java.util.Optional;
|
||||
import javax.lang.model.element.Modifier;
|
||||
import javax.lang.model.element.Name;
|
||||
|
||||
/** A {@link BugChecker} which flags non-canonical JUnit method declarations. */
|
||||
// XXX: Consider introducing a class-level check which enforces that test classes:
|
||||
@@ -35,16 +47,21 @@ import javax.lang.model.element.Modifier;
|
||||
@BugPattern(
|
||||
name = "JUnitMethodDeclaration",
|
||||
summary = "JUnit method declaration can likely be improved",
|
||||
linkType = BugPattern.LinkType.NONE,
|
||||
severity = BugPattern.SeverityLevel.SUGGESTION,
|
||||
tags = BugPattern.StandardTags.SIMPLIFICATION)
|
||||
linkType = NONE,
|
||||
severity = SUGGESTION,
|
||||
tags = SIMPLIFICATION)
|
||||
public final class JUnitMethodDeclarationCheck extends BugChecker implements MethodTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
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> OVERRIDE_METHOD =
|
||||
annotations(AT_LEAST_ONE, isType("java.lang.Override"));
|
||||
private static final Matcher<MethodTree> HAS_UNMODIFIABLE_SIGNATURE =
|
||||
anyOf(
|
||||
annotations(AT_LEAST_ONE, isType("java.lang.Override")),
|
||||
allOf(
|
||||
Matchers.not(hasModifier(Modifier.FINAL)),
|
||||
Matchers.not(hasModifier(Modifier.PRIVATE)),
|
||||
enclosingClass(hasModifier(Modifier.ABSTRACT))));
|
||||
private static final MultiMatcher<MethodTree, AnnotationTree> TEST_METHOD =
|
||||
annotations(
|
||||
AT_LEAST_ONE,
|
||||
@@ -62,9 +79,7 @@ public final class JUnitMethodDeclarationCheck extends BugChecker implements Met
|
||||
|
||||
@Override
|
||||
public Description matchMethod(MethodTree tree, VisitorState state) {
|
||||
// XXX: Perhaps we should also skip analysis of non-`private` non-`final` methods in abstract
|
||||
// classes?
|
||||
if (OVERRIDE_METHOD.matches(tree, state)) {
|
||||
if (HAS_UNMODIFIABLE_SIGNATURE.matches(tree, state)) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
@@ -73,29 +88,101 @@ public final class JUnitMethodDeclarationCheck extends BugChecker implements Met
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
SuggestedFix.Builder builder = SuggestedFix.builder();
|
||||
SuggestedFix.Builder fixBuilder = SuggestedFix.builder();
|
||||
SuggestedFixes.removeModifiers(tree.getModifiers(), state, ILLEGAL_MODIFIERS)
|
||||
.ifPresent(builder::merge);
|
||||
.ifPresent(fixBuilder::merge);
|
||||
|
||||
if (isTestMethod) {
|
||||
// XXX: In theory this rename could clash with an existing method or static import. In that
|
||||
// case we should emit a warning without a suggested replacement.
|
||||
tryCanonicalizeMethodName(tree, state).ifPresent(builder::merge);
|
||||
suggestTestMethodRenameIfApplicable(tree, fixBuilder, state);
|
||||
}
|
||||
|
||||
return builder.isEmpty() ? Description.NO_MATCH : describeMatch(tree, builder.build());
|
||||
return fixBuilder.isEmpty() ? Description.NO_MATCH : describeMatch(tree, fixBuilder.build());
|
||||
}
|
||||
|
||||
private static Optional<SuggestedFix> tryCanonicalizeMethodName(
|
||||
MethodTree tree, VisitorState state) {
|
||||
private void suggestTestMethodRenameIfApplicable(
|
||||
MethodTree tree, SuggestedFix.Builder fixBuilder, VisitorState state) {
|
||||
tryCanonicalizeMethodName(tree)
|
||||
.ifPresent(
|
||||
newName ->
|
||||
findMethodRenameBlocker(newName, state)
|
||||
.ifPresentOrElse(
|
||||
blocker -> reportMethodRenameBlocker(tree, blocker, state),
|
||||
() -> fixBuilder.merge(SuggestedFixes.renameMethod(tree, newName, state))));
|
||||
}
|
||||
|
||||
private void reportMethodRenameBlocker(MethodTree tree, String reason, VisitorState state) {
|
||||
state.reportMatch(
|
||||
buildDescription(tree)
|
||||
.setMessage(
|
||||
String.format(
|
||||
"This method's name should not redundantly start with `%s` (but note that %s)",
|
||||
TEST_PREFIX, reason))
|
||||
.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* If applicable, returns a human-readable argument against assigning the given name to an
|
||||
* existing method.
|
||||
*
|
||||
* <p>This method implements imperfect heuristics. Things it currently does not consider include
|
||||
* the following:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Whether the rename would merely introduce a method overload, rather than clashing with an
|
||||
* existing method declaration.
|
||||
* <li>Whether the rename would cause a method in a superclass to be overridden.
|
||||
* <li>Whether the rename would in fact clash with a static import. (It could be that a static
|
||||
* import of the same name is only referenced from lexical scopes in which the method under
|
||||
* consideration cannot be referenced directly.)
|
||||
* </ul>
|
||||
*/
|
||||
private static Optional<String> findMethodRenameBlocker(String methodName, VisitorState state) {
|
||||
if (isMethodInEnclosingClass(methodName, state)) {
|
||||
return Optional.of(
|
||||
String.format("a method named `%s` already exists in this class", methodName));
|
||||
}
|
||||
|
||||
if (isSimpleNameStaticallyImported(methodName, state)) {
|
||||
return Optional.of(String.format("`%s` is already statically imported", methodName));
|
||||
}
|
||||
|
||||
if (isReservedKeyword(methodName)) {
|
||||
return Optional.of(String.format("`%s` is a reserved keyword", methodName));
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private static boolean isMethodInEnclosingClass(String methodName, VisitorState state) {
|
||||
return state.findEnclosing(ClassTree.class).getMembers().stream()
|
||||
.filter(MethodTree.class::isInstance)
|
||||
.map(MethodTree.class::cast)
|
||||
.map(MethodTree::getName)
|
||||
.map(Name::toString)
|
||||
.anyMatch(methodName::equals);
|
||||
}
|
||||
|
||||
private static boolean isSimpleNameStaticallyImported(String simpleName, VisitorState state) {
|
||||
return state.getPath().getCompilationUnit().getImports().stream()
|
||||
.filter(ImportTree::isStatic)
|
||||
.map(ImportTree::getQualifiedIdentifier)
|
||||
.map(tree -> getStaticImportSimpleName(tree, state))
|
||||
.anyMatch(simpleName::contentEquals);
|
||||
}
|
||||
|
||||
private static CharSequence getStaticImportSimpleName(Tree tree, VisitorState state) {
|
||||
String source = Util.treeToString(tree, state);
|
||||
return source.subSequence(source.lastIndexOf('.') + 1, source.length());
|
||||
}
|
||||
|
||||
private static Optional<String> tryCanonicalizeMethodName(MethodTree tree) {
|
||||
return Optional.ofNullable(ASTHelpers.getSymbol(tree))
|
||||
.map(sym -> sym.getQualifiedName().toString())
|
||||
.filter(name -> name.startsWith(TEST_PREFIX))
|
||||
.map(name -> name.substring(TEST_PREFIX.length()))
|
||||
.filter(not(String::isEmpty))
|
||||
.map(name -> Character.toLowerCase(name.charAt(0)) + name.substring(1))
|
||||
.filter(name -> !Character.isDigit(name.charAt(0)))
|
||||
.map(name -> SuggestedFixes.renameMethod(tree, name, state));
|
||||
.filter(name -> !Character.isDigit(name.charAt(0)));
|
||||
}
|
||||
|
||||
// XXX: Move to a `MoreMatchers` utility class.
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
final class JavaKeywords {
|
||||
/**
|
||||
* List of all reserved keywords in the Java language.
|
||||
*
|
||||
* @see <a href="https://docs.oracle.com/javase/specs/jls/se17/html/jls-3.html#jls-3.9">JDK 17 JLS
|
||||
* section 3.9: Keywords</a>
|
||||
*/
|
||||
private static final ImmutableSet<String> RESERVED_KEYWORDS =
|
||||
ImmutableSet.of(
|
||||
"_",
|
||||
"abstract",
|
||||
"assert",
|
||||
"boolean",
|
||||
"break",
|
||||
"byte",
|
||||
"case",
|
||||
"catch",
|
||||
"char",
|
||||
"class",
|
||||
"const",
|
||||
"continue",
|
||||
"default",
|
||||
"do",
|
||||
"double",
|
||||
"else",
|
||||
"enum",
|
||||
"extends",
|
||||
"final",
|
||||
"finally",
|
||||
"float",
|
||||
"for",
|
||||
"goto",
|
||||
"if",
|
||||
"implements",
|
||||
"import",
|
||||
"instanceof",
|
||||
"int",
|
||||
"interface",
|
||||
"long",
|
||||
"native",
|
||||
"new",
|
||||
"package",
|
||||
"private",
|
||||
"protected",
|
||||
"public",
|
||||
"return",
|
||||
"short",
|
||||
"static",
|
||||
"strictfp",
|
||||
"super",
|
||||
"switch",
|
||||
"synchronized",
|
||||
"this",
|
||||
"throw",
|
||||
"throws",
|
||||
"transient",
|
||||
"try",
|
||||
"void",
|
||||
"volatile",
|
||||
"while");
|
||||
|
||||
/**
|
||||
* List of all contextual keywords in the Java language.
|
||||
*
|
||||
* @see <a href="https://docs.oracle.com/javase/specs/jls/se17/html/jls-3.html#jls-3.9">JDK 17 JLS
|
||||
* section 3.9: Keywords</a>
|
||||
*/
|
||||
private static final ImmutableSet<String> CONTEXTUAL_KEYWORDS =
|
||||
ImmutableSet.of(
|
||||
"exports",
|
||||
"module",
|
||||
"non-sealed",
|
||||
"open",
|
||||
"opens",
|
||||
"permits",
|
||||
"provides",
|
||||
"record",
|
||||
"requires",
|
||||
"sealed",
|
||||
"to",
|
||||
"transitive",
|
||||
"uses",
|
||||
"var",
|
||||
"with",
|
||||
"yield");
|
||||
|
||||
/** List of all keywords in the Java language. */
|
||||
private static final ImmutableSet<String> ALL_KEYWORDS =
|
||||
Sets.union(RESERVED_KEYWORDS, CONTEXTUAL_KEYWORDS).immutableCopy();
|
||||
|
||||
private JavaKeywords() {}
|
||||
|
||||
/** Tells whether the given string is a reserved keyword in the Java language. */
|
||||
public static boolean isReservedKeyword(String str) {
|
||||
return RESERVED_KEYWORDS.contains(str);
|
||||
}
|
||||
|
||||
/** Tells whether the given string is a contextual keyword in the Java language. */
|
||||
public static boolean isContextualKeyword(String str) {
|
||||
return CONTEXTUAL_KEYWORDS.contains(str);
|
||||
}
|
||||
|
||||
/** Tells whether the given string is a reserved or contextual keyword in the Java language. */
|
||||
public static boolean isKeyword(String str) {
|
||||
return ALL_KEYWORDS.contains(str);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.BugPattern.LinkType.NONE;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.STYLE;
|
||||
import static java.util.Comparator.comparing;
|
||||
import static java.util.Comparator.naturalOrder;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
@@ -9,9 +12,6 @@ import com.google.common.collect.Comparators;
|
||||
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.SeverityLevel;
|
||||
import com.google.errorprone.BugPattern.StandardTags;
|
||||
import com.google.errorprone.ErrorProneFlags;
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
@@ -48,9 +48,9 @@ import java.util.stream.Stream;
|
||||
@BugPattern(
|
||||
name = "LexicographicalAnnotationAttributeListing",
|
||||
summary = "Where possible, sort annotation array attributes lexicographically",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.SUGGESTION,
|
||||
tags = StandardTags.STYLE)
|
||||
linkType = NONE,
|
||||
severity = SUGGESTION,
|
||||
tags = STYLE)
|
||||
public final class LexicographicalAnnotationAttributeListingCheck extends BugChecker
|
||||
implements AnnotationTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
import static com.google.errorprone.BugPattern.LinkType.NONE;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.STYLE;
|
||||
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;
|
||||
@@ -31,9 +31,9 @@ import java.util.Optional;
|
||||
@BugPattern(
|
||||
name = "LexicographicalAnnotationListing",
|
||||
summary = "Sort annotations lexicographically where possible",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.SUGGESTION,
|
||||
tags = StandardTags.STYLE)
|
||||
linkType = NONE,
|
||||
severity = SUGGESTION,
|
||||
tags = STYLE)
|
||||
public final class LexicographicalAnnotationListingCheck extends BugChecker
|
||||
implements MethodTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
import static com.google.errorprone.BugPattern.LinkType.NONE;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.STYLE;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
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.SeverityLevel;
|
||||
import com.google.errorprone.BugPattern.StandardTags;
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
import com.google.errorprone.bugpatterns.BugChecker.LambdaExpressionTreeMatcher;
|
||||
@@ -53,9 +53,9 @@ import javax.lang.model.element.Name;
|
||||
@BugPattern(
|
||||
name = "MethodReferenceUsage",
|
||||
summary = "Prefer method references over lambda expressions",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.SUGGESTION,
|
||||
tags = StandardTags.STYLE)
|
||||
linkType = NONE,
|
||||
severity = SUGGESTION,
|
||||
tags = STYLE)
|
||||
public final class MethodReferenceUsageCheck extends BugChecker
|
||||
implements LambdaExpressionTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.BugPattern.LinkType.NONE;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.LIKELY_ERROR;
|
||||
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;
|
||||
@@ -7,9 +10,6 @@ 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;
|
||||
@@ -26,9 +26,9 @@ import com.sun.source.tree.Tree;
|
||||
@BugPattern(
|
||||
name = "MissingRefasterAnnotation",
|
||||
summary = "The Refaster template contains a method without any Refaster annotations",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.WARNING,
|
||||
tags = StandardTags.LIKELY_ERROR)
|
||||
linkType = NONE,
|
||||
severity = WARNING,
|
||||
tags = LIKELY_ERROR)
|
||||
public final class MissingRefasterAnnotationCheck extends BugChecker implements ClassTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final MultiMatcher<Tree, AnnotationTree> REFASTER_ANNOTATION =
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.BugPattern.LinkType.NONE;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.SIMPLIFICATION;
|
||||
import static com.google.errorprone.matchers.Matchers.staticMethod;
|
||||
|
||||
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.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;
|
||||
@@ -26,9 +26,9 @@ import java.util.List;
|
||||
@BugPattern(
|
||||
name = "MockitoStubbing",
|
||||
summary = "Don't unnecessarily use Mockito's `eq(...)`",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.SUGGESTION,
|
||||
tags = StandardTags.SIMPLIFICATION)
|
||||
linkType = NONE,
|
||||
severity = SUGGESTION,
|
||||
tags = SIMPLIFICATION)
|
||||
public final class MockitoStubbingCheck extends BugChecker implements MethodInvocationTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Matcher<ExpressionTree> MOCKITO_EQ_METHOD =
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.BugPattern.LinkType.NONE;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.PERFORMANCE;
|
||||
import static com.google.errorprone.matchers.Matchers.anyOf;
|
||||
import static com.google.errorprone.matchers.method.MethodMatchers.instanceMethod;
|
||||
import static com.google.errorprone.matchers.method.MethodMatchers.staticMethod;
|
||||
import static java.util.function.Predicate.not;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
|
||||
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.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;
|
||||
@@ -30,6 +31,7 @@ import com.sun.tools.javac.tree.JCTree.JCMemberReference;
|
||||
import java.util.Comparator;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* A {@link BugChecker} which flags {@code Comparator#comparing*} invocations that can be replaced
|
||||
@@ -37,16 +39,15 @@ import java.util.function.Function;
|
||||
*/
|
||||
// XXX: Add more documentation. Explain how this is useful in the face of refactoring to more
|
||||
// specific types.
|
||||
// XXX: Change this checker's name?
|
||||
@AutoService(BugChecker.class)
|
||||
@BugPattern(
|
||||
name = "PrimitiveComparison",
|
||||
summary =
|
||||
"Ensure invocations of `Comparator#comparing{,Double,Int,Long}` match the return type"
|
||||
+ " of the provided function",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.WARNING,
|
||||
tags = StandardTags.PERFORMANCE)
|
||||
linkType = NONE,
|
||||
severity = WARNING,
|
||||
tags = PERFORMANCE)
|
||||
public final class PrimitiveComparisonCheck extends BugChecker
|
||||
implements MethodInvocationTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
@@ -77,23 +78,53 @@ public final class PrimitiveComparisonCheck extends BugChecker
|
||||
}
|
||||
|
||||
return getPotentiallyBoxedReturnType(tree.getArguments().get(0))
|
||||
.flatMap(cmpType -> tryFix(tree, state, cmpType, isStatic))
|
||||
.flatMap(cmpType -> attemptMethodInvocationReplacement(tree, cmpType, isStatic, state))
|
||||
.map(fix -> describeMatch(tree, fix))
|
||||
.orElse(Description.NO_MATCH);
|
||||
}
|
||||
|
||||
private static Optional<Fix> tryFix(
|
||||
MethodInvocationTree tree, VisitorState state, Type cmpType, boolean isStatic) {
|
||||
private static Optional<Fix> attemptMethodInvocationReplacement(
|
||||
MethodInvocationTree tree, Type cmpType, boolean isStatic, VisitorState state) {
|
||||
return Optional.ofNullable(ASTHelpers.getSymbol(tree))
|
||||
.map(methodSymbol -> methodSymbol.getSimpleName().toString())
|
||||
.flatMap(
|
||||
actualMethodName ->
|
||||
Optional.of(getPreferredMethod(state, cmpType, isStatic))
|
||||
Optional.of(getPreferredMethod(cmpType, isStatic, state))
|
||||
.filter(not(actualMethodName::equals)))
|
||||
.map(
|
||||
preferredMethodName ->
|
||||
prefixTypeArgumentsIfRelevant(preferredMethodName, tree, cmpType, state))
|
||||
.map(preferredMethodName -> suggestFix(tree, preferredMethodName, state));
|
||||
}
|
||||
|
||||
private static String getPreferredMethod(VisitorState state, Type cmpType, boolean isStatic) {
|
||||
/**
|
||||
* Prefixes the given method name with generic type parameters if it replaces a {@code
|
||||
* Comparator#comparing{,Double,Long,Int}} method which also has generic type parameters.
|
||||
*
|
||||
* <p>Such type parameters are retained as they are likely required.
|
||||
*
|
||||
* <p>Note that any type parameter to {@code Comparator#thenComparing} is likely redundant, and in
|
||||
* any case becomes obsolete once that method is replaced with {@code
|
||||
* Comparator#thenComparing{Double,Long,Int}}. Conversion in the opposite direction does not
|
||||
* require the introduction of a generic type parameter.
|
||||
*/
|
||||
private static String prefixTypeArgumentsIfRelevant(
|
||||
String preferredMethodName, MethodInvocationTree tree, Type cmpType, VisitorState state) {
|
||||
if (tree.getTypeArguments().isEmpty() || preferredMethodName.startsWith("then")) {
|
||||
return preferredMethodName;
|
||||
}
|
||||
|
||||
String typeArguments =
|
||||
Stream.concat(
|
||||
Stream.of(Util.treeToString(tree.getTypeArguments().get(0), state)),
|
||||
Stream.of(cmpType.tsym.getSimpleName())
|
||||
.filter(u -> "comparing".equals(preferredMethodName)))
|
||||
.collect(joining(", ", "<", ">"));
|
||||
|
||||
return typeArguments + preferredMethodName;
|
||||
}
|
||||
|
||||
private static String getPreferredMethod(Type cmpType, boolean isStatic, VisitorState state) {
|
||||
Types types = state.getTypes();
|
||||
Symtab symtab = state.getSymtab();
|
||||
|
||||
@@ -128,9 +159,6 @@ public final class PrimitiveComparisonCheck extends BugChecker
|
||||
}
|
||||
}
|
||||
|
||||
// XXX: We drop explicitly specified generic type information. In case the number of type
|
||||
// arguments before and after doesn't match, that's for the better. But if we e.g. replace
|
||||
// `comparingLong` with `comparingInt`, then we should retain it.
|
||||
private static Fix suggestFix(
|
||||
MethodInvocationTree tree, String preferredMethodName, VisitorState state) {
|
||||
ExpressionTree expr = tree.getMethodSelect();
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.BugPattern.LinkType.NONE;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.SIMPLIFICATION;
|
||||
import static com.google.errorprone.matchers.Matchers.allOf;
|
||||
import static com.google.errorprone.matchers.Matchers.anyOf;
|
||||
import static com.google.errorprone.matchers.Matchers.isNonNullUsingDataflow;
|
||||
@@ -12,9 +15,6 @@ import static com.google.errorprone.matchers.method.MethodMatchers.staticMethod;
|
||||
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.SeverityLevel;
|
||||
import com.google.errorprone.BugPattern.StandardTags;
|
||||
import com.google.errorprone.ErrorProneFlags;
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
@@ -47,9 +47,9 @@ import java.util.Optional;
|
||||
@BugPattern(
|
||||
name = "RedundantStringConversion",
|
||||
summary = "Avoid redundant string conversions when possible",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.SUGGESTION,
|
||||
tags = StandardTags.SIMPLIFICATION)
|
||||
linkType = NONE,
|
||||
severity = SUGGESTION,
|
||||
tags = SIMPLIFICATION)
|
||||
public final class RedundantStringConversionCheck extends BugChecker
|
||||
implements BinaryTreeMatcher, CompoundAssignmentTreeMatcher, MethodInvocationTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.BugPattern.LinkType.NONE;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.SIMPLIFICATION;
|
||||
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;
|
||||
@@ -27,9 +27,9 @@ import com.sun.source.tree.MethodInvocationTree;
|
||||
@BugPattern(
|
||||
name = "RefasterAnyOfUsage",
|
||||
summary = "`Refaster#anyOf` should be passed at least two parameters",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.SUGGESTION,
|
||||
tags = StandardTags.SIMPLIFICATION)
|
||||
linkType = NONE,
|
||||
severity = SUGGESTION,
|
||||
tags = SIMPLIFICATION)
|
||||
public final class RefasterAnyOfUsageCheck extends BugChecker
|
||||
implements MethodInvocationTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -2,7 +2,9 @@ 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 com.google.errorprone.BugPattern.LinkType.NONE;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.SIMPLIFICATION;
|
||||
import static java.util.function.Predicate.not;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
@@ -19,9 +21,6 @@ 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.SeverityLevel;
|
||||
import com.google.errorprone.BugPattern.StandardTags;
|
||||
import com.google.errorprone.CodeTransformer;
|
||||
import com.google.errorprone.CompositeCodeTransformer;
|
||||
import com.google.errorprone.ErrorProneFlags;
|
||||
@@ -32,6 +31,7 @@ import com.google.errorprone.bugpatterns.BugChecker.CompilationUnitTreeMatcher;
|
||||
import com.google.errorprone.fixes.Replacement;
|
||||
import com.google.errorprone.matchers.Description;
|
||||
import com.sun.source.tree.CompilationUnitTree;
|
||||
import com.sun.source.util.TreePath;
|
||||
import com.sun.tools.javac.tree.EndPosTable;
|
||||
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
|
||||
import java.io.IOException;
|
||||
@@ -44,9 +44,12 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
import javax.naming.Context;
|
||||
import tech.picnic.errorprone.plexus.compiler.javac.caching.CachingJavacCompiler;
|
||||
|
||||
/**
|
||||
* A {@link BugChecker} which flags code which can be simplified using Refaster templates located on
|
||||
@@ -60,9 +63,9 @@ import java.util.stream.Stream;
|
||||
@BugPattern(
|
||||
name = "Refaster",
|
||||
summary = "Write idiomatic code when possible",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.SUGGESTION,
|
||||
tags = StandardTags.SIMPLIFICATION)
|
||||
linkType = NONE,
|
||||
severity = SUGGESTION,
|
||||
tags = SIMPLIFICATION)
|
||||
public final class RefasterCheck extends BugChecker implements CompilationUnitTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final String REFASTER_TEMPLATE_SUFFIX = ".refaster";
|
||||
@@ -72,7 +75,8 @@ public final class RefasterCheck extends BugChecker implements CompilationUnitTr
|
||||
static final Supplier<ImmutableListMultimap<String, CodeTransformer>> ALL_CODE_TRANSFORMERS =
|
||||
Suppliers.memoize(RefasterCheck::loadAllCodeTransformers);
|
||||
|
||||
private final CodeTransformer codeTransformer;
|
||||
private final ErrorProneFlags errorProneFlags;
|
||||
private final Supplier<CodeTransformer> codeTransformer;
|
||||
|
||||
/** Instantiates the default {@link RefasterCheck}. */
|
||||
public RefasterCheck() {
|
||||
@@ -85,15 +89,37 @@ public final class RefasterCheck extends BugChecker implements CompilationUnitTr
|
||||
* @param flags Any provided command line flags.
|
||||
*/
|
||||
public RefasterCheck(ErrorProneFlags flags) {
|
||||
codeTransformer = createCompositeCodeTransformer(flags);
|
||||
errorProneFlags = flags;
|
||||
codeTransformer = Suppliers.memoize(() -> createCompositeCodeTransformer(flags));
|
||||
}
|
||||
|
||||
// XXX: Need to somehow convert `Description` to handle classloading issue.
|
||||
// private BiFunction<TreePath, Context, List<Description>>
|
||||
|
||||
@Override
|
||||
public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState state) {
|
||||
// XXX Use the `codeTransformer` field only if `cache` is empty. In that case, populate the
|
||||
// cache.
|
||||
// XXX: Current code is wrong: doesn't respect flags.
|
||||
System.out.println("XXXX :" + CachingJavacCompiler.class.toString());
|
||||
System.out.println("XXXX Path :" + TreePath.class.hashCode());
|
||||
System.out.println("XXXX Context:" + Context.class.hashCode());
|
||||
ConcurrentMap<String, Object> cache = state.context.get(ConcurrentMap.class);
|
||||
System.err.printf("XXX %s%n", cache);
|
||||
CodeTransformer transformer;
|
||||
if (cache != null) {
|
||||
cache.compute("x", (a, b) -> b instanceof Integer ? ((Integer) b) + 1 : 1);
|
||||
transformer = (CodeTransformer) cache.computeIfAbsent("c", k -> codeTransformer.get());
|
||||
} else {
|
||||
// We're not using the hacked compiler
|
||||
System.err.printf("XXX NOP!%n");
|
||||
transformer = codeTransformer.get();
|
||||
}
|
||||
|
||||
/* First, collect all matches. */
|
||||
List<Description> matches = new ArrayList<>();
|
||||
try {
|
||||
codeTransformer.apply(state.getPath(), new SubContext(state.context), matches::add);
|
||||
transformer.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
|
||||
@@ -196,10 +222,7 @@ public final class RefasterCheck extends BugChecker implements CompilationUnitTr
|
||||
|
||||
private static ImmutableSet<ResourceInfo> getClassPathResources() {
|
||||
try {
|
||||
return ClassPath.from(
|
||||
requireNonNullElseGet(
|
||||
RefasterCheck.class.getClassLoader(), ClassLoader::getSystemClassLoader))
|
||||
.getResources();
|
||||
return ClassPath.from(ClassLoader.getSystemClassLoader()).getResources();
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Failed to scan classpath for resources", e);
|
||||
}
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.BugPattern.LinkType.NONE;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.LIKELY_ERROR;
|
||||
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;
|
||||
@@ -33,9 +32,9 @@ import com.sun.source.tree.Tree;
|
||||
@BugPattern(
|
||||
name = "RequestMappingAnnotation",
|
||||
summary = "Make sure all `@RequestMapping` method parameters are annotated",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.WARNING,
|
||||
tags = StandardTags.LIKELY_ERROR)
|
||||
linkType = NONE,
|
||||
severity = WARNING,
|
||||
tags = 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.";
|
||||
@@ -51,8 +50,11 @@ public final class RequestMappingAnnotationCheck extends BugChecker implements M
|
||||
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.
|
||||
// XXX: Add other parameters as necessary. Also consider whether it makes sense to have WebMVC-
|
||||
// and WebFlux-specific logic. See
|
||||
// https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-arguments
|
||||
// and
|
||||
// https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html#webflux-ann-arguments.
|
||||
private static final Matcher<MethodTree> LACKS_PARAMETER_ANNOTATION =
|
||||
not(
|
||||
methodHasParameters(
|
||||
@@ -66,10 +68,17 @@ public final class RequestMappingAnnotationCheck extends BugChecker implements M
|
||||
isType(ANN_PACKAGE_PREFIX + "RequestHeader"),
|
||||
isType(ANN_PACKAGE_PREFIX + "RequestParam"))),
|
||||
isSameType("java.io.InputStream"),
|
||||
isSameType("java.time.ZoneId"),
|
||||
isSameType("java.util.Locale"),
|
||||
isSameType("java.util.TimeZone"),
|
||||
isSameType("javax.servlet.http.HttpServletRequest"),
|
||||
isSameType("javax.servlet.http.HttpServletResponse"),
|
||||
isSameType("org.springframework.http.HttpMethod"),
|
||||
isSubtypeOf("org.springframework.web.context.request.WebRequest"))));
|
||||
isSameType("org.springframework.web.context.request.NativeWebRequest"),
|
||||
isSameType("org.springframework.web.context.request.WebRequest"),
|
||||
isSameType("org.springframework.web.server.ServerWebExchange"),
|
||||
isSameType("org.springframework.web.util.UriBuilder"),
|
||||
isSameType("org.springframework.web.util.UriComponentsBuilder"))));
|
||||
|
||||
@Override
|
||||
public Description matchMethod(MethodTree tree, VisitorState state) {
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.BugPattern.LinkType.NONE;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.ERROR;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.LIKELY_ERROR;
|
||||
import static com.google.errorprone.matchers.ChildMultiMatcher.MatchType.AT_LEAST_ONE;
|
||||
import static com.google.errorprone.matchers.Matchers.allOf;
|
||||
import static com.google.errorprone.matchers.Matchers.annotations;
|
||||
import static com.google.errorprone.matchers.Matchers.anyOf;
|
||||
import static com.google.errorprone.matchers.Matchers.isSubtypeOf;
|
||||
import static com.google.errorprone.matchers.Matchers.isType;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.google.common.collect.ImmutableCollection;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
import com.google.errorprone.bugpatterns.BugChecker.VariableTreeMatcher;
|
||||
import com.google.errorprone.matchers.Description;
|
||||
import com.google.errorprone.matchers.Matcher;
|
||||
import com.sun.source.tree.VariableTree;
|
||||
|
||||
/** A {@link BugChecker} which flags {@code @RequestParam} parameters with an unsupported type. */
|
||||
@AutoService(BugChecker.class)
|
||||
@BugPattern(
|
||||
name = "RequestParamType",
|
||||
summary = "`@RequestParam` does not support `ImmutableCollection` and `ImmutableMap` subtypes",
|
||||
linkType = NONE,
|
||||
severity = ERROR,
|
||||
tags = LIKELY_ERROR)
|
||||
public final class RequestParamTypeCheck extends BugChecker implements VariableTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Matcher<VariableTree> HAS_UNSUPPORTED_REQUEST_PARAM =
|
||||
allOf(
|
||||
annotations(AT_LEAST_ONE, isType("org.springframework.web.bind.annotation.RequestParam")),
|
||||
anyOf(isSubtypeOf(ImmutableCollection.class), isSubtypeOf(ImmutableMap.class)));
|
||||
|
||||
@Override
|
||||
public Description matchVariable(VariableTree tree, VisitorState state) {
|
||||
return HAS_UNSUPPORTED_REQUEST_PARAM.matches(tree, state)
|
||||
? describeMatch(tree)
|
||||
: Description.NO_MATCH;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.BugPattern.LinkType.NONE;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.ERROR;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.LIKELY_ERROR;
|
||||
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.hasAnnotation;
|
||||
import static com.google.errorprone.matchers.Matchers.isType;
|
||||
|
||||
import com.google.auto.common.AnnotationMirrors;
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
import com.google.errorprone.bugpatterns.BugChecker.MethodTreeMatcher;
|
||||
import com.google.errorprone.fixes.SuggestedFix;
|
||||
import com.google.errorprone.fixes.SuggestedFixes;
|
||||
import com.google.errorprone.matchers.Description;
|
||||
import com.google.errorprone.matchers.Matcher;
|
||||
import com.google.errorprone.matchers.MultiMatcher;
|
||||
import com.google.errorprone.util.ASTHelpers;
|
||||
import com.sun.source.tree.AnnotationTree;
|
||||
import com.sun.source.tree.MethodTree;
|
||||
import com.sun.source.tree.Tree;
|
||||
|
||||
/**
|
||||
* A {@link BugChecker} which flags methods with Spring's {@code @Scheduled} annotation that lack
|
||||
* New Relic Agent's {@code @Trace(dispatcher = true)}.
|
||||
*/
|
||||
@AutoService(BugChecker.class)
|
||||
@BugPattern(
|
||||
name = "ScheduledTransactionTrace",
|
||||
summary = "Scheduled operation must start a new New Relic transaction",
|
||||
linkType = NONE,
|
||||
severity = ERROR,
|
||||
tags = LIKELY_ERROR)
|
||||
public final class ScheduledTransactionTraceCheck extends BugChecker implements MethodTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final String TRACE_ANNOTATION_FQCN = "com.newrelic.api.agent.Trace";
|
||||
private static final Matcher<Tree> IS_SCHEDULED =
|
||||
hasAnnotation("org.springframework.scheduling.annotation.Scheduled");
|
||||
private static final MultiMatcher<Tree, AnnotationTree> TRACE_ANNOTATION =
|
||||
annotations(AT_LEAST_ONE, isType(TRACE_ANNOTATION_FQCN));
|
||||
|
||||
@Override
|
||||
public Description matchMethod(MethodTree tree, VisitorState state) {
|
||||
if (!IS_SCHEDULED.matches(tree, state)) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
ImmutableList<AnnotationTree> traceAnnotations =
|
||||
TRACE_ANNOTATION.multiMatchResult(tree, state).matchingNodes();
|
||||
if (traceAnnotations.isEmpty()) {
|
||||
/* This method completely lacks the `@Trace` annotation; add it. */
|
||||
return describeMatch(
|
||||
tree,
|
||||
SuggestedFix.builder()
|
||||
.addImport(TRACE_ANNOTATION_FQCN)
|
||||
.prefixWith(tree, "@Trace(dispatcher = true)")
|
||||
.build());
|
||||
}
|
||||
|
||||
AnnotationTree traceAnnotation = Iterables.getOnlyElement(traceAnnotations);
|
||||
if (isCorrectAnnotation(traceAnnotation)) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
/*
|
||||
* The `@Trace` annotation is present but does not specify `dispatcher = true`. Add or update
|
||||
* the `dispatcher` annotation element.
|
||||
*/
|
||||
return describeMatch(
|
||||
traceAnnotation,
|
||||
SuggestedFixes.updateAnnotationArgumentValues(
|
||||
traceAnnotation, "dispatcher", ImmutableList.of("true"))
|
||||
.build());
|
||||
}
|
||||
|
||||
private static boolean isCorrectAnnotation(AnnotationTree traceAnnotation) {
|
||||
return Boolean.TRUE.equals(
|
||||
AnnotationMirrors.getAnnotationValue(
|
||||
ASTHelpers.getAnnotationMirror(traceAnnotation), "dispatcher")
|
||||
.getValue());
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.common.base.Verify.verify;
|
||||
import static com.google.errorprone.BugPattern.LinkType.NONE;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.LIKELY_ERROR;
|
||||
import static com.google.errorprone.matchers.Matchers.isSubtypeOf;
|
||||
import static com.google.errorprone.matchers.method.MethodMatchers.instanceMethod;
|
||||
|
||||
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.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;
|
||||
@@ -33,9 +33,9 @@ import java.util.Optional;
|
||||
@BugPattern(
|
||||
name = "Slf4jLogStatement",
|
||||
summary = "Make sure SLF4J log statements contain proper placeholders with matching arguments",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.WARNING,
|
||||
tags = StandardTags.LIKELY_ERROR)
|
||||
linkType = NONE,
|
||||
severity = WARNING,
|
||||
tags = LIKELY_ERROR)
|
||||
public final class Slf4jLogStatementCheck extends BugChecker
|
||||
implements MethodInvocationTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.common.base.Verify.verify;
|
||||
import static com.google.errorprone.BugPattern.LinkType.NONE;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.SIMPLIFICATION;
|
||||
import static java.util.function.Predicate.not;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
|
||||
@@ -9,9 +12,6 @@ import com.google.common.base.VerifyException;
|
||||
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.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;
|
||||
@@ -35,9 +35,9 @@ import java.util.Optional;
|
||||
name = "SpringMvcAnnotation",
|
||||
summary =
|
||||
"Prefer the conciseness of `@{Get,Put,Post,Delete,Patch}Mapping` over `@RequestMapping`",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.SUGGESTION,
|
||||
tags = StandardTags.SIMPLIFICATION)
|
||||
linkType = NONE,
|
||||
severity = SUGGESTION,
|
||||
tags = 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,8 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.BugPattern.LinkType.NONE;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.SIMPLIFICATION;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
@@ -7,9 +10,6 @@ import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSetMultimap;
|
||||
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.MemberSelectTreeMatcher;
|
||||
@@ -19,14 +19,18 @@ import com.google.errorprone.fixes.Fix;
|
||||
import com.google.errorprone.fixes.SuggestedFix;
|
||||
import com.google.errorprone.fixes.SuggestedFixes;
|
||||
import com.google.errorprone.matchers.Description;
|
||||
import com.google.errorprone.util.ASTHelpers;
|
||||
import com.sun.source.tree.MemberSelectTree;
|
||||
import com.sun.source.tree.MethodInvocationTree;
|
||||
import com.sun.source.tree.Tree;
|
||||
import com.sun.tools.javac.code.Type;
|
||||
import java.util.Optional;
|
||||
|
||||
/** A {@link BugChecker} which flags methods that can and should be statically imported. */
|
||||
/**
|
||||
* A {@link BugChecker} which flags methods and constants that can and should be statically
|
||||
* imported.
|
||||
*/
|
||||
// XXX: Tricky cases:
|
||||
// - `org.springframework.http.MediaType` (do except for `ALL`?)
|
||||
// - `org.springframework.http.HttpStatus` (not always an improvement, and `valueOf` must
|
||||
// certainly be excluded)
|
||||
// - `com.google.common.collect.Tables`
|
||||
@@ -42,20 +46,28 @@ import java.util.Optional;
|
||||
@AutoService(BugChecker.class)
|
||||
@BugPattern(
|
||||
name = "StaticImport",
|
||||
summary = "Method should be statically imported",
|
||||
linkType = LinkType.NONE,
|
||||
severity = SeverityLevel.SUGGESTION,
|
||||
tags = StandardTags.SIMPLIFICATION)
|
||||
summary = "Identifier should be statically imported",
|
||||
linkType = NONE,
|
||||
severity = SUGGESTION,
|
||||
tags = SIMPLIFICATION)
|
||||
public final class StaticImportCheck extends BugChecker implements MemberSelectTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Types whose members should be statically imported, unless exempted by {@link
|
||||
* #STATIC_IMPORT_EXEMPTED_MEMBERS} or {@link #STATIC_IMPORT_EXEMPTED_IDENTIFIERS}.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
static final ImmutableSet<String> STATIC_IMPORT_CANDIDATE_CLASSES =
|
||||
static final ImmutableSet<String> STATIC_IMPORT_CANDIDATE_TYPES =
|
||||
ImmutableSet.of(
|
||||
"com.google.common.base.Preconditions",
|
||||
"com.google.common.base.Predicates",
|
||||
"com.google.common.base.Verify",
|
||||
"com.google.common.collect.MoreCollectors",
|
||||
"com.google.errorprone.BugPattern.LinkType",
|
||||
"com.google.errorprone.BugPattern.SeverityLevel",
|
||||
"com.google.errorprone.BugPattern.StandardTags",
|
||||
"com.google.errorprone.refaster.ImportPolicy",
|
||||
"com.mongodb.client.model.Accumulators",
|
||||
"com.mongodb.client.model.Aggregates",
|
||||
"com.mongodb.client.model.Filters",
|
||||
@@ -64,8 +76,10 @@ public final class StaticImportCheck extends BugChecker implements MemberSelectT
|
||||
"com.mongodb.client.model.Sorts",
|
||||
"com.mongodb.client.model.Updates",
|
||||
"java.nio.charset.StandardCharsets",
|
||||
"java.util.Collections",
|
||||
"java.util.Comparator",
|
||||
"java.util.Map.Entry",
|
||||
"java.util.regex.Pattern",
|
||||
"java.util.stream.Collectors",
|
||||
"org.assertj.core.api.Assertions",
|
||||
"org.assertj.core.api.InstanceOfAssertFactories",
|
||||
@@ -84,11 +98,13 @@ public final class StaticImportCheck extends BugChecker implements MemberSelectT
|
||||
"org.springframework.format.annotation.DateTimeFormat.ISO",
|
||||
"org.springframework.http.HttpHeaders",
|
||||
"org.springframework.http.HttpMethod",
|
||||
"org.springframework.http.MediaType",
|
||||
"org.testng.Assert",
|
||||
"reactor.function.TupleUtils");
|
||||
|
||||
/** Type members that should be statically imported. */
|
||||
@VisibleForTesting
|
||||
static final ImmutableSetMultimap<String, String> STATIC_IMPORT_CANDIDATE_METHODS =
|
||||
static final ImmutableSetMultimap<String, String> STATIC_IMPORT_CANDIDATE_MEMBERS =
|
||||
ImmutableSetMultimap.<String, String>builder()
|
||||
.putAll(
|
||||
"com.google.common.collect.ImmutableListMultimap",
|
||||
@@ -109,8 +125,10 @@ public final class StaticImportCheck extends BugChecker implements MemberSelectT
|
||||
.put("com.google.common.collect.ImmutableTable", "toImmutableTable")
|
||||
.put("com.google.common.collect.Sets", "toImmutableEnumSet")
|
||||
.put("com.google.common.base.Functions", "identity")
|
||||
.put("java.time.ZoneOffset", "UTC")
|
||||
.put("java.util.function.Function", "identity")
|
||||
.put("java.util.function.Predicate", "not")
|
||||
.put("java.util.UUID", "randomUUID")
|
||||
.put("org.junit.jupiter.params.provider.Arguments", "arguments")
|
||||
.putAll(
|
||||
"java.util.Objects",
|
||||
@@ -123,9 +141,57 @@ public final class StaticImportCheck extends BugChecker implements MemberSelectT
|
||||
.putAll("com.google.common.collect.Comparators", "emptiesFirst", "emptiesLast")
|
||||
.build();
|
||||
|
||||
/**
|
||||
* Type members that should never be statically imported.
|
||||
*
|
||||
* <p>Identifiers listed by {@link #STATIC_IMPORT_EXEMPTED_IDENTIFIERS} should be omitted from
|
||||
* this collection.
|
||||
*/
|
||||
// XXX: Perhaps the set of exempted `java.util.Collections` methods is too strict. For now any
|
||||
// method name that could be considered "too vague" or could conceivably mean something else in a
|
||||
// specific context is left out.
|
||||
@VisibleForTesting
|
||||
static final ImmutableSetMultimap<String, String> STATIC_IMPORT_EXEMPTED_MEMBERS =
|
||||
ImmutableSetMultimap.<String, String>builder()
|
||||
.put("com.mongodb.client.model.Filters", "empty")
|
||||
.putAll(
|
||||
"java.util.Collections",
|
||||
"addAll",
|
||||
"copy",
|
||||
"fill",
|
||||
"list",
|
||||
"max",
|
||||
"min",
|
||||
"nCopies",
|
||||
"rotate",
|
||||
"sort",
|
||||
"swap")
|
||||
.putAll("java.util.regex.Pattern", "compile", "matches", "quote")
|
||||
.put("org.springframework.http.MediaType", "ALL")
|
||||
.build();
|
||||
|
||||
/**
|
||||
* Identifiers that should never be statically imported.
|
||||
*
|
||||
* <p>This should be a superset of the identifiers flagged by {@link
|
||||
* com.google.errorprone.bugpatterns.BadImport}.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
static final ImmutableSet<String> STATIC_IMPORT_EXEMPTED_IDENTIFIERS =
|
||||
ImmutableSet.of(
|
||||
"builder",
|
||||
"create",
|
||||
"copyOf",
|
||||
"from",
|
||||
"getDefaultInstance",
|
||||
"INSTANCE",
|
||||
"newBuilder",
|
||||
"of",
|
||||
"valueOf");
|
||||
|
||||
@Override
|
||||
public Description matchMemberSelect(MemberSelectTree tree, VisitorState state) {
|
||||
if (!isCandidate(state)) {
|
||||
if (!isCandidateContext(state) || !isCandidate(tree)) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
@@ -140,7 +206,7 @@ public final class StaticImportCheck extends BugChecker implements MemberSelectT
|
||||
.orElse(Description.NO_MATCH);
|
||||
}
|
||||
|
||||
private static boolean isCandidate(VisitorState state) {
|
||||
private static boolean isCandidateContext(VisitorState state) {
|
||||
Tree parentTree =
|
||||
requireNonNull(state.getPath().getParentPath(), "MemberSelectTree lacks enclosing node")
|
||||
.getLeaf();
|
||||
@@ -155,6 +221,17 @@ public final class StaticImportCheck extends BugChecker implements MemberSelectT
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isCandidate(MemberSelectTree tree) {
|
||||
String identifier = tree.getIdentifier().toString();
|
||||
if (STATIC_IMPORT_EXEMPTED_IDENTIFIERS.contains(identifier)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Type type = ASTHelpers.getType(tree.getExpression());
|
||||
return type != null
|
||||
&& !STATIC_IMPORT_EXEMPTED_MEMBERS.containsEntry(type.toString(), identifier);
|
||||
}
|
||||
|
||||
private static Optional<String> getCandidateSimpleName(StaticImportInfo importInfo) {
|
||||
String canonicalName = importInfo.canonicalName();
|
||||
return importInfo
|
||||
@@ -162,8 +239,8 @@ public final class StaticImportCheck extends BugChecker implements MemberSelectT
|
||||
.toJavaUtil()
|
||||
.filter(
|
||||
name ->
|
||||
STATIC_IMPORT_CANDIDATE_CLASSES.contains(canonicalName)
|
||||
|| STATIC_IMPORT_CANDIDATE_METHODS.containsEntry(canonicalName, name));
|
||||
STATIC_IMPORT_CANDIDATE_TYPES.contains(canonicalName)
|
||||
|| STATIC_IMPORT_CANDIDATE_MEMBERS.containsEntry(canonicalName, name));
|
||||
}
|
||||
|
||||
private static Optional<Fix> tryStaticImport(
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.BugPattern.LinkType.NONE;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.FRAGILE_CODE;
|
||||
import static com.google.errorprone.matchers.Matchers.allOf;
|
||||
import static com.google.errorprone.matchers.Matchers.anyOf;
|
||||
import static com.google.errorprone.matchers.Matchers.enclosingClass;
|
||||
@@ -10,9 +13,6 @@ 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;
|
||||
@@ -32,9 +32,9 @@ import java.time.LocalTime;
|
||||
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)
|
||||
linkType = NONE,
|
||||
severity = WARNING,
|
||||
tags = FRAGILE_CODE)
|
||||
public final class TimeZoneUsageCheck extends BugChecker implements MethodInvocationTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Matcher<ExpressionTree> BANNED_TIME_METHOD =
|
||||
|
||||
@@ -8,13 +8,22 @@ import com.google.errorprone.refaster.annotation.AfterTemplate;
|
||||
import com.google.errorprone.refaster.annotation.BeforeTemplate;
|
||||
import java.math.BigDecimal;
|
||||
import org.assertj.core.api.AbstractBigDecimalAssert;
|
||||
import org.assertj.core.api.BigDecimalAssert;
|
||||
|
||||
// XXX: If we add a rule which drops unnecessary `L` suffixes from literal longs, then the `0L`/`1L`
|
||||
// cases below can go.
|
||||
/**
|
||||
* Refaster templates related to AssertJ assertions over {@link BigDecimal}s.
|
||||
*
|
||||
* <p>Note that, contrary to collections of Refaster templates for other {@link
|
||||
* org.assertj.core.api.NumberAssert} subtypes, these templates do not rewrite to/from {@link
|
||||
* BigDecimalAssert#isEqualTo(Object)} and {@link BigDecimalAssert#isNotEqualTo(Object)}. This is
|
||||
* because {@link BigDecimal#equals(Object)} considers not only the numeric value of compared
|
||||
* instances, but also their scale. As a result various seemingly straightforward transformations
|
||||
* would actually subtly change the assertion's semantics.
|
||||
*/
|
||||
final class AssertJBigDecimalTemplates {
|
||||
private AssertJBigDecimalTemplates() {}
|
||||
|
||||
static final class AbstractBigDecimalAssertIsEqualTo {
|
||||
static final class AbstractBigDecimalAssertIsEqualByComparingTo {
|
||||
@BeforeTemplate
|
||||
AbstractBigDecimalAssert<?> before(AbstractBigDecimalAssert<?> bigDecimalAssert, BigDecimal n) {
|
||||
return Refaster.anyOf(
|
||||
@@ -24,11 +33,11 @@ final class AssertJBigDecimalTemplates {
|
||||
|
||||
@AfterTemplate
|
||||
AbstractBigDecimalAssert<?> after(AbstractBigDecimalAssert<?> bigDecimalAssert, BigDecimal n) {
|
||||
return bigDecimalAssert.isEqualTo(n);
|
||||
return bigDecimalAssert.isEqualByComparingTo(n);
|
||||
}
|
||||
}
|
||||
|
||||
static final class AbstractBigDecimalAssertIsNotEqualTo {
|
||||
static final class AbstractBigDecimalAssertIsNotEqualByComparingTo {
|
||||
@BeforeTemplate
|
||||
AbstractBigDecimalAssert<?> before(AbstractBigDecimalAssert<?> bigDecimalAssert, BigDecimal n) {
|
||||
return Refaster.anyOf(
|
||||
@@ -38,52 +47,7 @@ final class AssertJBigDecimalTemplates {
|
||||
|
||||
@AfterTemplate
|
||||
AbstractBigDecimalAssert<?> after(AbstractBigDecimalAssert<?> bigDecimalAssert, BigDecimal n) {
|
||||
return bigDecimalAssert.isNotEqualTo(n);
|
||||
}
|
||||
}
|
||||
|
||||
static final class AbstractBigDecimalAssertIsZero {
|
||||
@BeforeTemplate
|
||||
AbstractBigDecimalAssert<?> before(AbstractBigDecimalAssert<?> bigDecimalAssert) {
|
||||
return Refaster.anyOf(
|
||||
bigDecimalAssert.isZero(),
|
||||
bigDecimalAssert.isEqualTo(0L),
|
||||
bigDecimalAssert.isEqualTo(BigDecimal.ZERO));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
AbstractBigDecimalAssert<?> after(AbstractBigDecimalAssert<?> bigDecimalAssert) {
|
||||
return bigDecimalAssert.isEqualTo(0);
|
||||
}
|
||||
}
|
||||
|
||||
static final class AbstractBigDecimalAssertIsNotZero {
|
||||
@BeforeTemplate
|
||||
AbstractBigDecimalAssert<?> before(AbstractBigDecimalAssert<?> bigDecimalAssert) {
|
||||
return Refaster.anyOf(
|
||||
bigDecimalAssert.isNotZero(),
|
||||
bigDecimalAssert.isNotEqualTo(0L),
|
||||
bigDecimalAssert.isNotEqualTo(BigDecimal.ZERO));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
AbstractBigDecimalAssert<?> after(AbstractBigDecimalAssert<?> bigDecimalAssert) {
|
||||
return bigDecimalAssert.isNotEqualTo(0);
|
||||
}
|
||||
}
|
||||
|
||||
static final class AbstractBigDecimalAssertIsOne {
|
||||
@BeforeTemplate
|
||||
AbstractBigDecimalAssert<?> before(AbstractBigDecimalAssert<?> bigDecimalAssert) {
|
||||
return Refaster.anyOf(
|
||||
bigDecimalAssert.isOne(),
|
||||
bigDecimalAssert.isEqualTo(1L),
|
||||
bigDecimalAssert.isEqualTo(BigDecimal.ONE));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
AbstractBigDecimalAssert<?> after(AbstractBigDecimalAssert<?> bigDecimalAssert) {
|
||||
return bigDecimalAssert.isEqualTo(1);
|
||||
return bigDecimalAssert.isNotEqualByComparingTo(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
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;
|
||||
@@ -59,7 +59,7 @@ final class AssertJBooleanTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractBooleanAssert<?> after(boolean b) {
|
||||
return assertThat(b).isTrue();
|
||||
}
|
||||
@@ -88,7 +88,7 @@ final class AssertJBooleanTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractBooleanAssert<?> after(boolean b) {
|
||||
return assertThat(b).isFalse();
|
||||
}
|
||||
|
||||
@@ -15,11 +15,7 @@ final class AssertJByteTemplates {
|
||||
@BeforeTemplate
|
||||
AbstractByteAssert<?> before(AbstractByteAssert<?> byteAssert, byte n) {
|
||||
return Refaster.anyOf(
|
||||
byteAssert.isCloseTo(n, offset((byte) 0)),
|
||||
byteAssert.isCloseTo(Byte.valueOf(n), offset((byte) 0)),
|
||||
byteAssert.isCloseTo(n, withPercentage(0)),
|
||||
byteAssert.isCloseTo(Byte.valueOf(n), withPercentage(0)),
|
||||
byteAssert.isEqualTo(Byte.valueOf(n)));
|
||||
byteAssert.isCloseTo(n, offset((byte) 0)), byteAssert.isCloseTo(n, withPercentage(0)));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -33,10 +29,7 @@ final class AssertJByteTemplates {
|
||||
AbstractByteAssert<?> before(AbstractByteAssert<?> byteAssert, byte n) {
|
||||
return Refaster.anyOf(
|
||||
byteAssert.isNotCloseTo(n, offset((byte) 0)),
|
||||
byteAssert.isNotCloseTo(Byte.valueOf(n), offset((byte) 0)),
|
||||
byteAssert.isNotCloseTo(n, withPercentage(0)),
|
||||
byteAssert.isNotCloseTo(Byte.valueOf(n), withPercentage(0)),
|
||||
byteAssert.isNotEqualTo(Byte.valueOf(n)));
|
||||
byteAssert.isNotCloseTo(n, withPercentage(0)));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
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;
|
||||
@@ -21,7 +21,7 @@ final class AssertJCharSequenceTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(CharSequence charSequence) {
|
||||
assertThat(charSequence).isEmpty();
|
||||
}
|
||||
@@ -36,7 +36,7 @@ final class AssertJCharSequenceTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractAssert<?, ?> after(CharSequence charSequence) {
|
||||
return assertThat(charSequence).isNotEmpty();
|
||||
}
|
||||
@@ -49,7 +49,7 @@ final class AssertJCharSequenceTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractAssert<?, ?> after(CharSequence charSequence, int length) {
|
||||
return assertThat(charSequence).hasSize(length);
|
||||
}
|
||||
|
||||
@@ -36,11 +36,7 @@ final class AssertJDoubleTemplates {
|
||||
@BeforeTemplate
|
||||
AbstractDoubleAssert<?> before(AbstractDoubleAssert<?> doubleAssert, double n) {
|
||||
return Refaster.anyOf(
|
||||
doubleAssert.isCloseTo(n, offset(0.0)),
|
||||
doubleAssert.isCloseTo(Double.valueOf(n), offset(0.0)),
|
||||
doubleAssert.isCloseTo(n, withPercentage(0.0)),
|
||||
doubleAssert.isCloseTo(Double.valueOf(n), withPercentage(0.0)),
|
||||
doubleAssert.isEqualTo(Double.valueOf(n)));
|
||||
doubleAssert.isCloseTo(n, offset(0.0)), doubleAssert.isCloseTo(n, withPercentage(0.0)));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -54,10 +50,7 @@ final class AssertJDoubleTemplates {
|
||||
AbstractDoubleAssert<?> before(AbstractDoubleAssert<?> doubleAssert, double n) {
|
||||
return Refaster.anyOf(
|
||||
doubleAssert.isNotCloseTo(n, offset(0.0)),
|
||||
doubleAssert.isNotCloseTo(Double.valueOf(n), offset(0.0)),
|
||||
doubleAssert.isNotCloseTo(n, withPercentage(0.0)),
|
||||
doubleAssert.isNotCloseTo(Double.valueOf(n), withPercentage(0.0)),
|
||||
doubleAssert.isNotEqualTo(Double.valueOf(n)));
|
||||
doubleAssert.isNotCloseTo(n, withPercentage(0.0)));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
|
||||
@@ -36,11 +36,7 @@ final class AssertJFloatTemplates {
|
||||
@BeforeTemplate
|
||||
AbstractFloatAssert<?> before(AbstractFloatAssert<?> floatAssert, float n) {
|
||||
return Refaster.anyOf(
|
||||
floatAssert.isCloseTo(n, offset(0F)),
|
||||
floatAssert.isCloseTo(Float.valueOf(n), offset(0F)),
|
||||
floatAssert.isCloseTo(n, withPercentage(0)),
|
||||
floatAssert.isCloseTo(Float.valueOf(n), withPercentage(0)),
|
||||
floatAssert.isEqualTo(Float.valueOf(n)));
|
||||
floatAssert.isCloseTo(n, offset(0F)), floatAssert.isCloseTo(n, withPercentage(0)));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -53,11 +49,7 @@ final class AssertJFloatTemplates {
|
||||
@BeforeTemplate
|
||||
AbstractFloatAssert<?> before(AbstractFloatAssert<?> floatAssert, float n) {
|
||||
return Refaster.anyOf(
|
||||
floatAssert.isNotCloseTo(n, offset(0F)),
|
||||
floatAssert.isNotCloseTo(Float.valueOf(n), offset(0F)),
|
||||
floatAssert.isNotCloseTo(n, withPercentage(0)),
|
||||
floatAssert.isNotCloseTo(Float.valueOf(n), withPercentage(0)),
|
||||
floatAssert.isNotEqualTo(Float.valueOf(n)));
|
||||
floatAssert.isNotCloseTo(n, offset(0F)), floatAssert.isNotCloseTo(n, withPercentage(0)));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
|
||||
@@ -15,11 +15,7 @@ final class AssertJIntegerTemplates {
|
||||
@BeforeTemplate
|
||||
AbstractIntegerAssert<?> before(AbstractIntegerAssert<?> intAssert, int n) {
|
||||
return Refaster.anyOf(
|
||||
intAssert.isCloseTo(n, offset(0)),
|
||||
intAssert.isCloseTo(Integer.valueOf(n), offset(0)),
|
||||
intAssert.isCloseTo(n, withPercentage(0)),
|
||||
intAssert.isCloseTo(Integer.valueOf(n), withPercentage(0)),
|
||||
intAssert.isEqualTo(Integer.valueOf(n)));
|
||||
intAssert.isCloseTo(n, offset(0)), intAssert.isCloseTo(n, withPercentage(0)));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -32,11 +28,7 @@ final class AssertJIntegerTemplates {
|
||||
@BeforeTemplate
|
||||
AbstractIntegerAssert<?> before(AbstractIntegerAssert<?> intAssert, int n) {
|
||||
return Refaster.anyOf(
|
||||
intAssert.isNotCloseTo(n, offset(0)),
|
||||
intAssert.isNotCloseTo(Integer.valueOf(n), offset(0)),
|
||||
intAssert.isNotCloseTo(n, withPercentage(0)),
|
||||
intAssert.isNotCloseTo(Integer.valueOf(n), withPercentage(0)),
|
||||
intAssert.isNotEqualTo(Integer.valueOf(n)));
|
||||
intAssert.isNotCloseTo(n, offset(0)), intAssert.isNotCloseTo(n, withPercentage(0)));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
|
||||
@@ -15,11 +15,7 @@ final class AssertJLongTemplates {
|
||||
@BeforeTemplate
|
||||
AbstractLongAssert<?> before(AbstractLongAssert<?> longAssert, long n) {
|
||||
return Refaster.anyOf(
|
||||
longAssert.isCloseTo(n, offset(0L)),
|
||||
longAssert.isCloseTo(Long.valueOf(n), offset(0L)),
|
||||
longAssert.isCloseTo(n, withPercentage(0)),
|
||||
longAssert.isCloseTo(Long.valueOf(n), withPercentage(0)),
|
||||
longAssert.isEqualTo(Long.valueOf(n)));
|
||||
longAssert.isCloseTo(n, offset(0L)), longAssert.isCloseTo(n, withPercentage(0)));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -32,11 +28,7 @@ final class AssertJLongTemplates {
|
||||
@BeforeTemplate
|
||||
AbstractLongAssert<?> before(AbstractLongAssert<?> longAssert, long n) {
|
||||
return Refaster.anyOf(
|
||||
longAssert.isNotCloseTo(n, offset(0L)),
|
||||
longAssert.isNotCloseTo(Long.valueOf(n), offset(0L)),
|
||||
longAssert.isNotCloseTo(n, withPercentage(0)),
|
||||
longAssert.isNotCloseTo(Long.valueOf(n), withPercentage(0)),
|
||||
longAssert.isNotEqualTo(Long.valueOf(n)));
|
||||
longAssert.isNotCloseTo(n, offset(0L)), longAssert.isNotCloseTo(n, withPercentage(0)));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.errorprone.refaster.annotation.AfterTemplate;
|
||||
import com.google.errorprone.refaster.annotation.BeforeTemplate;
|
||||
import java.util.Map;
|
||||
import org.assertj.core.api.AbstractMapAssert;
|
||||
|
||||
final class AssertJMapTemplates {
|
||||
private AssertJMapTemplates() {}
|
||||
|
||||
static final class AbstractMapAssertContainsExactlyInAnyOrderEntriesOf<K, V> {
|
||||
@BeforeTemplate
|
||||
AbstractMapAssert<?, ?, K, V> before(AbstractMapAssert<?, ?, K, V> mapAssert, Map<K, V> map) {
|
||||
return mapAssert.isEqualTo(map);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
AbstractMapAssert<?, ?, K, V> after(AbstractMapAssert<?, ?, K, V> mapAssert, Map<K, V> map) {
|
||||
return mapAssert.containsExactlyInAnyOrderEntriesOf(map);
|
||||
}
|
||||
}
|
||||
|
||||
static final class AbstractMapAssertContainsExactlyEntriesOf<K, V> {
|
||||
@BeforeTemplate
|
||||
AbstractMapAssert<?, ?, K, V> before(AbstractMapAssert<?, ?, K, V> mapAssert, K key, V value) {
|
||||
return mapAssert.containsExactlyInAnyOrderEntriesOf(ImmutableMap.of(key, value));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
AbstractMapAssert<?, ?, K, V> after(AbstractMapAssert<?, ?, K, V> mapAssert, K key, V value) {
|
||||
return mapAssert.containsExactlyEntriesOf(ImmutableMap.of(key, value));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,12 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
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.UseImportPolicy;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import org.assertj.core.api.AbstractBigDecimalAssert;
|
||||
@@ -18,7 +22,7 @@ import org.assertj.core.api.NumberAssert;
|
||||
final class AssertJNumberTemplates {
|
||||
private AssertJNumberTemplates() {}
|
||||
|
||||
static final class NumberIsPositive {
|
||||
static final class NumberAssertIsPositive {
|
||||
@BeforeTemplate
|
||||
AbstractByteAssert<?> before(AbstractByteAssert<?> numberAssert) {
|
||||
return Refaster.anyOf(
|
||||
@@ -69,7 +73,7 @@ final class AssertJNumberTemplates {
|
||||
}
|
||||
}
|
||||
|
||||
static final class NumberIsNotPositive {
|
||||
static final class NumberAssertIsNotPositive {
|
||||
@BeforeTemplate
|
||||
AbstractByteAssert<?> before(AbstractByteAssert<?> numberAssert) {
|
||||
return Refaster.anyOf(
|
||||
@@ -120,7 +124,7 @@ final class AssertJNumberTemplates {
|
||||
}
|
||||
}
|
||||
|
||||
static final class NumberIsNegative {
|
||||
static final class NumberAssertIsNegative {
|
||||
@BeforeTemplate
|
||||
AbstractByteAssert<?> before(AbstractByteAssert<?> numberAssert) {
|
||||
return Refaster.anyOf(
|
||||
@@ -171,7 +175,7 @@ final class AssertJNumberTemplates {
|
||||
}
|
||||
}
|
||||
|
||||
static final class NumberIsNotNegative {
|
||||
static final class NumberAssertIsNotNegative {
|
||||
@BeforeTemplate
|
||||
AbstractByteAssert<?> before(AbstractByteAssert<?> numberAssert) {
|
||||
return Refaster.anyOf(
|
||||
@@ -221,4 +225,40 @@ final class AssertJNumberTemplates {
|
||||
return numberAssert.isNotNegative();
|
||||
}
|
||||
}
|
||||
|
||||
static final class AssertThatIsOdd {
|
||||
@BeforeTemplate
|
||||
AbstractIntegerAssert<?> before(int number) {
|
||||
return assertThat(number % 2).isEqualTo(1);
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
AbstractLongAssert<?> before(long number) {
|
||||
return assertThat(number % 2).isEqualTo(1);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
NumberAssert<?, ?> after(long number) {
|
||||
return assertThat(number).isOdd();
|
||||
}
|
||||
}
|
||||
|
||||
static final class AssertThatIsEven {
|
||||
@BeforeTemplate
|
||||
AbstractIntegerAssert<?> before(int number) {
|
||||
return assertThat(number % 2).isEqualTo(0);
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
AbstractLongAssert<?> before(long number) {
|
||||
return assertThat(number % 2).isEqualTo(0);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
NumberAssert<?, ?> after(long number) {
|
||||
return assertThat(number).isEven();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
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;
|
||||
@@ -21,7 +21,7 @@ final class AssertJObjectTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ObjectAssert<S> after(S object) {
|
||||
return assertThat(object).isInstanceOf(Refaster.<T>clazz());
|
||||
}
|
||||
@@ -34,7 +34,7 @@ final class AssertJObjectTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ObjectAssert<S> after(S object) {
|
||||
return assertThat(object).isNotInstanceOf(Refaster.<T>clazz());
|
||||
}
|
||||
@@ -47,7 +47,7 @@ final class AssertJObjectTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ObjectAssert<S> after(S object1, T object2) {
|
||||
return assertThat(object1).isEqualTo(object2);
|
||||
}
|
||||
@@ -60,7 +60,7 @@ final class AssertJObjectTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ObjectAssert<S> after(S object1, T object2) {
|
||||
return assertThat(object1).isNotEqualTo(object2);
|
||||
}
|
||||
@@ -73,7 +73,7 @@ final class AssertJObjectTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ObjectAssert<T> after(T object, String str) {
|
||||
return assertThat(object).hasToString(str);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
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;
|
||||
@@ -26,7 +26,7 @@ final class AssertJOptionalTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractObjectAssert<?, T> after(Optional<T> optional) {
|
||||
return assertThat(optional).get();
|
||||
}
|
||||
@@ -53,7 +53,7 @@ final class AssertJOptionalTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
OptionalAssert<T> after(Optional<T> optional) {
|
||||
return assertThat(optional).isPresent();
|
||||
}
|
||||
@@ -80,7 +80,7 @@ final class AssertJOptionalTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
OptionalAssert<T> after(Optional<T> optional) {
|
||||
return assertThat(optional).isEmpty();
|
||||
}
|
||||
@@ -122,7 +122,7 @@ final class AssertJOptionalTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractObjectAssert<?, T> after(Optional<T> optional, Predicate<? super T> predicate) {
|
||||
return assertThat(optional).get().matches(predicate);
|
||||
}
|
||||
|
||||
@@ -15,11 +15,7 @@ final class AssertJShortTemplates {
|
||||
@BeforeTemplate
|
||||
AbstractShortAssert<?> before(AbstractShortAssert<?> shortAssert, short n) {
|
||||
return Refaster.anyOf(
|
||||
shortAssert.isCloseTo(n, offset((short) 0)),
|
||||
shortAssert.isCloseTo(Short.valueOf(n), offset((short) 0)),
|
||||
shortAssert.isCloseTo(n, withPercentage(0)),
|
||||
shortAssert.isCloseTo(Short.valueOf(n), withPercentage(0)),
|
||||
shortAssert.isEqualTo(Short.valueOf(n)));
|
||||
shortAssert.isCloseTo(n, offset((short) 0)), shortAssert.isCloseTo(n, withPercentage(0)));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -33,10 +29,7 @@ final class AssertJShortTemplates {
|
||||
AbstractShortAssert<?> before(AbstractShortAssert<?> shortAssert, short n) {
|
||||
return Refaster.anyOf(
|
||||
shortAssert.isNotCloseTo(n, offset((short) 0)),
|
||||
shortAssert.isNotCloseTo(Short.valueOf(n), offset((short) 0)),
|
||||
shortAssert.isNotCloseTo(n, withPercentage(0)),
|
||||
shortAssert.isNotCloseTo(Short.valueOf(n), withPercentage(0)),
|
||||
shortAssert.isNotEqualTo(Short.valueOf(n)));
|
||||
shortAssert.isNotCloseTo(n, withPercentage(0)));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import com.google.errorprone.refaster.ImportPolicy;
|
||||
import com.google.errorprone.refaster.annotation.AfterTemplate;
|
||||
import com.google.errorprone.refaster.annotation.BeforeTemplate;
|
||||
import com.google.errorprone.refaster.annotation.UseImportPolicy;
|
||||
@@ -31,7 +31,7 @@ final class AssertJStringTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(String string) {
|
||||
assertThat(string).isEmpty();
|
||||
}
|
||||
@@ -56,9 +56,35 @@ final class AssertJStringTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractAssert<?, ?> after(String string) {
|
||||
return assertThat(string).isNotEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
static final class AssertThatMatches {
|
||||
@BeforeTemplate
|
||||
AbstractAssert<?, ?> before(String string, String regex) {
|
||||
return assertThat(string.matches(regex)).isTrue();
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractAssert<?, ?> after(String string, String regex) {
|
||||
return assertThat(string).matches(regex);
|
||||
}
|
||||
}
|
||||
|
||||
static final class AssertThatDoesNotMatch {
|
||||
@BeforeTemplate
|
||||
AbstractAssert<?, ?> before(String string, String regex) {
|
||||
return assertThat(string.matches(regex)).isFalse();
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractAssert<?, ?> after(String string, String regex) {
|
||||
return assertThat(string).doesNotMatch(regex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import com.google.common.collect.ImmutableBiMap;
|
||||
@@ -12,7 +13,6 @@ import com.google.common.collect.ImmutableSortedMultiset;
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Multiset;
|
||||
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;
|
||||
@@ -97,7 +97,6 @@ import tech.picnic.errorprone.refaster.util.IsArray;
|
||||
// XXX: Right now we use and import `Offset.offset` and `Percentage.withPercentage`. Use the AssertJ
|
||||
// methods instead. (Also in the TestNG migration.)
|
||||
// ^ Also for `Tuple`!
|
||||
// XXX: Use `assertThatIllegalArgumentException` and variants.
|
||||
// XXX: `assertThatCode(x).isInstanceOf(clazz)` -> `assertThatThrownBy(x).isInstanceOf(clazz)`
|
||||
// (etc.)
|
||||
// XXX: Look into using Assertions#contentOf(URL url, Charset charset) instead of our own test
|
||||
@@ -137,7 +136,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
OptionalDoubleAssert after(OptionalDouble optional, double expected) {
|
||||
return assertThat(optional).hasValue(expected);
|
||||
}
|
||||
@@ -156,7 +155,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
OptionalIntAssert after(OptionalInt optional, int expected) {
|
||||
return assertThat(optional).hasValue(expected);
|
||||
}
|
||||
@@ -175,7 +174,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
OptionalLongAssert after(OptionalLong optional, long expected) {
|
||||
return assertThat(optional).hasValue(expected);
|
||||
}
|
||||
@@ -365,6 +364,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ObjectEnumerableAssert<?, S> after(Set<S> set, T element) {
|
||||
return assertThat(set).containsExactly(element);
|
||||
}
|
||||
@@ -429,7 +429,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(Collection<E> iterable) {
|
||||
assertThat(iterable).isEmpty();
|
||||
}
|
||||
@@ -453,7 +453,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
IterableAssert<E> after(Iterable<E> iterable) {
|
||||
return assertThat(iterable).isNotEmpty();
|
||||
}
|
||||
@@ -471,7 +471,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
IterableAssert<E> after(Iterable<E> iterable, int length) {
|
||||
return assertThat(iterable).hasSize(length);
|
||||
}
|
||||
@@ -484,7 +484,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
IterableAssert<S> after(Iterable<S> iterable, T element) {
|
||||
return assertThat(iterable).containsExactly(element);
|
||||
}
|
||||
@@ -501,7 +501,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
IterableAssert<S> after(Iterable<S> iterable, T element) {
|
||||
return assertThat(iterable).containsExactly(element);
|
||||
}
|
||||
@@ -518,7 +518,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(List<S> list1, List<T> list2) {
|
||||
return assertThat(list1).containsExactlyElementsOf(list2);
|
||||
}
|
||||
@@ -537,7 +537,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractCollectionAssert<?, ?, S, ?> after(Set<S> set1, Set<T> set2) {
|
||||
return assertThat(set1).hasSameElementsAs(set2);
|
||||
}
|
||||
@@ -554,7 +554,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractCollectionAssert<?, ?, S, ?> after(Multiset<S> multiset1, Multiset<T> multiset2) {
|
||||
return assertThat(multiset1).containsExactlyInAnyOrderElementsOf(multiset2);
|
||||
}
|
||||
@@ -632,7 +632,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(Map<K, V> map) {
|
||||
assertThat(map).isEmpty();
|
||||
}
|
||||
@@ -669,7 +669,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
MapAssert<K, V> after(Map<K, V> map) {
|
||||
return assertThat(map).isNotEmpty();
|
||||
}
|
||||
@@ -684,7 +684,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
MapAssert<K, V> after(Map<K, V> map, int length) {
|
||||
return assertThat(map).hasSize(length);
|
||||
}
|
||||
@@ -698,7 +698,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
MapAssert<K, V> after(Map<K, V> map1, Map<K, V> map2) {
|
||||
return assertThat(map1).hasSameSizeAs(map2);
|
||||
}
|
||||
@@ -712,7 +712,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
MapAssert<K, V> after(Map<K, V> map, K key) {
|
||||
return assertThat(map).containsKey(key);
|
||||
}
|
||||
@@ -725,7 +725,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
MapAssert<K, V> after(Map<K, V> map, K key) {
|
||||
return assertThat(map).doesNotContainKey(key);
|
||||
}
|
||||
@@ -738,7 +738,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
MapAssert<K, V> after(Map<K, V> map, K key, V value) {
|
||||
return assertThat(map).containsEntry(key, value);
|
||||
}
|
||||
@@ -763,7 +763,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, Iterable<U> iterable) {
|
||||
return assertThat(stream).containsAnyElementsOf(iterable);
|
||||
}
|
||||
@@ -784,7 +784,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, U[] array) {
|
||||
return assertThat(stream).containsAnyOf(array);
|
||||
}
|
||||
@@ -808,7 +808,7 @@ final class AssertJTemplates {
|
||||
|
||||
@AfterTemplate
|
||||
@SuppressWarnings("ObjectEnumerableContainsOneElement" /* Not a true singleton. */)
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, @Repeated U elements) {
|
||||
return assertThat(stream).containsAnyOf(elements);
|
||||
}
|
||||
@@ -829,7 +829,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, Iterable<U> iterable) {
|
||||
return assertThat(stream).containsAll(iterable);
|
||||
}
|
||||
@@ -850,7 +850,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, U[] array) {
|
||||
return assertThat(stream).contains(array);
|
||||
}
|
||||
@@ -873,7 +873,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, @Repeated U elements) {
|
||||
return assertThat(stream).contains(elements);
|
||||
}
|
||||
@@ -888,7 +888,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, Iterable<U> iterable) {
|
||||
return assertThat(stream).containsExactlyElementsOf(iterable);
|
||||
}
|
||||
@@ -903,7 +903,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, U[] array) {
|
||||
return assertThat(stream).containsExactly(array);
|
||||
}
|
||||
@@ -919,7 +919,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, @Repeated U elements) {
|
||||
return assertThat(stream).containsExactly(elements);
|
||||
}
|
||||
@@ -941,7 +941,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, Iterable<U> iterable) {
|
||||
return assertThat(stream).containsExactlyInAnyOrderElementsOf(iterable);
|
||||
}
|
||||
@@ -962,7 +962,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, U[] array) {
|
||||
return assertThat(stream).containsExactlyInAnyOrder(array);
|
||||
}
|
||||
@@ -988,7 +988,7 @@ final class AssertJTemplates {
|
||||
|
||||
@AfterTemplate
|
||||
@SuppressWarnings("ObjectEnumerableContainsExactlyOneElement" /* Not a true singleton. */)
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, @Repeated U elements) {
|
||||
return assertThat(stream).containsExactlyInAnyOrder(elements);
|
||||
}
|
||||
@@ -1009,7 +1009,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, Iterable<U> iterable) {
|
||||
return assertThat(stream).containsSequence(iterable);
|
||||
}
|
||||
@@ -1026,7 +1026,7 @@ final class AssertJTemplates {
|
||||
|
||||
@AfterTemplate
|
||||
@SuppressWarnings("ObjectEnumerableContainsOneElement" /* Not a true singleton. */)
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, @Repeated U elements) {
|
||||
return assertThat(stream).containsSequence(elements);
|
||||
}
|
||||
@@ -1047,7 +1047,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, Iterable<U> iterable) {
|
||||
return assertThat(stream).containsSubsequence(iterable);
|
||||
}
|
||||
@@ -1065,7 +1065,7 @@ final class AssertJTemplates {
|
||||
|
||||
@AfterTemplate
|
||||
@SuppressWarnings("ObjectEnumerableContainsOneElement" /* Not a true singleton. */)
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, @Repeated U elements) {
|
||||
return assertThat(stream).containsSubsequence(elements);
|
||||
}
|
||||
@@ -1086,7 +1086,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, Iterable<U> iterable) {
|
||||
return assertThat(stream).doesNotContainAnyElementsOf(iterable);
|
||||
}
|
||||
@@ -1107,7 +1107,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, U[] array) {
|
||||
return assertThat(stream).doesNotContain(array);
|
||||
}
|
||||
@@ -1130,7 +1130,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, @Repeated U elements) {
|
||||
return assertThat(stream).doesNotContain(elements);
|
||||
}
|
||||
@@ -1151,7 +1151,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, Iterable<U> iterable) {
|
||||
return assertThat(stream).doesNotContainSequence(iterable);
|
||||
}
|
||||
@@ -1169,7 +1169,7 @@ final class AssertJTemplates {
|
||||
|
||||
@AfterTemplate
|
||||
@SuppressWarnings("ObjectEnumerableDoesNotContainOneElement" /* Not a true singleton. */)
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, @Repeated U elements) {
|
||||
return assertThat(stream).doesNotContainSequence(elements);
|
||||
}
|
||||
@@ -1190,7 +1190,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, Iterable<U> iterable) {
|
||||
return assertThat(stream).hasSameElementsAs(iterable);
|
||||
}
|
||||
@@ -1211,7 +1211,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, U[] array) {
|
||||
return assertThat(stream).containsOnly(array);
|
||||
}
|
||||
@@ -1234,7 +1234,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, @Repeated U elements) {
|
||||
return assertThat(stream).containsOnly(elements);
|
||||
}
|
||||
@@ -1267,7 +1267,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, U[] iterable) {
|
||||
return assertThat(stream).isSubsetOf(iterable);
|
||||
}
|
||||
@@ -1290,7 +1290,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(Stream<S> stream, @Repeated U elements) {
|
||||
return assertThat(stream).isSubsetOf(elements);
|
||||
}
|
||||
@@ -1309,7 +1309,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(Stream<S> stream) {
|
||||
assertThat(stream).isEmpty();
|
||||
}
|
||||
@@ -1328,7 +1328,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(Stream<S> stream) {
|
||||
assertThat(stream).isNotEmpty();
|
||||
}
|
||||
@@ -1341,7 +1341,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(Stream<T> stream, int size) {
|
||||
assertThat(stream).hasSize(size);
|
||||
}
|
||||
@@ -1358,7 +1358,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(Predicate<T> predicate, T object) {
|
||||
assertThat(predicate).accepts(object);
|
||||
}
|
||||
@@ -1371,7 +1371,7 @@ final class AssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(Predicate<T> predicate, T object) {
|
||||
assertThat(predicate).rejects(object);
|
||||
}
|
||||
@@ -2212,7 +2212,7 @@ final class AssertJTemplates {
|
||||
// }
|
||||
//
|
||||
// @AfterTemplate
|
||||
// @UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
// @UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
// IterableAssert<E> after(Iterable<E> iterable, E expected) {
|
||||
// return assertThat(iterable).containsExactly(expected);
|
||||
// }
|
||||
|
||||
@@ -0,0 +1,363 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatIOException;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
import static org.assertj.core.api.Assertions.assertThatNullPointerException;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
import com.google.errorprone.refaster.annotation.AfterTemplate;
|
||||
import com.google.errorprone.refaster.annotation.BeforeTemplate;
|
||||
import com.google.errorprone.refaster.annotation.Repeated;
|
||||
import com.google.errorprone.refaster.annotation.UseImportPolicy;
|
||||
import java.io.IOException;
|
||||
import org.assertj.core.api.AbstractObjectAssert;
|
||||
import org.assertj.core.api.AbstractThrowableAssert;
|
||||
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
|
||||
|
||||
/**
|
||||
* Refaster templates related to AssertJ assertions over expressions that may throw a {@link
|
||||
* Throwable} subtype.
|
||||
*
|
||||
* <p>For reasons of consistency we prefer {@link
|
||||
* org.assertj.core.api.Assertions#assertThatThrownBy} over static methods for specific exception
|
||||
* types. Note that only the most common assertion expressions are rewritten here; covering all
|
||||
* cases would require the implementation of an Error Prone check instead.
|
||||
*/
|
||||
final class AssertJThrowingCallableTemplates {
|
||||
private AssertJThrowingCallableTemplates() {}
|
||||
|
||||
static final class AssertThatThrownByIllegalArgumentException {
|
||||
@BeforeTemplate
|
||||
AbstractObjectAssert<?, ?> before(ThrowingCallable throwingCallable) {
|
||||
return assertThatIllegalArgumentException().isThrownBy(throwingCallable);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractObjectAssert<?, ?> after(ThrowingCallable throwingCallable) {
|
||||
return assertThatThrownBy(throwingCallable).isInstanceOf(IllegalArgumentException.class);
|
||||
}
|
||||
}
|
||||
|
||||
static final class AssertThatThrownByIllegalArgumentExceptionHasMessage {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings(
|
||||
"AssertThatThrownByIllegalArgumentException" /* Matches strictly more specific expressions. */)
|
||||
AbstractObjectAssert<?, ?> before(ThrowingCallable throwingCallable, String message) {
|
||||
return assertThatIllegalArgumentException().isThrownBy(throwingCallable).withMessage(message);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractObjectAssert<?, ?> after(ThrowingCallable throwingCallable, String message) {
|
||||
return assertThatThrownBy(throwingCallable)
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
static final class AssertThatThrownByIllegalArgumentExceptionHasMessageStartingWith {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings(
|
||||
"AssertThatThrownByIllegalArgumentException" /* Matches strictly more specific expressions. */)
|
||||
AbstractObjectAssert<?, ?> before(ThrowingCallable throwingCallable, String message) {
|
||||
return assertThatIllegalArgumentException()
|
||||
.isThrownBy(throwingCallable)
|
||||
.withMessageStartingWith(message);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractObjectAssert<?, ?> after(ThrowingCallable throwingCallable, String message) {
|
||||
return assertThatThrownBy(throwingCallable)
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessageStartingWith(message);
|
||||
}
|
||||
}
|
||||
|
||||
static final class AssertThatThrownByIllegalArgumentExceptionHasMessageContaining {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings(
|
||||
"AssertThatThrownByIllegalArgumentException" /* Matches strictly more specific expressions. */)
|
||||
AbstractObjectAssert<?, ?> before(ThrowingCallable throwingCallable, String message) {
|
||||
return assertThatIllegalArgumentException()
|
||||
.isThrownBy(throwingCallable)
|
||||
.withMessageContaining(message);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractObjectAssert<?, ?> after(ThrowingCallable throwingCallable, String message) {
|
||||
return assertThatThrownBy(throwingCallable)
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessageContaining(message);
|
||||
}
|
||||
}
|
||||
|
||||
static final class AssertThatThrownByIllegalArgumentExceptionHasMessageNotContainingAny {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings(
|
||||
"AssertThatThrownByIllegalArgumentException" /* Matches strictly more specific expressions. */)
|
||||
AbstractObjectAssert<?, ?> before(
|
||||
ThrowingCallable throwingCallable, @Repeated CharSequence values) {
|
||||
return assertThatIllegalArgumentException()
|
||||
.isThrownBy(throwingCallable)
|
||||
.withMessageNotContainingAny(values);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractObjectAssert<?, ?> after(
|
||||
ThrowingCallable throwingCallable, @Repeated CharSequence values) {
|
||||
return assertThatThrownBy(throwingCallable)
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessageNotContainingAny(values);
|
||||
}
|
||||
}
|
||||
|
||||
static final class AssertThatThrownByIllegalStateException {
|
||||
@BeforeTemplate
|
||||
AbstractObjectAssert<?, ?> before(ThrowingCallable throwingCallable) {
|
||||
return assertThatIllegalStateException().isThrownBy(throwingCallable);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractObjectAssert<?, ?> after(ThrowingCallable throwingCallable) {
|
||||
return assertThatThrownBy(throwingCallable).isInstanceOf(IllegalStateException.class);
|
||||
}
|
||||
}
|
||||
|
||||
static final class AssertThatThrownByIllegalStateExceptionHasMessage {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings(
|
||||
"AssertThatThrownByIllegalStateException" /* Matches strictly more specific expressions. */)
|
||||
AbstractObjectAssert<?, ?> before(ThrowingCallable throwingCallable, String message) {
|
||||
return assertThatIllegalStateException().isThrownBy(throwingCallable).withMessage(message);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractObjectAssert<?, ?> after(ThrowingCallable throwingCallable, String message) {
|
||||
return assertThatThrownBy(throwingCallable)
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
static final class AssertThatThrownByIllegalStateExceptionHasMessageStartingWith {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings(
|
||||
"AssertThatThrownByIllegalStateException" /* Matches strictly more specific expressions. */)
|
||||
AbstractObjectAssert<?, ?> before(ThrowingCallable throwingCallable, String message) {
|
||||
return assertThatIllegalStateException()
|
||||
.isThrownBy(throwingCallable)
|
||||
.withMessageStartingWith(message);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractObjectAssert<?, ?> after(ThrowingCallable throwingCallable, String message) {
|
||||
return assertThatThrownBy(throwingCallable)
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessageStartingWith(message);
|
||||
}
|
||||
}
|
||||
|
||||
static final class AssertThatThrownByIllegalStateExceptionHasMessageContaining {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings(
|
||||
"AssertThatThrownByIllegalStateException" /* Matches strictly more specific expressions. */)
|
||||
AbstractObjectAssert<?, ?> before(ThrowingCallable throwingCallable, String message) {
|
||||
return assertThatIllegalStateException()
|
||||
.isThrownBy(throwingCallable)
|
||||
.withMessageContaining(message);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractObjectAssert<?, ?> after(ThrowingCallable throwingCallable, String message) {
|
||||
return assertThatThrownBy(throwingCallable)
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessageContaining(message);
|
||||
}
|
||||
}
|
||||
|
||||
static final class AssertThatThrownByIllegalStateExceptionHasMessageNotContaining {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings(
|
||||
"AssertThatThrownByIllegalStateException" /* Matches strictly more specific expressions. */)
|
||||
AbstractObjectAssert<?, ?> before(ThrowingCallable throwingCallable, String message) {
|
||||
return assertThatIllegalStateException()
|
||||
.isThrownBy(throwingCallable)
|
||||
.withMessageNotContaining(message);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractObjectAssert<?, ?> after(ThrowingCallable throwingCallable, String message) {
|
||||
return assertThatThrownBy(throwingCallable)
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessageNotContaining(message);
|
||||
}
|
||||
}
|
||||
|
||||
static final class AssertThatThrownByNullPointerException {
|
||||
@BeforeTemplate
|
||||
AbstractObjectAssert<?, ?> before(ThrowingCallable throwingCallable) {
|
||||
return assertThatNullPointerException().isThrownBy(throwingCallable);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractObjectAssert<?, ?> after(ThrowingCallable throwingCallable) {
|
||||
return assertThatThrownBy(throwingCallable).isInstanceOf(NullPointerException.class);
|
||||
}
|
||||
}
|
||||
|
||||
static final class AssertThatThrownByNullPointerExceptionHasMessage {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings(
|
||||
"AssertThatThrownByNullPointerException" /* Matches strictly more specific expressions. */)
|
||||
AbstractObjectAssert<?, ?> before(ThrowingCallable throwingCallable, String message) {
|
||||
return assertThatNullPointerException().isThrownBy(throwingCallable).withMessage(message);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractObjectAssert<?, ?> after(ThrowingCallable throwingCallable, String message) {
|
||||
return assertThatThrownBy(throwingCallable)
|
||||
.isInstanceOf(NullPointerException.class)
|
||||
.hasMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
static final class AssertThatThrownByNullPointerExceptionHasMessageStartingWith {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings(
|
||||
"AssertThatThrownByNullPointerException" /* Matches strictly more specific expressions. */)
|
||||
AbstractObjectAssert<?, ?> before(ThrowingCallable throwingCallable, String message) {
|
||||
return assertThatNullPointerException()
|
||||
.isThrownBy(throwingCallable)
|
||||
.withMessageStartingWith(message);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractObjectAssert<?, ?> after(ThrowingCallable throwingCallable, String message) {
|
||||
return assertThatThrownBy(throwingCallable)
|
||||
.isInstanceOf(NullPointerException.class)
|
||||
.hasMessageStartingWith(message);
|
||||
}
|
||||
}
|
||||
|
||||
static final class AssertThatThrownByIOException {
|
||||
@BeforeTemplate
|
||||
AbstractObjectAssert<?, ?> before(ThrowingCallable throwingCallable) {
|
||||
return assertThatIOException().isThrownBy(throwingCallable);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractObjectAssert<?, ?> after(ThrowingCallable throwingCallable) {
|
||||
return assertThatThrownBy(throwingCallable).isInstanceOf(IOException.class);
|
||||
}
|
||||
}
|
||||
|
||||
static final class AssertThatThrownByIOExceptionHasMessage {
|
||||
@SuppressWarnings(
|
||||
"AssertThatThrownByIOException" /* Matches strictly more specific expressions. */)
|
||||
@BeforeTemplate
|
||||
AbstractObjectAssert<?, ?> before(ThrowingCallable throwingCallable, String message) {
|
||||
return assertThatIOException().isThrownBy(throwingCallable).withMessage(message);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractObjectAssert<?, ?> after(ThrowingCallable throwingCallable, String message) {
|
||||
return assertThatThrownBy(throwingCallable)
|
||||
.isInstanceOf(IOException.class)
|
||||
.hasMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
static final class AssertThatThrownBy {
|
||||
@BeforeTemplate
|
||||
AbstractObjectAssert<?, ?> before(
|
||||
Class<? extends Throwable> exceptionType, ThrowingCallable throwingCallable) {
|
||||
return assertThatExceptionOfType(exceptionType).isThrownBy(throwingCallable);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractObjectAssert<?, ?> after(
|
||||
Class<? extends Throwable> exceptionType, ThrowingCallable throwingCallable) {
|
||||
return assertThatThrownBy(throwingCallable).isInstanceOf(exceptionType);
|
||||
}
|
||||
}
|
||||
|
||||
static final class AssertThatThrownByHasMessage {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings("AssertThatThrownBy" /* Matches strictly more specific expressions. */)
|
||||
AbstractObjectAssert<?, ?> before(
|
||||
Class<? extends Throwable> exceptionType,
|
||||
ThrowingCallable throwingCallable,
|
||||
String message) {
|
||||
return assertThatExceptionOfType(exceptionType)
|
||||
.isThrownBy(throwingCallable)
|
||||
.withMessage(message);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractObjectAssert<?, ?> after(
|
||||
Class<? extends Throwable> exceptionType,
|
||||
ThrowingCallable throwingCallable,
|
||||
String message) {
|
||||
return assertThatThrownBy(throwingCallable).isInstanceOf(exceptionType).hasMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX: Drop this template in favour of a generic Error Prone check which flags
|
||||
// `String.format(...)` arguments to a wide range of format methods.
|
||||
static final class AbstractThrowableAssertHasMessage {
|
||||
@BeforeTemplate
|
||||
AbstractThrowableAssert<?, ? extends Throwable> before(
|
||||
AbstractThrowableAssert<?, ? extends Throwable> abstractThrowableAssert,
|
||||
String message,
|
||||
@Repeated Object parameters) {
|
||||
return abstractThrowableAssert.hasMessage(String.format(message, parameters));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
AbstractThrowableAssert<?, ? extends Throwable> after(
|
||||
AbstractThrowableAssert<?, ? extends Throwable> abstractThrowableAssert,
|
||||
String message,
|
||||
@Repeated Object parameters) {
|
||||
return abstractThrowableAssert.hasMessage(message, parameters);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX: Drop this template in favour of a generic Error Prone check which flags
|
||||
// `String.format(...)` arguments to a wide range of format methods.
|
||||
static final class AbstractThrowableAssertWithFailMessage {
|
||||
@BeforeTemplate
|
||||
AbstractThrowableAssert<?, ? extends Throwable> before(
|
||||
AbstractThrowableAssert<?, ? extends Throwable> abstractThrowableAssert,
|
||||
String message,
|
||||
@Repeated Object args) {
|
||||
return abstractThrowableAssert.withFailMessage(String.format(message, args));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
AbstractThrowableAssert<?, ? extends Throwable> after(
|
||||
AbstractThrowableAssert<?, ? extends Throwable> abstractThrowableAssert,
|
||||
String message,
|
||||
@Repeated Object args) {
|
||||
return abstractThrowableAssert.withFailMessage(message, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,8 @@ 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 com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
|
||||
import static java.util.Collections.disjoint;
|
||||
import static java.util.Objects.checkIndex;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
@@ -11,7 +13,6 @@ import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Iterators;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.collect.Streams;
|
||||
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;
|
||||
@@ -92,7 +93,7 @@ final class AssortedTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ImmutableSet<T> after(Stream<T> stream) {
|
||||
return stream.collect(toImmutableEnumSet());
|
||||
}
|
||||
@@ -162,7 +163,7 @@ final class AssortedTemplates {
|
||||
|
||||
@AfterTemplate
|
||||
boolean after(Set<T> set1, Set<T> set2) {
|
||||
return Collections.disjoint(set1, set2);
|
||||
return disjoint(set1, set2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,15 +178,15 @@ final class AssortedTemplates {
|
||||
@BeforeTemplate
|
||||
boolean before(Collection<T> collection1, Collection<T> collection2) {
|
||||
return Refaster.anyOf(
|
||||
Collections.disjoint(ImmutableSet.copyOf(collection1), collection2),
|
||||
Collections.disjoint(new HashSet<>(collection1), collection2),
|
||||
Collections.disjoint(collection1, ImmutableSet.copyOf(collection2)),
|
||||
Collections.disjoint(collection1, new HashSet<>(collection2)));
|
||||
disjoint(ImmutableSet.copyOf(collection1), collection2),
|
||||
disjoint(new HashSet<>(collection1), collection2),
|
||||
disjoint(collection1, ImmutableSet.copyOf(collection2)),
|
||||
disjoint(collection1, new HashSet<>(collection2)));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
boolean after(Collection<T> collection1, Collection<T> collection2) {
|
||||
return Collections.disjoint(collection1, collection2);
|
||||
return disjoint(collection1, collection2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -187,7 +187,7 @@ final class CollectionTemplates {
|
||||
* Don't call {@link ImmutableCollection#asList()} if the result is going to be streamed; stream
|
||||
* directly.
|
||||
*/
|
||||
static final class ImmutableCollectionAsListToStream<T> {
|
||||
static final class ImmutableCollectionStream<T> {
|
||||
@BeforeTemplate
|
||||
Stream<T> before(ImmutableCollection<T> collection) {
|
||||
return collection.asList().stream();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
|
||||
import static java.util.Comparator.comparing;
|
||||
import static java.util.Comparator.comparingDouble;
|
||||
import static java.util.Comparator.comparingInt;
|
||||
@@ -11,7 +12,6 @@ import static java.util.function.Function.identity;
|
||||
import com.google.common.collect.Comparators;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
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;
|
||||
@@ -38,7 +38,7 @@ final class ComparatorTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
Comparator<T> after() {
|
||||
return naturalOrder();
|
||||
}
|
||||
@@ -52,7 +52,7 @@ final class ComparatorTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
Comparator<T> after() {
|
||||
return reverseOrder();
|
||||
}
|
||||
@@ -66,7 +66,7 @@ final class ComparatorTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
Comparator<T> after(Comparator<T> cmp) {
|
||||
return cmp;
|
||||
}
|
||||
@@ -93,7 +93,7 @@ final class ComparatorTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
Comparator<S> after(Comparator<S> cmp, Function<? super S, ? extends T> function) {
|
||||
return cmp.thenComparing(function, reverseOrder());
|
||||
}
|
||||
@@ -180,7 +180,7 @@ final class ComparatorTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
Comparator<T> after(Comparator<T> cmp) {
|
||||
return cmp.thenComparing(naturalOrder());
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static com.google.common.collect.ImmutableListMultimap.flatteningToImmutableListMultimap;
|
||||
import static com.google.common.collect.ImmutableListMultimap.toImmutableListMultimap;
|
||||
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
|
||||
import static java.util.function.Function.identity;
|
||||
|
||||
import com.google.common.collect.ImmutableListMultimap;
|
||||
@@ -12,7 +13,6 @@ import com.google.common.collect.Multimaps;
|
||||
import com.google.common.collect.SetMultimap;
|
||||
import com.google.common.collect.SortedSetMultimap;
|
||||
import com.google.common.collect.Streams;
|
||||
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;
|
||||
@@ -161,7 +161,7 @@ final class ImmutableListMultimapTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ImmutableListMultimap<K, V> after(Stream<E> stream) {
|
||||
return stream.collect(toImmutableListMultimap(e -> keyFunction(e), e -> valueFunction(e)));
|
||||
}
|
||||
@@ -272,17 +272,4 @@ final class ImmutableListMultimapTemplates {
|
||||
return ImmutableListMultimap.copyOf(Multimaps.transformValues(multimap, transformation));
|
||||
}
|
||||
}
|
||||
|
||||
/** Don't unnecessarily copy an {@link ImmutableListMultimap}. */
|
||||
static final class ImmutableListMultimapCopyOfImmutableListMultimap<K, V> {
|
||||
@BeforeTemplate
|
||||
ImmutableListMultimap<K, V> before(ImmutableListMultimap<K, V> multimap) {
|
||||
return ImmutableListMultimap.copyOf(multimap);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
ImmutableListMultimap<K, V> after(ImmutableListMultimap<K, V> multimap) {
|
||||
return multimap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@ package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static java.util.Comparator.naturalOrder;
|
||||
import static java.util.stream.Collectors.collectingAndThen;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
@@ -9,14 +12,12 @@ import static java.util.stream.Collectors.toList;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Streams;
|
||||
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.UseImportPolicy;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@@ -41,37 +42,6 @@ final class ImmutableListTemplates {
|
||||
}
|
||||
}
|
||||
|
||||
/** Prefer {@link ImmutableList#of()} over more contrived alternatives. */
|
||||
static final class EmptyImmutableList<T> {
|
||||
@BeforeTemplate
|
||||
ImmutableList<T> before() {
|
||||
return Refaster.anyOf(
|
||||
ImmutableList.<T>builder().build(), Stream.<T>empty().collect(toImmutableList()));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
ImmutableList<T> after() {
|
||||
return ImmutableList.of();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link ImmutableList#of(Object)} over alternatives that don't communicate the
|
||||
* immutability of the resulting list at the type level.
|
||||
*/
|
||||
// XXX: Note that this rewrite rule is incorrect for nullable elements.
|
||||
static final class SingletonImmutableList<T> {
|
||||
@BeforeTemplate
|
||||
List<T> before(T element) {
|
||||
return Collections.singletonList(element);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
ImmutableList<T> after(T element) {
|
||||
return ImmutableList.of(element);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link ImmutableList#copyOf(Iterable)} and variants over more contrived alternatives.
|
||||
*/
|
||||
@@ -122,7 +92,7 @@ final class ImmutableListTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ImmutableList<T> after(Stream<T> stream) {
|
||||
return stream.collect(toImmutableList());
|
||||
}
|
||||
@@ -181,9 +151,122 @@ final class ImmutableListTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ImmutableList<T> after(Stream<T> stream) {
|
||||
return stream.collect(toImmutableSet()).asList();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link ImmutableList#of()} over more contrived alternatives or alternatives that don't
|
||||
* communicate the immutability of the resulting list at the type level.
|
||||
*/
|
||||
// XXX: The `Stream` variant may be too contrived to warrant inclusion. Review its usage if/when
|
||||
// this and similar Refaster templates are replaced with an Error Prone check.
|
||||
static final class ImmutableListOf<T> {
|
||||
@BeforeTemplate
|
||||
List<T> before() {
|
||||
return Refaster.anyOf(
|
||||
ImmutableList.<T>builder().build(),
|
||||
Stream.<T>empty().collect(toImmutableList()),
|
||||
emptyList(),
|
||||
List.of());
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
ImmutableList<T> after() {
|
||||
return ImmutableList.of();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link ImmutableList#of(Object)} over more contrived alternatives or alternatives that
|
||||
* don't communicate the immutability of the resulting list at the type level.
|
||||
*/
|
||||
// XXX: Note that the replacement of `Collections#singletonList` is incorrect for nullable
|
||||
// elements.
|
||||
static final class ImmutableListOf1<T> {
|
||||
@BeforeTemplate
|
||||
List<T> before(T e1) {
|
||||
return Refaster.anyOf(
|
||||
ImmutableList.<T>builder().add(e1).build(), singletonList(e1), List.of(e1));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
ImmutableList<T> after(T e1) {
|
||||
return ImmutableList.of(e1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link ImmutableList#of(Object, Object)} over alternatives that don't communicate the
|
||||
* immutability of the resulting list at the type level.
|
||||
*/
|
||||
// XXX: Consider writing an Error Prone check which also flags straightforward
|
||||
// `ImmutableList.builder()` usages.
|
||||
static final class ImmutableListOf2<T> {
|
||||
@BeforeTemplate
|
||||
List<T> before(T e1, T e2) {
|
||||
return List.of(e1, e2);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
ImmutableList<T> after(T e1, T e2) {
|
||||
return ImmutableList.of(e1, e2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link ImmutableList#of(Object, Object, Object)} over alternatives that don't
|
||||
* communicate the immutability of the resulting list at the type level.
|
||||
*/
|
||||
// XXX: Consider writing an Error Prone check which also flags straightforward
|
||||
// `ImmutableList.builder()` usages.
|
||||
static final class ImmutableListOf3<T> {
|
||||
@BeforeTemplate
|
||||
List<T> before(T e1, T e2, T e3) {
|
||||
return List.of(e1, e2, e3);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
ImmutableList<T> after(T e1, T e2, T e3) {
|
||||
return ImmutableList.of(e1, e2, e3);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link ImmutableList#of(Object, Object, Object, Object)} over alternatives that don't
|
||||
* communicate the immutability of the resulting list at the type level.
|
||||
*/
|
||||
// XXX: Consider writing an Error Prone check which also flags straightforward
|
||||
// `ImmutableList.builder()` usages.
|
||||
static final class ImmutableListOf4<T> {
|
||||
@BeforeTemplate
|
||||
List<T> before(T e1, T e2, T e3, T e4) {
|
||||
return List.of(e1, e2, e3, e4);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
ImmutableList<T> after(T e1, T e2, T e3, T e4) {
|
||||
return ImmutableList.of(e1, e2, e3, e4);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link ImmutableList#of(Object, Object, Object, Object, Object)} over alternatives that
|
||||
* don't communicate the immutability of the resulting list at the type level.
|
||||
*/
|
||||
// XXX: Consider writing an Error Prone check which also flags straightforward
|
||||
// `ImmutableList.builder()` usages.
|
||||
static final class ImmutableListOf5<T> {
|
||||
@BeforeTemplate
|
||||
List<T> before(T e1, T e2, T e3, T e4, T e5) {
|
||||
return List.of(e1, e2, e3, e4, e5);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
ImmutableList<T> after(T e1, T e2, T e3, T e4, T e5) {
|
||||
return ImmutableList.of(e1, e2, e3, e4, e5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static com.google.common.collect.ImmutableMap.toImmutableMap;
|
||||
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
|
||||
import static java.util.Collections.emptyMap;
|
||||
import static java.util.Collections.singletonMap;
|
||||
import static java.util.function.Function.identity;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Streams;
|
||||
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;
|
||||
@@ -14,7 +16,6 @@ import com.google.errorprone.refaster.annotation.MayOptionallyUse;
|
||||
import com.google.errorprone.refaster.annotation.Placeholder;
|
||||
import com.google.errorprone.refaster.annotation.UseImportPolicy;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -40,41 +41,6 @@ final class ImmutableMapTemplates {
|
||||
}
|
||||
}
|
||||
|
||||
/** Prefer {@link ImmutableMap#of()} over more contrived alternatives. */
|
||||
static final class EmptyImmutableMap<K, V> {
|
||||
@BeforeTemplate
|
||||
ImmutableMap<K, V> before() {
|
||||
return ImmutableMap.<K, V>builder().build();
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
ImmutableMap<K, V> after() {
|
||||
return ImmutableMap.of();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link ImmutableMap#of(Object, Object)} over more contrived alternatives and
|
||||
* alternatives that don't communicate the immutability of the resulting map at the type level..
|
||||
*/
|
||||
// XXX: One can define variants for more than one key-value pair, but at some point the builder
|
||||
// actually produces nicer code. So it's not clear we should add Refaster templates for those
|
||||
// variants.
|
||||
// XXX: Note that the `singletonMap` rewrite rule is incorrect for nullable elements.
|
||||
static final class PairToImmutableMap<K, V> {
|
||||
@BeforeTemplate
|
||||
Map<K, V> before(K key, V value) {
|
||||
return Refaster.anyOf(
|
||||
ImmutableMap.<K, V>builder().put(key, value).build(),
|
||||
Collections.singletonMap(key, value));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
ImmutableMap<K, V> after(K key, V value) {
|
||||
return ImmutableMap.of(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
/** Prefer {@link ImmutableMap#of(Object, Object)} over more contrived alternatives. */
|
||||
static final class EntryToImmutableMap<K, V> {
|
||||
@BeforeTemplate
|
||||
@@ -178,7 +144,7 @@ final class ImmutableMapTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ImmutableMap<K, V> after(Stream<E> stream) {
|
||||
return stream.collect(toImmutableMap(e -> keyFunction(e), e -> valueFunction(e)));
|
||||
}
|
||||
@@ -242,16 +208,108 @@ final class ImmutableMapTemplates {
|
||||
}
|
||||
}
|
||||
|
||||
/** Don't unnecessarily copy an {@link ImmutableMap}. */
|
||||
static final class ImmutableMapCopyOfImmutableMap<K, V> {
|
||||
/**
|
||||
* Prefer {@link ImmutableMap#of()} over more contrived alternatives or alternatives that don't
|
||||
* communicate the immutability of the resulting map at the type level.
|
||||
*/
|
||||
static final class ImmutableMapOf<K, V> {
|
||||
@BeforeTemplate
|
||||
ImmutableMap<K, V> before(ImmutableMap<K, V> map) {
|
||||
return ImmutableMap.copyOf(map);
|
||||
Map<K, V> before() {
|
||||
return Refaster.anyOf(ImmutableMap.<K, V>builder().build(), emptyMap(), Map.of());
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
ImmutableMap<K, V> after(ImmutableMap<K, V> map) {
|
||||
return map;
|
||||
ImmutableMap<K, V> after() {
|
||||
return ImmutableMap.of();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link ImmutableMap#of(Object, Object)} over more contrived alternatives or alternatives
|
||||
* that don't communicate the immutability of the resulting map at the type level.
|
||||
*/
|
||||
// XXX: Note that the replacement of `Collections#singletonMap` is incorrect for nullable
|
||||
// elements.
|
||||
static final class ImmutableMapOf1<K, V> {
|
||||
@BeforeTemplate
|
||||
Map<K, V> before(K k1, V v1) {
|
||||
return Refaster.anyOf(
|
||||
ImmutableMap.<K, V>builder().put(k1, v1).build(), singletonMap(k1, v1), Map.of(k1, v1));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
ImmutableMap<K, V> after(K k1, V v1) {
|
||||
return ImmutableMap.of(k1, v1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link ImmutableMap#of(Object, Object, Object, Object)} over alternatives that don't
|
||||
* communicate the immutability of the resulting map at the type level.
|
||||
*/
|
||||
// XXX: Also rewrite the `ImmutableMap.builder()` variant?
|
||||
static final class ImmutableMapOf2<K, V> {
|
||||
@BeforeTemplate
|
||||
Map<K, V> before(K k1, V v1, K k2, V v2) {
|
||||
return Map.of(k1, v1, k2, v2);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
ImmutableMap<K, V> after(K k1, V v1, K k2, V v2) {
|
||||
return ImmutableMap.of(k1, v1, k2, v2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link ImmutableMap#of(Object, Object, Object, Object, Object, Object)} over
|
||||
* alternatives that don't communicate the immutability of the resulting map at the type level.
|
||||
*/
|
||||
// XXX: Also rewrite the `ImmutableMap.builder()` variant?
|
||||
static final class ImmutableMapOf3<K, V> {
|
||||
@BeforeTemplate
|
||||
Map<K, V> before(K k1, V v1, K k2, V v2, K k3, V v3) {
|
||||
return Map.of(k1, v1, k2, v2, k3, v3);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
ImmutableMap<K, V> after(K k1, V v1, K k2, V v2, K k3, V v3) {
|
||||
return ImmutableMap.of(k1, v1, k2, v2, k3, v3);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link ImmutableMap#of(Object, Object, Object, Object, Object, Object, Object, Object)}
|
||||
* over alternatives that don't communicate the immutability of the resulting map at the type
|
||||
* level.
|
||||
*/
|
||||
// XXX: Also rewrite the `ImmutableMap.builder()` variant?
|
||||
static final class ImmutableMapOf4<K, V> {
|
||||
@BeforeTemplate
|
||||
Map<K, V> before(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
|
||||
return Map.of(k1, v1, k2, v2, k3, v3, k4, v4);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
ImmutableMap<K, V> after(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
|
||||
return ImmutableMap.of(k1, v1, k2, v2, k3, v3, k4, v4);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link ImmutableMap#of(Object, Object, Object, Object, Object, Object, Object, Object,
|
||||
* Object, Object)} over alternatives that don't communicate the immutability of the resulting map
|
||||
* at the type level.
|
||||
*/
|
||||
// XXX: Also rewrite the `ImmutableMap.builder()` variant?
|
||||
static final class ImmutableMapOf5<K, V> {
|
||||
@BeforeTemplate
|
||||
Map<K, V> before(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) {
|
||||
return Map.of(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
ImmutableMap<K, V> after(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) {
|
||||
return ImmutableMap.of(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static com.google.common.collect.ImmutableMultiset.toImmutableMultiset;
|
||||
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
|
||||
import static java.util.stream.Collectors.collectingAndThen;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
import com.google.common.collect.ImmutableMultiset;
|
||||
import com.google.common.collect.Streams;
|
||||
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;
|
||||
@@ -96,22 +96,9 @@ final class ImmutableMultisetTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ImmutableMultiset<T> after(Stream<T> stream) {
|
||||
return stream.collect(toImmutableMultiset());
|
||||
}
|
||||
}
|
||||
|
||||
/** Don't unnecessarily copy an {@link ImmutableMultiset}. */
|
||||
static final class ImmutableMultisetCopyOfImmutableMultiset<T> {
|
||||
@BeforeTemplate
|
||||
ImmutableMultiset<T> before(ImmutableMultiset<T> multiset) {
|
||||
return ImmutableMultiset.copyOf(multiset);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
ImmutableMultiset<T> after(ImmutableMultiset<T> multiset) {
|
||||
return multiset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static com.google.common.collect.ImmutableSetMultimap.flatteningToImmutableSetMultimap;
|
||||
import static com.google.common.collect.ImmutableSetMultimap.toImmutableSetMultimap;
|
||||
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
|
||||
|
||||
import com.google.common.collect.ImmutableSetMultimap;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
@@ -10,7 +11,6 @@ import com.google.common.collect.Multimaps;
|
||||
import com.google.common.collect.SetMultimap;
|
||||
import com.google.common.collect.SortedSetMultimap;
|
||||
import com.google.common.collect.Streams;
|
||||
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;
|
||||
@@ -138,7 +138,7 @@ final class ImmutableSetMultimapTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ImmutableSetMultimap<K, V> after(Stream<E> stream) {
|
||||
return stream.collect(toImmutableSetMultimap(e -> keyFunction(e), e -> valueFunction(e)));
|
||||
}
|
||||
@@ -162,7 +162,7 @@ final class ImmutableSetMultimapTemplates {
|
||||
@AfterTemplate
|
||||
ImmutableSetMultimap<K, V2> after(Multimap<K, V1> multimap) {
|
||||
return ImmutableSetMultimap.copyOf(
|
||||
Multimaps.transformValues(multimap, v -> valueTransformation(v)));
|
||||
Multimaps.transformValues(multimap, e -> valueTransformation(e)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,17 +215,4 @@ final class ImmutableSetMultimapTemplates {
|
||||
return ImmutableSetMultimap.copyOf(Multimaps.transformValues(multimap, transformation));
|
||||
}
|
||||
}
|
||||
|
||||
/** Don't unnecessarily copy an {@link ImmutableSetMultimap}. */
|
||||
static final class ImmutableSetMultimapCopyOfImmutableSetMultimap<K, V> {
|
||||
@BeforeTemplate
|
||||
ImmutableSetMultimap<K, V> before(ImmutableSetMultimap<K, V> multimap) {
|
||||
return ImmutableSetMultimap.copyOf(multimap);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
ImmutableSetMultimap<K, V> after(ImmutableSetMultimap<K, V> multimap) {
|
||||
return multimap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
|
||||
import static java.util.Collections.emptySet;
|
||||
import static java.util.Collections.singleton;
|
||||
import static java.util.stream.Collectors.collectingAndThen;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static java.util.stream.Collectors.toSet;
|
||||
@@ -8,14 +11,12 @@ import static java.util.stream.Collectors.toSet;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets.SetView;
|
||||
import com.google.common.collect.Streams;
|
||||
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.UseImportPolicy;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
@@ -39,37 +40,6 @@ final class ImmutableSetTemplates {
|
||||
}
|
||||
}
|
||||
|
||||
/** Prefer {@link ImmutableSet#of()} over more contrived alternatives. */
|
||||
static final class EmptyImmutableSet<T> {
|
||||
@BeforeTemplate
|
||||
ImmutableSet<T> before() {
|
||||
return Refaster.anyOf(
|
||||
ImmutableSet.<T>builder().build(), Stream.<T>empty().collect(toImmutableSet()));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
ImmutableSet<T> after() {
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link ImmutableSet#of(Object)} over alternatives that don't communicate the
|
||||
* immutability of the resulting set at the type level.
|
||||
*/
|
||||
// XXX: Note that this rewrite rule is incorrect for nullable elements.
|
||||
static final class SingletonImmutableSet<T> {
|
||||
@BeforeTemplate
|
||||
Set<T> before(T element) {
|
||||
return Collections.singleton(element);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
ImmutableSet<T> after(T element) {
|
||||
return ImmutableSet.of(element);
|
||||
}
|
||||
}
|
||||
|
||||
/** Prefer {@link ImmutableSet#copyOf(Iterable)} and variants over more contrived alternatives. */
|
||||
static final class IterableToImmutableSet<T> {
|
||||
@BeforeTemplate
|
||||
@@ -120,25 +90,12 @@ final class ImmutableSetTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ImmutableSet<T> after(Stream<T> stream) {
|
||||
return stream.collect(toImmutableSet());
|
||||
}
|
||||
}
|
||||
|
||||
/** Don't unnecessarily copy an {@link ImmutableSet}. */
|
||||
static final class ImmutableSetCopyOfImmutableSet<T> {
|
||||
@BeforeTemplate
|
||||
ImmutableSet<T> before(ImmutableSet<T> set) {
|
||||
return ImmutableSet.copyOf(set);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
ImmutableSet<T> after(ImmutableSet<T> set) {
|
||||
return set;
|
||||
}
|
||||
}
|
||||
|
||||
/** Prefer {@link SetView#immutableCopy()} over the more verbose alternative. */
|
||||
static final class ImmutableSetCopyOfSetView<T> {
|
||||
@BeforeTemplate
|
||||
@@ -151,4 +108,115 @@ final class ImmutableSetTemplates {
|
||||
return set.immutableCopy();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link ImmutableSet#of()} over more contrived alternatives or alternatives that don't
|
||||
* communicate the immutability of the resulting set at the type level.
|
||||
*/
|
||||
// XXX: The `Stream` variant may be too contrived to warrant inclusion. Review its usage if/when
|
||||
// this and similar Refaster templates are replaced with an Error Prone check.
|
||||
static final class ImmutableSetOf<T> {
|
||||
@BeforeTemplate
|
||||
Set<T> before() {
|
||||
return Refaster.anyOf(
|
||||
ImmutableSet.<T>builder().build(),
|
||||
Stream.<T>empty().collect(toImmutableSet()),
|
||||
emptySet(),
|
||||
Set.of());
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
ImmutableSet<T> after() {
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link ImmutableSet#of(Object)} over more contrived alternatives or alternatives that
|
||||
* don't communicate the immutability of the resulting set at the type level.
|
||||
*/
|
||||
// XXX: Note that the replacement of `Collections#singleton` is incorrect for nullable elements.
|
||||
static final class ImmutableSetOf1<T> {
|
||||
@BeforeTemplate
|
||||
Set<T> before(T e1) {
|
||||
return Refaster.anyOf(ImmutableSet.<T>builder().add(e1).build(), singleton(e1), Set.of(e1));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
ImmutableSet<T> after(T e1) {
|
||||
return ImmutableSet.of(e1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link ImmutableSet#of(Object, Object)} over alternatives that don't communicate the
|
||||
* immutability of the resulting set at the type level.
|
||||
*/
|
||||
// XXX: Consider writing an Error Prone check which also flags straightforward
|
||||
// `ImmutableSet.builder()` usages.
|
||||
static final class ImmutableSetOf2<T> {
|
||||
@BeforeTemplate
|
||||
Set<T> before(T e1, T e2) {
|
||||
return Set.of(e1, e2);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
ImmutableSet<T> after(T e1, T e2) {
|
||||
return ImmutableSet.of(e1, e2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link ImmutableSet#of(Object, Object, Object)} over alternatives that don't communicate
|
||||
* the immutability of the resulting set at the type level.
|
||||
*/
|
||||
// XXX: Consider writing an Error Prone check which also flags straightforward
|
||||
// `ImmutableSet.builder()` usages.
|
||||
static final class ImmutableSetOf3<T> {
|
||||
@BeforeTemplate
|
||||
Set<T> before(T e1, T e2, T e3) {
|
||||
return Set.of(e1, e2, e3);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
ImmutableSet<T> after(T e1, T e2, T e3) {
|
||||
return ImmutableSet.of(e1, e2, e3);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link ImmutableSet#of(Object, Object, Object, Object)} over alternatives that don't
|
||||
* communicate the immutability of the resulting set at the type level.
|
||||
*/
|
||||
// XXX: Consider writing an Error Prone check which also flags straightforward
|
||||
// `ImmutableSet.builder()` usages.
|
||||
static final class ImmutableSetOf4<T> {
|
||||
@BeforeTemplate
|
||||
Set<T> before(T e1, T e2, T e3, T e4) {
|
||||
return Set.of(e1, e2, e3, e4);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
ImmutableSet<T> after(T e1, T e2, T e3, T e4) {
|
||||
return ImmutableSet.of(e1, e2, e3, e4);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link ImmutableSet#of(Object, Object, Object, Object, Object)} over alternatives that
|
||||
* don't communicate the immutability of the resulting set at the type level.
|
||||
*/
|
||||
// XXX: Consider writing an Error Prone check which also flags straightforward
|
||||
// `ImmutableSet.builder()` usages.
|
||||
static final class ImmutableSetOf5<T> {
|
||||
@BeforeTemplate
|
||||
Set<T> before(T e1, T e2, T e3, T e4, T e5) {
|
||||
return Set.of(e1, e2, e3, e4, e5);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
ImmutableSet<T> after(T e1, T e2, T e3, T e4, T e5) {
|
||||
return ImmutableSet.of(e1, e2, e3, e4, e5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static com.google.common.collect.ImmutableSortedMultiset.toImmutableSortedMultiset;
|
||||
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
|
||||
import static java.util.Comparator.naturalOrder;
|
||||
import static java.util.stream.Collectors.collectingAndThen;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
@@ -8,7 +9,6 @@ import static java.util.stream.Collectors.toList;
|
||||
import com.google.common.collect.ImmutableMultiset;
|
||||
import com.google.common.collect.ImmutableSortedMultiset;
|
||||
import com.google.common.collect.Streams;
|
||||
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;
|
||||
@@ -140,7 +140,7 @@ final class ImmutableSortedMultisetTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ImmutableSortedMultiset<T> after(Stream<T> stream) {
|
||||
return stream.collect(toImmutableSortedMultiset(naturalOrder()));
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static com.google.common.collect.ImmutableSortedSet.toImmutableSortedSet;
|
||||
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
|
||||
import static java.util.Comparator.naturalOrder;
|
||||
import static java.util.stream.Collectors.collectingAndThen;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
@@ -8,7 +9,6 @@ import static java.util.stream.Collectors.toList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
import com.google.common.collect.Streams;
|
||||
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;
|
||||
@@ -140,7 +140,7 @@ final class ImmutableSortedSetTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ImmutableSortedSet<T> after(Stream<T> stream) {
|
||||
return stream.collect(toImmutableSortedSet(naturalOrder()));
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
|
||||
import static org.junit.jupiter.params.provider.Arguments.arguments;
|
||||
|
||||
import com.google.errorprone.refaster.ImportPolicy;
|
||||
import com.google.errorprone.refaster.annotation.AfterTemplate;
|
||||
import com.google.errorprone.refaster.annotation.BeforeTemplate;
|
||||
import com.google.errorprone.refaster.annotation.Repeated;
|
||||
@@ -21,7 +21,7 @@ final class JUnitTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
Arguments after(@Repeated T objects) {
|
||||
return arguments(objects);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
|
||||
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;
|
||||
import com.google.errorprone.refaster.annotation.AfterTemplate;
|
||||
import com.google.errorprone.refaster.annotation.BeforeTemplate;
|
||||
@@ -51,7 +51,7 @@ final class MapEntryTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
Comparator<Map.Entry<K, V>> after() {
|
||||
return comparingByKey();
|
||||
}
|
||||
@@ -65,7 +65,7 @@ final class MapEntryTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
Comparator<Map.Entry<K, V>> after(Comparator<? super K> cmp) {
|
||||
return comparingByKey(cmp);
|
||||
}
|
||||
@@ -80,7 +80,7 @@ final class MapEntryTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
Comparator<Map.Entry<K, V>> after() {
|
||||
return comparingByValue();
|
||||
}
|
||||
@@ -94,7 +94,7 @@ final class MapEntryTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
Comparator<Map.Entry<K, V>> after(Comparator<? super V> cmp) {
|
||||
return comparingByValue(cmp);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import com.google.errorprone.refaster.ImportPolicy;
|
||||
import com.google.errorprone.refaster.annotation.AfterTemplate;
|
||||
import com.google.errorprone.refaster.annotation.BeforeTemplate;
|
||||
import com.google.errorprone.refaster.annotation.UseImportPolicy;
|
||||
@@ -26,7 +26,7 @@ final class MockitoTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
VerificationMode after() {
|
||||
return never();
|
||||
}
|
||||
@@ -43,7 +43,7 @@ final class MockitoTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
T after(T mock) {
|
||||
return verify(mock);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
|
||||
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;
|
||||
import com.google.errorprone.refaster.annotation.BeforeTemplate;
|
||||
import com.google.errorprone.refaster.annotation.UseImportPolicy;
|
||||
@@ -24,7 +24,7 @@ final class NullTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
T after(T first, T second) {
|
||||
return requireNonNullElse(first, second);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
|
||||
|
||||
import com.google.common.collect.Streams;
|
||||
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;
|
||||
@@ -103,7 +104,7 @@ final class OptionalTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
Optional<T> after(Iterator<T> it) {
|
||||
return Streams.stream(it).findFirst();
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static com.google.common.collect.MoreCollectors.toOptional;
|
||||
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import com.google.common.collect.MoreCollectors;
|
||||
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;
|
||||
@@ -142,6 +143,35 @@ final class ReactorTemplates {
|
||||
}
|
||||
}
|
||||
|
||||
/** Prefer {@link Flux#concatMap(Function)} over more contrived alternatives. */
|
||||
static final class FluxConcatMap<T, S> {
|
||||
@BeforeTemplate
|
||||
Flux<S> before(Flux<T> flux, Function<? super T, ? extends Publisher<? extends S>> function) {
|
||||
return Refaster.anyOf(flux.flatMap(function, 1), flux.flatMapSequential(function, 1));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Flux<S> after(Flux<T> flux, Function<? super T, ? extends Publisher<? extends S>> function) {
|
||||
return flux.concatMap(function);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link Flux#concatMapIterable(Function)} over {@link Flux#concatMapIterable(Function)},
|
||||
* as the former has equivalent semantics but a clearer name.
|
||||
*/
|
||||
static final class FluxConcatMapIterable<T, S> {
|
||||
@BeforeTemplate
|
||||
Flux<S> before(Flux<T> flux, Function<? super T, ? extends Iterable<? extends S>> function) {
|
||||
return flux.flatMapIterable(function);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Flux<S> after(Flux<T> flux, Function<? super T, ? extends Iterable<? extends S>> function) {
|
||||
return flux.concatMapIterable(function);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't use {@link Mono#flatMapMany(Function)} to implicitly convert a {@link Mono} to a {@link
|
||||
* Flux}.
|
||||
@@ -174,19 +204,6 @@ final class ReactorTemplates {
|
||||
}
|
||||
}
|
||||
|
||||
/** Don't unnecessarily invoke {@link Flux#concat(Publisher)}. */
|
||||
static final class FluxIdentity<T> {
|
||||
@BeforeTemplate
|
||||
Flux<T> before(Flux<T> flux) {
|
||||
return Flux.concat(flux);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Flux<T> after(Flux<T> flux) {
|
||||
return flux;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer a collection using {@link MoreCollectors#toOptional()} over more contrived alternatives.
|
||||
*/
|
||||
@@ -201,7 +218,7 @@ final class ReactorTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
Mono<Optional<T>> after(Mono<T> mono) {
|
||||
return mono.flux().collect(toOptional());
|
||||
}
|
||||
@@ -304,7 +321,9 @@ final class ReactorTemplates {
|
||||
static final class StepVerifierLastStepVerifyErrorClass<T extends Throwable> {
|
||||
@BeforeTemplate
|
||||
Duration before(StepVerifier.LastStep step, Class<T> clazz) {
|
||||
return step.expectError(clazz).verify();
|
||||
return Refaster.anyOf(
|
||||
step.expectError(clazz).verify(),
|
||||
step.verifyErrorSatisfies(t -> assertThat(t).isInstanceOf(clazz)));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
|
||||
@@ -41,11 +41,9 @@ final class RxJava2AdapterTemplates {
|
||||
@BeforeTemplate
|
||||
Publisher<T> before(Flowable<T> flowable) {
|
||||
return Refaster.anyOf(
|
||||
Flux.from(flowable),
|
||||
flowable.compose(Flux::from),
|
||||
flowable.to(Flux::from),
|
||||
flowable.as(Flux::from),
|
||||
RxJava2Adapter.flowableToFlux(flowable),
|
||||
flowable.compose(RxJava2Adapter::flowableToFlux),
|
||||
flowable.to(RxJava2Adapter::flowableToFlux));
|
||||
}
|
||||
@@ -67,7 +65,6 @@ final class RxJava2AdapterTemplates {
|
||||
Flowable.fromPublisher(flux),
|
||||
flux.transform(Flowable::fromPublisher),
|
||||
flux.as(Flowable::fromPublisher),
|
||||
RxJava2Adapter.fluxToFlowable(flux),
|
||||
flux.transform(RxJava2Adapter::fluxToFlowable));
|
||||
}
|
||||
|
||||
@@ -140,7 +137,6 @@ final class RxJava2AdapterTemplates {
|
||||
Flowable.fromPublisher(mono),
|
||||
mono.transform(Flowable::fromPublisher),
|
||||
mono.as(Flowable::fromPublisher),
|
||||
RxJava2Adapter.monoToFlowable(mono),
|
||||
mono.transform(RxJava2Adapter::monoToFlowable));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
|
||||
import static java.util.Comparator.naturalOrder;
|
||||
import static java.util.Comparator.reverseOrder;
|
||||
import static java.util.function.Predicate.not;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
|
||||
import com.google.common.collect.Streams;
|
||||
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;
|
||||
@@ -18,12 +19,31 @@ import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collector;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/** Refaster templates related to expressions dealing with {@link Stream}s. */
|
||||
final class StreamTemplates {
|
||||
private StreamTemplates() {}
|
||||
|
||||
/**
|
||||
* Prefer {@link Collectors#joining()} over {@link Collectors#joining(CharSequence)} with an empty
|
||||
* delimiter string.
|
||||
*/
|
||||
static final class Joining {
|
||||
@BeforeTemplate
|
||||
Collector<CharSequence, ?, String> before() {
|
||||
return joining("");
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
Collector<CharSequence, ?, String> after() {
|
||||
return joining();
|
||||
}
|
||||
}
|
||||
|
||||
/** Prefer {@link Stream#empty()} over less clear alternatives. */
|
||||
static final class EmptyStream<T> {
|
||||
@BeforeTemplate
|
||||
@@ -216,7 +236,7 @@ final class StreamTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
Optional<T> after(Stream<T> stream) {
|
||||
return stream.min(naturalOrder());
|
||||
}
|
||||
@@ -242,7 +262,7 @@ final class StreamTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
Optional<T> after(Stream<T> stream) {
|
||||
return stream.max(naturalOrder());
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.assertj.core.api.Assertions.fail;
|
||||
@@ -17,7 +18,6 @@ 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;
|
||||
import com.google.errorprone.refaster.annotation.UseImportPolicy;
|
||||
@@ -96,7 +96,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(String message) {
|
||||
fail(message);
|
||||
}
|
||||
@@ -110,7 +110,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(String message, Throwable throwable) {
|
||||
fail(message, throwable);
|
||||
}
|
||||
@@ -123,7 +123,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(boolean condition) {
|
||||
assertThat(condition).isTrue();
|
||||
}
|
||||
@@ -136,7 +136,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(boolean condition, String message) {
|
||||
assertThat(condition).withFailMessage(message).isTrue();
|
||||
}
|
||||
@@ -149,7 +149,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(boolean condition) {
|
||||
assertThat(condition).isFalse();
|
||||
}
|
||||
@@ -162,7 +162,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(boolean condition, String message) {
|
||||
assertThat(condition).withFailMessage(message).isFalse();
|
||||
}
|
||||
@@ -175,7 +175,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(Object object) {
|
||||
assertThat(object).isNull();
|
||||
}
|
||||
@@ -188,7 +188,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(Object object, String message) {
|
||||
assertThat(object).withFailMessage(message).isNull();
|
||||
}
|
||||
@@ -201,7 +201,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(Object object) {
|
||||
assertThat(object).isNotNull();
|
||||
}
|
||||
@@ -214,7 +214,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(Object object, String message) {
|
||||
assertThat(object).withFailMessage(message).isNotNull();
|
||||
}
|
||||
@@ -227,7 +227,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(Object actual, Object expected) {
|
||||
assertThat(actual).isSameAs(expected);
|
||||
}
|
||||
@@ -240,7 +240,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(Object actual, Object expected, String message) {
|
||||
assertThat(actual).withFailMessage(message).isSameAs(expected);
|
||||
}
|
||||
@@ -253,7 +253,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(Object actual, Object expected) {
|
||||
assertThat(actual).isNotSameAs(expected);
|
||||
}
|
||||
@@ -266,7 +266,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(Object actual, Object expected, String message) {
|
||||
assertThat(actual).withFailMessage(message).isNotSameAs(expected);
|
||||
}
|
||||
@@ -329,7 +329,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(Object actual, Object expected) {
|
||||
assertThat(actual).isEqualTo(expected);
|
||||
}
|
||||
@@ -392,7 +392,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(Object actual, Object expected, String message) {
|
||||
assertThat(actual).withFailMessage(message).isEqualTo(expected);
|
||||
}
|
||||
@@ -405,7 +405,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(float actual, float expected, float delta) {
|
||||
assertThat(actual).isCloseTo(expected, offset(delta));
|
||||
}
|
||||
@@ -418,7 +418,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(float actual, float expected, float delta, String message) {
|
||||
assertThat(actual).withFailMessage(message).isCloseTo(expected, offset(delta));
|
||||
}
|
||||
@@ -431,7 +431,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(double actual, double expected, double delta) {
|
||||
assertThat(actual).isCloseTo(expected, offset(delta));
|
||||
}
|
||||
@@ -444,7 +444,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(double actual, double expected, double delta, String message) {
|
||||
assertThat(actual).withFailMessage(message).isCloseTo(expected, offset(delta));
|
||||
}
|
||||
@@ -497,7 +497,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(Object[] actual, Object[] expected) {
|
||||
assertThat(actual).containsExactly(expected);
|
||||
}
|
||||
@@ -550,7 +550,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(Object[] actual, Object[] expected, String message) {
|
||||
assertThat(actual).withFailMessage(message).containsExactly(expected);
|
||||
}
|
||||
@@ -563,7 +563,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(Object[] actual, Object[] expected) {
|
||||
assertThat(actual).containsExactlyInAnyOrder(expected);
|
||||
}
|
||||
@@ -576,7 +576,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(Object[] actual, Object[] expected, String message) {
|
||||
assertThat(actual).withFailMessage(message).containsExactlyInAnyOrder(expected);
|
||||
}
|
||||
@@ -589,7 +589,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
<S, T extends S> void after(Iterator<S> actual, Iterator<T> expected) {
|
||||
// XXX: This is not `null`-safe.
|
||||
// XXX: The `ImmutableList.copyOf` should actually *not* be imported statically.
|
||||
@@ -604,7 +604,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
<S, T extends S> void after(Iterator<S> actual, Iterator<T> expected, String message) {
|
||||
// XXX: This is not `null`-safe.
|
||||
// XXX: The `ImmutableList.copyOf` should actually *not* be imported statically.
|
||||
@@ -629,7 +629,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
<S, T extends S> void after(Iterable<S> actual, Iterable<T> expected) {
|
||||
assertThat(actual).containsExactlyElementsOf(expected);
|
||||
}
|
||||
@@ -647,7 +647,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
<S, T extends S> void after(Iterable<S> actual, Iterable<T> expected, String message) {
|
||||
assertThat(actual).withFailMessage(message).containsExactlyElementsOf(expected);
|
||||
}
|
||||
@@ -660,7 +660,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
<S, T extends S> void after(Set<S> actual, Set<T> expected) {
|
||||
assertThat(actual).hasSameElementsAs(expected);
|
||||
}
|
||||
@@ -673,7 +673,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
<S, T extends S> void after(Set<S> actual, Set<T> expected, String message) {
|
||||
assertThat(actual).withFailMessage(message).hasSameElementsAs(expected);
|
||||
}
|
||||
@@ -741,7 +741,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(Object actual, Object expected) {
|
||||
assertThat(actual).isNotEqualTo(expected);
|
||||
}
|
||||
@@ -809,7 +809,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(Object actual, Object expected, String message) {
|
||||
assertThat(actual).withFailMessage(message).isNotEqualTo(expected);
|
||||
}
|
||||
@@ -822,7 +822,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(float actual, float expected, float delta) {
|
||||
assertThat(actual).isNotCloseTo(expected, offset(delta));
|
||||
}
|
||||
@@ -835,7 +835,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(float actual, float expected, float delta, String message) {
|
||||
assertThat(actual).withFailMessage(message).isNotCloseTo(expected, offset(delta));
|
||||
}
|
||||
@@ -848,7 +848,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(double actual, double expected, double delta) {
|
||||
assertThat(actual).isNotCloseTo(expected, offset(delta));
|
||||
}
|
||||
@@ -861,7 +861,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(double actual, double expected, double delta, String message) {
|
||||
assertThat(actual).withFailMessage(message).isNotCloseTo(expected, offset(delta));
|
||||
}
|
||||
@@ -874,7 +874,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(ThrowingCallable runnable) {
|
||||
assertThatThrownBy(runnable);
|
||||
}
|
||||
@@ -887,7 +887,7 @@ final class TestNGToAssertJTemplates {
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS)
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after(ThrowingCallable runnable, Class<T> clazz) {
|
||||
assertThatThrownBy(runnable).isInstanceOf(clazz);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static java.time.ZoneOffset.UTC;
|
||||
|
||||
import com.google.errorprone.refaster.Refaster;
|
||||
import com.google.errorprone.refaster.annotation.AfterTemplate;
|
||||
import com.google.errorprone.refaster.annotation.AlsoNegation;
|
||||
@@ -17,6 +19,7 @@ import java.time.ZoneOffset;
|
||||
import java.time.chrono.ChronoLocalDate;
|
||||
import java.time.chrono.ChronoLocalDateTime;
|
||||
import java.time.chrono.ChronoZonedDateTime;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.time.temporal.TemporalUnit;
|
||||
|
||||
/** Refaster templates related to expressions dealing with time. */
|
||||
@@ -49,13 +52,26 @@ final class TimeTemplates {
|
||||
ZoneId.of("UTC"),
|
||||
ZoneId.of("+0"),
|
||||
ZoneId.of("-0"),
|
||||
ZoneOffset.UTC.normalized(),
|
||||
ZoneId.from(ZoneOffset.UTC));
|
||||
UTC.normalized(),
|
||||
ZoneId.from(UTC));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
ZoneOffset after() {
|
||||
return ZoneOffset.UTC;
|
||||
return UTC;
|
||||
}
|
||||
}
|
||||
|
||||
/** Prefer {@link Instant#atOffset(ZoneOffset)} over the more verbose alternative. */
|
||||
static final class InstantAtOffset {
|
||||
@BeforeTemplate
|
||||
OffsetDateTime before(Instant instant, ZoneOffset zoneOffset) {
|
||||
return OffsetDateTime.ofInstant(instant, zoneOffset);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
OffsetDateTime after(Instant instant, ZoneOffset zoneOffset) {
|
||||
return instant.atOffset(zoneOffset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +80,7 @@ final class TimeTemplates {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings("TimeZoneUsage")
|
||||
Clock before() {
|
||||
return Clock.system(ZoneOffset.UTC);
|
||||
return Clock.system(UTC);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -310,8 +326,86 @@ final class TimeTemplates {
|
||||
}
|
||||
}
|
||||
|
||||
/** Prefer {@link Duration#ofDays(long)} over alternative representations. */
|
||||
static final class DurationOfDays {
|
||||
@BeforeTemplate
|
||||
Duration before(long amount) {
|
||||
return Duration.of(amount, ChronoUnit.DAYS);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Duration after(long amount) {
|
||||
return Duration.ofDays(amount);
|
||||
}
|
||||
}
|
||||
|
||||
/** Prefer {@link Duration#ofHours(long)} over alternative representations. */
|
||||
static final class DurationOfHours {
|
||||
@BeforeTemplate
|
||||
Duration before(long amount) {
|
||||
return Duration.of(amount, ChronoUnit.HOURS);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Duration after(long amount) {
|
||||
return Duration.ofHours(amount);
|
||||
}
|
||||
}
|
||||
|
||||
/** Prefer {@link Duration#ofMillis(long)} over alternative representations. */
|
||||
static final class DurationOfMillis {
|
||||
@BeforeTemplate
|
||||
Duration before(long amount) {
|
||||
return Duration.of(amount, ChronoUnit.MILLIS);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Duration after(long amount) {
|
||||
return Duration.ofMillis(amount);
|
||||
}
|
||||
}
|
||||
|
||||
/** Prefer {@link Duration#ofMinutes(long)} over alternative representations. */
|
||||
static final class DurationOfMinutes {
|
||||
@BeforeTemplate
|
||||
Duration before(long amount) {
|
||||
return Duration.of(amount, ChronoUnit.MINUTES);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Duration after(long amount) {
|
||||
return Duration.ofMinutes(amount);
|
||||
}
|
||||
}
|
||||
|
||||
/** Prefer {@link Duration#ofNanos(long)} over alternative representations. */
|
||||
static final class DurationOfNanos {
|
||||
@BeforeTemplate
|
||||
Duration before(long amount) {
|
||||
return Duration.of(amount, ChronoUnit.NANOS);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Duration after(long amount) {
|
||||
return Duration.ofNanos(amount);
|
||||
}
|
||||
}
|
||||
|
||||
/** Prefer {@link Duration#ofSeconds(long)} over alternative representations. */
|
||||
static final class DurationOfSeconds {
|
||||
@BeforeTemplate
|
||||
Duration before(long amount) {
|
||||
return Duration.of(amount, ChronoUnit.SECONDS);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Duration after(long amount) {
|
||||
return Duration.ofSeconds(amount);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't unnecessarily convert two and from milliseconds. (This way nanosecond precision is
|
||||
* Don't unnecessarily convert to and from milliseconds. (This way nanosecond precision is
|
||||
* retained.)
|
||||
*
|
||||
* <p><strong>Warning:</strong> this rewrite rule increases precision!
|
||||
@@ -329,7 +423,7 @@ final class TimeTemplates {
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't unnecessarily convert two and from milliseconds. (This way nanosecond precision is
|
||||
* Don't unnecessarily convert to and from milliseconds. (This way nanosecond precision is
|
||||
* retained.)
|
||||
*
|
||||
* <p><strong>Warning:</strong> this rewrite rule increases precision!
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.BugCheckerRefactoringTestHelper.newInstance;
|
||||
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper.FixChoosers;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
final class FluxFlatMapUsageCheckTest {
|
||||
private final CompilationTestHelper compilationTestHelper =
|
||||
CompilationTestHelper.newInstance(FluxFlatMapUsageCheck.class, getClass());
|
||||
private final BugCheckerRefactoringTestHelper refactoringTestHelper =
|
||||
newInstance(FluxFlatMapUsageCheck.class, getClass());
|
||||
|
||||
@Test
|
||||
void identification() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"import java.util.function.BiFunction;",
|
||||
"import java.util.function.Function;",
|
||||
"import reactor.core.publisher.Mono;",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).flatMap(Flux::just);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).<String>flatMap(i -> Flux.just(String.valueOf(i)));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).flatMapSequential(Flux::just);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).<String>flatMapSequential(i -> Flux.just(String.valueOf(i)));",
|
||||
"",
|
||||
" Mono.just(1).flatMap(Mono::just);",
|
||||
" Flux.just(1).concatMap(Flux::just);",
|
||||
"",
|
||||
" Flux.just(1).flatMap(Flux::just, 1);",
|
||||
" Flux.just(1).flatMap(Flux::just, 1, 1);",
|
||||
" Flux.just(1).flatMap(Flux::just, throwable -> Flux.empty(), Flux::empty);",
|
||||
"",
|
||||
" Flux.just(1).flatMapSequential(Flux::just, 1);",
|
||||
" Flux.just(1).flatMapSequential(Flux::just, 1, 1);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" this.<String, Flux<String>>sink(Flux::flatMap);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" this.<Integer, Flux<Integer>>sink(Flux::<Integer>flatMap);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" this.<String, Flux<String>>sink(Flux::flatMapSequential);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" this.<Integer, Flux<Integer>>sink(Flux::<Integer>flatMapSequential);",
|
||||
"",
|
||||
" this.<String, Mono<String>>sink(Mono::flatMap);",
|
||||
" }",
|
||||
"",
|
||||
" private <T, P> void sink(BiFunction<P, Function<T, P>, P> fun) {}",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
void replacementFirstSuggestedFix() {
|
||||
refactoringTestHelper
|
||||
.setFixChooser(FixChoosers.FIRST)
|
||||
.addInputLines(
|
||||
"in/A.java",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Flux.just(1).flatMap(Flux::just);",
|
||||
" Flux.just(1).flatMapSequential(Flux::just);",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"out/A.java",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Flux.just(1).concatMap(Flux::just);",
|
||||
" Flux.just(1).concatMap(Flux::just);",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
void replacementSecondSuggestedFix() {
|
||||
refactoringTestHelper
|
||||
.setFixChooser(FixChoosers.SECOND)
|
||||
.addInputLines(
|
||||
"in/A.java",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"",
|
||||
"class A {",
|
||||
" private static final int MAX_CONCURRENCY = 8;",
|
||||
"",
|
||||
" void m() {",
|
||||
" Flux.just(1).flatMap(Flux::just);",
|
||||
" Flux.just(1).flatMapSequential(Flux::just);",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"out/A.java",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"",
|
||||
"class A {",
|
||||
" private static final int MAX_CONCURRENCY = 8;",
|
||||
"",
|
||||
" void m() {",
|
||||
" Flux.just(1).flatMap(Flux::just, MAX_CONCURRENCY);",
|
||||
" Flux.just(1).flatMapSequential(Flux::just, MAX_CONCURRENCY);",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,308 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper.FixChoosers;
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
final class IdentityConversionCheckTest {
|
||||
private final CompilationTestHelper compilationTestHelper =
|
||||
CompilationTestHelper.newInstance(IdentityConversionCheck.class, getClass());
|
||||
private final BugCheckerRefactoringTestHelper refactoringTestHelper =
|
||||
BugCheckerRefactoringTestHelper.newInstance(IdentityConversionCheck.class, getClass());
|
||||
|
||||
@Test
|
||||
void identification() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"Foo.java",
|
||||
"import com.google.common.collect.ImmutableBiMap;",
|
||||
"import com.google.common.collect.ImmutableList;",
|
||||
"import com.google.common.collect.ImmutableListMultimap;",
|
||||
"import com.google.common.collect.ImmutableMap;",
|
||||
"import com.google.common.collect.ImmutableMultimap;",
|
||||
"import com.google.common.collect.ImmutableMultiset;",
|
||||
"import com.google.common.collect.ImmutableRangeMap;",
|
||||
"import com.google.common.collect.ImmutableRangeSet;",
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import com.google.common.collect.ImmutableSetMultimap;",
|
||||
"import com.google.common.collect.ImmutableTable;",
|
||||
"import reactor.adapter.rxjava.RxJava2Adapter;",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"import reactor.core.publisher.Mono;",
|
||||
"",
|
||||
"public final class Foo {",
|
||||
" public void foo() {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Boolean b1 = Boolean.valueOf(Boolean.FALSE);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Boolean b2 = Boolean.valueOf(false);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" boolean b3 = Boolean.valueOf(Boolean.FALSE);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" boolean b4 = Boolean.valueOf(false);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Byte byte1 = Byte.valueOf((Byte) Byte.MIN_VALUE);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Byte byte2 = Byte.valueOf(Byte.MIN_VALUE);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" byte byte3 = Byte.valueOf((Byte) Byte.MIN_VALUE);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" byte byte4 = Byte.valueOf(Byte.MIN_VALUE);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Character c1 = Character.valueOf((Character) 'a');",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Character c2 = Character.valueOf('a');",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" char c3 = Character.valueOf((Character) 'a');",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" char c4 = Character.valueOf('a');",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Double d1 = Double.valueOf((Double) 0.0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Double d2 = Double.valueOf(0.0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" double d3 = Double.valueOf((Double) 0.0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" double d4 = Double.valueOf(0.0);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Float f1 = Float.valueOf((Float) 0.0F);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Float f2 = Float.valueOf(0.0F);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" float f3 = Float.valueOf((Float) 0.0F);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" float f4 = Float.valueOf(0.0F);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Integer i1 = Integer.valueOf((Integer) 1);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Integer i2 = Integer.valueOf(1);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" int i3 = Integer.valueOf((Integer) 1);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" int i4 = Integer.valueOf(1);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Long l1 = Long.valueOf((Long) 1L);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Long l2 = Long.valueOf(1L);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" long l3 = Long.valueOf((Long) 1L);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" long l4 = Long.valueOf(1L);",
|
||||
"",
|
||||
" Long l5 = Long.valueOf((Integer) 1);",
|
||||
" Long l6 = Long.valueOf(1);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" long l7 = Long.valueOf((Integer) 1);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" long l8 = Long.valueOf(1);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Short s1 = Short.valueOf((Short) Short.MIN_VALUE);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Short s2 = Short.valueOf(Short.MIN_VALUE);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" short s3 = Short.valueOf((Short) Short.MIN_VALUE);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" short s4 = Short.valueOf(Short.MIN_VALUE);",
|
||||
"",
|
||||
" String str1 = String.valueOf(0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String str2 = String.valueOf(\"1\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableBiMap<Object, Object> o1 = ImmutableBiMap.copyOf(ImmutableBiMap.of());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableList<Object> o2 = ImmutableList.copyOf(ImmutableList.of());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableListMultimap<Object, Object> o3 = ImmutableListMultimap.copyOf(ImmutableListMultimap.of());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableMap<Object, Object> o4 = ImmutableMap.copyOf(ImmutableMap.of());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableMultimap<Object, Object> o5 = ImmutableMultimap.copyOf(ImmutableMultimap.of());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableMultiset<Object> o6 = ImmutableMultiset.copyOf(ImmutableMultiset.of());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableRangeMap<String, Object> o7 = ImmutableRangeMap.copyOf(ImmutableRangeMap.of());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableRangeSet<String> o8 = ImmutableRangeSet.copyOf(ImmutableRangeSet.of());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableSet<Object> o9 = ImmutableSet.copyOf(ImmutableSet.of());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableSetMultimap<Object, Object> o10 = ImmutableSetMultimap.copyOf(ImmutableSetMultimap.of());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableTable<Object, Object, Object> o11 = ImmutableTable.copyOf(ImmutableTable.of());",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux<Integer> flux1 = Flux.just(1).flatMap(e -> RxJava2Adapter.fluxToFlowable(Flux.just(2)));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux<Integer> flux2 = Flux.concat(Flux.just(1));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux<Integer> flux3 = Flux.firstWithSignal(Flux.just(1));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux<Integer> flux4 = Flux.from(Flux.just(1));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux<Integer> flux5 = Flux.merge(Flux.just(1));",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Mono<Integer> m1 = Mono.from(Mono.just(1));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Mono<Integer> m2 = Mono.fromDirect(Mono.just(1));",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
void replacementFirstSuggestedFix() {
|
||||
refactoringTestHelper
|
||||
.setFixChooser(FixChoosers.FIRST)
|
||||
.addInputLines(
|
||||
"Foo.java",
|
||||
"import static org.mockito.Mockito.when;",
|
||||
"",
|
||||
"import com.google.common.collect.ImmutableCollection;",
|
||||
"import com.google.common.collect.ImmutableList;",
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import java.util.Collection;",
|
||||
"import java.util.ArrayList;",
|
||||
"import org.reactivestreams.Publisher;",
|
||||
"import reactor.adapter.rxjava.RxJava2Adapter;",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"import reactor.core.publisher.Mono;",
|
||||
"",
|
||||
"public final class Foo {",
|
||||
" public void foo() {",
|
||||
" ImmutableSet<Object> set1 = ImmutableSet.copyOf(ImmutableSet.of());",
|
||||
" ImmutableSet<Object> set2 = ImmutableSet.copyOf(ImmutableList.of());",
|
||||
"",
|
||||
" ImmutableCollection<Integer> list1 = ImmutableList.copyOf(ImmutableList.of(1));",
|
||||
" ImmutableCollection<Integer> list2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1)));",
|
||||
"",
|
||||
" Collection<Integer> c1 = ImmutableSet.copyOf(ImmutableSet.of(1));",
|
||||
" Collection<Integer> c2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1)));",
|
||||
"",
|
||||
" Flux<Integer> f1 = Flux.just(1).flatMap(e -> RxJava2Adapter.fluxToFlowable(Flux.just(2)));",
|
||||
" Flux<Integer> f2 = Flux.concat(Flux.just(3));",
|
||||
" Publisher<Integer> f3 = Flux.firstWithSignal(Flux.just(4));",
|
||||
" Publisher<Integer> f4 = Flux.from(Flux.just(5));",
|
||||
" Publisher<Integer> f5 = Flux.merge(Flux.just(6));",
|
||||
"",
|
||||
" Mono<Integer> m1 = Mono.from(Mono.just(7));",
|
||||
" Publisher<Integer> m2 = Mono.fromDirect(Mono.just(8));",
|
||||
"",
|
||||
" bar(Flux.concat(Flux.just(9)));",
|
||||
" bar(Mono.from(Mono.just(10)));",
|
||||
"",
|
||||
" Object o1 = ImmutableSet.copyOf(ImmutableList.of());",
|
||||
" Object o2 = ImmutableSet.copyOf(ImmutableSet.of());",
|
||||
"",
|
||||
" when(\"foo\".contains(\"f\"))",
|
||||
" .thenAnswer(inv-> ImmutableSet.copyOf(ImmutableList.of(1)));",
|
||||
" }",
|
||||
"",
|
||||
" void bar(Publisher<Integer> publisher) {}",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"Foo.java",
|
||||
"import static org.mockito.Mockito.when;",
|
||||
"",
|
||||
"import com.google.common.collect.ImmutableCollection;",
|
||||
"import com.google.common.collect.ImmutableList;",
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import java.util.Collection;",
|
||||
"import java.util.ArrayList;",
|
||||
"import org.reactivestreams.Publisher;",
|
||||
"import reactor.adapter.rxjava.RxJava2Adapter;",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"import reactor.core.publisher.Mono;",
|
||||
"",
|
||||
"public final class Foo {",
|
||||
" public void foo() {",
|
||||
" ImmutableSet<Object> set1 = ImmutableSet.of();",
|
||||
" ImmutableSet<Object> set2 = ImmutableSet.copyOf(ImmutableList.of());",
|
||||
"",
|
||||
" ImmutableCollection<Integer> list1 = ImmutableList.of(1);",
|
||||
" ImmutableCollection<Integer> list2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1)));",
|
||||
"",
|
||||
" Collection<Integer> c1 = ImmutableSet.of(1);",
|
||||
" Collection<Integer> c2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1)));",
|
||||
"",
|
||||
" Flux<Integer> f1 = Flux.just(1).flatMap(e -> Flux.just(2));",
|
||||
" Flux<Integer> f2 = Flux.just(3);",
|
||||
" Publisher<Integer> f3 = Flux.just(4);",
|
||||
" Publisher<Integer> f4 = Flux.just(5);",
|
||||
" Publisher<Integer> f5 = Flux.just(6);",
|
||||
"",
|
||||
" Mono<Integer> m1 = Mono.just(7);",
|
||||
" Publisher<Integer> m2 = Mono.just(8);",
|
||||
"",
|
||||
" bar(Flux.just(9));",
|
||||
" bar(Mono.just(10));",
|
||||
"",
|
||||
" Object o1 = ImmutableSet.copyOf(ImmutableList.of());",
|
||||
" Object o2 = ImmutableSet.of();",
|
||||
"",
|
||||
" when(\"foo\".contains(\"f\"))",
|
||||
" .thenAnswer(inv-> ImmutableSet.copyOf(ImmutableList.of(1)));",
|
||||
" }",
|
||||
"",
|
||||
" void bar(Publisher<Integer> publisher) {}",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
|
||||
@Test
|
||||
void replacementSecondSuggestedFix() {
|
||||
refactoringTestHelper
|
||||
.setFixChooser(FixChoosers.SECOND)
|
||||
.addInputLines(
|
||||
"Foo.java",
|
||||
"import com.google.common.collect.ImmutableCollection;",
|
||||
"import com.google.common.collect.ImmutableList;",
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import java.util.ArrayList;",
|
||||
"import reactor.adapter.rxjava.RxJava2Adapter;",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"import reactor.core.publisher.Mono;",
|
||||
"",
|
||||
"public final class Foo {",
|
||||
" public void foo() {",
|
||||
" ImmutableSet<Object> set1 = ImmutableSet.copyOf(ImmutableSet.of());",
|
||||
" ImmutableSet<Object> set2 = ImmutableSet.copyOf(ImmutableList.of());",
|
||||
"",
|
||||
" ImmutableCollection<Integer> list1 = ImmutableList.copyOf(ImmutableList.of(1));",
|
||||
" ImmutableCollection<Integer> list2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1)));",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"Foo.java",
|
||||
"import com.google.common.collect.ImmutableCollection;",
|
||||
"import com.google.common.collect.ImmutableList;",
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import java.util.ArrayList;",
|
||||
"import reactor.adapter.rxjava.RxJava2Adapter;",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"import reactor.core.publisher.Mono;",
|
||||
"",
|
||||
"public final class Foo {",
|
||||
" public void foo() {",
|
||||
" @SuppressWarnings(\"IdentityConversion\")",
|
||||
" ImmutableSet<Object> set1 = ImmutableSet.copyOf(ImmutableSet.of());",
|
||||
" ImmutableSet<Object> set2 = ImmutableSet.copyOf(ImmutableList.of());",
|
||||
"",
|
||||
" @SuppressWarnings(\"IdentityConversion\")",
|
||||
" ImmutableCollection<Integer> list1 = ImmutableList.copyOf(ImmutableList.of(1));",
|
||||
" ImmutableCollection<Integer> list2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1)));",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public final class JUnitMethodDeclarationCheckTest {
|
||||
final class JUnitMethodDeclarationCheckTest {
|
||||
private final CompilationTestHelper compilationTestHelper =
|
||||
CompilationTestHelper.newInstance(JUnitMethodDeclarationCheck.class, getClass());
|
||||
private final BugCheckerRefactoringTestHelper refactoringTestHelper =
|
||||
@@ -16,6 +16,8 @@ public final class JUnitMethodDeclarationCheckTest {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"import static org.junit.jupiter.params.provider.Arguments.arguments;",
|
||||
"",
|
||||
"import org.junit.jupiter.api.AfterAll;",
|
||||
"import org.junit.jupiter.api.AfterEach;",
|
||||
"import org.junit.jupiter.api.BeforeAll;",
|
||||
@@ -81,6 +83,14 @@ public final class JUnitMethodDeclarationCheckTest {
|
||||
" protected void testNonTestMethod3() {}",
|
||||
" private void testNonTestMethod4() {}",
|
||||
" @Test void test5() {}",
|
||||
"",
|
||||
" // BUG: Diagnostic contains: (but note that a method named `overload` already exists in this class)",
|
||||
" @Test void testOverload() {}",
|
||||
" void overload() {}",
|
||||
" // BUG: Diagnostic contains: (but note that `arguments` is already statically imported)",
|
||||
" @Test void testArguments() {}",
|
||||
" // BUG: Diagnostic contains: (but note that `public` is a reserved keyword)",
|
||||
" @Test void testPublic() {}",
|
||||
"}")
|
||||
.addSourceLines(
|
||||
"B.java",
|
||||
@@ -122,6 +132,26 @@ public final class JUnitMethodDeclarationCheckTest {
|
||||
" @Override public void testNonTestMethod2() {}",
|
||||
" @Override protected void testNonTestMethod3() {}",
|
||||
" @Override @Test void test5() {}",
|
||||
"",
|
||||
" @Override @Test void testOverload() {}",
|
||||
" @Override void overload() {}",
|
||||
" @Override @Test void testArguments() {}",
|
||||
" @Override @Test void testPublic() {}",
|
||||
"}")
|
||||
.addSourceLines(
|
||||
"C.java",
|
||||
"import org.junit.jupiter.api.AfterAll;",
|
||||
"import org.junit.jupiter.api.BeforeAll;",
|
||||
"import org.junit.jupiter.api.Test;",
|
||||
"",
|
||||
"abstract class C {",
|
||||
" @BeforeAll public void setUp() {}",
|
||||
" @Test void testMethod1() {}",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @AfterAll private void tearDown() {}",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Test final void testMethod2() {}",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
@@ -131,6 +161,8 @@ public final class JUnitMethodDeclarationCheckTest {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/A.java",
|
||||
"import static org.junit.jupiter.params.provider.Arguments.arguments;",
|
||||
"",
|
||||
"import org.junit.jupiter.api.AfterAll;",
|
||||
"import org.junit.jupiter.api.AfterEach;",
|
||||
"import org.junit.jupiter.api.BeforeAll;",
|
||||
@@ -151,9 +183,16 @@ public final class JUnitMethodDeclarationCheckTest {
|
||||
" @Test public void baz() {}",
|
||||
" @RepeatedTest(2) private void qux() {}",
|
||||
" @ParameterizedTest protected void quux() {}",
|
||||
"",
|
||||
" @Test public void testOverload() {}",
|
||||
" void overload() {}",
|
||||
" @Test protected void testArguments() {}",
|
||||
" @Test private void testClass() {}",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"out/A.java",
|
||||
"import static org.junit.jupiter.params.provider.Arguments.arguments;",
|
||||
"",
|
||||
"import org.junit.jupiter.api.AfterAll;",
|
||||
"import org.junit.jupiter.api.AfterEach;",
|
||||
"import org.junit.jupiter.api.BeforeAll;",
|
||||
@@ -174,6 +213,11 @@ public final class JUnitMethodDeclarationCheckTest {
|
||||
" @Test void baz() {}",
|
||||
" @RepeatedTest(2) void qux() {}",
|
||||
" @ParameterizedTest void quux() {}",
|
||||
"",
|
||||
" @Test void testOverload() {}",
|
||||
" void overload() {}",
|
||||
" @Test void testArguments() {}",
|
||||
" @Test void testClass() {}",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.BugPattern.SeverityLevel;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
@@ -19,7 +19,7 @@ public final class MethodMatcherFactoryTest {
|
||||
/** A {@link BugChecker} which flags method invocations matched by {@link #TEST_MATCHER}. */
|
||||
@BugPattern(
|
||||
name = "MatchedMethodsFlagger",
|
||||
severity = SeverityLevel.SUGGESTION,
|
||||
severity = SUGGESTION,
|
||||
summary = "Flags methods matched by the test matcher.")
|
||||
public static final class MatchedMethodsFlagger extends BugChecker
|
||||
implements MethodInvocationTreeMatcher {
|
||||
|
||||
@@ -426,8 +426,6 @@ public final class PrimitiveComparisonCheckTest {
|
||||
.doTest();
|
||||
}
|
||||
|
||||
// XXX: If the explicit `<A, BoxedPrimitive>` generic type information was necessary, then this
|
||||
// replacement drops too much information.
|
||||
@Test
|
||||
void replacementWithPrimitiveVariants() {
|
||||
refactoringTestHelper
|
||||
@@ -436,21 +434,35 @@ public final class PrimitiveComparisonCheckTest {
|
||||
"import java.util.Comparator;",
|
||||
"",
|
||||
"interface A extends Comparable<A> {",
|
||||
" Comparator<A> bCmp = Comparator.<A, Byte>comparing(o -> (byte) 0);",
|
||||
" Comparator<A> cCmp = Comparator.<A, Character>comparing(o -> (char) 0);",
|
||||
" Comparator<A> sCmp = Comparator.<A, Short>comparing(o -> (short) 0);",
|
||||
" Comparator<A> iCmp = Comparator.<A, Integer>comparing(o -> 0);",
|
||||
" Comparator<A> lCmp = Comparator.<A, Long>comparing(o -> 0L);",
|
||||
" Comparator<A> fCmp = Comparator.<A, Float>comparing(o -> 0.0f);",
|
||||
" Comparator<A> dCmp = Comparator.<A, Double>comparing(o -> 0.0);",
|
||||
" Comparator<A> bCmp = Comparator.comparing(o -> (byte) 0);",
|
||||
" Comparator<A> bCmp2 = Comparator.<A, Byte>comparing(o -> (byte) 0);",
|
||||
" Comparator<A> cCmp = Comparator.comparing(o -> (char) 0);",
|
||||
" Comparator<A> cCmp2 = Comparator.<A, Character>comparing(o -> (char) 0);",
|
||||
" Comparator<A> sCmp = Comparator.comparing(o -> (short) 0);",
|
||||
" Comparator<A> sCmp2 = Comparator.<A, Short>comparing(o -> (short) 0);",
|
||||
" Comparator<A> iCmp = Comparator.comparing(o -> 0);",
|
||||
" Comparator<A> iCmp2 = Comparator.<A, Integer>comparing(o -> 0);",
|
||||
" Comparator<A> lCmp = Comparator.comparing(o -> 0L);",
|
||||
" Comparator<A> lCmp2 = Comparator.<A, Long>comparing(o -> 0L);",
|
||||
" Comparator<A> fCmp = Comparator.comparing(o -> 0.0f);",
|
||||
" Comparator<A> fCmp2 = Comparator.<A, Float>comparing(o -> 0.0f);",
|
||||
" Comparator<A> dCmp = Comparator.comparing(o -> 0.0);",
|
||||
" Comparator<A> dCmp2 = Comparator.<A, Double>comparing(o -> 0.0);",
|
||||
"",
|
||||
" default void m() {",
|
||||
" bCmp.<Byte>thenComparing(o -> (byte) 0);",
|
||||
" bCmp.thenComparing(o -> (byte) 0);",
|
||||
" cCmp.<Character>thenComparing(o -> (char) 0);",
|
||||
" cCmp.thenComparing(o -> (char) 0);",
|
||||
" sCmp.<Short>thenComparing(o -> (short) 0);",
|
||||
" sCmp.thenComparing(o -> (short) 0);",
|
||||
" iCmp.<Integer>thenComparing(o -> 0);",
|
||||
" iCmp.thenComparing(o -> 0);",
|
||||
" lCmp.<Long>thenComparing(o -> 0L);",
|
||||
" lCmp.thenComparing(o -> 0L);",
|
||||
" fCmp.<Float>thenComparing(o -> 0.0f);",
|
||||
" fCmp.thenComparing(o -> 0.0f);",
|
||||
" dCmp.<Double>thenComparing(o -> 0.0);",
|
||||
" dCmp.thenComparing(o -> 0.0);",
|
||||
" }",
|
||||
"}")
|
||||
@@ -460,28 +472,40 @@ public final class PrimitiveComparisonCheckTest {
|
||||
"",
|
||||
"interface A extends Comparable<A> {",
|
||||
" Comparator<A> bCmp = Comparator.comparingInt(o -> (byte) 0);",
|
||||
" Comparator<A> bCmp2 = Comparator.<A>comparingInt(o -> (byte) 0);",
|
||||
" Comparator<A> cCmp = Comparator.comparingInt(o -> (char) 0);",
|
||||
" Comparator<A> cCmp2 = Comparator.<A>comparingInt(o -> (char) 0);",
|
||||
" Comparator<A> sCmp = Comparator.comparingInt(o -> (short) 0);",
|
||||
" Comparator<A> sCmp2 = Comparator.<A>comparingInt(o -> (short) 0);",
|
||||
" Comparator<A> iCmp = Comparator.comparingInt(o -> 0);",
|
||||
" Comparator<A> iCmp2 = Comparator.<A>comparingInt(o -> 0);",
|
||||
" Comparator<A> lCmp = Comparator.comparingLong(o -> 0L);",
|
||||
" Comparator<A> lCmp2 = Comparator.<A>comparingLong(o -> 0L);",
|
||||
" Comparator<A> fCmp = Comparator.comparingDouble(o -> 0.0f);",
|
||||
" Comparator<A> fCmp2 = Comparator.<A>comparingDouble(o -> 0.0f);",
|
||||
" Comparator<A> dCmp = Comparator.comparingDouble(o -> 0.0);",
|
||||
" Comparator<A> dCmp2 = Comparator.<A>comparingDouble(o -> 0.0);",
|
||||
"",
|
||||
" default void m() {",
|
||||
" bCmp.thenComparingInt(o -> (byte) 0);",
|
||||
" bCmp.thenComparingInt(o -> (byte) 0);",
|
||||
" cCmp.thenComparingInt(o -> (char) 0);",
|
||||
" cCmp.thenComparingInt(o -> (char) 0);",
|
||||
" sCmp.thenComparingInt(o -> (short) 0);",
|
||||
" sCmp.thenComparingInt(o -> (short) 0);",
|
||||
" iCmp.thenComparingInt(o -> 0);",
|
||||
" iCmp.thenComparingInt(o -> 0);",
|
||||
" lCmp.thenComparingLong(o -> 0L);",
|
||||
" lCmp.thenComparingLong(o -> 0L);",
|
||||
" fCmp.thenComparingDouble(o -> 0.0f);",
|
||||
" fCmp.thenComparingDouble(o -> 0.0f);",
|
||||
" dCmp.thenComparingDouble(o -> 0.0);",
|
||||
" dCmp.thenComparingDouble(o -> 0.0);",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
|
||||
// XXX: If the explicit `<A>` generic type information was necessary, then this replacement drops
|
||||
// too much information.
|
||||
@Test
|
||||
void replacementWithBoxedVariants() {
|
||||
refactoringTestHelper
|
||||
@@ -490,13 +514,20 @@ public final class PrimitiveComparisonCheckTest {
|
||||
"import java.util.Comparator;",
|
||||
"",
|
||||
"interface A extends Comparable<A> {",
|
||||
" Comparator<A> bCmp = Comparator.<A>comparingInt(o -> Byte.valueOf((byte) 0));",
|
||||
" Comparator<A> cCmp = Comparator.<A>comparingInt(o -> Character.valueOf((char) 0));",
|
||||
" Comparator<A> sCmp = Comparator.<A>comparingInt(o -> Short.valueOf((short) 0));",
|
||||
" Comparator<A> iCmp = Comparator.<A>comparingInt(o -> Integer.valueOf(0));",
|
||||
" Comparator<A> lCmp = Comparator.<A>comparingLong(o -> Long.valueOf(0));",
|
||||
" Comparator<A> fCmp = Comparator.<A>comparingDouble(o -> Float.valueOf(0));",
|
||||
" Comparator<A> dCmp = Comparator.<A>comparingDouble(o -> Double.valueOf(0));",
|
||||
" Comparator<A> bCmp = Comparator.comparingInt(o -> Byte.valueOf((byte) 0));",
|
||||
" Comparator<A> bCmp2 = Comparator.<A>comparingInt(o -> Byte.valueOf((byte) 0));",
|
||||
" Comparator<A> cCmp = Comparator.comparingInt(o -> Character.valueOf((char) 0));",
|
||||
" Comparator<A> cCmp2 = Comparator.<A>comparingInt(o -> Character.valueOf((char) 0));",
|
||||
" Comparator<A> sCmp = Comparator.comparingInt(o -> Short.valueOf((short) 0));",
|
||||
" Comparator<A> sCmp2 = Comparator.<A>comparingInt(o -> Short.valueOf((short) 0));",
|
||||
" Comparator<A> iCmp = Comparator.comparingInt(o -> Integer.valueOf(0));",
|
||||
" Comparator<A> iCmp2 = Comparator.<A>comparingInt(o -> Integer.valueOf(0));",
|
||||
" Comparator<A> lCmp = Comparator.comparingLong(o -> Long.valueOf(0));",
|
||||
" Comparator<A> lCmp2 = Comparator.<A>comparingLong(o -> Long.valueOf(0));",
|
||||
" Comparator<A> fCmp = Comparator.comparingDouble(o -> Float.valueOf(0));",
|
||||
" Comparator<A> fCmp2 = Comparator.<A>comparingDouble(o -> Float.valueOf(0));",
|
||||
" Comparator<A> dCmp = Comparator.comparingDouble(o -> Double.valueOf(0));",
|
||||
" Comparator<A> dCmp2 = Comparator.<A>comparingDouble(o -> Double.valueOf(0));",
|
||||
"",
|
||||
" default void m() {",
|
||||
" bCmp.thenComparingInt(o -> Byte.valueOf((byte) 0));",
|
||||
@@ -514,12 +545,19 @@ public final class PrimitiveComparisonCheckTest {
|
||||
"",
|
||||
"interface A extends Comparable<A> {",
|
||||
" Comparator<A> bCmp = Comparator.comparing(o -> Byte.valueOf((byte) 0));",
|
||||
" Comparator<A> bCmp2 = Comparator.<A, Byte>comparing(o -> Byte.valueOf((byte) 0));",
|
||||
" Comparator<A> cCmp = Comparator.comparing(o -> Character.valueOf((char) 0));",
|
||||
" Comparator<A> cCmp2 = Comparator.<A, Character>comparing(o -> Character.valueOf((char) 0));",
|
||||
" Comparator<A> sCmp = Comparator.comparing(o -> Short.valueOf((short) 0));",
|
||||
" Comparator<A> sCmp2 = Comparator.<A, Short>comparing(o -> Short.valueOf((short) 0));",
|
||||
" Comparator<A> iCmp = Comparator.comparing(o -> Integer.valueOf(0));",
|
||||
" Comparator<A> iCmp2 = Comparator.<A, Integer>comparing(o -> Integer.valueOf(0));",
|
||||
" Comparator<A> lCmp = Comparator.comparing(o -> Long.valueOf(0));",
|
||||
" Comparator<A> lCmp2 = Comparator.<A, Long>comparing(o -> Long.valueOf(0));",
|
||||
" Comparator<A> fCmp = Comparator.comparing(o -> Float.valueOf(0));",
|
||||
" Comparator<A> fCmp2 = Comparator.<A, Float>comparing(o -> Float.valueOf(0));",
|
||||
" Comparator<A> dCmp = Comparator.comparing(o -> Double.valueOf(0));",
|
||||
" Comparator<A> dCmp2 = Comparator.<A, Double>comparing(o -> Double.valueOf(0));",
|
||||
"",
|
||||
" default void m() {",
|
||||
" bCmp.thenComparing(o -> Byte.valueOf((byte) 0));",
|
||||
|
||||
@@ -34,10 +34,12 @@ public final class RefasterCheckTest {
|
||||
"AssertJInteger",
|
||||
"AssertJLong",
|
||||
"AssertJNumber",
|
||||
"AssertJMap",
|
||||
"AssertJObject",
|
||||
"AssertJOptional",
|
||||
"AssertJShort",
|
||||
"AssertJString",
|
||||
"AssertJThrowingCallable",
|
||||
"Assorted",
|
||||
"BigDecimal",
|
||||
"Collection",
|
||||
@@ -166,7 +168,24 @@ public final class RefasterCheckTest {
|
||||
|
||||
private BugCheckerRefactoringTestHelper createRestrictedRefactoringTestHelper(
|
||||
String namePattern) {
|
||||
return BugCheckerRefactoringTestHelper.newInstance(RefasterCheck.class, getClass())
|
||||
return BugCheckerRefactoringTestHelper.newInstance(
|
||||
RefasterCheck.class, getRefasterTemplateCollectionClass())
|
||||
.setArgs("-XepOpt:Refaster:NamePattern=" + namePattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an arbitrary Refaster template collection class inside the {@code
|
||||
* tech.picnic.errorprone.refastertemplates} package, enabling {@link
|
||||
* BugCheckerRefactoringTestHelper} to load test resources from said package.
|
||||
*/
|
||||
private Class<?> getRefasterTemplateCollectionClass() {
|
||||
try {
|
||||
return Class.forName(
|
||||
"tech.picnic.errorprone.refastertemplates.AssortedTemplates",
|
||||
/* initialize= */ false,
|
||||
getClass().getClassLoader());
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new IllegalStateException("Failed to load Refaster template collection class", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package tech.picnic.errorprone.bugpatterns;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public final class RequestMappingAnnotationCheckTest {
|
||||
final class RequestMappingAnnotationCheckTest {
|
||||
private final CompilationTestHelper compilationTestHelper =
|
||||
CompilationTestHelper.newInstance(RequestMappingAnnotationCheck.class, getClass());
|
||||
|
||||
@@ -13,6 +13,9 @@ public final class RequestMappingAnnotationCheckTest {
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"import java.io.InputStream;",
|
||||
"import java.time.ZoneId;",
|
||||
"import java.util.Locale;",
|
||||
"import java.util.TimeZone;",
|
||||
"import javax.servlet.http.HttpServletRequest;",
|
||||
"import javax.servlet.http.HttpServletResponse;",
|
||||
"import org.springframework.http.HttpMethod;",
|
||||
@@ -27,7 +30,11 @@ public final class RequestMappingAnnotationCheckTest {
|
||||
"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.NativeWebRequest;",
|
||||
"import org.springframework.web.context.request.WebRequest;",
|
||||
"import org.springframework.web.server.ServerWebExchange;",
|
||||
"import org.springframework.web.util.UriBuilder;",
|
||||
"import org.springframework.web.util.UriComponentsBuilder;",
|
||||
"",
|
||||
"interface A {",
|
||||
" A noMapping();",
|
||||
@@ -38,10 +45,17 @@ public final class RequestMappingAnnotationCheckTest {
|
||||
" @PostMapping A properRequestHeader(@RequestHeader String header);",
|
||||
" @PutMapping A properRequestParam(@RequestParam String param);",
|
||||
" @RequestMapping A properInputStream(InputStream input);",
|
||||
" @RequestMapping A properZoneId(ZoneId zoneId);",
|
||||
" @RequestMapping A properLocale(Locale locale);",
|
||||
" @RequestMapping A properTimeZone(TimeZone timeZone);",
|
||||
" @RequestMapping A properHttpServletRequest(HttpServletRequest request);",
|
||||
" @RequestMapping A properHttpServletResponse(HttpServletResponse response);",
|
||||
" @RequestMapping A properHttpMethod(HttpMethod method);",
|
||||
" @RequestMapping A properNativeWebRequest(NativeWebRequest request);",
|
||||
" @RequestMapping A properWebRequest(WebRequest request);",
|
||||
" @RequestMapping A properServerWebExchange(ServerWebExchange exchange);",
|
||||
" @RequestMapping A properServerUriBuilder(UriBuilder builder);",
|
||||
" @RequestMapping A properServerUriComponentsBuilder(UriComponentsBuilder builder);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @DeleteMapping A delete(String param);",
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
final class RequestParamTypeCheckTest {
|
||||
private final CompilationTestHelper compilationTestHelper =
|
||||
CompilationTestHelper.newInstance(RequestParamTypeCheck.class, getClass());
|
||||
|
||||
@Test
|
||||
void identification() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"import com.google.common.collect.ImmutableBiMap;",
|
||||
"import com.google.common.collect.ImmutableList;",
|
||||
"import com.google.common.collect.ImmutableMap;",
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import java.util.List;",
|
||||
"import java.util.Map;",
|
||||
"import java.util.Set;",
|
||||
"import javax.annotation.Nullable;",
|
||||
"import org.springframework.web.bind.annotation.DeleteMapping;",
|
||||
"import org.springframework.web.bind.annotation.GetMapping;",
|
||||
"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.RequestParam;",
|
||||
"",
|
||||
"interface A {",
|
||||
" @PostMapping A properRequestParam(@RequestBody String body);",
|
||||
" @GetMapping A properRequestParam(@RequestParam int param);",
|
||||
" @GetMapping A properRequestParam(@RequestParam List<String> param);",
|
||||
" @PostMapping A properRequestParam(@RequestBody String body, @RequestParam Set<String> param);",
|
||||
" @PutMapping A properRequestParam(@RequestBody String body, @RequestParam Map<String, String> param);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @GetMapping A get(@RequestParam ImmutableBiMap<String, String> param);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @PostMapping A post(@Nullable @RequestParam ImmutableList<String> param);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @PutMapping A put(@RequestBody String body, @RequestParam ImmutableSet<String> param);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @DeleteMapping A delete(@RequestBody String body, @RequestParam ImmutableMap<String, String> param);",
|
||||
"",
|
||||
" void negative(ImmutableSet<Integer> set, ImmutableMap<String, String> map);",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
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;
|
||||
import org.junit.jupiter.api.condition.DisabledForJreRange;
|
||||
import org.junit.jupiter.api.condition.JRE;
|
||||
|
||||
public final class ScheduledTransactionTraceCheckTest {
|
||||
private final CompilationTestHelper compilationTestHelper =
|
||||
CompilationTestHelper.newInstance(ScheduledTransactionTraceCheck.class, getClass());
|
||||
private final BugCheckerRefactoringTestHelper refactoringTestHelper =
|
||||
BugCheckerRefactoringTestHelper.newInstance(ScheduledTransactionTraceCheck.class, getClass());
|
||||
|
||||
@Test
|
||||
void identification() {
|
||||
compilationTestHelper
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"import com.newrelic.api.agent.Trace;",
|
||||
"import org.springframework.scheduling.annotation.Scheduled;",
|
||||
"",
|
||||
"class A {",
|
||||
" void notScheduled() {}",
|
||||
"",
|
||||
" @Scheduled(fixedDelay = 1)",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" void scheduledButNotTraced() {}",
|
||||
"",
|
||||
" @Scheduled(fixedDelay = 1)",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Trace",
|
||||
" void scheduledButImproperlyTraced1() {}",
|
||||
"",
|
||||
" @Scheduled(fixedDelay = 1)",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Trace(dispatcher = false)",
|
||||
" void scheduledButImproperlyTraced2() {}",
|
||||
"",
|
||||
" @Scheduled(fixedDelay = 1)",
|
||||
" @Trace(dispatcher = true)",
|
||||
" void scheduledAndProperlyTraced() {}",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
// XXX: Enable this test for all JREs once https://github.com/google/error-prone/pull/2820 is
|
||||
// merged and released.
|
||||
@Test
|
||||
@DisabledForJreRange(min = JRE.JAVA_12)
|
||||
void replacement() {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/A.java",
|
||||
"import com.newrelic.api.agent.Trace;",
|
||||
"import org.springframework.scheduling.annotation.Scheduled;",
|
||||
"",
|
||||
"class A {",
|
||||
" @Scheduled(fixedDelay = 1)",
|
||||
" void scheduledButNotTraced() {}",
|
||||
"",
|
||||
" @Scheduled(fixedDelay = 1)",
|
||||
" @Trace",
|
||||
" void scheduledButImproperlyTraced1() {}",
|
||||
"",
|
||||
" @Scheduled(fixedDelay = 1)",
|
||||
" @Trace(dispatcher = false)",
|
||||
" void scheduledButImproperlyTraced2() {}",
|
||||
"",
|
||||
" @Scheduled(fixedDelay = 1)",
|
||||
" @Trace(leaf = true)",
|
||||
" void scheduledButImproperlyTraced3() {}",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"out/A.java",
|
||||
"import com.newrelic.api.agent.Trace;",
|
||||
"import org.springframework.scheduling.annotation.Scheduled;",
|
||||
"",
|
||||
"class A {",
|
||||
" @Trace(dispatcher = true)",
|
||||
" @Scheduled(fixedDelay = 1)",
|
||||
" void scheduledButNotTraced() {}",
|
||||
"",
|
||||
" @Scheduled(fixedDelay = 1)",
|
||||
" @Trace(dispatcher = true)",
|
||||
" void scheduledButImproperlyTraced1() {}",
|
||||
"",
|
||||
" @Scheduled(fixedDelay = 1)",
|
||||
" @Trace(dispatcher = true)",
|
||||
" void scheduledButImproperlyTraced2() {}",
|
||||
"",
|
||||
" @Scheduled(fixedDelay = 1)",
|
||||
" @Trace(dispatcher = true, leaf = true)",
|
||||
" void scheduledButImproperlyTraced3() {}",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package tech.picnic.errorprone.bugpatterns;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -14,8 +15,20 @@ public final class StaticImportCheckTest {
|
||||
|
||||
@Test
|
||||
void candidateMethodsAreNotRedundant() {
|
||||
assertThat(StaticImportCheck.STATIC_IMPORT_CANDIDATE_METHODS.keySet())
|
||||
.doesNotContainAnyElementsOf(StaticImportCheck.STATIC_IMPORT_CANDIDATE_CLASSES);
|
||||
assertThat(StaticImportCheck.STATIC_IMPORT_CANDIDATE_MEMBERS.keySet())
|
||||
.doesNotContainAnyElementsOf(StaticImportCheck.STATIC_IMPORT_CANDIDATE_TYPES);
|
||||
}
|
||||
|
||||
@Test
|
||||
void exemptedMembersAreNotVacuous() {
|
||||
assertThat(StaticImportCheck.STATIC_IMPORT_EXEMPTED_MEMBERS.keySet())
|
||||
.isSubsetOf(StaticImportCheck.STATIC_IMPORT_CANDIDATE_TYPES);
|
||||
}
|
||||
|
||||
@Test
|
||||
void exemptedMembersAreNotRedundant() {
|
||||
assertThat(StaticImportCheck.STATIC_IMPORT_EXEMPTED_MEMBERS.values())
|
||||
.doesNotContainAnyElementsOf(StaticImportCheck.STATIC_IMPORT_EXEMPTED_IDENTIFIERS);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -33,11 +46,16 @@ public final class StaticImportCheckTest {
|
||||
"import com.google.common.collect.ImmutableMap;",
|
||||
"import com.google.common.collect.ImmutableMultiset;",
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import com.google.errorprone.refaster.ImportPolicy;",
|
||||
"import com.google.errorprone.refaster.annotation.UseImportPolicy;",
|
||||
"import java.nio.charset.StandardCharsets;",
|
||||
"import java.time.ZoneOffset;",
|
||||
"import java.util.Optional;",
|
||||
"import java.util.function.Predicate;",
|
||||
"import java.util.UUID;",
|
||||
"import org.springframework.boot.test.context.SpringBootTest;",
|
||||
"import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;",
|
||||
"import org.springframework.http.MediaType;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
@@ -68,6 +86,9 @@ public final class StaticImportCheckTest {
|
||||
" Predicates.not(null);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" UUID uuid = UUID.randomUUID();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Object o1 = StandardCharsets.UTF_8;",
|
||||
" Object o2 = UTF_8;",
|
||||
"",
|
||||
@@ -75,9 +96,22 @@ public final class StaticImportCheckTest {
|
||||
" Object e1 = WebEnvironment.RANDOM_PORT;",
|
||||
" Object e2 = RANDOM_PORT;",
|
||||
"",
|
||||
" // Not flagged because `MediaType.ALL` is exempted.",
|
||||
" MediaType t1 = MediaType.ALL;",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" MediaType t2 = MediaType.APPLICATION_JSON;",
|
||||
"",
|
||||
" Optional.empty();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ZoneOffset zo1 = ZoneOffset.UTC;",
|
||||
" ZoneOffset zo2 = ZoneOffset.MIN;",
|
||||
" }",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @UseImportPolicy(ImportPolicy.IMPORT_TOP_LEVEL)",
|
||||
" void refasterAfterTemplate() {}",
|
||||
"",
|
||||
" void toImmutableMultiset() {}",
|
||||
"}")
|
||||
.doTest();
|
||||
@@ -93,13 +127,19 @@ public final class StaticImportCheckTest {
|
||||
"import com.google.common.base.Predicates;",
|
||||
"import com.google.common.collect.ImmutableMap;",
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import com.google.errorprone.BugPattern;",
|
||||
"import com.google.errorprone.BugPattern.SeverityLevel;",
|
||||
"import java.nio.charset.StandardCharsets;",
|
||||
"import java.util.ArrayList;",
|
||||
"import java.util.Collections;",
|
||||
"import java.util.Objects;",
|
||||
"import java.util.regex.Pattern;",
|
||||
"import org.junit.jupiter.params.provider.Arguments;",
|
||||
"import org.springframework.format.annotation.DateTimeFormat;",
|
||||
"import org.springframework.format.annotation.DateTimeFormat.ISO;",
|
||||
"import org.springframework.boot.test.context.SpringBootTest;",
|
||||
"import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;",
|
||||
"import org.springframework.http.MediaType;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m1() {",
|
||||
@@ -109,6 +149,9 @@ public final class StaticImportCheckTest {
|
||||
" ImmutableSet.toImmutableSet();",
|
||||
" ImmutableSet.<String>toImmutableSet();",
|
||||
"",
|
||||
" Collections.disjoint(ImmutableSet.of(), ImmutableSet.of());",
|
||||
" Collections.reverse(new ArrayList<>());",
|
||||
"",
|
||||
" Predicates.not(null);",
|
||||
" not(null);",
|
||||
"",
|
||||
@@ -117,6 +160,14 @@ public final class StaticImportCheckTest {
|
||||
" Objects.requireNonNull(\"bar\");",
|
||||
"",
|
||||
" Object o = StandardCharsets.UTF_8;",
|
||||
"",
|
||||
" ImmutableSet.of(",
|
||||
" MediaType.ALL,",
|
||||
" MediaType.APPLICATION_XHTML_XML,",
|
||||
" MediaType.TEXT_HTML,",
|
||||
" MediaType.valueOf(\"image/webp\"));",
|
||||
"",
|
||||
" Pattern.compile(\"\", Pattern.CASE_INSENSITIVE);",
|
||||
" }",
|
||||
"",
|
||||
" void m2(",
|
||||
@@ -129,6 +180,14 @@ public final class StaticImportCheckTest {
|
||||
" @DateTimeFormat(iso = ISO.DATE_TIME) String dateTime,",
|
||||
" @DateTimeFormat(iso = ISO.TIME) String time) {}",
|
||||
"",
|
||||
" @BugPattern(",
|
||||
" name = \"TestBugPattern\",",
|
||||
" summary = \"\",",
|
||||
" linkType = BugPattern.LinkType.NONE,",
|
||||
" severity = SeverityLevel.SUGGESTION,",
|
||||
" tags = BugPattern.StandardTags.SIMPLIFICATION)",
|
||||
" static final class TestBugPattern {}",
|
||||
"",
|
||||
" @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)",
|
||||
" final class Test {}",
|
||||
"}")
|
||||
@@ -136,25 +195,39 @@ public final class StaticImportCheckTest {
|
||||
"out/A.java",
|
||||
"import static com.google.common.collect.ImmutableMap.toImmutableMap;",
|
||||
"import static com.google.common.collect.ImmutableSet.toImmutableSet;",
|
||||
"import static com.google.errorprone.BugPattern.LinkType.NONE;",
|
||||
"import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION;",
|
||||
"import static com.google.errorprone.BugPattern.StandardTags.SIMPLIFICATION;",
|
||||
"import static java.nio.charset.StandardCharsets.UTF_8;",
|
||||
"import static java.util.Collections.disjoint;",
|
||||
"import static java.util.Collections.reverse;",
|
||||
"import static java.util.Objects.requireNonNull;",
|
||||
"import static java.util.function.Predicate.not;",
|
||||
"import static java.util.regex.Pattern.CASE_INSENSITIVE;",
|
||||
"import static org.junit.jupiter.params.provider.Arguments.arguments;",
|
||||
"import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;",
|
||||
"import static org.springframework.format.annotation.DateTimeFormat.ISO.DATE;",
|
||||
"import static org.springframework.format.annotation.DateTimeFormat.ISO.DATE_TIME;",
|
||||
"import static org.springframework.format.annotation.DateTimeFormat.ISO.TIME;",
|
||||
"import static org.springframework.http.MediaType.APPLICATION_XHTML_XML;",
|
||||
"import static org.springframework.http.MediaType.TEXT_HTML;",
|
||||
"",
|
||||
"import com.google.common.base.Predicates;",
|
||||
"import com.google.common.collect.ImmutableMap;",
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import com.google.errorprone.BugPattern;",
|
||||
"import com.google.errorprone.BugPattern.SeverityLevel;",
|
||||
"import java.nio.charset.StandardCharsets;",
|
||||
"import java.util.ArrayList;",
|
||||
"import java.util.Collections;",
|
||||
"import java.util.Objects;",
|
||||
"import java.util.regex.Pattern;",
|
||||
"import org.junit.jupiter.params.provider.Arguments;",
|
||||
"import org.springframework.boot.test.context.SpringBootTest;",
|
||||
"import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;",
|
||||
"import org.springframework.format.annotation.DateTimeFormat;",
|
||||
"import org.springframework.format.annotation.DateTimeFormat.ISO;",
|
||||
"import org.springframework.http.MediaType;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m1() {",
|
||||
@@ -164,6 +237,9 @@ public final class StaticImportCheckTest {
|
||||
" toImmutableSet();",
|
||||
" ImmutableSet.<String>toImmutableSet();",
|
||||
"",
|
||||
" disjoint(ImmutableSet.of(), ImmutableSet.of());",
|
||||
" reverse(new ArrayList<>());",
|
||||
"",
|
||||
" Predicates.not(null);",
|
||||
" not(null);",
|
||||
"",
|
||||
@@ -172,6 +248,14 @@ public final class StaticImportCheckTest {
|
||||
" requireNonNull(\"bar\");",
|
||||
"",
|
||||
" Object o = UTF_8;",
|
||||
"",
|
||||
" ImmutableSet.of(",
|
||||
" MediaType.ALL,",
|
||||
" APPLICATION_XHTML_XML,",
|
||||
" TEXT_HTML,",
|
||||
" MediaType.valueOf(\"image/webp\"));",
|
||||
"",
|
||||
" Pattern.compile(\"\", CASE_INSENSITIVE);",
|
||||
" }",
|
||||
"",
|
||||
" void m2(",
|
||||
@@ -184,9 +268,17 @@ public final class StaticImportCheckTest {
|
||||
" @DateTimeFormat(iso = DATE_TIME) String dateTime,",
|
||||
" @DateTimeFormat(iso = TIME) String time) {}",
|
||||
"",
|
||||
" @BugPattern(",
|
||||
" name = \"TestBugPattern\",",
|
||||
" summary = \"\",",
|
||||
" linkType = NONE,",
|
||||
" severity = SUGGESTION,",
|
||||
" tags = SIMPLIFICATION)",
|
||||
" static final class TestBugPattern {}",
|
||||
"",
|
||||
" @SpringBootTest(webEnvironment = RANDOM_PORT)",
|
||||
" final class Test {}",
|
||||
"}")
|
||||
.doTest(BugCheckerRefactoringTestHelper.TestMode.TEXT_MATCH);
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
import static org.assertj.core.data.Percentage.withPercentage;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.math.BigDecimal;
|
||||
import org.assertj.core.api.AbstractBigDecimalAssert;
|
||||
|
||||
final class AssertJBigDecimalTemplatesTest implements RefasterTemplateTestCase {
|
||||
@Override
|
||||
public ImmutableSet<?> elidedTypesAndStaticImports() {
|
||||
return ImmutableSet.of(offset(0), withPercentage(0));
|
||||
}
|
||||
|
||||
ImmutableSet<AbstractBigDecimalAssert<?>> testAbstractBigDecimalAssertIsEqualTo() {
|
||||
return ImmutableSet.of(
|
||||
assertThat(BigDecimal.ZERO).isEqualTo(BigDecimal.ONE),
|
||||
assertThat(BigDecimal.ZERO).isEqualTo(BigDecimal.ONE));
|
||||
}
|
||||
|
||||
ImmutableSet<AbstractBigDecimalAssert<?>> testAbstractBigDecimalAssertIsNotEqualTo() {
|
||||
return ImmutableSet.of(
|
||||
assertThat(BigDecimal.ZERO).isNotEqualTo(BigDecimal.ONE),
|
||||
assertThat(BigDecimal.ZERO).isNotEqualTo(BigDecimal.ONE));
|
||||
}
|
||||
|
||||
ImmutableSet<AbstractBigDecimalAssert<?>> testAbstractBigDecimalAssertIsZero() {
|
||||
return ImmutableSet.of(
|
||||
assertThat(BigDecimal.ZERO).isEqualTo(0),
|
||||
assertThat(BigDecimal.ZERO).isEqualTo(0),
|
||||
assertThat(BigDecimal.ZERO).isEqualTo(0));
|
||||
}
|
||||
|
||||
ImmutableSet<AbstractBigDecimalAssert<?>> testAbstractBigDecimalAssertIsNotZero() {
|
||||
return ImmutableSet.of(
|
||||
assertThat(BigDecimal.ZERO).isNotEqualTo(0),
|
||||
assertThat(BigDecimal.ZERO).isNotEqualTo(0),
|
||||
assertThat(BigDecimal.ZERO).isNotEqualTo(0));
|
||||
}
|
||||
|
||||
ImmutableSet<AbstractBigDecimalAssert<?>> testAbstractBigDecimalAssertIsOne() {
|
||||
return ImmutableSet.of(
|
||||
assertThat(BigDecimal.ZERO).isEqualTo(1),
|
||||
assertThat(BigDecimal.ZERO).isEqualTo(1),
|
||||
assertThat(BigDecimal.ZERO).isEqualTo(1));
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
@@ -14,36 +14,15 @@ final class AssertJBigDecimalTemplatesTest implements RefasterTemplateTestCase {
|
||||
return ImmutableSet.of(offset(0), withPercentage(0));
|
||||
}
|
||||
|
||||
ImmutableSet<AbstractBigDecimalAssert<?>> testAbstractBigDecimalAssertIsEqualTo() {
|
||||
ImmutableSet<AbstractBigDecimalAssert<?>> testAbstractBigDecimalAssertIsEqualByComparingTo() {
|
||||
return ImmutableSet.of(
|
||||
assertThat(BigDecimal.ZERO).isCloseTo(BigDecimal.ONE, offset(BigDecimal.ZERO)),
|
||||
assertThat(BigDecimal.ZERO).isCloseTo(BigDecimal.ONE, withPercentage(0)));
|
||||
}
|
||||
|
||||
ImmutableSet<AbstractBigDecimalAssert<?>> testAbstractBigDecimalAssertIsNotEqualTo() {
|
||||
ImmutableSet<AbstractBigDecimalAssert<?>> testAbstractBigDecimalAssertIsNotEqualByComparingTo() {
|
||||
return ImmutableSet.of(
|
||||
assertThat(BigDecimal.ZERO).isNotCloseTo(BigDecimal.ONE, offset(BigDecimal.ZERO)),
|
||||
assertThat(BigDecimal.ZERO).isNotCloseTo(BigDecimal.ONE, withPercentage(0)));
|
||||
}
|
||||
|
||||
ImmutableSet<AbstractBigDecimalAssert<?>> testAbstractBigDecimalAssertIsZero() {
|
||||
return ImmutableSet.of(
|
||||
assertThat(BigDecimal.ZERO).isZero(),
|
||||
assertThat(BigDecimal.ZERO).isEqualTo(0L),
|
||||
assertThat(BigDecimal.ZERO).isEqualTo(BigDecimal.ZERO));
|
||||
}
|
||||
|
||||
ImmutableSet<AbstractBigDecimalAssert<?>> testAbstractBigDecimalAssertIsNotZero() {
|
||||
return ImmutableSet.of(
|
||||
assertThat(BigDecimal.ZERO).isNotZero(),
|
||||
assertThat(BigDecimal.ZERO).isNotEqualTo(0L),
|
||||
assertThat(BigDecimal.ZERO).isNotEqualTo(BigDecimal.ZERO));
|
||||
}
|
||||
|
||||
ImmutableSet<AbstractBigDecimalAssert<?>> testAbstractBigDecimalAssertIsOne() {
|
||||
return ImmutableSet.of(
|
||||
assertThat(BigDecimal.ZERO).isOne(),
|
||||
assertThat(BigDecimal.ZERO).isEqualTo(1L),
|
||||
assertThat(BigDecimal.ZERO).isEqualTo(BigDecimal.ONE));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
import static org.assertj.core.data.Percentage.withPercentage;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.math.BigDecimal;
|
||||
import org.assertj.core.api.AbstractBigDecimalAssert;
|
||||
|
||||
final class AssertJBigDecimalTemplatesTest implements RefasterTemplateTestCase {
|
||||
@Override
|
||||
public ImmutableSet<?> elidedTypesAndStaticImports() {
|
||||
return ImmutableSet.of(offset(0), withPercentage(0));
|
||||
}
|
||||
|
||||
ImmutableSet<AbstractBigDecimalAssert<?>> testAbstractBigDecimalAssertIsEqualByComparingTo() {
|
||||
return ImmutableSet.of(
|
||||
assertThat(BigDecimal.ZERO).isEqualByComparingTo(BigDecimal.ONE),
|
||||
assertThat(BigDecimal.ZERO).isEqualByComparingTo(BigDecimal.ONE));
|
||||
}
|
||||
|
||||
ImmutableSet<AbstractBigDecimalAssert<?>> testAbstractBigDecimalAssertIsNotEqualByComparingTo() {
|
||||
return ImmutableSet.of(
|
||||
assertThat(BigDecimal.ZERO).isNotEqualByComparingTo(BigDecimal.ONE),
|
||||
assertThat(BigDecimal.ZERO).isNotEqualByComparingTo(BigDecimal.ONE));
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
@@ -16,19 +16,13 @@ final class AssertJByteTemplatesTest implements RefasterTemplateTestCase {
|
||||
ImmutableSet<AbstractByteAssert<?>> testAbstractByteAssertIsEqualTo() {
|
||||
return ImmutableSet.of(
|
||||
assertThat((byte) 0).isCloseTo((byte) 1, offset((byte) 0)),
|
||||
assertThat((byte) 0).isCloseTo(Byte.valueOf((byte) 1), offset((byte) 0)),
|
||||
assertThat((byte) 0).isCloseTo((byte) 1, withPercentage(0)),
|
||||
assertThat((byte) 0).isCloseTo(Byte.valueOf((byte) 1), withPercentage(0)),
|
||||
assertThat((byte) 0).isEqualTo(Byte.valueOf((byte) 1)));
|
||||
assertThat((byte) 0).isCloseTo((byte) 1, withPercentage(0)));
|
||||
}
|
||||
|
||||
ImmutableSet<AbstractByteAssert<?>> testAbstractByteAssertIsNotEqualTo() {
|
||||
return ImmutableSet.of(
|
||||
assertThat((byte) 0).isNotCloseTo((byte) 1, offset((byte) 0)),
|
||||
assertThat((byte) 0).isNotCloseTo(Byte.valueOf((byte) 1), offset((byte) 0)),
|
||||
assertThat((byte) 0).isNotCloseTo((byte) 1, withPercentage(0)),
|
||||
assertThat((byte) 0).isNotCloseTo(Byte.valueOf((byte) 1), withPercentage(0)),
|
||||
assertThat((byte) 0).isNotEqualTo(Byte.valueOf((byte) 1)));
|
||||
assertThat((byte) 0).isNotCloseTo((byte) 1, withPercentage(0)));
|
||||
}
|
||||
|
||||
AbstractByteAssert<?> testAbstractByteAssertIsZero() {
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
@@ -15,20 +15,12 @@ final class AssertJByteTemplatesTest implements RefasterTemplateTestCase {
|
||||
|
||||
ImmutableSet<AbstractByteAssert<?>> testAbstractByteAssertIsEqualTo() {
|
||||
return ImmutableSet.of(
|
||||
assertThat((byte) 0).isEqualTo((byte) 1),
|
||||
assertThat((byte) 0).isEqualTo((byte) 1),
|
||||
assertThat((byte) 0).isEqualTo((byte) 1),
|
||||
assertThat((byte) 0).isEqualTo((byte) 1),
|
||||
assertThat((byte) 0).isEqualTo((byte) 1));
|
||||
assertThat((byte) 0).isEqualTo((byte) 1), assertThat((byte) 0).isEqualTo((byte) 1));
|
||||
}
|
||||
|
||||
ImmutableSet<AbstractByteAssert<?>> testAbstractByteAssertIsNotEqualTo() {
|
||||
return ImmutableSet.of(
|
||||
assertThat((byte) 0).isNotEqualTo((byte) 1),
|
||||
assertThat((byte) 0).isNotEqualTo((byte) 1),
|
||||
assertThat((byte) 0).isNotEqualTo((byte) 1),
|
||||
assertThat((byte) 0).isNotEqualTo((byte) 1),
|
||||
assertThat((byte) 0).isNotEqualTo((byte) 1));
|
||||
assertThat((byte) 0).isNotEqualTo((byte) 1), assertThat((byte) 0).isNotEqualTo((byte) 1));
|
||||
}
|
||||
|
||||
AbstractByteAssert<?> testAbstractByteAssertIsZero() {
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -6,11 +6,8 @@ import com.google.common.collect.ImmutableSet;
|
||||
import org.assertj.core.api.AbstractAssert;
|
||||
|
||||
final class AssertJCharSequenceTemplatesTest implements RefasterTemplateTestCase {
|
||||
void testAssertThatCharSequenceIsEmpty1() {
|
||||
void testAssertThatCharSequenceIsEmpty() {
|
||||
assertThat("foo".length()).isEqualTo(0L);
|
||||
}
|
||||
|
||||
void testAssertThatCharSequenceIsEmpty2() {
|
||||
assertThat("foo".length()).isNotPositive();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -6,11 +6,8 @@ import com.google.common.collect.ImmutableSet;
|
||||
import org.assertj.core.api.AbstractAssert;
|
||||
|
||||
final class AssertJCharSequenceTemplatesTest implements RefasterTemplateTestCase {
|
||||
void testAssertThatCharSequenceIsEmpty1() {
|
||||
void testAssertThatCharSequenceIsEmpty() {
|
||||
assertThat("foo").isEmpty();
|
||||
}
|
||||
|
||||
void testAssertThatCharSequenceIsEmpty2() {
|
||||
assertThat("foo").isEmpty();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
@@ -21,20 +21,13 @@ final class AssertJDoubleTemplatesTest implements RefasterTemplateTestCase {
|
||||
|
||||
ImmutableSet<AbstractDoubleAssert<?>> testAbstractDoubleAssertIsEqualTo() {
|
||||
return ImmutableSet.of(
|
||||
assertThat(0.0).isCloseTo(1, offset(0.0)),
|
||||
assertThat(0.0).isCloseTo(Double.valueOf(1), offset(0.0)),
|
||||
assertThat(0.0).isCloseTo(1, withPercentage(0)),
|
||||
assertThat(0.0).isCloseTo(Double.valueOf(1), withPercentage(0)),
|
||||
assertThat(0.0).isEqualTo(Double.valueOf(1)));
|
||||
assertThat(0.0).isCloseTo(1, offset(0.0)), assertThat(0.0).isCloseTo(1, withPercentage(0)));
|
||||
}
|
||||
|
||||
ImmutableSet<AbstractDoubleAssert<?>> testAbstractDoubleAssertIsNotEqualTo() {
|
||||
return ImmutableSet.of(
|
||||
assertThat(0.0).isNotCloseTo(1, offset(0.0)),
|
||||
assertThat(0.0).isNotCloseTo(Double.valueOf(1), offset(0.0)),
|
||||
assertThat(0.0).isNotCloseTo(1, withPercentage(0)),
|
||||
assertThat(0.0).isNotCloseTo(Double.valueOf(1), withPercentage(0)),
|
||||
assertThat(0.0).isNotEqualTo(Double.valueOf(1)));
|
||||
assertThat(0.0).isNotCloseTo(1, withPercentage(0)));
|
||||
}
|
||||
|
||||
AbstractDoubleAssert<?> testAbstractDoubleAssertIsZero() {
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
@@ -20,21 +20,11 @@ final class AssertJDoubleTemplatesTest implements RefasterTemplateTestCase {
|
||||
}
|
||||
|
||||
ImmutableSet<AbstractDoubleAssert<?>> testAbstractDoubleAssertIsEqualTo() {
|
||||
return ImmutableSet.of(
|
||||
assertThat(0.0).isEqualTo(1),
|
||||
assertThat(0.0).isEqualTo(1),
|
||||
assertThat(0.0).isEqualTo(1),
|
||||
assertThat(0.0).isEqualTo(1),
|
||||
assertThat(0.0).isEqualTo(1));
|
||||
return ImmutableSet.of(assertThat(0.0).isEqualTo(1), assertThat(0.0).isEqualTo(1));
|
||||
}
|
||||
|
||||
ImmutableSet<AbstractDoubleAssert<?>> testAbstractDoubleAssertIsNotEqualTo() {
|
||||
return ImmutableSet.of(
|
||||
assertThat(0.0).isNotEqualTo(1),
|
||||
assertThat(0.0).isNotEqualTo(1),
|
||||
assertThat(0.0).isNotEqualTo(1),
|
||||
assertThat(0.0).isNotEqualTo(1),
|
||||
assertThat(0.0).isNotEqualTo(1));
|
||||
return ImmutableSet.of(assertThat(0.0).isNotEqualTo(1), assertThat(0.0).isNotEqualTo(1));
|
||||
}
|
||||
|
||||
AbstractDoubleAssert<?> testAbstractDoubleAssertIsZero() {
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -12,15 +12,9 @@ final class AssertJEnumableTemplatesTest implements RefasterTemplateTestCase {
|
||||
return ImmutableSet.of(Iterables.class);
|
||||
}
|
||||
|
||||
void testEnumerableAssertIsEmpty1() {
|
||||
void testEnumerableAssertIsEmpty() {
|
||||
assertThat(ImmutableSet.of()).hasSize(0);
|
||||
}
|
||||
|
||||
void testEnumerableAssertIsEmpty2() {
|
||||
assertThat(ImmutableSet.of()).hasSizeLessThanOrEqualTo(0);
|
||||
}
|
||||
|
||||
void testEnumerableAssertIsEmpty3() {
|
||||
assertThat(ImmutableSet.of()).hasSizeLessThan(1);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -12,15 +12,9 @@ final class AssertJEnumableTemplatesTest implements RefasterTemplateTestCase {
|
||||
return ImmutableSet.of(Iterables.class);
|
||||
}
|
||||
|
||||
void testEnumerableAssertIsEmpty1() {
|
||||
void testEnumerableAssertIsEmpty() {
|
||||
assertThat(ImmutableSet.of()).isEmpty();
|
||||
}
|
||||
|
||||
void testEnumerableAssertIsEmpty2() {
|
||||
assertThat(ImmutableSet.of()).isEmpty();
|
||||
}
|
||||
|
||||
void testEnumerableAssertIsEmpty3() {
|
||||
assertThat(ImmutableSet.of()).isEmpty();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
@@ -21,20 +21,13 @@ final class AssertJFloatTemplatesTest implements RefasterTemplateTestCase {
|
||||
|
||||
ImmutableSet<AbstractFloatAssert<?>> testAbstractFloatAssertIsEqualTo() {
|
||||
return ImmutableSet.of(
|
||||
assertThat(0F).isCloseTo(1, offset(0F)),
|
||||
assertThat(0F).isCloseTo(Float.valueOf(1), offset(0F)),
|
||||
assertThat(0F).isCloseTo(1, withPercentage(0)),
|
||||
assertThat(0F).isCloseTo(Float.valueOf(1), withPercentage(0)),
|
||||
assertThat(0F).isEqualTo(Float.valueOf(1)));
|
||||
assertThat(0F).isCloseTo(1, offset(0F)), assertThat(0F).isCloseTo(1, withPercentage(0)));
|
||||
}
|
||||
|
||||
ImmutableSet<AbstractFloatAssert<?>> testAbstractFloatAssertIsNotEqualTo() {
|
||||
return ImmutableSet.of(
|
||||
assertThat(0F).isNotCloseTo(1, offset(0F)),
|
||||
assertThat(0F).isNotCloseTo(Float.valueOf(1), offset(0F)),
|
||||
assertThat(0F).isNotCloseTo(1, withPercentage(0)),
|
||||
assertThat(0F).isNotCloseTo(Float.valueOf(1), withPercentage(0)),
|
||||
assertThat(0F).isNotEqualTo(Float.valueOf(1)));
|
||||
assertThat(0F).isNotCloseTo(1, withPercentage(0)));
|
||||
}
|
||||
|
||||
AbstractFloatAssert<?> testAbstractFloatAssertIsZero() {
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
@@ -20,21 +20,11 @@ final class AssertJFloatTemplatesTest implements RefasterTemplateTestCase {
|
||||
}
|
||||
|
||||
ImmutableSet<AbstractFloatAssert<?>> testAbstractFloatAssertIsEqualTo() {
|
||||
return ImmutableSet.of(
|
||||
assertThat(0F).isEqualTo(1),
|
||||
assertThat(0F).isEqualTo(1),
|
||||
assertThat(0F).isEqualTo(1),
|
||||
assertThat(0F).isEqualTo(1),
|
||||
assertThat(0F).isEqualTo(1));
|
||||
return ImmutableSet.of(assertThat(0F).isEqualTo(1), assertThat(0F).isEqualTo(1));
|
||||
}
|
||||
|
||||
ImmutableSet<AbstractFloatAssert<?>> testAbstractFloatAssertIsNotEqualTo() {
|
||||
return ImmutableSet.of(
|
||||
assertThat(0F).isNotEqualTo(1),
|
||||
assertThat(0F).isNotEqualTo(1),
|
||||
assertThat(0F).isNotEqualTo(1),
|
||||
assertThat(0F).isNotEqualTo(1),
|
||||
assertThat(0F).isNotEqualTo(1));
|
||||
return ImmutableSet.of(assertThat(0F).isNotEqualTo(1), assertThat(0F).isNotEqualTo(1));
|
||||
}
|
||||
|
||||
AbstractFloatAssert<?> testAbstractFloatAssertIsZero() {
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
@@ -15,20 +15,12 @@ final class AssertJIntegerTemplatesTest implements RefasterTemplateTestCase {
|
||||
|
||||
ImmutableSet<AbstractIntegerAssert<?>> testAbstractIntegerAssertIsEqualTo() {
|
||||
return ImmutableSet.of(
|
||||
assertThat(0).isCloseTo(1, offset(0)),
|
||||
assertThat(0).isCloseTo(Integer.valueOf(1), offset(0)),
|
||||
assertThat(0).isCloseTo(1, withPercentage(0)),
|
||||
assertThat(0).isCloseTo(Integer.valueOf(1), withPercentage(0)),
|
||||
assertThat(0).isEqualTo(Integer.valueOf(1)));
|
||||
assertThat(0).isCloseTo(1, offset(0)), assertThat(0).isCloseTo(1, withPercentage(0)));
|
||||
}
|
||||
|
||||
ImmutableSet<AbstractIntegerAssert<?>> testAbstractIntegerAssertIsNotEqualTo() {
|
||||
return ImmutableSet.of(
|
||||
assertThat(0).isNotCloseTo(1, offset(0)),
|
||||
assertThat(0).isNotCloseTo(Integer.valueOf(1), offset(0)),
|
||||
assertThat(0).isNotCloseTo(1, withPercentage(0)),
|
||||
assertThat(0).isNotCloseTo(Integer.valueOf(1), withPercentage(0)),
|
||||
assertThat(0).isNotEqualTo(Integer.valueOf(1)));
|
||||
assertThat(0).isNotCloseTo(1, offset(0)), assertThat(0).isNotCloseTo(1, withPercentage(0)));
|
||||
}
|
||||
|
||||
AbstractIntegerAssert<?> testAbstractIntegerAssertIsZero() {
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
@@ -14,21 +14,11 @@ final class AssertJIntegerTemplatesTest implements RefasterTemplateTestCase {
|
||||
}
|
||||
|
||||
ImmutableSet<AbstractIntegerAssert<?>> testAbstractIntegerAssertIsEqualTo() {
|
||||
return ImmutableSet.of(
|
||||
assertThat(0).isEqualTo(1),
|
||||
assertThat(0).isEqualTo(1),
|
||||
assertThat(0).isEqualTo(1),
|
||||
assertThat(0).isEqualTo(1),
|
||||
assertThat(0).isEqualTo(1));
|
||||
return ImmutableSet.of(assertThat(0).isEqualTo(1), assertThat(0).isEqualTo(1));
|
||||
}
|
||||
|
||||
ImmutableSet<AbstractIntegerAssert<?>> testAbstractIntegerAssertIsNotEqualTo() {
|
||||
return ImmutableSet.of(
|
||||
assertThat(0).isNotEqualTo(1),
|
||||
assertThat(0).isNotEqualTo(1),
|
||||
assertThat(0).isNotEqualTo(1),
|
||||
assertThat(0).isNotEqualTo(1),
|
||||
assertThat(0).isNotEqualTo(1));
|
||||
return ImmutableSet.of(assertThat(0).isNotEqualTo(1), assertThat(0).isNotEqualTo(1));
|
||||
}
|
||||
|
||||
AbstractIntegerAssert<?> testAbstractIntegerAssertIsZero() {
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
@@ -15,20 +15,13 @@ final class AssertJLongTemplatesTest implements RefasterTemplateTestCase {
|
||||
|
||||
ImmutableSet<AbstractLongAssert<?>> testAbstractLongAssertIsEqualTo() {
|
||||
return ImmutableSet.of(
|
||||
assertThat(0L).isCloseTo(1, offset(0L)),
|
||||
assertThat(0L).isCloseTo(Long.valueOf(1), offset(0L)),
|
||||
assertThat(0L).isCloseTo(1, withPercentage(0)),
|
||||
assertThat(0L).isCloseTo(Long.valueOf(1), withPercentage(0)),
|
||||
assertThat(0L).isEqualTo(Long.valueOf(1)));
|
||||
assertThat(0L).isCloseTo(1, offset(0L)), assertThat(0L).isCloseTo(1, withPercentage(0)));
|
||||
}
|
||||
|
||||
ImmutableSet<AbstractLongAssert<?>> testAbstractLongAssertIsNotEqualTo() {
|
||||
return ImmutableSet.of(
|
||||
assertThat(0L).isNotCloseTo(1, offset(0L)),
|
||||
assertThat(0L).isNotCloseTo(Long.valueOf(1), offset(0L)),
|
||||
assertThat(0L).isNotCloseTo(1, withPercentage(0)),
|
||||
assertThat(0L).isNotCloseTo(Long.valueOf(1), withPercentage(0)),
|
||||
assertThat(0L).isNotEqualTo(Long.valueOf(1)));
|
||||
assertThat(0L).isNotCloseTo(1, withPercentage(0)));
|
||||
}
|
||||
|
||||
AbstractLongAssert<?> testAbstractLongAssertIsZero() {
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.bugpatterns;
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
@@ -14,21 +14,11 @@ final class AssertJLongTemplatesTest implements RefasterTemplateTestCase {
|
||||
}
|
||||
|
||||
ImmutableSet<AbstractLongAssert<?>> testAbstractLongAssertIsEqualTo() {
|
||||
return ImmutableSet.of(
|
||||
assertThat(0L).isEqualTo(1),
|
||||
assertThat(0L).isEqualTo(1),
|
||||
assertThat(0L).isEqualTo(1),
|
||||
assertThat(0L).isEqualTo(1),
|
||||
assertThat(0L).isEqualTo(1));
|
||||
return ImmutableSet.of(assertThat(0L).isEqualTo(1), assertThat(0L).isEqualTo(1));
|
||||
}
|
||||
|
||||
ImmutableSet<AbstractLongAssert<?>> testAbstractLongAssertIsNotEqualTo() {
|
||||
return ImmutableSet.of(
|
||||
assertThat(0L).isNotEqualTo(1),
|
||||
assertThat(0L).isNotEqualTo(1),
|
||||
assertThat(0L).isNotEqualTo(1),
|
||||
assertThat(0L).isNotEqualTo(1),
|
||||
assertThat(0L).isNotEqualTo(1));
|
||||
return ImmutableSet.of(assertThat(0L).isNotEqualTo(1), assertThat(0L).isNotEqualTo(1));
|
||||
}
|
||||
|
||||
AbstractLongAssert<?> testAbstractLongAssertIsZero() {
|
||||
@@ -0,0 +1,18 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.assertj.core.api.AbstractMapAssert;
|
||||
|
||||
final class AssertJMapTemplatesTest implements RefasterTemplateTestCase {
|
||||
AbstractMapAssert<?, ?, Integer, Integer>
|
||||
testAbstractMapAssertContainsExactlyInAnyOrderEntriesOf() {
|
||||
return assertThat(ImmutableMap.of(1, 2, 3, 4)).isEqualTo(ImmutableMap.of(1, 2, 3, 4));
|
||||
}
|
||||
|
||||
AbstractMapAssert<?, ?, Integer, Integer> testAbstractMapAssertContainsExactlyEntriesOf() {
|
||||
return assertThat(ImmutableMap.of(1, 2))
|
||||
.containsExactlyInAnyOrderEntriesOf(ImmutableMap.of(1, 2));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.assertj.core.api.AbstractMapAssert;
|
||||
|
||||
final class AssertJMapTemplatesTest implements RefasterTemplateTestCase {
|
||||
AbstractMapAssert<?, ?, Integer, Integer>
|
||||
testAbstractMapAssertContainsExactlyInAnyOrderEntriesOf() {
|
||||
return assertThat(ImmutableMap.of(1, 2, 3, 4))
|
||||
.containsExactlyInAnyOrderEntriesOf(ImmutableMap.of(1, 2, 3, 4));
|
||||
}
|
||||
|
||||
AbstractMapAssert<?, ?, Integer, Integer> testAbstractMapAssertContainsExactlyEntriesOf() {
|
||||
return assertThat(ImmutableMap.of(1, 2)).containsExactlyEntriesOf(ImmutableMap.of(1, 2));
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user