mirror of
https://github.com/jlengrand/error-prone-support.git
synced 2026-03-10 08:11:25 +00:00
Compare commits
68 Commits
werli/mong
...
v0.18.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b733179cd0 | ||
|
|
3d9aab7c5b | ||
|
|
366cdda3d8 | ||
|
|
5b6dd147ef | ||
|
|
a868b03130 | ||
|
|
fdf9bb5d25 | ||
|
|
363b0c22c7 | ||
|
|
32ec35a354 | ||
|
|
635fe280f8 | ||
|
|
aac9b6bf10 | ||
|
|
c322ea1bbc | ||
|
|
a433a90673 | ||
|
|
5a37d65632 | ||
|
|
77d183f8fd | ||
|
|
2eb4e853c5 | ||
|
|
45a7242cf5 | ||
|
|
c85070ba23 | ||
|
|
a687f09bf0 | ||
|
|
2e4fdcb0db | ||
|
|
1005d93b7e | ||
|
|
136123f6b4 | ||
|
|
4cb5f0079d | ||
|
|
290ddf1972 | ||
|
|
5a163ce2e9 | ||
|
|
4eb0aae452 | ||
|
|
b5b98d899b | ||
|
|
bbf3d79d9a | ||
|
|
1164270589 | ||
|
|
f03d72388a | ||
|
|
2e5d1f1e87 | ||
|
|
4b1c892f04 | ||
|
|
2b6b8de150 | ||
|
|
b275a33eb8 | ||
|
|
7a9aeca248 | ||
|
|
bd5cdefea9 | ||
|
|
a265a450f9 | ||
|
|
5fbb0636aa | ||
|
|
6eb22da201 | ||
|
|
781b4d0c57 | ||
|
|
5234fca96d | ||
|
|
8daedccaea | ||
|
|
886e65d7ac | ||
|
|
ec502cef20 | ||
|
|
f3ff515271 | ||
|
|
d662eb1cbc | ||
|
|
c40b73186b | ||
|
|
6734af6742 | ||
|
|
c5ec2a552d | ||
|
|
a3e3a32332 | ||
|
|
8c3756c4f7 | ||
|
|
c472225f9c | ||
|
|
7a8538a87a | ||
|
|
dba37a3f23 | ||
|
|
e89cfe0aef | ||
|
|
9c1993e5a7 | ||
|
|
d586014379 | ||
|
|
3a441487a3 | ||
|
|
6f6a4c481e | ||
|
|
56f0cc81c9 | ||
|
|
6c58d4cc01 | ||
|
|
a1e47542e7 | ||
|
|
eff958d4c1 | ||
|
|
81704c6534 | ||
|
|
1e229949fc | ||
|
|
28a93e949e | ||
|
|
40ad38bc2a | ||
|
|
e125c6b7e2 | ||
|
|
5596c4530d |
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ ubuntu-22.04 ]
|
||||
jdk: [ 17.0.10, 21.0.2 ]
|
||||
jdk: [ 17.0.10, 21.0.2, 22.0.2 ]
|
||||
distribution: [ temurin ]
|
||||
experimental: [ false ]
|
||||
include:
|
||||
|
||||
4
.github/workflows/openssf-scorecard.yml
vendored
4
.github/workflows/openssf-scorecard.yml
vendored
@@ -30,11 +30,9 @@ jobs:
|
||||
api.osv.dev:443
|
||||
api.scorecard.dev:443
|
||||
api.securityscorecards.dev:443
|
||||
fulcio.sigstore.dev:443
|
||||
github.com:443
|
||||
oss-fuzz-build-logs.storage.googleapis.com:443
|
||||
rekor.sigstore.dev:443
|
||||
tuf-repo-cdn.sigstore.dev:443
|
||||
*.sigstore.dev:443
|
||||
www.bestpractices.dev:443
|
||||
- name: Check out code
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
|
||||
4
.github/workflows/sonarcloud.yml
vendored
4
.github/workflows/sonarcloud.yml
vendored
@@ -24,13 +24,15 @@ jobs:
|
||||
disable-sudo: true
|
||||
egress-policy: block
|
||||
allowed-endpoints: >
|
||||
analysis-sensorcache-eu-central-1-prod.s3.amazonaws.com:443
|
||||
api.adoptium.net:443
|
||||
api.nuget.org:443
|
||||
ea6ne4j2sb.execute-api.eu-central-1.amazonaws.com:443
|
||||
github.com:443
|
||||
objects.githubusercontent.com:443
|
||||
repo.maven.apache.org:443
|
||||
sc-cleancode-sensorcache-eu-central-1-prod.s3.amazonaws.com:443
|
||||
scanner.sonarcloud.io:443
|
||||
*.sonarcloud.io:443
|
||||
sonarcloud.io:443
|
||||
- name: Check out code and set up JDK and Maven
|
||||
uses: s4u/setup-maven-action@489441643219d2b93ee2a127b2402eb640a1b947 # v1.13.0
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.16.2-SNAPSHOT</version>
|
||||
<version>0.18.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>documentation-support</artifactId>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.16.2-SNAPSHOT</version>
|
||||
<version>0.18.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>error-prone-contrib</artifactId>
|
||||
@@ -122,6 +122,11 @@
|
||||
<artifactId>jakarta.servlet-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>javax.annotation-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
<artifactId>javax.inject</artifactId>
|
||||
|
||||
@@ -3,6 +3,7 @@ package tech.picnic.errorprone.refasterrules;
|
||||
import com.google.errorprone.refaster.Refaster;
|
||||
import com.google.errorprone.refaster.annotation.AfterTemplate;
|
||||
import com.google.errorprone.refaster.annotation.BeforeTemplate;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
|
||||
|
||||
@@ -37,7 +38,12 @@ final class ClassRules {
|
||||
}
|
||||
}
|
||||
|
||||
/** Prefer {@link Class#isInstance(Object)} method references over more verbose alternatives. */
|
||||
/**
|
||||
* Prefer {@link Class#isInstance(Object)} method references over lambda expressions that require
|
||||
* naming a variable.
|
||||
*/
|
||||
// XXX: Once the `ClassReferenceIsInstancePredicate` rule is dropped, rename this rule to just
|
||||
// `ClassIsInstancePredicate`.
|
||||
static final class ClassLiteralIsInstancePredicate<T, S> {
|
||||
@BeforeTemplate
|
||||
Predicate<S> before() {
|
||||
@@ -50,7 +56,11 @@ final class ClassRules {
|
||||
}
|
||||
}
|
||||
|
||||
/** Prefer {@link Class#isInstance(Object)} method references over more verbose alternatives. */
|
||||
/**
|
||||
* Prefer {@link Class#isInstance(Object)} method references over lambda expressions that require
|
||||
* naming a variable.
|
||||
*/
|
||||
// XXX: Drop this rule once the `MethodReferenceUsage` rule is enabled by default.
|
||||
static final class ClassReferenceIsInstancePredicate<T, S> {
|
||||
@BeforeTemplate
|
||||
Predicate<S> before(Class<T> clazz) {
|
||||
@@ -62,4 +72,39 @@ final class ClassRules {
|
||||
return clazz::isInstance;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link Class#cast(Object)} method references over lambda expressions that require naming
|
||||
* a variable.
|
||||
*/
|
||||
// XXX: Once the `ClassReferenceCast` rule is dropped, rename this rule to just `ClassCast`.
|
||||
static final class ClassLiteralCast<T, S> {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings("unchecked")
|
||||
Function<T, S> before() {
|
||||
return t -> (S) t;
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Function<T, S> after() {
|
||||
return Refaster.<S>clazz()::cast;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link Class#cast(Object)} method references over lambda expressions that require naming
|
||||
* a variable.
|
||||
*/
|
||||
// XXX: Drop this rule once the `MethodReferenceUsage` rule is enabled by default.
|
||||
static final class ClassReferenceCast<T, S> {
|
||||
@BeforeTemplate
|
||||
Function<T, S> before(Class<? extends S> clazz) {
|
||||
return o -> clazz.cast(o);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Function<T, S> after(Class<? extends S> clazz) {
|
||||
return clazz::cast;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,9 @@ import com.google.errorprone.refaster.Refaster;
|
||||
import com.google.errorprone.refaster.annotation.AfterTemplate;
|
||||
import com.google.errorprone.refaster.annotation.AlsoNegation;
|
||||
import com.google.errorprone.refaster.annotation.BeforeTemplate;
|
||||
import com.google.errorprone.refaster.annotation.NotMatches;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@@ -21,6 +23,7 @@ import java.util.function.Consumer;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.stream.Stream;
|
||||
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
|
||||
import tech.picnic.errorprone.refaster.matchers.IsRefasterAsVarargs;
|
||||
|
||||
/** Refaster rules related to expressions dealing with (arbitrary) collections. */
|
||||
// XXX: There are other Guava `Iterables` methods that should not be called if the input is known to
|
||||
@@ -184,6 +187,24 @@ final class CollectionRules {
|
||||
}
|
||||
}
|
||||
|
||||
/** Don't unnecessarily call {@link Stream#distinct()} on an already-unique stream of elements. */
|
||||
// XXX: This rule assumes that the `Set` relies on `Object#equals`, rather than a custom
|
||||
// equivalence relation.
|
||||
// XXX: Expressions that drop or reorder elements from the stream, such as `.filter`, `.skip` and
|
||||
// `sorted`, can similarly be simplified. Covering all cases is better done using an Error Prone
|
||||
// check.
|
||||
static final class SetStream<T> {
|
||||
@BeforeTemplate
|
||||
Stream<?> before(Set<T> set) {
|
||||
return set.stream().distinct();
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Stream<?> after(Set<T> set) {
|
||||
return set.stream();
|
||||
}
|
||||
}
|
||||
|
||||
/** Prefer {@link ArrayList#ArrayList(Collection)} over the Guava alternative. */
|
||||
@SuppressWarnings(
|
||||
"NonApiType" /* Matching against `List` would unnecessarily constrain the rule. */)
|
||||
@@ -276,6 +297,23 @@ final class CollectionRules {
|
||||
}
|
||||
}
|
||||
|
||||
/** Prefer {@link Arrays#asList(Object[])} over more contrived alternatives. */
|
||||
// XXX: Consider moving this rule to `ImmutableListRules` and having it suggest
|
||||
// `ImmutableList#copyOf`. That would retain immutability, at the cost of no longer handling
|
||||
// `null`s.
|
||||
static final class ArraysAsList<T> {
|
||||
// XXX: This expression produces an unmodifiable list, while the alternative doesn't.
|
||||
@BeforeTemplate
|
||||
List<T> before(@NotMatches(IsRefasterAsVarargs.class) T[] array) {
|
||||
return Arrays.stream(array).toList();
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
List<T> after(T[] array) {
|
||||
return Arrays.asList(array);
|
||||
}
|
||||
}
|
||||
|
||||
/** Prefer calling {@link Collection#toArray()} over more contrived alternatives. */
|
||||
static final class CollectionToArray<T> {
|
||||
@BeforeTemplate
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
|
||||
import static java.util.function.Predicate.isEqual;
|
||||
import static java.util.function.Predicate.not;
|
||||
|
||||
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
||||
@@ -19,9 +20,9 @@ import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
|
||||
final class EqualityRules {
|
||||
private EqualityRules() {}
|
||||
|
||||
/** Prefer reference-based quality for enums. */
|
||||
// Primitive value comparisons are not listed, because Error Prone flags those out of the box.
|
||||
static final class PrimitiveOrReferenceEquality<T extends Enum<T>> {
|
||||
/** Prefer reference-based equality for enums. */
|
||||
// Primitive value comparisons are not matched, because Error Prone flags those out of the box.
|
||||
static final class EnumReferenceEquality<T extends Enum<T>> {
|
||||
/**
|
||||
* Enums can be compared by reference. It is safe to do so even in the face of refactorings,
|
||||
* because if the type is ever converted to a non-enum, then Error-Prone will complain about any
|
||||
@@ -43,6 +44,20 @@ final class EqualityRules {
|
||||
}
|
||||
}
|
||||
|
||||
/** Prefer reference-based equality for enums. */
|
||||
static final class EnumReferenceEqualityLambda<T extends Enum<T>> {
|
||||
@BeforeTemplate
|
||||
Predicate<T> before(T e) {
|
||||
return Refaster.anyOf(isEqual(e), e::equals);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@SuppressWarnings("java:S1698" /* Reference comparison is valid for enums. */)
|
||||
Predicate<T> after(T e) {
|
||||
return v -> v == e;
|
||||
}
|
||||
}
|
||||
|
||||
/** Prefer {@link Object#equals(Object)} over the equivalent lambda function. */
|
||||
// XXX: As it stands, this rule is a special case of what `MethodReferenceUsage` tries to achieve.
|
||||
// If/when `MethodReferenceUsage` becomes production ready, we should simply drop this check.
|
||||
|
||||
@@ -2,12 +2,15 @@ package tech.picnic.errorprone.refasterrules;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import com.google.errorprone.refaster.Refaster;
|
||||
import com.google.errorprone.refaster.annotation.AfterTemplate;
|
||||
import com.google.errorprone.refaster.annotation.BeforeTemplate;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.FileAttribute;
|
||||
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
|
||||
|
||||
/** Refaster rules related to expressions dealing with files. */
|
||||
@@ -40,4 +43,24 @@ final class FileRules {
|
||||
return Files.readString(path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link Files#createTempFile(String, String, FileAttribute[])} over alternatives that
|
||||
* create files with more liberal permissions.
|
||||
*/
|
||||
static final class FilesCreateTempFileToFile {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings("java:S5443" /* This violation will be rewritten. */)
|
||||
File before(String prefix, String suffix) throws IOException {
|
||||
return Refaster.anyOf(
|
||||
File.createTempFile(prefix, suffix), File.createTempFile(prefix, suffix, null));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@SuppressWarnings(
|
||||
"java:S5443" /* On POSIX systems the file will only have user read-write permissions. */)
|
||||
File after(String prefix, String suffix) throws IOException {
|
||||
return Files.createTempFile(prefix, suffix).toFile();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,16 +302,22 @@ import tech.picnic.errorprone.refaster.annotation.TypeMigration;
|
||||
final class JUnitToAssertJRules {
|
||||
private JUnitToAssertJRules() {}
|
||||
|
||||
static final class ThrowNewAssertionError {
|
||||
static final class Fail<T> {
|
||||
@BeforeTemplate
|
||||
void before() {
|
||||
Assertions.fail();
|
||||
T before() {
|
||||
return Assertions.fail();
|
||||
}
|
||||
|
||||
// XXX: Add `@UseImportPolicy(STATIC_IMPORT_ALWAYS)` once
|
||||
// https://github.com/google/error-prone/pull/3584 is resolved. Until that time, statically
|
||||
// importing AssertJ's `fail` is likely to clash with an existing static import of JUnit's
|
||||
// `fail`. Note that combining Error Prone's `RemoveUnusedImports` and
|
||||
// `UnnecessarilyFullyQualified` checks and our `StaticImport` check will anyway cause the
|
||||
// method to be imported statically if possible; just in a less efficient manner.
|
||||
@AfterTemplate
|
||||
@DoNotCall
|
||||
void after() {
|
||||
throw new AssertionError();
|
||||
T after() {
|
||||
return fail();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -321,12 +327,7 @@ final class JUnitToAssertJRules {
|
||||
return Assertions.fail(message);
|
||||
}
|
||||
|
||||
// XXX: Add `@UseImportPolicy(STATIC_IMPORT_ALWAYS)` once
|
||||
// https://github.com/google/error-prone/pull/3584 is resolved. Until that time, statically
|
||||
// importing AssertJ's `fail` is likely to clash with an existing static import of JUnit's
|
||||
// `fail`. Note that combining Error Prone's `RemoveUnusedImports` and
|
||||
// `UnnecessarilyFullyQualified` checks and our `StaticImport` check will anyway cause the
|
||||
// method to be imported statically if possible; just in a less efficient manner.
|
||||
// XXX: Add `@UseImportPolicy(STATIC_IMPORT_ALWAYS)`. See `Fail` comment.
|
||||
@AfterTemplate
|
||||
T after(String message) {
|
||||
return fail(message);
|
||||
@@ -339,28 +340,24 @@ final class JUnitToAssertJRules {
|
||||
return Assertions.fail(message, throwable);
|
||||
}
|
||||
|
||||
// XXX: Add `@UseImportPolicy(STATIC_IMPORT_ALWAYS)` once
|
||||
// https://github.com/google/error-prone/pull/3584 is resolved. Until that time, statically
|
||||
// importing AssertJ's `fail` is likely to clash with an existing static import of JUnit's
|
||||
// `fail`. Note that combining Error Prone's `RemoveUnusedImports` and
|
||||
// `UnnecessarilyFullyQualified` checks and our `StaticImport` check will anyway cause the
|
||||
// method to be imported statically if possible; just in a less efficient manner.
|
||||
// XXX: Add `@UseImportPolicy(STATIC_IMPORT_ALWAYS)`. See `Fail` comment.
|
||||
@AfterTemplate
|
||||
T after(String message, Throwable throwable) {
|
||||
return fail(message, throwable);
|
||||
}
|
||||
}
|
||||
|
||||
static final class FailWithThrowable {
|
||||
static final class FailWithThrowable<T> {
|
||||
@BeforeTemplate
|
||||
void before(Throwable throwable) {
|
||||
Assertions.fail(throwable);
|
||||
T before(Throwable throwable) {
|
||||
return Assertions.fail(throwable);
|
||||
}
|
||||
|
||||
// XXX: Add `@UseImportPolicy(STATIC_IMPORT_ALWAYS)`. See `Fail` comment.
|
||||
@AfterTemplate
|
||||
@DoNotCall
|
||||
void after(Throwable throwable) {
|
||||
throw new AssertionError(throwable);
|
||||
T after(Throwable throwable) {
|
||||
return fail(throwable);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
@@ -40,6 +41,7 @@ import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collector;
|
||||
import java.util.stream.Stream;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.reactivestreams.Publisher;
|
||||
import reactor.core.publisher.Flux;
|
||||
@@ -480,15 +482,20 @@ final class ReactorRules {
|
||||
}
|
||||
|
||||
/** Prefer {@link Flux#just(Object)} over more contrived alternatives. */
|
||||
static final class FluxJust {
|
||||
static final class FluxJust<T> {
|
||||
@BeforeTemplate
|
||||
Flux<Integer> before(int start) {
|
||||
return Flux.range(start, 1);
|
||||
Flux<Integer> before(int value) {
|
||||
return Flux.range(value, 1);
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
Flux<T> before(T value) {
|
||||
return Mono.just(value).repeat().take(1);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Flux<Integer> after(int start) {
|
||||
return Flux.just(start);
|
||||
Flux<T> after(T value) {
|
||||
return Flux.just(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1198,10 +1205,17 @@ final class ReactorRules {
|
||||
}
|
||||
|
||||
/** Prefer {@link Flux#fromIterable(Iterable)} over less efficient alternatives. */
|
||||
// XXX: Once the `FluxFromStreamSupplier` rule is constrained using
|
||||
// `@NotMatches(IsIdentityOperation.class)`, this rule should also cover
|
||||
// `Flux.fromStream(collection.stream())`.
|
||||
static final class FluxFromIterable<T> {
|
||||
// XXX: Once the `MethodReferenceUsage` check is generally enabled, drop the second
|
||||
// `Refaster.anyOf` variant.
|
||||
@BeforeTemplate
|
||||
Flux<T> before(Collection<T> collection) {
|
||||
return Flux.fromStream(collection.stream());
|
||||
return Flux.fromStream(
|
||||
Refaster.<Supplier<Stream<? extends T>>>anyOf(
|
||||
collection::stream, () -> collection.stream()));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -1904,4 +1918,60 @@ final class ReactorRules {
|
||||
return step.verifyTimeout(duration);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link Mono#fromFuture(Supplier)} over {@link Mono#fromFuture(CompletableFuture)}, as
|
||||
* the former may defer initiation of the asynchronous computation until subscription.
|
||||
*/
|
||||
static final class MonoFromFutureSupplier<T> {
|
||||
// XXX: Constrain the `future` parameter using `@NotMatches(IsIdentityOperation.class)` once
|
||||
// `IsIdentityOperation` no longer matches nullary method invocations.
|
||||
@BeforeTemplate
|
||||
Mono<T> before(CompletableFuture<T> future) {
|
||||
return Mono.fromFuture(future);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Mono<T> after(CompletableFuture<T> future) {
|
||||
return Mono.fromFuture(() -> future);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link Mono#fromFuture(Supplier, boolean)} over {@link
|
||||
* Mono#fromFuture(CompletableFuture, boolean)}, as the former may defer initiation of the
|
||||
* asynchronous computation until subscription.
|
||||
*/
|
||||
static final class MonoFromFutureSupplierBoolean<T> {
|
||||
// XXX: Constrain the `future` parameter using `@NotMatches(IsIdentityOperation.class)` once
|
||||
// `IsIdentityOperation` no longer matches nullary method invocations.
|
||||
@BeforeTemplate
|
||||
Mono<T> before(CompletableFuture<T> future, boolean suppressCancel) {
|
||||
return Mono.fromFuture(future, suppressCancel);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Mono<T> after(CompletableFuture<T> future, boolean suppressCancel) {
|
||||
return Mono.fromFuture(() -> future, suppressCancel);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer {@link Flux#fromStream(Supplier)} over {@link Flux#fromStream(Stream)}, as the former
|
||||
* yields a {@link Flux} that is more likely to behave as expected when subscribed to more than
|
||||
* once.
|
||||
*/
|
||||
static final class FluxFromStreamSupplier<T> {
|
||||
// XXX: Constrain the `stream` parameter using `@NotMatches(IsIdentityOperation.class)` once
|
||||
// `IsIdentityOperation` no longer matches nullary method invocations.
|
||||
@BeforeTemplate
|
||||
Flux<T> before(Stream<T> stream) {
|
||||
return Flux.fromStream(stream);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Flux<T> after(Stream<T> stream) {
|
||||
return Flux.fromStream(() -> stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,8 +161,9 @@ final class TestNGToAssertJRules {
|
||||
|
||||
@AfterTemplate
|
||||
@DoNotCall
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
void after() {
|
||||
throw new AssertionError();
|
||||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,26 +1,34 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.io.IOException;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
|
||||
|
||||
final class ClassRulesTest implements RefasterRuleCollectionTestCase {
|
||||
boolean testClassIsInstance() throws IOException {
|
||||
boolean testClassIsInstance() {
|
||||
return CharSequence.class.isAssignableFrom("foo".getClass());
|
||||
}
|
||||
|
||||
ImmutableSet<Boolean> testInstanceof() throws IOException {
|
||||
ImmutableSet<Boolean> testInstanceof() {
|
||||
Class<?> clazz = CharSequence.class;
|
||||
return ImmutableSet.of(CharSequence.class.isInstance("foo"), clazz.isInstance("bar"));
|
||||
}
|
||||
|
||||
Predicate<String> testClassLiteralIsInstancePredicate() throws IOException {
|
||||
Predicate<String> testClassLiteralIsInstancePredicate() {
|
||||
return s -> s instanceof CharSequence;
|
||||
}
|
||||
|
||||
Predicate<String> testClassReferenceIsInstancePredicate() throws IOException {
|
||||
Predicate<String> testClassReferenceIsInstancePredicate() {
|
||||
Class<?> clazz = CharSequence.class;
|
||||
return s -> clazz.isInstance(s);
|
||||
}
|
||||
|
||||
Function<Number, Integer> testClassLiteralCast() {
|
||||
return i -> (Integer) i;
|
||||
}
|
||||
|
||||
Function<Number, Integer> testClassReferenceCast() {
|
||||
return i -> Integer.class.cast(i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,34 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.io.IOException;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
|
||||
|
||||
final class ClassRulesTest implements RefasterRuleCollectionTestCase {
|
||||
boolean testClassIsInstance() throws IOException {
|
||||
boolean testClassIsInstance() {
|
||||
return CharSequence.class.isInstance("foo");
|
||||
}
|
||||
|
||||
ImmutableSet<Boolean> testInstanceof() throws IOException {
|
||||
ImmutableSet<Boolean> testInstanceof() {
|
||||
Class<?> clazz = CharSequence.class;
|
||||
return ImmutableSet.of("foo" instanceof CharSequence, clazz.isInstance("bar"));
|
||||
}
|
||||
|
||||
Predicate<String> testClassLiteralIsInstancePredicate() throws IOException {
|
||||
Predicate<String> testClassLiteralIsInstancePredicate() {
|
||||
return CharSequence.class::isInstance;
|
||||
}
|
||||
|
||||
Predicate<String> testClassReferenceIsInstancePredicate() throws IOException {
|
||||
Predicate<String> testClassReferenceIsInstancePredicate() {
|
||||
Class<?> clazz = CharSequence.class;
|
||||
return clazz::isInstance;
|
||||
}
|
||||
|
||||
Function<Number, Integer> testClassLiteralCast() {
|
||||
return Integer.class::cast;
|
||||
}
|
||||
|
||||
Function<Number, Integer> testClassReferenceCast() {
|
||||
return Integer.class::cast;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,11 @@ import com.google.common.collect.ImmutableSortedSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.TreeSet;
|
||||
import java.util.stream.Stream;
|
||||
@@ -70,6 +72,10 @@ final class CollectionRulesTest implements RefasterRuleCollectionTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
Stream<Integer> testSetStream() {
|
||||
return ImmutableSet.of(1).stream().distinct();
|
||||
}
|
||||
|
||||
ArrayList<String> testNewArrayListFromCollection() {
|
||||
return Lists.newArrayList(ImmutableList.of("foo"));
|
||||
}
|
||||
@@ -94,6 +100,10 @@ final class CollectionRulesTest implements RefasterRuleCollectionTestCase {
|
||||
return ImmutableSet.of(1).asList().toString();
|
||||
}
|
||||
|
||||
List<String> testArraysAsList() {
|
||||
return Arrays.stream(new String[0]).toList();
|
||||
}
|
||||
|
||||
ImmutableSet<Object[]> testCollectionToArray() {
|
||||
return ImmutableSet.of(
|
||||
ImmutableSet.of(1).toArray(new Object[1]),
|
||||
|
||||
@@ -6,9 +6,11 @@ import com.google.common.collect.ImmutableSortedSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.TreeSet;
|
||||
import java.util.stream.Stream;
|
||||
@@ -62,6 +64,10 @@ final class CollectionRulesTest implements RefasterRuleCollectionTestCase {
|
||||
new HashSet<Number>().removeAll(ImmutableSet.of(2));
|
||||
}
|
||||
|
||||
Stream<Integer> testSetStream() {
|
||||
return ImmutableSet.of(1).stream();
|
||||
}
|
||||
|
||||
ArrayList<String> testNewArrayListFromCollection() {
|
||||
return new ArrayList<>(ImmutableList.of("foo"));
|
||||
}
|
||||
@@ -86,6 +92,10 @@ final class CollectionRulesTest implements RefasterRuleCollectionTestCase {
|
||||
return ImmutableSet.of(1).toString();
|
||||
}
|
||||
|
||||
List<String> testArraysAsList() {
|
||||
return Arrays.asList(new String[0]);
|
||||
}
|
||||
|
||||
ImmutableSet<Object[]> testCollectionToArray() {
|
||||
return ImmutableSet.of(
|
||||
ImmutableSet.of(1).toArray(), ImmutableSet.of(2).toArray(), ImmutableSet.of(3).toArray());
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
|
||||
import static java.util.function.Predicate.isEqual;
|
||||
import static java.util.function.Predicate.not;
|
||||
|
||||
import com.google.common.collect.BoundType;
|
||||
@@ -14,10 +15,10 @@ import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
|
||||
final class EqualityRulesTest implements RefasterRuleCollectionTestCase {
|
||||
@Override
|
||||
public ImmutableSet<Object> elidedTypesAndStaticImports() {
|
||||
return ImmutableSet.of(Objects.class, Optional.class, not(null));
|
||||
return ImmutableSet.of(Objects.class, Optional.class, isEqual(null), not(null));
|
||||
}
|
||||
|
||||
ImmutableSet<Boolean> testPrimitiveOrReferenceEquality() {
|
||||
ImmutableSet<Boolean> testEnumReferenceEquality() {
|
||||
return ImmutableSet.of(
|
||||
RoundingMode.UP.equals(RoundingMode.DOWN),
|
||||
Objects.equals(RoundingMode.UP, RoundingMode.DOWN),
|
||||
@@ -27,6 +28,10 @@ final class EqualityRulesTest implements RefasterRuleCollectionTestCase {
|
||||
RoundingMode.UP.ordinal() != RoundingMode.DOWN.ordinal());
|
||||
}
|
||||
|
||||
ImmutableSet<Predicate<RoundingMode>> testEnumReferenceEqualityLambda() {
|
||||
return ImmutableSet.of(isEqual(RoundingMode.DOWN), RoundingMode.UP::equals);
|
||||
}
|
||||
|
||||
boolean testEqualsPredicate() {
|
||||
// XXX: When boxing is involved this rule seems to break. Example:
|
||||
// Stream.of(1).anyMatch(e -> Integer.MIN_VALUE.equals(e));
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
|
||||
import static java.util.function.Predicate.isEqual;
|
||||
import static java.util.function.Predicate.not;
|
||||
|
||||
import com.google.common.collect.BoundType;
|
||||
@@ -14,10 +15,10 @@ import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
|
||||
final class EqualityRulesTest implements RefasterRuleCollectionTestCase {
|
||||
@Override
|
||||
public ImmutableSet<Object> elidedTypesAndStaticImports() {
|
||||
return ImmutableSet.of(Objects.class, Optional.class, not(null));
|
||||
return ImmutableSet.of(Objects.class, Optional.class, isEqual(null), not(null));
|
||||
}
|
||||
|
||||
ImmutableSet<Boolean> testPrimitiveOrReferenceEquality() {
|
||||
ImmutableSet<Boolean> testEnumReferenceEquality() {
|
||||
return ImmutableSet.of(
|
||||
RoundingMode.UP == RoundingMode.DOWN,
|
||||
RoundingMode.UP == RoundingMode.DOWN,
|
||||
@@ -27,6 +28,10 @@ final class EqualityRulesTest implements RefasterRuleCollectionTestCase {
|
||||
RoundingMode.UP != RoundingMode.DOWN);
|
||||
}
|
||||
|
||||
ImmutableSet<Predicate<RoundingMode>> testEnumReferenceEqualityLambda() {
|
||||
return ImmutableSet.of(v -> v == RoundingMode.DOWN, v -> v == RoundingMode.UP);
|
||||
}
|
||||
|
||||
boolean testEqualsPredicate() {
|
||||
// XXX: When boxing is involved this rule seems to break. Example:
|
||||
// Stream.of(1).anyMatch(e -> Integer.MIN_VALUE.equals(e));
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
@@ -14,4 +16,9 @@ final class FileRulesTest implements RefasterRuleCollectionTestCase {
|
||||
String testFilesReadString() throws IOException {
|
||||
return Files.readString(Paths.get("foo"), StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
ImmutableSet<File> testFilesCreateTempFileToFile() throws IOException {
|
||||
return ImmutableSet.of(
|
||||
File.createTempFile("foo", "bar"), File.createTempFile("baz", "qux", null));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
@@ -14,4 +16,9 @@ final class FileRulesTest implements RefasterRuleCollectionTestCase {
|
||||
String testFilesReadString() throws IOException {
|
||||
return Files.readString(Paths.get("foo"));
|
||||
}
|
||||
|
||||
ImmutableSet<File> testFilesCreateTempFileToFile() throws IOException {
|
||||
return ImmutableSet.of(
|
||||
Files.createTempFile("foo", "bar").toFile(), Files.createTempFile("baz", "qux").toFile());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,8 +32,8 @@ final class JUnitToAssertJRulesTest implements RefasterRuleCollectionTestCase {
|
||||
(Runnable) () -> assertTrue(true));
|
||||
}
|
||||
|
||||
void testThrowNewAssertionError() {
|
||||
Assertions.fail();
|
||||
Object testFail() {
|
||||
return Assertions.fail();
|
||||
}
|
||||
|
||||
Object testFailWithMessage() {
|
||||
@@ -44,8 +44,8 @@ final class JUnitToAssertJRulesTest implements RefasterRuleCollectionTestCase {
|
||||
return Assertions.fail("foo", new IllegalStateException());
|
||||
}
|
||||
|
||||
void testFailWithThrowable() {
|
||||
Assertions.fail(new IllegalStateException());
|
||||
Object testFailWithThrowable() {
|
||||
return Assertions.fail(new IllegalStateException());
|
||||
}
|
||||
|
||||
void testAssertThatIsTrue() {
|
||||
|
||||
@@ -35,8 +35,8 @@ final class JUnitToAssertJRulesTest implements RefasterRuleCollectionTestCase {
|
||||
(Runnable) () -> assertTrue(true));
|
||||
}
|
||||
|
||||
void testThrowNewAssertionError() {
|
||||
throw new AssertionError();
|
||||
Object testFail() {
|
||||
return org.assertj.core.api.Assertions.fail();
|
||||
}
|
||||
|
||||
Object testFailWithMessage() {
|
||||
@@ -47,8 +47,8 @@ final class JUnitToAssertJRulesTest implements RefasterRuleCollectionTestCase {
|
||||
return org.assertj.core.api.Assertions.fail("foo", new IllegalStateException());
|
||||
}
|
||||
|
||||
void testFailWithThrowable() {
|
||||
throw new AssertionError(new IllegalStateException());
|
||||
Object testFailWithThrowable() {
|
||||
return org.assertj.core.api.Assertions.fail(new IllegalStateException());
|
||||
}
|
||||
|
||||
void testAssertThatIsTrue() {
|
||||
|
||||
@@ -21,7 +21,9 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.math.MathFlux;
|
||||
@@ -182,8 +184,8 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
|
||||
Flux.range(0, 0));
|
||||
}
|
||||
|
||||
Flux<Integer> testFluxJust() {
|
||||
return Flux.range(0, 1);
|
||||
ImmutableSet<Flux<Integer>> testFluxJust() {
|
||||
return ImmutableSet.of(Flux.range(0, 1), Mono.just(2).repeat().take(1));
|
||||
}
|
||||
|
||||
ImmutableSet<Mono<?>> testMonoIdentity() {
|
||||
@@ -433,8 +435,10 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
|
||||
Flux.just(ImmutableList.of("bar")).concatMap(Flux::fromIterable, 2));
|
||||
}
|
||||
|
||||
Flux<String> testFluxFromIterable() {
|
||||
return Flux.fromStream(ImmutableList.of("foo").stream());
|
||||
ImmutableSet<Flux<String>> testFluxFromIterable() {
|
||||
return ImmutableSet.of(
|
||||
Flux.fromStream(ImmutableList.of("foo")::stream),
|
||||
Flux.fromStream(() -> ImmutableList.of("bar").stream()));
|
||||
}
|
||||
|
||||
ImmutableSet<Mono<Integer>> testFluxCountMapMathToIntExact() {
|
||||
@@ -651,4 +655,16 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
|
||||
Duration testStepVerifierLastStepVerifyTimeout() {
|
||||
return Mono.empty().as(StepVerifier::create).expectTimeout(Duration.ZERO).verify();
|
||||
}
|
||||
|
||||
Mono<Void> testMonoFromFutureSupplier() {
|
||||
return Mono.fromFuture(CompletableFuture.completedFuture(null));
|
||||
}
|
||||
|
||||
Mono<Void> testMonoFromFutureSupplierBoolean() {
|
||||
return Mono.fromFuture(CompletableFuture.completedFuture(null), true);
|
||||
}
|
||||
|
||||
Flux<Integer> testFluxFromStreamSupplier() {
|
||||
return Flux.fromStream(Stream.of(1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,9 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.function.TupleUtils;
|
||||
@@ -186,8 +188,8 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
|
||||
Flux.empty());
|
||||
}
|
||||
|
||||
Flux<Integer> testFluxJust() {
|
||||
return Flux.just(0);
|
||||
ImmutableSet<Flux<Integer>> testFluxJust() {
|
||||
return ImmutableSet.of(Flux.just(0), Flux.just(2));
|
||||
}
|
||||
|
||||
ImmutableSet<Mono<?>> testMonoIdentity() {
|
||||
@@ -428,8 +430,9 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
|
||||
Flux.just(ImmutableList.of("bar")).concatMapIterable(identity(), 2));
|
||||
}
|
||||
|
||||
Flux<String> testFluxFromIterable() {
|
||||
return Flux.fromIterable(ImmutableList.of("foo"));
|
||||
ImmutableSet<Flux<String>> testFluxFromIterable() {
|
||||
return ImmutableSet.of(
|
||||
Flux.fromIterable(ImmutableList.of("foo")), Flux.fromIterable(ImmutableList.of("bar")));
|
||||
}
|
||||
|
||||
ImmutableSet<Mono<Integer>> testFluxCountMapMathToIntExact() {
|
||||
@@ -632,4 +635,16 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
|
||||
Duration testStepVerifierLastStepVerifyTimeout() {
|
||||
return Mono.empty().as(StepVerifier::create).verifyTimeout(Duration.ZERO);
|
||||
}
|
||||
|
||||
Mono<Void> testMonoFromFutureSupplier() {
|
||||
return Mono.fromFuture(() -> CompletableFuture.completedFuture(null));
|
||||
}
|
||||
|
||||
Mono<Void> testMonoFromFutureSupplierBoolean() {
|
||||
return Mono.fromFuture(() -> CompletableFuture.completedFuture(null), true);
|
||||
}
|
||||
|
||||
Flux<Integer> testFluxFromStreamSupplier() {
|
||||
return Flux.fromStream(() -> Stream.of(1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ final class TestNGToAssertJRulesTest implements RefasterRuleCollectionTestCase {
|
||||
}
|
||||
|
||||
void testFail() {
|
||||
throw new AssertionError();
|
||||
fail();
|
||||
}
|
||||
|
||||
void testFailWithMessage() {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.16.2-SNAPSHOT</version>
|
||||
<version>0.18.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>error-prone-experimental</artifactId>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.16.2-SNAPSHOT</version>
|
||||
<version>0.18.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>error-prone-guidelines</artifactId>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.16.2-SNAPSHOT</version>
|
||||
<version>0.18.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>error-prone-utils</artifactId>
|
||||
|
||||
@@ -2,205 +2,35 @@
|
||||
|
||||
set -e -u -o pipefail
|
||||
|
||||
integration_test_root="$(cd "$(dirname -- "${0}")" && pwd)"
|
||||
error_prone_support_root="${integration_test_root}/.."
|
||||
repos_root="${integration_test_root}/.repos"
|
||||
|
||||
test_name="$(basename "${0}" .sh)"
|
||||
project=checkstyle
|
||||
repository=https://github.com/checkstyle/checkstyle.git
|
||||
revision=checkstyle-10.14.0
|
||||
|
||||
if [ "${#}" -gt 2 ] || ([ "${#}" = 2 ] && [ "${1:---sync}" != '--sync' ]); then
|
||||
echo "Usage: ${0} [--sync] [<report_directory>]"
|
||||
exit 1
|
||||
fi
|
||||
do_sync="$([ "${#}" = 0 ] || [ "${1:-}" != '--sync' ] || echo 1)"
|
||||
report_directory="$([ "${#}" = 0 ] || ([ -z "${do_sync}" ] && echo "${1}") || ([ "${#}" = 1 ] || echo "${2}"))"
|
||||
|
||||
if [ -n "${report_directory}" ]; then
|
||||
mkdir -p "${report_directory}"
|
||||
else
|
||||
report_directory="$(mktemp -d)"
|
||||
trap 'rm -rf -- "${report_directory}"' INT TERM HUP EXIT
|
||||
fi
|
||||
|
||||
case "$(uname -s)" in
|
||||
Linux*)
|
||||
grep_command=grep
|
||||
sed_command=sed
|
||||
;;
|
||||
Darwin*)
|
||||
grep_command=ggrep
|
||||
sed_command=gsed
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported distribution $(uname -s) for this script."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
project='checkstyle'
|
||||
repository='https://github.com/checkstyle/checkstyle.git'
|
||||
revision='checkstyle-10.14.0'
|
||||
# XXX: Configure Renovate to manage the AssertJ version declared here.
|
||||
shared_build_flags="
|
||||
-Perror-prone-compile,error-prone-test-compile
|
||||
-Dassertj.version=3.24.2
|
||||
-Derror-prone.version=$(
|
||||
mvn -f "${error_prone_support_root}" help:evaluate -Dexpression=version.error-prone -q -DforceStdout
|
||||
)
|
||||
-Derror-prone-support.version=$(
|
||||
mvn -f "${error_prone_support_root}" help:evaluate -Dexpression=project.version -q -DforceStdout
|
||||
)
|
||||
-DadditionalSourceDirectories=\${project.basedir}\${file.separator}src\${file.separator}it\${file.separator}java,\${project.basedir}\${file.separator}src\${file.separator}xdocs-examples\${file.separator}java
|
||||
"
|
||||
|
||||
# XXX: Configure Renovate to manage the fmt-maven-plugin version declared here.
|
||||
# XXX: Once GitHub actions uses Maven 3.9.2+, we can inline this variable with
|
||||
# version reference `${fmt.version}`, and `-Dfmt.version=2.21.1` added to
|
||||
# `shared_build_flags`.
|
||||
format_goal='com.spotify.fmt:fmt-maven-plugin:2.21.1:format'
|
||||
|
||||
error_prone_shared_flags='-XepExcludedPaths:(\Q${project.basedir}${file.separator}src${file.separator}\E(it|test|xdocs-examples)\Q${file.separator}resources\E|\Q${project.build.directory}${file.separator}\E).*'
|
||||
|
||||
error_prone_patch_flags="${error_prone_shared_flags} -XepPatchLocation:IN_PLACE -XepPatchChecks:$(
|
||||
find "${error_prone_support_root}" \
|
||||
-path "*/META-INF/services/com.google.errorprone.bugpatterns.BugChecker" \
|
||||
-not -path "*/error-prone-experimental/*" \
|
||||
-not -path "*/error-prone-guidelines/*" \
|
||||
-print0 \
|
||||
| xargs -0 "${grep_command}" -hoP '[^.]+$' \
|
||||
| paste -s -d ',' -
|
||||
)"
|
||||
|
||||
error_prone_validation_flags="${error_prone_shared_flags} -XepDisableAllChecks $(
|
||||
find "${error_prone_support_root}" \
|
||||
-path "*/META-INF/services/com.google.errorprone.bugpatterns.BugChecker" \
|
||||
-not -path "*/error-prone-experimental/*" \
|
||||
-not -path "*/error-prone-guidelines/*" \
|
||||
-print0 \
|
||||
| xargs -0 "${grep_command}" -hoP '[^.]+$' \
|
||||
| "${sed_command}" -r 's,(.*),-Xep:\1:WARN,' \
|
||||
| paste -s -d ' ' -
|
||||
)"
|
||||
|
||||
echo "Shared build flags: ${shared_build_flags}"
|
||||
echo "Error Prone patch flags: ${error_prone_patch_flags}"
|
||||
echo "Error Prone validation flags: ${error_prone_validation_flags}"
|
||||
|
||||
mkdir -p "${repos_root}"
|
||||
|
||||
# Make sure that the targeted tag of the project's Git repository is checked
|
||||
# out.
|
||||
project_root="${repos_root}/${project}"
|
||||
if [ ! -d "${project_root}" ]; then
|
||||
# The repository has not yet been cloned; create a shallow clone.
|
||||
git clone --branch "${revision}" --depth 1 "${repository}" "${project_root}"
|
||||
else
|
||||
# The repository does already appear to exist. Try to check out the requested
|
||||
# tag if possible, and fetch it otherwise.
|
||||
#
|
||||
# Under certain circumstances this does not cause the relevant tag to be
|
||||
# created, so if necessary we manually create it.
|
||||
git -C "${project_root}" checkout --force "${revision}" 2>/dev/null \
|
||||
|| (
|
||||
git -C "${project_root}" fetch --depth 1 "${repository}" "${revision}" \
|
||||
&& git -C "${project_root}" checkout --force FETCH_HEAD \
|
||||
&& (git -C "${project_root}" tag "${revision}" || true)
|
||||
)
|
||||
fi
|
||||
|
||||
pushd "${project_root}"
|
||||
|
||||
# Make sure that Git is sufficiently configured to enable committing to the
|
||||
# project's Git repository.
|
||||
git config user.email || git config user.email "integration-test@example.com"
|
||||
git config user.name || git config user.name "Integration Test"
|
||||
|
||||
# Prepare the code for analysis by (a) applying the minimal set of changes
|
||||
# required to run Error Prone with Error Prone Support and (b) formatting the
|
||||
# code using the same method by which it will be formatted after each
|
||||
# compilation round. The initial formatting operation ensures that subsequent
|
||||
# modifications can be rendered in a clean manner.
|
||||
git clean -fdx
|
||||
git apply < "${integration_test_root}/${test_name}-init.patch"
|
||||
git commit -m 'dependency: Introduce Error Prone Support' .
|
||||
mvn ${shared_build_flags} "${format_goal}"
|
||||
git commit -m 'minor: Reformat using Google Java Format' .
|
||||
diff_base="$(git rev-parse HEAD)"
|
||||
|
||||
# Apply Error Prone Support-suggested changes until a fixed point is reached.
|
||||
function apply_patch() {
|
||||
local extra_build_args="${1}"
|
||||
|
||||
mvn ${shared_build_flags} ${extra_build_args} \
|
||||
package "${format_goal}" \
|
||||
-Derror-prone.configuration-args="${error_prone_patch_flags}" \
|
||||
-DskipTests
|
||||
|
||||
if ! git diff --exit-code; then
|
||||
git commit -m 'minor: Apply patches' .
|
||||
|
||||
# Changes were applied, so another compilation round may apply yet more
|
||||
# changes. For performance reasons we perform incremental compilation,
|
||||
# enabled using a misleading flag. (See
|
||||
# https://issues.apache.org/jira/browse/MCOMPILER-209 for details.)
|
||||
apply_patch '-Dmaven.compiler.useIncrementalCompilation=false'
|
||||
elif [ "${extra_build_args}" != 'clean' ]; then
|
||||
# No changes were applied. We'll attempt one more round in which all files
|
||||
# are recompiled, because there are cases in which violations are missed
|
||||
# during incremental compilation.
|
||||
apply_patch 'clean'
|
||||
fi
|
||||
}
|
||||
apply_patch ''
|
||||
|
||||
# Run one more full build and log the output.
|
||||
#
|
||||
# By also running the tests, we validate that the (majority of) applied changes
|
||||
# are behavior preserving. Some tests are skipped:
|
||||
additional_build_flags='-Dassertj.version=3.24.2'
|
||||
additional_source_directories='${project.basedir}${file.separator}src${file.separator}it${file.separator}java,${project.basedir}${file.separator}src${file.separator}xdocs-examples${file.separator}java'
|
||||
patch_error_prone_flags=''
|
||||
validation_error_prone_flags=''
|
||||
# Validation skips some tests:
|
||||
# - The `metadataFilesGenerationAllFiles` test is skipped because it makes line
|
||||
# number assertions that will fail when the code is formatted or patched.
|
||||
# - The `allCheckSectionJavaDocs` test is skipped because is validates that
|
||||
# - The `allCheckSectionJavaDocs` test is skipped because it validates that
|
||||
# Javadoc has certain closing tags that are removed by Google Java Format.
|
||||
validation_build_log="${report_directory}/${test_name}-validation-build-log.txt"
|
||||
mvn ${shared_build_flags} \
|
||||
clean package \
|
||||
-Derror-prone.configuration-args="${error_prone_validation_flags}" \
|
||||
-Dtest='
|
||||
!MetadataGeneratorUtilTest#metadataFilesGenerationAllFiles,
|
||||
!XdocsJavaDocsTest#allCheckSectionJavaDocs' \
|
||||
| tee "${validation_build_log}" \
|
||||
|| failure=1
|
||||
validation_build_flags='-Dtest=!MetadataGeneratorUtilTest#metadataFilesGenerationAllFiles,!XdocsJavaDocsTest#allCheckSectionJavaDocs'
|
||||
|
||||
# Collect the applied changes.
|
||||
expected_changes="${integration_test_root}/${test_name}-expected-changes.patch"
|
||||
actual_changes="${report_directory}/${test_name}-changes.patch"
|
||||
(git diff "${diff_base}"..HEAD | "${grep_command}" -vP '^(diff|index)' || true) > "${actual_changes}"
|
||||
|
||||
# Collect the warnings reported by Error Prone Support checks.
|
||||
expected_warnings="${integration_test_root}/${test_name}-expected-warnings.txt"
|
||||
actual_warnings="${report_directory}/${test_name}-validation-build-warnings.txt"
|
||||
("${grep_command}" -oP "(?<=^\\Q[WARNING] ${PWD}/\\E).*" "${validation_build_log}" | "${grep_command}" -P '\] \[' || true) | LC_ALL=C sort > "${actual_warnings}"
|
||||
|
||||
# Persist or validate the applied changes and reported warnings.
|
||||
if [ -n "${do_sync}" ]; then
|
||||
echo 'Saving changes...'
|
||||
cp "${actual_changes}" "${expected_changes}"
|
||||
cp "${actual_warnings}" "${expected_warnings}"
|
||||
else
|
||||
echo 'Inspecting changes...'
|
||||
# XXX: This "diff of diffs" also contains vacuous sections, introduced due to
|
||||
# line offset differences. Try to omit those from the final output.
|
||||
if ! diff -u "${expected_changes}" "${actual_changes}"; then
|
||||
echo 'There are unexpected changes. Inspect the preceding output for details.'
|
||||
failure=1
|
||||
fi
|
||||
echo 'Inspecting emitted warnings...'
|
||||
if ! diff -u "${expected_warnings}" "${actual_warnings}"; then
|
||||
echo 'Diagnostics output changed. Inspect the preceding output for details.'
|
||||
failure=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "${failure:-}" ]; then
|
||||
if [ "${#}" -gt 2 ] || ([ "${#}" = 2 ] && [ "${1:---sync}" != '--sync' ]); then
|
||||
>&2 echo "Usage: ${0} [--sync] [<report_directory>]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
"$(dirname "${0}")/run-integration-test.sh" \
|
||||
"${test_name}" \
|
||||
"${project}" \
|
||||
"${repository}" \
|
||||
"${revision}" \
|
||||
"${additional_build_flags}" \
|
||||
"${additional_source_directories}" \
|
||||
"${patch_error_prone_flags}" \
|
||||
"${validation_error_prone_flags}" \
|
||||
"${validation_build_flags}" \
|
||||
$@
|
||||
|
||||
210
integration-tests/run-integration-test.sh
Executable file
210
integration-tests/run-integration-test.sh
Executable file
@@ -0,0 +1,210 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Integration test framework for Maven builds.
|
||||
#
|
||||
# This script is not meant to be invoked manually. Instead it should be invoked
|
||||
# through one of the top-level integration test scripts, such as
|
||||
# `checkstyle.sh`.
|
||||
|
||||
set -e -u -o pipefail
|
||||
|
||||
integration_test_root="$(cd "$(dirname -- "${0}")" && pwd)"
|
||||
error_prone_support_root="${integration_test_root}/.."
|
||||
repos_root="${integration_test_root}/.repos"
|
||||
|
||||
if [ "${#}" -lt 9 ] || [ "${#}" -gt 11 ] || ([ "${#}" = 11 ] && [ "${10:---sync}" != '--sync' ]); then
|
||||
>&2 echo "Usage: $(basename "${0}") <test_name> <project> <repository> <revision> <additional_build_flags> <additional_source_directories> <patch_error_prone_flags> <validation_error_prone_flags> <validation_build_flags> [--sync] [<report_directory>]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
test_name="${1}"
|
||||
project="${2}"
|
||||
repository="${3}"
|
||||
revision="${4}"
|
||||
additional_build_flags="${5}"
|
||||
additional_source_directories="${6}"
|
||||
patch_error_prone_flags="${7}"
|
||||
validation_error_prone_flags="${8}"
|
||||
validation_build_flags="${9}"
|
||||
do_sync="$([ "${#}" = 9 ] || [ "${10:-}" != '--sync' ] || echo 1)"
|
||||
report_directory="$([ "${#}" = 9 ] || ([ -z "${do_sync}" ] && echo "${10}") || ([ "${#}" = 10 ] || echo "${11}"))"
|
||||
|
||||
if [ -n "${report_directory}" ]; then
|
||||
mkdir -p "${report_directory}"
|
||||
else
|
||||
report_directory="$(mktemp -d)"
|
||||
trap 'rm -rf -- "${report_directory}"' INT TERM HUP EXIT
|
||||
fi
|
||||
|
||||
case "$(uname -s)" in
|
||||
Linux*)
|
||||
grep_command=grep
|
||||
sed_command=sed
|
||||
;;
|
||||
Darwin*)
|
||||
grep_command=ggrep
|
||||
sed_command=gsed
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported distribution $(uname -s) for this script."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
shared_build_flags="
|
||||
-Perror-prone-compile,error-prone-test-compile
|
||||
-Derror-prone.version=$(
|
||||
mvn -f "${error_prone_support_root}" help:evaluate -Dexpression=version.error-prone -q -DforceStdout
|
||||
)
|
||||
-Derror-prone-support.version=$(
|
||||
mvn -f "${error_prone_support_root}" help:evaluate -Dexpression=project.version -q -DforceStdout
|
||||
)
|
||||
-DadditionalSourceDirectories=${additional_source_directories}
|
||||
${additional_build_flags}
|
||||
"
|
||||
|
||||
# XXX: Configure Renovate to manage the fmt-maven-plugin version declared here.
|
||||
# XXX: Once GitHub actions uses Maven 3.9.2+, we can inline this variable with
|
||||
# version reference `${fmt.version}`, and `-Dfmt.version=2.21.1` added to
|
||||
# `shared_build_flags`.
|
||||
format_goal='com.spotify.fmt:fmt-maven-plugin:2.21.1:format'
|
||||
|
||||
error_prone_shared_flags='-XepExcludedPaths:(\Q${project.basedir}${file.separator}src${file.separator}\E(it|test|xdocs-examples)\Q${file.separator}resources\E|\Q${project.build.directory}${file.separator}\E).*'
|
||||
|
||||
error_prone_patch_flags="${error_prone_shared_flags} -XepPatchLocation:IN_PLACE -XepPatchChecks:$(
|
||||
find "${error_prone_support_root}" \
|
||||
-path "*/META-INF/services/com.google.errorprone.bugpatterns.BugChecker" \
|
||||
-not -path "*/error-prone-experimental/*" \
|
||||
-not -path "*/error-prone-guidelines/*" \
|
||||
-print0 \
|
||||
| xargs -0 "${grep_command}" -hoP '[^.]+$' \
|
||||
| paste -s -d ',' -
|
||||
) ${patch_error_prone_flags}"
|
||||
|
||||
error_prone_validation_flags="${error_prone_shared_flags} -XepDisableAllChecks $(
|
||||
find "${error_prone_support_root}" \
|
||||
-path "*/META-INF/services/com.google.errorprone.bugpatterns.BugChecker" \
|
||||
-not -path "*/error-prone-experimental/*" \
|
||||
-not -path "*/error-prone-guidelines/*" \
|
||||
-print0 \
|
||||
| xargs -0 "${grep_command}" -hoP '[^.]+$' \
|
||||
| "${sed_command}" -r 's,(.*),-Xep:\1:WARN,' \
|
||||
| paste -s -d ' ' -
|
||||
) ${validation_error_prone_flags}"
|
||||
|
||||
echo "Shared build flags: ${shared_build_flags}"
|
||||
echo "Error Prone patch flags: ${error_prone_patch_flags}"
|
||||
echo "Error Prone validation flags: ${error_prone_validation_flags}"
|
||||
|
||||
mkdir -p "${repos_root}"
|
||||
|
||||
# Make sure that the targeted tag of the project's Git repository is checked
|
||||
# out.
|
||||
project_root="${repos_root}/${project}"
|
||||
if [ ! -d "${project_root}" ]; then
|
||||
# The repository has not yet been cloned; create a shallow clone.
|
||||
git clone --branch "${revision}" --depth 1 "${repository}" "${project_root}"
|
||||
else
|
||||
# The repository does already appear to exist. Try to check out the requested
|
||||
# tag if possible, and fetch it otherwise.
|
||||
#
|
||||
# Under certain circumstances this does not cause the relevant tag to be
|
||||
# created, so if necessary we manually create it.
|
||||
git -C "${project_root}" checkout --force "${revision}" 2>/dev/null \
|
||||
|| (
|
||||
git -C "${project_root}" fetch --depth 1 "${repository}" "${revision}" \
|
||||
&& git -C "${project_root}" checkout --force FETCH_HEAD \
|
||||
&& (git -C "${project_root}" tag "${revision}" || true)
|
||||
)
|
||||
fi
|
||||
|
||||
pushd "${project_root}"
|
||||
|
||||
# Make sure that Git is sufficiently configured to enable committing to the
|
||||
# project's Git repository.
|
||||
git config user.email || git config user.email 'integration-test@example.com'
|
||||
git config user.name || git config user.name 'Integration Test'
|
||||
|
||||
# Prepare the code for analysis by (a) applying the minimal set of changes
|
||||
# required to run Error Prone with Error Prone Support and (b) formatting the
|
||||
# code using the same method by which it will be formatted after each
|
||||
# compilation round. The initial formatting operation ensures that subsequent
|
||||
# modifications can be rendered in a clean manner.
|
||||
git clean -fdx
|
||||
git apply < "${integration_test_root}/${test_name}-init.patch"
|
||||
git commit -m 'dependency: Introduce Error Prone Support' .
|
||||
mvn ${shared_build_flags} "${format_goal}"
|
||||
git commit -m 'minor: Reformat using Google Java Format' .
|
||||
diff_base="$(git rev-parse HEAD)"
|
||||
|
||||
# Apply Error Prone Support-suggested changes until a fixed point is reached.
|
||||
function apply_patch() {
|
||||
local extra_build_args="${1}"
|
||||
|
||||
mvn ${shared_build_flags} ${extra_build_args} \
|
||||
package "${format_goal}" \
|
||||
-Derror-prone.configuration-args="${error_prone_patch_flags}" \
|
||||
-DskipTests
|
||||
|
||||
if ! git diff --exit-code; then
|
||||
git commit -m 'minor: Apply patches' .
|
||||
|
||||
# Changes were applied, so another compilation round may apply yet more
|
||||
# changes. For performance reasons we perform incremental compilation,
|
||||
# enabled using a misleading flag. (See
|
||||
# https://issues.apache.org/jira/browse/MCOMPILER-209 for details.)
|
||||
apply_patch '-Dmaven.compiler.useIncrementalCompilation=false'
|
||||
elif [ "${extra_build_args}" != 'clean' ]; then
|
||||
# No changes were applied. We'll attempt one more round in which all files
|
||||
# are recompiled, because there are cases in which violations are missed
|
||||
# during incremental compilation.
|
||||
apply_patch 'clean'
|
||||
fi
|
||||
}
|
||||
apply_patch ''
|
||||
|
||||
# Run one more full build and log the output.
|
||||
#
|
||||
# By also running the tests, we validate that the (majority of) applied changes
|
||||
# are behavior preserving.
|
||||
validation_build_log="${report_directory}/${test_name}-validation-build-log.txt"
|
||||
mvn ${shared_build_flags} \
|
||||
clean package \
|
||||
-Derror-prone.configuration-args="${error_prone_validation_flags}" \
|
||||
${validation_build_flags} \
|
||||
| tee "${validation_build_log}" \
|
||||
|| failure=1
|
||||
|
||||
# Collect the applied changes.
|
||||
expected_changes="${integration_test_root}/${test_name}-expected-changes.patch"
|
||||
actual_changes="${report_directory}/${test_name}-changes.patch"
|
||||
(git diff "${diff_base}"..HEAD | "${grep_command}" -vP '^(diff|index)' || true) > "${actual_changes}"
|
||||
|
||||
# Collect the warnings reported by Error Prone Support checks.
|
||||
expected_warnings="${integration_test_root}/${test_name}-expected-warnings.txt"
|
||||
actual_warnings="${report_directory}/${test_name}-validation-build-warnings.txt"
|
||||
("${grep_command}" -oP "(?<=^\\Q[WARNING] ${PWD}/\\E).*" "${validation_build_log}" | "${grep_command}" -P '\] \[' || true) | LC_ALL=C sort > "${actual_warnings}"
|
||||
|
||||
# Persist or validate the applied changes and reported warnings.
|
||||
if [ -n "${do_sync}" ]; then
|
||||
echo 'Saving changes...'
|
||||
cp "${actual_changes}" "${expected_changes}"
|
||||
cp "${actual_warnings}" "${expected_warnings}"
|
||||
else
|
||||
echo 'Inspecting changes...'
|
||||
# XXX: This "diff of diffs" also contains vacuous sections, introduced due to
|
||||
# line offset differences. Try to omit those from the final output.
|
||||
if ! diff -u "${expected_changes}" "${actual_changes}"; then
|
||||
echo 'There are unexpected changes. Inspect the preceding output for details.'
|
||||
failure=1
|
||||
fi
|
||||
echo 'Inspecting emitted warnings...'
|
||||
if ! diff -u "${expected_warnings}" "${actual_warnings}"; then
|
||||
echo 'Diagnostics output changed. Inspect the preceding output for details.'
|
||||
failure=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "${failure:-}" ]; then
|
||||
exit 1
|
||||
fi
|
||||
133
pom.xml
133
pom.xml
@@ -4,7 +4,7 @@
|
||||
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.16.2-SNAPSHOT</version>
|
||||
<version>0.18.0</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>Picnic :: Error Prone Support</name>
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
<scm child.scm.developerConnection.inherit.append.path="false" child.scm.url.inherit.append.path="false">
|
||||
<developerConnection>scm:git:git@github.com:PicnicSupermarket/error-prone-support.git</developerConnection>
|
||||
<tag>HEAD</tag>
|
||||
<tag>v0.18.0</tag>
|
||||
<url>https://github.com/PicnicSupermarket/error-prone-support</url>
|
||||
</scm>
|
||||
<issueManagement>
|
||||
@@ -148,7 +148,7 @@
|
||||
<groupId.error-prone>com.google.errorprone</groupId.error-prone>
|
||||
<!-- The build timestamp is derived from the most recent commit
|
||||
timestamp in support of reproducible builds. -->
|
||||
<project.build.outputTimestamp>2024-03-15T12:04:44Z</project.build.outputTimestamp>
|
||||
<project.build.outputTimestamp>2024-08-11T13:04:41Z</project.build.outputTimestamp>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<!-- Glob pattern identifying Refaster rule definition files. These
|
||||
Java classes don't contain "regular" code, and thus require special
|
||||
@@ -208,16 +208,16 @@
|
||||
<version.auto-value>1.11.0</version.auto-value>
|
||||
<version.error-prone>${version.error-prone-orig}</version.error-prone>
|
||||
<version.error-prone-fork>v${version.error-prone-orig}-picnic-1</version.error-prone-fork>
|
||||
<version.error-prone-orig>2.27.1</version.error-prone-orig>
|
||||
<version.error-prone-orig>2.30.0</version.error-prone-orig>
|
||||
<version.error-prone-slf4j>0.1.25</version.error-prone-slf4j>
|
||||
<version.guava-beta-checker>1.0</version.guava-beta-checker>
|
||||
<version.jdk>17</version.jdk>
|
||||
<version.maven>3.9.5</version.maven>
|
||||
<version.mockito>5.12.0</version.mockito>
|
||||
<version.nopen-checker>1.0.1</version.nopen-checker>
|
||||
<version.nullaway>0.11.0</version.nullaway>
|
||||
<version.nullaway>0.11.1</version.nullaway>
|
||||
<version.pitest-git>1.1.4</version.pitest-git>
|
||||
<version.rewrite-templating>1.10.0</version.rewrite-templating>
|
||||
<version.rewrite-templating>1.12.3</version.rewrite-templating>
|
||||
<version.surefire>3.2.3</version.surefire>
|
||||
</properties>
|
||||
|
||||
@@ -296,7 +296,7 @@
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson</groupId>
|
||||
<artifactId>jackson-bom</artifactId>
|
||||
<version>2.17.1</version>
|
||||
<version>2.17.2</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -328,7 +328,7 @@
|
||||
<dependency>
|
||||
<groupId>com.google.googlejavaformat</groupId>
|
||||
<artifactId>google-java-format</artifactId>
|
||||
<version>1.22.0</version>
|
||||
<version>1.23.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
@@ -345,7 +345,7 @@
|
||||
<dependency>
|
||||
<groupId>com.google.truth</groupId>
|
||||
<artifactId>truth</artifactId>
|
||||
<version>1.4.2</version>
|
||||
<version>1.4.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jakewharton.nopen</groupId>
|
||||
@@ -360,7 +360,7 @@
|
||||
<dependency>
|
||||
<groupId>io.projectreactor</groupId>
|
||||
<artifactId>reactor-bom</artifactId>
|
||||
<version>2023.0.6</version>
|
||||
<version>2023.0.8</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -382,7 +382,12 @@
|
||||
<dependency>
|
||||
<groupId>jakarta.servlet</groupId>
|
||||
<artifactId>jakarta.servlet-api</artifactId>
|
||||
<version>6.0.0</version>
|
||||
<version>6.1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>javax.annotation-api</artifactId>
|
||||
<version>1.3.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
@@ -407,7 +412,7 @@
|
||||
<dependency>
|
||||
<groupId>net.bytebuddy</groupId>
|
||||
<artifactId>byte-buddy</artifactId>
|
||||
<version>1.14.17</version>
|
||||
<version>1.14.18</version>
|
||||
</dependency>
|
||||
<!-- Specified so that Renovate will file Maven upgrade PRs, which
|
||||
subsequently will cause `maven-enforcer-plugin` to require that
|
||||
@@ -425,19 +430,19 @@
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-bom</artifactId>
|
||||
<version>3.25.3</version>
|
||||
<version>3.26.3</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.checkerframework</groupId>
|
||||
<artifactId>checker-qual</artifactId>
|
||||
<version>3.44.0</version>
|
||||
<version>3.46.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-core</artifactId>
|
||||
<version>2.2</version>
|
||||
<version>3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.immutables</groupId>
|
||||
@@ -447,12 +452,12 @@
|
||||
<dependency>
|
||||
<groupId>org.jspecify</groupId>
|
||||
<artifactId>jspecify</artifactId>
|
||||
<version>0.3.0</version>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit</groupId>
|
||||
<artifactId>junit-bom</artifactId>
|
||||
<version>5.10.2</version>
|
||||
<version>5.10.3</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -466,7 +471,7 @@
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongodb-driver-core</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.1.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openrewrite</groupId>
|
||||
@@ -476,33 +481,33 @@
|
||||
<dependency>
|
||||
<groupId>org.openrewrite.recipe</groupId>
|
||||
<artifactId>rewrite-recipe-bom</artifactId>
|
||||
<version>2.12.0</version>
|
||||
<version>2.16.0</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-bom</artifactId>
|
||||
<version>2.0.13</version>
|
||||
<version>2.0.16</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>6.1.8</version>
|
||||
<version>6.1.11</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-test</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<version>3.3.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-bom</artifactId>
|
||||
<version>6.3.0</version>
|
||||
<version>6.3.1</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@@ -624,7 +629,7 @@
|
||||
<plugin>
|
||||
<groupId>io.github.git-commit-id</groupId>
|
||||
<artifactId>git-commit-id-maven-plugin</artifactId>
|
||||
<version>9.0.0</version>
|
||||
<version>9.0.1</version>
|
||||
<configuration>
|
||||
<injectAllReactorProjects>true</injectAllReactorProjects>
|
||||
<runOnlyOnce>true</runOnlyOnce>
|
||||
@@ -912,7 +917,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-clean-plugin</artifactId>
|
||||
<version>3.3.2</version>
|
||||
<version>3.4.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
@@ -960,11 +965,43 @@
|
||||
https://issues.apache.org/jira/browse/MCOMPILER-209. -->
|
||||
<useIncrementalCompilation>false</useIncrementalCompilation>
|
||||
</configuration>
|
||||
<executions>
|
||||
<!-- OpenRewrite recipe sources, generated by the
|
||||
`rewrite-templating` annotation processor and
|
||||
identified as classes whose name ends in `Recipes`, are
|
||||
compiled to target Java 8 for compatibility with the
|
||||
wider OpenRewrite ecosystem. The `maven-jar-plugin` is
|
||||
configured to package these files into a separate JAR. -->
|
||||
<execution>
|
||||
<id>compile-recipes</id>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<compilerArgs combine.self="override">
|
||||
<!-- When Java 8 is targeted we can't use
|
||||
the `add-exports` flag. And since this goal
|
||||
only recompiles already-compiled code,
|
||||
static analysis is irrelevant. As such we
|
||||
clear all compiler arguments, and only
|
||||
suppress source/target/bootstrap classpath
|
||||
warnings. -->
|
||||
<arg>-Xlint:-options</arg>
|
||||
</compilerArgs>
|
||||
<source>8</source>
|
||||
<target>8</target>
|
||||
<includes>
|
||||
<include>**/*Recipes.java</include>
|
||||
</includes>
|
||||
<outputDirectory>${project.build.directory}/openrewrite-recipes</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<version>3.6.1</version>
|
||||
<version>3.7.1</version>
|
||||
<configuration>
|
||||
<!-- XXX: Drop `ignoreAllNonTestScoped` once
|
||||
https://issues.apache.org/jira/browse/MNG-6058 is
|
||||
@@ -1090,7 +1127,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.4.1</version>
|
||||
<version>3.4.2</version>
|
||||
<configuration>
|
||||
<skipIfEmpty>true</skipIfEmpty>
|
||||
<archive>
|
||||
@@ -1107,6 +1144,39 @@
|
||||
</archive>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>default-jar</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<!-- These Java 17 bytecode classes are omitted
|
||||
from the default JAR, as instead we produce a
|
||||
separate artifact with Java 8 bytecode variants. -->
|
||||
<excludes>
|
||||
<excludes>**/*Recipe$*.class</excludes>
|
||||
<excludes>**/*Recipe.class</excludes>
|
||||
<excludes>**/*Recipes.class</excludes>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<!-- Creates a custom JAR with Java 8-compatible
|
||||
OpenRewrite recipe classes. -->
|
||||
<id>create-openrewrite-recipes-jar</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<classesDirectory>${project.build.directory}/openrewrite-recipes</classesDirectory>
|
||||
<classifier>recipes</classifier>
|
||||
<includes>
|
||||
<includes>**/*Recipe$*.class</includes>
|
||||
<includes>**/*Recipe.class</includes>
|
||||
<includes>**/*Recipes.class</includes>
|
||||
</includes>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>create-test-jar</id>
|
||||
<goals>
|
||||
@@ -1118,7 +1188,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>3.7.0</version>
|
||||
<version>3.8.0</version>
|
||||
<configuration>
|
||||
<additionalJOptions>
|
||||
<additionalJOption>--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</additionalJOption>
|
||||
@@ -1147,7 +1217,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-release-plugin</artifactId>
|
||||
<version>3.0.1</version>
|
||||
<version>3.1.1</version>
|
||||
<configuration>
|
||||
<autoVersionSubmodules>true</autoVersionSubmodules>
|
||||
<preparationProfiles>release</preparationProfiles>
|
||||
@@ -1188,7 +1258,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.2.5</version>
|
||||
<version>3.3.1</version>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*Test.java</include>
|
||||
@@ -1300,6 +1370,7 @@
|
||||
<!-- -->
|
||||
GPL-2.0-with-classpath-exception
|
||||
| CDDL/GPLv2+CE
|
||||
| CDDL + GPLv2 with classpath exception
|
||||
| GNU General Public License, version 2 (GPL2), with the classpath exception
|
||||
| GNU General Public License, version 2, with the Classpath Exception
|
||||
| GPL2 w/ CPE
|
||||
@@ -1347,7 +1418,7 @@
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>versions-maven-plugin</artifactId>
|
||||
<version>2.16.2</version>
|
||||
<version>2.17.1</version>
|
||||
<configuration>
|
||||
<updateBuildOutputTimestampPolicy>never</updateBuildOutputTimestampPolicy>
|
||||
</configuration>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.16.2-SNAPSHOT</version>
|
||||
<version>0.18.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>refaster-compiler</artifactId>
|
||||
|
||||
@@ -21,7 +21,6 @@ import com.sun.tools.javac.code.Symbol.ClassSymbol;
|
||||
import com.sun.tools.javac.code.Symbol.PackageSymbol;
|
||||
import com.sun.tools.javac.main.JavaCompiler;
|
||||
import com.sun.tools.javac.util.Context;
|
||||
import com.sun.tools.javac.util.Name;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectOutput;
|
||||
import java.io.ObjectOutputStream;
|
||||
@@ -137,10 +136,10 @@ final class RefasterRuleCompilerTaskListener implements TaskListener {
|
||||
return enclosingPackage == null ? "" : enclosingPackage.toString();
|
||||
}
|
||||
|
||||
private static CharSequence toSimpleFlatName(ClassSymbol symbol) {
|
||||
Name flatName = symbol.flatName();
|
||||
private static String toSimpleFlatName(ClassSymbol symbol) {
|
||||
String flatName = symbol.flatName().toString();
|
||||
int lastDot = flatName.lastIndexOf((byte) '.');
|
||||
return lastDot < 0 ? flatName : flatName.subSequence(lastDot + 1, flatName.length());
|
||||
return lastDot < 0 ? flatName : flatName.substring(lastDot + 1);
|
||||
}
|
||||
|
||||
private static void outputCodeTransformer(CodeTransformer codeTransformer, FileObject target)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.16.2-SNAPSHOT</version>
|
||||
<version>0.18.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>refaster-runner</artifactId>
|
||||
@@ -58,6 +58,11 @@
|
||||
<artifactId>guava</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>javax.annotation-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
<artifactId>javax.inject</artifactId>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.16.2-SNAPSHOT</version>
|
||||
<version>0.18.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>refaster-support</artifactId>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.16.2-SNAPSHOT</version>
|
||||
<version>0.18.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>refaster-test-support</artifactId>
|
||||
@@ -50,6 +50,11 @@
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>javax.annotation-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
<artifactId>javax.inject</artifactId>
|
||||
|
||||
@@ -319,7 +319,7 @@ public final class RefasterRuleCollection extends BugChecker implements Compilat
|
||||
return indexedMatches.subRangeMap(Range.closedOpen(startPosition, endPosition));
|
||||
}
|
||||
|
||||
private ImmutableListMultimap<Long, String> getUnexpectedMatchesByLineNumber(
|
||||
private static ImmutableListMultimap<Long, String> getUnexpectedMatchesByLineNumber(
|
||||
ImmutableRangeMap<Integer, String> matches, String ruleUnderTest, VisitorState state) {
|
||||
LineMap lineMap = state.getPath().getCompilationUnit().getLineMap();
|
||||
return matches.asMapOfRanges().entrySet().stream()
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
releases:
|
||||
- version: 0.16.1
|
||||
compatible:
|
||||
- "2.29.2"
|
||||
- "2.29.1"
|
||||
- "2.29.0"
|
||||
- "2.28.0"
|
||||
- "2.27.1"
|
||||
- "2.27.0"
|
||||
- "2.26.1"
|
||||
@@ -13,6 +17,10 @@ releases:
|
||||
- "2.23.0"
|
||||
- version: 0.16.0
|
||||
compatible:
|
||||
- "2.29.2"
|
||||
- "2.29.1"
|
||||
- "2.29.0"
|
||||
- "2.28.0"
|
||||
- "2.27.1"
|
||||
- "2.27.0"
|
||||
- "2.26.1"
|
||||
@@ -23,6 +31,10 @@ releases:
|
||||
- "2.23.0"
|
||||
- version: 0.15.0
|
||||
compatible:
|
||||
- "2.29.2"
|
||||
- "2.29.1"
|
||||
- "2.29.0"
|
||||
- "2.28.0"
|
||||
- "2.27.1"
|
||||
- "2.27.0"
|
||||
- "2.26.1"
|
||||
@@ -33,6 +45,10 @@ releases:
|
||||
- "2.23.0"
|
||||
- version: 0.14.0
|
||||
compatible:
|
||||
- "2.29.2"
|
||||
- "2.29.1"
|
||||
- "2.29.0"
|
||||
- "2.28.0"
|
||||
- "2.27.1"
|
||||
- "2.27.0"
|
||||
- "2.26.1"
|
||||
|
||||
Reference in New Issue
Block a user