Compare commits

..

1 Commits

Author SHA1 Message Date
Stephan Schroevers
51dc075f1c Introduce StringFormat Refaster rule
XXX: Requires dropping JDK 11 support, or a means of filtering by target
language level.
2024-12-28 19:07:06 +01:00
108 changed files with 1367 additions and 3864 deletions

View File

@@ -14,11 +14,11 @@ jobs:
distribution: [ temurin ]
experimental: [ false ]
include:
- os: macos-15
- os: macos-14
jdk: 17.0.13
distribution: temurin
experimental: false
- os: windows-2025
- os: windows-2022
jdk: 17.0.13
distribution: temurin
experimental: false
@@ -26,16 +26,14 @@ jobs:
continue-on-error: ${{ matrix.experimental }}
steps:
- name: Install Harden-Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
with:
disable-sudo: true
egress-policy: block
allowed-endpoints: >
api.adoptium.net:443
github.com:443
github-registry-files.githubusercontent.com:443
jitpack.io:443
maven.pkg.github.com:443
objects.githubusercontent.com:443
repo.maven.apache.org:443
# We run the build twice for each supported JDK: once against the
@@ -44,7 +42,7 @@ jobs:
# additionally enabling all checks defined in this project and any Error
# Prone checks available only from other artifact repositories.
- name: Check out code and set up JDK and Maven
uses: s4u/setup-maven-action@4f7fb9d9675e899ca81c6161dadbba0189a4ebb1 # v1.18.0
uses: s4u/setup-maven-action@9a27433d289dd99d73851f653607c39d3444e8ba # v1.17.0
with:
java-version: ${{ matrix.jdk }}
java-distribution: ${{ matrix.distribution }}
@@ -55,8 +53,6 @@ jobs:
run: mvn -T1C install javadoc:jar
- name: Build project with self-check against Error Prone fork
run: mvn -T1C clean verify -Perror-prone-fork -Pnon-maven-central -Pself-check -s settings.xml
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Remove installed project artifacts
run: mvn dependency:purge-local-repository -DmanualInclude='${project.groupId}' -DresolutionFuzziness=groupId

View File

@@ -22,7 +22,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Install Harden-Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
with:
disable-sudo: true
egress-policy: block
@@ -34,19 +34,19 @@ jobs:
repo.maven.apache.org:443
uploads.github.com:443
- name: Check out code and set up JDK and Maven
uses: s4u/setup-maven-action@4f7fb9d9675e899ca81c6161dadbba0189a4ebb1 # v1.18.0
uses: s4u/setup-maven-action@9a27433d289dd99d73851f653607c39d3444e8ba # v1.17.0
with:
java-version: 17.0.13
java-distribution: temurin
maven-version: 3.9.9
- name: Initialize CodeQL
uses: github/codeql-action/init@5f8171a638ada777af81d42b55959a643bb29017 # v3.28.12
uses: github/codeql-action/init@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5
with:
languages: ${{ matrix.language }}
- name: Perform minimal build
if: matrix.language == 'java'
run: mvn -T1C clean package -DskipTests -Dverification.skip
- name: Perform CodeQL analysis
uses: github/codeql-action/analyze@5f8171a638ada777af81d42b55959a643bb29017 # v3.28.12
uses: github/codeql-action/analyze@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5
with:
category: /language:${{ matrix.language }}

View File

@@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Install Harden-Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
with:
disable-sudo: true
egress-policy: block
@@ -21,7 +21,6 @@ jobs:
api.github.com:443
bestpractices.coreinfrastructure.org:443
blog.picnic.nl:443
docs.github.com:443
errorprone.info:443
github.com:443
img.shields.io:443
@@ -43,7 +42,7 @@ jobs:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- uses: ruby/setup-ruby@1a615958ad9d422dd932dc1d5823942ee002799f # v1.227.0
- uses: ruby/setup-ruby@a2bbe5b1b236842c1cb7dd11e8e3b51e0a616acc # v1.202.0
with:
working-directory: ./website
bundler-cache: true
@@ -75,7 +74,7 @@ jobs:
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Install Harden-Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
with:
disable-sudo: true
egress-policy: block

View File

@@ -21,7 +21,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Install Harden-Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
with:
disable-sudo: true
egress-policy: block
@@ -42,12 +42,12 @@ jobs:
with:
persist-credentials: false
- name: Run OpenSSF Scorecard analysis
uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
with:
results_file: results.sarif
results_format: sarif
publish_results: ${{ github.ref == 'refs/heads/master' }}
- name: Update GitHub's code scanning dashboard
uses: github/codeql-action/upload-sarif@5f8171a638ada777af81d42b55959a643bb29017 # v3.28.12
uses: github/codeql-action/upload-sarif@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5
with:
sarif_file: results.sarif

View File

@@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Install Harden-Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
with:
disable-sudo: true
egress-policy: block
@@ -22,7 +22,7 @@ jobs:
objects.githubusercontent.com:443
repo.maven.apache.org:443
- name: Check out code and set up JDK and Maven
uses: s4u/setup-maven-action@4f7fb9d9675e899ca81c6161dadbba0189a4ebb1 # v1.18.0
uses: s4u/setup-maven-action@9a27433d289dd99d73851f653607c39d3444e8ba # v1.17.0
with:
checkout-fetch-depth: 2
java-version: 17.0.13
@@ -38,7 +38,7 @@ jobs:
- name: Aggregate Pitest reports
run: mvn pitest-git:aggregate -DkilledEmoji=":tada:" -DmutantEmoji=":zombie:" -DtrailingText="Mutation testing report by [Pitest](https://pitest.org/). Review any surviving mutants by inspecting the line comments under [_Files changed_](${{ github.event.number }}/files)."
- name: Upload Pitest reports as artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
with:
name: pitest-reports
path: ./target/pit-reports-ci

View File

@@ -20,7 +20,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Install Harden-Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
with:
disable-sudo: true
egress-policy: block
@@ -31,7 +31,7 @@ jobs:
objects.githubusercontent.com:443
repo.maven.apache.org:443
- name: Check out code and set up JDK and Maven
uses: s4u/setup-maven-action@4f7fb9d9675e899ca81c6161dadbba0189a4ebb1 # v1.18.0
uses: s4u/setup-maven-action@9a27433d289dd99d73851f653607c39d3444e8ba # v1.17.0
with:
java-version: 17.0.13
java-distribution: temurin

View File

@@ -22,14 +22,14 @@ jobs:
integration-test: [ "checkstyle", "metrics", "prometheus-java-client" ]
steps:
- name: Install Harden-Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
with:
disable-sudo: true
egress-policy: block
# XXX: After updating the validation build flags in
# `integration-tests/prometheus-java-client.sh`, review whether the
# Docker domains specified here can be dropped.
allowed-endpoints: >
# XXX: After updating the validation build flags in
# `integration-tests/prometheus-java-client.sh`, review whether the
# Docker domains specified here can be dropped.
api.adoptium.net:443
auth.docker.io:443
checkstyle.org:443
@@ -43,7 +43,7 @@ jobs:
repo.maven.apache.org:443
repository.sonatype.org:443
- name: Check out code and set up JDK and Maven
uses: s4u/setup-maven-action@4f7fb9d9675e899ca81c6161dadbba0189a4ebb1 # v1.18.0
uses: s4u/setup-maven-action@9a27433d289dd99d73851f653607c39d3444e8ba # v1.17.0
with:
checkout-ref: "refs/pull/${{ github.event.issue.number }}/head"
java-version: 17.0.13
@@ -55,7 +55,7 @@ jobs:
run: xvfb-run "./integration-tests/${{ matrix.integration-test }}.sh" "${{ runner.temp }}/artifacts"
- name: Upload artifacts on failure
if: ${{ failure() }}
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
with:
name: "integration-test-${{ matrix.integration-test }}"
path: "${{ runner.temp }}/artifacts"

View File

@@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Install Harden-Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
with:
disable-sudo: true
egress-policy: block
@@ -35,7 +35,7 @@ jobs:
*.sonarcloud.io:443
sonarcloud.io:443
- name: Check out code and set up JDK and Maven
uses: s4u/setup-maven-action@4f7fb9d9675e899ca81c6161dadbba0189a4ebb1 # v1.18.0
uses: s4u/setup-maven-action@9a27433d289dd99d73851f653607c39d3444e8ba # v1.17.0
with:
checkout-fetch-depth: 0
java-version: 17.0.13

View File

@@ -205,13 +205,12 @@ Relevant Maven build parameters:
version of Error Prone. This is useful e.g. when testing a locally built
Error Prone SNAPSHOT.
- `-Perror-prone-fork` runs the build using Picnic's [Error Prone
fork][error-prone-fork-repo], hosted using [GitHub
Packages][error-prone-fork-packages]. This fork generally contains a few
changes on top of the latest Error Prone release. Using this profile
generally requires passing `-s settings.xml`, with [suitably
configured][github-packages-auth] `GITHUB_ACTOR` and `GITHUB_TOKEN`
environment variables.
fork][error-prone-fork-repo], hosted on [Jitpack][error-prone-fork-jitpack].
This fork generally contains a few changes on top of the latest Error Prone
release.
- `-Pself-check` runs the checks defined by this project against itself.
Pending a release of [google/error-prone#3301][error-prone-pull-3301], this
flag must currently be used in combination with `-Perror-prone-fork`.
Other highly relevant commands:
@@ -236,9 +235,8 @@ Other highly relevant commands:
against _all_ code in the current working directory. For more information
check the [PIT Maven plugin][pitest-maven].
Opening the project in IntelliJ IDEA may require running `mvn clean install`
first. Additionally, when running the project's tests using the IDE, you might
see the following error:
When running the project's tests in IntelliJ IDEA, you might see the following
error:
```
java: exporting a package from system module jdk.compiler is not allowed with --release
@@ -276,14 +274,14 @@ channel; please see our [security policy][security] for details.
[contributing]: https://github.com/PicnicSupermarket/error-prone-support/blob/master/CONTRIBUTING.md
[contributing-pull-request]: https://github.com/PicnicSupermarket/error-prone-support/blob/master/CONTRIBUTING.md#-opening-a-pull-request
[error-prone-bugchecker]: https://github.com/google/error-prone/blob/master/check_api/src/main/java/com/google/errorprone/bugpatterns/BugChecker.java
[error-prone-fork-packages]: https://github.com/PicnicSupermarket/error-prone/packages
[error-prone-fork-jitpack]: https://jitpack.io/#PicnicSupermarket/error-prone
[error-prone-fork-repo]: https://github.com/PicnicSupermarket/error-prone
[error-prone-gradle-installation-guide]: https://github.com/tbroyer/gradle-errorprone-plugin
[error-prone-installation-guide]: https://errorprone.info/docs/installation#maven
[error-prone-orig-repo]: https://github.com/google/error-prone
[error-prone-pull-3301]: https://github.com/google/error-prone/pull/3301
[github-actions-build-badge]: https://github.com/PicnicSupermarket/error-prone-support/actions/workflows/build.yml/badge.svg
[github-actions-build-master]: https://github.com/PicnicSupermarket/error-prone-support/actions/workflows/build.yml?query=branch:master&event=push
[github-packages-auth]: https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-apache-maven-registry#authenticating-to-github-packages
[google-java-format]: https://github.com/google/google-java-format
[idea-288052]: https://youtrack.jetbrains.com/issue/IDEA-288052
[license-badge]: https://img.shields.io/github/license/PicnicSupermarket/error-prone-support

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.22.1-SNAPSHOT</version>
<version>0.19.2-SNAPSHOT</version>
</parent>
<artifactId>documentation-support</artifactId>
@@ -15,6 +15,24 @@
<url>https://error-prone.picnic.tech</url>
<dependencies>
<dependency>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_annotation</artifactId>
</dependency>
<dependency>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_check_api</artifactId>
</dependency>
<dependency>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_test_helpers</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>error-prone-utils</artifactId>
@@ -54,24 +72,6 @@
<artifactId>auto-value-annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_annotation</artifactId>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_check_api</artifactId>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_test_helpers</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>

View File

@@ -2,7 +2,6 @@ package tech.picnic.errorprone.documentation;
import static com.google.errorprone.matchers.Matchers.instanceMethod;
import static com.google.errorprone.matchers.method.MethodMatchers.staticMethod;
import static java.util.Objects.requireNonNull;
import static java.util.function.Predicate.not;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@@ -168,10 +167,7 @@ public final class BugPatternTestExtractor implements Extractor<BugPatternTestCa
* is safe, because this code is guarded by an earlier call to `#getClassUnderTest(..)`,
* which ensures that `tree` is part of a longer method invocation chain.
*/
MethodInvocationTree inputTree =
(MethodInvocationTree)
requireNonNull(
ASTHelpers.getReceiver(tree), "Instance method invocation must have receiver");
MethodInvocationTree inputTree = (MethodInvocationTree) ASTHelpers.getReceiver(tree);
String path = ASTHelpers.constValue(inputTree.getArguments().get(0), String.class);
Optional<String> inputCode = getSourceCode(inputTree);

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.22.1-SNAPSHOT</version>
<version>0.19.2-SNAPSHOT</version>
</parent>
<artifactId>error-prone-contrib</artifactId>
@@ -15,6 +15,31 @@
<url>https://error-prone.picnic.tech</url>
<dependencies>
<dependency>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_annotation</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_check_api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_test_helpers</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>documentation-support</artifactId>
@@ -62,41 +87,6 @@
<artifactId>auto-value-annotations</artifactId>
<scope>provided</scope>
</dependency>
<!-- XXX: JSR-305 (meta-)annotation usage by some dependencies triggers
NullAway to attempt to load said annotations. As such some modules
require these annotations to be on the classpath. Periodically review
whether we can drop this dependeny declaration. See
https://github.com/uber/NullAway/issues/1171. -->
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_annotation</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_check_api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_test_helpers</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>

View File

@@ -11,7 +11,6 @@ import static com.google.errorprone.matchers.Matchers.not;
import static com.google.errorprone.matchers.Matchers.returnStatement;
import static com.google.errorprone.matchers.Matchers.staticMethod;
import static com.google.errorprone.matchers.Matchers.toType;
import static java.util.Objects.requireNonNull;
import static tech.picnic.errorprone.utils.Documentation.BUG_PATTERNS_BASE_URL;
import com.google.auto.service.AutoService;
@@ -80,10 +79,7 @@ public final class DirectReturn extends BugChecker implements BlockTreeMatcher {
return Description.NO_MATCH;
}
Symbol variableSymbol =
requireNonNull(
ASTHelpers.getSymbol(((ReturnTree) finalStatement).getExpression()),
"Missing symbol for returned variable");
Symbol variableSymbol = ASTHelpers.getSymbol(((ReturnTree) finalStatement).getExpression());
StatementTree precedingStatement = statements.get(statements.size() - 2);
return tryMatchAssignment(variableSymbol, precedingStatement)

View File

@@ -1,325 +0,0 @@
package tech.picnic.errorprone.bugpatterns;
import static com.google.errorprone.BugPattern.LinkType.CUSTOM;
import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
import static com.google.errorprone.BugPattern.StandardTags.PERFORMANCE;
import static com.google.errorprone.BugPattern.StandardTags.SIMPLIFICATION;
import static com.google.errorprone.matchers.Matchers.anyOf;
import static com.google.errorprone.matchers.Matchers.isSubtypeOf;
import static com.google.errorprone.matchers.Matchers.staticMethod;
import static com.google.errorprone.matchers.method.MethodMatchers.instanceMethod;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.joining;
import static tech.picnic.errorprone.utils.Documentation.BUG_PATTERNS_BASE_URL;
import com.google.auto.service.AutoService;
import com.google.auto.value.AutoValue;
import com.google.common.base.Preconditions;
import com.google.common.base.Verify;
import com.google.common.base.VerifyException;
import com.google.common.collect.ImmutableList;
import com.google.errorprone.BugPattern;
import com.google.errorprone.VisitorState;
import com.google.errorprone.annotations.Var;
import com.google.errorprone.bugpatterns.BugChecker;
import com.google.errorprone.bugpatterns.BugChecker.MethodInvocationTreeMatcher;
import com.google.errorprone.fixes.SuggestedFix;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.matchers.Matcher;
import com.google.errorprone.util.ASTHelpers;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.MethodInvocationTree;
import com.sun.source.tree.Tree;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.code.Symbol.VarSymbol;
import java.util.Collections;
import java.util.Formattable;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Stream;
import tech.picnic.errorprone.utils.SourceCode;
/**
* A {@link BugChecker} that flags {@link String#format} and {@link String#formatted} invocations
* that can be omitted by delegating to another format method.
*/
// XXX: The special-casing of Throwable applies only to SLF4J 1.6.0+; see
// https://www.slf4j.org/faq.html#paramException. That should be documented.
// XXX: Some of the `Matcher`s defined here are also declared by the `Slf4jLogStatement` and
// `RedundantStringConversion` checks. Look into deduplicating them.
// XXX: Should we also simplify e.g. `LOG.error(String.join("sep", arg1, arg2), throwable)`? Perhaps
// that's too obscure.
// XXX: This check currently only flags string format expressions that are a direct argument to
// another format-capable method invocation. Indirect cases, such as where the result is assigned to
// a variable, are currently not covered.
@AutoService(BugChecker.class)
@BugPattern(
summary = "String formatting can be deferred",
link = BUG_PATTERNS_BASE_URL + "EagerStringFormatting",
linkType = CUSTOM,
severity = WARNING,
tags = {PERFORMANCE, SIMPLIFICATION})
public final class EagerStringFormatting extends BugChecker implements MethodInvocationTreeMatcher {
private static final long serialVersionUID = 1L;
private static final Matcher<ExpressionTree> FORMATTABLE = isSubtypeOf(Formattable.class);
private static final Matcher<ExpressionTree> LOCALE = isSubtypeOf(Locale.class);
private static final Matcher<ExpressionTree> SLF4J_MARKER = isSubtypeOf("org.slf4j.Marker");
private static final Matcher<ExpressionTree> THROWABLE = isSubtypeOf(Throwable.class);
private static final Matcher<ExpressionTree> REQUIRE_NON_NULL_INVOCATION =
staticMethod().onClass(Objects.class.getCanonicalName()).named("requireNonNull");
private static final Matcher<ExpressionTree> GUAVA_GUARD_INVOCATION =
anyOf(
staticMethod()
.onClass(Preconditions.class.getCanonicalName())
.namedAnyOf("checkArgument", "checkNotNull", "checkState"),
staticMethod()
.onClass(Verify.class.getCanonicalName())
.namedAnyOf("verify", "verifyNotNull"));
private static final Matcher<ExpressionTree> SLF4J_LOGGER_INVOCATION =
instanceMethod()
.onDescendantOf("org.slf4j.Logger")
.namedAnyOf("trace", "debug", "info", "warn", "error");
private static final Matcher<ExpressionTree> STATIC_FORMAT_STRING =
staticMethod().onClass(String.class.getCanonicalName()).named("format");
private static final Matcher<ExpressionTree> INSTANCE_FORMAT_STRING =
instanceMethod().onDescendantOf(String.class.getCanonicalName()).named("formatted");
private static final String MESSAGE_NEVER_NULL_ARGUMENT =
"String formatting never yields `null` expression";
/** Instantiates a new {@link EagerStringFormatting} instance. */
public EagerStringFormatting() {}
@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
Tree parent = state.getPath().getParentPath().getLeaf();
if (!(parent instanceof MethodInvocationTree methodInvocation)) {
/*
* Fast path: this isn't a method invocation whose result is an argument to another method
* invocation.
*/
// XXX: This logic assumes that the string format operation isn't redundantly wrapped in
// parentheses. Similar assumptions likely exist throughout the code base. Investigate how to
// structurally cover such cases.
return Description.NO_MATCH;
}
return StringFormatExpression.tryCreate(tree, state)
.map(expr -> analyzeFormatStringContext(expr, methodInvocation, state))
.orElse(Description.NO_MATCH);
}
private Description analyzeFormatStringContext(
StringFormatExpression stringFormat, MethodInvocationTree context, VisitorState state) {
if (REQUIRE_NON_NULL_INVOCATION.matches(context, state)) {
return analyzeRequireNonNullStringFormatContext(stringFormat, context);
}
if (GUAVA_GUARD_INVOCATION.matches(context, state)) {
return analyzeGuavaGuardStringFormatContext(stringFormat, context, state);
}
if (SLF4J_LOGGER_INVOCATION.matches(context, state)) {
return analyzeSlf4jLoggerStringFormatContext(stringFormat, context, state);
}
/*
* The string formatting operation does not appear to happen in a context that admits of
* simplification or optimization.
*/
return Description.NO_MATCH;
}
private Description analyzeRequireNonNullStringFormatContext(
StringFormatExpression stringFormat, MethodInvocationTree context) {
List<? extends ExpressionTree> arguments = context.getArguments();
if (arguments.size() != 2 || arguments.get(0).equals(stringFormat.expression())) {
/* Vacuous validation that string formatting doesn't yield `null`. */
return buildDescription(context).setMessage(MESSAGE_NEVER_NULL_ARGUMENT).build();
}
if (stringFormat.arguments().stream()
.anyMatch(EagerStringFormatting::isNonFinalLocalVariable)) {
/*
* The format operation depends on a variable that isn't final or effectively final; moving
* it into a lambda expression would cause a compilation error.
*/
return buildDescription(context)
.setMessage(message() + " (but this requires introducing an effectively final variable)")
.build();
}
/* Suggest that the string formatting is deferred. */
return describeMatch(context, SuggestedFix.prefixWith(stringFormat.expression(), "() -> "));
}
private Description analyzeGuavaGuardStringFormatContext(
StringFormatExpression stringFormat, MethodInvocationTree context, VisitorState state) {
List<? extends ExpressionTree> arguments = context.getArguments();
if (arguments.get(0).equals(stringFormat.expression())) {
/*
* Vacuous `checkNotNull` or `verifyNotNull` validation that string formatting doesn't yield
* `null`.
*/
return buildDescription(context).setMessage(MESSAGE_NEVER_NULL_ARGUMENT).build();
}
if (stringFormat.simplifiableFormatString().isEmpty() || arguments.size() > 2) {
/*
* The format string cannot be simplified, or the format string produces a format string
* itself, or its result is the input to another format operation. These are complex cases
* that we'll only flag.
*/
return createSimplificationSuggestion(context, "Guava");
}
return describeMatch(context, stringFormat.suggestFlattening("%s", state));
}
private Description analyzeSlf4jLoggerStringFormatContext(
StringFormatExpression stringFormat, MethodInvocationTree context, VisitorState state) {
if (stringFormat.simplifiableFormatString().isEmpty()) {
/* We can't simplify this case; only flag it. */
return createSimplificationSuggestion(context, "SLF4J");
}
List<? extends ExpressionTree> arguments = context.getArguments();
int leftOffset = SLF4J_MARKER.matches(arguments.get(0), state) ? 1 : 0;
int rightOffset = THROWABLE.matches(arguments.get(arguments.size() - 1), state) ? 1 : 0;
if (arguments.size() != leftOffset + 1 + rightOffset) {
/*
* The format string produces a format string itself, or its result is the input to another
* format operation. This is a complex case that we'll only flag.
*/
return createSimplificationSuggestion(context, "SLF4J");
}
return describeMatch(context, stringFormat.suggestFlattening("{}", state));
}
private static boolean isNonFinalLocalVariable(Tree tree) {
Symbol symbol = ASTHelpers.getSymbol(tree);
return symbol instanceof VarSymbol
&& symbol.owner instanceof MethodSymbol
&& !ASTHelpers.isConsideredFinal(symbol);
}
private Description createSimplificationSuggestion(MethodInvocationTree context, String library) {
return buildDescription(context)
.setMessage(
"%s (assuming that %s's simplified formatting support suffices)"
.formatted(message(), library))
.build();
}
/** Description of a string format expression. */
@AutoValue
abstract static class StringFormatExpression {
/** The full string format expression. */
abstract MethodInvocationTree expression();
/** The format string expression. */
abstract Tree formatString();
/** The string format arguments to be plugged into its format string. */
abstract ImmutableList<ExpressionTree> arguments();
/**
* The constant format string, if it contains only {@code %s} placeholders, and the number of
* said placeholders matches the number of format arguments.
*/
abstract Optional<String> simplifiableFormatString();
private SuggestedFix suggestFlattening(String newPlaceholder, VisitorState state) {
return SuggestedFix.replace(
expression(),
Stream.concat(
Stream.of(deriveFormatStringExpression(newPlaceholder, state)),
arguments().stream().map(arg -> SourceCode.treeToString(arg, state)))
.collect(joining(", ")));
}
private String deriveFormatStringExpression(String newPlaceholder, VisitorState state) {
String formatString =
String.format(
simplifiableFormatString()
.orElseThrow(() -> new VerifyException("Format string cannot be simplified")),
Collections.nCopies(arguments().size(), newPlaceholder).toArray());
/*
* If the suggested replacement format string is the same as the original, then use the
* expression's existing source code representation. This way string constant references are
* not unnecessarily replaced.
*/
return formatString.equals(ASTHelpers.constValue(formatString(), String.class))
? SourceCode.treeToString(formatString(), state)
: SourceCode.toStringConstantExpression(formatString, state);
}
private static Optional<StringFormatExpression> tryCreate(
MethodInvocationTree tree, VisitorState state) {
if (INSTANCE_FORMAT_STRING.matches(tree, state)) {
return Optional.of(
create(
tree,
requireNonNull(ASTHelpers.getReceiver(tree), "Receiver unexpectedly absent"),
ImmutableList.copyOf(tree.getArguments()),
state));
}
if (STATIC_FORMAT_STRING.matches(tree, state)) {
List<? extends ExpressionTree> arguments = tree.getArguments();
int argOffset = LOCALE.matches(arguments.get(0), state) ? 1 : 0;
return Optional.of(
create(
tree,
arguments.get(argOffset),
ImmutableList.copyOf(arguments.subList(argOffset + 1, arguments.size())),
state));
}
return Optional.empty();
}
private static StringFormatExpression create(
MethodInvocationTree expression,
Tree formatString,
ImmutableList<ExpressionTree> arguments,
VisitorState state) {
return new AutoValue_EagerStringFormatting_StringFormatExpression(
expression,
formatString,
arguments,
Optional.ofNullable(ASTHelpers.constValue(formatString, String.class))
.filter(template -> isSimplifiable(template, arguments, state)));
}
private static boolean isSimplifiable(
String formatString, ImmutableList<ExpressionTree> arguments, VisitorState state) {
if (arguments.stream().anyMatch(arg -> FORMATTABLE.matches(arg, state))) {
/* `Formattable` arguments can have arbitrary format semantics. */
return false;
}
@Var int placeholderCount = 0;
for (int p = formatString.indexOf('%'); p != -1; p = formatString.indexOf('%', p + 2)) {
if (p == formatString.length() - 1) {
/* Malformed format string with trailing `%`. */
return false;
}
char modifier = formatString.charAt(p + 1);
if (modifier == 's') {
placeholderCount++;
} else if (modifier != '%') {
/* Only `%s` and `%%` (a literal `%`) are supported. */
return false;
}
}
return placeholderCount == arguments.size();
}
}
}

View File

@@ -18,7 +18,6 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMultiset;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableTable;
import com.google.common.collect.Iterables;
import com.google.errorprone.BugPattern;
import com.google.errorprone.VisitorState;
import com.google.errorprone.bugpatterns.BugChecker;
@@ -34,8 +33,6 @@ import com.sun.source.tree.MethodInvocationTree;
import com.sun.source.tree.MethodTree;
import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.code.Symbol.VarSymbol;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.Types;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -116,7 +113,7 @@ public final class ExplicitArgumentEnumeration extends BugChecker
.put(OBJECT_ENUMERABLE_ASSERT, "doesNotContainAnyElementsOf", "doesNotContain")
.put(OBJECT_ENUMERABLE_ASSERT, "hasSameElementsAs", "containsOnly")
.put(STEP_VERIFIER_STEP, "expectNextSequence", "expectNext")
.buildOrThrow();
.build();
/** Instantiates a new {@link ExplicitArgumentEnumeration} instance. */
public ExplicitArgumentEnumeration() {}
@@ -181,45 +178,30 @@ public final class ExplicitArgumentEnumeration extends BugChecker
state.getTypes())
.collect(toImmutableList());
return hasLikelySuitableVarargsOverload(method, overloads, state)
/*
* If all overloads have a single parameter, and at least one of them is a varargs method, then
* we assume that unwrapping the iterable argument will cause a suitable overload to be invoked.
* (Note that there may be multiple varargs overloads, either with different parameter types, or
* due to method overriding; this check does not attempt to determine which exact method or
* overload will be invoked as a result of the suggested simplification.)
*
* Note that this is a (highly!) imperfect heuristic, but it is sufficient to prevent e.g.
* unwrapping of arguments to `org.jooq.impl.DSL#row`, which can cause the expression's return
* type to change from `RowN` to (e.g.) `Row2`.
*/
// XXX: There are certainly cases where it _would_ be nice to unwrap the arguments to
// `org.jooq.impl.DSL#row(Collection<?>)`. Look into this.
// XXX: Ideally we do check that one of the overloads accepts the unwrapped arguments.
// XXX: Ideally we validate that eligible overloads have compatible return types.
boolean hasLikelySuitableVarargsOverload =
overloads.stream().allMatch(m -> m.params().size() == 1)
&& overloads.stream().anyMatch(MethodSymbol::isVarArgs);
return hasLikelySuitableVarargsOverload
? Optional.of(SourceCode.unwrapMethodInvocation(argument, state))
: Optional.empty();
}
/**
* Tells whether it is likely that, if the argument to the given method is unwrapped, a suitable
* varargs overload will be invoked instead.
*
* <p>If all overloads have a single parameter, and at least one of them is a suitably-typed
* varargs method, then we assume that unwrapping the iterable argument will cause a suitable
* overload to be invoked. (Note that there may be multiple varargs overloads due to method
* overriding; this check does not attempt to determine which exact method or overload will be
* invoked as a result of the suggested simplification.)
*
* <p>Note that this is a (highly!) imperfect heuristic, but it is sufficient to prevent e.g.
* unwrapping of arguments to `org.jooq.impl.DSL#row`, which can cause the expression's return
* type to change from `RowN` to (e.g.) `Row2`.
*/
// XXX: There are certainly cases where it _would_ be nice to unwrap the arguments to
// `org.jooq.impl.DSL#row(Collection<?>)`. Look into this.
// XXX: Ideally we validate that eligible overloads have compatible return types.
private static boolean hasLikelySuitableVarargsOverload(
MethodSymbol method, ImmutableList<MethodSymbol> overloads, VisitorState state) {
Types types = state.getTypes();
// XXX: This logic is fragile, as it assumes that the method parameter's type is of the form
// `X<T>`, where `T` is the type of the explicitly enumerated values passed to the expression to
// be unwrapped. This should generally hold, given the types returned by the
// `EXPLICIT_ITERABLE_CREATOR` expressions: `Iterable<T>`, `List<T>`, `Set<T>`, etc.
Type parameterType =
Iterables.getOnlyElement(
Iterables.getOnlyElement(method.getParameters()).type.getTypeArguments());
return overloads.stream().allMatch(m -> m.params().size() == 1)
&& overloads.stream()
.filter(MethodSymbol::isVarArgs)
.map(m -> types.elemtype(Iterables.getOnlyElement(m.getParameters()).type))
.anyMatch(varArgsType -> types.containsType(parameterType, varArgsType));
}
private static Optional<SuggestedFix> trySuggestCallingCustomAlternative(
MethodInvocationTree tree, MethodInvocationTree argument, VisitorState state) {
return ALTERNATIVE_METHODS.rowMap().entrySet().stream()

View File

@@ -17,7 +17,6 @@ import static com.google.errorprone.matchers.Matchers.isSameType;
import static com.google.errorprone.matchers.Matchers.methodHasParameters;
import static com.google.errorprone.matchers.Matchers.staticMethod;
import static com.google.errorprone.matchers.Matchers.toType;
import static java.util.Objects.requireNonNull;
import static java.util.function.Predicate.not;
import static java.util.stream.Collectors.joining;
import static tech.picnic.errorprone.utils.Documentation.BUG_PATTERNS_BASE_URL;
@@ -130,10 +129,7 @@ public final class JUnitValueSource extends BugChecker implements MethodTreeMatc
return Description.NO_MATCH;
}
Type parameterType =
requireNonNull(
ASTHelpers.getType(Iterables.getOnlyElement(tree.getParameters())),
"Missing type for method parameter");
Type parameterType = ASTHelpers.getType(Iterables.getOnlyElement(tree.getParameters()));
return findMethodSourceAnnotation(tree, state)
.flatMap(
@@ -177,9 +173,7 @@ public final class JUnitValueSource extends BugChecker implements MethodTreeMatc
private static Optional<MethodTree> findMatchingSibling(
MethodTree tree, Predicate<? super MethodTree> predicate, VisitorState state) {
return requireNonNull(state.findEnclosing(ClassTree.class), "No class enclosing method")
.getMembers()
.stream()
return state.findEnclosing(ClassTree.class).getMembers().stream()
.filter(MethodTree.class::isInstance)
.map(MethodTree.class::cast)
.filter(not(tree::equals))

View File

@@ -5,7 +5,6 @@ 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.instanceMethod;
import static java.util.Objects.requireNonNull;
import static tech.picnic.errorprone.utils.Documentation.BUG_PATTERNS_BASE_URL;
import com.google.auto.service.AutoService;
@@ -87,9 +86,7 @@ public final class NonEmptyMono extends BugChecker implements MethodInvocationTr
return Description.NO_MATCH;
}
ExpressionTree receiver =
requireNonNull(
ASTHelpers.getReceiver(tree), "Instance method invocation must have receiver");
ExpressionTree receiver = ASTHelpers.getReceiver(tree);
if (!NON_EMPTY_MONO.matches(receiver, state)) {
return Description.NO_MATCH;
}

View File

@@ -30,7 +30,6 @@ import com.sun.source.tree.Tree;
import com.sun.source.util.TreeScanner;
import com.sun.tools.javac.code.Symbol;
import java.time.Clock;
import java.time.InstantSource;
import java.time.ZoneOffset;
import java.util.Collections;
import java.util.Locale;
@@ -70,7 +69,6 @@ public final class NonStaticImport extends BugChecker implements CompilationUnit
ImmutableSet.of(
ASTHelpers.class.getCanonicalName(),
Clock.class.getCanonicalName(),
InstantSource.class.getCanonicalName(),
Strings.class.getCanonicalName(),
VisitorState.class.getCanonicalName(),
ZoneOffset.class.getCanonicalName(),
@@ -131,7 +129,6 @@ public final class NonStaticImport extends BugChecker implements CompilationUnit
"builder",
"copyOf",
"create",
"EPOCH",
"from",
"getDefaultInstance",
"INSTANCE",
@@ -185,7 +182,7 @@ public final class NonStaticImport extends BugChecker implements CompilationUnit
}
}
return imports.buildOrThrow();
return imports.build();
}
private static boolean shouldNotBeStaticallyImported(String type, String member) {

View File

@@ -28,6 +28,8 @@ import tech.picnic.errorprone.utils.SourceCode;
/** A {@link BugChecker} that flags SLF4J usages that are likely to be in error. */
// XXX: The special-casing of Throwable applies only to SLF4J 1.6.0+; see
// https://www.slf4j.org/faq.html#paramException. That should be documented.
// XXX: Also simplify `LOG.error(String.format("Something %s", arg), throwable)`.
// XXX: Also simplify `LOG.error(String.join("sep", arg1, arg2), throwable)`? Perhaps too obscure.
// XXX: Write a similar checker for Spring RestTemplates, String.format and friends, Guava
// preconditions, ...
@AutoService(BugChecker.class)

View File

@@ -54,7 +54,7 @@ public final class SpringMvcAnnotation extends BugChecker implements AnnotationT
.put("PATCH", "PatchMapping")
.put("POST", "PostMapping")
.put("PUT", "PutMapping")
.buildOrThrow();
.build();
/** Instantiates a new {@link SpringMvcAnnotation} instance. */
public SpringMvcAnnotation() {}

View File

@@ -16,12 +16,10 @@ import com.google.auto.service.AutoService;
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.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.time.Clock;
import java.time.Instant;
@@ -43,8 +41,7 @@ import java.time.ZonedDateTime;
linkType = CUSTOM,
severity = WARNING,
tags = FRAGILE_CODE)
public final class TimeZoneUsage extends BugChecker
implements MethodInvocationTreeMatcher, MemberReferenceTreeMatcher {
public final class TimeZoneUsage extends BugChecker implements MethodInvocationTreeMatcher {
private static final long serialVersionUID = 1L;
private static final Matcher<ExpressionTree> BANNED_TIME_METHOD =
anyOf(
@@ -62,10 +59,6 @@ public final class TimeZoneUsage extends BugChecker
"tickMillis",
"tickMinutes",
"tickSeconds"),
staticMethod()
.onClassAny(Instant.class.getCanonicalName())
.named("now")
.withNoParameters(),
staticMethod()
.onClassAny(
LocalDate.class.getCanonicalName(),
@@ -74,22 +67,17 @@ public final class TimeZoneUsage extends BugChecker
OffsetDateTime.class.getCanonicalName(),
OffsetTime.class.getCanonicalName(),
ZonedDateTime.class.getCanonicalName())
.named("now"));
.named("now"),
staticMethod()
.onClassAny(Instant.class.getCanonicalName())
.named("now")
.withNoParameters());
/** Instantiates a new {@link TimeZoneUsage} instance. */
public TimeZoneUsage() {}
@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
return getDescription(tree, state);
}
@Override
public Description matchMemberReference(MemberReferenceTree tree, VisitorState state) {
return getDescription(tree, state);
}
private Description getDescription(ExpressionTree tree, VisitorState state) {
return BANNED_TIME_METHOD.matches(tree, state)
? buildDescription(tree).build()
: Description.NO_MATCH;

View File

@@ -18,7 +18,6 @@ final class AssertJCharSequenceRules {
@BeforeTemplate
void before(CharSequence charSequence) {
Refaster.anyOf(
assertThat(charSequence.isEmpty()).isTrue(),
assertThat(charSequence.length()).isEqualTo(0L),
assertThat(charSequence.length()).isNotPositive());
}
@@ -34,7 +33,6 @@ final class AssertJCharSequenceRules {
@BeforeTemplate
AbstractAssert<?, ?> before(CharSequence charSequence) {
return Refaster.anyOf(
assertThat(charSequence.isEmpty()).isFalse(),
assertThat(charSequence.length()).isNotEqualTo(0),
assertThat(charSequence.length()).isPositive());
}

View File

@@ -5,9 +5,6 @@ import com.google.errorprone.refaster.Refaster;
import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import java.util.Collection;
import org.assertj.core.api.AbstractIntegerAssert;
import org.assertj.core.api.AbstractIterableAssert;
import org.assertj.core.api.AbstractIterableSizeAssert;
import org.assertj.core.api.EnumerableAssert;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
@@ -24,11 +21,6 @@ final class AssertJEnumerableRules {
enumAssert.hasSizeLessThan(1));
}
@BeforeTemplate
void before(AbstractIterableAssert<?, ?, E, ?> enumAssert) {
enumAssert.size().isNotPositive();
}
@AfterTemplate
void after(EnumerableAssert<?, E> enumAssert) {
enumAssert.isEmpty();
@@ -42,175 +34,30 @@ final class AssertJEnumerableRules {
enumAssert.hasSizeGreaterThan(0), enumAssert.hasSizeGreaterThanOrEqualTo(1));
}
@BeforeTemplate
AbstractIterableAssert<?, ?, E, ?> before(AbstractIterableAssert<?, ?, E, ?> enumAssert) {
return Refaster.anyOf(
enumAssert.size().isNotEqualTo(0).returnToIterable(),
enumAssert.size().isPositive().returnToIterable());
}
// XXX: If this template matches, then the expression's return type changes incompatibly.
// Consider moving this template to a separate block (statement) rule.
@BeforeTemplate
AbstractIntegerAssert<?> before2(AbstractIterableAssert<?, ?, E, ?> enumAssert) {
return Refaster.anyOf(enumAssert.size().isNotEqualTo(0), enumAssert.size().isPositive());
}
@AfterTemplate
EnumerableAssert<?, E> after(EnumerableAssert<?, E> enumAssert) {
return enumAssert.isNotEmpty();
}
}
static final class EnumerableAssertHasSize<E> {
static final class EnumerableAssertHasSameSizeAs<S, T> {
@BeforeTemplate
AbstractIterableAssert<?, ?, E, ?> before(
AbstractIterableAssert<?, ?, E, ?> enumAssert, int size) {
return enumAssert.size().isEqualTo(size).returnToIterable();
}
// XXX: If this template matches, then the expression's return type changes incompatibly.
// Consider moving this template to a separate block (statement) rule.
@BeforeTemplate
AbstractIterableSizeAssert<?, ?, E, ?> before2(
AbstractIterableAssert<?, ?, E, ?> enumAssert, int size) {
return enumAssert.size().isEqualTo(size);
}
@AfterTemplate
EnumerableAssert<?, E> after(EnumerableAssert<?, E> enumAssert, int size) {
return enumAssert.hasSize(size);
}
}
static final class EnumerableAssertHasSizeLessThan<E> {
@BeforeTemplate
AbstractIterableAssert<?, ?, E, ?> before(
AbstractIterableAssert<?, ?, E, ?> enumAssert, int size) {
return enumAssert.size().isLessThan(size).returnToIterable();
}
// XXX: If this template matches, then the expression's return type changes incompatibly.
// Consider moving this template to a separate block (statement) rule.
@BeforeTemplate
AbstractIterableSizeAssert<?, ?, E, ?> before2(
AbstractIterableAssert<?, ?, E, ?> enumAssert, int size) {
return enumAssert.size().isLessThan(size);
}
@AfterTemplate
EnumerableAssert<?, E> after(EnumerableAssert<?, E> enumAssert, int size) {
return enumAssert.hasSizeLessThan(size);
}
}
static final class EnumerableAssertHasSizeLessThanOrEqualTo<E> {
@BeforeTemplate
AbstractIterableAssert<?, ?, E, ?> before(
AbstractIterableAssert<?, ?, E, ?> enumAssert, int size) {
return enumAssert.size().isLessThanOrEqualTo(size).returnToIterable();
}
// XXX: If this template matches, then the expression's return type changes incompatibly.
// Consider moving this template to a separate block (statement) rule.
@BeforeTemplate
AbstractIterableSizeAssert<?, ?, E, ?> before2(
AbstractIterableAssert<?, ?, E, ?> enumAssert, int size) {
return enumAssert.size().isLessThanOrEqualTo(size);
}
@AfterTemplate
EnumerableAssert<?, E> after(EnumerableAssert<?, E> enumAssert, int size) {
return enumAssert.hasSizeLessThanOrEqualTo(size);
}
}
static final class EnumerableAssertHasSizeGreaterThan<E> {
@BeforeTemplate
AbstractIterableAssert<?, ?, E, ?> before(
AbstractIterableAssert<?, ?, E, ?> enumAssert, int size) {
return enumAssert.size().isGreaterThan(size).returnToIterable();
}
// XXX: If this template matches, then the expression's return type changes incompatibly.
// Consider moving this template to a separate block (statement) rule.
@BeforeTemplate
AbstractIterableSizeAssert<?, ?, E, ?> before2(
AbstractIterableAssert<?, ?, E, ?> enumAssert, int size) {
return enumAssert.size().isGreaterThan(size);
}
@AfterTemplate
EnumerableAssert<?, E> after(EnumerableAssert<?, E> enumAssert, int size) {
return enumAssert.hasSizeGreaterThan(size);
}
}
static final class EnumerableAssertHasSizeGreaterThanOrEqualTo<E> {
@BeforeTemplate
AbstractIterableAssert<?, ?, E, ?> before(
AbstractIterableAssert<?, ?, E, ?> enumAssert, int size) {
return enumAssert.size().isGreaterThanOrEqualTo(size).returnToIterable();
}
// XXX: If this template matches, then the expression's return type changes incompatibly.
// Consider moving this template to a separate block (statement) rule.
@BeforeTemplate
AbstractIterableSizeAssert<?, ?, E, ?> before2(
AbstractIterableAssert<?, ?, E, ?> enumAssert, int size) {
return enumAssert.size().isGreaterThanOrEqualTo(size);
}
@AfterTemplate
EnumerableAssert<?, E> after(EnumerableAssert<?, E> enumAssert, int size) {
return enumAssert.hasSizeGreaterThanOrEqualTo(size);
}
}
static final class EnumerableAssertHasSizeBetween<E> {
@BeforeTemplate
AbstractIterableAssert<?, ?, E, ?> before(
AbstractIterableAssert<?, ?, E, ?> enumAssert, int lower, int upper) {
return enumAssert.size().isBetween(lower, upper).returnToIterable();
}
// XXX: If this template matches, then the expression's return type changes incompatibly.
// Consider moving this template to a separate block (statement) rule.
@BeforeTemplate
AbstractIterableSizeAssert<?, ?, E, ?> before2(
AbstractIterableAssert<?, ?, E, ?> enumAssert, int lower, int upper) {
return enumAssert.size().isBetween(lower, upper);
}
@AfterTemplate
EnumerableAssert<?, E> after(EnumerableAssert<?, E> enumAssert, int lower, int upper) {
return enumAssert.hasSizeBetween(lower, upper);
}
}
static final class EnumerableAssertHasSameSizeAs<S, E> {
@BeforeTemplate
EnumerableAssert<?, S> before(EnumerableAssert<?, S> enumAssert, Iterable<E> iterable) {
EnumerableAssert<?, S> before(EnumerableAssert<?, S> enumAssert, Iterable<T> iterable) {
return enumAssert.hasSize(Iterables.size(iterable));
}
@BeforeTemplate
EnumerableAssert<?, S> before(EnumerableAssert<?, S> enumAssert, Collection<E> iterable) {
EnumerableAssert<?, S> before(EnumerableAssert<?, S> enumAssert, Collection<T> iterable) {
return enumAssert.hasSize(iterable.size());
}
@BeforeTemplate
EnumerableAssert<?, S> before(EnumerableAssert<?, S> enumAssert, E[] iterable) {
EnumerableAssert<?, S> before(EnumerableAssert<?, S> enumAssert, T[] iterable) {
return enumAssert.hasSize(iterable.length);
}
@BeforeTemplate
EnumerableAssert<?, S> before(EnumerableAssert<?, S> enumAssert, CharSequence iterable) {
return enumAssert.hasSize(iterable.length());
}
@AfterTemplate
EnumerableAssert<?, S> after(EnumerableAssert<?, S> enumAssert, Iterable<E> iterable) {
EnumerableAssert<?, S> after(EnumerableAssert<?, S> enumAssert, Iterable<T> iterable) {
return enumAssert.hasSameSizeAs(iterable);
}
}

View File

@@ -1,90 +0,0 @@
package tech.picnic.errorprone.refasterrules;
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
import static org.assertj.core.api.Assertions.assertThat;
import com.google.common.collect.Iterables;
import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import com.google.errorprone.refaster.annotation.UseImportPolicy;
import java.util.Collection;
import org.assertj.core.api.AbstractAssert;
import org.assertj.core.api.AbstractIntegerAssert;
import org.assertj.core.api.IterableAssert;
import org.assertj.core.api.ObjectAssert;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
@OnlineDocumentation
final class AssertJIterableRules {
private AssertJIterableRules() {}
static final class AssertThatIterableIsEmpty<E> {
@BeforeTemplate
void before(Iterable<E> iterable) {
assertThat(iterable.iterator()).isExhausted();
}
@BeforeTemplate
void before(Collection<E> iterable) {
assertThat(iterable.isEmpty()).isTrue();
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(Collection<E> iterable) {
assertThat(iterable).isEmpty();
}
}
static final class AssertThatIterableIsNotEmpty<E> {
@BeforeTemplate
AbstractAssert<?, ?> before(Iterable<E> iterable) {
return assertThat(iterable.iterator()).hasNext();
}
@BeforeTemplate
AbstractAssert<?, ?> before(Collection<E> iterable) {
return assertThat(iterable.isEmpty()).isFalse();
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
IterableAssert<E> after(Iterable<E> iterable) {
return assertThat(iterable).isNotEmpty();
}
}
static final class AssertThatIterableSize<E> {
@BeforeTemplate
AbstractIntegerAssert<?> before(Iterable<E> iterable) {
return assertThat(Iterables.size(iterable));
}
@BeforeTemplate
AbstractIntegerAssert<?> before(Collection<E> iterable) {
return assertThat(iterable.size());
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
AbstractIntegerAssert<?> after(Iterable<E> iterable) {
return assertThat(iterable).size();
}
}
// XXX: In practice this rule isn't very useful, as it only matches invocations of
// `assertThat(E)`. In most cases a more specific overload of `assertThat` is invoked, in which
// case this rule won't match. Look into a more robust approach.
static final class AssertThatIterableHasOneElementEqualTo<S, E extends S> {
@BeforeTemplate
ObjectAssert<S> before(Iterable<S> iterable, E element) {
return assertThat(Iterables.getOnlyElement(iterable)).isEqualTo(element);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
IterableAssert<S> after(Iterable<S> iterable, E element) {
return assertThat(iterable).containsExactly(element);
}
}
}

View File

@@ -1,43 +0,0 @@
package tech.picnic.errorprone.refasterrules;
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
import static org.assertj.core.api.Assertions.assertThat;
import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import com.google.errorprone.refaster.annotation.UseImportPolicy;
import java.util.Iterator;
import org.assertj.core.api.AbstractBooleanAssert;
import org.assertj.core.api.IteratorAssert;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
@OnlineDocumentation
final class AssertJIteratorRules {
private AssertJIteratorRules() {}
static final class AssertThatHasNext<T> {
@BeforeTemplate
AbstractBooleanAssert<?> before(Iterator<T> iterator) {
return assertThat(iterator.hasNext()).isTrue();
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
IteratorAssert<T> after(Iterator<T> iterator) {
return assertThat(iterator).hasNext();
}
}
static final class AssertThatIsExhausted<T> {
@BeforeTemplate
AbstractBooleanAssert<?> before(Iterator<T> iterator) {
return assertThat(iterator.hasNext()).isFalse();
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
IteratorAssert<T> after(Iterator<T> iterator) {
return assertThat(iterator).isExhausted();
}
}
}

View File

@@ -11,6 +11,7 @@ import com.google.errorprone.refaster.annotation.Matches;
import com.google.errorprone.refaster.annotation.UseImportPolicy;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import org.assertj.core.api.AbstractAssert;
import org.assertj.core.api.AbstractBooleanAssert;
import org.assertj.core.api.AbstractCollectionAssert;
@@ -181,13 +182,13 @@ final class AssertJMapRules {
static final class AssertThatMapContainsOnlyKeys<K, V> {
@BeforeTemplate
AbstractCollectionAssert<?, Collection<? extends K>, K, ?> before(
Map<K, V> map, Iterable<? extends K> keys) {
Map<K, V> map, Set<? extends K> keys) {
return assertThat(map.keySet()).hasSameElementsAs(keys);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
MapAssert<K, V> after(Map<K, V> map, Iterable<? extends K> keys) {
MapAssert<K, V> after(Map<K, V> map, Set<? extends K> keys) {
return assertThat(map).containsOnlyKeys(keys);
}
}

View File

@@ -3,6 +3,7 @@ package tech.picnic.errorprone.refasterrules;
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
import static org.assertj.core.api.Assertions.assertThat;
import com.google.common.collect.Iterables;
import com.google.common.collect.Multiset;
import com.google.errorprone.refaster.Refaster;
import com.google.errorprone.refaster.annotation.AfterTemplate;
@@ -11,6 +12,7 @@ import com.google.errorprone.refaster.annotation.Matches;
import com.google.errorprone.refaster.annotation.NotMatches;
import com.google.errorprone.refaster.annotation.Repeated;
import com.google.errorprone.refaster.annotation.UseImportPolicy;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.OptionalDouble;
@@ -20,7 +22,9 @@ import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collector;
import java.util.stream.Stream;
import org.assertj.core.api.AbstractAssert;
import org.assertj.core.api.AbstractCollectionAssert;
import org.assertj.core.api.AbstractComparableAssert;
import org.assertj.core.api.AbstractDoubleAssert;
import org.assertj.core.api.AbstractIntegerAssert;
import org.assertj.core.api.AbstractLongAssert;
@@ -250,19 +254,121 @@ final class AssertJRules {
}
}
//
// Iterable
//
static final class AssertThatIterableIsEmpty<E> {
@BeforeTemplate
void before(Iterable<E> iterable) {
Refaster.anyOf(
assertThat(iterable).hasSize(0),
assertThat(iterable.iterator().hasNext()).isFalse(),
assertThat(iterable.iterator()).isExhausted(),
assertThat(Iterables.size(iterable)).isEqualTo(0L),
assertThat(Iterables.size(iterable)).isNotPositive());
}
@BeforeTemplate
void before(Collection<E> iterable) {
Refaster.anyOf(
assertThat(iterable.isEmpty()).isTrue(),
assertThat(iterable.size()).isEqualTo(0L),
assertThat(iterable.size()).isNotPositive());
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(Collection<E> iterable) {
assertThat(iterable).isEmpty();
}
}
static final class AssertThatIterableIsNotEmpty<E> {
@BeforeTemplate
AbstractAssert<?, ?> before(Iterable<E> iterable) {
return Refaster.anyOf(
assertThat(iterable.iterator().hasNext()).isTrue(),
assertThat(Iterables.size(iterable)).isNotEqualTo(0),
assertThat(Iterables.size(iterable)).isPositive());
}
@BeforeTemplate
AbstractAssert<?, ?> before(Collection<E> iterable) {
return Refaster.anyOf(
assertThat(iterable.isEmpty()).isFalse(),
assertThat(iterable.size()).isNotEqualTo(0),
assertThat(iterable.size()).isPositive());
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
IterableAssert<E> after(Iterable<E> iterable) {
return assertThat(iterable).isNotEmpty();
}
}
static final class AssertThatIterableHasSize<E> {
@BeforeTemplate
AbstractIntegerAssert<?> before(Iterable<E> iterable, int length) {
return assertThat(Iterables.size(iterable)).isEqualTo(length);
}
@BeforeTemplate
AbstractIntegerAssert<?> before(Collection<E> iterable, int length) {
return assertThat(iterable.size()).isEqualTo(length);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
IterableAssert<E> after(Iterable<E> iterable, int length) {
return assertThat(iterable).hasSize(length);
}
}
static final class AssertThatIterableHasOneElementEqualTo<S, T extends S> {
@BeforeTemplate
ObjectAssert<S> before(Iterable<S> iterable, T element) {
return assertThat(Iterables.getOnlyElement(iterable)).isEqualTo(element);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
IterableAssert<S> after(Iterable<S> iterable, T element) {
return assertThat(iterable).containsExactly(element);
}
}
// XXX: This overload is here because `assertThat` has an overload for `Comparable` types.
// Unfortunately this still doesn't convince Refaster to match this rule in the context of
// Comparable types. Figure out why! Note that this also affects the `AssertThatOptional` rule.
static final class AssertThatIterableHasOneComparableElementEqualTo<
S extends Comparable<? super S>, T extends S> {
@BeforeTemplate
AbstractComparableAssert<?, S> before(Iterable<S> iterable, T element) {
return assertThat(Iterables.getOnlyElement(iterable)).isEqualTo(element);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
IterableAssert<S> after(Iterable<S> iterable, T element) {
return assertThat(iterable).containsExactly(element);
}
}
//
// List
//
static final class AssertThatListsAreEqual<S, T extends S> {
@BeforeTemplate
ListAssert<S> before(List<S> list1, Iterable<T> list2) {
ListAssert<S> before(List<S> list1, List<T> list2) {
return assertThat(list1).isEqualTo(list2);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
ListAssert<S> after(List<S> list1, Iterable<T> list2) {
ListAssert<S> after(List<S> list1, List<T> list2) {
return assertThat(list1).containsExactlyElementsOf(list2);
}
}
@@ -273,7 +379,7 @@ final class AssertJRules {
static final class AssertThatSetsAreEqual<S, T extends S> {
@BeforeTemplate
AbstractCollectionAssert<?, ?, S, ?> before(Set<S> set1, Iterable<T> set2) {
AbstractCollectionAssert<?, ?, S, ?> before(Set<S> set1, Set<T> set2) {
return Refaster.anyOf(
assertThat(set1).isEqualTo(set2),
assertThat(set1).containsExactlyInAnyOrderElementsOf(set2));
@@ -281,7 +387,7 @@ final class AssertJRules {
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
AbstractCollectionAssert<?, ?, S, ?> after(Set<S> set1, Iterable<T> set2) {
AbstractCollectionAssert<?, ?, S, ?> after(Set<S> set1, Set<T> set2) {
return assertThat(set1).hasSameElementsAs(set2);
}
}
@@ -292,13 +398,13 @@ final class AssertJRules {
static final class AssertThatMultisetsAreEqual<S, T extends S> {
@BeforeTemplate
AbstractCollectionAssert<?, ?, S, ?> before(Multiset<S> multiset1, Iterable<T> multiset2) {
AbstractCollectionAssert<?, ?, S, ?> before(Multiset<S> multiset1, Multiset<T> multiset2) {
return assertThat(multiset1).isEqualTo(multiset2);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
AbstractCollectionAssert<?, ?, S, ?> after(Multiset<S> multiset1, Iterable<T> multiset2) {
AbstractCollectionAssert<?, ?, S, ?> after(Multiset<S> multiset1, Multiset<T> multiset2) {
return assertThat(multiset1).containsExactlyInAnyOrderElementsOf(multiset2);
}
}

View File

@@ -32,6 +32,19 @@ final class AssertJStringRules {
}
}
static final class AssertThatStringIsEmpty {
@BeforeTemplate
void before(String string) {
assertThat(string.isEmpty()).isTrue();
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(String string) {
assertThat(string).isEmpty();
}
}
static final class AbstractStringAssertStringIsNotEmpty {
@BeforeTemplate
AbstractStringAssert<?> before(AbstractStringAssert<?> stringAssert) {
@@ -44,28 +57,41 @@ final class AssertJStringRules {
}
}
static final class AssertThatStringIsNotEmpty {
@BeforeTemplate
AbstractAssert<?, ?> before(String string) {
return assertThat(string.isEmpty()).isFalse();
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
AbstractAssert<?, ?> after(String string) {
return assertThat(string).isNotEmpty();
}
}
static final class AssertThatStringContains {
@BeforeTemplate
AbstractBooleanAssert<?> before(String string, CharSequence substring) {
AbstractBooleanAssert<?> before(String string, String substring) {
return assertThat(string.contains(substring)).isTrue();
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
AbstractStringAssert<?> after(String string, CharSequence substring) {
AbstractStringAssert<?> after(String string, String substring) {
return assertThat(string).contains(substring);
}
}
static final class AssertThatStringDoesNotContain {
@BeforeTemplate
AbstractBooleanAssert<?> before(String string, CharSequence substring) {
AbstractBooleanAssert<?> before(String string, String substring) {
return assertThat(string.contains(substring)).isFalse();
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
AbstractStringAssert<?> after(String string, CharSequence substring) {
AbstractStringAssert<?> after(String string, String substring) {
return assertThat(string).doesNotContain(substring);
}
}

View File

@@ -121,18 +121,18 @@ final class AssortedRules {
*/
static final class DisjointSets<T> {
@BeforeTemplate
boolean before(Set<T> collection1, Set<T> collection2) {
return Sets.intersection(collection1, collection2).isEmpty();
boolean before(Set<T> set1, Set<T> set2) {
return Sets.intersection(set1, set2).isEmpty();
}
@BeforeTemplate
boolean before2(Collection<T> collection1, Collection<T> collection2) {
return collection1.stream().noneMatch(collection2::contains);
boolean before2(Set<T> set1, Set<T> set2) {
return set1.stream().noneMatch(set2::contains);
}
@AfterTemplate
boolean after(Collection<T> collection1, Collection<T> collection2) {
return disjoint(collection1, collection2);
boolean after(Set<T> set1, Set<T> set2) {
return disjoint(set1, set2);
}
}

View File

@@ -158,14 +158,14 @@ final class CollectionRules {
}
}
static final class CollectionRemoveAllFromCollectionBlock<T, S extends T> {
static final class SetRemoveAllCollection<T, S extends T> {
@BeforeTemplate
void before(Collection<T> removeFrom, Collection<S> elementsToRemove) {
void before(Set<T> removeFrom, Collection<S> elementsToRemove) {
elementsToRemove.forEach(removeFrom::remove);
}
@BeforeTemplate
void before2(Collection<T> removeFrom, Collection<S> elementsToRemove) {
void before2(Set<T> removeFrom, Collection<S> elementsToRemove) {
for (T element : elementsToRemove) {
removeFrom.remove(element);
}
@@ -175,14 +175,14 @@ final class CollectionRules {
// that this is supported out of the box. After doing so, also drop the `S extends T` type
// constraint; ideally this check applies to any `S`.
@BeforeTemplate
void before3(Collection<T> removeFrom, Collection<S> elementsToRemove) {
void before3(Set<T> removeFrom, Collection<S> elementsToRemove) {
for (S element : elementsToRemove) {
removeFrom.remove(element);
}
}
@AfterTemplate
void after(Collection<T> removeFrom, Collection<S> elementsToRemove) {
void after(Set<T> removeFrom, Collection<S> elementsToRemove) {
removeFrom.removeAll(elementsToRemove);
}
}

View File

@@ -4,7 +4,6 @@ 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.AlsoNegation;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import com.google.errorprone.refaster.annotation.Repeated;
import java.io.File;
@@ -12,7 +11,6 @@ import java.io.IOException;
import java.net.URI;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.FileAttribute;
@@ -143,35 +141,4 @@ final class FileRules {
return Files.createTempFile(directory.toPath(), prefix, suffix).toFile();
}
}
/**
* Invoke {@link File#mkdirs()} before {@link Files#exists(Path, LinkOption...)} to avoid
* concurrency issues.
*/
static final class PathToFileMkDirsFilesExists {
@BeforeTemplate
boolean before(Path path) {
return Files.exists(path) || path.toFile().mkdirs();
}
@AfterTemplate
@AlsoNegation
boolean after(Path path) {
return path.toFile().mkdirs() || Files.exists(path);
}
}
/** Invoke {@link File#mkdirs()} before {@link File#exists()} to avoid concurrency issues. */
static final class FileMkDirsFileExists {
@BeforeTemplate
boolean before(File file) {
return file.exists() || file.mkdirs();
}
@AfterTemplate
@AlsoNegation
boolean after(File file) {
return file.mkdirs() || file.exists();
}
}
}

View File

@@ -15,7 +15,6 @@ import com.google.errorprone.refaster.annotation.BeforeTemplate;
import com.google.errorprone.refaster.annotation.Matches;
import com.google.errorprone.refaster.annotation.MayOptionallyUse;
import com.google.errorprone.refaster.annotation.Placeholder;
import com.google.errorprone.refaster.annotation.Repeated;
import com.google.errorprone.refaster.annotation.UseImportPolicy;
import java.util.Collection;
import java.util.Iterator;
@@ -45,28 +44,12 @@ final class ImmutableMapRules {
}
}
/**
* Prefer {@link ImmutableMap.Builder#buildOrThrow()} over the less explicit {@link
* ImmutableMap.Builder#build()}.
*/
static final class ImmutableMapBuilderBuildOrThrow<K, V> {
@BeforeTemplate
ImmutableMap<K, V> before(ImmutableMap.Builder<K, V> builder) {
return builder.build();
}
@AfterTemplate
ImmutableMap<K, V> after(ImmutableMap.Builder<K, V> builder) {
return builder.buildOrThrow();
}
}
/** Prefer {@link ImmutableMap#of(Object, Object)} over more contrived alternatives. */
static final class EntryToImmutableMap<K, V> {
@BeforeTemplate
ImmutableMap<K, V> before(Map.Entry<? extends K, ? extends V> entry) {
return Refaster.anyOf(
ImmutableMap.<K, V>builder().put(entry).buildOrThrow(),
ImmutableMap.<K, V>builder().put(entry).build(),
Stream.of(entry).collect(toImmutableMap(Map.Entry::getKey, Map.Entry::getValue)));
}
@@ -121,17 +104,16 @@ final class ImmutableMapRules {
/** Prefer {@link ImmutableMap#copyOf(Iterable)} over more contrived alternatives. */
static final class EntryIterableToImmutableMap<K, V> {
@BeforeTemplate
Map<K, V> before(Map<? extends K, ? extends V> iterable) {
ImmutableMap<K, V> before(Map<? extends K, ? extends V> iterable) {
return Refaster.anyOf(
ImmutableMap.copyOf(iterable.entrySet()),
ImmutableMap.<K, V>builder().putAll(iterable).buildOrThrow(),
Map.copyOf(iterable));
ImmutableMap.<K, V>builder().putAll(iterable).build());
}
@BeforeTemplate
ImmutableMap<K, V> before(Iterable<? extends Map.Entry<? extends K, ? extends V>> iterable) {
return Refaster.anyOf(
ImmutableMap.<K, V>builder().putAll(iterable).buildOrThrow(),
ImmutableMap.<K, V>builder().putAll(iterable).build(),
Streams.stream(iterable).collect(toImmutableMap(Map.Entry::getKey, Map.Entry::getValue)));
}
@@ -157,6 +139,8 @@ final class ImmutableMapRules {
@Placeholder(allowsIdentity = true)
abstract V valueFunction(@MayOptionallyUse E element);
// XXX: We could add variants in which the entry is created some other way, but we have another
// rule that covers canonicalization to `Map.entry`.
@BeforeTemplate
ImmutableMap<K, V> before(Stream<E> stream) {
return stream
@@ -240,11 +224,7 @@ final class ImmutableMapRules {
static final class ImmutableMapOf<K, V> {
@BeforeTemplate
Map<K, V> before() {
return Refaster.anyOf(
ImmutableMap.<K, V>builder().buildOrThrow(),
ImmutableMap.ofEntries(),
emptyMap(),
Map.of());
return Refaster.anyOf(ImmutableMap.<K, V>builder().build(), emptyMap(), Map.of());
}
@AfterTemplate
@@ -263,10 +243,7 @@ final class ImmutableMapRules {
@BeforeTemplate
Map<K, V> before(K k1, V v1) {
return Refaster.anyOf(
ImmutableMap.<K, V>builder().put(k1, v1).buildOrThrow(),
ImmutableMap.ofEntries(Map.entry(k1, v1)),
singletonMap(k1, v1),
Map.of(k1, v1));
ImmutableMap.<K, V>builder().put(k1, v1).build(), singletonMap(k1, v1), Map.of(k1, v1));
}
@AfterTemplate
@@ -284,8 +261,7 @@ final class ImmutableMapRules {
static final class ImmutableMapOf2<K, V> {
@BeforeTemplate
Map<K, V> before(K k1, V v1, K k2, V v2) {
return Refaster.anyOf(
ImmutableMap.ofEntries(Map.entry(k1, v1), Map.entry(k2, v2)), Map.of(k1, v1, k2, v2));
return Map.of(k1, v1, k2, v2);
}
@AfterTemplate
@@ -303,9 +279,7 @@ final class ImmutableMapRules {
static final class ImmutableMapOf3<K, V> {
@BeforeTemplate
Map<K, V> before(K k1, V v1, K k2, V v2, K k3, V v3) {
return Refaster.anyOf(
ImmutableMap.ofEntries(Map.entry(k1, v1), Map.entry(k2, v2), Map.entry(k3, v3)),
Map.of(k1, v1, k2, v2, k3, v3));
return Map.of(k1, v1, k2, v2, k3, v3);
}
@AfterTemplate
@@ -325,10 +299,7 @@ final class ImmutableMapRules {
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 Refaster.anyOf(
ImmutableMap.ofEntries(
Map.entry(k1, v1), Map.entry(k2, v2), Map.entry(k3, v3), Map.entry(k4, v4)),
Map.of(k1, v1, k2, v2, k3, v3, k4, v4));
return Map.of(k1, v1, k2, v2, k3, v3, k4, v4);
}
@AfterTemplate
@@ -348,14 +319,7 @@ final class ImmutableMapRules {
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 Refaster.anyOf(
ImmutableMap.ofEntries(
Map.entry(k1, v1),
Map.entry(k2, v2),
Map.entry(k3, v3),
Map.entry(k4, v4),
Map.entry(k5, v5)),
Map.of(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5));
return Map.of(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5);
}
@AfterTemplate
@@ -373,14 +337,14 @@ final class ImmutableMapRules {
abstract boolean keyFilter(@MayOptionallyUse K key);
@BeforeTemplate
ImmutableMap<K, V> before(Map<K, V> map) {
ImmutableMap<K, V> before(ImmutableMap<K, V> map) {
return map.entrySet().stream()
.filter(e -> keyFilter(e.getKey()))
.collect(toImmutableMap(Map.Entry::getKey, Map.Entry::getValue));
}
@AfterTemplate
ImmutableMap<K, V> after(Map<K, V> map) {
ImmutableMap<K, V> after(ImmutableMap<K, V> map) {
return ImmutableMap.copyOf(Maps.filterKeys(map, k -> keyFilter(k)));
}
}
@@ -394,34 +358,18 @@ final class ImmutableMapRules {
abstract boolean valueFilter(@MayOptionallyUse V value);
@BeforeTemplate
ImmutableMap<K, V> before(Map<K, V> map) {
ImmutableMap<K, V> before(ImmutableMap<K, V> map) {
return map.entrySet().stream()
.filter(e -> valueFilter(e.getValue()))
.collect(toImmutableMap(Map.Entry::getKey, Map.Entry::getValue));
}
@AfterTemplate
ImmutableMap<K, V> after(Map<K, V> map) {
ImmutableMap<K, V> after(ImmutableMap<K, V> map) {
return ImmutableMap.copyOf(Maps.filterValues(map, v -> valueFilter(v)));
}
}
/**
* Prefer {@link ImmutableMap#ofEntries(Map.Entry[])} over alternatives that don't communicate the
* immutability of the resulting map at the type level.
*/
static final class ImmutableMapOfEntries<K, V> {
@BeforeTemplate
Map<K, V> before(@Repeated Map.Entry<? extends K, ? extends V> entries) {
return Map.ofEntries(entries);
}
@AfterTemplate
ImmutableMap<K, V> after(@Repeated Map.Entry<? extends K, ? extends V> entries) {
return ImmutableMap.ofEntries(entries);
}
}
// XXX: Add a rule for this:
// Maps.transformValues(streamOfEntries.collect(groupBy(fun)), ImmutableMap::copyOf)
// ->

View File

@@ -71,7 +71,7 @@ final class ImmutableSortedMapRules {
static final class EmptyImmutableSortedMap<K extends Comparable<? super K>, V> {
@BeforeTemplate
ImmutableSortedMap<K, V> before() {
return ImmutableSortedMap.<K, V>naturalOrder().buildOrThrow();
return ImmutableSortedMap.<K, V>naturalOrder().build();
}
@AfterTemplate
@@ -89,7 +89,7 @@ final class ImmutableSortedMapRules {
static final class PairToImmutableSortedMap<K extends Comparable<? super K>, V> {
@BeforeTemplate
ImmutableSortedMap<K, V> before(K key, V value) {
return ImmutableSortedMap.<K, V>naturalOrder().put(key, value).buildOrThrow();
return ImmutableSortedMap.<K, V>naturalOrder().put(key, value).build();
}
@AfterTemplate
@@ -105,7 +105,7 @@ final class ImmutableSortedMapRules {
@BeforeTemplate
ImmutableSortedMap<K, V> before(Map.Entry<? extends K, ? extends V> entry) {
return Refaster.anyOf(
ImmutableSortedMap.<K, V>naturalOrder().put(entry).buildOrThrow(),
ImmutableSortedMap.<K, V>naturalOrder().put(entry).build(),
Stream.of(entry)
.collect(
toImmutableSortedMap(naturalOrder(), Map.Entry::getKey, Map.Entry::getValue)));
@@ -126,7 +126,7 @@ final class ImmutableSortedMapRules {
return Refaster.anyOf(
ImmutableSortedMap.copyOf(iterable, naturalOrder()),
ImmutableSortedMap.copyOf(iterable.entrySet()),
ImmutableSortedMap.<K, V>naturalOrder().putAll(iterable).buildOrThrow());
ImmutableSortedMap.<K, V>naturalOrder().putAll(iterable).build());
}
@BeforeTemplate
@@ -134,7 +134,7 @@ final class ImmutableSortedMapRules {
Iterable<? extends Map.Entry<? extends K, ? extends V>> iterable) {
return Refaster.anyOf(
ImmutableSortedMap.copyOf(iterable, naturalOrder()),
ImmutableSortedMap.<K, V>naturalOrder().putAll(iterable).buildOrThrow(),
ImmutableSortedMap.<K, V>naturalOrder().putAll(iterable).build(),
Streams.stream(iterable)
.collect(
toImmutableSortedMap(

View File

@@ -1,114 +0,0 @@
package tech.picnic.errorprone.refasterrules;
import static com.google.common.collect.ImmutableTable.toImmutableTable;
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
import com.google.common.collect.ImmutableTable;
import com.google.common.collect.Table;
import com.google.common.collect.Tables;
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.MayOptionallyUse;
import com.google.errorprone.refaster.annotation.Placeholder;
import com.google.errorprone.refaster.annotation.UseImportPolicy;
import java.util.stream.Stream;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to expressions dealing with {@link ImmutableTable}s. */
@OnlineDocumentation
final class ImmutableTableRules {
private ImmutableTableRules() {}
/** Prefer {@link ImmutableTable#builder()} over the associated constructor. */
// XXX: This rule may drop generic type information, leading to non-compilable code.
static final class ImmutableTableBuilder<R, C, V> {
@BeforeTemplate
ImmutableTable.Builder<R, C, V> before() {
return new ImmutableTable.Builder<>();
}
@AfterTemplate
ImmutableTable.Builder<R, C, V> after() {
return ImmutableTable.builder();
}
}
/**
* Prefer {@link ImmutableTable.Builder#buildOrThrow()} over the less explicit {@link
* ImmutableTable.Builder#build()}.
*/
static final class ImmutableTableBuilderBuildOrThrow<R, C, V> {
@BeforeTemplate
ImmutableTable<R, C, V> before(ImmutableTable.Builder<R, C, V> builder) {
return builder.build();
}
@AfterTemplate
ImmutableTable<R, C, V> after(ImmutableTable.Builder<R, C, V> builder) {
return builder.buildOrThrow();
}
}
/** Prefer {@link ImmutableTable#of(Object, Object, Object)} over more contrived alternatives. */
static final class CellToImmutableTable<R, C, V> {
@BeforeTemplate
ImmutableTable<R, C, V> before(Table.Cell<? extends R, ? extends C, ? extends V> cell) {
return Refaster.anyOf(
ImmutableTable.<R, C, V>builder().put(cell).buildOrThrow(),
Stream.of(cell)
.collect(
toImmutableTable(
Table.Cell::getRowKey, Table.Cell::getColumnKey, Table.Cell::getValue)));
}
@AfterTemplate
ImmutableTable<R, C, V> after(Table.Cell<? extends R, ? extends C, ? extends V> cell) {
return ImmutableTable.of(cell.getRowKey(), cell.getColumnKey(), cell.getValue());
}
}
/**
* Don't map a stream's elements to table cells, only to subsequently collect them into an {@link
* ImmutableTable}. The collection can be performed directly.
*/
abstract static class StreamOfCellsToImmutableTable<E, R, C, V> {
@Placeholder(allowsIdentity = true)
abstract R rowFunction(@MayOptionallyUse E element);
@Placeholder(allowsIdentity = true)
abstract C columnFunction(@MayOptionallyUse E element);
@Placeholder(allowsIdentity = true)
abstract V valueFunction(@MayOptionallyUse E element);
@BeforeTemplate
ImmutableTable<R, C, V> before(Stream<E> stream) {
return stream
.map(e -> Tables.immutableCell(rowFunction(e), columnFunction(e), valueFunction(e)))
.collect(
toImmutableTable(
Table.Cell::getRowKey, Table.Cell::getColumnKey, Table.Cell::getValue));
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
ImmutableTable<R, C, V> after(Stream<E> stream) {
return stream.collect(
toImmutableTable(e -> rowFunction(e), e -> columnFunction(e), e -> valueFunction(e)));
}
}
/** Prefer {@link ImmutableTable#of()} over more contrived alternatives . */
static final class ImmutableTableOf<R, C, V> {
@BeforeTemplate
ImmutableTable<R, C, V> before() {
return ImmutableTable.<R, C, V>builder().buildOrThrow();
}
@AfterTemplate
ImmutableTable<R, C, V> after() {
return ImmutableTable.of();
}
}
}

View File

@@ -5,8 +5,6 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.fail;
import static org.assertj.core.api.Assertions.offset;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
@@ -36,8 +34,7 @@ import tech.picnic.errorprone.refaster.annotation.TypeMigration;
* <p>Note that, while both libraries throw an {@link AssertionError} in case of an assertion
* failure, the exact subtype used generally differs.
*/
// XXX: The `AssertThat*Array*ContainsExactly*` rules assume that `expected` and `actual` are not
// both `null`.
// XXX: Not all JUnit `Assertions` methods have an associated Refaster rule yet; expand this class.
// XXX: Introduce a `@Matcher` on `Executable` and `ThrowingSupplier` expressions, such that they
// are only matched if they are also compatible with the `ThrowingCallable` functional interface.
// When implementing such a matcher, note that expressions with a non-void return type such as
@@ -53,6 +50,39 @@ import tech.picnic.errorprone.refaster.annotation.TypeMigration;
"assertAll(String, Collection<Executable>)",
"assertAll(String, Executable[])",
"assertAll(String, Stream<Executable>)",
"assertArrayEquals(boolean[], boolean[])",
"assertArrayEquals(boolean[], boolean[], String)",
"assertArrayEquals(boolean[], boolean[], Supplier<String>)",
"assertArrayEquals(byte[], byte[])",
"assertArrayEquals(byte[], byte[], String)",
"assertArrayEquals(byte[], byte[], Supplier<String>)",
"assertArrayEquals(char[], char[])",
"assertArrayEquals(char[], char[], String)",
"assertArrayEquals(char[], char[], Supplier<String>)",
"assertArrayEquals(double[], double[])",
"assertArrayEquals(double[], double[], double)",
"assertArrayEquals(double[], double[], double, String)",
"assertArrayEquals(double[], double[], double, Supplier<String>)",
"assertArrayEquals(double[], double[], String)",
"assertArrayEquals(double[], double[], Supplier<String>)",
"assertArrayEquals(float[], float[])",
"assertArrayEquals(float[], float[], float)",
"assertArrayEquals(float[], float[], float, String)",
"assertArrayEquals(float[], float[], float, Supplier<String>)",
"assertArrayEquals(float[], float[], String)",
"assertArrayEquals(float[], float[], Supplier<String>)",
"assertArrayEquals(int[], int[])",
"assertArrayEquals(int[], int[], String)",
"assertArrayEquals(int[], int[], Supplier<String>)",
"assertArrayEquals(long[], long[])",
"assertArrayEquals(long[], long[], String)",
"assertArrayEquals(long[], long[], Supplier<String>)",
"assertArrayEquals(Object[], Object[])",
"assertArrayEquals(Object[], Object[], String)",
"assertArrayEquals(Object[], Object[], Supplier<String>)",
"assertArrayEquals(short[], short[])",
"assertArrayEquals(short[], short[], String)",
"assertArrayEquals(short[], short[], Supplier<String>)",
"assertEquals(Byte, Byte)",
"assertEquals(Byte, byte)",
"assertEquals(byte, Byte)",
@@ -272,436 +302,6 @@ import tech.picnic.errorprone.refaster.annotation.TypeMigration;
final class JUnitToAssertJRules {
private JUnitToAssertJRules() {}
static final class AssertThatBooleanArrayContainsExactly {
@BeforeTemplate
void before(boolean[] actual, boolean[] expected) {
assertArrayEquals(expected, actual);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(boolean[] actual, boolean[] expected) {
assertThat(actual).containsExactly(expected);
}
}
static final class AssertThatBooleanArrayWithFailMessageContainsExactly {
@BeforeTemplate
void before(boolean[] actual, String message, boolean[] expected) {
assertArrayEquals(expected, actual, message);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(boolean[] actual, String message, boolean[] expected) {
assertThat(actual).withFailMessage(message).containsExactly(expected);
}
}
static final class AssertThatBooleanArrayWithFailMessageSupplierContainsExactly {
@BeforeTemplate
void before(boolean[] actual, Supplier<String> message, boolean[] expected) {
assertArrayEquals(expected, actual, message);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(boolean[] actual, Supplier<String> message, boolean[] expected) {
assertThat(actual).withFailMessage(message).containsExactly(expected);
}
}
static final class AssertThatByteArrayContainsExactly {
@BeforeTemplate
void before(byte[] actual, byte[] expected) {
assertArrayEquals(expected, actual);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(byte[] actual, byte[] expected) {
assertThat(actual).containsExactly(expected);
}
}
static final class AssertThatByteArrayWithFailMessageContainsExactly {
@BeforeTemplate
void before(byte[] actual, String message, byte[] expected) {
assertArrayEquals(expected, actual, message);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(byte[] actual, String message, byte[] expected) {
assertThat(actual).withFailMessage(message).containsExactly(expected);
}
}
static final class AssertThatByteArrayWithFailMessageSupplierContainsExactly {
@BeforeTemplate
void before(byte[] actual, Supplier<String> message, byte[] expected) {
assertArrayEquals(expected, actual, message);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(byte[] actual, Supplier<String> message, byte[] expected) {
assertThat(actual).withFailMessage(message).containsExactly(expected);
}
}
static final class AssertThatCharArrayContainsExactly {
@BeforeTemplate
void before(char[] actual, char[] expected) {
assertArrayEquals(expected, actual);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(char[] actual, char[] expected) {
assertThat(actual).containsExactly(expected);
}
}
static final class AssertThatCharArrayWithFailMessageContainsExactly {
@BeforeTemplate
void before(char[] actual, String message, char[] expected) {
assertArrayEquals(expected, actual, message);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(char[] actual, String message, char[] expected) {
assertThat(actual).withFailMessage(message).containsExactly(expected);
}
}
static final class AssertThatCharArrayWithFailMessageSupplierContainsExactly {
@BeforeTemplate
void before(char[] actual, Supplier<String> message, char[] expected) {
assertArrayEquals(expected, actual, message);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(char[] actual, Supplier<String> message, char[] expected) {
assertThat(actual).withFailMessage(message).containsExactly(expected);
}
}
static final class AssertThatShortArrayContainsExactly {
@BeforeTemplate
void before(short[] actual, short[] expected) {
assertArrayEquals(expected, actual);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(short[] actual, short[] expected) {
assertThat(actual).containsExactly(expected);
}
}
static final class AssertThatShortArrayWithFailMessageContainsExactly {
@BeforeTemplate
void before(short[] actual, String message, short[] expected) {
assertArrayEquals(expected, actual, message);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(short[] actual, String message, short[] expected) {
assertThat(actual).withFailMessage(message).containsExactly(expected);
}
}
static final class AssertThatShortArrayWithFailMessageSupplierContainsExactly {
@BeforeTemplate
void before(short[] actual, Supplier<String> message, short[] expected) {
assertArrayEquals(expected, actual, message);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(short[] actual, Supplier<String> message, short[] expected) {
assertThat(actual).withFailMessage(message).containsExactly(expected);
}
}
static final class AssertThatIntArrayContainsExactly {
@BeforeTemplate
void before(int[] actual, int[] expected) {
assertArrayEquals(expected, actual);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(int[] actual, int[] expected) {
assertThat(actual).containsExactly(expected);
}
}
static final class AssertThatIntArrayWithFailMessageContainsExactly {
@BeforeTemplate
void before(int[] actual, String message, int[] expected) {
assertArrayEquals(expected, actual, message);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(int[] actual, String message, int[] expected) {
assertThat(actual).withFailMessage(message).containsExactly(expected);
}
}
static final class AssertThatIntArrayWithFailMessageSupplierContainsExactly {
@BeforeTemplate
void before(int[] actual, Supplier<String> message, int[] expected) {
assertArrayEquals(expected, actual, message);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(int[] actual, Supplier<String> message, int[] expected) {
assertThat(actual).withFailMessage(message).containsExactly(expected);
}
}
static final class AssertThatLongArrayContainsExactly {
@BeforeTemplate
void before(long[] actual, long[] expected) {
assertArrayEquals(expected, actual);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(long[] actual, long[] expected) {
assertThat(actual).containsExactly(expected);
}
}
static final class AssertThatLongArrayWithFailMessageContainsExactly {
@BeforeTemplate
void before(long[] actual, String message, long[] expected) {
assertArrayEquals(expected, actual, message);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(long[] actual, String message, long[] expected) {
assertThat(actual).withFailMessage(message).containsExactly(expected);
}
}
static final class AssertThatLongArrayWithFailMessageSupplierContainsExactly {
@BeforeTemplate
void before(long[] actual, Supplier<String> message, long[] expected) {
assertArrayEquals(expected, actual, message);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(long[] actual, Supplier<String> message, long[] expected) {
assertThat(actual).withFailMessage(message).containsExactly(expected);
}
}
static final class AssertThatFloatArrayContainsExactly {
@BeforeTemplate
void before(float[] actual, float[] expected) {
assertArrayEquals(expected, actual);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(float[] actual, float[] expected) {
assertThat(actual).containsExactly(expected);
}
}
static final class AssertThatFloatArrayWithFailMessageContainsExactly {
@BeforeTemplate
void before(float[] actual, String message, float[] expected) {
assertArrayEquals(expected, actual, message);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(float[] actual, String message, float[] expected) {
assertThat(actual).withFailMessage(message).containsExactly(expected);
}
}
static final class AssertThatFloatArrayWithFailMessageSupplierContainsExactly {
@BeforeTemplate
void before(float[] actual, Supplier<String> message, float[] expected) {
assertArrayEquals(expected, actual, message);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(float[] actual, Supplier<String> message, float[] expected) {
assertThat(actual).withFailMessage(message).containsExactly(expected);
}
}
static final class AssertThatFloatArrayContainsExactlyWithOffset {
@BeforeTemplate
void before(float[] actual, float[] expected, float delta) {
assertArrayEquals(expected, actual, delta);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(float[] actual, float[] expected, float delta) {
assertThat(actual).containsExactly(expected, offset(delta));
}
}
static final class AssertThatFloatArrayWithFailMessageContainsExactlyWithOffset {
@BeforeTemplate
void before(float[] actual, String message, float[] expected, float delta) {
assertArrayEquals(expected, actual, delta, message);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(float[] actual, String message, float[] expected, float delta) {
assertThat(actual).withFailMessage(message).containsExactly(expected, offset(delta));
}
}
static final class AssertThatFloatArrayWithFailMessageSupplierContainsExactlyWithOffset {
@BeforeTemplate
void before(float[] actual, Supplier<String> message, float[] expected, float delta) {
assertArrayEquals(expected, actual, delta, message);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(float[] actual, Supplier<String> message, float[] expected, float delta) {
assertThat(actual).withFailMessage(message).containsExactly(expected, offset(delta));
}
}
static final class AssertThatDoubleArrayContainsExactly {
@BeforeTemplate
void before(double[] actual, double[] expected) {
assertArrayEquals(expected, actual);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(double[] actual, double[] expected) {
assertThat(actual).containsExactly(expected);
}
}
static final class AssertThatDoubleArrayWithFailMessageContainsExactly {
@BeforeTemplate
void before(double[] actual, String message, double[] expected) {
assertArrayEquals(expected, actual, message);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(double[] actual, String message, double[] expected) {
assertThat(actual).withFailMessage(message).containsExactly(expected);
}
}
static final class AssertThatDoubleArrayWithFailMessageSupplierContainsExactly {
@BeforeTemplate
void before(double[] actual, Supplier<String> message, double[] expected) {
assertArrayEquals(expected, actual, message);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(double[] actual, Supplier<String> message, double[] expected) {
assertThat(actual).withFailMessage(message).containsExactly(expected);
}
}
static final class AssertThatDoubleArrayContainsExactlyWithOffset {
@BeforeTemplate
void before(double[] actual, double[] expected, double delta) {
assertArrayEquals(expected, actual, delta);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(double[] actual, double[] expected, double delta) {
assertThat(actual).containsExactly(expected, offset(delta));
}
}
static final class AssertThatDoubleArrayWithFailMessageContainsExactlyWithOffset {
@BeforeTemplate
void before(double[] actual, String message, double[] expected, double delta) {
assertArrayEquals(expected, actual, delta, message);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(double[] actual, String message, double[] expected, double delta) {
assertThat(actual).withFailMessage(message).containsExactly(expected, offset(delta));
}
}
static final class AssertThatDoubleArrayWithFailMessageSupplierContainsExactlyWithOffset {
@BeforeTemplate
void before(
double[] actual, Supplier<String> messageSupplier, double[] expected, double delta) {
assertArrayEquals(expected, actual, delta, messageSupplier);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(double[] actual, Supplier<String> messageSupplier, double[] expected, double delta) {
assertThat(actual).withFailMessage(messageSupplier).containsExactly(expected, offset(delta));
}
}
static final class AssertThatObjectArrayContainsExactly {
@BeforeTemplate
void before(Object[] actual, Object[] expected) {
assertArrayEquals(expected, actual);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(Object[] actual, Object[] expected) {
assertThat(actual).containsExactly(expected);
}
}
static final class AssertThatObjectArrayWithFailMessageContainsExactly {
@BeforeTemplate
void before(Object[] actual, String message, Object[] expected) {
assertArrayEquals(expected, actual, message);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(Object[] actual, String message, Object[] expected) {
assertThat(actual).withFailMessage(message).containsExactly(expected);
}
}
static final class AssertThatObjectArrayWithFailMessageSupplierContainsExactly {
@BeforeTemplate
void before(Object[] actual, Supplier<String> message, Object[] expected) {
assertArrayEquals(expected, actual, message);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(Object[] actual, Supplier<String> message, Object[] expected) {
assertThat(actual).withFailMessage(message).containsExactly(expected);
}
}
static final class Fail<T> {
@BeforeTemplate
T before() {

View File

@@ -3,7 +3,6 @@ package tech.picnic.errorprone.refasterrules;
import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
import static java.util.Objects.requireNonNullElse;
import static java.util.Objects.requireNonNullElseGet;
import static java.util.function.Predicate.not;
import com.google.common.base.MoreObjects;
import com.google.errorprone.refaster.Refaster;
@@ -95,14 +94,11 @@ final class NullRules {
}
}
/**
* Prefer {@link Objects#isNull(Object)} over the equivalent lambda function or more contrived
* alternatives.
*/
/** Prefer {@link Objects#isNull(Object)} over the equivalent lambda function. */
static final class IsNullFunction<T> {
@BeforeTemplate
Predicate<T> before() {
return Refaster.anyOf(o -> o == null, not(Objects::nonNull));
return o -> o == null;
}
@AfterTemplate
@@ -111,14 +107,11 @@ final class NullRules {
}
}
/**
* Prefer {@link Objects#nonNull(Object)} over the equivalent lambda function or more contrived
* alternatives.
*/
/** Prefer {@link Objects#nonNull(Object)} over the equivalent lambda function. */
static final class NonNullFunction<T> {
@BeforeTemplate
Predicate<T> before() {
return Refaster.anyOf(o -> o != null, not(Objects::isNull));
return o -> o != null;
}
@AfterTemplate

View File

@@ -282,8 +282,6 @@ final class OptionalRules {
// XXX: The rewritten `filter`/`map` expression may be more performant than its replacement. See
// https://github.com/palantir/gradle-baseline/pull/2946. (There are plans to pair Refaster rules
// with JMH benchmarks; this would be a great use case.)
// XXX: Perhaps `stream.mapMulti(Optional::ifPresent)` is what we should use. See
// https://github.com/palantir/gradle-baseline/pull/2996.
static final class StreamFlatMapOptional<T> {
@BeforeTemplate
Stream<T> before(Stream<Optional<T>> stream) {

View File

@@ -8,15 +8,12 @@ import com.google.common.primitives.Floats;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
import com.google.common.primitives.Shorts;
import com.google.common.primitives.UnsignedBytes;
import com.google.common.primitives.UnsignedInts;
import com.google.common.primitives.UnsignedLongs;
import com.google.errorprone.refaster.Refaster;
import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.AlsoNegation;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import java.util.Arrays;
import java.util.Comparator;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to expressions dealing with primitives. */
@@ -528,7 +525,10 @@ final class PrimitiveRules {
}
}
/** Prefer JDK's {@link Integer#toUnsignedString(int,int)} over third-party alternatives. */
/**
* Prefer JDK's {@link Integer#toUnsignedString(int,int)} over third-party or more verbose
* alternatives.
*/
static final class IntegerToUnsignedStringWithRadix {
@BeforeTemplate
String before(int i, int radix) {
@@ -541,7 +541,10 @@ final class PrimitiveRules {
}
}
/** Prefer JDK's {@link Long#toUnsignedString(long,int)} over third-party alternatives. */
/**
* Prefer JDK's {@link Long#toUnsignedString(long,int)} over third-party or more verbose
* alternatives.
*/
static final class LongToUnsignedStringWithRadix {
@BeforeTemplate
String before(long i, int radix) {
@@ -553,49 +556,4 @@ final class PrimitiveRules {
return Long.toUnsignedString(i, radix);
}
}
/** Prefer JDK's {@link Arrays#compareUnsigned(byte[], byte[])} over third-party alternatives. */
// XXX: This rule will yield non-compilable code if the result of the replaced expression is
// dereferenced. Investigate how to make this safe.
static final class ArraysCompareUnsignedBytes {
@BeforeTemplate
Comparator<byte[]> before() {
return UnsignedBytes.lexicographicalComparator();
}
@AfterTemplate
Comparator<byte[]> after() {
return Arrays::compareUnsigned;
}
}
/** Prefer JDK's {@link Arrays#compareUnsigned(int[], int[])} over third-party alternatives. */
// XXX: This rule will yield non-compilable code if the result of the replaced expression is
// dereferenced. Investigate how to make this safe.
static final class ArraysCompareUnsignedInts {
@BeforeTemplate
Comparator<int[]> before() {
return UnsignedInts.lexicographicalComparator();
}
@AfterTemplate
Comparator<int[]> after() {
return Arrays::compareUnsigned;
}
}
/** Prefer JDK's {@link Arrays#compareUnsigned(long[], long[])} over third-party alternatives. */
// XXX: This rule will yield non-compilable code if the result of the replaced expression is
// dereferenced. Investigate how to make this safe.
static final class ArraysCompareUnsignedLongs {
@BeforeTemplate
Comparator<long[]> before() {
return UnsignedLongs.lexicographicalComparator();
}
@AfterTemplate
Comparator<long[]> after() {
return Arrays::compareUnsigned;
}
}
}

View File

@@ -489,16 +489,9 @@ final class ReactorRules {
return Flux.range(value, 1);
}
// XXX: Consider generalizing part of this template using an Error Prone check that covers any
// sequence of explicitly enumerated values passed to an iteration order-preserving collection
// factory method.
@BeforeTemplate
Flux<T> before(T value) {
return Refaster.anyOf(
Mono.just(value).flux(),
Mono.just(value).repeat().take(1),
Flux.fromIterable(ImmutableList.of(value)),
Flux.fromIterable(ImmutableSet.of(value)));
return Mono.just(value).repeat().take(1);
}
@AfterTemplate
@@ -515,14 +508,8 @@ final class ReactorRules {
mono.switchIfEmpty(Mono.empty()), mono.flux().next(), mono.flux().singleOrEmpty());
}
// XXX: Consider filing a SonarCloud issue for the S2637 false positive.
@BeforeTemplate
@SuppressWarnings({
"java:S2637" /* False positive: result is never `null`. */,
"java:S4968" /* Result may be `Mono<Void>`. */,
"key-to-resolve-AnnotationUseStyle-and-TrailingComment-check-conflict"
})
Mono<? extends @Nullable Void> before2(Mono<@Nullable Void> mono) {
Mono<@Nullable Void> before2(Mono<@Nullable Void> mono) {
return Refaster.anyOf(mono.ignoreElement(), mono.then());
}
@@ -902,38 +889,6 @@ final class ReactorRules {
}
}
/**
* Prefer immediately unwrapping {@link Optional} transformation results inside {@link
* Flux#mapNotNull(Function)} over more contrived alternatives.
*/
abstract static class FluxMapNotNullTransformationOrElse<T, S> {
@Placeholder(allowsIdentity = true)
abstract Optional<S> transformation(@MayOptionallyUse T value);
@BeforeTemplate
Flux<S> before(Flux<T> flux) {
return flux.map(v -> transformation(v)).mapNotNull(o -> o.orElse(null));
}
@AfterTemplate
Flux<S> after(Flux<T> flux) {
return flux.mapNotNull(x -> transformation(x).orElse(null));
}
}
/** Prefer {@link Flux#mapNotNull(Function)} over more contrived alternatives. */
static final class FluxMapNotNullOrElse<T> {
@BeforeTemplate
Flux<T> before(Flux<Optional<T>> flux) {
return flux.filter(Optional::isPresent).map(Optional::orElseThrow);
}
@AfterTemplate
Flux<T> after(Flux<Optional<T>> flux) {
return flux.mapNotNull(x -> x.orElse(null));
}
}
/** Prefer {@link Mono#flux()}} over more contrived alternatives. */
static final class MonoFlux<T> {
@BeforeTemplate
@@ -951,18 +906,12 @@ final class ReactorRules {
/** Prefer direct invocation of {@link Mono#then()}} over more contrived alternatives. */
static final class MonoThen<T> {
@BeforeTemplate
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
Mono<? extends @Nullable Void> before(Mono<T> mono) {
return Refaster.anyOf(
mono.ignoreElement().then(),
mono.flux().then(),
Mono.when(mono),
Mono.whenDelayError(mono));
Mono<@Nullable Void> before(Mono<T> mono) {
return Refaster.anyOf(mono.ignoreElement().then(), mono.flux().then());
}
@AfterTemplate
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
Mono<? extends @Nullable Void> after(Mono<T> mono) {
Mono<@Nullable Void> after(Mono<T> mono) {
return mono.then();
}
}
@@ -970,25 +919,17 @@ final class ReactorRules {
/** Avoid vacuous invocations of {@link Flux#ignoreElements()}. */
static final class FluxThen<T> {
@BeforeTemplate
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
Mono<? extends @Nullable Void> before(Flux<T> flux) {
Mono<@Nullable Void> before(Flux<T> flux) {
return flux.ignoreElements().then();
}
// XXX: Consider filing a SonarCloud issue for the S2637 false positive.
@BeforeTemplate
@SuppressWarnings({
"java:S2637" /* False positive: result is never `null`. */,
"java:S4968" /* Result may be `Mono<Void>`. */,
"key-to-resolve-AnnotationUseStyle-and-TrailingComment-check-conflict"
})
Mono<? extends @Nullable Void> before2(Flux<@Nullable Void> flux) {
Mono<@Nullable Void> before2(Flux<@Nullable Void> flux) {
return flux.ignoreElements();
}
@AfterTemplate
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
Mono<? extends @Nullable Void> after(Flux<T> flux) {
Mono<@Nullable Void> after(Flux<T> flux) {
return flux.then();
}
}
@@ -996,14 +937,12 @@ final class ReactorRules {
/** Avoid vacuous invocations of {@link Mono#ignoreElement()}. */
static final class MonoThenEmpty<T> {
@BeforeTemplate
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
Mono<? extends @Nullable Void> before(Mono<T> mono, Publisher<@Nullable Void> publisher) {
Mono<@Nullable Void> before(Mono<T> mono, Publisher<@Nullable Void> publisher) {
return mono.ignoreElement().thenEmpty(publisher);
}
@AfterTemplate
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
Mono<? extends @Nullable Void> after(Mono<T> mono, Publisher<@Nullable Void> publisher) {
Mono<@Nullable Void> after(Mono<T> mono, Publisher<@Nullable Void> publisher) {
return mono.thenEmpty(publisher);
}
}
@@ -1011,14 +950,12 @@ final class ReactorRules {
/** Avoid vacuous invocations of {@link Flux#ignoreElements()}. */
static final class FluxThenEmpty<T> {
@BeforeTemplate
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
Mono<? extends @Nullable Void> before(Flux<T> flux, Publisher<@Nullable Void> publisher) {
Mono<@Nullable Void> before(Flux<T> flux, Publisher<@Nullable Void> publisher) {
return flux.ignoreElements().thenEmpty(publisher);
}
@AfterTemplate
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
Mono<? extends @Nullable Void> after(Flux<T> flux, Publisher<@Nullable Void> publisher) {
Mono<@Nullable Void> after(Flux<T> flux, Publisher<@Nullable Void> publisher) {
return flux.thenEmpty(publisher);
}
}
@@ -1074,8 +1011,7 @@ final class ReactorRules {
}
@BeforeTemplate
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
Mono<? extends @Nullable Void> before2(Mono<T> mono1, Mono<@Nullable Void> mono2) {
Mono<@Nullable Void> before2(Mono<T> mono1, Mono<@Nullable Void> mono2) {
return mono1.thenEmpty(mono2);
}
@@ -1093,8 +1029,7 @@ final class ReactorRules {
}
@BeforeTemplate
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
Mono<? extends @Nullable Void> before2(Flux<T> flux, Mono<@Nullable Void> mono) {
Mono<@Nullable Void> before2(Flux<T> flux, Mono<@Nullable Void> mono) {
return flux.thenEmpty(mono);
}
@@ -1111,12 +1046,10 @@ final class ReactorRules {
// rule. Consider introducing an Error Prone check for this.
static final class MonoSingleOptional<T> {
@BeforeTemplate
Mono<Optional<T>> before(Mono<T> mono, Optional<T> optional, Mono<Optional<T>> alternate) {
Mono<Optional<T>> before(Mono<T> mono) {
return Refaster.anyOf(
mono.flux().collect(toOptional()),
mono.map(Optional::of),
mono.singleOptional().defaultIfEmpty(optional),
mono.singleOptional().switchIfEmpty(alternate),
mono.map(Optional::of).defaultIfEmpty(Optional.empty()),
mono.transform(Mono::singleOptional));
}
@@ -2209,22 +2142,6 @@ final class ReactorRules {
}
}
/**
* Don't propagate {@link Mono} cancellations to upstream cache value computations, as completion
* of such computations may benefit concurrent or subsequent cache usages.
*/
static final class MonoFromFutureAsyncLoadingCacheGetAll<K1, K2 extends K1, V> {
@BeforeTemplate
Mono<Map<K1, V>> before(AsyncLoadingCache<K1, V> cache, Iterable<K2> keys) {
return Mono.fromFuture(() -> cache.getAll(keys));
}
@AfterTemplate
Mono<Map<K1, V>> after(AsyncLoadingCache<K1, V> cache, Iterable<K2> keys) {
return Mono.fromFuture(() -> cache.getAll(keys), /* suppressCancel= */ true);
}
}
/**
* 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

View File

@@ -23,16 +23,14 @@ final class RxJava2AdapterRules {
/** Use the fluent API style when using {@link RxJava2Adapter#completableToMono}. */
static final class CompletableToMono {
@BeforeTemplate
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
Mono<? extends @Nullable Void> before(Completable completable) {
Mono<@Nullable Void> before(Completable completable) {
return Refaster.anyOf(
RxJava2Adapter.completableToMono(completable),
completable.to(RxJava2Adapter::completableToMono));
}
@AfterTemplate
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
Mono<? extends @Nullable Void> after(Completable completable) {
Mono<@Nullable Void> after(Completable completable) {
return completable.as(RxJava2Adapter::completableToMono);
}
}

View File

@@ -9,10 +9,12 @@ import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.base.Utf8;
import com.google.common.collect.Streams;
import com.google.errorprone.annotations.FormatMethod;
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.Repeated;
import com.google.errorprone.refaster.annotation.UseImportPolicy;
import java.util.Arrays;
import java.util.Collection;
@@ -348,4 +350,23 @@ final class StringRules {
return string.startsWith(prefix, fromIndex);
}
}
/**
* Prefer {@link String#formatted(Object...)} over {@link String#format(String, Object...)}, as
* the former works more nicely with text blocks, while the latter does not appear advantageous in
* any circumstance (assuming one targets JDK 15+).
*/
static final class StringFormatted {
@BeforeTemplate
@FormatMethod
String before(String format, @Repeated Object args) {
return String.format(format, args);
}
@AfterTemplate
@FormatMethod
String after(String format, @Repeated Object args) {
return format.formatted(args);
}
}
}

View File

@@ -1,6 +1,5 @@
package tech.picnic.errorprone.refasterrules;
import com.google.errorprone.VisitorState;
import com.google.errorprone.fixes.SuggestedFix;
import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
@@ -66,18 +65,16 @@ final class SuggestedFixRules {
}
}
/**
* Prefer {@link SuggestedFix#swap(Tree, Tree, VisitorState)} over more contrived alternatives.
*/
/** Prefer {@link SuggestedFix#swap(Tree, Tree)} over more contrived alternatives. */
static final class SuggestedFixSwap {
@BeforeTemplate
SuggestedFix before(Tree tree1, Tree tree2, VisitorState state) {
return SuggestedFix.builder().swap(tree1, tree2, state).build();
SuggestedFix before(Tree tree1, Tree tree2) {
return SuggestedFix.builder().swap(tree1, tree2).build();
}
@AfterTemplate
SuggestedFix after(Tree tree1, Tree tree2, VisitorState state) {
return SuggestedFix.swap(tree1, tree2, state);
SuggestedFix after(Tree tree1, Tree tree2) {
return SuggestedFix.swap(tree1, tree2);
}
}

View File

@@ -53,20 +53,71 @@ import tech.picnic.errorprone.refaster.annotation.TypeMigration;
// XXX: As-is these rules do not result in a complete migration:
// - Expressions containing comments are skipped due to a limitation of Refaster.
// - Assertions inside lambda expressions are also skipped. Unclear why.
// XXX: Many of the test expressions for these rules use the same expression for `expected` and
// XXX: The `assertEquals` tests for this class generally use the same expression for `expected` and
// `actual`, which makes the validation weaker than necessary; fix this. (And investigate whether we
// can introduce validation for this.)
@OnlineDocumentation
@TypeMigration(
of = Assert.class,
unmigratedMethods = {
// XXX: Add migrations for the methods below.
"assertEquals(Boolean, Boolean)",
"assertEquals(Boolean, boolean)",
"assertEquals(boolean, Boolean)",
"assertEquals(Boolean, Boolean, String)",
"assertEquals(Boolean, boolean, String)",
"assertEquals(boolean, Boolean, String)",
"assertEquals(Byte, Byte)",
"assertEquals(Byte, byte)",
"assertEquals(byte, Byte)",
"assertEquals(Byte, Byte, String)",
"assertEquals(Byte, byte, String)",
"assertEquals(byte, Byte, String)",
"assertEquals(char, Character)",
"assertEquals(char, Character, String)",
"assertEquals(Character, char)",
"assertEquals(Character, char, String)",
"assertEquals(Character, Character)",
"assertEquals(Character, Character, String)",
"assertEquals(Double, Double)",
"assertEquals(Double, double)",
"assertEquals(double, Double)",
"assertEquals(Double, Double, String)",
"assertEquals(Double, double, String)",
"assertEquals(double, Double, String)",
"assertEquals(double[], double[], double)",
"assertEquals(double[], double[], double, String)",
"assertEquals(Float, Float)",
"assertEquals(Float, float)",
"assertEquals(float, Float)",
"assertEquals(Float, Float, String)",
"assertEquals(Float, float, String)",
"assertEquals(float, Float, String)",
"assertEquals(float[], float[], float)",
"assertEquals(float[], float[], float, String)",
"assertEquals(int, Integer)",
"assertEquals(int, Integer, String)",
"assertEquals(Integer, int)",
"assertEquals(Integer, int, String)",
"assertEquals(Integer, Integer)",
"assertEquals(Integer, Integer, String)",
"assertEquals(Long, Long)",
"assertEquals(Long, long)",
"assertEquals(long, Long)",
"assertEquals(Long, Long, String)",
"assertEquals(Long, long, String)",
"assertEquals(Short, Short)",
"assertEquals(Short, short)",
"assertEquals(short, Short)",
"assertEquals(Short, Short, String)",
"assertEquals(Short, short, String)",
"assertEquals(short, Short, String)",
/*
* These `assertEqualsDeep` methods cannot (easily) be expressed using AssertJ because they
* mix regular equality and array equality:
*/
"assertEqualsDeep(Map<?, ?>, Map<?, ?>)",
"assertEqualsDeep(Map<?, ?>, Map<?, ?>, String)",
"assertEqualsDeep(Set<?>, Set<?>)",
"assertEqualsDeep(Set<?>, Set<?>, String)",
// XXX: Add migrations for the methods below.
"assertEqualsNoOrder(Collection<?>, Collection<?>)",
@@ -300,168 +351,47 @@ final class TestNGToAssertJRules {
}
}
@SuppressWarnings("java:S1448" /* Each variant requires a separate `@BeforeTemplate` method. */)
static final class AssertEqual {
@BeforeTemplate
void before(boolean actual, boolean expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(boolean actual, Boolean expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(Boolean actual, boolean expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(Boolean actual, Boolean expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(byte actual, byte expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(byte actual, Byte expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(Byte actual, byte expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(Byte actual, Byte expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(char actual, char expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(char actual, Character expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(Character actual, char expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(Character actual, Character expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(short actual, short expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(short actual, Short expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(Short actual, short expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(Short actual, Short expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(int actual, int expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(int actual, Integer expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(Integer actual, int expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(Integer actual, Integer expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(long actual, long expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(long actual, Long expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(Long actual, long expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(Long actual, Long expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(float actual, float expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(float actual, Float expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(Float actual, float expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(Float actual, Float expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(double actual, double expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(double actual, Double expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(Double actual, double expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(Double actual, Double expected) {
assertEquals(actual, expected);
}
@BeforeTemplate
void before(Object actual, Object expected) {
assertEquals(actual, expected);
@@ -484,168 +414,47 @@ final class TestNGToAssertJRules {
}
}
@SuppressWarnings("java:S1448" /* Each variant requires a separate `@BeforeTemplate` method. */)
static final class AssertEqualWithMessage {
@BeforeTemplate
void before(boolean actual, String message, boolean expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(boolean actual, String message, Boolean expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(Boolean actual, String message, boolean expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(Boolean actual, String message, Boolean expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(byte actual, String message, byte expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(byte actual, String message, Byte expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(Byte actual, String message, byte expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(Byte actual, String message, Byte expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(char actual, String message, char expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(char actual, String message, Character expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(Character actual, String message, char expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(Character actual, String message, Character expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(short actual, String message, short expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(short actual, String message, Short expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(Short actual, String message, short expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(Short actual, String message, Short expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(int actual, String message, int expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(int actual, String message, Integer expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(Integer actual, String message, int expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(Integer actual, String message, Integer expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(long actual, String message, long expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(long actual, String message, Long expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(Long actual, String message, long expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(Long actual, String message, Long expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(float actual, String message, float expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(float actual, String message, Float expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(Float actual, String message, float expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(Float actual, String message, Float expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(double actual, String message, double expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(double actual, String message, Double expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(Double actual, String message, double expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(Double actual, String message, Double expected) {
assertEquals(actual, expected, message);
}
@BeforeTemplate
void before(Object actual, String message, Object expected) {
assertEquals(actual, expected, message);
@@ -676,7 +485,7 @@ final class TestNGToAssertJRules {
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(Float actual, float expected, float delta) {
void after(float actual, float expected, float delta) {
assertThat(actual).isCloseTo(expected, offset(delta));
}
}
@@ -826,58 +635,6 @@ final class TestNGToAssertJRules {
}
}
static final class AssertEqualFloatArraysWithDelta {
@BeforeTemplate
void before(float[] actual, float[] expected, float delta) {
assertEquals(actual, expected, delta);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(float[] actual, float[] expected, float delta) {
assertThat(actual).containsExactly(expected, offset(delta));
}
}
static final class AssertEqualFloatArraysWithDeltaWithMessage {
@BeforeTemplate
void before(float[] actual, String message, float[] expected, float delta) {
assertEquals(actual, expected, delta, message);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(float[] actual, String message, float[] expected, float delta) {
assertThat(actual).withFailMessage(message).containsExactly(expected, offset(delta));
}
}
static final class AssertEqualDoubleArraysWithDelta {
@BeforeTemplate
void before(double[] actual, double[] expected, double delta) {
assertEquals(actual, expected, delta);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(double[] actual, double[] expected, double delta) {
assertThat(actual).containsExactly(expected, offset(delta));
}
}
static final class AssertEqualDoubleArraysWithDeltaWithMessage {
@BeforeTemplate
void before(double[] actual, String message, double[] expected, double delta) {
assertEquals(actual, expected, delta, message);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after(double[] actual, String message, double[] expected, double delta) {
assertThat(actual).withFailMessage(message).containsExactly(expected, offset(delta));
}
}
static final class AssertEqualArraysIrrespectiveOfOrder {
@BeforeTemplate
void before(Object[] actual, Object[] expected) {

View File

@@ -1,286 +0,0 @@
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;
final class EagerStringFormattingTest {
@Test
void identification() {
CompilationTestHelper.newInstance(EagerStringFormatting.class, getClass())
.expectErrorMessage("DEFER", m -> m.contains("String formatting can be deferred\n"))
.expectErrorMessage(
"DEFER_EXTRA_VARIABLE",
m ->
m.contains(
"String formatting can be deferred (but this requires introducing an effectively final variable)"))
.expectErrorMessage(
"DEFER_SIMPLIFIED_GUAVA",
m ->
m.contains(
"String formatting can be deferred (assuming that Guava's simplified formatting support suffices)"))
.expectErrorMessage(
"DEFER_SIMPLIFIED_SLF4J",
m ->
m.contains(
"String formatting can be deferred (assuming that SLF4J's simplified formatting support suffices)"))
.expectErrorMessage(
"VACUOUS", m -> m.contains("String formatting never yields `null` expression"))
.addSourceLines(
"A.java",
"import static com.google.common.base.Preconditions.checkArgument;",
"import static com.google.common.base.Preconditions.checkNotNull;",
"import static com.google.common.base.Preconditions.checkState;",
"import static com.google.common.base.Verify.verify;",
"import static com.google.common.base.Verify.verifyNotNull;",
"import static java.util.Objects.requireNonNull;",
"",
"import java.util.Formattable;",
"import java.util.Locale;",
"import org.slf4j.Logger;",
"import org.slf4j.LoggerFactory;",
"import org.slf4j.Marker;",
"",
"class A {",
" private static final Logger LOG = LoggerFactory.getLogger(A.class);",
"",
" private int nonFinalField = 0;",
"",
" void m() {",
" Formattable formattable = (formatter, flags, width, precision) -> {};",
" int effectivelyFinalLocal = 0;",
" /* A local variable that is also not effectively final. */",
" int nonFinalLocal = 0;",
" nonFinalLocal = 1;",
"",
" String.format(\"%s\", \"foo\");",
" String.format(Locale.US, \"%s\", \"foo\");",
" \"%s\".formatted(\"foo\");",
" String.format(\"%s\", \"foo\", \"bar\");",
" String.format(\"%s %s\", \"foo\", \"bar\");",
" String.format(\"%s %s %%\", \"foo\", \"bar\");",
"",
" System.out.println(String.format(\"%s\", nonFinalLocal));",
"",
" requireNonNull(\"never-null\");",
" requireNonNull(\"never-null\", () -> String.format(\"Format string: %s\", nonFinalField));",
" // BUG: Diagnostic matches: VACUOUS",
" requireNonNull(String.format(\"Never-null format string: %s\", nonFinalField));",
" // BUG: Diagnostic matches: VACUOUS",
" requireNonNull(\"Never-null format string: %s\".formatted(nonFinalField), \"message\");",
" // BUG: Diagnostic matches: VACUOUS",
" requireNonNull(",
" String.format(\"Never-null format string\"), String.format(\"Malformed format string: %\"));",
" // BUG: Diagnostic matches: DEFER_EXTRA_VARIABLE",
" requireNonNull(\"never-null\", String.format(\"Format string: %s\", nonFinalLocal));",
" // BUG: Diagnostic matches: DEFER",
" requireNonNull(\"never-null\", String.format(\"Format string: %s\", effectivelyFinalLocal));",
" // BUG: Diagnostic matches: DEFER",
" requireNonNull(",
" \"never-null\",",
" String.format(",
" \"Custom format string: %s, %d, %s\", getClass(), nonFinalField, \"string-constant\"));",
"",
" checkArgument(true);",
" checkNotNull(\"never-null\");",
" checkState(false);",
" verify(true);",
" verifyNotNull(\"never-null\");",
" checkArgument(false, \"Without format string\");",
" checkNotNull(\"never-null\", \"Without format string\");",
" checkState(true, \"Without format string\");",
" verify(false, \"Without format string\");",
" verifyNotNull(\"never-null\", \"Without format string\");",
" checkArgument(true, \"With format string: %s\", nonFinalLocal);",
" checkNotNull(\"never-null\", \"With format string: %s\", nonFinalLocal);",
" checkState(false, \"With format string: %s\", nonFinalLocal);",
" verify(true, \"With format string: %s\", nonFinalLocal);",
" verifyNotNull(\"never-null\", \"With format string: %s\", nonFinalLocal);",
" // BUG: Diagnostic matches: VACUOUS",
" checkNotNull(String.format(\"Never-null format string: %s\", nonFinalLocal));",
" // BUG: Diagnostic matches: VACUOUS",
" verifyNotNull(\"Never-null format string: %s\".formatted(nonFinalLocal), \"message\");",
" // BUG: Diagnostic matches: VACUOUS",
" checkNotNull(",
" String.format(\"Never-null format string\"), String.format(\"Malformed format string: %\"));",
" // BUG: Diagnostic matches: DEFER_SIMPLIFIED_GUAVA",
" checkArgument(true, String.format(toString()));",
" // BUG: Diagnostic matches: DEFER_SIMPLIFIED_GUAVA",
" checkNotNull(\"never-null\", toString().formatted());",
" // BUG: Diagnostic matches: DEFER_SIMPLIFIED_GUAVA",
" checkState(true, String.format(\"Custom format string: %d\", nonFinalLocal));",
" // BUG: Diagnostic matches: DEFER_SIMPLIFIED_GUAVA",
" verify(true, \"Mismatched format string:\".formatted(nonFinalLocal));",
" // BUG: Diagnostic matches: DEFER_SIMPLIFIED_GUAVA",
" verifyNotNull(\"never-null\", \"Mismatched format string: %d\".formatted());",
" // BUG: Diagnostic matches: DEFER_SIMPLIFIED_GUAVA",
" checkArgument(true, String.format(\"Malformed format string: %\"));",
" // BUG: Diagnostic matches: DEFER_SIMPLIFIED_GUAVA",
" checkNotNull(\"never-null\", \"Format string with `Formattable`: %s\".formatted(formattable));",
" // BUG: Diagnostic matches: DEFER_SIMPLIFIED_GUAVA",
" checkState(true, String.format(\"Generated format string: %%s\"), nonFinalLocal);",
" // BUG: Diagnostic matches: DEFER_SIMPLIFIED_GUAVA",
" verify(",
" true,",
" \"Format string with format string argument: %s\",",
" String.format(\"Format string argument: %s\", nonFinalLocal));",
" // BUG: Diagnostic matches: DEFER",
" verifyNotNull(",
" \"never-null\", String.format(\"Format string: %s, %s\", nonFinalLocal, nonFinalLocal));",
" // BUG: Diagnostic matches: DEFER",
" checkArgument(true, \"Format string: %s%%\".formatted(nonFinalLocal));",
" // BUG: Diagnostic matches: DEFER",
" checkNotNull(",
" \"never-null\", String.format(Locale.US, \"Format string with locale: %s\", nonFinalLocal));",
"",
" LOG.trace(\"Without format string\");",
" LOG.debug(\"With format string: {}\", nonFinalLocal);",
" LOG.info((Marker) null, \"With marker\");",
" LOG.warn((Marker) null, \"With marker and format string: {}\", nonFinalLocal);",
" LOG.error(\"With throwable\", new RuntimeException());",
" LOG.trace(\"With throwable and format string: {}\", nonFinalLocal, new RuntimeException());",
" LOG.debug((Marker) null, \"With marker and throwable\", new RuntimeException());",
" LOG.info(",
" (Marker) null,",
" \"With marker, throwable and format string: {}\",",
" nonFinalLocal,",
" new RuntimeException());",
" // BUG: Diagnostic matches: DEFER_SIMPLIFIED_SLF4J",
" LOG.warn(String.format(toString()));",
" // BUG: Diagnostic matches: DEFER_SIMPLIFIED_SLF4J",
" LOG.error(toString().formatted());",
" // BUG: Diagnostic matches: DEFER_SIMPLIFIED_SLF4J",
" LOG.trace(String.format(\"Custom format string: %d\", nonFinalLocal));",
" // BUG: Diagnostic matches: DEFER_SIMPLIFIED_SLF4J",
" LOG.debug(\"Mismatched format string:\".formatted(nonFinalLocal));",
" // BUG: Diagnostic matches: DEFER_SIMPLIFIED_SLF4J",
" LOG.info(\"Mismatched format string %d:\".formatted());",
" // BUG: Diagnostic matches: DEFER_SIMPLIFIED_SLF4J",
" LOG.warn(String.format(\"Malformed format string: %\"));",
" // BUG: Diagnostic matches: DEFER_SIMPLIFIED_SLF4J",
" LOG.error(\"Format string with `Formattable`: %s\".formatted(formattable));",
" // BUG: Diagnostic matches: DEFER_SIMPLIFIED_SLF4J",
" LOG.trace(String.format(\"Generated format string: {}\"), nonFinalLocal);",
" // BUG: Diagnostic matches: DEFER_SIMPLIFIED_SLF4J",
" LOG.debug(",
" \"Format string with format string argument: {}\",",
" String.format(\"Format string argument: %s\", nonFinalLocal));",
" // BUG: Diagnostic matches: DEFER",
" LOG.info(String.format(\"Vacuous format string %%\"));",
" // BUG: Diagnostic matches: DEFER",
" LOG.warn(String.format(\"With format string: %s, %s\", nonFinalLocal, nonFinalLocal));",
" // BUG: Diagnostic matches: DEFER",
" LOG.error(String.format(Locale.ROOT, \"With vacuous localized format string %%\"));",
" // BUG: Diagnostic matches: DEFER",
" LOG.trace((Marker) null, String.format(\"With marker and format string: %s\", nonFinalLocal));",
" // BUG: Diagnostic matches: DEFER",
" LOG.debug(",
" String.format(\"With throwable and format string: %s\", nonFinalLocal),",
" new RuntimeException());",
" // BUG: Diagnostic matches: DEFER",
" LOG.info(",
" (Marker) null,",
" String.format(\"With marker, throwable and format string: %s\", nonFinalLocal),",
" new RuntimeException());",
" }",
"}")
.doTest();
}
@Test
void replacement() {
BugCheckerRefactoringTestHelper.newInstance(EagerStringFormatting.class, getClass())
.addInputLines(
"A.java",
"import static com.google.common.base.Preconditions.checkArgument;",
"import static com.google.common.base.Preconditions.checkNotNull;",
"import static com.google.common.base.Preconditions.checkState;",
"import static com.google.common.base.Verify.verify;",
"import static com.google.common.base.Verify.verifyNotNull;",
"import static java.util.Objects.requireNonNull;",
"",
"import java.util.Locale;",
"import org.slf4j.Logger;",
"import org.slf4j.LoggerFactory;",
"import org.slf4j.Marker;",
"",
"class A {",
" private static final Logger LOG = LoggerFactory.getLogger(A.class);",
" private static final String GUAVA_COMPATIBLE_PATTERN = \"with-only-%s-placeholder\";",
" private static final String GUAVA_INCOMPATIBLE_PATTERN = \"with-%%-marker\";",
"",
" void m() {",
" requireNonNull(\"never-null\", String.format(\"Format string: %s\", 0));",
"",
" checkArgument(true, String.format(\"Vacuous format string %%\"));",
" checkNotNull(\"never-null\", \"Format string: %s %s%%\".formatted(1, 2));",
" checkState(false, String.format(Locale.US, \"Format string with locale: %s\", 3));",
" verify(true, GUAVA_COMPATIBLE_PATTERN.formatted(4));",
" verifyNotNull(\"never-null\", String.format(Locale.ENGLISH, GUAVA_COMPATIBLE_PATTERN, 5));",
" checkArgument(false, GUAVA_INCOMPATIBLE_PATTERN.formatted());",
" checkNotNull(\"never-null\", String.format(GUAVA_INCOMPATIBLE_PATTERN));",
"",
" LOG.trace(\"Vacuous format string %%\".formatted());",
" LOG.debug(String.format(\"With format string: %s, %s%%\", 6, 7));",
" LOG.info(String.format(Locale.ROOT, \"With vacuous localized format string %%\"));",
" LOG.warn((Marker) null, \"With marker and format string: %s\".formatted(8));",
" LOG.error(",
" String.format(Locale.US, \"With throwable and format string: %s, %s\", 9, 10),",
" new RuntimeException());",
" LOG.trace(",
" (Marker) null,",
" \"With marker, throwable and format string: %s\".formatted(11),",
" new RuntimeException());",
" LOG.debug(GUAVA_COMPATIBLE_PATTERN.formatted(12));",
" LOG.info(String.format(Locale.ENGLISH, GUAVA_COMPATIBLE_PATTERN, 13));",
" LOG.warn(GUAVA_INCOMPATIBLE_PATTERN.formatted());",
" LOG.error(String.format(GUAVA_INCOMPATIBLE_PATTERN));",
" }",
"}")
.addOutputLines(
"A.java",
"import static com.google.common.base.Preconditions.checkArgument;",
"import static com.google.common.base.Preconditions.checkNotNull;",
"import static com.google.common.base.Preconditions.checkState;",
"import static com.google.common.base.Verify.verify;",
"import static com.google.common.base.Verify.verifyNotNull;",
"import static java.util.Objects.requireNonNull;",
"",
"import java.util.Locale;",
"import org.slf4j.Logger;",
"import org.slf4j.LoggerFactory;",
"import org.slf4j.Marker;",
"",
"class A {",
" private static final Logger LOG = LoggerFactory.getLogger(A.class);",
" private static final String GUAVA_COMPATIBLE_PATTERN = \"with-only-%s-placeholder\";",
" private static final String GUAVA_INCOMPATIBLE_PATTERN = \"with-%%-marker\";",
"",
" void m() {",
" requireNonNull(\"never-null\", () -> String.format(\"Format string: %s\", 0));",
"",
" checkArgument(true, \"Vacuous format string %\");",
" checkNotNull(\"never-null\", \"Format string: %s %s%\", 1, 2);",
" checkState(false, \"Format string with locale: %s\", 3);",
" verify(true, GUAVA_COMPATIBLE_PATTERN, 4);",
" verifyNotNull(\"never-null\", GUAVA_COMPATIBLE_PATTERN, 5);",
" checkArgument(false, \"with-%-marker\");",
" checkNotNull(\"never-null\", \"with-%-marker\");",
"",
" LOG.trace(\"Vacuous format string %\");",
" LOG.debug(\"With format string: {}, {}%\", 6, 7);",
" LOG.info(\"With vacuous localized format string %\");",
" LOG.warn((Marker) null, \"With marker and format string: {}\", 8);",
" LOG.error(\"With throwable and format string: {}, {}\", 9, 10, new RuntimeException());",
" LOG.trace(",
" (Marker) null, \"With marker, throwable and format string: {}\", 11, new RuntimeException());",
" LOG.debug(\"with-only-{}-placeholder\", 12);",
" LOG.info(\"with-only-{}-placeholder\", 13);",
" LOG.warn(\"with-%-marker\");",
" LOG.error(\"with-%-marker\");",
" }",
"}")
.doTest(TestMode.TEXT_MATCH);
}
}

View File

@@ -16,8 +16,6 @@ final class ExplicitArgumentEnumerationTest {
"import com.google.common.collect.ImmutableList;",
"import com.google.errorprone.CompilationTestHelper;",
"import com.google.errorprone.bugpatterns.BugChecker;",
"import io.micrometer.core.instrument.Counter;",
"import io.micrometer.core.instrument.Tag;",
"import org.jooq.impl.DSL;",
"import reactor.core.publisher.Flux;",
"import reactor.test.StepVerifier;",
@@ -34,8 +32,6 @@ final class ExplicitArgumentEnumerationTest {
"",
" DSL.row(ImmutableList.of(1, 2));",
"",
" Counter.builder(\"foo\").tags(ImmutableList.of(Tag.of(\"bar\", \"baz\")));",
"",
" // BUG: Diagnostic contains:",
" unaryMethod(ImmutableList.of(1, 2));",
" unaryMethodWithLessVisibleOverload(ImmutableList.of(1, 2));",

View File

@@ -55,10 +55,6 @@ final class NonStaticImportTest {
"// BUG: Diagnostic contains:",
"import static java.time.Instant.MIN;",
"// BUG: Diagnostic contains:",
"import static java.time.InstantSource.system;",
"// BUG: Diagnostic contains:",
"import static java.time.LocalDate.EPOCH;",
"// BUG: Diagnostic contains:",
"import static java.time.ZoneOffset.SHORT_IDS;",
"import static java.time.ZoneOffset.UTC;",
"// BUG: Diagnostic contains:",
@@ -75,7 +71,6 @@ final class NonStaticImportTest {
"import com.google.common.collect.ImmutableList;",
"import com.google.common.collect.ImmutableSet;",
"import java.time.Instant;",
"import java.time.LocalDate;",
"import java.time.ZoneOffset;",
"import java.util.Locale;",
"import java.util.Map;",
@@ -87,10 +82,8 @@ final class NonStaticImportTest {
" void m() {",
" nullToEmpty(null);",
" copyOf(ImmutableList.of());",
" LocalDate epoch = EPOCH;",
" int max = MAX_VALUE;",
" int min = MIN_VALUE;",
" system();",
" systemUTC();",
" Instant minInstant = MIN;",
" Map<String, String> shortIds = SHORT_IDS;",

View File

@@ -21,7 +21,6 @@ final class TimeZoneUsageTest {
"import java.time.OffsetTime;",
"import java.time.ZoneId;",
"import java.time.ZonedDateTime;",
"import reactor.core.publisher.Mono;",
"",
"class A {",
" void m() {",
@@ -32,122 +31,68 @@ final class TimeZoneUsageTest {
" Clock.tick(clock, Duration.ZERO);",
"",
" // BUG: Diagnostic contains:",
" clock.getZone();",
" // BUG: Diagnostic contains:",
" Mono.fromSupplier(clock::getZone);",
" // BUG: Diagnostic contains:",
" clock.withZone(UTC);",
" // BUG: Diagnostic contains:",
" Mono.<ZoneId>empty().map(clock::withZone);",
" // BUG: Diagnostic contains:",
" Clock.system(UTC);",
" // BUG: Diagnostic contains:",
" Mono.<ZoneId>empty().map(Clock::system);",
" Clock.systemUTC();",
" // BUG: Diagnostic contains:",
" Clock.systemDefaultZone();",
" // BUG: Diagnostic contains:",
" Mono.fromSupplier(Clock::systemDefaultZone);",
" // BUG: Diagnostic contains:",
" Clock.systemUTC();",
" // BUG: Diagnostic contains:",
" Mono.fromSupplier(Clock::systemUTC);",
" Clock.system(UTC);",
" // BUG: Diagnostic contains:",
" Clock.tickMillis(UTC);",
" // BUG: Diagnostic contains:",
" Mono.<ZoneId>empty().map(Clock::tickMillis);",
" // BUG: Diagnostic contains:",
" Clock.tickMinutes(UTC);",
" // BUG: Diagnostic contains:",
" Mono.<ZoneId>empty().map(Clock::tickMinutes);",
" // BUG: Diagnostic contains:",
" Clock.tickSeconds(UTC);",
" // BUG: Diagnostic contains:",
" Mono.<ZoneId>empty().map(Clock::tickSeconds);",
" clock.getZone();",
" // BUG: Diagnostic contains:",
" clock.withZone(UTC);",
"",
" Instant.now(clock);",
" Mono.<Clock>empty().map(Instant::now);",
" // BUG: Diagnostic contains:",
" Instant.now();",
" // BUG: Diagnostic contains:",
" Mono.fromSupplier(Instant::now);",
" // This is equivalent to `clock.instant()`, which is fine.",
" Instant.now(clock);",
"",
" // BUG: Diagnostic contains:",
" LocalDate.now();",
" // BUG: Diagnostic contains:",
" Mono.fromSupplier(LocalDate::now);",
" // BUG: Diagnostic contains:",
" LocalDate.now(clock);",
" // BUG: Diagnostic contains:",
" Mono.<Clock>empty().map(LocalDate::now);",
" // BUG: Diagnostic contains:",
" LocalDate.now(UTC);",
" // BUG: Diagnostic contains:",
" Mono.<ZoneId>empty().map(LocalDate::now);",
"",
" // BUG: Diagnostic contains:",
" LocalDateTime.now();",
" // BUG: Diagnostic contains:",
" Mono.fromSupplier(LocalDateTime::now);",
" // BUG: Diagnostic contains:",
" LocalDateTime.now(clock);",
" // BUG: Diagnostic contains:",
" Mono.<Clock>empty().map(LocalDateTime::now);",
" // BUG: Diagnostic contains:",
" LocalDateTime.now(UTC);",
" // BUG: Diagnostic contains:",
" Mono.<ZoneId>empty().map(LocalDateTime::now);",
"",
" // BUG: Diagnostic contains:",
" LocalTime.now();",
" // BUG: Diagnostic contains:",
" Mono.fromSupplier(LocalTime::now);",
" // BUG: Diagnostic contains:",
" LocalTime.now(clock);",
" // BUG: Diagnostic contains:",
" Mono.<Clock>empty().map(LocalTime::now);",
" // BUG: Diagnostic contains:",
" LocalTime.now(UTC);",
" // BUG: Diagnostic contains:",
" Mono.<ZoneId>empty().map(LocalTime::now);",
"",
" // BUG: Diagnostic contains:",
" OffsetDateTime.now();",
" // BUG: Diagnostic contains:",
" Mono.fromSupplier(OffsetDateTime::now);",
" // BUG: Diagnostic contains:",
" OffsetDateTime.now(clock);",
" // BUG: Diagnostic contains:",
" Mono.<Clock>empty().map(OffsetDateTime::now);",
" // BUG: Diagnostic contains:",
" OffsetDateTime.now(UTC);",
" // BUG: Diagnostic contains:",
" Mono.<ZoneId>empty().map(OffsetDateTime::now);",
"",
" // BUG: Diagnostic contains:",
" OffsetTime.now();",
" // BUG: Diagnostic contains:",
" Mono.fromSupplier(OffsetTime::now);",
" // BUG: Diagnostic contains:",
" OffsetTime.now(clock);",
" // BUG: Diagnostic contains:",
" Mono.<Clock>empty().map(OffsetTime::now);",
" // BUG: Diagnostic contains:",
" OffsetTime.now(UTC);",
" // BUG: Diagnostic contains:",
" Mono.<ZoneId>empty().map(OffsetTime::now);",
"",
" // BUG: Diagnostic contains:",
" ZonedDateTime.now();",
" // BUG: Diagnostic contains:",
" Mono.fromSupplier(ZonedDateTime::now);",
" // BUG: Diagnostic contains:",
" ZonedDateTime.now(clock);",
" // BUG: Diagnostic contains:",
" Mono.<Clock>empty().map(ZonedDateTime::now);",
" // BUG: Diagnostic contains:",
" ZonedDateTime.now(UTC);",
" // BUG: Diagnostic contains:",
" Mono.<ZoneId>empty().map(ZonedDateTime::now);",
" }",
"",
" abstract class ForwardingClock extends Clock {",

View File

@@ -23,8 +23,6 @@ final class RefasterRulesTest {
AssertJEnumerableRules.class,
AssertJFloatRules.class,
AssertJIntegerRules.class,
AssertJIterableRules.class,
AssertJIteratorRules.class,
AssertJLongRules.class,
AssertJMapRules.class,
AssertJNumberRules.class,
@@ -45,6 +43,7 @@ final class RefasterRulesTest {
DoubleStreamRules.class,
EqualityRules.class,
FileRules.class,
InputStreamRules.class,
ImmutableEnumSetRules.class,
ImmutableListRules.class,
ImmutableListMultimapRules.class,
@@ -55,8 +54,6 @@ final class RefasterRulesTest {
ImmutableSortedMapRules.class,
ImmutableSortedMultisetRules.class,
ImmutableSortedSetRules.class,
ImmutableTableRules.class,
InputStreamRules.class,
IntStreamRules.class,
JUnitRules.class,
JUnitToAssertJRules.class,

View File

@@ -8,16 +8,13 @@ import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
final class AssertJCharSequenceRulesTest implements RefasterRuleCollectionTestCase {
void testAssertThatCharSequenceIsEmpty() {
assertThat("foo".isEmpty()).isTrue();
assertThat("bar".length()).isEqualTo(0L);
assertThat("baz".length()).isNotPositive();
assertThat("foo".length()).isEqualTo(0L);
assertThat("foo".length()).isNotPositive();
}
ImmutableSet<AbstractAssert<?, ?>> testAssertThatCharSequenceIsNotEmpty() {
return ImmutableSet.of(
assertThat("foo".isEmpty()).isFalse(),
assertThat("bar".length()).isNotEqualTo(0),
assertThat("baz".length()).isPositive());
assertThat("foo".length()).isNotEqualTo(0), assertThat("bar".length()).isPositive());
}
AbstractAssert<?, ?> testAssertThatCharSequenceHasSize() {

View File

@@ -9,15 +9,11 @@ import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
final class AssertJCharSequenceRulesTest implements RefasterRuleCollectionTestCase {
void testAssertThatCharSequenceIsEmpty() {
assertThat("foo").isEmpty();
assertThat("bar").isEmpty();
assertThat("baz").isEmpty();
assertThat("foo").isEmpty();
}
ImmutableSet<AbstractAssert<?, ?>> testAssertThatCharSequenceIsNotEmpty() {
return ImmutableSet.of(
assertThat("foo").isNotEmpty(),
assertThat("bar").isNotEmpty(),
assertThat("baz").isNotEmpty());
return ImmutableSet.of(assertThat("foo").isNotEmpty(), assertThat("bar").isNotEmpty());
}
AbstractAssert<?, ?> testAssertThatCharSequenceHasSize() {

View File

@@ -4,7 +4,6 @@ import static org.assertj.core.api.Assertions.assertThat;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import org.assertj.core.api.AbstractAssert;
import org.assertj.core.api.EnumerableAssert;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
@@ -15,63 +14,20 @@ final class AssertJEnumerableRulesTest implements RefasterRuleCollectionTestCase
}
void testEnumerableAssertIsEmpty() {
assertThat(ImmutableSet.of(1)).hasSize(0);
assertThat(ImmutableSet.of(2)).hasSizeLessThanOrEqualTo(0);
assertThat(ImmutableSet.of(3)).hasSizeLessThan(1);
assertThat(ImmutableSet.of(4)).size().isNotPositive();
assertThat(ImmutableSet.of()).hasSize(0);
assertThat(ImmutableSet.of()).hasSizeLessThanOrEqualTo(0);
assertThat(ImmutableSet.of()).hasSizeLessThan(1);
}
ImmutableSet<AbstractAssert<?, ?>> testEnumerableAssertIsNotEmpty() {
ImmutableSet<EnumerableAssert<?, Character>> testEnumerableAssertIsNotEmpty() {
return ImmutableSet.of(
assertThat(ImmutableSet.of(1)).hasSizeGreaterThan(0),
assertThat(ImmutableSet.of(2)).hasSizeGreaterThanOrEqualTo(1),
assertThat(ImmutableSet.of(3)).size().isNotEqualTo(0).returnToIterable(),
assertThat(ImmutableSet.of(4)).size().isPositive().returnToIterable(),
assertThat(ImmutableSet.of(5)).size().isNotEqualTo(0),
assertThat(ImmutableSet.of(6)).size().isPositive());
assertThat("foo").hasSizeGreaterThan(0), assertThat("bar").hasSizeGreaterThanOrEqualTo(1));
}
ImmutableSet<AbstractAssert<?, ?>> testEnumerableAssertHasSize() {
ImmutableSet<EnumerableAssert<?, Integer>> testEnumerableAssertHasSameSizeAs() {
return ImmutableSet.of(
assertThat(ImmutableSet.of(1)).size().isEqualTo(2).returnToIterable(),
assertThat(ImmutableSet.of(3)).size().isEqualTo(4));
}
ImmutableSet<AbstractAssert<?, ?>> testEnumerableAssertHasSizeLessThan() {
return ImmutableSet.of(
assertThat(ImmutableSet.of(1)).size().isLessThan(2).returnToIterable(),
assertThat(ImmutableSet.of(3)).size().isLessThan(4));
}
ImmutableSet<AbstractAssert<?, ?>> testEnumerableAssertHasSizeLessThanOrEqualTo() {
return ImmutableSet.of(
assertThat(ImmutableSet.of(1)).size().isLessThanOrEqualTo(2).returnToIterable(),
assertThat(ImmutableSet.of(3)).size().isLessThanOrEqualTo(4));
}
ImmutableSet<AbstractAssert<?, ?>> testEnumerableAssertHasSizeGreaterThan() {
return ImmutableSet.of(
assertThat(ImmutableSet.of(1)).size().isGreaterThan(2).returnToIterable(),
assertThat(ImmutableSet.of(3)).size().isGreaterThan(4));
}
ImmutableSet<AbstractAssert<?, ?>> testEnumerableAssertHasSizeGreaterThanOrEqualTo() {
return ImmutableSet.of(
assertThat(ImmutableSet.of(1)).size().isGreaterThanOrEqualTo(2).returnToIterable(),
assertThat(ImmutableSet.of(3)).size().isGreaterThanOrEqualTo(4));
}
ImmutableSet<AbstractAssert<?, ?>> testEnumerableAssertHasSizeBetween() {
return ImmutableSet.of(
assertThat(ImmutableSet.of(1)).size().isBetween(2, 3).returnToIterable(),
assertThat(ImmutableSet.of(4)).size().isBetween(5, 6));
}
ImmutableSet<EnumerableAssert<?, Character>> testEnumerableAssertHasSameSizeAs() {
return ImmutableSet.of(
assertThat("foo").hasSize(Iterables.size(ImmutableSet.of(1))),
assertThat("bar").hasSize(ImmutableSet.of(2).size()),
assertThat("baz").hasSize(new Integer[0].length),
assertThat("qux").hasSize("quux".length()));
assertThat(ImmutableSet.of(1)).hasSize(Iterables.size(ImmutableSet.of(2))),
assertThat(ImmutableSet.of(3)).hasSize(ImmutableSet.of(4).size()),
assertThat(ImmutableSet.of(5)).hasSize(new Integer[0].length));
}
}

View File

@@ -4,7 +4,6 @@ import static org.assertj.core.api.Assertions.assertThat;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import org.assertj.core.api.AbstractAssert;
import org.assertj.core.api.EnumerableAssert;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
@@ -15,62 +14,19 @@ final class AssertJEnumerableRulesTest implements RefasterRuleCollectionTestCase
}
void testEnumerableAssertIsEmpty() {
assertThat(ImmutableSet.of(1)).isEmpty();
assertThat(ImmutableSet.of(2)).isEmpty();
assertThat(ImmutableSet.of(3)).isEmpty();
assertThat(ImmutableSet.of(4)).isEmpty();
assertThat(ImmutableSet.of()).isEmpty();
assertThat(ImmutableSet.of()).isEmpty();
assertThat(ImmutableSet.of()).isEmpty();
}
ImmutableSet<AbstractAssert<?, ?>> testEnumerableAssertIsNotEmpty() {
return ImmutableSet.of(
assertThat(ImmutableSet.of(1)).isNotEmpty(),
assertThat(ImmutableSet.of(2)).isNotEmpty(),
assertThat(ImmutableSet.of(3)).isNotEmpty(),
assertThat(ImmutableSet.of(4)).isNotEmpty(),
assertThat(ImmutableSet.of(5)).isNotEmpty(),
assertThat(ImmutableSet.of(6)).isNotEmpty());
ImmutableSet<EnumerableAssert<?, Character>> testEnumerableAssertIsNotEmpty() {
return ImmutableSet.of(assertThat("foo").isNotEmpty(), assertThat("bar").isNotEmpty());
}
ImmutableSet<AbstractAssert<?, ?>> testEnumerableAssertHasSize() {
ImmutableSet<EnumerableAssert<?, Integer>> testEnumerableAssertHasSameSizeAs() {
return ImmutableSet.of(
assertThat(ImmutableSet.of(1)).hasSize(2), assertThat(ImmutableSet.of(3)).hasSize(4));
}
ImmutableSet<AbstractAssert<?, ?>> testEnumerableAssertHasSizeLessThan() {
return ImmutableSet.of(
assertThat(ImmutableSet.of(1)).hasSizeLessThan(2),
assertThat(ImmutableSet.of(3)).hasSizeLessThan(4));
}
ImmutableSet<AbstractAssert<?, ?>> testEnumerableAssertHasSizeLessThanOrEqualTo() {
return ImmutableSet.of(
assertThat(ImmutableSet.of(1)).hasSizeLessThanOrEqualTo(2),
assertThat(ImmutableSet.of(3)).hasSizeLessThanOrEqualTo(4));
}
ImmutableSet<AbstractAssert<?, ?>> testEnumerableAssertHasSizeGreaterThan() {
return ImmutableSet.of(
assertThat(ImmutableSet.of(1)).hasSizeGreaterThan(2),
assertThat(ImmutableSet.of(3)).hasSizeGreaterThan(4));
}
ImmutableSet<AbstractAssert<?, ?>> testEnumerableAssertHasSizeGreaterThanOrEqualTo() {
return ImmutableSet.of(
assertThat(ImmutableSet.of(1)).hasSizeGreaterThanOrEqualTo(2),
assertThat(ImmutableSet.of(3)).hasSizeGreaterThanOrEqualTo(4));
}
ImmutableSet<AbstractAssert<?, ?>> testEnumerableAssertHasSizeBetween() {
return ImmutableSet.of(
assertThat(ImmutableSet.of(1)).hasSizeBetween(2, 3),
assertThat(ImmutableSet.of(4)).hasSizeBetween(5, 6));
}
ImmutableSet<EnumerableAssert<?, Character>> testEnumerableAssertHasSameSizeAs() {
return ImmutableSet.of(
assertThat("foo").hasSameSizeAs(ImmutableSet.of(1)),
assertThat("bar").hasSameSizeAs(ImmutableSet.of(2)),
assertThat("baz").hasSameSizeAs(new Integer[0]),
assertThat("qux").hasSameSizeAs("quux"));
assertThat(ImmutableSet.of(1)).hasSameSizeAs(ImmutableSet.of(2)),
assertThat(ImmutableSet.of(3)).hasSameSizeAs(ImmutableSet.of(4)),
assertThat(ImmutableSet.of(5)).hasSameSizeAs(new Integer[0]));
}
}

View File

@@ -1,35 +0,0 @@
package tech.picnic.errorprone.refasterrules;
import static org.assertj.core.api.Assertions.assertThat;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import org.assertj.core.api.AbstractAssert;
import org.assertj.core.api.AbstractIntegerAssert;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
final class AssertJIterableRulesTest implements RefasterRuleCollectionTestCase {
public ImmutableSet<Object> elidedTypesAndStaticImports() {
return ImmutableSet.of(Iterables.class);
}
void testAssertThatIterableIsEmpty() {
assertThat(ImmutableSet.of(1).iterator()).isExhausted();
assertThat(ImmutableSet.of(2).isEmpty()).isTrue();
}
ImmutableSet<AbstractAssert<?, ?>> testAssertThatIterableIsNotEmpty() {
return ImmutableSet.of(
assertThat(ImmutableSet.of(1).iterator()).hasNext(),
assertThat(ImmutableSet.of(2).isEmpty()).isFalse());
}
ImmutableSet<AbstractIntegerAssert<?>> testAssertThatIterableSize() {
return ImmutableSet.of(
assertThat(Iterables.size(ImmutableSet.of(1))), assertThat(ImmutableSet.of(2).size()));
}
AbstractAssert<?, ?> testAssertThatIterableHasOneElementEqualTo() {
return assertThat(Iterables.getOnlyElement(ImmutableSet.of(new Object()))).isEqualTo("foo");
}
}

View File

@@ -1,34 +0,0 @@
package tech.picnic.errorprone.refasterrules;
import static org.assertj.core.api.Assertions.assertThat;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import org.assertj.core.api.AbstractAssert;
import org.assertj.core.api.AbstractIntegerAssert;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
final class AssertJIterableRulesTest implements RefasterRuleCollectionTestCase {
public ImmutableSet<Object> elidedTypesAndStaticImports() {
return ImmutableSet.of(Iterables.class);
}
void testAssertThatIterableIsEmpty() {
assertThat(ImmutableSet.of(1)).isEmpty();
assertThat(ImmutableSet.of(2)).isEmpty();
}
ImmutableSet<AbstractAssert<?, ?>> testAssertThatIterableIsNotEmpty() {
return ImmutableSet.of(
assertThat(ImmutableSet.of(1)).isNotEmpty(), assertThat(ImmutableSet.of(2)).isNotEmpty());
}
ImmutableSet<AbstractIntegerAssert<?>> testAssertThatIterableSize() {
return ImmutableSet.of(
assertThat(ImmutableSet.of(1)).size(), assertThat(ImmutableSet.of(2)).size());
}
AbstractAssert<?, ?> testAssertThatIterableHasOneElementEqualTo() {
return assertThat(ImmutableSet.of(new Object())).containsExactly("foo");
}
}

View File

@@ -1,17 +0,0 @@
package tech.picnic.errorprone.refasterrules;
import static org.assertj.core.api.Assertions.assertThat;
import com.google.common.collect.ImmutableSet;
import org.assertj.core.api.AbstractAssert;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
final class AssertJIteratorRulesTest implements RefasterRuleCollectionTestCase {
AbstractAssert<?, ?> testAssertThatHasNext() {
return assertThat(ImmutableSet.of().iterator().hasNext()).isTrue();
}
AbstractAssert<?, ?> testAssertThatIsExhausted() {
return assertThat(ImmutableSet.of().iterator().hasNext()).isFalse();
}
}

View File

@@ -1,17 +0,0 @@
package tech.picnic.errorprone.refasterrules;
import static org.assertj.core.api.Assertions.assertThat;
import com.google.common.collect.ImmutableSet;
import org.assertj.core.api.AbstractAssert;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
final class AssertJIteratorRulesTest implements RefasterRuleCollectionTestCase {
AbstractAssert<?, ?> testAssertThatHasNext() {
return assertThat(ImmutableSet.of().iterator()).hasNext();
}
AbstractAssert<?, ?> testAssertThatIsExhausted() {
return assertThat(ImmutableSet.of().iterator()).isExhausted();
}
}

View File

@@ -21,10 +21,18 @@ final class AssertJStringRulesTest implements RefasterRuleCollectionTestCase {
assertThat("foo").isEqualTo("");
}
void testAssertThatStringIsEmpty() {
assertThat("foo".isEmpty()).isTrue();
}
AbstractStringAssert<?> testAbstractStringAssertStringIsNotEmpty() {
return assertThat("foo").isNotEqualTo("");
}
AbstractAssert<?, ?> testAssertThatStringIsNotEmpty() {
return assertThat("foo".isEmpty()).isFalse();
}
AbstractAssert<?, ?> testAssertThatStringContains() {
return assertThat("foo".contains("bar")).isTrue();
}

View File

@@ -22,10 +22,18 @@ final class AssertJStringRulesTest implements RefasterRuleCollectionTestCase {
assertThat("foo").isEmpty();
}
void testAssertThatStringIsEmpty() {
assertThat("foo").isEmpty();
}
AbstractStringAssert<?> testAbstractStringAssertStringIsNotEmpty() {
return assertThat("foo").isNotEmpty();
}
AbstractAssert<?, ?> testAssertThatStringIsNotEmpty() {
return assertThat("foo").isNotEmpty();
}
AbstractAssert<?, ?> testAssertThatStringContains() {
return assertThat("foo").contains("bar");
}

View File

@@ -62,7 +62,7 @@ final class CollectionRulesTest implements RefasterRuleCollectionTestCase {
return Iterables.removeAll(new ArrayList<>(), ImmutableSet.of("foo"));
}
void testCollectionRemoveAllFromCollectionBlock() {
void testSetRemoveAllCollection() {
ImmutableSet.of("foo").forEach(new HashSet<>()::remove);
for (Number element : ImmutableList.of(1)) {
new HashSet<Number>().remove(element);

View File

@@ -58,7 +58,7 @@ final class CollectionRulesTest implements RefasterRuleCollectionTestCase {
return new ArrayList<>().removeAll(ImmutableSet.of("foo"));
}
void testCollectionRemoveAllFromCollectionBlock() {
void testSetRemoveAllCollection() {
new HashSet<>().removeAll(ImmutableSet.of("foo"));
new HashSet<Number>().removeAll(ImmutableList.of(1));
new HashSet<Number>().removeAll(ImmutableSet.of(2));

View File

@@ -39,16 +39,4 @@ final class FileRulesTest implements RefasterRuleCollectionTestCase {
File testFilesCreateTempFileInCustomDirectoryToFile() throws IOException {
return File.createTempFile("foo", "bar", new File("baz"));
}
ImmutableSet<Boolean> testPathToFileMkDirsFilesExists() {
return ImmutableSet.of(
Files.exists(Path.of("foo")) || Path.of("foo").toFile().mkdirs(),
!Files.exists(Path.of("bar")) && !Path.of("bar").toFile().mkdirs());
}
ImmutableSet<Boolean> testFileMkDirsFileExists() {
return ImmutableSet.of(
new File("foo").exists() || new File("foo").mkdirs(),
!new File("bar").exists() && !new File("bar").mkdirs());
}
}

View File

@@ -39,16 +39,4 @@ final class FileRulesTest implements RefasterRuleCollectionTestCase {
File testFilesCreateTempFileInCustomDirectoryToFile() throws IOException {
return Files.createTempFile(new File("baz").toPath(), "foo", "bar").toFile();
}
ImmutableSet<Boolean> testPathToFileMkDirsFilesExists() {
return ImmutableSet.of(
Path.of("foo").toFile().mkdirs() || Files.exists(Path.of("foo")),
!Path.of("bar").toFile().mkdirs() && !Files.exists(Path.of("bar")));
}
ImmutableSet<Boolean> testFileMkDirsFileExists() {
return ImmutableSet.of(
new File("foo").mkdirs() || new File("foo").exists(),
!new File("bar").mkdirs() && !new File("bar").exists());
}
}

View File

@@ -24,13 +24,9 @@ final class ImmutableMapRulesTest implements RefasterRuleCollectionTestCase {
return new ImmutableMap.Builder<>();
}
ImmutableMap<Object, Object> testImmutableMapBuilderBuildOrThrow() {
return ImmutableMap.builder().build();
}
ImmutableSet<ImmutableMap<String, Integer>> testEntryToImmutableMap() {
return ImmutableSet.of(
ImmutableMap.<String, Integer>builder().put(Map.entry("foo", 1)).buildOrThrow(),
ImmutableMap.<String, Integer>builder().put(Map.entry("foo", 1)).build(),
Stream.of(Map.entry("foo", 1))
.collect(toImmutableMap(Map.Entry::getKey, Map.Entry::getValue)));
}
@@ -55,14 +51,13 @@ final class ImmutableMapRulesTest implements RefasterRuleCollectionTestCase {
ImmutableMap.copyOf(Maps.asMap(ImmutableSet.of(10), Integer::valueOf)));
}
ImmutableSet<Map<String, Integer>> testEntryIterableToImmutableMap() {
ImmutableSet<ImmutableMap<String, Integer>> testEntryIterableToImmutableMap() {
return ImmutableSet.of(
ImmutableMap.copyOf(ImmutableMap.of("foo", 1).entrySet()),
ImmutableMap.<String, Integer>builder().putAll(ImmutableMap.of("foo", 1)).buildOrThrow(),
Map.copyOf(ImmutableMap.of("foo", 1)),
ImmutableMap.<String, Integer>builder().putAll(ImmutableMap.of("foo", 1)).build(),
ImmutableMap.<String, Integer>builder()
.putAll(ImmutableMap.of("foo", 1).entrySet())
.buildOrThrow(),
.build(),
ImmutableMap.of("foo", 1).entrySet().stream()
.collect(toImmutableMap(Map.Entry::getKey, Map.Entry::getValue)),
Streams.stream(Iterables.cycle(Map.entry("foo", 1)))
@@ -105,51 +100,32 @@ final class ImmutableMapRulesTest implements RefasterRuleCollectionTestCase {
ImmutableSet<Map<String, String>> testImmutableMapOf() {
return ImmutableSet.of(
ImmutableMap.<String, String>builder().buildOrThrow(),
ImmutableMap.ofEntries(),
ImmutableMap.<String, String>builder().build(),
Collections.<String, String>emptyMap(),
Map.<String, String>of());
}
ImmutableSet<Map<String, String>> testImmutableMapOf1() {
return ImmutableSet.of(
ImmutableMap.<String, String>builder().put("k1", "v1").buildOrThrow(),
ImmutableMap.ofEntries(Map.entry("k1", "v1")),
ImmutableMap.<String, String>builder().put("k1", "v1").build(),
Collections.singletonMap("k1", "v1"),
Map.of("k1", "v1"));
}
ImmutableSet<Map<String, String>> testImmutableMapOf2() {
return ImmutableSet.of(
ImmutableMap.ofEntries(Map.entry("k1", "v1"), Map.entry("k2", "v2")),
Map.of("k1", "v1", "k2", "v2"));
Map<String, String> testImmutableMapOf2() {
return Map.of("k1", "v1", "k2", "v2");
}
ImmutableSet<Map<String, String>> testImmutableMapOf3() {
return ImmutableSet.of(
ImmutableMap.ofEntries(Map.entry("k1", "v1"), Map.entry("k2", "v2"), Map.entry("k3", "v3")),
Map.of("k1", "v1", "k2", "v2", "k3", "v3"));
Map<String, String> testImmutableMapOf3() {
return Map.of("k1", "v1", "k2", "v2", "k3", "v3");
}
ImmutableSet<Map<String, String>> testImmutableMapOf4() {
return ImmutableSet.of(
ImmutableMap.ofEntries(
Map.entry("k1", "v1"),
Map.entry("k2", "v2"),
Map.entry("k3", "v3"),
Map.entry("k4", "v4")),
Map.of("k1", "v1", "k2", "v2", "k3", "v3", "k4", "v4"));
Map<String, String> testImmutableMapOf4() {
return Map.of("k1", "v1", "k2", "v2", "k3", "v3", "k4", "v4");
}
ImmutableSet<Map<String, String>> testImmutableMapOf5() {
return ImmutableSet.of(
ImmutableMap.ofEntries(
Map.entry("k1", "v1"),
Map.entry("k2", "v2"),
Map.entry("k3", "v3"),
Map.entry("k4", "v4"),
Map.entry("k5", "v5")),
Map.of("k1", "v1", "k2", "v2", "k3", "v3", "k4", "v4", "k5", "v5"));
Map<String, String> testImmutableMapOf5() {
return Map.of("k1", "v1", "k2", "v2", "k3", "v3", "k4", "v4", "k5", "v5");
}
ImmutableMap<String, Integer> testImmutableMapCopyOfMapsFilterKeys() {
@@ -163,11 +139,4 @@ final class ImmutableMapRulesTest implements RefasterRuleCollectionTestCase {
.filter(entry -> entry.getValue() > 0)
.collect(toImmutableMap(Map.Entry::getKey, Map.Entry::getValue));
}
ImmutableSet<Map<String, Integer>> testImmutableMapOfEntries() {
return ImmutableSet.of(
Map.ofEntries(),
Map.ofEntries(Map.entry("foo", 1)),
Map.ofEntries(Map.entry("bar", 2), Map.entry("baz", 3)));
}
}

View File

@@ -24,10 +24,6 @@ final class ImmutableMapRulesTest implements RefasterRuleCollectionTestCase {
return ImmutableMap.builder();
}
ImmutableMap<Object, Object> testImmutableMapBuilderBuildOrThrow() {
return ImmutableMap.builder().buildOrThrow();
}
ImmutableSet<ImmutableMap<String, Integer>> testEntryToImmutableMap() {
return ImmutableSet.of(
ImmutableMap.of(Map.entry("foo", 1).getKey(), Map.entry("foo", 1).getValue()),
@@ -50,9 +46,8 @@ final class ImmutableMapRulesTest implements RefasterRuleCollectionTestCase {
Maps.toMap(ImmutableSet.of(10), Integer::valueOf));
}
ImmutableSet<Map<String, Integer>> testEntryIterableToImmutableMap() {
ImmutableSet<ImmutableMap<String, Integer>> testEntryIterableToImmutableMap() {
return ImmutableSet.of(
ImmutableMap.copyOf(ImmutableMap.of("foo", 1)),
ImmutableMap.copyOf(ImmutableMap.of("foo", 1)),
ImmutableMap.copyOf(ImmutableMap.of("foo", 1)),
ImmutableMap.copyOf(ImmutableMap.of("foo", 1).entrySet()),
@@ -88,39 +83,28 @@ final class ImmutableMapRulesTest implements RefasterRuleCollectionTestCase {
}
ImmutableSet<Map<String, String>> testImmutableMapOf() {
return ImmutableSet.of(
ImmutableMap.of(), ImmutableMap.of(), ImmutableMap.of(), ImmutableMap.of());
return ImmutableSet.of(ImmutableMap.of(), ImmutableMap.of(), ImmutableMap.of());
}
ImmutableSet<Map<String, String>> testImmutableMapOf1() {
return ImmutableSet.of(
ImmutableMap.of("k1", "v1"),
ImmutableMap.of("k1", "v1"),
ImmutableMap.of("k1", "v1"),
ImmutableMap.of("k1", "v1"));
ImmutableMap.of("k1", "v1"), ImmutableMap.of("k1", "v1"), ImmutableMap.of("k1", "v1"));
}
ImmutableSet<Map<String, String>> testImmutableMapOf2() {
return ImmutableSet.of(
ImmutableMap.of("k1", "v1", "k2", "v2"), ImmutableMap.of("k1", "v1", "k2", "v2"));
Map<String, String> testImmutableMapOf2() {
return ImmutableMap.of("k1", "v1", "k2", "v2");
}
ImmutableSet<Map<String, String>> testImmutableMapOf3() {
return ImmutableSet.of(
ImmutableMap.of("k1", "v1", "k2", "v2", "k3", "v3"),
ImmutableMap.of("k1", "v1", "k2", "v2", "k3", "v3"));
Map<String, String> testImmutableMapOf3() {
return ImmutableMap.of("k1", "v1", "k2", "v2", "k3", "v3");
}
ImmutableSet<Map<String, String>> testImmutableMapOf4() {
return ImmutableSet.of(
ImmutableMap.of("k1", "v1", "k2", "v2", "k3", "v3", "k4", "v4"),
ImmutableMap.of("k1", "v1", "k2", "v2", "k3", "v3", "k4", "v4"));
Map<String, String> testImmutableMapOf4() {
return ImmutableMap.of("k1", "v1", "k2", "v2", "k3", "v3", "k4", "v4");
}
ImmutableSet<Map<String, String>> testImmutableMapOf5() {
return ImmutableSet.of(
ImmutableMap.of("k1", "v1", "k2", "v2", "k3", "v3", "k4", "v4", "k5", "v5"),
ImmutableMap.of("k1", "v1", "k2", "v2", "k3", "v3", "k4", "v4", "k5", "v5"));
Map<String, String> testImmutableMapOf5() {
return ImmutableMap.of("k1", "v1", "k2", "v2", "k3", "v3", "k4", "v4", "k5", "v5");
}
ImmutableMap<String, Integer> testImmutableMapCopyOfMapsFilterKeys() {
@@ -130,11 +114,4 @@ final class ImmutableMapRulesTest implements RefasterRuleCollectionTestCase {
ImmutableMap<String, Integer> testImmutableMapCopyOfMapsFilterValues() {
return ImmutableMap.copyOf(Maps.filterValues(ImmutableMap.of("foo", 1), v -> v > 0));
}
ImmutableSet<Map<String, Integer>> testImmutableMapOfEntries() {
return ImmutableSet.of(
ImmutableMap.ofEntries(),
ImmutableMap.ofEntries(Map.entry("foo", 1)),
ImmutableMap.ofEntries(Map.entry("bar", 2), Map.entry("baz", 3)));
}
}

View File

@@ -32,16 +32,16 @@ final class ImmutableSortedMapRulesTest implements RefasterRuleCollectionTestCas
}
ImmutableSortedMap<String, Integer> testEmptyImmutableSortedMap() {
return ImmutableSortedMap.<String, Integer>naturalOrder().buildOrThrow();
return ImmutableSortedMap.<String, Integer>naturalOrder().build();
}
ImmutableSortedMap<String, Integer> testPairToImmutableSortedMap() {
return ImmutableSortedMap.<String, Integer>naturalOrder().put("foo", 1).buildOrThrow();
return ImmutableSortedMap.<String, Integer>naturalOrder().put("foo", 1).build();
}
ImmutableSet<ImmutableSortedMap<String, Integer>> testEntryToImmutableSortedMap() {
return ImmutableSet.of(
ImmutableSortedMap.<String, Integer>naturalOrder().put(Map.entry("foo", 1)).buildOrThrow(),
ImmutableSortedMap.<String, Integer>naturalOrder().put(Map.entry("foo", 1)).build(),
Stream.of(Map.entry("foo", 1))
.collect(toImmutableSortedMap(naturalOrder(), Map.Entry::getKey, Map.Entry::getValue)));
}
@@ -52,10 +52,10 @@ final class ImmutableSortedMapRulesTest implements RefasterRuleCollectionTestCas
ImmutableSortedMap.copyOf(ImmutableSortedMap.of("foo", 1).entrySet()),
ImmutableSortedMap.<String, Integer>naturalOrder()
.putAll(ImmutableSortedMap.of("foo", 1))
.buildOrThrow(),
.build(),
ImmutableSortedMap.<String, Integer>naturalOrder()
.putAll(ImmutableSortedMap.of("foo", 1).entrySet())
.buildOrThrow(),
.build(),
ImmutableSortedMap.of("foo", 1).entrySet().stream()
.collect(toImmutableSortedMap(naturalOrder(), Map.Entry::getKey, Map.Entry::getValue)),
Streams.stream(Iterables.cycle(Map.entry("foo", 1)))

View File

@@ -1,48 +0,0 @@
package tech.picnic.errorprone.refasterrules;
import static com.google.common.collect.ImmutableTable.toImmutableTable;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableTable;
import com.google.common.collect.Table;
import com.google.common.collect.Tables;
import java.util.stream.Stream;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
final class ImmutableTableRulesTest implements RefasterRuleCollectionTestCase {
@Override
public ImmutableSet<Object> elidedTypesAndStaticImports() {
return ImmutableSet.of(Table.class);
}
ImmutableTable.Builder<String, Integer, String> testImmutableTableBuilder() {
return new ImmutableTable.Builder<>();
}
ImmutableTable<Object, Object, Object> testImmutableTableBuilderBuildOrThrow() {
return ImmutableTable.builder().build();
}
ImmutableSet<ImmutableTable<String, Integer, String>> testCellToImmutableTable() {
return ImmutableSet.of(
ImmutableTable.<String, Integer, String>builder()
.put(Tables.immutableCell("foo", 1, "bar"))
.buildOrThrow(),
Stream.of(Tables.immutableCell("baz", 2, "qux"))
.collect(
toImmutableTable(
Table.Cell::getRowKey, Table.Cell::getColumnKey, Table.Cell::getValue)));
}
ImmutableTable<Integer, String, Integer> testStreamOfCellsToImmutableTable() {
return Stream.of(1, 2, 3)
.map(n -> Tables.immutableCell(n, n.toString(), n * 2))
.collect(
toImmutableTable(
Table.Cell::getRowKey, Table.Cell::getColumnKey, Table.Cell::getValue));
}
ImmutableTable<String, String, String> testImmutableTableOf() {
return ImmutableTable.<String, String, String>builder().buildOrThrow();
}
}

View File

@@ -1,45 +0,0 @@
package tech.picnic.errorprone.refasterrules;
import static com.google.common.collect.ImmutableTable.toImmutableTable;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableTable;
import com.google.common.collect.Table;
import com.google.common.collect.Tables;
import java.util.stream.Stream;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
final class ImmutableTableRulesTest implements RefasterRuleCollectionTestCase {
@Override
public ImmutableSet<Object> elidedTypesAndStaticImports() {
return ImmutableSet.of(Table.class);
}
ImmutableTable.Builder<String, Integer, String> testImmutableTableBuilder() {
return ImmutableTable.builder();
}
ImmutableTable<Object, Object, Object> testImmutableTableBuilderBuildOrThrow() {
return ImmutableTable.builder().buildOrThrow();
}
ImmutableSet<ImmutableTable<String, Integer, String>> testCellToImmutableTable() {
return ImmutableSet.of(
ImmutableTable.of(
Tables.immutableCell("foo", 1, "bar").getRowKey(),
Tables.immutableCell("foo", 1, "bar").getColumnKey(),
Tables.immutableCell("foo", 1, "bar").getValue()),
ImmutableTable.of(
Tables.immutableCell("baz", 2, "qux").getRowKey(),
Tables.immutableCell("baz", 2, "qux").getColumnKey(),
Tables.immutableCell("baz", 2, "qux").getValue()));
}
ImmutableTable<Integer, String, Integer> testStreamOfCellsToImmutableTable() {
return Stream.of(1, 2, 3).collect(toImmutableTable(n -> n, n -> n.toString(), n -> n * 2));
}
ImmutableTable<String, String, String> testImmutableTableOf() {
return ImmutableTable.of();
}
}

View File

@@ -1,7 +1,5 @@
package tech.picnic.errorprone.refasterrules;
import static org.assertj.core.api.Assertions.offset;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
@@ -26,8 +24,6 @@ final class JUnitToAssertJRulesTest implements RefasterRuleCollectionTestCase {
assertInstanceOf(null, null),
assertThrows(null, null),
assertThrowsExactly(null, null),
offset(0.0),
(Runnable) () -> assertArrayEquals((int[]) null, null),
(Runnable) () -> assertFalse(true),
(Runnable) () -> assertNotNull(null),
(Runnable) () -> assertNotSame(null, null),
@@ -36,138 +32,6 @@ final class JUnitToAssertJRulesTest implements RefasterRuleCollectionTestCase {
(Runnable) () -> assertTrue(true));
}
void testAssertThatBooleanArrayContainsExactly() {
assertArrayEquals(new boolean[] {true}, new boolean[] {false});
}
void testAssertThatBooleanArrayWithFailMessageContainsExactly() {
assertArrayEquals(new boolean[] {true}, new boolean[] {false}, "foo");
}
void testAssertThatBooleanArrayWithFailMessageSupplierContainsExactly() {
assertArrayEquals(new boolean[] {true}, new boolean[] {false}, () -> "foo");
}
void testAssertThatByteArrayContainsExactly() {
assertArrayEquals(new byte[] {1}, new byte[] {2});
}
void testAssertThatByteArrayWithFailMessageContainsExactly() {
assertArrayEquals(new byte[] {1}, new byte[] {2}, "foo");
}
void testAssertThatByteArrayWithFailMessageSupplierContainsExactly() {
assertArrayEquals(new byte[] {1}, new byte[] {2}, () -> "foo");
}
void testAssertThatCharArrayContainsExactly() {
assertArrayEquals(new char[] {'a'}, new char[] {'b'});
}
void testAssertThatCharArrayWithFailMessageContainsExactly() {
assertArrayEquals(new char[] {'a'}, new char[] {'b'}, "foo");
}
void testAssertThatCharArrayWithFailMessageSupplierContainsExactly() {
assertArrayEquals(new char[] {'a'}, new char[] {'b'}, () -> "foo");
}
void testAssertThatShortArrayContainsExactly() {
assertArrayEquals(new short[] {1}, new short[] {2});
}
void testAssertThatShortArrayWithFailMessageContainsExactly() {
assertArrayEquals(new short[] {1}, new short[] {2}, "foo");
}
void testAssertThatShortArrayWithFailMessageSupplierContainsExactly() {
assertArrayEquals(new short[] {1}, new short[] {2}, () -> "foo");
}
void testAssertThatIntArrayContainsExactly() {
assertArrayEquals(new int[] {1}, new int[] {2});
}
void testAssertThatIntArrayWithFailMessageContainsExactly() {
assertArrayEquals(new int[] {1}, new int[] {2}, "foo");
}
void testAssertThatIntArrayWithFailMessageSupplierContainsExactly() {
assertArrayEquals(new int[] {1}, new int[] {2}, () -> "foo");
}
void testAssertThatLongArrayContainsExactly() {
assertArrayEquals(new long[] {1L}, new long[] {2L});
}
void testAssertThatLongArrayWithFailMessageContainsExactly() {
assertArrayEquals(new long[] {1L}, new long[] {2L}, "foo");
}
void testAssertThatLongArrayWithFailMessageSupplierContainsExactly() {
assertArrayEquals(new long[] {1L}, new long[] {2L}, () -> "foo");
}
void testAssertThatFloatArrayContainsExactly() {
assertArrayEquals(new float[] {1.0F}, new float[] {2.0F});
}
void testAssertThatFloatArrayWithFailMessageContainsExactly() {
assertArrayEquals(new float[] {1.0F}, new float[] {2.0F}, "foo");
}
void testAssertThatFloatArrayWithFailMessageSupplierContainsExactly() {
assertArrayEquals(new float[] {1.0F}, new float[] {2.0F}, () -> "foo");
}
void testAssertThatFloatArrayContainsExactlyWithOffset() {
assertArrayEquals(new float[] {1.0F}, new float[] {2.0F}, 0.1f);
}
void testAssertThatFloatArrayWithFailMessageContainsExactlyWithOffset() {
assertArrayEquals(new float[] {1.0F}, new float[] {2.0F}, 0.1f, "foo");
}
void testAssertThatFloatArrayWithFailMessageSupplierContainsExactlyWithOffset() {
assertArrayEquals(new float[] {1.0F}, new float[] {2.0F}, 0.1f, () -> "foo");
}
void testAssertThatDoubleArrayContainsExactly() {
assertArrayEquals(new double[] {1.0}, new double[] {2.0});
}
void testAssertThatDoubleArrayWithFailMessageContainsExactly() {
assertArrayEquals(new double[] {1.0}, new double[] {2.0}, "foo");
}
void testAssertThatDoubleArrayWithFailMessageSupplierContainsExactly() {
assertArrayEquals(new double[] {1.0}, new double[] {2.0}, () -> "foo");
}
void testAssertThatDoubleArrayContainsExactlyWithOffset() {
assertArrayEquals(new double[] {1.0}, new double[] {2.0}, 0.1);
}
void testAssertThatDoubleArrayWithFailMessageContainsExactlyWithOffset() {
assertArrayEquals(new double[] {1.0}, new double[] {2.0}, 0.1, "foo");
}
void testAssertThatDoubleArrayWithFailMessageSupplierContainsExactlyWithOffset() {
assertArrayEquals(new double[] {1.0}, new double[] {2.0}, 0.1, () -> "foo");
}
void testAssertThatObjectArrayContainsExactly() {
assertArrayEquals(new Object[] {"foo"}, new Object[] {"bar"});
}
void testAssertThatObjectArrayWithFailMessageContainsExactly() {
assertArrayEquals(new Object[] {"foo"}, new Object[] {"bar"}, "foo");
}
void testAssertThatObjectArrayWithFailMessageSupplierContainsExactly() {
assertArrayEquals(new Object[] {"foo"}, new Object[] {"bar"}, () -> "foo");
}
Object testFail() {
return Assertions.fail();
}

View File

@@ -3,8 +3,6 @@ package tech.picnic.errorprone.refasterrules;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.offset;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
@@ -29,8 +27,6 @@ final class JUnitToAssertJRulesTest implements RefasterRuleCollectionTestCase {
assertInstanceOf(null, null),
assertThrows(null, null),
assertThrowsExactly(null, null),
offset(0.0),
(Runnable) () -> assertArrayEquals((int[]) null, null),
(Runnable) () -> assertFalse(true),
(Runnable) () -> assertNotNull(null),
(Runnable) () -> assertNotSame(null, null),
@@ -39,150 +35,6 @@ final class JUnitToAssertJRulesTest implements RefasterRuleCollectionTestCase {
(Runnable) () -> assertTrue(true));
}
void testAssertThatBooleanArrayContainsExactly() {
assertThat(new boolean[] {false}).containsExactly(new boolean[] {true});
}
void testAssertThatBooleanArrayWithFailMessageContainsExactly() {
assertThat(new boolean[] {false}).withFailMessage("foo").containsExactly(new boolean[] {true});
}
void testAssertThatBooleanArrayWithFailMessageSupplierContainsExactly() {
assertThat(new boolean[] {false})
.withFailMessage(() -> "foo")
.containsExactly(new boolean[] {true});
}
void testAssertThatByteArrayContainsExactly() {
assertThat(new byte[] {2}).containsExactly(new byte[] {1});
}
void testAssertThatByteArrayWithFailMessageContainsExactly() {
assertThat(new byte[] {2}).withFailMessage("foo").containsExactly(new byte[] {1});
}
void testAssertThatByteArrayWithFailMessageSupplierContainsExactly() {
assertThat(new byte[] {2}).withFailMessage(() -> "foo").containsExactly(new byte[] {1});
}
void testAssertThatCharArrayContainsExactly() {
assertThat(new char[] {'b'}).containsExactly(new char[] {'a'});
}
void testAssertThatCharArrayWithFailMessageContainsExactly() {
assertThat(new char[] {'b'}).withFailMessage("foo").containsExactly(new char[] {'a'});
}
void testAssertThatCharArrayWithFailMessageSupplierContainsExactly() {
assertThat(new char[] {'b'}).withFailMessage(() -> "foo").containsExactly(new char[] {'a'});
}
void testAssertThatShortArrayContainsExactly() {
assertThat(new short[] {2}).containsExactly(new short[] {1});
}
void testAssertThatShortArrayWithFailMessageContainsExactly() {
assertThat(new short[] {2}).withFailMessage("foo").containsExactly(new short[] {1});
}
void testAssertThatShortArrayWithFailMessageSupplierContainsExactly() {
assertThat(new short[] {2}).withFailMessage(() -> "foo").containsExactly(new short[] {1});
}
void testAssertThatIntArrayContainsExactly() {
assertThat(new int[] {2}).containsExactly(new int[] {1});
}
void testAssertThatIntArrayWithFailMessageContainsExactly() {
assertThat(new int[] {2}).withFailMessage("foo").containsExactly(new int[] {1});
}
void testAssertThatIntArrayWithFailMessageSupplierContainsExactly() {
assertThat(new int[] {2}).withFailMessage(() -> "foo").containsExactly(new int[] {1});
}
void testAssertThatLongArrayContainsExactly() {
assertThat(new long[] {2L}).containsExactly(new long[] {1L});
}
void testAssertThatLongArrayWithFailMessageContainsExactly() {
assertThat(new long[] {2L}).withFailMessage("foo").containsExactly(new long[] {1L});
}
void testAssertThatLongArrayWithFailMessageSupplierContainsExactly() {
assertThat(new long[] {2L}).withFailMessage(() -> "foo").containsExactly(new long[] {1L});
}
void testAssertThatFloatArrayContainsExactly() {
assertThat(new float[] {2.0F}).containsExactly(new float[] {1.0F});
}
void testAssertThatFloatArrayWithFailMessageContainsExactly() {
assertThat(new float[] {2.0F}).withFailMessage("foo").containsExactly(new float[] {1.0F});
}
void testAssertThatFloatArrayWithFailMessageSupplierContainsExactly() {
assertThat(new float[] {2.0F}).withFailMessage(() -> "foo").containsExactly(new float[] {1.0F});
}
void testAssertThatFloatArrayContainsExactlyWithOffset() {
assertThat(new float[] {2.0F}).containsExactly(new float[] {1.0F}, offset(0.1f));
}
void testAssertThatFloatArrayWithFailMessageContainsExactlyWithOffset() {
assertThat(new float[] {2.0F})
.withFailMessage("foo")
.containsExactly(new float[] {1.0F}, offset(0.1f));
}
void testAssertThatFloatArrayWithFailMessageSupplierContainsExactlyWithOffset() {
assertThat(new float[] {2.0F})
.withFailMessage(() -> "foo")
.containsExactly(new float[] {1.0F}, offset(0.1f));
}
void testAssertThatDoubleArrayContainsExactly() {
assertThat(new double[] {2.0}).containsExactly(new double[] {1.0});
}
void testAssertThatDoubleArrayWithFailMessageContainsExactly() {
assertThat(new double[] {2.0}).withFailMessage("foo").containsExactly(new double[] {1.0});
}
void testAssertThatDoubleArrayWithFailMessageSupplierContainsExactly() {
assertThat(new double[] {2.0}).withFailMessage(() -> "foo").containsExactly(new double[] {1.0});
}
void testAssertThatDoubleArrayContainsExactlyWithOffset() {
assertThat(new double[] {2.0}).containsExactly(new double[] {1.0}, offset(0.1));
}
void testAssertThatDoubleArrayWithFailMessageContainsExactlyWithOffset() {
assertThat(new double[] {2.0})
.withFailMessage("foo")
.containsExactly(new double[] {1.0}, offset(0.1));
}
void testAssertThatDoubleArrayWithFailMessageSupplierContainsExactlyWithOffset() {
assertThat(new double[] {2.0})
.withFailMessage(() -> "foo")
.containsExactly(new double[] {1.0}, offset(0.1));
}
void testAssertThatObjectArrayContainsExactly() {
assertThat(new Object[] {"bar"}).containsExactly(new Object[] {"foo"});
}
void testAssertThatObjectArrayWithFailMessageContainsExactly() {
assertThat(new Object[] {"bar"}).withFailMessage("foo").containsExactly(new Object[] {"foo"});
}
void testAssertThatObjectArrayWithFailMessageSupplierContainsExactly() {
assertThat(new Object[] {"bar"})
.withFailMessage(() -> "foo")
.containsExactly(new Object[] {"foo"});
}
Object testFail() {
return org.assertj.core.api.Assertions.fail();
}

View File

@@ -1,18 +1,16 @@
package tech.picnic.errorprone.refasterrules;
import static java.util.function.Predicate.not;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableSet;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Stream;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
final class NullRulesTest implements RefasterRuleCollectionTestCase {
@Override
public ImmutableSet<Object> elidedTypesAndStaticImports() {
return ImmutableSet.of(MoreObjects.class, Optional.class, not(null));
return ImmutableSet.of(MoreObjects.class, Optional.class);
}
ImmutableSet<Boolean> testIsNull() {
@@ -32,11 +30,11 @@ final class NullRulesTest implements RefasterRuleCollectionTestCase {
return Optional.ofNullable("foo").orElseGet(() -> "bar");
}
ImmutableSet<Predicate<String>> testIsNullFunction() {
return ImmutableSet.of(s -> s == null, not(Objects::nonNull));
long testIsNullFunction() {
return Stream.of("foo").filter(s -> s == null).count();
}
ImmutableSet<Predicate<String>> testNonNullFunction() {
return ImmutableSet.of(s -> s != null, not(Objects::isNull));
long testNonNullFunction() {
return Stream.of("foo").filter(s -> s != null).count();
}
}

View File

@@ -2,19 +2,18 @@ package tech.picnic.errorprone.refasterrules;
import static java.util.Objects.requireNonNullElse;
import static java.util.Objects.requireNonNullElseGet;
import static java.util.function.Predicate.not;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableSet;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Stream;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
final class NullRulesTest implements RefasterRuleCollectionTestCase {
@Override
public ImmutableSet<Object> elidedTypesAndStaticImports() {
return ImmutableSet.of(MoreObjects.class, Optional.class, not(null));
return ImmutableSet.of(MoreObjects.class, Optional.class);
}
ImmutableSet<Boolean> testIsNull() {
@@ -33,11 +32,11 @@ final class NullRulesTest implements RefasterRuleCollectionTestCase {
return requireNonNullElseGet("foo", () -> "bar");
}
ImmutableSet<Predicate<String>> testIsNullFunction() {
return ImmutableSet.of(Objects::isNull, Objects::isNull);
long testIsNullFunction() {
return Stream.of("foo").filter(Objects::isNull).count();
}
ImmutableSet<Predicate<String>> testNonNullFunction() {
return ImmutableSet.of(Objects::nonNull, Objects::nonNull);
long testNonNullFunction() {
return Stream.of("foo").filter(Objects::nonNull).count();
}
}

View File

@@ -9,10 +9,8 @@ import com.google.common.primitives.Floats;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
import com.google.common.primitives.Shorts;
import com.google.common.primitives.UnsignedBytes;
import com.google.common.primitives.UnsignedInts;
import com.google.common.primitives.UnsignedLongs;
import java.util.Comparator;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
final class PrimitiveRulesTest implements RefasterRuleCollectionTestCase {
@@ -27,7 +25,6 @@ final class PrimitiveRulesTest implements RefasterRuleCollectionTestCase {
Ints.class,
Longs.class,
Shorts.class,
UnsignedBytes.class,
UnsignedInts.class,
UnsignedLongs.class);
}
@@ -225,16 +222,4 @@ final class PrimitiveRulesTest implements RefasterRuleCollectionTestCase {
String testLongToUnsignedStringWithRadix() {
return UnsignedLongs.toString(1, 2);
}
Comparator<byte[]> testArraysCompareUnsignedBytes() {
return UnsignedBytes.lexicographicalComparator();
}
Comparator<int[]> testArraysCompareUnsignedInts() {
return UnsignedInts.lexicographicalComparator();
}
Comparator<long[]> testArraysCompareUnsignedLongs() {
return UnsignedLongs.lexicographicalComparator();
}
}

View File

@@ -9,11 +9,8 @@ import com.google.common.primitives.Floats;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
import com.google.common.primitives.Shorts;
import com.google.common.primitives.UnsignedBytes;
import com.google.common.primitives.UnsignedInts;
import com.google.common.primitives.UnsignedLongs;
import java.util.Arrays;
import java.util.Comparator;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
final class PrimitiveRulesTest implements RefasterRuleCollectionTestCase {
@@ -28,7 +25,6 @@ final class PrimitiveRulesTest implements RefasterRuleCollectionTestCase {
Ints.class,
Longs.class,
Shorts.class,
UnsignedBytes.class,
UnsignedInts.class,
UnsignedLongs.class);
}
@@ -226,16 +222,4 @@ final class PrimitiveRulesTest implements RefasterRuleCollectionTestCase {
String testLongToUnsignedStringWithRadix() {
return Long.toUnsignedString(1, 2);
}
Comparator<byte[]> testArraysCompareUnsignedBytes() {
return Arrays::compareUnsigned;
}
Comparator<int[]> testArraysCompareUnsignedInts() {
return Arrays::compareUnsigned;
}
Comparator<long[]> testArraysCompareUnsignedLongs() {
return Arrays::compareUnsigned;
}
}

View File

@@ -20,7 +20,6 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
@@ -188,12 +187,7 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
}
ImmutableSet<Flux<Integer>> testFluxJust() {
return ImmutableSet.of(
Flux.range(0, 1),
Mono.just(2).flux(),
Mono.just(3).repeat().take(1),
Flux.fromIterable(ImmutableList.of(4)),
Flux.fromIterable(ImmutableSet.of(5)));
return ImmutableSet.of(Flux.range(0, 1), Mono.just(2).repeat().take(1));
}
ImmutableSet<Mono<?>> testMonoIdentity() {
@@ -331,14 +325,6 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
Flux.just(1).switchMap(n -> Mono.fromSupplier(() -> n * 2)));
}
Flux<String> testFluxMapNotNullTransformationOrElse() {
return Flux.just(1).map(x -> Optional.of(x.toString())).mapNotNull(x -> x.orElse(null));
}
Flux<Integer> testFluxMapNotNullOrElse() {
return Flux.just(Optional.of(1)).filter(Optional::isPresent).map(Optional::orElseThrow);
}
ImmutableSet<Flux<String>> testMonoFlux() {
return ImmutableSet.of(
Mono.just("foo").flatMapMany(Mono::just),
@@ -347,11 +333,7 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
}
ImmutableSet<Mono<Void>> testMonoThen() {
return ImmutableSet.of(
Mono.just("foo").ignoreElement().then(),
Mono.just("bar").flux().then(),
Mono.when(Mono.just("baz")),
Mono.whenDelayError(Mono.just("qux")));
return ImmutableSet.of(Mono.just("foo").ignoreElement().then(), Mono.just("bar").flux().then());
}
ImmutableSet<Mono<Void>> testFluxThen() {
@@ -397,10 +379,8 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
ImmutableSet<Mono<Optional<String>>> testMonoSingleOptional() {
return ImmutableSet.of(
Mono.just("foo").flux().collect(toOptional()),
Mono.just("bar").map(Optional::of),
Mono.just("baz").singleOptional().defaultIfEmpty(Optional.empty()),
Mono.just("quux").singleOptional().switchIfEmpty(Mono.just(Optional.empty())),
Mono.just("quuz").transform(Mono::singleOptional));
Mono.just("bar").map(Optional::of).defaultIfEmpty(Optional.empty()),
Mono.just("baz").transform(Mono::singleOptional));
}
Mono<Number> testMonoCast() {
@@ -757,11 +737,6 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
return Mono.fromFuture(() -> ((AsyncLoadingCache<Integer, String>) null).get(0));
}
Mono<Map<Integer, String>> testMonoFromFutureAsyncLoadingCacheGetAll() {
return Mono.fromFuture(
() -> ((AsyncLoadingCache<Integer, String>) null).getAll(ImmutableSet.of()));
}
Flux<Integer> testFluxFromStreamSupplier() {
return Flux.fromStream(Stream.of(1));
}

View File

@@ -22,7 +22,6 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
@@ -192,7 +191,7 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
}
ImmutableSet<Flux<Integer>> testFluxJust() {
return ImmutableSet.of(Flux.just(0), Flux.just(2), Flux.just(3), Flux.just(4), Flux.just(5));
return ImmutableSet.of(Flux.just(0), Flux.just(2));
}
ImmutableSet<Mono<?>> testMonoIdentity() {
@@ -326,25 +325,13 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
Flux.just(1).mapNotNull(n -> n * 2));
}
Flux<String> testFluxMapNotNullTransformationOrElse() {
return Flux.just(1).mapNotNull(x -> Optional.of(x.toString()).orElse(null));
}
Flux<Integer> testFluxMapNotNullOrElse() {
return Flux.just(Optional.of(1)).mapNotNull(x -> x.orElse(null));
}
ImmutableSet<Flux<String>> testMonoFlux() {
return ImmutableSet.of(
Mono.just("foo").flux(), Mono.just("bar").flux(), Mono.just("baz").flux());
}
ImmutableSet<Mono<Void>> testMonoThen() {
return ImmutableSet.of(
Mono.just("foo").then(),
Mono.just("bar").then(),
Mono.just("baz").then(),
Mono.just("qux").then());
return ImmutableSet.of(Mono.just("foo").then(), Mono.just("bar").then());
}
ImmutableSet<Mono<Void>> testFluxThen() {
@@ -388,9 +375,7 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
return ImmutableSet.of(
Mono.just("foo").singleOptional(),
Mono.just("bar").singleOptional(),
Mono.just("baz").singleOptional(),
Mono.just("quux").singleOptional(),
Mono.just("quuz").singleOptional());
Mono.just("baz").singleOptional());
}
Mono<Number> testMonoCast() {
@@ -726,11 +711,6 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
return Mono.fromFuture(() -> ((AsyncLoadingCache<Integer, String>) null).get(0), true);
}
Mono<Map<Integer, String>> testMonoFromFutureAsyncLoadingCacheGetAll() {
return Mono.fromFuture(
() -> ((AsyncLoadingCache<Integer, String>) null).getAll(ImmutableSet.of()), true);
}
Flux<Integer> testFluxFromStreamSupplier() {
return Flux.fromStream(() -> Stream.of(1));
}

View File

@@ -124,4 +124,8 @@ final class StringRulesTest implements RefasterRuleCollectionTestCase {
boolean testStringStartsWith() {
return "foo".substring(1).startsWith("bar");
}
String testStringFormatted() {
return String.format("%s%s", "foo", "bar");
}
}

View File

@@ -124,4 +124,8 @@ final class StringRulesTest implements RefasterRuleCollectionTestCase {
boolean testStringStartsWith() {
return "foo".startsWith("bar", 1);
}
String testStringFormatted() {
return "%s%s".formatted("foo", "bar");
}
}

View File

@@ -1,6 +1,5 @@
package tech.picnic.errorprone.refasterrules;
import com.google.errorprone.VisitorState;
import com.google.errorprone.fixes.SuggestedFix;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.Tree;
@@ -24,9 +23,7 @@ final class SuggestedFixRulesTest implements RefasterRuleCollectionTestCase {
}
SuggestedFix testSuggestedFixSwap() {
return SuggestedFix.builder()
.swap((Tree) null, (ExpressionTree) null, (VisitorState) null)
.build();
return SuggestedFix.builder().swap((Tree) null, (ExpressionTree) null).build();
}
SuggestedFix testSuggestedFixPrefixWith() {

View File

@@ -1,6 +1,5 @@
package tech.picnic.errorprone.refasterrules;
import com.google.errorprone.VisitorState;
import com.google.errorprone.fixes.SuggestedFix;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.Tree;
@@ -24,7 +23,7 @@ final class SuggestedFixRulesTest implements RefasterRuleCollectionTestCase {
}
SuggestedFix testSuggestedFixSwap() {
return SuggestedFix.swap((Tree) null, (ExpressionTree) null, (VisitorState) null);
return SuggestedFix.swap((Tree) null, (ExpressionTree) null);
}
SuggestedFix testSuggestedFixPrefixWith() {

View File

@@ -96,79 +96,31 @@ final class TestNGToAssertJRulesTest implements RefasterRuleCollectionTestCase {
}
void testAssertEqual() {
assertEquals(true, false);
assertEquals(true, Boolean.FALSE);
assertEquals(Boolean.TRUE, false);
assertEquals(Boolean.TRUE, Boolean.FALSE);
assertEquals((byte) 0, (byte) 1);
assertEquals((byte) 0, Byte.decode("1"));
assertEquals(Byte.decode("0"), (byte) 1);
assertEquals(Byte.decode("0"), Byte.decode("1"));
assertEquals('a', 'b');
assertEquals('a', Character.valueOf('b'));
assertEquals(Character.valueOf('a'), 'b');
assertEquals(Character.valueOf('a'), Character.valueOf('b'));
assertEquals((short) 0, (short) 1);
assertEquals((short) 0, Short.decode("1"));
assertEquals(Short.decode("0"), (short) 1);
assertEquals(Short.decode("0"), Short.decode("1"));
assertEquals(0, 1);
assertEquals(0, Integer.valueOf(1));
assertEquals(Integer.valueOf(0), 1);
assertEquals(Integer.valueOf(0), Integer.valueOf(1));
assertEquals(0L, 1L);
assertEquals(0L, Long.valueOf(1));
assertEquals(Long.valueOf(0), 1L);
assertEquals(Long.valueOf(0), Long.valueOf(1));
assertEquals(0.0F, 1.0F);
assertEquals(0.0F, Float.valueOf(1.0F));
assertEquals(Float.valueOf(0.0F), 1.0F);
assertEquals(Float.valueOf(0.0F), Float.valueOf(1.0F));
assertEquals(0.0, 1.0);
assertEquals(0.0, Double.valueOf(1.0));
assertEquals(Double.valueOf(0.0), 1.0);
assertEquals(Double.valueOf(0.0), Double.valueOf(1.0));
assertEquals(new Object(), new StringBuilder());
assertEquals(true, true);
assertEquals((byte) 0, (byte) 0);
assertEquals((char) 0, (char) 0);
assertEquals((short) 0, (short) 0);
assertEquals(0, 0);
assertEquals(0L, 0L);
assertEquals(0.0F, 0.0F);
assertEquals(0.0, 0.0);
assertEquals(new Object(), new Object());
assertEquals("actual", "expected");
assertEquals(ImmutableMap.of(), ImmutableMap.of(1, 2));
assertEquals(ImmutableMap.of(), ImmutableMap.of());
}
void testAssertEqualWithMessage() {
assertEquals(true, false, "foo");
assertEquals(true, Boolean.FALSE, "bar");
assertEquals(Boolean.TRUE, false, "baz");
assertEquals(Boolean.TRUE, Boolean.FALSE, "qux");
assertEquals((byte) 0, (byte) 1, "quux");
assertEquals((byte) 0, Byte.decode("1"), "corge");
assertEquals(Byte.decode("0"), (byte) 1, "grault");
assertEquals(Byte.decode("0"), Byte.decode("1"), "garply");
assertEquals('a', 'b', "waldo");
assertEquals('a', Character.valueOf('b'), "fred");
assertEquals(Character.valueOf('a'), 'b', "plugh");
assertEquals(Character.valueOf('a'), Character.valueOf('b'), "xyzzy");
assertEquals((short) 0, (short) 1, "thud");
assertEquals((short) 0, Short.decode("1"), "foo");
assertEquals(Short.decode("0"), (short) 1, "bar");
assertEquals(Short.decode("0"), Short.decode("1"), "baz");
assertEquals(0, 1, "qux");
assertEquals(0, Integer.valueOf(1), "quux");
assertEquals(Integer.valueOf(0), 1, "corge");
assertEquals(Integer.valueOf(0), Integer.valueOf(1), "grault");
assertEquals(0L, 1L, "garply");
assertEquals(0L, Long.valueOf(1), "waldo");
assertEquals(Long.valueOf(0), 1L, "fred");
assertEquals(Long.valueOf(0), Long.valueOf(1), "plugh");
assertEquals(0.0F, 1.0F, "xyzzy");
assertEquals(0.0F, Float.valueOf(1.0F), "thud");
assertEquals(Float.valueOf(0.0F), 1.0F, "foo");
assertEquals(Float.valueOf(0.0F), Float.valueOf(1.0F), "bar");
assertEquals(0.0, 1.0, "baz");
assertEquals(0.0, Double.valueOf(1.0), "qux");
assertEquals(Double.valueOf(0.0), 1.0, "quux");
assertEquals(Double.valueOf(0.0), Double.valueOf(1.0), "corge");
assertEquals(new Object(), new StringBuilder(), "grault");
assertEquals("actual", "expected", "garply");
assertEquals(ImmutableMap.of(), ImmutableMap.of(1, 2), "waldo");
assertEquals(true, true, "foo");
assertEquals((byte) 0, (byte) 0, "bar");
assertEquals((char) 0, (char) 0, "baz");
assertEquals((short) 0, (short) 0, "qux");
assertEquals(0, 0, "quux");
assertEquals(0L, 0L, "quuz");
assertEquals(0.0F, 0.0F, "corge");
assertEquals(0.0, 0.0, "grault");
assertEquals(new Object(), new Object(), "garply");
assertEquals("actual", "expected", "waldo");
assertEquals(ImmutableMap.of(), ImmutableMap.of(), "plugh");
}
void testAssertEqualFloatsWithDelta() {
@@ -211,22 +163,6 @@ final class TestNGToAssertJRulesTest implements RefasterRuleCollectionTestCase {
assertEquals(new Object[0], new Object[0], "garply");
}
void testAssertEqualFloatArraysWithDelta() {
assertEquals(new float[0], new float[0], 0.0F);
}
void testAssertEqualFloatArraysWithDeltaWithMessage() {
assertEquals(new float[0], new float[0], 0.0F, "foo");
}
void testAssertEqualDoubleArraysWithDelta() {
assertEquals(new double[0], new double[0], 0.0);
}
void testAssertEqualDoubleArraysWithDeltaWithMessage() {
assertEquals(new double[0], new double[0], 0.0, "foo");
}
void testAssertEqualArraysIrrespectiveOfOrder() {
assertEqualsNoOrder(new Object[0], new Object[0]);
}

View File

@@ -101,79 +101,31 @@ final class TestNGToAssertJRulesTest implements RefasterRuleCollectionTestCase {
}
void testAssertEqual() {
assertThat(true).isEqualTo(false);
assertThat(true).isEqualTo(Boolean.FALSE);
assertThat(Boolean.TRUE).isEqualTo(false);
assertThat(Boolean.TRUE).isEqualTo(Boolean.FALSE);
assertThat((byte) 0).isEqualTo((byte) 1);
assertThat((byte) 0).isEqualTo(Byte.decode("1"));
assertThat(Byte.decode("0")).isEqualTo((byte) 1);
assertThat(Byte.decode("0")).isEqualTo(Byte.decode("1"));
assertThat('a').isEqualTo('b');
assertThat('a').isEqualTo(Character.valueOf('b'));
assertThat(Character.valueOf('a')).isEqualTo('b');
assertThat(Character.valueOf('a')).isEqualTo(Character.valueOf('b'));
assertThat((short) 0).isEqualTo((short) 1);
assertThat((short) 0).isEqualTo(Short.decode("1"));
assertThat(Short.decode("0")).isEqualTo((short) 1);
assertThat(Short.decode("0")).isEqualTo(Short.decode("1"));
assertThat(0).isEqualTo(1);
assertThat(0).isEqualTo(Integer.valueOf(1));
assertThat(Integer.valueOf(0)).isEqualTo(1);
assertThat(Integer.valueOf(0)).isEqualTo(Integer.valueOf(1));
assertThat(0L).isEqualTo(1L);
assertThat(0L).isEqualTo(Long.valueOf(1));
assertThat(Long.valueOf(0)).isEqualTo(1L);
assertThat(Long.valueOf(0)).isEqualTo(Long.valueOf(1));
assertThat(0.0F).isEqualTo(1.0F);
assertThat(0.0F).isEqualTo(Float.valueOf(1.0F));
assertThat(Float.valueOf(0.0F)).isEqualTo(1.0F);
assertThat(Float.valueOf(0.0F)).isEqualTo(Float.valueOf(1.0F));
assertThat(0.0).isEqualTo(1.0);
assertThat(0.0).isEqualTo(Double.valueOf(1.0));
assertThat(Double.valueOf(0.0)).isEqualTo(1.0);
assertThat(Double.valueOf(0.0)).isEqualTo(Double.valueOf(1.0));
assertThat(new Object()).isEqualTo(new StringBuilder());
assertThat(true).isEqualTo(true);
assertThat((byte) 0).isEqualTo((byte) 0);
assertThat((char) 0).isEqualTo((char) 0);
assertThat((short) 0).isEqualTo((short) 0);
assertThat(0).isEqualTo(0);
assertThat(0L).isEqualTo(0L);
assertThat(0.0F).isEqualTo(0.0F);
assertThat(0.0).isEqualTo(0.0);
assertThat(new Object()).isEqualTo(new Object());
assertThat("actual").isEqualTo("expected");
assertThat(ImmutableMap.of()).isEqualTo(ImmutableMap.of(1, 2));
assertThat(ImmutableMap.of()).isEqualTo(ImmutableMap.of());
}
void testAssertEqualWithMessage() {
assertThat(true).withFailMessage("foo").isEqualTo(false);
assertThat(true).withFailMessage("bar").isEqualTo(Boolean.FALSE);
assertThat(Boolean.TRUE).withFailMessage("baz").isEqualTo(false);
assertThat(Boolean.TRUE).withFailMessage("qux").isEqualTo(Boolean.FALSE);
assertThat((byte) 0).withFailMessage("quux").isEqualTo((byte) 1);
assertThat((byte) 0).withFailMessage("corge").isEqualTo(Byte.decode("1"));
assertThat(Byte.decode("0")).withFailMessage("grault").isEqualTo((byte) 1);
assertThat(Byte.decode("0")).withFailMessage("garply").isEqualTo(Byte.decode("1"));
assertThat('a').withFailMessage("waldo").isEqualTo('b');
assertThat('a').withFailMessage("fred").isEqualTo(Character.valueOf('b'));
assertThat(Character.valueOf('a')).withFailMessage("plugh").isEqualTo('b');
assertThat(Character.valueOf('a')).withFailMessage("xyzzy").isEqualTo(Character.valueOf('b'));
assertThat((short) 0).withFailMessage("thud").isEqualTo((short) 1);
assertThat((short) 0).withFailMessage("foo").isEqualTo(Short.decode("1"));
assertThat(Short.decode("0")).withFailMessage("bar").isEqualTo((short) 1);
assertThat(Short.decode("0")).withFailMessage("baz").isEqualTo(Short.decode("1"));
assertThat(0).withFailMessage("qux").isEqualTo(1);
assertThat(0).withFailMessage("quux").isEqualTo(Integer.valueOf(1));
assertThat(Integer.valueOf(0)).withFailMessage("corge").isEqualTo(1);
assertThat(Integer.valueOf(0)).withFailMessage("grault").isEqualTo(Integer.valueOf(1));
assertThat(0L).withFailMessage("garply").isEqualTo(1L);
assertThat(0L).withFailMessage("waldo").isEqualTo(Long.valueOf(1));
assertThat(Long.valueOf(0)).withFailMessage("fred").isEqualTo(1L);
assertThat(Long.valueOf(0)).withFailMessage("plugh").isEqualTo(Long.valueOf(1));
assertThat(0.0F).withFailMessage("xyzzy").isEqualTo(1.0F);
assertThat(0.0F).withFailMessage("thud").isEqualTo(Float.valueOf(1.0F));
assertThat(Float.valueOf(0.0F)).withFailMessage("foo").isEqualTo(1.0F);
assertThat(Float.valueOf(0.0F)).withFailMessage("bar").isEqualTo(Float.valueOf(1.0F));
assertThat(0.0).withFailMessage("baz").isEqualTo(1.0);
assertThat(0.0).withFailMessage("qux").isEqualTo(Double.valueOf(1.0));
assertThat(Double.valueOf(0.0)).withFailMessage("quux").isEqualTo(1.0);
assertThat(Double.valueOf(0.0)).withFailMessage("corge").isEqualTo(Double.valueOf(1.0));
assertThat(new Object()).withFailMessage("grault").isEqualTo(new StringBuilder());
assertThat("actual").withFailMessage("garply").isEqualTo("expected");
assertThat(ImmutableMap.of()).withFailMessage("waldo").isEqualTo(ImmutableMap.of(1, 2));
assertThat(true).withFailMessage("foo").isEqualTo(true);
assertThat((byte) 0).withFailMessage("bar").isEqualTo((byte) 0);
assertThat((char) 0).withFailMessage("baz").isEqualTo((char) 0);
assertThat((short) 0).withFailMessage("qux").isEqualTo((short) 0);
assertThat(0).withFailMessage("quux").isEqualTo(0);
assertThat(0L).withFailMessage("quuz").isEqualTo(0L);
assertThat(0.0F).withFailMessage("corge").isEqualTo(0.0F);
assertThat(0.0).withFailMessage("grault").isEqualTo(0.0);
assertThat(new Object()).withFailMessage("garply").isEqualTo(new Object());
assertThat("actual").withFailMessage("waldo").isEqualTo("expected");
assertThat(ImmutableMap.of()).withFailMessage("plugh").isEqualTo(ImmutableMap.of());
}
void testAssertEqualFloatsWithDelta() {
@@ -216,22 +168,6 @@ final class TestNGToAssertJRulesTest implements RefasterRuleCollectionTestCase {
assertThat(new Object[0]).withFailMessage("garply").containsExactly(new Object[0]);
}
void testAssertEqualFloatArraysWithDelta() {
assertThat(new float[0]).containsExactly(new float[0], offset(0.0F));
}
void testAssertEqualFloatArraysWithDeltaWithMessage() {
assertThat(new float[0]).withFailMessage("foo").containsExactly(new float[0], offset(0.0F));
}
void testAssertEqualDoubleArraysWithDelta() {
assertThat(new double[0]).containsExactly(new double[0], offset(0.0));
}
void testAssertEqualDoubleArraysWithDeltaWithMessage() {
assertThat(new double[0]).withFailMessage("foo").containsExactly(new double[0], offset(0.0));
}
void testAssertEqualArraysIrrespectiveOfOrder() {
assertThat(new Object[0]).containsExactlyInAnyOrder(new Object[0]);
}

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.22.1-SNAPSHOT</version>
<version>0.19.2-SNAPSHOT</version>
</parent>
<artifactId>error-prone-experimental</artifactId>
@@ -15,6 +15,26 @@
<url>https://error-prone.picnic.tech</url>
<dependencies>
<dependency>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_annotation</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_check_api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_test_helpers</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>error-prone-utils</artifactId>
@@ -25,26 +45,6 @@
<artifactId>auto-service-annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_annotation</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_check_api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_test_helpers</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>

View File

@@ -29,7 +29,6 @@ import com.sun.source.tree.ReturnTree;
import com.sun.source.tree.Tree;
import com.sun.source.tree.VariableTree;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.PackageSymbol;
import com.sun.tools.javac.code.Type;
import java.util.List;
import java.util.Optional;
@@ -127,7 +126,7 @@ public final class MethodReferenceUsage extends BugChecker implements LambdaExpr
return Optional.empty();
}
Symbol sym = ASTHelpers.getSymbol(subTree);
Symbol sym = ASTHelpers.getSymbol(methodSelect);
return ASTHelpers.isStatic(sym)
? constructFix(lambdaExpr, sym.owner, methodSelect)
: constructFix(lambdaExpr, "this", methodSelect);
@@ -201,8 +200,7 @@ public final class MethodReferenceUsage extends BugChecker implements LambdaExpr
Name sName = target.getSimpleName();
Optional<SuggestedFix.Builder> fix = constructFix(lambdaExpr, sName, methodName);
PackageSymbol pkg = ASTHelpers.enclosingPackage(target);
if (pkg != null && !"java.lang".equals(pkg.toString())) {
if (!"java.lang".equals(ASTHelpers.enclosingPackage(target).toString())) {
Name fqName = target.getQualifiedName();
if (!sName.equals(fqName)) {
return fix.map(b -> b.addImport(fqName.toString()));

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.22.1-SNAPSHOT</version>
<version>0.19.2-SNAPSHOT</version>
</parent>
<artifactId>error-prone-guidelines</artifactId>
@@ -15,6 +15,31 @@
<url>https://error-prone.picnic.tech</url>
<dependencies>
<dependency>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_annotation</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_check_api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_test_helpers</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>documentation-support</artifactId>
@@ -43,31 +68,6 @@
<artifactId>auto-service-annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_annotation</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_check_api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_test_helpers</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.googlejavaformat</groupId>
<artifactId>google-java-format</artifactId>

View File

@@ -46,6 +46,7 @@ import java.util.Set;
import java.util.function.Consumer;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Modifier;
import org.jspecify.annotations.Nullable;
import tech.picnic.errorprone.utils.SourceCode;
@@ -101,8 +102,7 @@ public final class ExhaustiveRefasterTypeMigration extends BugChecker implements
AnnotationTree migrationAnnotation = migrationAnnotations.onlyMatchingNode();
AnnotationMirror annotationMirror = ASTHelpers.getAnnotationMirror(migrationAnnotation);
TypeSymbol migratedType = getMigratedType(annotationMirror);
if (migratedType.asType().isPrimitive()
|| !(migratedType instanceof ClassSymbol migratedClass)) {
if (migratedType.asType().isPrimitive() || !(migratedType instanceof ClassSymbol)) {
return buildDescription(migrationAnnotation)
.setMessage(String.format("Migration of type '%s' is unsupported", migratedType))
.build();
@@ -111,7 +111,7 @@ public final class ExhaustiveRefasterTypeMigration extends BugChecker implements
ImmutableList<String> methodsClaimedUnmigrated = getMethodsClaimedUnmigrated(annotationMirror);
ImmutableList<String> unmigratedMethods =
getMethodsDefinitelyUnmigrated(
tree, migratedClass, signatureOrder(methodsClaimedUnmigrated), state);
tree, (ClassSymbol) migratedType, signatureOrder(methodsClaimedUnmigrated), state);
if (unmigratedMethods.equals(methodsClaimedUnmigrated)) {
return Description.NO_MATCH;
@@ -160,11 +160,17 @@ public final class ExhaustiveRefasterTypeMigration extends BugChecker implements
.getValue().stream().map(a -> a.getValue().toString()).collect(toImmutableList());
}
// XXX: Once only JDK 14 and above are supported, change the
// `m.getModifiers().contains(Modifier.PUBLIC)` check to just `m.isPublic()`.
private static ImmutableList<String> getMethodsDefinitelyUnmigrated(
ClassTree tree, ClassSymbol migratedType, Comparator<String> comparator, VisitorState state) {
Set<MethodSymbol> publicMethods =
Streams.stream(
migratedType.members().getSymbols(m -> m.isPublic() && m instanceof MethodSymbol))
ASTHelpers.scope(migratedType.members())
.getSymbols(
m ->
m.getModifiers().contains(Modifier.PUBLIC)
&& m instanceof MethodSymbol))
.map(MethodSymbol.class::cast)
.collect(toCollection(HashSet::new));

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.22.1-SNAPSHOT</version>
<version>0.19.2-SNAPSHOT</version>
</parent>
<artifactId>error-prone-utils</artifactId>
@@ -16,22 +16,22 @@
<dependencies>
<dependency>
<groupId>com.google.errorprone</groupId>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_annotation</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_check_api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_test_helpers</artifactId>
<scope>provided</scope>
</dependency>

View File

@@ -1,7 +1,5 @@
package tech.picnic.errorprone.utils;
import static java.util.Objects.requireNonNull;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableSet;
@@ -117,15 +115,9 @@ public final class AnnotationAttributeMatcher implements Serializable {
}
private static String extractAttributeName(ExpressionTree expr) {
if (!(expr instanceof AssignmentTree assignment)) {
return "value";
}
return requireNonNull(
ASTHelpers.getSymbol(assignment.getVariable()),
"Missing symbol for annotation attribute")
.getSimpleName()
.toString();
return (expr instanceof AssignmentTree assignment)
? ASTHelpers.getSymbol(assignment.getVariable()).getSimpleName().toString()
: "value";
}
// XXX: The caller of this method can be implemented more efficiently in case of a "wholeTypes"

View File

@@ -63,11 +63,9 @@ public final class SourceCode {
* found.
* @return A non-{@code null} string.
* @apiNote This method differs from {@link com.sun.tools.javac.util.Constants#format(Object)} in
* that it does not superfluously escape single quote characters (the latter only does the
* "clean thing" starting from JDK 23). It is different from {@link
* that it does not superfluously escape single quote characters. It is different from {@link
* VisitorState#getConstantExpression(Object)} in that it is more performant and accepts any
* {@link CharSequence} instance.
* @see <a href="https://bugs.openjdk.org/browse/JDK-8325078">JDK-8325078</a>
*/
// XXX: Drop this method if https://github.com/google/error-prone/pull/4586 is merged and released
// with the proposed `CharSequence` compatibility change.

View File

@@ -303,7 +303,14 @@ final class SourceCodeTest {
@Override
public Description matchLiteral(LiteralTree tree, VisitorState state) {
// XXX: The character conversion is a workaround for the fact that `ASTHelpers#constValue`
// returns an `Integer` value for `char` constants.
return Optional.ofNullable(ASTHelpers.constValue(tree))
.map(
constant ->
ASTHelpers.isSubtype(ASTHelpers.getType(tree), state.getSymtab().charType, state)
? (char) (int) constant
: constant)
.map(constant -> describeMatch(tree, addComment(tree, constant, state)))
.orElse(Description.NO_MATCH);
}

View File

@@ -14875,7 +14875,7 @@
final String defaultValue = getDefaultValue(propertyName, field, instance);
--- a/src/main/java/com/puppycrawl/tools/checkstyle/site/SiteUtil.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/site/SiteUtil.java
@@ -19,6 +19,15 @@
@@ -19,6 +19,14 @@
package com.puppycrawl.tools.checkstyle.site;
@@ -14886,12 +14886,11 @@
+
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.puppycrawl.tools.checkstyle.Checker;
import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
@@ -55,7 +64,6 @@ import java.net.URI;
@@ -55,7 +63,6 @@ import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -14899,7 +14898,7 @@
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
@@ -72,7 +80,6 @@ import java.util.Optional;
@@ -72,7 +79,6 @@ import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Pattern;
@@ -14907,31 +14906,7 @@
import java.util.stream.IntStream;
import java.util.stream.Stream;
import javax.annotation.Nullable;
@@ -131,12 +138,17 @@ public final class SiteUtil {
/** Class name and their corresponding parent module name. */
private static final Map<Class<?>, String> CLASS_TO_PARENT_MODULE =
- Map.ofEntries(
- Map.entry(AbstractCheck.class, TreeWalker.class.getSimpleName()),
- Map.entry(TreeWalkerFilter.class, TreeWalker.class.getSimpleName()),
- Map.entry(AbstractFileSetCheck.class, Checker.class.getSimpleName()),
- Map.entry(Filter.class, Checker.class.getSimpleName()),
- Map.entry(BeforeExecutionFileFilter.class, Checker.class.getSimpleName()));
+ ImmutableMap.of(
+ AbstractCheck.class,
+ TreeWalker.class.getSimpleName(),
+ TreeWalkerFilter.class,
+ TreeWalker.class.getSimpleName(),
+ AbstractFileSetCheck.class,
+ Checker.class.getSimpleName(),
+ Filter.class,
+ Checker.class.getSimpleName(),
+ BeforeExecutionFileFilter.class,
+ Checker.class.getSimpleName());
/** Set of properties that every check has. */
private static final Set<String> CHECK_PROPERTIES = getProperties(AbstractCheck.class);
@@ -156,7 +168,7 @@ public final class SiteUtil {
@@ -156,7 +162,7 @@ public final class SiteUtil {
/** Set of properties that are undocumented. Those are internal properties. */
private static final Set<String> UNDOCUMENTED_PROPERTIES =
@@ -14940,7 +14915,7 @@
"SuppressWithNearbyCommentFilter.fileContents", "SuppressionCommentFilter.fileContents");
/** Properties that can not be gathered from class instance. */
@@ -294,27 +306,25 @@ public final class SiteUtil {
@@ -294,27 +300,25 @@ public final class SiteUtil {
/** Path to main source code folder. */
private static final String MAIN_FOLDER_PATH =
@@ -14957,16 +14932,16 @@
+ new File(Path.of(MAIN_FOLDER_PATH, CHECKS, NAMING, "AbstractNameCheck.java").toString()),
new File(
- Paths.get(MAIN_FOLDER_PATH, CHECKS, NAMING, "AbstractNameCheck.java").toString()),
+ Path.of(MAIN_FOLDER_PATH, CHECKS, "javadoc", "AbstractJavadocCheck.java").toString()),
+ new File(Path.of(MAIN_FOLDER_PATH, "api", "AbstractFileSetCheck.java").toString()),
new File(
- new File(
- Paths.get(MAIN_FOLDER_PATH, CHECKS, "javadoc", "AbstractJavadocCheck.java")
- .toString()),
- new File(Paths.get(MAIN_FOLDER_PATH, "api", "AbstractFileSetCheck.java").toString()),
+ Path.of(MAIN_FOLDER_PATH, CHECKS, "header", "AbstractHeaderCheck.java").toString()),
+ Path.of(MAIN_FOLDER_PATH, CHECKS, "javadoc", "AbstractJavadocCheck.java").toString()),
+ new File(Path.of(MAIN_FOLDER_PATH, "api", "AbstractFileSetCheck.java").toString()),
new File(
- Paths.get(MAIN_FOLDER_PATH, CHECKS, "header", "AbstractHeaderCheck.java").toString()),
- new File(
+ Path.of(MAIN_FOLDER_PATH, CHECKS, "header", "AbstractHeaderCheck.java").toString()),
new File(
- Paths.get(MAIN_FOLDER_PATH, CHECKS, "metrics", "AbstractClassCouplingCheck.java")
+ Path.of(MAIN_FOLDER_PATH, CHECKS, "metrics", "AbstractClassCouplingCheck.java")
.toString()),
@@ -14976,7 +14951,7 @@
.toString()));
/** Private utility constructor. */
@@ -475,7 +485,7 @@ public final class SiteUtil {
@@ -475,7 +479,7 @@ public final class SiteUtil {
* @throws MacroExecutionException if an I/O error occurs.
*/
public static Set<Path> getXdocsTemplatesFilePaths() throws MacroExecutionException {
@@ -14985,7 +14960,7 @@
try (Stream<Path> stream =
Files.find(
directory,
@@ -483,7 +493,7 @@ public final class SiteUtil {
@@ -483,7 +487,7 @@ public final class SiteUtil {
(path, attr) -> {
return attr.isRegularFile() && path.toString().endsWith(".xml.template");
})) {
@@ -14994,7 +14969,7 @@
} catch (IOException ioException) {
throw new MacroExecutionException("Failed to find xdocs templates", ioException);
}
@@ -510,7 +520,7 @@ public final class SiteUtil {
@@ -510,7 +514,7 @@ public final class SiteUtil {
}
// If parent class is not found, check interfaces
@@ -15003,7 +14978,7 @@
final Class<?>[] interfaces = moduleClass.getInterfaces();
for (Class<?> interfaceClass : interfaces) {
parentModuleName = CLASS_TO_PARENT_MODULE.get(interfaceClass);
@@ -520,7 +530,7 @@ public final class SiteUtil {
@@ -520,7 +524,7 @@ public final class SiteUtil {
}
}
@@ -15012,7 +14987,7 @@
final String message =
String.format(
Locale.ROOT, "Failed to find parent module for %s", moduleClass.getSimpleName());
@@ -544,7 +554,7 @@ public final class SiteUtil {
@@ -544,7 +548,7 @@ public final class SiteUtil {
prop -> {
return !isGlobalProperty(clss, prop) && !isUndocumentedProperty(clss, prop);
})
@@ -15021,7 +14996,7 @@
properties.addAll(getNonExplicitProperties(instance, clss));
return new TreeSet<>(properties);
}
@@ -663,7 +673,7 @@ public final class SiteUtil {
@@ -663,7 +667,7 @@ public final class SiteUtil {
treeWalkerConfig.addChild(scraperCheckConfig);
try {
checker.configure(defaultConfiguration);
@@ -15030,7 +15005,7 @@
checker.process(filesToProcess);
checker.destroy();
} catch (CheckstyleException checkstyleException) {
@@ -986,9 +996,7 @@ public final class SiteUtil {
@@ -986,9 +990,7 @@ public final class SiteUtil {
if (value != null && Array.getLength(value) > 0) {
result =
removeSquareBrackets(
@@ -15041,7 +15016,7 @@
}
if (result.isEmpty()) {
@@ -1020,8 +1028,7 @@ public final class SiteUtil {
@@ -1020,8 +1022,7 @@ public final class SiteUtil {
result = "";
} else {
try (Stream<?> valuesStream = getValuesStream(value)) {
@@ -15051,7 +15026,7 @@
}
}
@@ -1062,10 +1069,7 @@ public final class SiteUtil {
@@ -1062,10 +1063,7 @@ public final class SiteUtil {
private static String getIntArrayPropertyValue(Object value) {
try (IntStream stream = getIntStream(value)) {
String result =
@@ -15063,7 +15038,7 @@
if (result.isEmpty()) {
result = CURLY_BRACKETS;
}
@@ -1170,11 +1174,11 @@ public final class SiteUtil {
@@ -1170,11 +1168,11 @@ public final class SiteUtil {
*/
public static List<Integer> getDifference(int[] tokens, int... subtractions) {
final Set<Integer> subtractionsSet =
@@ -15077,7 +15052,7 @@
}
/**
@@ -1221,7 +1225,7 @@ public final class SiteUtil {
@@ -1221,7 +1219,7 @@ public final class SiteUtil {
throw new MacroExecutionException("Failed to get parent path for " + templatePath);
}
return templatePathParent
@@ -15402,7 +15377,7 @@
- if (name == null) {
- throw new IllegalArgumentException(String.format(Locale.ROOT, TOKEN_ID_EXCEPTION_FORMAT, id));
- }
+ checkArgument(name != null, TOKEN_ID_EXCEPTION_FORMAT, id);
+ checkArgument(name != null, String.format(Locale.ROOT, TOKEN_ID_EXCEPTION_FORMAT, id));
return name;
}
@@ -15414,11 +15389,11 @@
- throw new IllegalArgumentException(
- String.format(Locale.ROOT, TOKEN_NAME_EXCEPTION_FORMAT, name));
- }
+ checkArgument(id != null, TOKEN_NAME_EXCEPTION_FORMAT, name);
+ checkArgument(id != null, String.format(Locale.ROOT, TOKEN_NAME_EXCEPTION_FORMAT, name));
return id;
}
@@ -165,10 +163,7 @@ public final class TokenUtil {
@@ -165,10 +163,9 @@ public final class TokenUtil {
* @throws IllegalArgumentException when name is unknown
*/
public static String getShortDescription(String name) {
@@ -15426,11 +15401,13 @@
- throw new IllegalArgumentException(
- String.format(Locale.ROOT, TOKEN_NAME_EXCEPTION_FORMAT, name));
- }
+ checkArgument(TOKEN_NAME_TO_VALUE.containsKey(name), TOKEN_NAME_EXCEPTION_FORMAT, name);
+ checkArgument(
+ TOKEN_NAME_TO_VALUE.containsKey(name),
+ String.format(Locale.ROOT, TOKEN_NAME_EXCEPTION_FORMAT, name));
final String tokenTypes = "com.puppycrawl.tools.checkstyle.api.tokentypes";
final ResourceBundle bundle = ResourceBundle.getBundle(tokenTypes, Locale.ROOT);
@@ -344,7 +339,7 @@ public final class TokenUtil {
@@ -344,7 +341,7 @@ public final class TokenUtil {
public static BitSet asBitSet(String... tokens) {
return Arrays.stream(tokens)
.map(String::trim)
@@ -15441,13 +15418,12 @@
}
--- a/src/main/java/com/puppycrawl/tools/checkstyle/utils/UnmodifiableCollectionUtil.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/utils/UnmodifiableCollectionUtil.java
@@ -19,13 +19,16 @@
@@ -19,13 +19,15 @@
package com.puppycrawl.tools.checkstyle.utils;
+import static java.util.stream.Collectors.toUnmodifiableList;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
import java.util.Arrays;
import java.util.Collection;
@@ -15459,7 +15435,7 @@
/**
* <div>Note: it simply wraps the existing JDK methods to provide a workaround for Pitest survival
@@ -57,7 +60,7 @@ public final class UnmodifiableCollectionUtil {
@@ -57,7 +59,7 @@ public final class UnmodifiableCollectionUtil {
* @return An unmodifiable List containing elements of the specified type.
*/
public static <S, T> List<T> unmodifiableList(Collection<S> items, Class<T> elementType) {
@@ -15468,16 +15444,7 @@
}
/**
@@ -81,7 +84,7 @@ public final class UnmodifiableCollectionUtil {
* @return an immutable copy of the input map
*/
public static <K, V> Map<K, V> copyOfMap(Map<? extends K, ? extends V> map) {
- return Map.copyOf(map);
+ return ImmutableMap.copyOf(map);
}
/**
@@ -92,6 +95,6 @@ public final class UnmodifiableCollectionUtil {
@@ -92,6 +94,6 @@ public final class UnmodifiableCollectionUtil {
* @return immutable set
*/
public static <T> Set<T> singleton(T obj) {
@@ -56970,15 +56937,6 @@
private static final Map<String, Class<?>> FULLY_QUALIFIED_CLASS_NAMES =
ImmutableMap.<String, Class<?>>builder()
.put("int", int.class)
@@ -97,7 +96,7 @@ public class XdocsJavaDocsTest extends AbstractModuleTestSupport {
.put("URI", URI.class)
.put("WrapOption", WrapOption.class)
.put("PARAM_LITERAL", int[].class)
- .build();
+ .buildOrThrow();
private static final List<List<Node>> CHECK_PROPERTIES = new ArrayList<>();
private static final Map<String, String> CHECK_PROPERTY_DOC = new HashMap<>();
@@ -115,14 +114,14 @@ public class XdocsJavaDocsTest extends AbstractModuleTestSupport {
}

View File

@@ -1,5 +1,3 @@
src/it/java/com/google/checkstyle/test/base/AbstractIndentationTestSupport.java:[100,21] [EagerStringFormatting] String formatting can be deferred (assuming that Guava's simplified formatting support suffices)
src/it/java/com/google/checkstyle/test/base/AbstractIndentationTestSupport.java:[85,21] [EagerStringFormatting] String formatting can be deferred (assuming that Guava's simplified formatting support suffices)
src/it/java/com/google/checkstyle/test/chapter7javadoc/rule734nonrequiredjavadoc/NonRequiredJavadocTest.java:[33,8] [JUnitMethodDeclaration] This method's name should not redundantly start with `test` (but note that `default` is not a valid identifier)
src/it/java/com/sun/checkstyle/test/chapter5comments/rule52documentationcomments/InvalidJavadocPositionTest.java:[35,8] [JUnitMethodDeclaration] This method's name should not redundantly start with `test` (but note that `default` is not a valid identifier)
src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionAbbreviationAsWordInNameTest.java:[116,8] [JUnitMethodDeclaration] This method's name should not redundantly start with `test` (but note that `enum` is not a valid identifier)
@@ -107,8 +105,6 @@ src/test/java/com/puppycrawl/tools/checkstyle/checks/design/InterfaceIsTypeCheck
src/test/java/com/puppycrawl/tools/checkstyle/checks/design/MutableExceptionCheckTest.java:[54,8] [JUnitMethodDeclaration] This method's name should not redundantly start with `test` (but note that `default` is not a valid identifier)
src/test/java/com/puppycrawl/tools/checkstyle/checks/imports/ImportControlCheckTest.java:[100,8] [JUnitMethodDeclaration] This method's name should not redundantly start with `test` (but note that `null` is not a valid identifier)
src/test/java/com/puppycrawl/tools/checkstyle/checks/imports/ImportOrderCheckTest.java:[81,8] [JUnitMethodDeclaration] This method's name should not redundantly start with `test` (but note that `default` is not a valid identifier)
src/test/java/com/puppycrawl/tools/checkstyle/checks/indentation/IndentationCheckTest.java:[69,21] [EagerStringFormatting] String formatting can be deferred (assuming that Guava's simplified formatting support suffices)
src/test/java/com/puppycrawl/tools/checkstyle/checks/indentation/IndentationCheckTest.java:[80,21] [EagerStringFormatting] String formatting can be deferred (assuming that Guava's simplified formatting support suffices)
src/test/java/com/puppycrawl/tools/checkstyle/checks/javadoc/InvalidJavadocPositionCheckTest.java:[59,8] [JUnitMethodDeclaration] This method's name should not redundantly start with `test` (but note that `default` is not a valid identifier)
src/test/java/com/puppycrawl/tools/checkstyle/checks/javadoc/JavadocContentLocationCheckTest.java:[57,8] [JUnitMethodDeclaration] This method's name should not redundantly start with `test` (but note that `default` is not a valid identifier)
src/test/java/com/puppycrawl/tools/checkstyle/checks/javadoc/JavadocContentLocationCheckTest.java:[75,8] [JUnitMethodDeclaration] This method's name should not redundantly start with `test` (but note that `package` is not a valid identifier)

View File

@@ -7,7 +7,7 @@
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <version>3.27.3<!-- Renovate: org.assertj:assertj-bom --></version>
+ <version>3.27.0<!-- Renovate: org.assertj:assertj-bom --></version>
+ <scope>test</scope>
+ </dependency>
<dependency>

View File

@@ -89,63 +89,15 @@
}
return new CollectdReporter(
registry,
@@ -177,7 +172,7 @@ public class CollectdReporter extends ScheduledReporter {
}
}
- private static final Logger LOG = LoggerFactory.getLogger(CollectdReporter.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(CollectdReporter.class);
private static final String REPORTER_NAME = "collectd-reporter";
private static final String FALLBACK_HOST_NAME = "localhost";
private static final String COLLECTD_TYPE_GAUGE = "gauge";
@@ -224,7 +219,7 @@ public class CollectdReporter extends ScheduledReporter {
try {
return InetAddress.getLocalHost().getHostName();
} catch (Exception e) {
- LOG.error("Failed to lookup local host name: {}", e.getMessage(), e);
+ LOGGER.error("Failed to lookup local host name: {}", e.getMessage(), e);
return FALLBACK_HOST_NAME;
}
}
@@ -263,7 +258,7 @@ public class CollectdReporter extends ScheduledReporter {
serializeTimer(metaData.plugin(entry.getKey().getKey()), entry.getValue());
}
} catch (IOException e) {
- LOG.warn("Unable to report to Collectd", e);
+ LOGGER.warn("Unable to report to Collectd", e);
} finally {
disconnect(sender);
}
@@ -279,7 +274,7 @@ public class CollectdReporter extends ScheduledReporter {
try {
sender.disconnect();
} catch (Exception e) {
- LOG.warn("Error disconnecting from Collectd", e);
+ LOGGER.warn("Error disconnecting from Collectd", e);
}
}
@@ -302,9 +297,9 @@ public class CollectdReporter extends ScheduledReporter {
@@ -302,7 +297,7 @@ public class CollectdReporter extends ScheduledReporter {
try {
writer.write(metaData, value);
} catch (RuntimeException e) {
- LOG.warn("Failed to process metric '" + metaData.getPlugin() + "': " + e.getMessage());
+ LOGGER.warn("Failed to process metric '{}': {}", metaData.getPlugin(), e.getMessage());
+ LOG.warn("Failed to process metric '{}': {}", metaData.getPlugin(), e.getMessage());
} catch (IOException e) {
- LOG.error("Failed to send metric to collectd", e);
+ LOGGER.error("Failed to send metric to collectd", e);
LOG.error("Failed to send metric to collectd", e);
}
}
@@ -314,7 +309,7 @@ public class CollectdReporter extends ScheduledReporter {
} else if (metric.getValue() instanceof Boolean) {
write(metaData.typeInstance("value").get(), ((Boolean) metric.getValue()) ? 1 : 0);
} else {
- LOG.warn(
+ LOGGER.warn(
"Failed to process metric '{}'. Unsupported gauge of type: {} ",
metaData.get().getPlugin(),
metric.getValue().getClass().getName());
@@ -336,9 +331,9 @@ public class CollectdReporter extends ScheduledReporter {
private void serializeHistogram(MetaData.Builder metaData, Histogram metric) {
final Snapshot snapshot = metric.getSnapshot();
@@ -524,6 +476,26 @@
}
/**
--- a/metrics-core/src/main/java/io/dropwizard/metrics5/CsvReporter.java
+++ b/metrics-core/src/main/java/io/dropwizard/metrics5/CsvReporter.java
@@ -179,7 +179,7 @@ public class CsvReporter extends ScheduledReporter {
}
}
- private static final Logger LOGGER = LoggerFactory.getLogger(CsvReporter.class);
+ private static final Logger LOG = LoggerFactory.getLogger(CsvReporter.class);
private final File directory;
private final Locale locale;
@@ -391,7 +391,7 @@ public class CsvReporter extends ScheduledReporter {
}
}
} catch (IOException e) {
- LOGGER.warn("Error writing to {}", name, e);
+ LOG.warn("Error writing to {}", name, e);
}
}
--- a/metrics-core/src/main/java/io/dropwizard/metrics5/ExponentialMovingAverages.java
+++ b/metrics-core/src/main/java/io/dropwizard/metrics5/ExponentialMovingAverages.java
@@ -17,9 +17,9 @@ public class ExponentialMovingAverages implements MovingAverages {
@@ -1018,15 +990,6 @@
import java.util.Locale;
import java.util.Set;
import java.util.SortedMap;
@@ -24,7 +27,7 @@ import org.slf4j.LoggerFactory;
*/
public abstract class ScheduledReporter implements Closeable, Reporter {
- private static final Logger LOG = LoggerFactory.getLogger(ScheduledReporter.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(ScheduledReporter.class);
/** A simple named thread factory. */
@SuppressWarnings("NullableProblems")
@@ -128,7 +131,7 @@ public abstract class ScheduledReporter implements Closeable, Reporter {
durationUnit,
executor,
@@ -1077,33 +1040,6 @@
protected ScheduledFuture<?> getScheduledFuture(
long initialDelay, long period, TimeUnit unit, Runnable runnable) {
return getScheduledFuture(initialDelay, period, unit, runnable, this.executor);
@@ -225,7 +224,7 @@ public abstract class ScheduledReporter implements Closeable, Reporter {
try {
report();
} catch (Throwable ex) {
- LOG.error(
+ LOGGER.error(
"Exception thrown from {}#report. Exception was suppressed.",
ScheduledReporter.this.getClass().getSimpleName(),
ex);
@@ -250,7 +249,7 @@ public abstract class ScheduledReporter implements Closeable, Reporter {
try {
report();
} catch (Exception e) {
- LOG.warn("Final reporting of metrics failed.", e);
+ LOGGER.warn("Final reporting of metrics failed.", e);
}
}
@@ -261,7 +260,7 @@ public abstract class ScheduledReporter implements Closeable, Reporter {
executor.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!executor.awaitTermination(1, TimeUnit.SECONDS)) {
- LOG.warn("ScheduledExecutorService did not terminate.");
+ LOGGER.warn("ScheduledExecutorService did not terminate.");
}
}
} catch (InterruptedException ie) {
--- a/metrics-core/src/main/java/io/dropwizard/metrics5/SharedMetricRegistries.java
+++ b/metrics-core/src/main/java/io/dropwizard/metrics5/SharedMetricRegistries.java
@@ -1,5 +1,7 @@
@@ -1264,15 +1200,32 @@
import java.util.ArrayList;
import java.util.List;
@@ -15,7 +14,7 @@ import org.junit.jupiter.api.Test;
@@ -15,8 +14,8 @@ import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-class CachedGaugeTest {
- private static final Logger LOGGER = LoggerFactory.getLogger(CachedGaugeTest.class);
+final class CachedGaugeTest {
private static final Logger LOGGER = LoggerFactory.getLogger(CachedGaugeTest.class);
+ private static final Logger LOG = LoggerFactory.getLogger(CachedGaugeTest.class);
private static final int THREAD_COUNT = 10;
private static final long RUNNING_TIME_MILLIS = TimeUnit.SECONDS.toMillis(10);
@@ -100,12 +99,12 @@ class CachedGaugeTest {
Integer newValue = shortTimeoutGauge.getValue();
if (newValue == null) {
- LOGGER.warn("Cached gauge returned null value");
+ LOG.warn("Cached gauge returned null value");
return false;
}
if (newValue < lastValue) {
- LOGGER.error(
+ LOG.error(
"Cached gauge returned stale value, last: {}, new: {}",
lastValue,
newValue);
@@ -122,7 +121,7 @@ class CachedGaugeTest {
}
@@ -1946,16 +1899,29 @@
assertThat(histogram.getSnapshot()).isEqualTo(snapshot);
--- a/metrics-core/src/test/java/io/dropwizard/metrics5/InstrumentedExecutorServiceTest.java
+++ b/metrics-core/src/test/java/io/dropwizard/metrics5/InstrumentedExecutorServiceTest.java
@@ -19,7 +19,7 @@ import org.junit.jupiter.api.Test;
@@ -19,10 +19,9 @@ import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-class InstrumentedExecutorServiceTest {
+final class InstrumentedExecutorServiceTest {
private static final Logger LOGGER =
LoggerFactory.getLogger(InstrumentedExecutorServiceTest.class);
@@ -115,8 +115,8 @@ class InstrumentedExecutorServiceTest {
- private static final Logger LOGGER =
- LoggerFactory.getLogger(InstrumentedExecutorServiceTest.class);
+ private static final Logger LOG = LoggerFactory.getLogger(InstrumentedExecutorServiceTest.class);
private ExecutorService executor;
private MetricRegistry registry;
private InstrumentedExecutorService instrumentedExecutorService;
@@ -48,7 +47,7 @@ class InstrumentedExecutorServiceTest {
void tearDown() throws Exception {
instrumentedExecutorService.shutdown();
if (!instrumentedExecutorService.awaitTermination(2, TimeUnit.SECONDS)) {
- LOGGER.error("InstrumentedExecutorService did not terminate.");
+ LOG.error("InstrumentedExecutorService did not terminate.");
}
}
@@ -115,8 +114,8 @@ class InstrumentedExecutorServiceTest {
assertThat(idle.getSnapshot().size()).isEqualTo(1);
}
@@ -1965,7 +1931,7 @@
void reportsTasksInformationForThreadPoolExecutor() throws Exception {
executor =
new ThreadPoolExecutor(4, 16, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(32));
@@ -180,7 +180,7 @@ class InstrumentedExecutorServiceTest {
@@ -180,7 +179,7 @@ class InstrumentedExecutorServiceTest {
}
@Test
@@ -1974,7 +1940,7 @@
executor =
new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1));
instrumentedExecutorService = new InstrumentedExecutorService(executor, registry, "tp");
@@ -207,7 +207,7 @@ class InstrumentedExecutorServiceTest {
@@ -207,7 +206,7 @@ class InstrumentedExecutorServiceTest {
}
@Test
@@ -1983,7 +1949,7 @@
executor =
new ThreadPoolExecutor(4, 16, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(32));
instrumentedExecutorService = new InstrumentedExecutorService(executor, registry, "stp");
@@ -236,8 +236,8 @@ class InstrumentedExecutorServiceTest {
@@ -236,8 +235,8 @@ class InstrumentedExecutorServiceTest {
MetricRegistry.name("stp", "tasks.capacity"));
}
@@ -1993,7 +1959,7 @@
void reportsTasksInformationForForkJoinPool() throws Exception {
executor = Executors.newWorkStealingPool(4);
instrumentedExecutorService = new InstrumentedExecutorService(executor, registry, "fjp");
@@ -291,7 +291,7 @@ class InstrumentedExecutorServiceTest {
@@ -291,7 +290,7 @@ class InstrumentedExecutorServiceTest {
}
@Test
@@ -2004,15 +1970,17 @@
--- a/metrics-core/src/test/java/io/dropwizard/metrics5/InstrumentedScheduledExecutorServiceTest.java
+++ b/metrics-core/src/test/java/io/dropwizard/metrics5/InstrumentedScheduledExecutorServiceTest.java
@@ -13,7 +13,7 @@ import org.junit.jupiter.api.Test;
@@ -13,8 +13,8 @@ import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-class InstrumentedScheduledExecutorServiceTest {
- private static final Logger LOGGER =
+final class InstrumentedScheduledExecutorServiceTest {
private static final Logger LOGGER =
+ private static final Logger LOG =
LoggerFactory.getLogger(InstrumentedScheduledExecutorServiceTest.class);
private final ScheduledExecutorService scheduledExecutor =
@@ -35,17 +35,17 @@ class InstrumentedScheduledExecutorServiceTest {
private final Histogram percentOfPeriod = registry.histogram("xs.scheduled.percent-of-period");
@@ -2370,6 +2338,15 @@
assertThat(completed.getCount()).isNotEqualTo(0);
assertThat(duration.getCount()).isNotEqualTo(0);
assertThat(duration.getSnapshot().size()).isNotEqualTo(0);
@@ -322,7 +322,7 @@ class InstrumentedScheduledExecutorServiceTest {
void tearDown() throws Exception {
instrumentedScheduledExecutor.shutdown();
if (!instrumentedScheduledExecutor.awaitTermination(2, TimeUnit.SECONDS)) {
- LOGGER.error("InstrumentedScheduledExecutorService did not terminate.");
+ LOG.error("InstrumentedScheduledExecutorService did not terminate.");
}
}
}
--- a/metrics-core/src/test/java/io/dropwizard/metrics5/InstrumentedThreadFactoryTest.java
+++ b/metrics-core/src/test/java/io/dropwizard/metrics5/InstrumentedThreadFactoryTest.java
@@ -11,7 +11,7 @@ import java.util.concurrent.TimeUnit;
@@ -3051,16 +3028,17 @@
SharedMetricRegistries.getDefault();
});
- assertTrue(exception.getMessage().contains("Default registry name has not been set."));
+ assertThat(exception.getMessage()).contains("Default registry name has not been set.");
+ assertThat(exception.getMessage().contains("Default registry name has not been set.")).isTrue();
}
@Test
@@ -81,7 +80,7 @@ class SharedMetricRegistriesTest {
@@ -81,7 +80,8 @@ class SharedMetricRegistriesTest {
SharedMetricRegistries.setDefault("foobah");
SharedMetricRegistries.setDefault("borg");
});
- assertTrue(exception.getMessage().contains("Default metric registry name is already set."));
+ assertThat(exception.getMessage()).contains("Default metric registry name is already set.");
+ assertThat(exception.getMessage().contains("Default metric registry name is already set."))
+ .isTrue();
}
@Test
@@ -3824,6 +3802,15 @@
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
@@ -29,7 +32,7 @@ public class Graphite implements GraphiteSender {
private Writer writer;
private int failures;
- private static final Logger LOGGER = LoggerFactory.getLogger(Graphite.class);
+ private static final Logger LOG = LoggerFactory.getLogger(Graphite.class);
/**
* Creates a new client which connects to the given address using the default {@link
@@ -63,13 +66,9 @@ public class Graphite implements GraphiteSender {
* @param charset the character set used by the server
*/
@@ -3851,6 +3838,24 @@
InetSocketAddress address = this.address;
// the previous dns retry logic did not work, as address.getAddress would always return the
// cached value
@@ -178,7 +175,7 @@ public class Graphite implements GraphiteSender {
writer.close();
}
} catch (IOException ex) {
- LOGGER.debug("Error closing writer", ex);
+ LOG.debug("Error closing writer", ex);
} finally {
this.writer = null;
}
@@ -188,7 +185,7 @@ public class Graphite implements GraphiteSender {
socket.close();
}
} catch (IOException ex) {
- LOGGER.debug("Error closing socket", ex);
+ LOG.debug("Error closing socket", ex);
} finally {
this.socket = null;
}
--- a/metrics-graphite/src/main/java/io/dropwizard/metrics5/graphite/GraphiteRabbitMQ.java
+++ b/metrics-graphite/src/main/java/io/dropwizard/metrics5/graphite/GraphiteRabbitMQ.java
@@ -1,5 +1,6 @@
@@ -3919,7 +3924,39 @@
this.addMetricAttributesAsTags = false;
this.floatingPointFormatter = DEFAULT_FP_FORMATTER;
}
@@ -455,9 +453,9 @@ public class GraphiteReporter extends ScheduledReporter {
@@ -249,7 +247,7 @@ public class GraphiteReporter extends ScheduledReporter {
}
}
- private static final Logger LOGGER = LoggerFactory.getLogger(GraphiteReporter.class);
+ private static final Logger LOG = LoggerFactory.getLogger(GraphiteReporter.class);
// the Carbon plaintext format is pretty underspecified, but it seems like it just wants
// US-formatted digits
private static final DoubleFunction<String> DEFAULT_FP_FORMATTER =
@@ -430,12 +428,12 @@ public class GraphiteReporter extends ScheduledReporter {
}
graphite.flush();
} catch (IOException e) {
- LOGGER.warn("Unable to report to Graphite", graphite, e);
+ LOG.warn("Unable to report to Graphite", graphite, e);
} finally {
try {
graphite.close();
} catch (IOException e1) {
- LOGGER.warn("Error closing Graphite", graphite, e1);
+ LOG.warn("Error closing Graphite", graphite, e1);
}
}
}
@@ -448,16 +446,16 @@ public class GraphiteReporter extends ScheduledReporter {
try {
graphite.close();
} catch (IOException e) {
- LOGGER.debug("Error disconnecting from Graphite", graphite, e);
+ LOG.debug("Error disconnecting from Graphite", graphite, e);
}
}
}
private void reportTimer(MetricName name, Timer timer, long timestamp) throws IOException {
final Snapshot snapshot = timer.getSnapshot();
@@ -3981,6 +4018,15 @@
import static java.nio.charset.StandardCharsets.UTF_8;
import java.io.BufferedWriter;
@@ -48,7 +49,7 @@ public class PickledGraphite implements GraphiteSender {
QUOTE = '\'',
LF = '\n';
- private static final Logger LOGGER = LoggerFactory.getLogger(PickledGraphite.class);
+ private static final Logger LOG = LoggerFactory.getLogger(PickledGraphite.class);
private static final int DEFAULT_BATCH_SIZE = 100;
private int batchSize;
@@ -173,9 +174,7 @@ public class PickledGraphite implements GraphiteSender {
@Override
@@ -4001,6 +4047,17 @@
try {
byte[] payload = pickleMetrics(metrics);
byte[] header = ByteBuffer.allocate(4).putInt(payload.length).array();
@@ -260,8 +259,8 @@ public class PickledGraphite implements GraphiteSender {
outputStream.write(payload);
outputStream.flush();
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("Wrote {} metrics", metrics.size());
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Wrote {} metrics", metrics.size());
}
} catch (IOException e) {
this.failures++;
--- a/metrics-graphite/src/test/java/io/dropwizard/metrics5/graphite/GraphiteRabbitMQTest.java
+++ b/metrics-graphite/src/test/java/io/dropwizard/metrics5/graphite/GraphiteRabbitMQTest.java
@@ -8,7 +8,6 @@ import static org.mockito.Mockito.anyString;
@@ -4419,6 +4476,15 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -27,7 +29,7 @@ import org.slf4j.LoggerFactory;
/** A registry for health checks. */
public class HealthCheckRegistry {
- private static final Logger LOGGER = LoggerFactory.getLogger(HealthCheckRegistry.class);
+ private static final Logger LOG = LoggerFactory.getLogger(HealthCheckRegistry.class);
private static final int ASYNC_EXECUTOR_POOL_SIZE = 2;
private final ConcurrentMap<String, HealthCheck> healthChecks;
@@ -92,9 +94,8 @@ public class HealthCheckRegistry {
public void register(String name, HealthCheck healthCheck) {
HealthCheck registered;
@@ -4449,7 +4515,13 @@
}
/**
@@ -222,7 +223,7 @@ public class HealthCheckRegistry {
@@ -217,12 +218,12 @@ public class HealthCheckRegistry {
try {
results.put(entry.getKey(), entry.getValue().get());
} catch (Exception e) {
- LOGGER.warn("Error executing health check {}", entry.getKey(), e);
+ LOG.warn("Error executing health check {}", entry.getKey(), e);
results.put(entry.getKey(), HealthCheck.Result.unhealthy(e));
}
}
@@ -4871,25 +4943,27 @@
SharedHealthCheckRegistries.getDefault();
});
- assertTrue(exception.getMessage().contains("Default registry name has not been set."));
+ assertThat(exception.getMessage()).contains("Default registry name has not been set.");
+ assertThat(exception.getMessage().contains("Default registry name has not been set.")).isTrue();
}
@Test
@@ -85,7 +84,7 @@ class SharedHealthCheckRegistriesTest {
@@ -85,7 +84,8 @@ class SharedHealthCheckRegistriesTest {
SharedHealthCheckRegistries.setDefault("default");
SharedHealthCheckRegistries.setDefault("default");
});
- assertTrue(exception.getMessage().contains("Default health check registry is already set."));
+ assertThat(exception.getMessage()).contains("Default health check registry is already set.");
+ assertThat(exception.getMessage().contains("Default health check registry is already set."))
+ .isTrue();
}
@Test
@@ -97,6 +96,6 @@ class SharedHealthCheckRegistriesTest {
@@ -97,6 +97,7 @@ class SharedHealthCheckRegistriesTest {
SharedHealthCheckRegistries.setDefault("default", new HealthCheckRegistry());
SharedHealthCheckRegistries.setDefault("default", new HealthCheckRegistry());
});
- assertTrue(exception.getMessage().contains("Default health check registry is already set."));
+ assertThat(exception.getMessage()).contains("Default health check registry is already set.");
+ assertThat(exception.getMessage().contains("Default health check registry is already set."))
+ .isTrue();
}
}
--- a/metrics-healthchecks/src/test/java/io/dropwizard/metrics5/health/jvm/ThreadDeadlockHealthCheckTest.java
@@ -5063,7 +5137,7 @@
- Mockito.verify(registry, Mockito.atLeast(1)).registerGauge(argumentCaptor.capture(), any());
- assertTrue(argumentCaptor.getValue().getKey().contains("some-other-name"));
+ verify(registry, atLeast(1)).registerGauge(argumentCaptor.capture(), any());
+ assertThat(argumentCaptor.getValue().getKey()).contains("some-other-name");
+ assertThat(argumentCaptor.getValue().getKey().contains("some-other-name")).isTrue();
}
}
--- a/metrics-httpclient/src/test/java/io/dropwizard/metrics5/httpclient/InstrumentedHttpClientsTest.java
@@ -5141,7 +5215,7 @@
- Mockito.verify(registry, Mockito.atLeast(1)).registerGauge(argumentCaptor.capture(), any());
- assertTrue(argumentCaptor.getValue().getKey().contains("some-other-name"));
+ verify(registry, atLeast(1)).registerGauge(argumentCaptor.capture(), any());
+ assertThat(argumentCaptor.getValue().getKey()).contains("some-other-name");
+ assertThat(argumentCaptor.getValue().getKey().contains("some-other-name")).isTrue();
}
}
--- a/metrics-httpclient5/src/test/java/io/dropwizard/metrics5/httpclient5/InstrumentedHttpAsyncClientsTest.java
@@ -5231,7 +5305,7 @@
- Mockito.verify(registry, Mockito.atLeast(1)).registerGauge(argumentCaptor.capture(), any());
- assertTrue(argumentCaptor.getValue().getKey().contains("some-other-name"));
+ verify(registry, atLeast(1)).registerGauge(argumentCaptor.capture(), any());
+ assertThat(argumentCaptor.getValue().getKey()).contains("some-other-name");
+ assertThat(argumentCaptor.getValue().getKey().contains("some-other-name")).isTrue();
}
}
--- a/metrics-httpclient5/src/test/java/io/dropwizard/metrics5/httpclient5/InstrumentedHttpClientsTest.java
@@ -5286,6 +5360,39 @@
}
/**
@@ -196,7 +196,7 @@ public class InfluxDbReporter extends GarbageFreeScheduledReporter {
}
}
- private static final Logger LOGGER = LoggerFactory.getLogger(InfluxDbReporter.class);
+ private static final Logger LOG = LoggerFactory.getLogger(InfluxDbReporter.class);
private static final String VALUE = "value";
private final Clock clock;
@@ -279,12 +279,12 @@ public class InfluxDbReporter extends GarbageFreeScheduledReporter {
}
sender.flush();
} catch (IOException e) {
- LOGGER.warn("Unable to report to InfluxDb", sender, e);
+ LOG.warn("Unable to report to InfluxDb", sender, e);
} finally {
try {
sender.disconnect();
} catch (IOException e) {
- LOGGER.warn("Error disconnecting InfluxDb", sender, e);
+ LOG.warn("Error disconnecting InfluxDb", sender, e);
}
}
}
@@ -297,7 +297,7 @@ public class InfluxDbReporter extends GarbageFreeScheduledReporter {
try {
sender.close();
} catch (IOException e) {
- LOGGER.debug("Error disconnecting from InfluxDb", e);
+ LOG.debug("Error disconnecting from InfluxDb", e);
}
}
}
--- a/metrics-influxdb/src/main/java/io/dropwizard/metrics5/influxdb/InfluxDbUdpSender.java
+++ b/metrics-influxdb/src/main/java/io/dropwizard/metrics5/influxdb/InfluxDbUdpSender.java
@@ -1,5 +1,7 @@
@@ -5961,6 +6068,15 @@
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
@@ -33,7 +33,7 @@ public class JCacheGaugeSet implements MetricSet {
private static final String M_BEAN_COORDINATES =
"javax.cache:type=CacheStatistics,CacheManager=*,Cache=*";
- private static final Logger LOGGER = LoggerFactory.getLogger(JCacheGaugeSet.class);
+ private static final Logger LOG = LoggerFactory.getLogger(JCacheGaugeSet.class);
@Override
public Map<MetricName, Metric> getMetrics() {
@@ -52,7 +52,7 @@ public class JCacheGaugeSet implements MetricSet {
}
}
@@ -5970,6 +6086,15 @@
}
private Set<ObjectInstance> getCacheBeans() {
@@ -60,7 +60,7 @@ public class JCacheGaugeSet implements MetricSet {
return ManagementFactory.getPlatformMBeanServer()
.queryMBeans(ObjectName.getInstance(M_BEAN_COORDINATES), null);
} catch (MalformedObjectNameException e) {
- LOGGER.error("Unable to retrieve {}. Are JCache statistics enabled?", M_BEAN_COORDINATES);
+ LOG.error("Unable to retrieve {}. Are JCache statistics enabled?", M_BEAN_COORDINATES);
throw new RuntimeException(e);
}
}
--- a/metrics-jcache/src/test/java/JCacheGaugeSetTest.java
+++ b/metrics-jcache/src/test/java/JCacheGaugeSetTest.java
@@ -11,7 +11,7 @@ import org.junit.jupiter.api.AfterEach;
@@ -8339,11 +8464,11 @@
private static final char[] QUOTABLE_CHARS = new char[] {',', '=', ':', '"'};
- private static final Logger LOGGER = LoggerFactory.getLogger(JmxReporter.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(DefaultObjectNameFactory.class);
+ private static final Logger LOG = LoggerFactory.getLogger(DefaultObjectNameFactory.class);
@Override
public ObjectName createName(String type, String domain, MetricName name) {
@@ -38,9 +38,8 @@ public class DefaultObjectNameFactory implements ObjectNameFactory {
@@ -38,14 +38,13 @@ public class DefaultObjectNameFactory implements ObjectNameFactory {
|| shouldQuote(objectName.getKeyProperty("type"))) {
properties.put("type", ObjectName.quote(type));
}
@@ -8354,6 +8479,12 @@
} catch (MalformedObjectNameException e) {
try {
return new ObjectName(domain, "name", ObjectName.quote(name.getKey()));
} catch (MalformedObjectNameException e1) {
- LOGGER.warn("Unable to register {} {}", type, name, e1);
+ LOG.warn("Unable to register {} {}", type, name, e1);
throw new RuntimeException(e1);
}
}
--- a/metrics-jmx/src/main/java/io/dropwizard/metrics5/jmx/JmxReporter.java
+++ b/metrics-jmx/src/main/java/io/dropwizard/metrics5/jmx/JmxReporter.java
@@ -1,5 +1,9 @@
@@ -8414,6 +8545,147 @@
return this;
}
@@ -159,7 +160,7 @@ public class JmxReporter implements Reporter, Closeable {
}
}
- private static final Logger LOGGER = LoggerFactory.getLogger(JmxReporter.class);
+ private static final Logger LOG = LoggerFactory.getLogger(JmxReporter.class);
@SuppressWarnings("UnusedDeclaration")
public interface MetricMBean {
@@ -570,9 +571,9 @@ public class JmxReporter implements Reporter, Closeable {
registerMBean(new JmxGauge(gauge, objectName), objectName);
}
} catch (InstanceAlreadyExistsException e) {
- LOGGER.debug("Unable to register gauge", e);
+ LOG.debug("Unable to register gauge", e);
} catch (JMException e) {
- LOGGER.warn("Unable to register gauge", e);
+ LOG.warn("Unable to register gauge", e);
}
}
@@ -582,9 +583,9 @@ public class JmxReporter implements Reporter, Closeable {
final ObjectName objectName = createName("gauges", name);
unregisterMBean(objectName);
} catch (InstanceNotFoundException e) {
- LOGGER.debug("Unable to unregister gauge", e);
+ LOG.debug("Unable to unregister gauge", e);
} catch (MBeanRegistrationException e) {
- LOGGER.warn("Unable to unregister gauge", e);
+ LOG.warn("Unable to unregister gauge", e);
}
}
@@ -596,9 +597,9 @@ public class JmxReporter implements Reporter, Closeable {
registerMBean(new JmxCounter(counter, objectName), objectName);
}
} catch (InstanceAlreadyExistsException e) {
- LOGGER.debug("Unable to register counter", e);
+ LOG.debug("Unable to register counter", e);
} catch (JMException e) {
- LOGGER.warn("Unable to register counter", e);
+ LOG.warn("Unable to register counter", e);
}
}
@@ -608,9 +609,9 @@ public class JmxReporter implements Reporter, Closeable {
final ObjectName objectName = createName("counters", name);
unregisterMBean(objectName);
} catch (InstanceNotFoundException e) {
- LOGGER.debug("Unable to unregister counter", e);
+ LOG.debug("Unable to unregister counter", e);
} catch (MBeanRegistrationException e) {
- LOGGER.warn("Unable to unregister counter", e);
+ LOG.warn("Unable to unregister counter", e);
}
}
@@ -622,9 +623,9 @@ public class JmxReporter implements Reporter, Closeable {
registerMBean(new JmxHistogram(histogram, objectName), objectName);
}
} catch (InstanceAlreadyExistsException e) {
- LOGGER.debug("Unable to register histogram", e);
+ LOG.debug("Unable to register histogram", e);
} catch (JMException e) {
- LOGGER.warn("Unable to register histogram", e);
+ LOG.warn("Unable to register histogram", e);
}
}
@@ -634,9 +635,9 @@ public class JmxReporter implements Reporter, Closeable {
final ObjectName objectName = createName("histograms", name);
unregisterMBean(objectName);
} catch (InstanceNotFoundException e) {
- LOGGER.debug("Unable to unregister histogram", e);
+ LOG.debug("Unable to unregister histogram", e);
} catch (MBeanRegistrationException e) {
- LOGGER.warn("Unable to unregister histogram", e);
+ LOG.warn("Unable to unregister histogram", e);
}
}
@@ -649,9 +650,9 @@ public class JmxReporter implements Reporter, Closeable {
new JmxMeter(meter, objectName, timeUnits.rateFor(name.getKey())), objectName);
}
} catch (InstanceAlreadyExistsException e) {
- LOGGER.debug("Unable to register meter", e);
+ LOG.debug("Unable to register meter", e);
} catch (JMException e) {
- LOGGER.warn("Unable to register meter", e);
+ LOG.warn("Unable to register meter", e);
}
}
@@ -661,9 +662,9 @@ public class JmxReporter implements Reporter, Closeable {
final ObjectName objectName = createName("meters", name);
unregisterMBean(objectName);
} catch (InstanceNotFoundException e) {
- LOGGER.debug("Unable to unregister meter", e);
+ LOG.debug("Unable to unregister meter", e);
} catch (MBeanRegistrationException e) {
- LOGGER.warn("Unable to unregister meter", e);
+ LOG.warn("Unable to unregister meter", e);
}
}
@@ -681,9 +682,9 @@ public class JmxReporter implements Reporter, Closeable {
objectName);
}
} catch (InstanceAlreadyExistsException e) {
- LOGGER.debug("Unable to register timer", e);
+ LOG.debug("Unable to register timer", e);
} catch (JMException e) {
- LOGGER.warn("Unable to register timer", e);
+ LOG.warn("Unable to register timer", e);
}
}
@@ -693,9 +694,9 @@ public class JmxReporter implements Reporter, Closeable {
final ObjectName objectName = createName("timers", name);
unregisterMBean(objectName);
} catch (InstanceNotFoundException e) {
- LOGGER.debug("Unable to unregister timer", e);
+ LOG.debug("Unable to unregister timer", e);
} catch (MBeanRegistrationException e) {
- LOGGER.warn("Unable to unregister timer", e);
+ LOG.warn("Unable to unregister timer", e);
}
}
@@ -708,9 +709,9 @@ public class JmxReporter implements Reporter, Closeable {
try {
unregisterMBean(name);
} catch (InstanceNotFoundException e) {
- LOGGER.debug("Unable to unregister metric", e);
+ LOG.debug("Unable to unregister metric", e);
} catch (MBeanRegistrationException e) {
- LOGGER.warn("Unable to unregister metric", e);
+ LOG.warn("Unable to unregister metric", e);
}
}
registered.clear();
--- a/metrics-jmx/src/test/java/io/dropwizard/metrics5/jmx/DefaultObjectNameFactoryTest.java
+++ b/metrics-jmx/src/test/java/io/dropwizard/metrics5/jmx/DefaultObjectNameFactoryTest.java
@@ -7,7 +7,7 @@ import io.dropwizard.metrics5.MetricName;
@@ -8733,7 +9005,21 @@
import java.util.HashMap;
import java.util.Map;
import javax.management.JMException;
@@ -47,6 +48,6 @@ public class BufferPoolMetricSet implements MetricSet {
@@ -19,7 +20,7 @@ import org.slf4j.LoggerFactory;
* <p>These JMX objects are only available on Java 7 and above.
*/
public class BufferPoolMetricSet implements MetricSet {
- private static final Logger LOGGER = LoggerFactory.getLogger(BufferPoolMetricSet.class);
+ private static final Logger LOG = LoggerFactory.getLogger(BufferPoolMetricSet.class);
private static final String[] ATTRIBUTES = {"Count", "MemoryUsed", "TotalCapacity"};
private static final String[] NAMES = {"count", "used", "capacity"};
private static final String[] POOLS = {"direct", "mapped"};
@@ -43,10 +44,10 @@ public class BufferPoolMetricSet implements MetricSet {
gauges.put(
MetricRegistry.name(pool, name), new JmxAttributeGauge(mBeanServer, on, attribute));
} catch (JMException ignored) {
- LOGGER.debug("Unable to load buffer pool MBeans, possibly running on Java 6");
+ LOG.debug("Unable to load buffer pool MBeans, possibly running on Java 6");
}
}
}

View File

@@ -9,9 +9,9 @@ metrics-collectd/src/main/java/io/dropwizard/metrics5/collectd/PacketWriter.java
metrics-core/src/main/java/io/dropwizard/metrics5/CsvReporter.java:[390,35] [FormatStringConcatenation] Defer string concatenation to the invoked method
metrics-core/src/main/java/io/dropwizard/metrics5/InstrumentedExecutorService.java:[244,25] [try] auto-closeable resource durationContext is never referenced in body of corresponding try statement
metrics-core/src/main/java/io/dropwizard/metrics5/InstrumentedExecutorService.java:[266,25] [try] auto-closeable resource context is never referenced in body of corresponding try statement
metrics-graphite/src/main/java/io/dropwizard/metrics5/graphite/GraphiteReporter.java:[431,17] [Slf4jLogStatement] Log statement contains 0 placeholders, but specifies 1 matching argument(s)
metrics-graphite/src/main/java/io/dropwizard/metrics5/graphite/GraphiteReporter.java:[436,19] [Slf4jLogStatement] Log statement contains 0 placeholders, but specifies 1 matching argument(s)
metrics-graphite/src/main/java/io/dropwizard/metrics5/graphite/GraphiteReporter.java:[449,20] [Slf4jLogStatement] Log statement contains 0 placeholders, but specifies 1 matching argument(s)
metrics-graphite/src/main/java/io/dropwizard/metrics5/graphite/GraphiteReporter.java:[431,14] [Slf4jLogStatement] Log statement contains 0 placeholders, but specifies 1 matching argument(s)
metrics-graphite/src/main/java/io/dropwizard/metrics5/graphite/GraphiteReporter.java:[436,16] [Slf4jLogStatement] Log statement contains 0 placeholders, but specifies 1 matching argument(s)
metrics-graphite/src/main/java/io/dropwizard/metrics5/graphite/GraphiteReporter.java:[449,17] [Slf4jLogStatement] Log statement contains 0 placeholders, but specifies 1 matching argument(s)
metrics-healthchecks/src/test/java/io/dropwizard/metrics5/health/HealthCheckTest.java:[189,46] [TimeZoneUsage] Derive the current time from an existing `Clock` Spring bean, and don't rely on a `Clock`'s time zone
metrics-healthchecks/src/test/java/io/dropwizard/metrics5/health/HealthCheckTest.java:[203,46] [TimeZoneUsage] Derive the current time from an existing `Clock` Spring bean, and don't rely on a `Clock`'s time zone
metrics-httpclient/src/test/java/io/dropwizard/metrics5/httpclient/HttpClientMetricNameStrategiesTest.java:[124,22] [deprecation] rewriteURI(URI,HttpHost,boolean) in URIUtils has been deprecated
@@ -26,8 +26,8 @@ metrics-httpclient5/src/main/java/io/dropwizard/metrics5/httpclient5/Instrumente
metrics-httpclient5/src/main/java/io/dropwizard/metrics5/httpclient5/InstrumentedHttpRequestExecutor.java:[49,4] [deprecation] HttpRequestExecutor(Timeout,ConnectionReuseStrategy,Http1StreamListener) in HttpRequestExecutor has been deprecated
metrics-httpclient5/src/test/java/io/dropwizard/metrics5/httpclient5/InstrumentedHttpClientsTest.java:[46,10] [deprecation] execute(ClassicHttpRequest) in HttpClient has been deprecated
metrics-httpclient5/src/test/java/io/dropwizard/metrics5/httpclient5/InstrumentedHttpClientsTest.java:[68,12] [deprecation] execute(ClassicHttpRequest) in HttpClient has been deprecated
metrics-influxdb/src/main/java/io/dropwizard/metrics5/influxdb/InfluxDbReporter.java:[282,17] [Slf4jLogStatement] Log statement contains 0 placeholders, but specifies 1 matching argument(s)
metrics-influxdb/src/main/java/io/dropwizard/metrics5/influxdb/InfluxDbReporter.java:[287,19] [Slf4jLogStatement] Log statement contains 0 placeholders, but specifies 1 matching argument(s)
metrics-influxdb/src/main/java/io/dropwizard/metrics5/influxdb/InfluxDbReporter.java:[282,14] [Slf4jLogStatement] Log statement contains 0 placeholders, but specifies 1 matching argument(s)
metrics-influxdb/src/main/java/io/dropwizard/metrics5/influxdb/InfluxDbReporter.java:[287,16] [Slf4jLogStatement] Log statement contains 0 placeholders, but specifies 1 matching argument(s)
metrics-jakarta-servlets/src/test/java/io/dropwizard/metrics5/servlets/HealthCheckServletTest.java:[31,67] [TimeZoneUsage] Derive the current time from an existing `Clock` Spring bean, and don't rely on a `Clock`'s time zone
metrics-jdbi3/src/test/java/io/dropwizard/metrics5/jdbi3/strategies/SmartNameStrategyTest.java:[18,10] [deprecation] InstrumentedTimingCollector in io.dropwizard.metrics5.jdbi3 has been deprecated
metrics-jdbi3/src/test/java/io/dropwizard/metrics5/jdbi3/strategies/SmartNameStrategyTest.java:[24,20] [deprecation] InstrumentedTimingCollector in io.dropwizard.metrics5.jdbi3 has been deprecated

View File

@@ -38,7 +38,7 @@
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>33.4.7-jre<!-- Renovate: com.google.guava:guava-bom --></version>
+ <version>33.4.0-jre<!-- Renovate: com.google.guava:guava-bom --></version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>

View File

@@ -8,7 +8,11 @@ repository='https://github.com/dropwizard/metrics.git'
revision='v5.0.0-rc22'
additional_build_flags=''
additional_source_directories=''
shared_error_prone_flags='-XepExcludedPaths:.*/target/generated-sources/.* -XepOpt:Slf4jLoggerDeclaration:CanonicalStaticLoggerName=LOGGER'
# XXX: Minimize the diff by including
# `-XepOpt:Slf4jLoggerDeclaration:CanonicalStaticLoggerName=LOGGER` once such
# flags are supported in patch mode. See
# https://github.com/google/error-prone/pull/4699.
shared_error_prone_flags='-XepExcludedPaths:.*/target/generated-sources/.*'
patch_error_prone_flags=''
validation_error_prone_flags=''
validation_build_flags=''

View File

@@ -4459,15 +4459,6 @@
"values from otel have precedence over builder",
new TestCase()
.expectedProperties(
@@ -113,7 +113,7 @@ class OtelAutoConfigTest {
.put("otel.exporter.otlp.timeout", Optional.of("13s"))
.put("otel.exporter.otlp.metrics.timeout", Optional.empty())
.put("otel.service.name", Optional.of("otel-service"))
- .build())
+ .buildOrThrow())
.expectedResourceAttributes(
ImmutableMap.of(
"key",
@@ -128,7 +128,7 @@ class OtelAutoConfigTest {
"otel-version"))
.exporterBuilder(OtelAutoConfigTest::setBuilderValues)
@@ -4477,44 +4468,15 @@
"values from prom properties have precedence over builder and otel",
new TestCase()
.expectedProperties(
@@ -143,7 +143,7 @@ class OtelAutoConfigTest {
.put("otel.exporter.otlp.metrics.timeout", Optional.of("23s"))
.put("otel.exporter.otlp.timeout", Optional.of("13s"))
.put("otel.service.name", Optional.of("prom-service"))
- .build())
+ .buildOrThrow())
.expectedResourceAttributes(
ImmutableMap.of(
"key",
@@ -176,8 +176,8 @@ class OtelAutoConfigTest {
.put(
@@ -177,7 +177,7 @@ class OtelAutoConfigTest {
"io.prometheus.exporter.opentelemetry.resourceAttributes",
"key=prom-value")
- .build())),
.build())),
- Arguments.of(
+ .buildOrThrow())),
+ arguments(
"values from prom properties builder have precedence over builder and otel",
new TestCase()
.expectedProperties(
@@ -192,7 +192,7 @@ class OtelAutoConfigTest {
.put("otel.exporter.otlp.metrics.timeout", Optional.of("23s"))
.put("otel.exporter.otlp.timeout", Optional.of("13s"))
.put("otel.service.name", Optional.of("prom-service"))
- .build())
+ .buildOrThrow())
.expectedResourceAttributes(
ImmutableMap.of(
"key",
@@ -233,7 +233,7 @@ class OtelAutoConfigTest {
.put(
"otel.resource.attributes",
"key=otel-value,service.namespace=otel-namespace,service.instance.id=otel-instance,service.version=otel-version")
- .build();
+ .buildOrThrow();
}
private static void setBuilderValues(OpenTelemetryExporter.Builder builder) {
@@ -250,8 +250,8 @@ class OtelAutoConfigTest {
.resourceAttribute("key", "builder-value");
}
@@ -4603,12 +4565,7 @@
}
--- a/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricDataTest.java
+++ b/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricDataTest.java
@@ -3,14 +3,15 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel;
import static java.util.Map.entry;
import static org.junit.jupiter.api.Assertions.*;
+import com.google.common.collect.ImmutableMap;
import io.prometheus.metrics.model.snapshots.Unit;
@@ -7,7 +7,7 @@ import io.prometheus.metrics.model.snapshots.Unit;
import java.util.Map;
import org.junit.jupiter.api.Test;
@@ -4616,11 +4573,7 @@
+final class PrometheusMetricDataTest {
Map<Object, Object> translations =
- Map.ofEntries(
+ ImmutableMap.ofEntries(
entry("days", "d"),
entry("hours", "h"),
entry("minutes", "min"),
Map.ofEntries(
--- a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/DefaultJobLabelDetector.java
+++ b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/DefaultJobLabelDetector.java
@@ -3,7 +3,6 @@ package io.prometheus.metrics.exporter.pushgateway;
@@ -5968,7 +5921,7 @@
import static io.prometheus.metrics.instrumentation.dropwizard5.labels.MapperConfig.METRIC_GLOB_REGEX;
import java.util.HashMap;
@@ -32,10 +33,11 @@ class GraphiteNamePattern {
@@ -32,10 +33,9 @@ class GraphiteNamePattern {
* @param pattern The glob style pattern to be used.
*/
GraphiteNamePattern(final String pattern) throws IllegalArgumentException {
@@ -5978,13 +5931,11 @@
- }
+ checkArgument(
+ VALIDATION_PATTERN.matcher(pattern).matches(),
+ "Provided pattern [%s] does not matches [%s]",
+ pattern,
+ METRIC_GLOB_REGEX);
+ String.format("Provided pattern [%s] does not matches [%s]", pattern, METRIC_GLOB_REGEX));
initializePattern(pattern);
}
@@ -84,7 +86,7 @@ class GraphiteNamePattern {
@@ -84,7 +84,7 @@ class GraphiteNamePattern {
escapedPattern.append("([^.]*)").append(quoted);
}
@@ -6003,7 +5954,7 @@
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
@@ -106,21 +108,21 @@ public final class MapperConfig {
@@ -106,21 +108,19 @@ public final class MapperConfig {
}
private void validateMatch(final String match) {
@@ -6015,9 +5966,9 @@
- }
+ checkArgument(
+ MATCH_EXPRESSION_PATTERN.matcher(match).matches(),
+ "Match expression [%s] does not match required pattern %s",
+ match,
+ MATCH_EXPRESSION_PATTERN);
+ String.format(
+ "Match expression [%s] does not match required pattern %s",
+ match, MATCH_EXPRESSION_PATTERN));
}
private void validateLabels(final Map<String, String> labels) {
@@ -6029,13 +5980,11 @@
- }
+ checkArgument(
+ LABEL_PATTERN.matcher(key).matches(),
+ "Label [%s] does not match required pattern %s",
+ match,
+ LABEL_PATTERN);
+ String.format("Label [%s] does not match required pattern %s", match, LABEL_PATTERN));
}
}
}
@@ -149,7 +151,6 @@ public final class MapperConfig {
@@ -149,7 +149,6 @@ public final class MapperConfig {
public int hashCode() {
int result = match != null ? match.hashCode() : 0;
result = 31 * result + (name != null ? name.hashCode() : 0);

270
pom.xml
View File

@@ -4,7 +4,7 @@
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.22.1-SNAPSHOT</version>
<version>0.19.2-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Picnic :: Error Prone Support</name>
@@ -113,7 +113,7 @@
-Xmx${argLine.xmx}
<!-- Configure the Byte Buddy Java agent used by Mockito to create
mocks. -->
-javaagent:${project.build.directory}/test-agents/mockito-core.jar
-javaagent:${org.mockito:mockito-core:jar}
<!-- This argument cannot be set through Surefire's
'systemPropertyVariables' configuration setting. Setting the file
encoding is necessary because forked unit test invocations
@@ -144,9 +144,14 @@
specified. Used by the `patch` and `self-check` profiles. -->
<error-prone.patch-args />
<error-prone.self-check-args />
<!-- The Maven `groupId` under which Error Prone dependencies are
published. We use an official Error Prone release by default. This
property allows the `error-prone-fork` profile below to build the
project using Picnic's Error Prone fork instead. -->
<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>2025-04-14T09:36:15Z</project.build.outputTimestamp>
<project.build.outputTimestamp>2024-11-03T15:58:19Z</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
@@ -205,22 +210,47 @@
<version.auto-service>1.1.1</version.auto-service>
<version.auto-value>1.11.0</version.auto-value>
<version.error-prone>${version.error-prone-orig}</version.error-prone>
<version.error-prone-fork>${version.error-prone-orig}-picnic-1</version.error-prone-fork>
<version.error-prone-orig>2.37.0</version.error-prone-orig>
<version.error-prone-fork>v${version.error-prone-orig}-picnic-1</version.error-prone-fork>
<version.error-prone-orig>2.36.0</version.error-prone-orig>
<version.error-prone-slf4j>0.1.28</version.error-prone-slf4j>
<version.guava-beta-checker>1.0</version.guava-beta-checker>
<version.jdk>17</version.jdk>
<version.maven>3.9.9</version.maven>
<version.mockito>5.17.0</version.mockito>
<version.mockito>5.14.2</version.mockito>
<version.nopen-checker>1.0.1</version.nopen-checker>
<version.nullaway>0.12.6</version.nullaway>
<version.pitest-git>2.2.1</version.pitest-git>
<version.rewrite-templating>1.25.1</version.rewrite-templating>
<version.nullaway>0.12.2</version.nullaway>
<version.pitest-git>1.1.4</version.pitest-git>
<version.rewrite-templating>1.20.2</version.rewrite-templating>
<version.surefire>3.2.3</version.surefire>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_annotation</artifactId>
<version>${version.error-prone}</version>
</dependency>
<dependency>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_annotations</artifactId>
<version>${version.error-prone}</version>
</dependency>
<dependency>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_check_api</artifactId>
<version>${version.error-prone}</version>
</dependency>
<dependency>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_core</artifactId>
<version>${version.error-prone}</version>
</dependency>
<dependency>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_test_helpers</artifactId>
<version>${version.error-prone}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>documentation-support</artifactId>
@@ -269,14 +299,14 @@
<dependency>
<groupId>com.fasterxml.jackson</groupId>
<artifactId>jackson-bom</artifactId>
<version>2.18.3</version>
<version>2.18.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>3.2.0</version>
<version>3.1.8</version>
</dependency>
<dependency>
<groupId>com.google.auto</groupId>
@@ -303,45 +333,10 @@
<artifactId>auto-value-annotations</artifactId>
<version>${version.auto-value}</version>
</dependency>
<!-- XXX: JSR-305 (meta-)annotation usage by some dependencies
triggers NullAway to attempt to load said annotations. As such
some modules require these annotations to be on the classpath.
Periodically review whether we can drop this dependeny version
declaration. See https://github.com/uber/NullAway/issues/1171. -->
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_annotation</artifactId>
<version>${version.error-prone}</version>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_annotations</artifactId>
<version>${version.error-prone}</version>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_check_api</artifactId>
<version>${version.error-prone}</version>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_core</artifactId>
<version>${version.error-prone}</version>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_test_helpers</artifactId>
<version>${version.error-prone}</version>
</dependency>
<dependency>
<groupId>com.google.googlejavaformat</groupId>
<artifactId>google-java-format</artifactId>
<version>1.26.0</version>
<version>1.25.2</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
@@ -351,7 +346,7 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava-bom</artifactId>
<version>33.4.7-jre</version>
<version>33.4.0-jre</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@@ -373,14 +368,14 @@
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-bom</artifactId>
<version>1.14.6</version>
<version>1.14.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-bom</artifactId>
<version>2024.0.5</version>
<version>2024.0.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@@ -392,12 +387,12 @@
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.6.15</version>
<version>1.6.14</version>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
<version>2.2.30</version>
<version>2.2.27</version>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
@@ -432,7 +427,7 @@
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>1.17.5</version>
<version>1.15.11</version>
</dependency>
<!-- Specified so that Renovate will file Maven upgrade PRs, which
subsequently will cause `maven-enforcer-plugin` to require that
@@ -445,19 +440,19 @@
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.24</version>
<version>1.9.22.1</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-bom</artifactId>
<version>3.27.3</version>
<version>3.27.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.checkerframework</groupId>
<artifactId>checker-qual</artifactId>
<version>3.49.2</version>
<version>3.48.3</version>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
@@ -472,7 +467,7 @@
<dependency>
<groupId>org.jooq</groupId>
<artifactId>jooq</artifactId>
<version>3.19.18</version>
<version>3.19.16</version>
</dependency>
<dependency>
<groupId>org.jspecify</groupId>
@@ -482,7 +477,7 @@
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.12.2</version>
<version>5.11.4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@@ -495,10 +490,8 @@
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-bom</artifactId>
<version>5.4.0</version>
<type>pom</type>
<scope>import</scope>
<artifactId>mongodb-driver-core</artifactId>
<version>5.2.1</version>
</dependency>
<dependency>
<groupId>org.openrewrite</groupId>
@@ -508,40 +501,40 @@
<dependency>
<groupId>org.openrewrite.recipe</groupId>
<artifactId>rewrite-recipe-bom</artifactId>
<version>3.6.1</version>
<version>2.23.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-bom</artifactId>
<version>2.0.17</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.2.5</version>
<version>6.2.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<version>3.4.4</version>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-bom</artifactId>
<version>6.4.4</version>
<version>6.4.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.11.0</version>
<version>7.10.2</version>
</dependency>
</dependencies>
</dependencyManagement>
@@ -560,16 +553,6 @@
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>com.arcmutate</groupId>
<artifactId>pitest-git-maven-plugin</artifactId>
<version>${version.pitest-git}</version>
</plugin>
<plugin>
<groupId>com.arcmutate</groupId>
<artifactId>pitest-github-maven-plugin</artifactId>
<version>${version.pitest-git}</version>
</plugin>
<plugin>
<groupId>com.github.ekryd.sortpom</groupId>
<artifactId>sortpom-maven-plugin</artifactId>
@@ -597,6 +580,16 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.groupcdg</groupId>
<artifactId>pitest-git-maven-plugin</artifactId>
<version>${version.pitest-git}</version>
</plugin>
<plugin>
<groupId>com.groupcdg</groupId>
<artifactId>pitest-github-maven-plugin</artifactId>
<version>${version.pitest-git}</version>
</plugin>
<plugin>
<groupId>com.spotify.fmt</groupId>
<artifactId>fmt-maven-plugin</artifactId>
@@ -620,7 +613,7 @@
<plugin>
<groupId>de.thetaphi</groupId>
<artifactId>forbiddenapis</artifactId>
<version>3.9</version>
<version>3.8</version>
<configuration>
<bundledSignatures>
<bundledSignature>jdk-internal</bundledSignature>
@@ -935,7 +928,7 @@
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>10.23.0</version>
<version>10.21.0</version>
</dependency>
<dependency>
<groupId>io.spring.nohttp</groupId>
@@ -955,12 +948,12 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>3.4.1</version>
<version>3.4.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.14.0</version>
<version>3.13.0</version>
<configuration>
<annotationProcessorPaths>
<!-- XXX: Inline and drop the version
@@ -1052,23 +1045,17 @@
</configuration>
<executions>
<execution>
<id>copy-test-agents</id>
<id>set-additional-properties</id>
<goals>
<goal>copy-dependencies</goal>
<goal>properties</goal>
</goals>
<configuration>
<includeGroupIds>org.mockito</includeGroupIds>
<includeArtifactIds>mockito-core</includeArtifactIds>
<stripVersion>true</stripVersion>
<outputDirectory>${project.build.directory}/test-agents</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>3.1.4</version>
<version>3.1.3</version>
<configuration>
<retryFailedDeploymentCount>3</retryFailedDeploymentCount>
</configuration>
@@ -1146,7 +1133,7 @@
<dependency>
<groupId>org.codehaus.mojo</groupId>
<artifactId>extra-enforcer-rules</artifactId>
<version>1.10.0</version>
<version>1.9.0</version>
</dependency>
</dependencies>
<executions>
@@ -1174,7 +1161,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>3.1.4</version>
<version>3.1.3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -1310,7 +1297,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.5.3</version>
<version>3.5.2</version>
<configuration>
<includes>
<include>**/*Test.java</include>
@@ -1318,7 +1305,6 @@
<properties>
<configurationParameters>junit.jupiter.execution.parallel.enabled=true
junit.jupiter.execution.parallel.mode.default=concurrent
junit.jupiter.execution.timeout.threaddump.enabled=true
junit.platform.stacktrace.pruning.enabled=false</configurationParameters>
</properties>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
@@ -1455,7 +1441,7 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tidy-maven-plugin</artifactId>
<version>1.4.0</version>
<version>1.3.0</version>
<executions>
<execution>
<id>check-pom</id>
@@ -1476,7 +1462,7 @@
<plugin>
<groupId>org.gaul</groupId>
<artifactId>modernizer-maven-plugin</artifactId>
<version>3.1.0</version>
<version>2.9.0</version>
<configuration>
<exclusionPatterns>
<!-- The plugin suggests replacing usages of
@@ -1507,7 +1493,7 @@
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.13</version>
<version>0.8.12</version>
<configuration>
<excludes>
<!-- Refaster rules are tested using a custom method
@@ -1537,7 +1523,7 @@
<plugin>
<groupId>org.pitest</groupId>
<artifactId>pitest-maven</artifactId>
<version>1.19.1</version>
<version>1.17.3</version>
<configuration>
<excludedClasses>
<!-- AutoValue generated classes. -->
@@ -1559,24 +1545,24 @@
</configuration>
<dependencies>
<dependency>
<groupId>com.arcmutate</groupId>
<artifactId>base</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>com.arcmutate</groupId>
<artifactId>pitest-accelerator-junit5</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>com.arcmutate</groupId>
<groupId>com.groupcdg</groupId>
<artifactId>pitest-git-plugin</artifactId>
<version>${version.pitest-git}</version>
</dependency>
<dependency>
<groupId>com.groupcdg.arcmutate</groupId>
<artifactId>base</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>com.groupcdg.pitest</groupId>
<artifactId>pitest-accelerator-junit5</artifactId>
<version>1.0.6</version>
</dependency>
<dependency>
<groupId>org.pitest</groupId>
<artifactId>pitest-junit5-plugin</artifactId>
<version>1.2.2</version>
<version>1.2.1</version>
</dependency>
</dependencies>
<executions>
@@ -1591,7 +1577,7 @@
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>5.1.0.4751</version>
<version>5.0.0.4389</version>
</plugin>
</plugins>
</pluginManagement>
@@ -1615,8 +1601,63 @@
<profile>
<id>error-prone-fork</id>
<properties>
<groupId.error-prone>com.github.PicnicSupermarket.error-prone</groupId.error-prone>
<version.error-prone>${version.error-prone-fork}</version.error-prone>
</properties>
<dependencyManagement>
<!-- Even when we directly depend on the Picnic Error Prone
fork, some other dependencies depend on the official (i.e.,
non-forked) `error_prone_annotations`. Here we fix which
version is pulled in. -->
<dependencies>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_annotations</artifactId>
<version>${version.error-prone-orig}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<configuration>
<rules>
<banDuplicateClasses>
<!-- The original
`error_prone_annotations` dependency
contains the same classes as those
provided by the corresponding Picnic
Error Prone fork artifact. -->
<dependencies combine.children="append">
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_annotations</artifactId>
<ignoreClasses>
<ignoreClass>*</ignoreClass>
</ignoreClasses>
</dependency>
</dependencies>
</banDuplicateClasses>
</rules>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<!-- Property used by `ErrorProneForkTest`
to verify fork identification. -->
<error-prone-fork-in-use>true</error-prone-fork-in-use>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
<profile>
<!-- Error Prone checks that are not available from Maven Central;
@@ -1866,7 +1907,7 @@
declarations once properly supported. See
https://youtrack.jetbrains.com/issue/IDEA-342187. -->
<path>
<groupId>com.google.errorprone</groupId>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_core</artifactId>
<version>${version.error-prone}</version>
</path>
@@ -1950,9 +1991,10 @@
-XepOpt:NullAway:AnnotatedPackages=tech.picnic
-XepOpt:NullAway:AssertsEnabled=true
-XepOpt:NullAway:CheckOptionalEmptiness=true
-XepOpt:NullAway:JSpecifyMode=true
-XepOpt:Nullness:Conservative=false
-XepOpt:StatementSwitchToExpressionSwitch:EnableAssignmentSwitchConversion=true
-XepOpt:StatementSwitchToExpressionSwitch:EnableDirectConversion=true
-XepOpt:StatementSwitchToExpressionSwitch:EnableReturnSwitchConversion=true
<!-- Append additional custom arguments. -->
${error-prone.patch-args}
${error-prone.self-check-args}

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.22.1-SNAPSHOT</version>
<version>0.19.2-SNAPSHOT</version>
</parent>
<artifactId>refaster-compiler</artifactId>
@@ -15,6 +15,19 @@
<url>https://error-prone.picnic.tech</url>
<dependencies>
<dependency>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_check_api</artifactId>
</dependency>
<dependency>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_core</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>refaster-support</artifactId>
@@ -24,19 +37,6 @@
<artifactId>auto-service-annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_check_api</artifactId>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_core</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>

Some files were not shown because too many files have changed in this diff Show More