mirror of
https://github.com/jlengrand/error-prone-support.git
synced 2026-03-10 15:49:33 +00:00
Compare commits
164 Commits
sschroever
...
junie-init
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
03b36a01c7 | ||
|
|
401b7f5f67 | ||
|
|
411066bedb | ||
|
|
bedf588e2a | ||
|
|
3a629b11ec | ||
|
|
fc2eb57b40 | ||
|
|
1c429f0d1c | ||
|
|
ac6ffc72e9 | ||
|
|
07399bb4ef | ||
|
|
aa988ef2b0 | ||
|
|
b58be2b89b | ||
|
|
8fa90f6121 | ||
|
|
6ba03c6352 | ||
|
|
912e06885d | ||
|
|
e803a5d333 | ||
|
|
4a1ad1b991 | ||
|
|
80d433f051 | ||
|
|
afd9703ce6 | ||
|
|
f9d310bc4b | ||
|
|
a3a9ca0bf0 | ||
|
|
0e609aeb1c | ||
|
|
e9dae1d66c | ||
|
|
f0ad9d21e6 | ||
|
|
7138aa2100 | ||
|
|
de4667628f | ||
|
|
5e958fe20b | ||
|
|
baa921caac | ||
|
|
ba040bd191 | ||
|
|
a3a20b52e5 | ||
|
|
5d8d27176b | ||
|
|
d878a57a8e | ||
|
|
eaec12f460 | ||
|
|
da7dafb6e7 | ||
|
|
5a7aaf12d6 | ||
|
|
92e4d74e4b | ||
|
|
4a0bc0c210 | ||
|
|
53152499d6 | ||
|
|
61d92fb33f | ||
|
|
8690f49c35 | ||
|
|
d808f664ec | ||
|
|
7f5f4820e9 | ||
|
|
f7a4427852 | ||
|
|
0e956bcd44 | ||
|
|
5395fc60e1 | ||
|
|
d8cae04a98 | ||
|
|
7b14711ecf | ||
|
|
c3351b9ee1 | ||
|
|
40b3c87b72 | ||
|
|
726db5ce5b | ||
|
|
99d359c548 | ||
|
|
4744113411 | ||
|
|
ae8f940f55 | ||
|
|
8d7633df2d | ||
|
|
4a351cfbe3 | ||
|
|
bb01447760 | ||
|
|
f12ed17b96 | ||
|
|
854e05f044 | ||
|
|
82c22682c0 | ||
|
|
25b3817876 | ||
|
|
e2a2b086ad | ||
|
|
5f9a0c5e17 | ||
|
|
2a0ae0af13 | ||
|
|
7a051146b6 | ||
|
|
d9398001cb | ||
|
|
0be99cb12a | ||
|
|
70e2d3d43f | ||
|
|
441258f9f2 | ||
|
|
b96efb533c | ||
|
|
5af067cc23 | ||
|
|
0c84665e38 | ||
|
|
9316d81fe3 | ||
|
|
ec96c044d5 | ||
|
|
ae4ed9273f | ||
|
|
0ec882e62e | ||
|
|
fef9ba23f4 | ||
|
|
3bd415b910 | ||
|
|
2128624261 | ||
|
|
c53fcace76 | ||
|
|
ff3759984c | ||
|
|
6358d1e2e1 | ||
|
|
db53631e76 | ||
|
|
86b2d929ab | ||
|
|
0db4462a64 | ||
|
|
f8667fc655 | ||
|
|
d91f94e879 | ||
|
|
ad6c8593f2 | ||
|
|
873ee47e8d | ||
|
|
fed281dc2b | ||
|
|
277d30467d | ||
|
|
064e0bbc8c | ||
|
|
3beadeec50 | ||
|
|
c2a26ed12f | ||
|
|
2419dad433 | ||
|
|
900d6eaf78 | ||
|
|
33d205e11f | ||
|
|
ee0651d9d3 | ||
|
|
fb22039fd3 | ||
|
|
cf294b8964 | ||
|
|
0004c8bc44 | ||
|
|
aedeeb0943 | ||
|
|
a68e5ae150 | ||
|
|
6a6354eb55 | ||
|
|
ab0a844f26 | ||
|
|
5105cb684f | ||
|
|
f128a7975f | ||
|
|
e572a3641d | ||
|
|
2b467832fb | ||
|
|
77557c80b1 | ||
|
|
9088369f89 | ||
|
|
36ef967f0e | ||
|
|
dd190ee056 | ||
|
|
4c32d3ce7a | ||
|
|
4608c00140 | ||
|
|
708317f314 | ||
|
|
636c1993d5 | ||
|
|
895875c849 | ||
|
|
1aea710c53 | ||
|
|
5085eb2f25 | ||
|
|
ad5b1c9917 | ||
|
|
34cab33b76 | ||
|
|
c836f1147f | ||
|
|
f43921f344 | ||
|
|
811e70ae3a | ||
|
|
5fd50e6181 | ||
|
|
3767341605 | ||
|
|
9f83eec36b | ||
|
|
126159878c | ||
|
|
78141b2528 | ||
|
|
56db8adb5a | ||
|
|
90b4baba12 | ||
|
|
54c56a4cc8 | ||
|
|
b123282778 | ||
|
|
f4562c7106 | ||
|
|
6211e7e651 | ||
|
|
3e4a01a673 | ||
|
|
a42353b41a | ||
|
|
d2ce18e33e | ||
|
|
7b81dc44e5 | ||
|
|
5e81719cea | ||
|
|
2f3788fc63 | ||
|
|
a98780cef2 | ||
|
|
ff0e30c885 | ||
|
|
4aacc58382 | ||
|
|
dec22b8633 | ||
|
|
37d8ea92c6 | ||
|
|
7eb46dd218 | ||
|
|
623bdd7344 | ||
|
|
c3ae1b5b92 | ||
|
|
19d3ba0505 | ||
|
|
9493f2d59a | ||
|
|
68ecd652f7 | ||
|
|
e67800e4e2 | ||
|
|
7f90f26830 | ||
|
|
6477c1899d | ||
|
|
03514f9f6a | ||
|
|
d11ac09bda | ||
|
|
667f83fd2f | ||
|
|
15ba59a9aa | ||
|
|
a46d6dc146 | ||
|
|
cf523bc811 | ||
|
|
9bd8095e0b | ||
|
|
6cfa9a0dfe | ||
|
|
7daa39a0b5 | ||
|
|
5fc7bc29ee |
12
.devcontainer/devcontainer.json
Normal file
12
.devcontainer/devcontainer.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "Java",
|
||||
"image": "mcr.microsoft.com/devcontainers/java:1-21",
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/java:1": {
|
||||
"version": "none",
|
||||
"installMaven": "true",
|
||||
"mavenVersion": "3.8.6",
|
||||
"installGradle": "true"
|
||||
}
|
||||
}
|
||||
}
|
||||
12
.github/workflows/build.yml
vendored
12
.github/workflows/build.yml
vendored
@@ -14,11 +14,11 @@ jobs:
|
||||
distribution: [ temurin ]
|
||||
experimental: [ false ]
|
||||
include:
|
||||
- os: macos-14
|
||||
- os: macos-15
|
||||
jdk: 17.0.13
|
||||
distribution: temurin
|
||||
experimental: false
|
||||
- os: windows-2022
|
||||
- os: windows-2025
|
||||
jdk: 17.0.13
|
||||
distribution: temurin
|
||||
experimental: false
|
||||
@@ -26,14 +26,16 @@ jobs:
|
||||
continue-on-error: ${{ matrix.experimental }}
|
||||
steps:
|
||||
- name: Install Harden-Runner
|
||||
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
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
|
||||
@@ -42,7 +44,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@9a27433d289dd99d73851f653607c39d3444e8ba # v1.17.0
|
||||
uses: s4u/setup-maven-action@4f7fb9d9675e899ca81c6161dadbba0189a4ebb1 # v1.18.0
|
||||
with:
|
||||
java-version: ${{ matrix.jdk }}
|
||||
java-distribution: ${{ matrix.distribution }}
|
||||
@@ -53,6 +55,8 @@ 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
|
||||
|
||||
|
||||
8
.github/workflows/codeql.yml
vendored
8
.github/workflows/codeql.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Install Harden-Runner
|
||||
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
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@9a27433d289dd99d73851f653607c39d3444e8ba # v1.17.0
|
||||
uses: s4u/setup-maven-action@4f7fb9d9675e899ca81c6161dadbba0189a4ebb1 # v1.18.0
|
||||
with:
|
||||
java-version: 17.0.13
|
||||
java-distribution: temurin
|
||||
maven-version: 3.9.9
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5
|
||||
uses: github/codeql-action/init@5f8171a638ada777af81d42b55959a643bb29017 # v3.28.12
|
||||
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@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5
|
||||
uses: github/codeql-action/analyze@5f8171a638ada777af81d42b55959a643bb29017 # v3.28.12
|
||||
with:
|
||||
category: /language:${{ matrix.language }}
|
||||
|
||||
7
.github/workflows/deploy-website.yml
vendored
7
.github/workflows/deploy-website.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Install Harden-Runner
|
||||
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
with:
|
||||
disable-sudo: true
|
||||
egress-policy: block
|
||||
@@ -21,6 +21,7 @@ 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
|
||||
@@ -42,7 +43,7 @@ jobs:
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: ruby/setup-ruby@a2bbe5b1b236842c1cb7dd11e8e3b51e0a616acc # v1.202.0
|
||||
- uses: ruby/setup-ruby@1a615958ad9d422dd932dc1d5823942ee002799f # v1.227.0
|
||||
with:
|
||||
working-directory: ./website
|
||||
bundler-cache: true
|
||||
@@ -74,7 +75,7 @@ jobs:
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
steps:
|
||||
- name: Install Harden-Runner
|
||||
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
with:
|
||||
disable-sudo: true
|
||||
egress-policy: block
|
||||
|
||||
22
.github/workflows/junie.yml
vendored
Normal file
22
.github/workflows/junie.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
name: Junie
|
||||
run-name: Junie run ${{ inputs.run_id }}
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
run_id:
|
||||
description: "id of workflow process"
|
||||
required: true
|
||||
workflow_params:
|
||||
description: "stringified params"
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
call-workflow-passing-data:
|
||||
uses: jetbrains-junie/junie-workflows/.github/workflows/ej-issue.yml@main
|
||||
with:
|
||||
workflow_params: ${{ inputs.workflow_params }}
|
||||
6
.github/workflows/openssf-scorecard.yml
vendored
6
.github/workflows/openssf-scorecard.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Install Harden-Runner
|
||||
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
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@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
|
||||
uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1
|
||||
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@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5
|
||||
uses: github/codeql-action/upload-sarif@5f8171a638ada777af81d42b55959a643bb29017 # v3.28.12
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
6
.github/workflows/pitest-analyze-pr.yml
vendored
6
.github/workflows/pitest-analyze-pr.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Install Harden-Runner
|
||||
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
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@9a27433d289dd99d73851f653607c39d3444e8ba # v1.17.0
|
||||
uses: s4u/setup-maven-action@4f7fb9d9675e899ca81c6161dadbba0189a4ebb1 # v1.18.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@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: pitest-reports
|
||||
path: ./target/pit-reports-ci
|
||||
|
||||
4
.github/workflows/pitest-update-pr.yml
vendored
4
.github/workflows/pitest-update-pr.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Install Harden-Runner
|
||||
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
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@9a27433d289dd99d73851f653607c39d3444e8ba # v1.17.0
|
||||
uses: s4u/setup-maven-action@4f7fb9d9675e899ca81c6161dadbba0189a4ebb1 # v1.18.0
|
||||
with:
|
||||
java-version: 17.0.13
|
||||
java-distribution: temurin
|
||||
|
||||
12
.github/workflows/run-integration-tests.yml
vendored
12
.github/workflows/run-integration-tests.yml
vendored
@@ -22,14 +22,14 @@ jobs:
|
||||
integration-test: [ "checkstyle", "metrics", "prometheus-java-client" ]
|
||||
steps:
|
||||
- name: Install Harden-Runner
|
||||
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
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@9a27433d289dd99d73851f653607c39d3444e8ba # v1.17.0
|
||||
uses: s4u/setup-maven-action@4f7fb9d9675e899ca81c6161dadbba0189a4ebb1 # v1.18.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@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: "integration-test-${{ matrix.integration-test }}"
|
||||
path: "${{ runner.temp }}/artifacts"
|
||||
|
||||
4
.github/workflows/sonarcloud.yml
vendored
4
.github/workflows/sonarcloud.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Install Harden-Runner
|
||||
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
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@9a27433d289dd99d73851f653607c39d3444e8ba # v1.17.0
|
||||
uses: s4u/setup-maven-action@4f7fb9d9675e899ca81c6161dadbba0189a4ebb1 # v1.18.0
|
||||
with:
|
||||
checkout-fetch-depth: 0
|
||||
java-version: 17.0.13
|
||||
|
||||
27
README.md
27
README.md
@@ -205,12 +205,13 @@ 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 on [Jitpack][error-prone-fork-jitpack].
|
||||
This fork generally contains a few changes on top of the latest Error Prone
|
||||
release.
|
||||
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.
|
||||
- `-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:
|
||||
|
||||
@@ -235,8 +236,9 @@ Other highly relevant commands:
|
||||
against _all_ code in the current working directory. For more information
|
||||
check the [PIT Maven plugin][pitest-maven].
|
||||
|
||||
When running the project's tests in IntelliJ IDEA, you might see the following
|
||||
error:
|
||||
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:
|
||||
|
||||
```
|
||||
java: exporting a package from system module jdk.compiler is not allowed with --release
|
||||
@@ -247,12 +249,6 @@ Java Compiler_ and deselect the option _Use '--release' option for
|
||||
cross-compilation (Java 9 and later)_. See [IDEA-288052][idea-288052] for
|
||||
details.
|
||||
|
||||
The `BugChecker` implementations provided by this project are tested using
|
||||
Error Prone's `CompilationTestHelper` and `BugCheckerRefactoringTestHelper`
|
||||
classes. These utilities accept text blocks containing inline Java source code.
|
||||
To ease modification of this inline source code, consider using IntelliJ IDEA's
|
||||
[language injection][idea-language-injection] feature.
|
||||
|
||||
## 💡 How it works
|
||||
|
||||
This project provides additional [`BugChecker`][error-prone-bugchecker]
|
||||
@@ -280,17 +276,16 @@ 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-jitpack]: https://jitpack.io/#PicnicSupermarket/error-prone
|
||||
[error-prone-fork-packages]: https://github.com/PicnicSupermarket/error-prone/packages
|
||||
[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
|
||||
[idea-language-injection]: https://www.jetbrains.com/help/idea/using-language-injections.html
|
||||
[license-badge]: https://img.shields.io/github/license/PicnicSupermarket/error-prone-support
|
||||
[license]: https://github.com/PicnicSupermarket/error-prone-support/blob/master/LICENSE.md
|
||||
[maven-central-badge]: https://img.shields.io/maven-central/v/tech.picnic.error-prone-support/error-prone-support?color=blue
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.19.2-SNAPSHOT</version>
|
||||
<version>0.22.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>documentation-support</artifactId>
|
||||
@@ -15,24 +15,6 @@
|
||||
<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>
|
||||
@@ -72,6 +54,24 @@
|
||||
<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>
|
||||
@@ -81,11 +81,6 @@
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jspecify</groupId>
|
||||
<artifactId>jspecify</artifactId>
|
||||
|
||||
@@ -2,6 +2,7 @@ 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;
|
||||
@@ -28,7 +29,6 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import tech.picnic.errorprone.documentation.BugPatternTestExtractor.BugPatternTestCases;
|
||||
import tech.picnic.errorprone.utils.SourceCode;
|
||||
|
||||
/**
|
||||
* An {@link Extractor} that describes how to extract data from classes that test a {@code
|
||||
@@ -168,7 +168,10 @@ 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) ASTHelpers.getReceiver(tree);
|
||||
MethodInvocationTree inputTree =
|
||||
(MethodInvocationTree)
|
||||
requireNonNull(
|
||||
ASTHelpers.getReceiver(tree), "Instance method invocation must have receiver");
|
||||
|
||||
String path = ASTHelpers.constValue(inputTree.getArguments().get(0), String.class);
|
||||
Optional<String> inputCode = getSourceCode(inputTree);
|
||||
@@ -190,10 +193,21 @@ public final class BugPatternTestExtractor implements Extractor<BugPatternTestCa
|
||||
}
|
||||
}
|
||||
|
||||
// XXX: This logic is duplicated in `ErrorProneTestSourceFormat`. Can we do better?
|
||||
private static Optional<String> getSourceCode(MethodInvocationTree tree) {
|
||||
return SourceCode.joinConstantSourceCodeLines(
|
||||
tree.getArguments().subList(1, tree.getArguments().size()))
|
||||
.map(s -> s + '\n');
|
||||
List<? extends ExpressionTree> sourceLines =
|
||||
tree.getArguments().subList(1, tree.getArguments().size());
|
||||
StringBuilder source = new StringBuilder();
|
||||
|
||||
for (ExpressionTree sourceLine : sourceLines) {
|
||||
String value = ASTHelpers.constValue(sourceLine, String.class);
|
||||
if (value == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
source.append(value).append('\n');
|
||||
}
|
||||
|
||||
return Optional.of(source.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,11 +19,9 @@ final class BugPatternExtractorTest {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"TestCheckerWithoutAnnotation.java",
|
||||
"""
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
|
||||
public final class TestCheckerWithoutAnnotation extends BugChecker {}
|
||||
""");
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"",
|
||||
"public final class TestCheckerWithoutAnnotation extends BugChecker {}");
|
||||
|
||||
assertThat(outputDirectory.toAbsolutePath()).isEmptyDirectory();
|
||||
}
|
||||
@@ -33,16 +31,14 @@ final class BugPatternExtractorTest {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"MinimalBugChecker.java",
|
||||
"""
|
||||
package pkg;
|
||||
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.BugPattern.SeverityLevel;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
|
||||
@BugPattern(summary = "MinimalBugChecker summary", severity = SeverityLevel.ERROR)
|
||||
public final class MinimalBugChecker extends BugChecker {}
|
||||
""");
|
||||
"package pkg;",
|
||||
"",
|
||||
"import com.google.errorprone.BugPattern;",
|
||||
"import com.google.errorprone.BugPattern.SeverityLevel;",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"",
|
||||
"@BugPattern(summary = \"MinimalBugChecker summary\", severity = SeverityLevel.ERROR)",
|
||||
"public final class MinimalBugChecker extends BugChecker {}");
|
||||
|
||||
verifyGeneratedFileContent(
|
||||
outputDirectory,
|
||||
@@ -66,27 +62,25 @@ final class BugPatternExtractorTest {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"CompleteBugChecker.java",
|
||||
"""
|
||||
package pkg;
|
||||
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.BugPattern.SeverityLevel;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@BugPattern(
|
||||
name = "OtherName",
|
||||
summary = "CompleteBugChecker summary",
|
||||
linkType = BugPattern.LinkType.CUSTOM,
|
||||
link = "https://error-prone.picnic.tech",
|
||||
explanation = "Example explanation",
|
||||
severity = SeverityLevel.SUGGESTION,
|
||||
altNames = "Check",
|
||||
tags = BugPattern.StandardTags.SIMPLIFICATION,
|
||||
disableable = false,
|
||||
suppressionAnnotations = {BugPattern.class, Test.class})
|
||||
public final class CompleteBugChecker extends BugChecker {}
|
||||
""");
|
||||
"package pkg;",
|
||||
"",
|
||||
"import com.google.errorprone.BugPattern;",
|
||||
"import com.google.errorprone.BugPattern.SeverityLevel;",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"import org.junit.jupiter.api.Test;",
|
||||
"",
|
||||
"@BugPattern(",
|
||||
" name = \"OtherName\",",
|
||||
" summary = \"CompleteBugChecker summary\",",
|
||||
" linkType = BugPattern.LinkType.CUSTOM,",
|
||||
" link = \"https://error-prone.picnic.tech\",",
|
||||
" explanation = \"Example explanation\",",
|
||||
" severity = SeverityLevel.SUGGESTION,",
|
||||
" altNames = \"Check\",",
|
||||
" tags = BugPattern.StandardTags.SIMPLIFICATION,",
|
||||
" disableable = false,",
|
||||
" suppressionAnnotations = {BugPattern.class, Test.class})",
|
||||
"public final class CompleteBugChecker extends BugChecker {}");
|
||||
|
||||
verifyGeneratedFileContent(
|
||||
outputDirectory,
|
||||
@@ -110,19 +104,17 @@ final class BugPatternExtractorTest {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"UndocumentedSuppressionBugPattern.java",
|
||||
"""
|
||||
package pkg;
|
||||
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.BugPattern.SeverityLevel;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
|
||||
@BugPattern(
|
||||
summary = "UndocumentedSuppressionBugPattern summary",
|
||||
severity = SeverityLevel.WARNING,
|
||||
documentSuppression = false)
|
||||
public final class UndocumentedSuppressionBugPattern extends BugChecker {}
|
||||
""");
|
||||
"package pkg;",
|
||||
"",
|
||||
"import com.google.errorprone.BugPattern;",
|
||||
"import com.google.errorprone.BugPattern.SeverityLevel;",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"",
|
||||
"@BugPattern(",
|
||||
" summary = \"UndocumentedSuppressionBugPattern summary\",",
|
||||
" severity = SeverityLevel.WARNING,",
|
||||
" documentSuppression = false)",
|
||||
"public final class UndocumentedSuppressionBugPattern extends BugChecker {}");
|
||||
|
||||
verifyGeneratedFileContent(
|
||||
outputDirectory,
|
||||
|
||||
@@ -18,11 +18,9 @@ final class BugPatternTestExtractorTest {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"TestCheckerWithoutAnnotation.java",
|
||||
"""
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
|
||||
public final class TestCheckerWithoutAnnotation extends BugChecker {}
|
||||
""");
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"",
|
||||
"public final class TestCheckerWithoutAnnotation extends BugChecker {}");
|
||||
|
||||
assertThat(outputDirectory.toAbsolutePath()).isEmptyDirectory();
|
||||
}
|
||||
@@ -32,24 +30,22 @@ final class BugPatternTestExtractorTest {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"TestCheckerTest.java",
|
||||
"""
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
|
||||
final class TestCheckerTest {
|
||||
private static class TestChecker extends BugChecker {}
|
||||
|
||||
void m() {
|
||||
CompilationTestHelper.newInstance(TestChecker.class, getClass())
|
||||
.addSourceLines("A.java", "// BUG: Diagnostic contains:", "class A {}");
|
||||
|
||||
BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass())
|
||||
.addInputLines("A.java", "class A {}")
|
||||
.addOutputLines("A.java", "class A { /* This is a change. */ }");
|
||||
}
|
||||
}
|
||||
""");
|
||||
"import com.google.errorprone.BugCheckerRefactoringTestHelper;",
|
||||
"import com.google.errorprone.CompilationTestHelper;",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"",
|
||||
"final class TestCheckerTest {",
|
||||
" private static class TestChecker extends BugChecker {}",
|
||||
"",
|
||||
" void m() {",
|
||||
" CompilationTestHelper.newInstance(TestChecker.class, getClass())",
|
||||
" .addSourceLines(\"A.java\", \"// BUG: Diagnostic contains:\", \"class A {}\");",
|
||||
"",
|
||||
" BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass())",
|
||||
" .addInputLines(\"A.java\", \"class A {}\")",
|
||||
" .addOutputLines(\"A.java\", \"class A { /* This is a change. */ }\");",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
assertThat(outputDirectory.toAbsolutePath()).isEmptyDirectory();
|
||||
}
|
||||
@@ -59,24 +55,22 @@ final class BugPatternTestExtractorTest {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"TestCheckerTest.java",
|
||||
"""
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
|
||||
final class TestCheckerTest {
|
||||
void m() {
|
||||
CompilationTestHelper.newInstance((Class<BugChecker>) null, getClass())
|
||||
.addSourceLines("A.java", "// BUG: Diagnostic contains:", "class A {}")
|
||||
.doTest();
|
||||
|
||||
BugCheckerRefactoringTestHelper.newInstance((Class<BugChecker>) null, getClass())
|
||||
.addInputLines("A.java", "class A {}")
|
||||
.addOutputLines("A.java", "class A { /* This is a change. */ }")
|
||||
.doTest();
|
||||
}
|
||||
}
|
||||
""");
|
||||
"import com.google.errorprone.BugCheckerRefactoringTestHelper;",
|
||||
"import com.google.errorprone.CompilationTestHelper;",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"",
|
||||
"final class TestCheckerTest {",
|
||||
" void m() {",
|
||||
" CompilationTestHelper.newInstance((Class<BugChecker>) null, getClass())",
|
||||
" .addSourceLines(\"A.java\", \"// BUG: Diagnostic contains:\", \"class A {}\")",
|
||||
" .doTest();",
|
||||
"",
|
||||
" BugCheckerRefactoringTestHelper.newInstance((Class<BugChecker>) null, getClass())",
|
||||
" .addInputLines(\"A.java\", \"class A {}\")",
|
||||
" .addOutputLines(\"A.java\", \"class A { /* This is a change. */ }\")",
|
||||
" .doTest();",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
assertThat(outputDirectory.toAbsolutePath()).isEmptyDirectory();
|
||||
}
|
||||
@@ -86,30 +80,28 @@ final class BugPatternTestExtractorTest {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"TestCheckerTest.java",
|
||||
"""
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
|
||||
final class TestCheckerTest {
|
||||
private static class TestChecker extends BugChecker {}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
void m() {
|
||||
@SuppressWarnings("rawtypes")
|
||||
Class bugChecker = TestChecker.class;
|
||||
|
||||
CompilationTestHelper.newInstance(bugChecker, getClass())
|
||||
.addSourceLines("A.java", "// BUG: Diagnostic contains:", "class A {}")
|
||||
.doTest();
|
||||
|
||||
BugCheckerRefactoringTestHelper.newInstance(bugChecker, getClass())
|
||||
.addInputLines("A.java", "class A {}")
|
||||
.addOutputLines("A.java", "class A { /* This is a change. */ }")
|
||||
.doTest();
|
||||
}
|
||||
}
|
||||
""");
|
||||
"import com.google.errorprone.BugCheckerRefactoringTestHelper;",
|
||||
"import com.google.errorprone.CompilationTestHelper;",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"",
|
||||
"final class TestCheckerTest {",
|
||||
" private static class TestChecker extends BugChecker {}",
|
||||
"",
|
||||
" @SuppressWarnings(\"unchecked\")",
|
||||
" void m() {",
|
||||
" @SuppressWarnings(\"rawtypes\")",
|
||||
" Class bugChecker = TestChecker.class;",
|
||||
"",
|
||||
" CompilationTestHelper.newInstance(bugChecker, getClass())",
|
||||
" .addSourceLines(\"A.java\", \"// BUG: Diagnostic contains:\", \"class A {}\")",
|
||||
" .doTest();",
|
||||
"",
|
||||
" BugCheckerRefactoringTestHelper.newInstance(bugChecker, getClass())",
|
||||
" .addInputLines(\"A.java\", \"class A {}\")",
|
||||
" .addOutputLines(\"A.java\", \"class A { /* This is a change. */ }\")",
|
||||
" .doTest();",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
assertThat(outputDirectory.toAbsolutePath()).isEmptyDirectory();
|
||||
}
|
||||
@@ -119,29 +111,27 @@ final class BugPatternTestExtractorTest {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"TestCheckerTest.java",
|
||||
"""
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
import com.google.errorprone.scanner.ScannerSupplier;
|
||||
|
||||
final class TestCheckerTest {
|
||||
private static class TestChecker extends BugChecker {}
|
||||
|
||||
void m() {
|
||||
CompilationTestHelper.newInstance(
|
||||
ScannerSupplier.fromBugCheckerClasses(TestChecker.class), getClass())
|
||||
.addSourceLines("A.java", "// BUG: Diagnostic contains:", "class A {}")
|
||||
.doTest();
|
||||
|
||||
BugCheckerRefactoringTestHelper.newInstance(
|
||||
ScannerSupplier.fromBugCheckerClasses(TestChecker.class), getClass())
|
||||
.addInputLines("A.java", "class A {}")
|
||||
.addOutputLines("A.java", "class A { /* This is a change. */ }")
|
||||
.doTest();
|
||||
}
|
||||
}
|
||||
""");
|
||||
"import com.google.errorprone.BugCheckerRefactoringTestHelper;",
|
||||
"import com.google.errorprone.CompilationTestHelper;",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"import com.google.errorprone.scanner.ScannerSupplier;",
|
||||
"",
|
||||
"final class TestCheckerTest {",
|
||||
" private static class TestChecker extends BugChecker {}",
|
||||
"",
|
||||
" void m() {",
|
||||
" CompilationTestHelper.newInstance(",
|
||||
" ScannerSupplier.fromBugCheckerClasses(TestChecker.class), getClass())",
|
||||
" .addSourceLines(\"A.java\", \"// BUG: Diagnostic contains:\", \"class A {}\")",
|
||||
" .doTest();",
|
||||
"",
|
||||
" BugCheckerRefactoringTestHelper.newInstance(",
|
||||
" ScannerSupplier.fromBugCheckerClasses(TestChecker.class), getClass())",
|
||||
" .addInputLines(\"A.java\", \"class A {}\")",
|
||||
" .addOutputLines(\"A.java\", \"class A { /* This is a change. */ }\")",
|
||||
" .doTest();",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
assertThat(outputDirectory.toAbsolutePath()).isEmptyDirectory();
|
||||
}
|
||||
@@ -151,31 +141,29 @@ final class BugPatternTestExtractorTest {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"TestCheckerTest.java",
|
||||
"""
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
|
||||
final class TestCheckerTest {
|
||||
private static class TestChecker extends BugChecker {}
|
||||
|
||||
void m() {
|
||||
CompilationTestHelper.newInstance(TestChecker.class, getClass())
|
||||
.addSourceLines(toString() + "A.java", "// BUG: Diagnostic contains:", "class A {}")
|
||||
.addSourceLines("B.java", "// BUG: Diagnostic contains:", "class B {}", toString())
|
||||
.doTest();
|
||||
|
||||
BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass())
|
||||
.addInputLines(toString() + "A.java", "class A {}")
|
||||
.addOutputLines("A.java", "class A { /* This is a change. */ }")
|
||||
.addInputLines("B.java", "class B {}", toString())
|
||||
.addOutputLines("B.java", "class B { /* This is a change. */ }")
|
||||
.addInputLines("C.java", "class C {}")
|
||||
.addOutputLines("C.java", "class C { /* This is a change. */ }", toString())
|
||||
.doTest();
|
||||
}
|
||||
}
|
||||
""");
|
||||
"import com.google.errorprone.BugCheckerRefactoringTestHelper;",
|
||||
"import com.google.errorprone.CompilationTestHelper;",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"",
|
||||
"final class TestCheckerTest {",
|
||||
" private static class TestChecker extends BugChecker {}",
|
||||
"",
|
||||
" void m() {",
|
||||
" CompilationTestHelper.newInstance(TestChecker.class, getClass())",
|
||||
" .addSourceLines(toString() + \"A.java\", \"// BUG: Diagnostic contains:\", \"class A {}\")",
|
||||
" .addSourceLines(\"B.java\", \"// BUG: Diagnostic contains:\", \"class B {}\", toString())",
|
||||
" .doTest();",
|
||||
"",
|
||||
" BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass())",
|
||||
" .addInputLines(toString() + \"A.java\", \"class A {}\")",
|
||||
" .addOutputLines(\"A.java\", \"class A { /* This is a change. */ }\")",
|
||||
" .addInputLines(\"B.java\", \"class B {}\", toString())",
|
||||
" .addOutputLines(\"B.java\", \"class B { /* This is a change. */ }\")",
|
||||
" .addInputLines(\"C.java\", \"class C {}\")",
|
||||
" .addOutputLines(\"C.java\", \"class C { /* This is a change. */ }\", toString())",
|
||||
" .doTest();",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
assertThat(outputDirectory.toAbsolutePath()).isEmptyDirectory();
|
||||
}
|
||||
@@ -185,28 +173,26 @@ final class BugPatternTestExtractorTest {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"TestCheckerTest.java",
|
||||
"""
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
|
||||
final class TestCheckerTest {
|
||||
private static class TestChecker extends BugChecker {}
|
||||
|
||||
void m() {
|
||||
CompilationTestHelper testHelper =
|
||||
CompilationTestHelper.newInstance(TestChecker.class, getClass())
|
||||
.addSourceLines("A.java", "class A {}");
|
||||
testHelper.doTest();
|
||||
|
||||
BugCheckerRefactoringTestHelper.ExpectOutput expectedOutput =
|
||||
BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass())
|
||||
.addInputLines("A.java", "class A {}");
|
||||
expectedOutput.addOutputLines("A.java", "class A {}").doTest();
|
||||
expectedOutput.expectUnchanged().doTest();
|
||||
}
|
||||
}
|
||||
""");
|
||||
"import com.google.errorprone.BugCheckerRefactoringTestHelper;",
|
||||
"import com.google.errorprone.CompilationTestHelper;",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"",
|
||||
"final class TestCheckerTest {",
|
||||
" private static class TestChecker extends BugChecker {}",
|
||||
"",
|
||||
" void m() {",
|
||||
" CompilationTestHelper testHelper =",
|
||||
" CompilationTestHelper.newInstance(TestChecker.class, getClass())",
|
||||
" .addSourceLines(\"A.java\", \"class A {}\");",
|
||||
" testHelper.doTest();",
|
||||
"",
|
||||
" BugCheckerRefactoringTestHelper.ExpectOutput expectedOutput =",
|
||||
" BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass())",
|
||||
" .addInputLines(\"A.java\", \"class A {}\");",
|
||||
" expectedOutput.addOutputLines(\"A.java\", \"class A {}\").doTest();",
|
||||
" expectedOutput.expectUnchanged().doTest();",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
assertThat(outputDirectory.toAbsolutePath()).isEmptyDirectory();
|
||||
}
|
||||
@@ -216,21 +202,19 @@ final class BugPatternTestExtractorTest {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"TestCheckerTest.java",
|
||||
"""
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
|
||||
final class TestCheckerTest {
|
||||
private static class TestChecker extends BugChecker {}
|
||||
|
||||
void m() {
|
||||
CompilationTestHelper.newInstance(TestChecker.class, getClass()).doTest();
|
||||
|
||||
BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass()).doTest();
|
||||
}
|
||||
}
|
||||
""");
|
||||
"import com.google.errorprone.BugCheckerRefactoringTestHelper;",
|
||||
"import com.google.errorprone.CompilationTestHelper;",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"",
|
||||
"final class TestCheckerTest {",
|
||||
" private static class TestChecker extends BugChecker {}",
|
||||
"",
|
||||
" void m() {",
|
||||
" CompilationTestHelper.newInstance(TestChecker.class, getClass()).doTest();",
|
||||
"",
|
||||
" BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass()).doTest();",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
assertThat(outputDirectory.toAbsolutePath()).isEmptyDirectory();
|
||||
}
|
||||
@@ -240,28 +224,26 @@ final class BugPatternTestExtractorTest {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"TestCheckerTest.java",
|
||||
"""
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
|
||||
final class TestCheckerTest {
|
||||
private static class TestChecker extends BugChecker {}
|
||||
|
||||
void m() {
|
||||
CompilationTestHelper.newInstance(TestChecker.class, getClass())
|
||||
.addSourceLines("A.java", "class A {}")
|
||||
.doTest();
|
||||
|
||||
BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass())
|
||||
.addInputLines("A.java", "class A {}")
|
||||
.addOutputLines("A.java", "class A {}")
|
||||
.addInputLines("B.java", "class B {}")
|
||||
.expectUnchanged()
|
||||
.doTest();
|
||||
}
|
||||
}
|
||||
""");
|
||||
"import com.google.errorprone.BugCheckerRefactoringTestHelper;",
|
||||
"import com.google.errorprone.CompilationTestHelper;",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"",
|
||||
"final class TestCheckerTest {",
|
||||
" private static class TestChecker extends BugChecker {}",
|
||||
"",
|
||||
" void m() {",
|
||||
" CompilationTestHelper.newInstance(TestChecker.class, getClass())",
|
||||
" .addSourceLines(\"A.java\", \"class A {}\")",
|
||||
" .doTest();",
|
||||
"",
|
||||
" BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass())",
|
||||
" .addInputLines(\"A.java\", \"class A {}\")",
|
||||
" .addOutputLines(\"A.java\", \"class A {}\")",
|
||||
" .addInputLines(\"B.java\", \"class B {}\")",
|
||||
" .expectUnchanged()",
|
||||
" .doTest();",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
assertThat(outputDirectory.toAbsolutePath()).isEmptyDirectory();
|
||||
}
|
||||
@@ -271,20 +253,18 @@ final class BugPatternTestExtractorTest {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"SingleFileCompilationTestHelperTest.java",
|
||||
"""
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
|
||||
final class SingleFileCompilationTestHelperTest {
|
||||
private static class TestChecker extends BugChecker {}
|
||||
|
||||
void m() {
|
||||
CompilationTestHelper.newInstance(TestChecker.class, getClass())
|
||||
.addSourceLines("A.java", "// BUG: Diagnostic contains:", "class A {}")
|
||||
.doTest();
|
||||
}
|
||||
}
|
||||
""");
|
||||
"import com.google.errorprone.CompilationTestHelper;",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"",
|
||||
"final class SingleFileCompilationTestHelperTest {",
|
||||
" private static class TestChecker extends BugChecker {}",
|
||||
"",
|
||||
" void m() {",
|
||||
" CompilationTestHelper.newInstance(TestChecker.class, getClass())",
|
||||
" .addSourceLines(\"A.java\", \"// BUG: Diagnostic contains:\", \"class A {}\")",
|
||||
" .doTest();",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
verifyGeneratedFileContent(
|
||||
outputDirectory,
|
||||
@@ -305,21 +285,19 @@ final class BugPatternTestExtractorTest {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"SingleFileCompilationTestHelperWithSetArgsTest.java",
|
||||
"""
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
|
||||
final class SingleFileCompilationTestHelperWithSetArgsTest {
|
||||
private static class TestChecker extends BugChecker {}
|
||||
|
||||
void m() {
|
||||
CompilationTestHelper.newInstance(TestChecker.class, getClass())
|
||||
.setArgs("-XepAllSuggestionsAsWarnings")
|
||||
.addSourceLines("A.java", "// BUG: Diagnostic contains:", "class A {}")
|
||||
.doTest();
|
||||
}
|
||||
}
|
||||
""");
|
||||
"import com.google.errorprone.CompilationTestHelper;",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"",
|
||||
"final class SingleFileCompilationTestHelperWithSetArgsTest {",
|
||||
" private static class TestChecker extends BugChecker {}",
|
||||
"",
|
||||
" void m() {",
|
||||
" CompilationTestHelper.newInstance(TestChecker.class, getClass())",
|
||||
" .setArgs(\"-XepAllSuggestionsAsWarnings\")",
|
||||
" .addSourceLines(\"A.java\", \"// BUG: Diagnostic contains:\", \"class A {}\")",
|
||||
" .doTest();",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
verifyGeneratedFileContent(
|
||||
outputDirectory,
|
||||
@@ -340,21 +318,19 @@ final class BugPatternTestExtractorTest {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"MultiFileCompilationTestHelperTest.java",
|
||||
"""
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
|
||||
final class MultiFileCompilationTestHelperTest {
|
||||
private static class TestChecker extends BugChecker {}
|
||||
|
||||
void m() {
|
||||
CompilationTestHelper.newInstance(TestChecker.class, getClass())
|
||||
.addSourceLines("A.java", "// BUG: Diagnostic contains:", "class A {}")
|
||||
.addSourceLines("B.java", "// BUG: Diagnostic contains:", "class B {}")
|
||||
.doTest();
|
||||
}
|
||||
}
|
||||
""");
|
||||
"import com.google.errorprone.CompilationTestHelper;",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"",
|
||||
"final class MultiFileCompilationTestHelperTest {",
|
||||
" private static class TestChecker extends BugChecker {}",
|
||||
"",
|
||||
" void m() {",
|
||||
" CompilationTestHelper.newInstance(TestChecker.class, getClass())",
|
||||
" .addSourceLines(\"A.java\", \"// BUG: Diagnostic contains:\", \"class A {}\")",
|
||||
" .addSourceLines(\"B.java\", \"// BUG: Diagnostic contains:\", \"class B {}\")",
|
||||
" .doTest();",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
verifyGeneratedFileContent(
|
||||
outputDirectory,
|
||||
@@ -377,21 +353,19 @@ final class BugPatternTestExtractorTest {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"SingleFileBugCheckerRefactoringTestHelperTest.java",
|
||||
"""
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
|
||||
final class SingleFileBugCheckerRefactoringTestHelperTest {
|
||||
private static class TestChecker extends BugChecker {}
|
||||
|
||||
void m() {
|
||||
BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass())
|
||||
.addInputLines("A.java", "class A {}")
|
||||
.addOutputLines("A.java", "class A { /* This is a change. */ }")
|
||||
.doTest();
|
||||
}
|
||||
}
|
||||
""");
|
||||
"import com.google.errorprone.BugCheckerRefactoringTestHelper;",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"",
|
||||
"final class SingleFileBugCheckerRefactoringTestHelperTest {",
|
||||
" private static class TestChecker extends BugChecker {}",
|
||||
"",
|
||||
" void m() {",
|
||||
" BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass())",
|
||||
" .addInputLines(\"A.java\", \"class A {}\")",
|
||||
" .addOutputLines(\"A.java\", \"class A { /* This is a change. */ }\")",
|
||||
" .doTest();",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
verifyGeneratedFileContent(
|
||||
outputDirectory,
|
||||
@@ -413,25 +387,23 @@ final class BugPatternTestExtractorTest {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"SingleFileBugCheckerRefactoringTestHelperWithSetArgsFixChooserAndCustomTestModeTest.java",
|
||||
"""
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper.FixChoosers;
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
|
||||
final class SingleFileBugCheckerRefactoringTestHelperWithSetArgsFixChooserAndCustomTestModeTest {
|
||||
private static class TestChecker extends BugChecker {}
|
||||
|
||||
void m() {
|
||||
BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass())
|
||||
.setArgs("-XepAllSuggestionsAsWarnings")
|
||||
.setFixChooser(FixChoosers.SECOND)
|
||||
.addInputLines("A.java", "class A {}")
|
||||
.addOutputLines("A.java", "class A { /* This is a change. */ }")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
""");
|
||||
"import com.google.errorprone.BugCheckerRefactoringTestHelper;",
|
||||
"import com.google.errorprone.BugCheckerRefactoringTestHelper.FixChoosers;",
|
||||
"import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"",
|
||||
"final class SingleFileBugCheckerRefactoringTestHelperWithSetArgsFixChooserAndCustomTestModeTest {",
|
||||
" private static class TestChecker extends BugChecker {}",
|
||||
"",
|
||||
" void m() {",
|
||||
" BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass())",
|
||||
" .setArgs(\"-XepAllSuggestionsAsWarnings\")",
|
||||
" .setFixChooser(FixChoosers.SECOND)",
|
||||
" .addInputLines(\"A.java\", \"class A {}\")",
|
||||
" .addOutputLines(\"A.java\", \"class A { /* This is a change. */ }\")",
|
||||
" .doTest(TestMode.TEXT_MATCH);",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
verifyGeneratedFileContent(
|
||||
outputDirectory,
|
||||
@@ -453,23 +425,21 @@ final class BugPatternTestExtractorTest {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"MultiFileBugCheckerRefactoringTestHelperTest.java",
|
||||
"""
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
|
||||
final class MultiFileBugCheckerRefactoringTestHelperTest {
|
||||
private static class TestChecker extends BugChecker {}
|
||||
|
||||
void m() {
|
||||
BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass())
|
||||
.addInputLines("A.java", "class A {}")
|
||||
.addOutputLines("A.java", "class A { /* This is a change. */ }")
|
||||
.addInputLines("B.java", "class B {}")
|
||||
.addOutputLines("B.java", "class B { /* This is a change. */ }")
|
||||
.doTest();
|
||||
}
|
||||
}
|
||||
""");
|
||||
"import com.google.errorprone.BugCheckerRefactoringTestHelper;",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"",
|
||||
"final class MultiFileBugCheckerRefactoringTestHelperTest {",
|
||||
" private static class TestChecker extends BugChecker {}",
|
||||
"",
|
||||
" void m() {",
|
||||
" BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass())",
|
||||
" .addInputLines(\"A.java\", \"class A {}\")",
|
||||
" .addOutputLines(\"A.java\", \"class A { /* This is a change. */ }\")",
|
||||
" .addInputLines(\"B.java\", \"class B {}\")",
|
||||
" .addOutputLines(\"B.java\", \"class B { /* This is a change. */ }\")",
|
||||
" .doTest();",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
verifyGeneratedFileContent(
|
||||
outputDirectory,
|
||||
@@ -492,26 +462,24 @@ final class BugPatternTestExtractorTest {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"CompilationAndBugCheckerRefactoringTestHelpersTest.java",
|
||||
"""
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
|
||||
final class CompilationAndBugCheckerRefactoringTestHelpersTest {
|
||||
private static class TestChecker extends BugChecker {}
|
||||
|
||||
void m() {
|
||||
CompilationTestHelper.newInstance(TestChecker.class, getClass())
|
||||
.addSourceLines("A.java", "// BUG: Diagnostic contains:", "class A {}")
|
||||
.doTest();
|
||||
|
||||
BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass())
|
||||
.addInputLines("A.java", "class A {}")
|
||||
.addOutputLines("A.java", "class A { /* This is a change. */ }")
|
||||
.doTest();
|
||||
}
|
||||
}
|
||||
""");
|
||||
"import com.google.errorprone.BugCheckerRefactoringTestHelper;",
|
||||
"import com.google.errorprone.CompilationTestHelper;",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"",
|
||||
"final class CompilationAndBugCheckerRefactoringTestHelpersTest {",
|
||||
" private static class TestChecker extends BugChecker {}",
|
||||
"",
|
||||
" void m() {",
|
||||
" CompilationTestHelper.newInstance(TestChecker.class, getClass())",
|
||||
" .addSourceLines(\"A.java\", \"// BUG: Diagnostic contains:\", \"class A {}\")",
|
||||
" .doTest();",
|
||||
"",
|
||||
" BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass())",
|
||||
" .addInputLines(\"A.java\", \"class A {}\")",
|
||||
" .addOutputLines(\"A.java\", \"class A { /* This is a change. */ }\")",
|
||||
" .doTest();",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
verifyGeneratedFileContent(
|
||||
outputDirectory,
|
||||
@@ -538,30 +506,28 @@ final class BugPatternTestExtractorTest {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"CompilationAndBugCheckerRefactoringTestHelpersWithCustomCheckerPackageAndNamesTest.java",
|
||||
"""
|
||||
package pkg;
|
||||
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
|
||||
final class CompilationAndBugCheckerRefactoringTestHelpersWithCustomCheckerPackageAndNamesTest {
|
||||
private static class CustomTestChecker extends BugChecker {}
|
||||
|
||||
private static class CustomTestChecker2 extends BugChecker {}
|
||||
|
||||
void m() {
|
||||
CompilationTestHelper.newInstance(CustomTestChecker.class, getClass())
|
||||
.addSourceLines("A.java", "// BUG: Diagnostic contains:", "class A {}")
|
||||
.doTest();
|
||||
|
||||
BugCheckerRefactoringTestHelper.newInstance(CustomTestChecker2.class, getClass())
|
||||
.addInputLines("A.java", "class A {}")
|
||||
.addOutputLines("A.java", "class A { /* This is a change. */ }")
|
||||
.doTest();
|
||||
}
|
||||
}
|
||||
""");
|
||||
"package pkg;",
|
||||
"",
|
||||
"import com.google.errorprone.BugCheckerRefactoringTestHelper;",
|
||||
"import com.google.errorprone.CompilationTestHelper;",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"",
|
||||
"final class CompilationAndBugCheckerRefactoringTestHelpersWithCustomCheckerPackageAndNamesTest {",
|
||||
" private static class CustomTestChecker extends BugChecker {}",
|
||||
"",
|
||||
" private static class CustomTestChecker2 extends BugChecker {}",
|
||||
"",
|
||||
" void m() {",
|
||||
" CompilationTestHelper.newInstance(CustomTestChecker.class, getClass())",
|
||||
" .addSourceLines(\"A.java\", \"// BUG: Diagnostic contains:\", \"class A {}\")",
|
||||
" .doTest();",
|
||||
"",
|
||||
" BugCheckerRefactoringTestHelper.newInstance(CustomTestChecker2.class, getClass())",
|
||||
" .addInputLines(\"A.java\", \"class A {}\")",
|
||||
" .addOutputLines(\"A.java\", \"class A { /* This is a change. */ }\")",
|
||||
" .doTest();",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
verifyGeneratedFileContent(
|
||||
outputDirectory,
|
||||
|
||||
@@ -14,29 +14,21 @@ import java.util.List;
|
||||
import javax.tools.Diagnostic;
|
||||
import javax.tools.JavaCompiler;
|
||||
import javax.tools.JavaFileObject;
|
||||
import org.intellij.lang.annotations.Language;
|
||||
|
||||
// XXX: Generalize and move this class so that it can also be used by `refaster-compiler`.
|
||||
// XXX: This class is supported by the `TestHelperSourceFormat` check, but until that support is
|
||||
// covered by unit tests, make sure to update that logic if this class or its methods are
|
||||
// XXX: This class is supported by the `ErrorProneTestHelperSourceFormat` check, but until that
|
||||
// support is covered by unit tests, make sure to update that logic if this class or its methods are
|
||||
// moved/renamed.
|
||||
public final class Compilation {
|
||||
private Compilation() {}
|
||||
|
||||
// XXX: Drop this method in favour of only supporting the text block-accepting variant.
|
||||
public static void compileWithDocumentationGenerator(
|
||||
Path outputDirectory, String path, @Language("JAVA") String... source) {
|
||||
compileWithDocumentationGenerator(
|
||||
outputDirectory.toAbsolutePath().toString(), path, String.join("\n", source));
|
||||
Path outputDirectory, String path, String... lines) {
|
||||
compileWithDocumentationGenerator(outputDirectory.toAbsolutePath().toString(), path, lines);
|
||||
}
|
||||
|
||||
public static void compileWithDocumentationGenerator(
|
||||
Path outputDirectory, String path, @Language("JAVA") String source) {
|
||||
compileWithDocumentationGenerator(outputDirectory.toAbsolutePath().toString(), path, source);
|
||||
}
|
||||
|
||||
public static void compileWithDocumentationGenerator(
|
||||
String outputDirectory, String path, @Language("JAVA") String source) {
|
||||
String outputDirectory, String path, String... lines) {
|
||||
/*
|
||||
* The compiler options specified here largely match those used by Error Prone's
|
||||
* `CompilationTestHelper`. A key difference is the stricter linting configuration. When
|
||||
@@ -57,7 +49,7 @@ public final class Compilation {
|
||||
"-Xplugin:DocumentationGenerator -XoutputDirectory=" + outputDirectory,
|
||||
"-XDdev",
|
||||
"-XDcompilePolicy=simple"),
|
||||
FileObjects.forSourceLines(path, source));
|
||||
FileObjects.forSourceLines(path, lines));
|
||||
}
|
||||
|
||||
private static void compile(ImmutableList<String> options, JavaFileObject javaFileObject) {
|
||||
|
||||
@@ -62,26 +62,15 @@ final class DocumentationGeneratorTaskListenerTest {
|
||||
assertThatThrownBy(
|
||||
() ->
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"A.java",
|
||||
"""
|
||||
class A {}
|
||||
"""))
|
||||
outputDirectory, "A.java", "class A {}"))
|
||||
.hasRootCauseInstanceOf(FileSystemException.class)
|
||||
.hasCauseInstanceOf(IllegalStateException.class)
|
||||
.hasMessageEndingWith("Error while creating directory with path '%s'", outputDirectory);
|
||||
}
|
||||
|
||||
// XXX: For this case the text block conversion introduces too much indentation. (Possibly i.c.w.
|
||||
// post-processing by GJF; TBD.)
|
||||
@Test
|
||||
void noClassNoOutput(@TempDir Path outputDirectory) {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"A.java",
|
||||
"""
|
||||
package pkg;
|
||||
""");
|
||||
Compilation.compileWithDocumentationGenerator(outputDirectory, "A.java", "package pkg;");
|
||||
|
||||
assertThat(outputDirectory).isEmptyDirectory();
|
||||
}
|
||||
@@ -92,11 +81,7 @@ final class DocumentationGeneratorTaskListenerTest {
|
||||
assertThatThrownBy(
|
||||
() ->
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
actualOutputDirectory,
|
||||
"A.java",
|
||||
"""
|
||||
package pkg;
|
||||
"""))
|
||||
actualOutputDirectory, "A.java", "package pkg;"))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("Precisely one path must be provided");
|
||||
}
|
||||
@@ -106,9 +91,7 @@ final class DocumentationGeneratorTaskListenerTest {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"DocumentationGeneratorTaskListenerTestClass.java",
|
||||
"""
|
||||
class DocumentationGeneratorTaskListenerTestClass {}
|
||||
""");
|
||||
"class DocumentationGeneratorTaskListenerTestClass {}");
|
||||
|
||||
assertThat(
|
||||
outputDirectory.resolve(
|
||||
|
||||
@@ -16,11 +16,7 @@ final class RefasterRuleCollectionTestExtractorTest {
|
||||
@Test
|
||||
void noRefasterRuleTest(@TempDir Path outputDirectory) {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"NoRefasterRuleTest.java",
|
||||
"""
|
||||
public final class NoRefasterRuleTest {}
|
||||
""");
|
||||
outputDirectory, "NoRefasterRuleTest.java", "public final class NoRefasterRuleTest {}");
|
||||
|
||||
assertThat(outputDirectory.toAbsolutePath()).isEmptyDirectory();
|
||||
}
|
||||
@@ -32,11 +28,9 @@ final class RefasterRuleCollectionTestExtractorTest {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"InvalidTestClassNameInput.java",
|
||||
"""
|
||||
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
|
||||
|
||||
final class InvalidTestClassName implements RefasterRuleCollectionTestCase {}
|
||||
"""))
|
||||
"import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;",
|
||||
"",
|
||||
"final class InvalidTestClassName implements RefasterRuleCollectionTestCase {}"))
|
||||
.cause()
|
||||
.isInstanceOf(VerifyException.class)
|
||||
.hasMessage(
|
||||
@@ -50,11 +44,9 @@ final class RefasterRuleCollectionTestExtractorTest {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"InvalidFileNameTest.java",
|
||||
"""
|
||||
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
|
||||
|
||||
final class InvalidFileNameTest implements RefasterRuleCollectionTestCase {}
|
||||
"""))
|
||||
"import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;",
|
||||
"",
|
||||
"final class InvalidFileNameTest implements RefasterRuleCollectionTestCase {}"))
|
||||
.cause()
|
||||
.isInstanceOf(VerifyException.class)
|
||||
.hasMessage(
|
||||
@@ -66,11 +58,9 @@ final class RefasterRuleCollectionTestExtractorTest {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"EmptyRefasterRuleCollectionTestInput.java",
|
||||
"""
|
||||
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
|
||||
|
||||
final class EmptyRefasterRuleCollectionTest implements RefasterRuleCollectionTestCase {}
|
||||
""");
|
||||
"import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;",
|
||||
"",
|
||||
"final class EmptyRefasterRuleCollectionTest implements RefasterRuleCollectionTestCase {}");
|
||||
|
||||
verifyGeneratedFileContent(
|
||||
outputDirectory,
|
||||
@@ -87,15 +77,13 @@ final class RefasterRuleCollectionTestExtractorTest {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"SingletonRefasterRuleCollectionTestOutput.java",
|
||||
"""
|
||||
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
|
||||
|
||||
final class SingletonRefasterRuleCollectionTest implements RefasterRuleCollectionTestCase {
|
||||
int testMyRule() {
|
||||
return 42;
|
||||
}
|
||||
}
|
||||
""");
|
||||
"import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;",
|
||||
"",
|
||||
"final class SingletonRefasterRuleCollectionTest implements RefasterRuleCollectionTestCase {",
|
||||
" int testMyRule() {",
|
||||
" return 42;",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
verifyGeneratedFileContent(
|
||||
outputDirectory,
|
||||
@@ -118,33 +106,31 @@ final class RefasterRuleCollectionTestExtractorTest {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"pkg/ComplexRefasterRuleCollectionTestInput.java",
|
||||
"""
|
||||
package pkg;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
|
||||
|
||||
final class ComplexRefasterRuleCollectionTest implements RefasterRuleCollectionTestCase {
|
||||
private static final String IGNORED_CONSTANT = "constant";
|
||||
|
||||
@Override
|
||||
public ImmutableSet<Object> elidedTypesAndStaticImports() {
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
|
||||
/** Javadoc. */
|
||||
String testFirstRule() {
|
||||
return "Don't panic";
|
||||
}
|
||||
|
||||
// Comment.
|
||||
String testSecondRule() {
|
||||
return "Carry a towel";
|
||||
}
|
||||
|
||||
void testEmptyRule() {}
|
||||
}
|
||||
""");
|
||||
"package pkg;",
|
||||
"",
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;",
|
||||
"",
|
||||
"final class ComplexRefasterRuleCollectionTest implements RefasterRuleCollectionTestCase {",
|
||||
" private static final String IGNORED_CONSTANT = \"constant\";",
|
||||
"",
|
||||
" @Override",
|
||||
" public ImmutableSet<Object> elidedTypesAndStaticImports() {",
|
||||
" return ImmutableSet.of();",
|
||||
" }",
|
||||
"",
|
||||
" /** Javadoc. */",
|
||||
" String testFirstRule() {",
|
||||
" return \"Don't panic\";",
|
||||
" }",
|
||||
"",
|
||||
" // Comment.",
|
||||
" String testSecondRule() {",
|
||||
" return \"Carry a towel\";",
|
||||
" }",
|
||||
"",
|
||||
" void testEmptyRule() {}",
|
||||
"}");
|
||||
|
||||
verifyGeneratedFileContent(
|
||||
outputDirectory,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>tech.picnic.error-prone-support</groupId>
|
||||
<artifactId>error-prone-support</artifactId>
|
||||
<version>0.19.2-SNAPSHOT</version>
|
||||
<version>0.22.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>error-prone-contrib</artifactId>
|
||||
@@ -15,31 +15,6 @@
|
||||
<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>
|
||||
@@ -87,6 +62,41 @@
|
||||
<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>
|
||||
|
||||
@@ -11,6 +11,7 @@ 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;
|
||||
@@ -79,7 +80,10 @@ public final class DirectReturn extends BugChecker implements BlockTreeMatcher {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
Symbol variableSymbol = ASTHelpers.getSymbol(((ReturnTree) finalStatement).getExpression());
|
||||
Symbol variableSymbol =
|
||||
requireNonNull(
|
||||
ASTHelpers.getSymbol(((ReturnTree) finalStatement).getExpression()),
|
||||
"Missing symbol for returned variable");
|
||||
StatementTree precedingStatement = statements.get(statements.size() - 2);
|
||||
|
||||
return tryMatchAssignment(variableSymbol, precedingStatement)
|
||||
|
||||
@@ -0,0 +1,325 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ 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;
|
||||
@@ -33,6 +34,8 @@ 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;
|
||||
@@ -113,7 +116,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")
|
||||
.build();
|
||||
.buildOrThrow();
|
||||
|
||||
/** Instantiates a new {@link ExplicitArgumentEnumeration} instance. */
|
||||
public ExplicitArgumentEnumeration() {}
|
||||
@@ -178,30 +181,45 @@ public final class ExplicitArgumentEnumeration extends BugChecker
|
||||
state.getTypes())
|
||||
.collect(toImmutableList());
|
||||
|
||||
/*
|
||||
* 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
|
||||
return hasLikelySuitableVarargsOverload(method, overloads, state)
|
||||
? 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()
|
||||
|
||||
@@ -17,6 +17,7 @@ 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;
|
||||
@@ -129,7 +130,10 @@ public final class JUnitValueSource extends BugChecker implements MethodTreeMatc
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
Type parameterType = ASTHelpers.getType(Iterables.getOnlyElement(tree.getParameters()));
|
||||
Type parameterType =
|
||||
requireNonNull(
|
||||
ASTHelpers.getType(Iterables.getOnlyElement(tree.getParameters())),
|
||||
"Missing type for method parameter");
|
||||
|
||||
return findMethodSourceAnnotation(tree, state)
|
||||
.flatMap(
|
||||
@@ -173,7 +177,9 @@ public final class JUnitValueSource extends BugChecker implements MethodTreeMatc
|
||||
|
||||
private static Optional<MethodTree> findMatchingSibling(
|
||||
MethodTree tree, Predicate<? super MethodTree> predicate, VisitorState state) {
|
||||
return state.findEnclosing(ClassTree.class).getMembers().stream()
|
||||
return requireNonNull(state.findEnclosing(ClassTree.class), "No class enclosing method")
|
||||
.getMembers()
|
||||
.stream()
|
||||
.filter(MethodTree.class::isInstance)
|
||||
.map(MethodTree.class::cast)
|
||||
.filter(not(tree::equals))
|
||||
|
||||
@@ -5,6 +5,7 @@ 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;
|
||||
@@ -86,7 +87,9 @@ public final class NonEmptyMono extends BugChecker implements MethodInvocationTr
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
ExpressionTree receiver = ASTHelpers.getReceiver(tree);
|
||||
ExpressionTree receiver =
|
||||
requireNonNull(
|
||||
ASTHelpers.getReceiver(tree), "Instance method invocation must have receiver");
|
||||
if (!NON_EMPTY_MONO.matches(receiver, state)) {
|
||||
return Description.NO_MATCH;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ 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;
|
||||
@@ -69,6 +70,7 @@ 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(),
|
||||
@@ -129,6 +131,7 @@ public final class NonStaticImport extends BugChecker implements CompilationUnit
|
||||
"builder",
|
||||
"copyOf",
|
||||
"create",
|
||||
"EPOCH",
|
||||
"from",
|
||||
"getDefaultInstance",
|
||||
"INSTANCE",
|
||||
@@ -182,7 +185,7 @@ public final class NonStaticImport extends BugChecker implements CompilationUnit
|
||||
}
|
||||
}
|
||||
|
||||
return imports.build();
|
||||
return imports.buildOrThrow();
|
||||
}
|
||||
|
||||
private static boolean shouldNotBeStaticallyImported(String type, String member) {
|
||||
|
||||
@@ -28,8 +28,6 @@ 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)
|
||||
|
||||
@@ -54,7 +54,7 @@ public final class SpringMvcAnnotation extends BugChecker implements AnnotationT
|
||||
.put("PATCH", "PatchMapping")
|
||||
.put("POST", "PostMapping")
|
||||
.put("PUT", "PutMapping")
|
||||
.build();
|
||||
.buildOrThrow();
|
||||
|
||||
/** Instantiates a new {@link SpringMvcAnnotation} instance. */
|
||||
public SpringMvcAnnotation() {}
|
||||
|
||||
@@ -16,10 +16,12 @@ 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;
|
||||
@@ -41,7 +43,8 @@ import java.time.ZonedDateTime;
|
||||
linkType = CUSTOM,
|
||||
severity = WARNING,
|
||||
tags = FRAGILE_CODE)
|
||||
public final class TimeZoneUsage extends BugChecker implements MethodInvocationTreeMatcher {
|
||||
public final class TimeZoneUsage extends BugChecker
|
||||
implements MethodInvocationTreeMatcher, MemberReferenceTreeMatcher {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Matcher<ExpressionTree> BANNED_TIME_METHOD =
|
||||
anyOf(
|
||||
@@ -59,6 +62,10 @@ public final class TimeZoneUsage extends BugChecker implements MethodInvocationT
|
||||
"tickMillis",
|
||||
"tickMinutes",
|
||||
"tickSeconds"),
|
||||
staticMethod()
|
||||
.onClassAny(Instant.class.getCanonicalName())
|
||||
.named("now")
|
||||
.withNoParameters(),
|
||||
staticMethod()
|
||||
.onClassAny(
|
||||
LocalDate.class.getCanonicalName(),
|
||||
@@ -67,17 +74,22 @@ public final class TimeZoneUsage extends BugChecker implements MethodInvocationT
|
||||
OffsetDateTime.class.getCanonicalName(),
|
||||
OffsetTime.class.getCanonicalName(),
|
||||
ZonedDateTime.class.getCanonicalName())
|
||||
.named("now"),
|
||||
staticMethod()
|
||||
.onClassAny(Instant.class.getCanonicalName())
|
||||
.named("now")
|
||||
.withNoParameters());
|
||||
.named("now"));
|
||||
|
||||
/** 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;
|
||||
|
||||
@@ -18,6 +18,7 @@ final class AssertJCharSequenceRules {
|
||||
@BeforeTemplate
|
||||
void before(CharSequence charSequence) {
|
||||
Refaster.anyOf(
|
||||
assertThat(charSequence.isEmpty()).isTrue(),
|
||||
assertThat(charSequence.length()).isEqualTo(0L),
|
||||
assertThat(charSequence.length()).isNotPositive());
|
||||
}
|
||||
@@ -33,6 +34,7 @@ final class AssertJCharSequenceRules {
|
||||
@BeforeTemplate
|
||||
AbstractAssert<?, ?> before(CharSequence charSequence) {
|
||||
return Refaster.anyOf(
|
||||
assertThat(charSequence.isEmpty()).isFalse(),
|
||||
assertThat(charSequence.length()).isNotEqualTo(0),
|
||||
assertThat(charSequence.length()).isPositive());
|
||||
}
|
||||
|
||||
@@ -5,6 +5,9 @@ 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;
|
||||
|
||||
@@ -21,6 +24,11 @@ final class AssertJEnumerableRules {
|
||||
enumAssert.hasSizeLessThan(1));
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
void before(AbstractIterableAssert<?, ?, E, ?> enumAssert) {
|
||||
enumAssert.size().isNotPositive();
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
void after(EnumerableAssert<?, E> enumAssert) {
|
||||
enumAssert.isEmpty();
|
||||
@@ -34,30 +42,175 @@ 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 EnumerableAssertHasSameSizeAs<S, T> {
|
||||
static final class EnumerableAssertHasSize<E> {
|
||||
@BeforeTemplate
|
||||
EnumerableAssert<?, S> before(EnumerableAssert<?, S> enumAssert, Iterable<T> iterable) {
|
||||
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) {
|
||||
return enumAssert.hasSize(Iterables.size(iterable));
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
EnumerableAssert<?, S> before(EnumerableAssert<?, S> enumAssert, Collection<T> iterable) {
|
||||
EnumerableAssert<?, S> before(EnumerableAssert<?, S> enumAssert, Collection<E> iterable) {
|
||||
return enumAssert.hasSize(iterable.size());
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
EnumerableAssert<?, S> before(EnumerableAssert<?, S> enumAssert, T[] iterable) {
|
||||
EnumerableAssert<?, S> before(EnumerableAssert<?, S> enumAssert, E[] 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<T> iterable) {
|
||||
EnumerableAssert<?, S> after(EnumerableAssert<?, S> enumAssert, Iterable<E> iterable) {
|
||||
return enumAssert.hasSameSizeAs(iterable);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,6 @@ 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;
|
||||
@@ -182,13 +181,13 @@ final class AssertJMapRules {
|
||||
static final class AssertThatMapContainsOnlyKeys<K, V> {
|
||||
@BeforeTemplate
|
||||
AbstractCollectionAssert<?, Collection<? extends K>, K, ?> before(
|
||||
Map<K, V> map, Set<? extends K> keys) {
|
||||
Map<K, V> map, Iterable<? extends K> keys) {
|
||||
return assertThat(map.keySet()).hasSameElementsAs(keys);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
MapAssert<K, V> after(Map<K, V> map, Set<? extends K> keys) {
|
||||
MapAssert<K, V> after(Map<K, V> map, Iterable<? extends K> keys) {
|
||||
return assertThat(map).containsOnlyKeys(keys);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ 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;
|
||||
@@ -12,7 +11,6 @@ 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;
|
||||
@@ -22,9 +20,7 @@ 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;
|
||||
@@ -254,121 +250,19 @@ 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, List<T> list2) {
|
||||
ListAssert<S> before(List<S> list1, Iterable<T> list2) {
|
||||
return assertThat(list1).isEqualTo(list2);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
ListAssert<S> after(List<S> list1, List<T> list2) {
|
||||
ListAssert<S> after(List<S> list1, Iterable<T> list2) {
|
||||
return assertThat(list1).containsExactlyElementsOf(list2);
|
||||
}
|
||||
}
|
||||
@@ -379,7 +273,7 @@ final class AssertJRules {
|
||||
|
||||
static final class AssertThatSetsAreEqual<S, T extends S> {
|
||||
@BeforeTemplate
|
||||
AbstractCollectionAssert<?, ?, S, ?> before(Set<S> set1, Set<T> set2) {
|
||||
AbstractCollectionAssert<?, ?, S, ?> before(Set<S> set1, Iterable<T> set2) {
|
||||
return Refaster.anyOf(
|
||||
assertThat(set1).isEqualTo(set2),
|
||||
assertThat(set1).containsExactlyInAnyOrderElementsOf(set2));
|
||||
@@ -387,7 +281,7 @@ final class AssertJRules {
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractCollectionAssert<?, ?, S, ?> after(Set<S> set1, Set<T> set2) {
|
||||
AbstractCollectionAssert<?, ?, S, ?> after(Set<S> set1, Iterable<T> set2) {
|
||||
return assertThat(set1).hasSameElementsAs(set2);
|
||||
}
|
||||
}
|
||||
@@ -398,13 +292,13 @@ final class AssertJRules {
|
||||
|
||||
static final class AssertThatMultisetsAreEqual<S, T extends S> {
|
||||
@BeforeTemplate
|
||||
AbstractCollectionAssert<?, ?, S, ?> before(Multiset<S> multiset1, Multiset<T> multiset2) {
|
||||
AbstractCollectionAssert<?, ?, S, ?> before(Multiset<S> multiset1, Iterable<T> multiset2) {
|
||||
return assertThat(multiset1).isEqualTo(multiset2);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractCollectionAssert<?, ?, S, ?> after(Multiset<S> multiset1, Multiset<T> multiset2) {
|
||||
AbstractCollectionAssert<?, ?, S, ?> after(Multiset<S> multiset1, Iterable<T> multiset2) {
|
||||
return assertThat(multiset1).containsExactlyInAnyOrderElementsOf(multiset2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,19 +32,6 @@ 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) {
|
||||
@@ -57,41 +44,28 @@ 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, String substring) {
|
||||
AbstractBooleanAssert<?> before(String string, CharSequence substring) {
|
||||
return assertThat(string.contains(substring)).isTrue();
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractStringAssert<?> after(String string, String substring) {
|
||||
AbstractStringAssert<?> after(String string, CharSequence substring) {
|
||||
return assertThat(string).contains(substring);
|
||||
}
|
||||
}
|
||||
|
||||
static final class AssertThatStringDoesNotContain {
|
||||
@BeforeTemplate
|
||||
AbstractBooleanAssert<?> before(String string, String substring) {
|
||||
AbstractBooleanAssert<?> before(String string, CharSequence substring) {
|
||||
return assertThat(string.contains(substring)).isFalse();
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
|
||||
AbstractStringAssert<?> after(String string, String substring) {
|
||||
AbstractStringAssert<?> after(String string, CharSequence substring) {
|
||||
return assertThat(string).doesNotContain(substring);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,18 +121,18 @@ final class AssortedRules {
|
||||
*/
|
||||
static final class DisjointSets<T> {
|
||||
@BeforeTemplate
|
||||
boolean before(Set<T> set1, Set<T> set2) {
|
||||
return Sets.intersection(set1, set2).isEmpty();
|
||||
boolean before(Set<T> collection1, Set<T> collection2) {
|
||||
return Sets.intersection(collection1, collection2).isEmpty();
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
boolean before2(Set<T> set1, Set<T> set2) {
|
||||
return set1.stream().noneMatch(set2::contains);
|
||||
boolean before2(Collection<T> collection1, Collection<T> collection2) {
|
||||
return collection1.stream().noneMatch(collection2::contains);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
boolean after(Set<T> set1, Set<T> set2) {
|
||||
return disjoint(set1, set2);
|
||||
boolean after(Collection<T> collection1, Collection<T> collection2) {
|
||||
return disjoint(collection1, collection2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
|
||||
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 tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
|
||||
|
||||
/** Refaster rules related to expressions dealing with {@link CharSequence}s. */
|
||||
@OnlineDocumentation
|
||||
final class CharSequenceRules {
|
||||
private CharSequenceRules() {}
|
||||
|
||||
/**
|
||||
* Prefer {@link CharSequence#isEmpty()} over alternatives that consult the char sequence's
|
||||
* length.
|
||||
*/
|
||||
// XXX: Drop this rule once we (and OpenRewrite) no longer support projects targeting Java 14 or
|
||||
// below.
|
||||
static final class CharSequenceIsEmpty {
|
||||
@BeforeTemplate
|
||||
boolean before(CharSequence charSequence) {
|
||||
return Refaster.anyOf(
|
||||
charSequence.length() == 0, charSequence.length() <= 0, charSequence.length() < 1);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@AlsoNegation
|
||||
boolean after(CharSequence charSequence) {
|
||||
return charSequence.isEmpty();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -158,14 +158,14 @@ final class CollectionRules {
|
||||
}
|
||||
}
|
||||
|
||||
static final class SetRemoveAllCollection<T, S extends T> {
|
||||
static final class CollectionRemoveAllFromCollectionBlock<T, S extends T> {
|
||||
@BeforeTemplate
|
||||
void before(Set<T> removeFrom, Collection<S> elementsToRemove) {
|
||||
void before(Collection<T> removeFrom, Collection<S> elementsToRemove) {
|
||||
elementsToRemove.forEach(removeFrom::remove);
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
void before2(Set<T> removeFrom, Collection<S> elementsToRemove) {
|
||||
void before2(Collection<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(Set<T> removeFrom, Collection<S> elementsToRemove) {
|
||||
void before3(Collection<T> removeFrom, Collection<S> elementsToRemove) {
|
||||
for (S element : elementsToRemove) {
|
||||
removeFrom.remove(element);
|
||||
}
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
void after(Set<T> removeFrom, Collection<S> elementsToRemove) {
|
||||
void after(Collection<T> removeFrom, Collection<S> elementsToRemove) {
|
||||
removeFrom.removeAll(elementsToRemove);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ 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;
|
||||
@@ -11,6 +12,7 @@ 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;
|
||||
@@ -141,4 +143,35 @@ 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,8 +36,7 @@ final class ImmutableListMultimapRules {
|
||||
* Prefer {@link ImmutableListMultimap#builder()} over the associated constructor on constructions
|
||||
* that produce a less-specific type.
|
||||
*/
|
||||
// XXX: This drops generic type information, sometimes leading to non-compilable code. See
|
||||
// https://github.com/google/error-prone/pull/2706.
|
||||
// XXX: This rule may drop generic type information, leading to non-compilable code.
|
||||
static final class ImmutableListMultimapBuilder<K, V> {
|
||||
@BeforeTemplate
|
||||
ImmutableMultimap.Builder<K, V> before() {
|
||||
|
||||
@@ -28,8 +28,7 @@ final class ImmutableListRules {
|
||||
private ImmutableListRules() {}
|
||||
|
||||
/** Prefer {@link ImmutableList#builder()} over the associated constructor. */
|
||||
// XXX: This drops generic type information, sometimes leading to non-compilable code. See
|
||||
// https://github.com/google/error-prone/pull/2706.
|
||||
// XXX: This rule may drop generic type information, leading to non-compilable code.
|
||||
static final class ImmutableListBuilder<T> {
|
||||
@BeforeTemplate
|
||||
ImmutableList.Builder<T> before() {
|
||||
|
||||
@@ -15,6 +15,7 @@ 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;
|
||||
@@ -31,8 +32,7 @@ final class ImmutableMapRules {
|
||||
private ImmutableMapRules() {}
|
||||
|
||||
/** Prefer {@link ImmutableMap#builder()} over the associated constructor. */
|
||||
// XXX: This drops generic type information, sometimes leading to non-compilable code. See
|
||||
// https://github.com/google/error-prone/pull/2706.
|
||||
// XXX: This rule may drop generic type information, leading to non-compilable code.
|
||||
static final class ImmutableMapBuilder<K, V> {
|
||||
@BeforeTemplate
|
||||
ImmutableMap.Builder<K, V> before() {
|
||||
@@ -45,12 +45,28 @@ 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).build(),
|
||||
ImmutableMap.<K, V>builder().put(entry).buildOrThrow(),
|
||||
Stream.of(entry).collect(toImmutableMap(Map.Entry::getKey, Map.Entry::getValue)));
|
||||
}
|
||||
|
||||
@@ -105,16 +121,17 @@ final class ImmutableMapRules {
|
||||
/** Prefer {@link ImmutableMap#copyOf(Iterable)} over more contrived alternatives. */
|
||||
static final class EntryIterableToImmutableMap<K, V> {
|
||||
@BeforeTemplate
|
||||
ImmutableMap<K, V> before(Map<? extends K, ? extends V> iterable) {
|
||||
Map<K, V> before(Map<? extends K, ? extends V> iterable) {
|
||||
return Refaster.anyOf(
|
||||
ImmutableMap.copyOf(iterable.entrySet()),
|
||||
ImmutableMap.<K, V>builder().putAll(iterable).build());
|
||||
ImmutableMap.<K, V>builder().putAll(iterable).buildOrThrow(),
|
||||
Map.copyOf(iterable));
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
ImmutableMap<K, V> before(Iterable<? extends Map.Entry<? extends K, ? extends V>> iterable) {
|
||||
return Refaster.anyOf(
|
||||
ImmutableMap.<K, V>builder().putAll(iterable).build(),
|
||||
ImmutableMap.<K, V>builder().putAll(iterable).buildOrThrow(),
|
||||
Streams.stream(iterable).collect(toImmutableMap(Map.Entry::getKey, Map.Entry::getValue)));
|
||||
}
|
||||
|
||||
@@ -140,8 +157,6 @@ 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
|
||||
@@ -225,7 +240,11 @@ final class ImmutableMapRules {
|
||||
static final class ImmutableMapOf<K, V> {
|
||||
@BeforeTemplate
|
||||
Map<K, V> before() {
|
||||
return Refaster.anyOf(ImmutableMap.<K, V>builder().build(), emptyMap(), Map.of());
|
||||
return Refaster.anyOf(
|
||||
ImmutableMap.<K, V>builder().buildOrThrow(),
|
||||
ImmutableMap.ofEntries(),
|
||||
emptyMap(),
|
||||
Map.of());
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -244,7 +263,10 @@ final class ImmutableMapRules {
|
||||
@BeforeTemplate
|
||||
Map<K, V> before(K k1, V v1) {
|
||||
return Refaster.anyOf(
|
||||
ImmutableMap.<K, V>builder().put(k1, v1).build(), singletonMap(k1, v1), Map.of(k1, v1));
|
||||
ImmutableMap.<K, V>builder().put(k1, v1).buildOrThrow(),
|
||||
ImmutableMap.ofEntries(Map.entry(k1, v1)),
|
||||
singletonMap(k1, v1),
|
||||
Map.of(k1, v1));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -262,7 +284,8 @@ final class ImmutableMapRules {
|
||||
static final class ImmutableMapOf2<K, V> {
|
||||
@BeforeTemplate
|
||||
Map<K, V> before(K k1, V v1, K k2, V v2) {
|
||||
return Map.of(k1, v1, k2, v2);
|
||||
return Refaster.anyOf(
|
||||
ImmutableMap.ofEntries(Map.entry(k1, v1), Map.entry(k2, v2)), Map.of(k1, v1, k2, v2));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -280,7 +303,9 @@ 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 Map.of(k1, v1, k2, v2, k3, 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));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -300,7 +325,10 @@ 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 Map.of(k1, v1, k2, v2, k3, v3, k4, 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));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -320,7 +348,14 @@ 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 Map.of(k1, v1, k2, v2, k3, v3, k4, v4, k5, 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));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -338,14 +373,14 @@ final class ImmutableMapRules {
|
||||
abstract boolean keyFilter(@MayOptionallyUse K key);
|
||||
|
||||
@BeforeTemplate
|
||||
ImmutableMap<K, V> before(ImmutableMap<K, V> map) {
|
||||
ImmutableMap<K, V> before(Map<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(ImmutableMap<K, V> map) {
|
||||
ImmutableMap<K, V> after(Map<K, V> map) {
|
||||
return ImmutableMap.copyOf(Maps.filterKeys(map, k -> keyFilter(k)));
|
||||
}
|
||||
}
|
||||
@@ -359,18 +394,34 @@ final class ImmutableMapRules {
|
||||
abstract boolean valueFilter(@MayOptionallyUse V value);
|
||||
|
||||
@BeforeTemplate
|
||||
ImmutableMap<K, V> before(ImmutableMap<K, V> map) {
|
||||
ImmutableMap<K, V> before(Map<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(ImmutableMap<K, V> map) {
|
||||
ImmutableMap<K, V> after(Map<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)
|
||||
// ->
|
||||
|
||||
@@ -21,8 +21,7 @@ final class ImmutableMultisetRules {
|
||||
private ImmutableMultisetRules() {}
|
||||
|
||||
/** Prefer {@link ImmutableMultiset#builder()} over the associated constructor. */
|
||||
// XXX: This drops generic type information, sometimes leading to non-compilable code. See
|
||||
// https://github.com/google/error-prone/pull/2706.
|
||||
// XXX: This rule may drop generic type information, leading to non-compilable code.
|
||||
static final class ImmutableMultisetBuilder<T> {
|
||||
@BeforeTemplate
|
||||
ImmutableMultiset.Builder<T> before() {
|
||||
|
||||
@@ -29,8 +29,7 @@ final class ImmutableSetMultimapRules {
|
||||
private ImmutableSetMultimapRules() {}
|
||||
|
||||
/** Prefer {@link ImmutableSetMultimap#builder()} over the associated constructor. */
|
||||
// XXX: This drops generic type information, sometimes leading to non-compilable code. See
|
||||
// https://github.com/google/error-prone/pull/2706.
|
||||
// XXX: This rule may drop generic type information, leading to non-compilable code.
|
||||
static final class ImmutableSetMultimapBuilder<K, V> {
|
||||
@BeforeTemplate
|
||||
ImmutableSetMultimap.Builder<K, V> before() {
|
||||
|
||||
@@ -29,8 +29,7 @@ final class ImmutableSetRules {
|
||||
private ImmutableSetRules() {}
|
||||
|
||||
/** Prefer {@link ImmutableSet#builder()} over the associated constructor. */
|
||||
// XXX: This drops generic type information, sometimes leading to non-compilable code. See
|
||||
// https://github.com/google/error-prone/pull/2706.
|
||||
// XXX: This rule may drop generic type information, leading to non-compilable code.
|
||||
static final class ImmutableSetBuilder<T> {
|
||||
@BeforeTemplate
|
||||
ImmutableSet.Builder<T> before() {
|
||||
|
||||
@@ -37,8 +37,7 @@ final class ImmutableSortedMapRules {
|
||||
* Prefer {@link ImmutableSortedMap#naturalOrder()} over the alternative that requires explicitly
|
||||
* providing the {@link Comparator}.
|
||||
*/
|
||||
// XXX: This drops generic type information, sometimes leading to non-compilable code. See
|
||||
// https://github.com/google/error-prone/pull/2706.
|
||||
// XXX: This rule may drop generic type information, leading to non-compilable code.
|
||||
static final class ImmutableSortedMapNaturalOrderBuilder<K extends Comparable<? super K>, V> {
|
||||
@BeforeTemplate
|
||||
ImmutableSortedMap.Builder<K, V> before() {
|
||||
@@ -55,8 +54,7 @@ final class ImmutableSortedMapRules {
|
||||
* Prefer {@link ImmutableSortedMap#reverseOrder()} over the alternative that requires explicitly
|
||||
* providing the {@link Comparator}.
|
||||
*/
|
||||
// XXX: This drops generic type information, sometimes leading to non-compilable code. See
|
||||
// https://github.com/google/error-prone/pull/2706.
|
||||
// XXX: This rule may drop generic type information, leading to non-compilable code.
|
||||
static final class ImmutableSortedMapReverseOrderBuilder<K extends Comparable<? super K>, V> {
|
||||
@BeforeTemplate
|
||||
ImmutableSortedMap.Builder<K, V> before() {
|
||||
@@ -73,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().build();
|
||||
return ImmutableSortedMap.<K, V>naturalOrder().buildOrThrow();
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -91,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).build();
|
||||
return ImmutableSortedMap.<K, V>naturalOrder().put(key, value).buildOrThrow();
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -107,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).build(),
|
||||
ImmutableSortedMap.<K, V>naturalOrder().put(entry).buildOrThrow(),
|
||||
Stream.of(entry)
|
||||
.collect(
|
||||
toImmutableSortedMap(naturalOrder(), Map.Entry::getKey, Map.Entry::getValue)));
|
||||
@@ -128,7 +126,7 @@ final class ImmutableSortedMapRules {
|
||||
return Refaster.anyOf(
|
||||
ImmutableSortedMap.copyOf(iterable, naturalOrder()),
|
||||
ImmutableSortedMap.copyOf(iterable.entrySet()),
|
||||
ImmutableSortedMap.<K, V>naturalOrder().putAll(iterable).build());
|
||||
ImmutableSortedMap.<K, V>naturalOrder().putAll(iterable).buildOrThrow());
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
@@ -136,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).build(),
|
||||
ImmutableSortedMap.<K, V>naturalOrder().putAll(iterable).buildOrThrow(),
|
||||
Streams.stream(iterable)
|
||||
.collect(
|
||||
toImmutableSortedMap(
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,8 @@ 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;
|
||||
@@ -34,7 +36,8 @@ 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: Not all JUnit `Assertions` methods have an associated Refaster rule yet; expand this class.
|
||||
// XXX: The `AssertThat*Array*ContainsExactly*` rules assume that `expected` and `actual` are not
|
||||
// both `null`.
|
||||
// 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
|
||||
@@ -50,39 +53,6 @@ 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)",
|
||||
@@ -302,6 +272,436 @@ 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() {
|
||||
|
||||
@@ -3,6 +3,7 @@ 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;
|
||||
@@ -94,11 +95,14 @@ final class NullRules {
|
||||
}
|
||||
}
|
||||
|
||||
/** Prefer {@link Objects#isNull(Object)} over the equivalent lambda function. */
|
||||
/**
|
||||
* Prefer {@link Objects#isNull(Object)} over the equivalent lambda function or more contrived
|
||||
* alternatives.
|
||||
*/
|
||||
static final class IsNullFunction<T> {
|
||||
@BeforeTemplate
|
||||
Predicate<T> before() {
|
||||
return o -> o == null;
|
||||
return Refaster.anyOf(o -> o == null, not(Objects::nonNull));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -107,11 +111,14 @@ final class NullRules {
|
||||
}
|
||||
}
|
||||
|
||||
/** Prefer {@link Objects#nonNull(Object)} over the equivalent lambda function. */
|
||||
/**
|
||||
* Prefer {@link Objects#nonNull(Object)} over the equivalent lambda function or more contrived
|
||||
* alternatives.
|
||||
*/
|
||||
static final class NonNullFunction<T> {
|
||||
@BeforeTemplate
|
||||
Predicate<T> before() {
|
||||
return o -> o != null;
|
||||
return Refaster.anyOf(o -> o != null, not(Objects::isNull));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
|
||||
@@ -282,6 +282,8 @@ 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) {
|
||||
|
||||
@@ -8,12 +8,15 @@ 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. */
|
||||
@@ -525,10 +528,7 @@ final class PrimitiveRules {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer JDK's {@link Integer#toUnsignedString(int,int)} over third-party or more verbose
|
||||
* alternatives.
|
||||
*/
|
||||
/** Prefer JDK's {@link Integer#toUnsignedString(int,int)} over third-party alternatives. */
|
||||
static final class IntegerToUnsignedStringWithRadix {
|
||||
@BeforeTemplate
|
||||
String before(int i, int radix) {
|
||||
@@ -541,10 +541,7 @@ final class PrimitiveRules {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer JDK's {@link Long#toUnsignedString(long,int)} over third-party or more verbose
|
||||
* alternatives.
|
||||
*/
|
||||
/** Prefer JDK's {@link Long#toUnsignedString(long,int)} over third-party alternatives. */
|
||||
static final class LongToUnsignedStringWithRadix {
|
||||
@BeforeTemplate
|
||||
String before(long i, int radix) {
|
||||
@@ -556,4 +553,49 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -489,9 +489,16 @@ 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 Mono.just(value).repeat().take(1);
|
||||
return Refaster.anyOf(
|
||||
Mono.just(value).flux(),
|
||||
Mono.just(value).repeat().take(1),
|
||||
Flux.fromIterable(ImmutableList.of(value)),
|
||||
Flux.fromIterable(ImmutableSet.of(value)));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
@@ -508,8 +515,14 @@ 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
|
||||
Mono<@Nullable Void> before2(Mono<@Nullable Void> mono) {
|
||||
@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) {
|
||||
return Refaster.anyOf(mono.ignoreElement(), mono.then());
|
||||
}
|
||||
|
||||
@@ -889,6 +902,38 @@ 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
|
||||
@@ -906,12 +951,18 @@ final class ReactorRules {
|
||||
/** Prefer direct invocation of {@link Mono#then()}} over more contrived alternatives. */
|
||||
static final class MonoThen<T> {
|
||||
@BeforeTemplate
|
||||
Mono<@Nullable Void> before(Mono<T> mono) {
|
||||
return Refaster.anyOf(mono.ignoreElement().then(), mono.flux().then());
|
||||
@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));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Mono<@Nullable Void> after(Mono<T> mono) {
|
||||
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
|
||||
Mono<? extends @Nullable Void> after(Mono<T> mono) {
|
||||
return mono.then();
|
||||
}
|
||||
}
|
||||
@@ -919,17 +970,25 @@ final class ReactorRules {
|
||||
/** Avoid vacuous invocations of {@link Flux#ignoreElements()}. */
|
||||
static final class FluxThen<T> {
|
||||
@BeforeTemplate
|
||||
Mono<@Nullable Void> before(Flux<T> flux) {
|
||||
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
|
||||
Mono<? extends @Nullable Void> before(Flux<T> flux) {
|
||||
return flux.ignoreElements().then();
|
||||
}
|
||||
|
||||
// XXX: Consider filing a SonarCloud issue for the S2637 false positive.
|
||||
@BeforeTemplate
|
||||
Mono<@Nullable Void> before2(Flux<@Nullable Void> flux) {
|
||||
@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) {
|
||||
return flux.ignoreElements();
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Mono<@Nullable Void> after(Flux<T> flux) {
|
||||
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
|
||||
Mono<? extends @Nullable Void> after(Flux<T> flux) {
|
||||
return flux.then();
|
||||
}
|
||||
}
|
||||
@@ -937,12 +996,14 @@ final class ReactorRules {
|
||||
/** Avoid vacuous invocations of {@link Mono#ignoreElement()}. */
|
||||
static final class MonoThenEmpty<T> {
|
||||
@BeforeTemplate
|
||||
Mono<@Nullable Void> before(Mono<T> mono, Publisher<@Nullable Void> publisher) {
|
||||
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
|
||||
Mono<? extends @Nullable Void> before(Mono<T> mono, Publisher<@Nullable Void> publisher) {
|
||||
return mono.ignoreElement().thenEmpty(publisher);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Mono<@Nullable Void> after(Mono<T> mono, Publisher<@Nullable Void> publisher) {
|
||||
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
|
||||
Mono<? extends @Nullable Void> after(Mono<T> mono, Publisher<@Nullable Void> publisher) {
|
||||
return mono.thenEmpty(publisher);
|
||||
}
|
||||
}
|
||||
@@ -950,12 +1011,14 @@ final class ReactorRules {
|
||||
/** Avoid vacuous invocations of {@link Flux#ignoreElements()}. */
|
||||
static final class FluxThenEmpty<T> {
|
||||
@BeforeTemplate
|
||||
Mono<@Nullable Void> before(Flux<T> flux, Publisher<@Nullable Void> publisher) {
|
||||
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
|
||||
Mono<? extends @Nullable Void> before(Flux<T> flux, Publisher<@Nullable Void> publisher) {
|
||||
return flux.ignoreElements().thenEmpty(publisher);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Mono<@Nullable Void> after(Flux<T> flux, Publisher<@Nullable Void> publisher) {
|
||||
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
|
||||
Mono<? extends @Nullable Void> after(Flux<T> flux, Publisher<@Nullable Void> publisher) {
|
||||
return flux.thenEmpty(publisher);
|
||||
}
|
||||
}
|
||||
@@ -1011,7 +1074,8 @@ final class ReactorRules {
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
Mono<@Nullable Void> before2(Mono<T> mono1, Mono<@Nullable Void> mono2) {
|
||||
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
|
||||
Mono<? extends @Nullable Void> before2(Mono<T> mono1, Mono<@Nullable Void> mono2) {
|
||||
return mono1.thenEmpty(mono2);
|
||||
}
|
||||
|
||||
@@ -1029,7 +1093,8 @@ final class ReactorRules {
|
||||
}
|
||||
|
||||
@BeforeTemplate
|
||||
Mono<@Nullable Void> before2(Flux<T> flux, Mono<@Nullable Void> mono) {
|
||||
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
|
||||
Mono<? extends @Nullable Void> before2(Flux<T> flux, Mono<@Nullable Void> mono) {
|
||||
return flux.thenEmpty(mono);
|
||||
}
|
||||
|
||||
@@ -1046,10 +1111,12 @@ 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) {
|
||||
Mono<Optional<T>> before(Mono<T> mono, Optional<T> optional, Mono<Optional<T>> alternate) {
|
||||
return Refaster.anyOf(
|
||||
mono.flux().collect(toOptional()),
|
||||
mono.map(Optional::of).defaultIfEmpty(Optional.empty()),
|
||||
mono.map(Optional::of),
|
||||
mono.singleOptional().defaultIfEmpty(optional),
|
||||
mono.singleOptional().switchIfEmpty(alternate),
|
||||
mono.transform(Mono::singleOptional));
|
||||
}
|
||||
|
||||
@@ -2142,6 +2209,22 @@ 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
|
||||
|
||||
@@ -23,14 +23,16 @@ final class RxJava2AdapterRules {
|
||||
/** Use the fluent API style when using {@link RxJava2Adapter#completableToMono}. */
|
||||
static final class CompletableToMono {
|
||||
@BeforeTemplate
|
||||
Mono<@Nullable Void> before(Completable completable) {
|
||||
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
|
||||
Mono<? extends @Nullable Void> before(Completable completable) {
|
||||
return Refaster.anyOf(
|
||||
RxJava2Adapter.completableToMono(completable),
|
||||
completable.to(RxJava2Adapter::completableToMono));
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Mono<@Nullable Void> after(Completable completable) {
|
||||
@SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
|
||||
Mono<? extends @Nullable Void> after(Completable completable) {
|
||||
return completable.as(RxJava2Adapter::completableToMono);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,11 +29,14 @@ final class StringRules {
|
||||
private StringRules() {}
|
||||
|
||||
/** Prefer {@link String#isEmpty()} over alternatives that consult the string's length. */
|
||||
// XXX: Now that we build with JDK 15+, this rule can be generalized to cover all `CharSequence`
|
||||
// subtypes. This does require a mechanism (perhaps an annotation, or a separate Maven module) to
|
||||
// make sure that non-String expressions are rewritten only if client code also targets JDK 15+.
|
||||
// XXX: Drop this rule once we (and OpenRewrite) no longer support projects targeting Java 14 or
|
||||
// below. The `CharSequenceIsEmpty` rule then suffices. (This rule exists so that e.g. projects
|
||||
// that target JDK 11 can disable `CharSequenceIsEmpty` without losing a valuable rule.)
|
||||
// XXX: Look into a more general approach to supporting different Java language levels, such as
|
||||
// rule selection based on some annotation, or a separate Maven module.
|
||||
static final class StringIsEmpty {
|
||||
@BeforeTemplate
|
||||
@SuppressWarnings("CharSequenceIsEmpty" /* This is a more specific template. */)
|
||||
boolean before(String str) {
|
||||
return Refaster.anyOf(str.length() == 0, str.length() <= 0, str.length() < 1);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
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;
|
||||
@@ -65,16 +66,18 @@ final class SuggestedFixRules {
|
||||
}
|
||||
}
|
||||
|
||||
/** Prefer {@link SuggestedFix#swap(Tree, Tree)} over more contrived alternatives. */
|
||||
/**
|
||||
* Prefer {@link SuggestedFix#swap(Tree, Tree, VisitorState)} over more contrived alternatives.
|
||||
*/
|
||||
static final class SuggestedFixSwap {
|
||||
@BeforeTemplate
|
||||
SuggestedFix before(Tree tree1, Tree tree2) {
|
||||
return SuggestedFix.builder().swap(tree1, tree2).build();
|
||||
SuggestedFix before(Tree tree1, Tree tree2, VisitorState state) {
|
||||
return SuggestedFix.builder().swap(tree1, tree2, state).build();
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
SuggestedFix after(Tree tree1, Tree tree2) {
|
||||
return SuggestedFix.swap(tree1, tree2);
|
||||
SuggestedFix after(Tree tree1, Tree tree2, VisitorState state) {
|
||||
return SuggestedFix.swap(tree1, tree2, state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,71 +53,20 @@ 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: The `assertEquals` tests for this class generally use the same expression for `expected` and
|
||||
// XXX: Many of the test expressions for these rules 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<?>)",
|
||||
@@ -351,47 +300,168 @@ 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);
|
||||
@@ -414,47 +484,168 @@ 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);
|
||||
@@ -485,7 +676,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));
|
||||
}
|
||||
}
|
||||
@@ -635,6 +826,58 @@ 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) {
|
||||
|
||||
@@ -13,101 +13,99 @@ final class AmbiguousJsonCreatorTest {
|
||||
"X", m -> m.contains("`JsonCreator.Mode` should be set for single-argument creators"))
|
||||
.addSourceLines(
|
||||
"Container.java",
|
||||
"""
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
|
||||
interface Container {
|
||||
enum A {
|
||||
FOO(1);
|
||||
|
||||
private final int i;
|
||||
|
||||
A(int i) {
|
||||
this.i = i;
|
||||
}
|
||||
|
||||
// BUG: Diagnostic matches: X
|
||||
@JsonCreator
|
||||
public static A of(int i) {
|
||||
return FOO;
|
||||
}
|
||||
}
|
||||
|
||||
enum B {
|
||||
FOO(1);
|
||||
|
||||
private final int i;
|
||||
|
||||
B(int i) {
|
||||
this.i = i;
|
||||
}
|
||||
|
||||
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
|
||||
public static B of(int i) {
|
||||
return FOO;
|
||||
}
|
||||
}
|
||||
|
||||
enum C {
|
||||
FOO(1, "s");
|
||||
|
||||
@JsonValue private final int i;
|
||||
private final String s;
|
||||
|
||||
C(int i, String s) {
|
||||
this.i = i;
|
||||
this.s = s;
|
||||
}
|
||||
|
||||
// BUG: Diagnostic matches: X
|
||||
@JsonCreator
|
||||
public static C of(int i) {
|
||||
return FOO;
|
||||
}
|
||||
}
|
||||
|
||||
enum D {
|
||||
FOO(1, "s");
|
||||
|
||||
private final int i;
|
||||
private final String s;
|
||||
|
||||
D(int i, String s) {
|
||||
this.i = i;
|
||||
this.s = s;
|
||||
}
|
||||
|
||||
@JsonCreator
|
||||
public static D of(int i, String s) {
|
||||
return FOO;
|
||||
}
|
||||
}
|
||||
|
||||
enum E {
|
||||
FOO;
|
||||
|
||||
// BUG: Diagnostic matches: X
|
||||
@JsonCreator
|
||||
public static E of(String s) {
|
||||
return FOO;
|
||||
}
|
||||
}
|
||||
|
||||
class F {
|
||||
private final String s;
|
||||
|
||||
F(String s) {
|
||||
this.s = s;
|
||||
}
|
||||
|
||||
@JsonCreator
|
||||
public static F of(String s) {
|
||||
return new F(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import com.fasterxml.jackson.annotation.JsonCreator;",
|
||||
"import com.fasterxml.jackson.annotation.JsonValue;",
|
||||
"",
|
||||
"interface Container {",
|
||||
" enum A {",
|
||||
" FOO(1);",
|
||||
"",
|
||||
" private final int i;",
|
||||
"",
|
||||
" A(int i) {",
|
||||
" this.i = i;",
|
||||
" }",
|
||||
"",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" @JsonCreator",
|
||||
" public static A of(int i) {",
|
||||
" return FOO;",
|
||||
" }",
|
||||
" }",
|
||||
"",
|
||||
" enum B {",
|
||||
" FOO(1);",
|
||||
"",
|
||||
" private final int i;",
|
||||
"",
|
||||
" B(int i) {",
|
||||
" this.i = i;",
|
||||
" }",
|
||||
"",
|
||||
" @JsonCreator(mode = JsonCreator.Mode.DELEGATING)",
|
||||
" public static B of(int i) {",
|
||||
" return FOO;",
|
||||
" }",
|
||||
" }",
|
||||
"",
|
||||
" enum C {",
|
||||
" FOO(1, \"s\");",
|
||||
"",
|
||||
" @JsonValue private final int i;",
|
||||
" private final String s;",
|
||||
"",
|
||||
" C(int i, String s) {",
|
||||
" this.i = i;",
|
||||
" this.s = s;",
|
||||
" }",
|
||||
"",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" @JsonCreator",
|
||||
" public static C of(int i) {",
|
||||
" return FOO;",
|
||||
" }",
|
||||
" }",
|
||||
"",
|
||||
" enum D {",
|
||||
" FOO(1, \"s\");",
|
||||
"",
|
||||
" private final int i;",
|
||||
" private final String s;",
|
||||
"",
|
||||
" D(int i, String s) {",
|
||||
" this.i = i;",
|
||||
" this.s = s;",
|
||||
" }",
|
||||
"",
|
||||
" @JsonCreator",
|
||||
" public static D of(int i, String s) {",
|
||||
" return FOO;",
|
||||
" }",
|
||||
" }",
|
||||
"",
|
||||
" enum E {",
|
||||
" FOO;",
|
||||
"",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" @JsonCreator",
|
||||
" public static E of(String s) {",
|
||||
" return FOO;",
|
||||
" }",
|
||||
" }",
|
||||
"",
|
||||
" class F {",
|
||||
" private final String s;",
|
||||
"",
|
||||
" F(String s) {",
|
||||
" this.s = s;",
|
||||
" }",
|
||||
"",
|
||||
" @JsonCreator",
|
||||
" public static F of(String s) {",
|
||||
" return new F(s);",
|
||||
" }",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -116,32 +114,28 @@ final class AmbiguousJsonCreatorTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(AmbiguousJsonCreator.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
|
||||
enum A {
|
||||
FOO;
|
||||
|
||||
@JsonCreator
|
||||
public static A of(String s) {
|
||||
return FOO;
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import com.fasterxml.jackson.annotation.JsonCreator;",
|
||||
"",
|
||||
"enum A {",
|
||||
" FOO;",
|
||||
"",
|
||||
" @JsonCreator",
|
||||
" public static A of(String s) {",
|
||||
" return FOO;",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
|
||||
enum A {
|
||||
FOO;
|
||||
|
||||
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
|
||||
public static A of(String s) {
|
||||
return FOO;
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import com.fasterxml.jackson.annotation.JsonCreator;",
|
||||
"",
|
||||
"enum A {",
|
||||
" FOO;",
|
||||
"",
|
||||
" @JsonCreator(mode = JsonCreator.Mode.DELEGATING)",
|
||||
" public static A of(String s) {",
|
||||
" return FOO;",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,24 +11,22 @@ final class AssertJIsNullTest {
|
||||
CompilationTestHelper.newInstance(AssertJIsNull.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
assertThat(1).isEqualTo(1);
|
||||
// BUG: Diagnostic contains:
|
||||
assertThat(1).isEqualTo(null);
|
||||
// BUG: Diagnostic contains:
|
||||
assertThat("foo").isEqualTo(null);
|
||||
isEqualTo(null);
|
||||
}
|
||||
|
||||
private boolean isEqualTo(Object value) {
|
||||
return value.equals("bar");
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static org.assertj.core.api.Assertions.assertThat;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" assertThat(1).isEqualTo(1);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" assertThat(1).isEqualTo(null);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" assertThat(\"foo\").isEqualTo(null);",
|
||||
" isEqualTo(null);",
|
||||
" }",
|
||||
"",
|
||||
" private boolean isEqualTo(Object value) {",
|
||||
" return value.equals(\"bar\");",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -37,28 +35,24 @@ final class AssertJIsNullTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(AssertJIsNull.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
assertThat(1).isEqualTo(null);
|
||||
assertThat("foo").isEqualTo(null);
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static org.assertj.core.api.Assertions.assertThat;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" assertThat(1).isEqualTo(null);",
|
||||
" assertThat(\"foo\").isEqualTo(null);",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
assertThat(1).isNull();
|
||||
assertThat("foo").isNull();
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static org.assertj.core.api.Assertions.assertThat;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" assertThat(1).isNull();",
|
||||
" assertThat(\"foo\").isNull();",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,58 +11,56 @@ final class AutowiredConstructorTest {
|
||||
CompilationTestHelper.newInstance(AutowiredConstructor.class, getClass())
|
||||
.addSourceLines(
|
||||
"Container.java",
|
||||
"""
|
||||
import com.google.errorprone.annotations.Immutable;
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
interface Container {
|
||||
@Immutable
|
||||
class A {
|
||||
A() {}
|
||||
}
|
||||
|
||||
class B {
|
||||
@Autowired
|
||||
void setProperty(Object o) {}
|
||||
}
|
||||
|
||||
class C {
|
||||
// BUG: Diagnostic contains:
|
||||
@Autowired
|
||||
C() {}
|
||||
}
|
||||
|
||||
class D {
|
||||
// BUG: Diagnostic contains:
|
||||
@Autowired
|
||||
D(String x) {}
|
||||
}
|
||||
|
||||
class E {
|
||||
@Autowired
|
||||
E() {}
|
||||
|
||||
E(String x) {}
|
||||
}
|
||||
|
||||
class F {
|
||||
F() {}
|
||||
|
||||
@Autowired
|
||||
F(String x) {}
|
||||
}
|
||||
|
||||
class G {
|
||||
@Autowired private Object o;
|
||||
}
|
||||
|
||||
class H {
|
||||
@SafeVarargs
|
||||
H(List<String>... lists) {}
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import com.google.errorprone.annotations.Immutable;",
|
||||
"import java.util.List;",
|
||||
"import org.springframework.beans.factory.annotation.Autowired;",
|
||||
"",
|
||||
"interface Container {",
|
||||
" @Immutable",
|
||||
" class A {",
|
||||
" A() {}",
|
||||
" }",
|
||||
"",
|
||||
" class B {",
|
||||
" @Autowired",
|
||||
" void setProperty(Object o) {}",
|
||||
" }",
|
||||
"",
|
||||
" class C {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Autowired",
|
||||
" C() {}",
|
||||
" }",
|
||||
"",
|
||||
" class D {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Autowired",
|
||||
" D(String x) {}",
|
||||
" }",
|
||||
"",
|
||||
" class E {",
|
||||
" @Autowired",
|
||||
" E() {}",
|
||||
"",
|
||||
" E(String x) {}",
|
||||
" }",
|
||||
"",
|
||||
" class F {",
|
||||
" F() {}",
|
||||
"",
|
||||
" @Autowired",
|
||||
" F(String x) {}",
|
||||
" }",
|
||||
"",
|
||||
" class G {",
|
||||
" @Autowired private Object o;",
|
||||
" }",
|
||||
"",
|
||||
" class H {",
|
||||
" @SafeVarargs",
|
||||
" H(List<String>... lists) {}",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -71,38 +69,34 @@ final class AutowiredConstructorTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(AutowiredConstructor.class, getClass())
|
||||
.addInputLines(
|
||||
"Container.java",
|
||||
"""
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
interface Container {
|
||||
class A {
|
||||
@Autowired
|
||||
@Deprecated
|
||||
A() {}
|
||||
}
|
||||
|
||||
class B {
|
||||
@Autowired
|
||||
B(String x) {}
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import org.springframework.beans.factory.annotation.Autowired;",
|
||||
"",
|
||||
"interface Container {",
|
||||
" class A {",
|
||||
" @Autowired",
|
||||
" @Deprecated",
|
||||
" A() {}",
|
||||
" }",
|
||||
"",
|
||||
" class B {",
|
||||
" @Autowired",
|
||||
" B(String x) {}",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"Container.java",
|
||||
"""
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
interface Container {
|
||||
class A {
|
||||
@Deprecated
|
||||
A() {}
|
||||
}
|
||||
|
||||
class B {
|
||||
B(String x) {}
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import org.springframework.beans.factory.annotation.Autowired;",
|
||||
"",
|
||||
"interface Container {",
|
||||
" class A {",
|
||||
" @Deprecated",
|
||||
" A() {}",
|
||||
" }",
|
||||
"",
|
||||
" class B {",
|
||||
" B(String x) {}",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,130 +11,128 @@ final class CanonicalAnnotationSyntaxTest {
|
||||
CompilationTestHelper.newInstance(CanonicalAnnotationSyntax.class, getClass())
|
||||
.addSourceLines(
|
||||
"pkg/A.java",
|
||||
"""
|
||||
package pkg;
|
||||
|
||||
import pkg.A.Foo;
|
||||
|
||||
interface A {
|
||||
@interface Foo {
|
||||
int[] value() default {};
|
||||
|
||||
int[] value2() default {};
|
||||
}
|
||||
|
||||
@pkg.A.Foo
|
||||
A minimal1();
|
||||
|
||||
@A.Foo
|
||||
A minimal2();
|
||||
|
||||
@Foo
|
||||
A minimal3();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@pkg.A.Foo()
|
||||
A functional1();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@A.Foo()
|
||||
A functional2();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@Foo()
|
||||
A functional3();
|
||||
|
||||
@pkg.A.Foo(1)
|
||||
A simple1();
|
||||
|
||||
@A.Foo(1)
|
||||
A simple2();
|
||||
|
||||
@Foo(1)
|
||||
A simple3();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@pkg.A.Foo({1})
|
||||
A singleton1();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@A.Foo({1})
|
||||
A singleton2();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@Foo({1})
|
||||
A singleton3();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@pkg.A.Foo(value = 1)
|
||||
A verbose1();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@A.Foo(value = 1)
|
||||
A verbose2();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@Foo(value = 1)
|
||||
A verbose3();
|
||||
|
||||
@pkg.A.Foo(value2 = 2)
|
||||
A custom1();
|
||||
|
||||
@A.Foo(value2 = 2)
|
||||
A custom2();
|
||||
|
||||
@Foo(value2 = 2)
|
||||
A custom3();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@pkg.A.Foo(value2 = {2})
|
||||
A customSingleton1();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@A.Foo(value2 = {2})
|
||||
A customSingleton2();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@Foo(value2 = {2})
|
||||
A customSingleton3();
|
||||
|
||||
@pkg.A.Foo(value2 = {2, 2})
|
||||
A customPair1();
|
||||
|
||||
@A.Foo(value2 = {2, 2})
|
||||
A customPair2();
|
||||
|
||||
@Foo(value2 = {2, 2})
|
||||
A customPair3();
|
||||
|
||||
@pkg.A.Foo(value = 1, value2 = 2)
|
||||
A extended1();
|
||||
|
||||
@A.Foo(value = 1, value2 = 2)
|
||||
A extended2();
|
||||
|
||||
@Foo(value = 1, value2 = 2)
|
||||
A extended3();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@pkg.A.Foo({
|
||||
1, 1,
|
||||
})
|
||||
A trailingComma1();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@A.Foo({
|
||||
1, 1,
|
||||
})
|
||||
A trailingComma2();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@Foo({
|
||||
1, 1,
|
||||
})
|
||||
A trailingComma3();
|
||||
}
|
||||
""")
|
||||
"package pkg;",
|
||||
"",
|
||||
"import pkg.A.Foo;",
|
||||
"",
|
||||
"interface A {",
|
||||
" @interface Foo {",
|
||||
" int[] value() default {};",
|
||||
"",
|
||||
" int[] value2() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @pkg.A.Foo",
|
||||
" A minimal1();",
|
||||
"",
|
||||
" @A.Foo",
|
||||
" A minimal2();",
|
||||
"",
|
||||
" @Foo",
|
||||
" A minimal3();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @pkg.A.Foo()",
|
||||
" A functional1();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @A.Foo()",
|
||||
" A functional2();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Foo()",
|
||||
" A functional3();",
|
||||
"",
|
||||
" @pkg.A.Foo(1)",
|
||||
" A simple1();",
|
||||
"",
|
||||
" @A.Foo(1)",
|
||||
" A simple2();",
|
||||
"",
|
||||
" @Foo(1)",
|
||||
" A simple3();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @pkg.A.Foo({1})",
|
||||
" A singleton1();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @A.Foo({1})",
|
||||
" A singleton2();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Foo({1})",
|
||||
" A singleton3();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @pkg.A.Foo(value = 1)",
|
||||
" A verbose1();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @A.Foo(value = 1)",
|
||||
" A verbose2();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Foo(value = 1)",
|
||||
" A verbose3();",
|
||||
"",
|
||||
" @pkg.A.Foo(value2 = 2)",
|
||||
" A custom1();",
|
||||
"",
|
||||
" @A.Foo(value2 = 2)",
|
||||
" A custom2();",
|
||||
"",
|
||||
" @Foo(value2 = 2)",
|
||||
" A custom3();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @pkg.A.Foo(value2 = {2})",
|
||||
" A customSingleton1();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @A.Foo(value2 = {2})",
|
||||
" A customSingleton2();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Foo(value2 = {2})",
|
||||
" A customSingleton3();",
|
||||
"",
|
||||
" @pkg.A.Foo(value2 = {2, 2})",
|
||||
" A customPair1();",
|
||||
"",
|
||||
" @A.Foo(value2 = {2, 2})",
|
||||
" A customPair2();",
|
||||
"",
|
||||
" @Foo(value2 = {2, 2})",
|
||||
" A customPair3();",
|
||||
"",
|
||||
" @pkg.A.Foo(value = 1, value2 = 2)",
|
||||
" A extended1();",
|
||||
"",
|
||||
" @A.Foo(value = 1, value2 = 2)",
|
||||
" A extended2();",
|
||||
"",
|
||||
" @Foo(value = 1, value2 = 2)",
|
||||
" A extended3();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @pkg.A.Foo({",
|
||||
" 1, 1,",
|
||||
" })",
|
||||
" A trailingComma1();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @A.Foo({",
|
||||
" 1, 1,",
|
||||
" })",
|
||||
" A trailingComma2();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Foo({",
|
||||
" 1, 1,",
|
||||
" })",
|
||||
" A trailingComma3();",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -143,143 +141,139 @@ final class CanonicalAnnotationSyntaxTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(CanonicalAnnotationSyntax.class, getClass())
|
||||
.addInputLines(
|
||||
"pkg/A.java",
|
||||
"""
|
||||
package pkg;
|
||||
|
||||
import pkg.A.Foo;
|
||||
|
||||
interface A {
|
||||
@interface Foo {
|
||||
String[] value() default {};
|
||||
|
||||
int[] value2() default {};
|
||||
}
|
||||
|
||||
@pkg.A.Foo()
|
||||
A functional1();
|
||||
|
||||
@A.Foo()
|
||||
A functional2();
|
||||
|
||||
@Foo()
|
||||
A functional3();
|
||||
|
||||
@pkg.A.Foo(value = "foo")
|
||||
A verbose1();
|
||||
|
||||
@A.Foo(value = "a'b")
|
||||
A verbose2();
|
||||
|
||||
@Foo(value = "a" + "\\nb")
|
||||
A verbose3();
|
||||
|
||||
@pkg.A.Foo(value = {"foo"})
|
||||
A moreVerbose1();
|
||||
|
||||
@A.Foo(value = {"a'b"})
|
||||
A moreVerbose2();
|
||||
|
||||
@Foo(value = {"a" + "\\nb"})
|
||||
A moreVerbose3();
|
||||
|
||||
@pkg.A.Foo(
|
||||
value = {"foo", "bar"},
|
||||
value2 = {2})
|
||||
A extended1();
|
||||
|
||||
@A.Foo(
|
||||
value = {"a'b", "c'd"},
|
||||
value2 = {2})
|
||||
A extended2();
|
||||
|
||||
@Foo(
|
||||
value = {"a" + "\\nb", "c" + "\\nd"},
|
||||
value2 = {2})
|
||||
A extended3();
|
||||
|
||||
@pkg.A.Foo({
|
||||
"foo", "bar",
|
||||
})
|
||||
A trailingComma1();
|
||||
|
||||
@A.Foo({
|
||||
"a'b", "c'd",
|
||||
})
|
||||
A trailingComma2();
|
||||
|
||||
@Foo({
|
||||
"a" + "\\nb",
|
||||
"c" + "\\nd",
|
||||
})
|
||||
A trailingComma3();
|
||||
}
|
||||
""")
|
||||
"package pkg;",
|
||||
"",
|
||||
"import pkg.A.Foo;",
|
||||
"",
|
||||
"interface A {",
|
||||
" @interface Foo {",
|
||||
" String[] value() default {};",
|
||||
"",
|
||||
" int[] value2() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @pkg.A.Foo()",
|
||||
" A functional1();",
|
||||
"",
|
||||
" @A.Foo()",
|
||||
" A functional2();",
|
||||
"",
|
||||
" @Foo()",
|
||||
" A functional3();",
|
||||
"",
|
||||
" @pkg.A.Foo(value = \"foo\")",
|
||||
" A verbose1();",
|
||||
"",
|
||||
" @A.Foo(value = \"a'b\")",
|
||||
" A verbose2();",
|
||||
"",
|
||||
" @Foo(value = \"a\" + \"\\nb\")",
|
||||
" A verbose3();",
|
||||
"",
|
||||
" @pkg.A.Foo(value = {\"foo\"})",
|
||||
" A moreVerbose1();",
|
||||
"",
|
||||
" @A.Foo(value = {\"a'b\"})",
|
||||
" A moreVerbose2();",
|
||||
"",
|
||||
" @Foo(value = {\"a\" + \"\\nb\"})",
|
||||
" A moreVerbose3();",
|
||||
"",
|
||||
" @pkg.A.Foo(",
|
||||
" value = {\"foo\", \"bar\"},",
|
||||
" value2 = {2})",
|
||||
" A extended1();",
|
||||
"",
|
||||
" @A.Foo(",
|
||||
" value = {\"a'b\", \"c'd\"},",
|
||||
" value2 = {2})",
|
||||
" A extended2();",
|
||||
"",
|
||||
" @Foo(",
|
||||
" value = {\"a\" + \"\\nb\", \"c\" + \"\\nd\"},",
|
||||
" value2 = {2})",
|
||||
" A extended3();",
|
||||
"",
|
||||
" @pkg.A.Foo({",
|
||||
" \"foo\", \"bar\",",
|
||||
" })",
|
||||
" A trailingComma1();",
|
||||
"",
|
||||
" @A.Foo({",
|
||||
" \"a'b\", \"c'd\",",
|
||||
" })",
|
||||
" A trailingComma2();",
|
||||
"",
|
||||
" @Foo({",
|
||||
" \"a\" + \"\\nb\",",
|
||||
" \"c\" + \"\\nd\",",
|
||||
" })",
|
||||
" A trailingComma3();",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"pkg/A.java",
|
||||
"""
|
||||
package pkg;
|
||||
|
||||
import pkg.A.Foo;
|
||||
|
||||
interface A {
|
||||
@interface Foo {
|
||||
String[] value() default {};
|
||||
|
||||
int[] value2() default {};
|
||||
}
|
||||
|
||||
@pkg.A.Foo
|
||||
A functional1();
|
||||
|
||||
@A.Foo
|
||||
A functional2();
|
||||
|
||||
@Foo
|
||||
A functional3();
|
||||
|
||||
@pkg.A.Foo("foo")
|
||||
A verbose1();
|
||||
|
||||
@A.Foo("a'b")
|
||||
A verbose2();
|
||||
|
||||
@Foo("a" + "\\nb")
|
||||
A verbose3();
|
||||
|
||||
@pkg.A.Foo("foo")
|
||||
A moreVerbose1();
|
||||
|
||||
@A.Foo("a'b")
|
||||
A moreVerbose2();
|
||||
|
||||
@Foo("a" + "\\nb")
|
||||
A moreVerbose3();
|
||||
|
||||
@pkg.A.Foo(
|
||||
value = {"foo", "bar"},
|
||||
value2 = 2)
|
||||
A extended1();
|
||||
|
||||
@A.Foo(
|
||||
value = {"a'b", "c'd"},
|
||||
value2 = 2)
|
||||
A extended2();
|
||||
|
||||
@Foo(
|
||||
value = {"a" + "\\nb", "c" + "\\nd"},
|
||||
value2 = 2)
|
||||
A extended3();
|
||||
|
||||
@pkg.A.Foo({"foo", "bar"})
|
||||
A trailingComma1();
|
||||
|
||||
@A.Foo({"a'b", "c'd"})
|
||||
A trailingComma2();
|
||||
|
||||
@Foo({"a" + "\\nb", "c" + "\\nd"})
|
||||
A trailingComma3();
|
||||
}
|
||||
""")
|
||||
"package pkg;",
|
||||
"",
|
||||
"import pkg.A.Foo;",
|
||||
"",
|
||||
"interface A {",
|
||||
" @interface Foo {",
|
||||
" String[] value() default {};",
|
||||
"",
|
||||
" int[] value2() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @pkg.A.Foo",
|
||||
" A functional1();",
|
||||
"",
|
||||
" @A.Foo",
|
||||
" A functional2();",
|
||||
"",
|
||||
" @Foo",
|
||||
" A functional3();",
|
||||
"",
|
||||
" @pkg.A.Foo(\"foo\")",
|
||||
" A verbose1();",
|
||||
"",
|
||||
" @A.Foo(\"a'b\")",
|
||||
" A verbose2();",
|
||||
"",
|
||||
" @Foo(\"a\" + \"\\nb\")",
|
||||
" A verbose3();",
|
||||
"",
|
||||
" @pkg.A.Foo(\"foo\")",
|
||||
" A moreVerbose1();",
|
||||
"",
|
||||
" @A.Foo(\"a'b\")",
|
||||
" A moreVerbose2();",
|
||||
"",
|
||||
" @Foo(\"a\" + \"\\nb\")",
|
||||
" A moreVerbose3();",
|
||||
"",
|
||||
" @pkg.A.Foo(",
|
||||
" value = {\"foo\", \"bar\"},",
|
||||
" value2 = 2)",
|
||||
" A extended1();",
|
||||
"",
|
||||
" @A.Foo(",
|
||||
" value = {\"a'b\", \"c'd\"},",
|
||||
" value2 = 2)",
|
||||
" A extended2();",
|
||||
"",
|
||||
" @Foo(",
|
||||
" value = {\"a\" + \"\\nb\", \"c\" + \"\\nd\"},",
|
||||
" value2 = 2)",
|
||||
" A extended3();",
|
||||
"",
|
||||
" @pkg.A.Foo({\"foo\", \"bar\"})",
|
||||
" A trailingComma1();",
|
||||
"",
|
||||
" @A.Foo({\"a'b\", \"c'd\"})",
|
||||
" A trailingComma2();",
|
||||
"",
|
||||
" @Foo({\"a\" + \"\\nb\", \"c\" + \"\\nd\"})",
|
||||
" A trailingComma3();",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,37 +14,35 @@ final class CanonicalClassNameUsageTest {
|
||||
"--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED")
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static com.google.errorprone.matchers.Matchers.instanceMethod;
|
||||
|
||||
import com.google.errorprone.VisitorState;
|
||||
import tech.picnic.errorprone.utils.MoreTypes;
|
||||
|
||||
class A {
|
||||
void m(VisitorState state) {
|
||||
String a = A.class.getName();
|
||||
String b = getClass().getName();
|
||||
A.class.getName().toString();
|
||||
System.out.println(A.class.getName());
|
||||
methodInUnnamedPackage(A.class.getName());
|
||||
instanceMethod().onExactClass(A.class.getCanonicalName());
|
||||
MoreTypes.type(A.class.getCanonicalName());
|
||||
MoreTypes.type(A.class.getCanonicalName() + ".SubType");
|
||||
instanceMethod().onExactClass(new Object() {}.getClass().getName());
|
||||
instanceMethod().onExactClass(methodInUnnamedPackage(A.class.getName()));
|
||||
// BUG: Diagnostic contains:
|
||||
instanceMethod().onExactClass(A.class.getName());
|
||||
// BUG: Diagnostic contains:
|
||||
MoreTypes.type(A.class.getName());
|
||||
// BUG: Diagnostic contains:
|
||||
state.binaryNameFromClassname(A.class.getName() + ".SubType");
|
||||
}
|
||||
|
||||
String methodInUnnamedPackage(String str) {
|
||||
return str;
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static com.google.errorprone.matchers.Matchers.instanceMethod;",
|
||||
"",
|
||||
"import com.google.errorprone.VisitorState;",
|
||||
"import tech.picnic.errorprone.utils.MoreTypes;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m(VisitorState state) {",
|
||||
" String a = A.class.getName();",
|
||||
" String b = getClass().getName();",
|
||||
" A.class.getName().toString();",
|
||||
" System.out.println(A.class.getName());",
|
||||
" methodInUnnamedPackage(A.class.getName());",
|
||||
" instanceMethod().onExactClass(A.class.getCanonicalName());",
|
||||
" MoreTypes.type(A.class.getCanonicalName());",
|
||||
" MoreTypes.type(A.class.getCanonicalName() + \".SubType\");",
|
||||
" instanceMethod().onExactClass(new Object() {}.getClass().getName());",
|
||||
" instanceMethod().onExactClass(methodInUnnamedPackage(A.class.getName()));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" instanceMethod().onExactClass(A.class.getName());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" MoreTypes.type(A.class.getName());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" state.binaryNameFromClassname(A.class.getName() + \".SubType\");",
|
||||
" }",
|
||||
"",
|
||||
" String methodInUnnamedPackage(String str) {",
|
||||
" return str;",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -53,36 +51,32 @@ final class CanonicalClassNameUsageTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(CanonicalClassNameUsage.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static com.google.errorprone.matchers.Matchers.instanceMethod;
|
||||
|
||||
import com.google.errorprone.BugPattern;
|
||||
import tech.picnic.errorprone.utils.MoreTypes;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
instanceMethod().onDescendantOfAny(A.class.getName(), BugPattern.LinkType.class.getName());
|
||||
MoreTypes.type(String.class.getName());
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static com.google.errorprone.matchers.Matchers.instanceMethod;",
|
||||
"",
|
||||
"import com.google.errorprone.BugPattern;",
|
||||
"import tech.picnic.errorprone.utils.MoreTypes;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" instanceMethod().onDescendantOfAny(A.class.getName(), BugPattern.LinkType.class.getName());",
|
||||
" MoreTypes.type(String.class.getName());",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static com.google.errorprone.matchers.Matchers.instanceMethod;
|
||||
|
||||
import com.google.errorprone.BugPattern;
|
||||
import tech.picnic.errorprone.utils.MoreTypes;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
instanceMethod()
|
||||
.onDescendantOfAny(
|
||||
A.class.getCanonicalName(), BugPattern.LinkType.class.getCanonicalName());
|
||||
MoreTypes.type(String.class.getCanonicalName());
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static com.google.errorprone.matchers.Matchers.instanceMethod;",
|
||||
"",
|
||||
"import com.google.errorprone.BugPattern;",
|
||||
"import tech.picnic.errorprone.utils.MoreTypes;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" instanceMethod()",
|
||||
" .onDescendantOfAny(",
|
||||
" A.class.getCanonicalName(), BugPattern.LinkType.class.getCanonicalName());",
|
||||
" MoreTypes.type(String.class.getCanonicalName());",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,39 +11,37 @@ final class ClassCastLambdaUsageTest {
|
||||
CompilationTestHelper.newInstance(ClassCastLambdaUsage.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
class A {
|
||||
<T> void m() {
|
||||
Number localVariable = 0;
|
||||
|
||||
Stream.of(0).map(i -> i);
|
||||
Stream.of(1).map(i -> i + 1);
|
||||
Stream.of(2).map(Integer.class::cast);
|
||||
Stream.of(3).map(i -> (Integer) 2);
|
||||
Stream.of(4).map(i -> (Integer) localVariable);
|
||||
// XXX: Ideally this case is also flagged. Pick this up in the context of merging the
|
||||
// `ClassCastLambdaUsage` and `MethodReferenceUsage` checks, or introduce a separate check that
|
||||
// simplifies unnecessary block lambda expressions.
|
||||
Stream.of(5)
|
||||
.map(
|
||||
i -> {
|
||||
return (Integer) i;
|
||||
});
|
||||
Stream.<ImmutableSet>of(ImmutableSet.of(6)).map(s -> (ImmutableSet<Number>) s);
|
||||
Stream.of(ImmutableSet.of(7)).map(s -> (ImmutableSet<?>) s);
|
||||
Stream.of(8).reduce((a, b) -> (Integer) a);
|
||||
IntStream.of(9).mapToObj(i -> (char) i);
|
||||
Stream.of(10).map(i -> (T) i);
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Stream.of(11).map(i -> (Integer) i);
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import java.util.stream.IntStream;",
|
||||
"import java.util.stream.Stream;",
|
||||
"",
|
||||
"class A {",
|
||||
" <T> void m() {",
|
||||
" Number localVariable = 0;",
|
||||
"",
|
||||
" Stream.of(0).map(i -> i);",
|
||||
" Stream.of(1).map(i -> i + 1);",
|
||||
" Stream.of(2).map(Integer.class::cast);",
|
||||
" Stream.of(3).map(i -> (Integer) 2);",
|
||||
" Stream.of(4).map(i -> (Integer) localVariable);",
|
||||
" // XXX: Ideally this case is also flagged. Pick this up in the context of merging the",
|
||||
" // `ClassCastLambdaUsage` and `MethodReferenceUsage` checks, or introduce a separate check that",
|
||||
" // simplifies unnecessary block lambda expressions.",
|
||||
" Stream.of(5)",
|
||||
" .map(",
|
||||
" i -> {",
|
||||
" return (Integer) i;",
|
||||
" });",
|
||||
" Stream.<ImmutableSet>of(ImmutableSet.of(6)).map(s -> (ImmutableSet<Number>) s);",
|
||||
" Stream.of(ImmutableSet.of(7)).map(s -> (ImmutableSet<?>) s);",
|
||||
" Stream.of(8).reduce((a, b) -> (Integer) a);",
|
||||
" IntStream.of(9).mapToObj(i -> (char) i);",
|
||||
" Stream.of(10).map(i -> (T) i);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Stream.of(11).map(i -> (Integer) i);",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -52,26 +50,22 @@ final class ClassCastLambdaUsageTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(ClassCastLambdaUsage.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import java.util.stream.Stream;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
Stream.of(1).map(i -> (Integer) i);
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import java.util.stream.Stream;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Stream.of(1).map(i -> (Integer) i);",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import java.util.stream.Stream;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
Stream.of(1).map(Integer.class::cast);
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import java.util.stream.Stream;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Stream.of(1).map(Integer.class::cast);",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,52 +13,50 @@ final class CollectorMutabilityTest {
|
||||
CompilationTestHelper.newInstance(CollectorMutability.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
import static com.google.common.collect.ImmutableMap.toImmutableMap;
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
import static java.util.stream.Collectors.toCollection;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
import static java.util.stream.Collectors.toSet;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1).collect(Collectors.toList());
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(2).collect(toList());
|
||||
Flux.just(3).collect(toImmutableList());
|
||||
Flux.just(4).collect(toCollection(ArrayList::new));
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just("foo").collect(Collectors.toMap(String::getBytes, String::length));
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just("bar").collect(toMap(String::getBytes, String::length));
|
||||
Flux.just("baz").collect(toImmutableMap(String::getBytes, String::length));
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just("qux").collect(toMap(String::getBytes, String::length, (a, b) -> a));
|
||||
Flux.just("quux").collect(toImmutableMap(String::getBytes, String::length, (a, b) -> a));
|
||||
Flux.just("quuz").collect(toMap(String::getBytes, String::length, (a, b) -> a, HashMap::new));
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Stream.of(1).collect(Collectors.toSet());
|
||||
// BUG: Diagnostic contains:
|
||||
Stream.of(2).collect(toSet());
|
||||
Stream.of(3).collect(toImmutableSet());
|
||||
Stream.of(4).collect(toCollection(HashSet::new));
|
||||
|
||||
Flux.just("foo").collect(Collectors.joining());
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static com.google.common.collect.ImmutableList.toImmutableList;",
|
||||
"import static com.google.common.collect.ImmutableMap.toImmutableMap;",
|
||||
"import static com.google.common.collect.ImmutableSet.toImmutableSet;",
|
||||
"import static java.util.stream.Collectors.toCollection;",
|
||||
"import static java.util.stream.Collectors.toList;",
|
||||
"import static java.util.stream.Collectors.toMap;",
|
||||
"import static java.util.stream.Collectors.toSet;",
|
||||
"",
|
||||
"import java.util.ArrayList;",
|
||||
"import java.util.HashMap;",
|
||||
"import java.util.HashSet;",
|
||||
"import java.util.stream.Collectors;",
|
||||
"import java.util.stream.Stream;",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).collect(Collectors.toList());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(2).collect(toList());",
|
||||
" Flux.just(3).collect(toImmutableList());",
|
||||
" Flux.just(4).collect(toCollection(ArrayList::new));",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(\"foo\").collect(Collectors.toMap(String::getBytes, String::length));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(\"bar\").collect(toMap(String::getBytes, String::length));",
|
||||
" Flux.just(\"baz\").collect(toImmutableMap(String::getBytes, String::length));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(\"qux\").collect(toMap(String::getBytes, String::length, (a, b) -> a));",
|
||||
" Flux.just(\"quux\").collect(toImmutableMap(String::getBytes, String::length, (a, b) -> a));",
|
||||
" Flux.just(\"quuz\").collect(toMap(String::getBytes, String::length, (a, b) -> a, HashMap::new));",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Stream.of(1).collect(Collectors.toSet());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Stream.of(2).collect(toSet());",
|
||||
" Stream.of(3).collect(toImmutableSet());",
|
||||
" Stream.of(4).collect(toCollection(HashSet::new));",
|
||||
"",
|
||||
" Flux.just(\"foo\").collect(Collectors.joining());",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -68,16 +66,14 @@ final class CollectorMutabilityTest {
|
||||
.withClasspath()
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
Stream.empty().collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import java.util.stream.Collectors;",
|
||||
"import java.util.stream.Stream;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Stream.empty().collect(Collectors.toList());",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -86,59 +82,55 @@ final class CollectorMutabilityTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(CollectorMutability.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
import static java.util.stream.Collectors.toSet;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
Flux.just(1).collect(Collectors.toList());
|
||||
Flux.just(2).collect(toList());
|
||||
|
||||
Stream.of("foo").collect(Collectors.toMap(String::getBytes, String::length));
|
||||
Stream.of("bar").collect(toMap(String::getBytes, String::length));
|
||||
Flux.just("baz").collect(Collectors.toMap(String::getBytes, String::length, (a, b) -> b));
|
||||
Flux.just("qux").collect(toMap(String::getBytes, String::length, (a, b) -> b));
|
||||
|
||||
Stream.of(1).collect(Collectors.toSet());
|
||||
Stream.of(2).collect(toSet());
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static java.util.stream.Collectors.toList;",
|
||||
"import static java.util.stream.Collectors.toMap;",
|
||||
"import static java.util.stream.Collectors.toSet;",
|
||||
"",
|
||||
"import java.util.stream.Collectors;",
|
||||
"import java.util.stream.Stream;",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Flux.just(1).collect(Collectors.toList());",
|
||||
" Flux.just(2).collect(toList());",
|
||||
"",
|
||||
" Stream.of(\"foo\").collect(Collectors.toMap(String::getBytes, String::length));",
|
||||
" Stream.of(\"bar\").collect(toMap(String::getBytes, String::length));",
|
||||
" Flux.just(\"baz\").collect(Collectors.toMap(String::getBytes, String::length, (a, b) -> b));",
|
||||
" Flux.just(\"qux\").collect(toMap(String::getBytes, String::length, (a, b) -> b));",
|
||||
"",
|
||||
" Stream.of(1).collect(Collectors.toSet());",
|
||||
" Stream.of(2).collect(toSet());",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
import static com.google.common.collect.ImmutableMap.toImmutableMap;
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
import static java.util.stream.Collectors.toSet;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
Flux.just(1).collect(toImmutableList());
|
||||
Flux.just(2).collect(toImmutableList());
|
||||
|
||||
Stream.of("foo").collect(toImmutableMap(String::getBytes, String::length));
|
||||
Stream.of("bar").collect(toImmutableMap(String::getBytes, String::length));
|
||||
Flux.just("baz").collect(toImmutableMap(String::getBytes, String::length, (a, b) -> b));
|
||||
Flux.just("qux").collect(toImmutableMap(String::getBytes, String::length, (a, b) -> b));
|
||||
|
||||
Stream.of(1).collect(toImmutableSet());
|
||||
Stream.of(2).collect(toImmutableSet());
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static com.google.common.collect.ImmutableList.toImmutableList;",
|
||||
"import static com.google.common.collect.ImmutableMap.toImmutableMap;",
|
||||
"import static com.google.common.collect.ImmutableSet.toImmutableSet;",
|
||||
"import static java.util.stream.Collectors.toList;",
|
||||
"import static java.util.stream.Collectors.toMap;",
|
||||
"import static java.util.stream.Collectors.toSet;",
|
||||
"",
|
||||
"import java.util.stream.Collectors;",
|
||||
"import java.util.stream.Stream;",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Flux.just(1).collect(toImmutableList());",
|
||||
" Flux.just(2).collect(toImmutableList());",
|
||||
"",
|
||||
" Stream.of(\"foo\").collect(toImmutableMap(String::getBytes, String::length));",
|
||||
" Stream.of(\"bar\").collect(toImmutableMap(String::getBytes, String::length));",
|
||||
" Flux.just(\"baz\").collect(toImmutableMap(String::getBytes, String::length, (a, b) -> b));",
|
||||
" Flux.just(\"qux\").collect(toImmutableMap(String::getBytes, String::length, (a, b) -> b));",
|
||||
"",
|
||||
" Stream.of(1).collect(toImmutableSet());",
|
||||
" Stream.of(2).collect(toImmutableSet());",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
|
||||
@@ -148,77 +140,73 @@ final class CollectorMutabilityTest {
|
||||
.setFixChooser(SECOND)
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
import static java.util.stream.Collectors.toSet;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
Flux.just(1).collect(Collectors.toList());
|
||||
Flux.just(2).collect(toList());
|
||||
|
||||
Stream.of("foo").collect(Collectors.toMap(String::getBytes, String::length));
|
||||
Stream.of("bar").collect(toMap(String::getBytes, String::length));
|
||||
Flux.just("baz").collect(Collectors.toMap(String::getBytes, String::length, (a, b) -> b));
|
||||
Flux.just("qux").collect(toMap(String::getBytes, String::length, (a, b) -> b));
|
||||
|
||||
Stream.of(1).collect(Collectors.toSet());
|
||||
Stream.of(2).collect(toSet());
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static java.util.stream.Collectors.toList;",
|
||||
"import static java.util.stream.Collectors.toMap;",
|
||||
"import static java.util.stream.Collectors.toSet;",
|
||||
"",
|
||||
"import java.util.stream.Collectors;",
|
||||
"import java.util.stream.Stream;",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Flux.just(1).collect(Collectors.toList());",
|
||||
" Flux.just(2).collect(toList());",
|
||||
"",
|
||||
" Stream.of(\"foo\").collect(Collectors.toMap(String::getBytes, String::length));",
|
||||
" Stream.of(\"bar\").collect(toMap(String::getBytes, String::length));",
|
||||
" Flux.just(\"baz\").collect(Collectors.toMap(String::getBytes, String::length, (a, b) -> b));",
|
||||
" Flux.just(\"qux\").collect(toMap(String::getBytes, String::length, (a, b) -> b));",
|
||||
"",
|
||||
" Stream.of(1).collect(Collectors.toSet());",
|
||||
" Stream.of(2).collect(toSet());",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static java.util.stream.Collectors.toCollection;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
import static java.util.stream.Collectors.toSet;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
Flux.just(1).collect(toCollection(ArrayList::new));
|
||||
Flux.just(2).collect(toCollection(ArrayList::new));
|
||||
|
||||
Stream.of("foo")
|
||||
.collect(
|
||||
Collectors.toMap(
|
||||
String::getBytes,
|
||||
String::length,
|
||||
(a, b) -> {
|
||||
throw new IllegalStateException();
|
||||
},
|
||||
HashMap::new));
|
||||
Stream.of("bar")
|
||||
.collect(
|
||||
toMap(
|
||||
String::getBytes,
|
||||
String::length,
|
||||
(a, b) -> {
|
||||
throw new IllegalStateException();
|
||||
},
|
||||
HashMap::new));
|
||||
Flux.just("baz")
|
||||
.collect(Collectors.toMap(String::getBytes, String::length, (a, b) -> b, HashMap::new));
|
||||
Flux.just("qux").collect(toMap(String::getBytes, String::length, (a, b) -> b, HashMap::new));
|
||||
|
||||
Stream.of(1).collect(toCollection(HashSet::new));
|
||||
Stream.of(2).collect(toCollection(HashSet::new));
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static java.util.stream.Collectors.toCollection;",
|
||||
"import static java.util.stream.Collectors.toList;",
|
||||
"import static java.util.stream.Collectors.toMap;",
|
||||
"import static java.util.stream.Collectors.toSet;",
|
||||
"",
|
||||
"import java.util.ArrayList;",
|
||||
"import java.util.HashMap;",
|
||||
"import java.util.HashSet;",
|
||||
"import java.util.stream.Collectors;",
|
||||
"import java.util.stream.Stream;",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Flux.just(1).collect(toCollection(ArrayList::new));",
|
||||
" Flux.just(2).collect(toCollection(ArrayList::new));",
|
||||
"",
|
||||
" Stream.of(\"foo\")",
|
||||
" .collect(",
|
||||
" Collectors.toMap(",
|
||||
" String::getBytes,",
|
||||
" String::length,",
|
||||
" (a, b) -> {",
|
||||
" throw new IllegalStateException();",
|
||||
" },",
|
||||
" HashMap::new));",
|
||||
" Stream.of(\"bar\")",
|
||||
" .collect(",
|
||||
" toMap(",
|
||||
" String::getBytes,",
|
||||
" String::length,",
|
||||
" (a, b) -> {",
|
||||
" throw new IllegalStateException();",
|
||||
" },",
|
||||
" HashMap::new));",
|
||||
" Flux.just(\"baz\")",
|
||||
" .collect(Collectors.toMap(String::getBytes, String::length, (a, b) -> b, HashMap::new));",
|
||||
" Flux.just(\"qux\").collect(toMap(String::getBytes, String::length, (a, b) -> b, HashMap::new));",
|
||||
"",
|
||||
" Stream.of(1).collect(toCollection(HashSet::new));",
|
||||
" Stream.of(2).collect(toCollection(HashSet::new));",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,32 +11,30 @@ final class ConstantNamingTest {
|
||||
CompilationTestHelper.newInstance(ConstantNaming.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
class A {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final int FOO = 1;
|
||||
// BUG: Diagnostic contains: consider renaming to 'BAR', though note that this is not a private
|
||||
// constant
|
||||
static final int bar = 2;
|
||||
// BUG: Diagnostic contains:
|
||||
private static final int baz = 3;
|
||||
// BUG: Diagnostic contains: consider renaming to 'QUX_QUUX', though note that a variable with
|
||||
// this name is already declared
|
||||
private static final int qux_QUUX = 4;
|
||||
// BUG: Diagnostic contains: consider renaming to 'QUUZ', though note that a variable with
|
||||
// this name is already declared
|
||||
private static final int quuz = 3;
|
||||
|
||||
private final int foo = 4;
|
||||
private final Runnable QUX_QUUX =
|
||||
new Runnable() {
|
||||
private static final int QUUZ = 1;
|
||||
|
||||
@Override
|
||||
public void run() {}
|
||||
};
|
||||
}
|
||||
""")
|
||||
"class A {",
|
||||
" private static final long serialVersionUID = 1L;",
|
||||
" private static final int FOO = 1;",
|
||||
" // BUG: Diagnostic contains: consider renaming to 'BAR', though note that this is not a private",
|
||||
" // constant",
|
||||
" static final int bar = 2;",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" private static final int baz = 3;",
|
||||
" // BUG: Diagnostic contains: consider renaming to 'QUX_QUUX', though note that a variable with",
|
||||
" // this name is already declared",
|
||||
" private static final int qux_QUUX = 4;",
|
||||
" // BUG: Diagnostic contains: consider renaming to 'QUUZ', though note that a variable with",
|
||||
" // this name is already declared",
|
||||
" private static final int quuz = 3;",
|
||||
"",
|
||||
" private final int foo = 4;",
|
||||
" private final Runnable QUX_QUUX =",
|
||||
" new Runnable() {",
|
||||
" private static final int QUUZ = 1;",
|
||||
"",
|
||||
" @Override",
|
||||
" public void run() {}",
|
||||
" };",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -46,15 +44,13 @@ final class ConstantNamingTest {
|
||||
.setArgs("-XepOpt:CanonicalConstantNaming:ExemptedNames=foo,baz")
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
class A {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final int foo = 1;
|
||||
// BUG: Diagnostic contains:
|
||||
private static final int bar = 2;
|
||||
private static final int baz = 3;
|
||||
}
|
||||
""")
|
||||
"class A {",
|
||||
" private static final long serialVersionUID = 1L;",
|
||||
" private static final int foo = 1;",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" private static final int bar = 2;",
|
||||
" private static final int baz = 3;",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -63,24 +59,20 @@ final class ConstantNamingTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(ConstantNaming.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
class A {
|
||||
static final int foo = 1;
|
||||
private static final int bar = 2;
|
||||
private static final int baz = 3;
|
||||
private static final int BAZ = 4;
|
||||
}
|
||||
""")
|
||||
"class A {",
|
||||
" static final int foo = 1;",
|
||||
" private static final int bar = 2;",
|
||||
" private static final int baz = 3;",
|
||||
" private static final int BAZ = 4;",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
class A {
|
||||
static final int foo = 1;
|
||||
private static final int BAR = 2;
|
||||
private static final int baz = 3;
|
||||
private static final int BAZ = 4;
|
||||
}
|
||||
""")
|
||||
"class A {",
|
||||
" static final int foo = 1;",
|
||||
" private static final int BAR = 2;",
|
||||
" private static final int baz = 3;",
|
||||
" private static final int BAZ = 4;",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,186 +11,184 @@ final class DirectReturnTest {
|
||||
CompilationTestHelper.newInstance(DirectReturn.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
class A {
|
||||
private String field;
|
||||
|
||||
void emptyMethod() {}
|
||||
|
||||
void voidMethod() {
|
||||
toString();
|
||||
return;
|
||||
}
|
||||
|
||||
String directReturnOfParam(String param) {
|
||||
return param;
|
||||
}
|
||||
|
||||
String assignmentToField() {
|
||||
field = toString();
|
||||
return field;
|
||||
}
|
||||
|
||||
Object redundantAssignmentToParam(String param) {
|
||||
// BUG: Diagnostic contains:
|
||||
param = toString();
|
||||
return param;
|
||||
}
|
||||
|
||||
String redundantMockAssignmentToParam(String param) {
|
||||
// BUG: Diagnostic contains:
|
||||
param = mock();
|
||||
return param;
|
||||
}
|
||||
|
||||
Object redundantMockWithExplicitTypeAssignmentToParam(String param) {
|
||||
// BUG: Diagnostic contains:
|
||||
param = mock(String.class);
|
||||
return param;
|
||||
}
|
||||
|
||||
Object salientMockAssignmentToParam(String param) {
|
||||
param = mock();
|
||||
return param;
|
||||
}
|
||||
|
||||
String redundantAssignmentToLocalVariable() {
|
||||
String variable = null;
|
||||
// BUG: Diagnostic contains:
|
||||
variable = toString();
|
||||
return variable;
|
||||
}
|
||||
|
||||
String unusedAssignmentToLocalVariable(String param) {
|
||||
String variable = null;
|
||||
variable = toString();
|
||||
return param;
|
||||
}
|
||||
|
||||
String redundantVariableDeclaration() {
|
||||
// BUG: Diagnostic contains:
|
||||
String variable = toString();
|
||||
return variable;
|
||||
}
|
||||
|
||||
String redundantSpyVariableDeclaration() {
|
||||
// BUG: Diagnostic contains:
|
||||
String variable = spy();
|
||||
return variable;
|
||||
}
|
||||
|
||||
Object redundantSpyWithExplicitTypeVariableDeclaration() {
|
||||
// BUG: Diagnostic contains:
|
||||
String variable = spy(String.class);
|
||||
return variable;
|
||||
}
|
||||
|
||||
Object salientSpyTypeVariableDeclaration() {
|
||||
String variable = spy("name");
|
||||
return variable;
|
||||
}
|
||||
|
||||
String unusedVariableDeclaration(String param) {
|
||||
String variable = toString();
|
||||
return param;
|
||||
}
|
||||
|
||||
String assignmentToAnnotatedVariable() {
|
||||
@SuppressWarnings("HereBeDragons")
|
||||
String variable = toString();
|
||||
return variable;
|
||||
}
|
||||
|
||||
String complexReturnStatement() {
|
||||
String variable = toString();
|
||||
return variable + toString();
|
||||
}
|
||||
|
||||
String assignmentInsideIfClause() {
|
||||
String variable = null;
|
||||
if (true) {
|
||||
variable = toString();
|
||||
}
|
||||
return variable;
|
||||
}
|
||||
|
||||
String redundantAssignmentInsideElseClause() {
|
||||
String variable = toString();
|
||||
if (true) {
|
||||
return variable;
|
||||
} else {
|
||||
// BUG: Diagnostic contains:
|
||||
variable = "foo";
|
||||
return variable;
|
||||
}
|
||||
}
|
||||
|
||||
Supplier<String> redundantAssignmentInsideLambda() {
|
||||
return () -> {
|
||||
// BUG: Diagnostic contains:
|
||||
String variable = toString();
|
||||
return variable;
|
||||
};
|
||||
}
|
||||
|
||||
String redundantAssignmentInsideTryBlock(AutoCloseable closeable) throws Exception {
|
||||
try (closeable) {
|
||||
// BUG: Diagnostic contains:
|
||||
String variable = toString();
|
||||
return variable;
|
||||
}
|
||||
}
|
||||
|
||||
String redundantAssignmentsInsideTryAndFinallyBlocks() {
|
||||
String variable = toString();
|
||||
try {
|
||||
// BUG: Diagnostic contains:
|
||||
variable = "foo";
|
||||
return variable;
|
||||
} finally {
|
||||
String variable2 = toString();
|
||||
if (true) {
|
||||
// BUG: Diagnostic contains:
|
||||
String variable3 = toString();
|
||||
return variable3;
|
||||
}
|
||||
return variable2;
|
||||
}
|
||||
}
|
||||
|
||||
String assignmentUsedInsideFinallyBlock() {
|
||||
String variable = toString();
|
||||
try {
|
||||
variable = "foo";
|
||||
return variable;
|
||||
} finally {
|
||||
String variable2 = toString();
|
||||
return variable + variable2;
|
||||
}
|
||||
}
|
||||
|
||||
String redundantAssignmentToVariableUsedInsideUnexecutedFinallyBlock(AutoCloseable closeable)
|
||||
throws Exception {
|
||||
String variable = toString();
|
||||
try (closeable) {
|
||||
if (true) {
|
||||
// BUG: Diagnostic contains:
|
||||
variable = "foo";
|
||||
return variable;
|
||||
}
|
||||
}
|
||||
try {
|
||||
} finally {
|
||||
return variable;
|
||||
}
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static org.mockito.Mockito.mock;",
|
||||
"import static org.mockito.Mockito.spy;",
|
||||
"",
|
||||
"import java.util.function.Supplier;",
|
||||
"",
|
||||
"class A {",
|
||||
" private String field;",
|
||||
"",
|
||||
" void emptyMethod() {}",
|
||||
"",
|
||||
" void voidMethod() {",
|
||||
" toString();",
|
||||
" return;",
|
||||
" }",
|
||||
"",
|
||||
" String directReturnOfParam(String param) {",
|
||||
" return param;",
|
||||
" }",
|
||||
"",
|
||||
" String assignmentToField() {",
|
||||
" field = toString();",
|
||||
" return field;",
|
||||
" }",
|
||||
"",
|
||||
" Object redundantAssignmentToParam(String param) {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" param = toString();",
|
||||
" return param;",
|
||||
" }",
|
||||
"",
|
||||
" String redundantMockAssignmentToParam(String param) {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" param = mock();",
|
||||
" return param;",
|
||||
" }",
|
||||
"",
|
||||
" Object redundantMockWithExplicitTypeAssignmentToParam(String param) {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" param = mock(String.class);",
|
||||
" return param;",
|
||||
" }",
|
||||
"",
|
||||
" Object salientMockAssignmentToParam(String param) {",
|
||||
" param = mock();",
|
||||
" return param;",
|
||||
" }",
|
||||
"",
|
||||
" String redundantAssignmentToLocalVariable() {",
|
||||
" String variable = null;",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" variable = toString();",
|
||||
" return variable;",
|
||||
" }",
|
||||
"",
|
||||
" String unusedAssignmentToLocalVariable(String param) {",
|
||||
" String variable = null;",
|
||||
" variable = toString();",
|
||||
" return param;",
|
||||
" }",
|
||||
"",
|
||||
" String redundantVariableDeclaration() {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String variable = toString();",
|
||||
" return variable;",
|
||||
" }",
|
||||
"",
|
||||
" String redundantSpyVariableDeclaration() {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String variable = spy();",
|
||||
" return variable;",
|
||||
" }",
|
||||
"",
|
||||
" Object redundantSpyWithExplicitTypeVariableDeclaration() {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String variable = spy(String.class);",
|
||||
" return variable;",
|
||||
" }",
|
||||
"",
|
||||
" Object salientSpyTypeVariableDeclaration() {",
|
||||
" String variable = spy(\"name\");",
|
||||
" return variable;",
|
||||
" }",
|
||||
"",
|
||||
" String unusedVariableDeclaration(String param) {",
|
||||
" String variable = toString();",
|
||||
" return param;",
|
||||
" }",
|
||||
"",
|
||||
" String assignmentToAnnotatedVariable() {",
|
||||
" @SuppressWarnings(\"HereBeDragons\")",
|
||||
" String variable = toString();",
|
||||
" return variable;",
|
||||
" }",
|
||||
"",
|
||||
" String complexReturnStatement() {",
|
||||
" String variable = toString();",
|
||||
" return variable + toString();",
|
||||
" }",
|
||||
"",
|
||||
" String assignmentInsideIfClause() {",
|
||||
" String variable = null;",
|
||||
" if (true) {",
|
||||
" variable = toString();",
|
||||
" }",
|
||||
" return variable;",
|
||||
" }",
|
||||
"",
|
||||
" String redundantAssignmentInsideElseClause() {",
|
||||
" String variable = toString();",
|
||||
" if (true) {",
|
||||
" return variable;",
|
||||
" } else {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" variable = \"foo\";",
|
||||
" return variable;",
|
||||
" }",
|
||||
" }",
|
||||
"",
|
||||
" Supplier<String> redundantAssignmentInsideLambda() {",
|
||||
" return () -> {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String variable = toString();",
|
||||
" return variable;",
|
||||
" };",
|
||||
" }",
|
||||
"",
|
||||
" String redundantAssignmentInsideTryBlock(AutoCloseable closeable) throws Exception {",
|
||||
" try (closeable) {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String variable = toString();",
|
||||
" return variable;",
|
||||
" }",
|
||||
" }",
|
||||
"",
|
||||
" String redundantAssignmentsInsideTryAndFinallyBlocks() {",
|
||||
" String variable = toString();",
|
||||
" try {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" variable = \"foo\";",
|
||||
" return variable;",
|
||||
" } finally {",
|
||||
" String variable2 = toString();",
|
||||
" if (true) {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String variable3 = toString();",
|
||||
" return variable3;",
|
||||
" }",
|
||||
" return variable2;",
|
||||
" }",
|
||||
" }",
|
||||
"",
|
||||
" String assignmentUsedInsideFinallyBlock() {",
|
||||
" String variable = toString();",
|
||||
" try {",
|
||||
" variable = \"foo\";",
|
||||
" return variable;",
|
||||
" } finally {",
|
||||
" String variable2 = toString();",
|
||||
" return variable + variable2;",
|
||||
" }",
|
||||
" }",
|
||||
"",
|
||||
" String redundantAssignmentToVariableUsedInsideUnexecutedFinallyBlock(AutoCloseable closeable)",
|
||||
" throws Exception {",
|
||||
" String variable = toString();",
|
||||
" try (closeable) {",
|
||||
" if (true) {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" variable = \"foo\";",
|
||||
" return variable;",
|
||||
" }",
|
||||
" }",
|
||||
" try {",
|
||||
" } finally {",
|
||||
" return variable;",
|
||||
" }",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -199,34 +197,30 @@ final class DirectReturnTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(DirectReturn.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
class A {
|
||||
String m1() {
|
||||
String variable = null;
|
||||
variable = toString();
|
||||
return variable;
|
||||
}
|
||||
|
||||
String m2() {
|
||||
String variable = toString();
|
||||
return variable;
|
||||
}
|
||||
}
|
||||
""")
|
||||
"class A {",
|
||||
" String m1() {",
|
||||
" String variable = null;",
|
||||
" variable = toString();",
|
||||
" return variable;",
|
||||
" }",
|
||||
"",
|
||||
" String m2() {",
|
||||
" String variable = toString();",
|
||||
" return variable;",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
class A {
|
||||
String m1() {
|
||||
String variable = null;
|
||||
return toString();
|
||||
}
|
||||
|
||||
String m2() {
|
||||
return toString();
|
||||
}
|
||||
}
|
||||
""")
|
||||
"class A {",
|
||||
" String m1() {",
|
||||
" String variable = null;",
|
||||
" return toString();",
|
||||
" }",
|
||||
"",
|
||||
" String m2() {",
|
||||
" return toString();",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,286 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -11,58 +11,54 @@ final class EmptyMethodTest {
|
||||
CompilationTestHelper.newInstance(EmptyMethod.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
class A {
|
||||
Object m1() {
|
||||
return null;
|
||||
}
|
||||
|
||||
void m2() {
|
||||
System.out.println(42);
|
||||
}
|
||||
|
||||
void m3() {}
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
static void m4() {}
|
||||
|
||||
interface F {
|
||||
void fun();
|
||||
}
|
||||
|
||||
final class MyTestClass {
|
||||
void helperMethod() {}
|
||||
}
|
||||
}
|
||||
""")
|
||||
"class A {",
|
||||
" Object m1() {",
|
||||
" return null;",
|
||||
" }",
|
||||
"",
|
||||
" void m2() {",
|
||||
" System.out.println(42);",
|
||||
" }",
|
||||
"",
|
||||
" void m3() {}",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" static void m4() {}",
|
||||
"",
|
||||
" interface F {",
|
||||
" void fun();",
|
||||
" }",
|
||||
"",
|
||||
" final class MyTestClass {",
|
||||
" void helperMethod() {}",
|
||||
" }",
|
||||
"}")
|
||||
.addSourceLines(
|
||||
"B.java",
|
||||
"""
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
|
||||
final class B implements A.F {
|
||||
@Override
|
||||
public void fun() {}
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
void m3() {}
|
||||
|
||||
/** Javadoc. */
|
||||
// BUG: Diagnostic contains:
|
||||
void m4() {}
|
||||
|
||||
void m5() {
|
||||
// Single-line comment.
|
||||
}
|
||||
|
||||
void m6() {
|
||||
/* Multi-line comment. */
|
||||
}
|
||||
|
||||
@Pointcut
|
||||
void m7() {}
|
||||
}
|
||||
""")
|
||||
"import org.aspectj.lang.annotation.Pointcut;",
|
||||
"",
|
||||
"final class B implements A.F {",
|
||||
" @Override",
|
||||
" public void fun() {}",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" void m3() {}",
|
||||
"",
|
||||
" /** Javadoc. */",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" void m4() {}",
|
||||
"",
|
||||
" void m5() {",
|
||||
" // Single-line comment.",
|
||||
" }",
|
||||
"",
|
||||
" void m6() {",
|
||||
" /* Multi-line comment. */",
|
||||
" }",
|
||||
"",
|
||||
" @Pointcut",
|
||||
" void m7() {}",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -71,26 +67,22 @@ final class EmptyMethodTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(EmptyMethod.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
final class A {
|
||||
void instanceMethod() {}
|
||||
|
||||
static void staticMethod() {}
|
||||
|
||||
static void staticMethodWithComment() {
|
||||
/* Foo. */
|
||||
}
|
||||
}
|
||||
""")
|
||||
"final class A {",
|
||||
" void instanceMethod() {}",
|
||||
"",
|
||||
" static void staticMethod() {}",
|
||||
"",
|
||||
" static void staticMethodWithComment() {",
|
||||
" /* Foo. */",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
final class A {
|
||||
static void staticMethodWithComment() {
|
||||
/* Foo. */
|
||||
}
|
||||
}
|
||||
""")
|
||||
"final class A {",
|
||||
" static void staticMethodWithComment() {",
|
||||
" /* Foo. */",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,64 +19,62 @@ final class EmptyMonoZipTest {
|
||||
"Invoking `Mono#zipWith` on `Mono#empty()` or a `Mono<Void>` is a no-op"))
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static reactor.core.publisher.Mono.zip;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
Flux.just(1).zip(Mono.empty(), Flux.just(2));
|
||||
|
||||
Mono<Void> voidMono = Mono.empty();
|
||||
Mono<Integer> integerMono = Mono.empty();
|
||||
|
||||
zip(Mono.just(1), Mono.just(2));
|
||||
Mono.zip(Mono.just(1), Mono.just(2));
|
||||
Mono.zip(Mono.just(1), Mono.just(2), Mono.just(3));
|
||||
Mono.zip(integerMono, integerMono);
|
||||
|
||||
// BUG: Diagnostic matches: ARGUMENT
|
||||
zip(Mono.empty(), Mono.empty());
|
||||
// BUG: Diagnostic matches: ARGUMENT
|
||||
Mono.zip(Mono.empty(), Mono.empty());
|
||||
// BUG: Diagnostic matches: ARGUMENT
|
||||
Mono.zip(voidMono, Mono.just(1));
|
||||
// BUG: Diagnostic matches: ARGUMENT
|
||||
Mono.zip(voidMono, voidMono);
|
||||
// BUG: Diagnostic matches: ARGUMENT
|
||||
Mono.zip(Mono.just(1).then(), Mono.just(2));
|
||||
// BUG: Diagnostic matches: ARGUMENT
|
||||
Mono.zip(Mono.just(1), Mono.just(2), voidMono);
|
||||
|
||||
Mono.just(1).zipWith(Mono.just(2));
|
||||
Mono.just(1).zipWith(integerMono);
|
||||
Mono.just(1).zipWith(integerMono, (a, b) -> a + b);
|
||||
|
||||
// BUG: Diagnostic matches: ARGUMENT
|
||||
Mono.just(1).zipWith(Mono.empty());
|
||||
// BUG: Diagnostic matches: ARGUMENT
|
||||
Mono.just(1).zipWith(voidMono);
|
||||
// BUG: Diagnostic matches: RECEIVER
|
||||
Mono.empty().zipWith(Mono.just(1));
|
||||
// BUG: Diagnostic matches: RECEIVER
|
||||
voidMono.zipWith(Mono.just(1));
|
||||
}
|
||||
|
||||
abstract class MyMono extends Mono<Object> {
|
||||
void m() {
|
||||
zip(Mono.just(1), Mono.just(2));
|
||||
// BUG: Diagnostic matches: ARGUMENT
|
||||
zip(Mono.empty(), Mono.empty());
|
||||
|
||||
zipWith(Mono.just(1));
|
||||
// BUG: Diagnostic matches: ARGUMENT
|
||||
zipWith(Mono.empty());
|
||||
}
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static reactor.core.publisher.Mono.zip;",
|
||||
"",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"import reactor.core.publisher.Mono;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Flux.just(1).zip(Mono.empty(), Flux.just(2));",
|
||||
"",
|
||||
" Mono<Void> voidMono = Mono.empty();",
|
||||
" Mono<Integer> integerMono = Mono.empty();",
|
||||
"",
|
||||
" zip(Mono.just(1), Mono.just(2));",
|
||||
" Mono.zip(Mono.just(1), Mono.just(2));",
|
||||
" Mono.zip(Mono.just(1), Mono.just(2), Mono.just(3));",
|
||||
" Mono.zip(integerMono, integerMono);",
|
||||
"",
|
||||
" // BUG: Diagnostic matches: ARGUMENT",
|
||||
" zip(Mono.empty(), Mono.empty());",
|
||||
" // BUG: Diagnostic matches: ARGUMENT",
|
||||
" Mono.zip(Mono.empty(), Mono.empty());",
|
||||
" // BUG: Diagnostic matches: ARGUMENT",
|
||||
" Mono.zip(voidMono, Mono.just(1));",
|
||||
" // BUG: Diagnostic matches: ARGUMENT",
|
||||
" Mono.zip(voidMono, voidMono);",
|
||||
" // BUG: Diagnostic matches: ARGUMENT",
|
||||
" Mono.zip(Mono.just(1).then(), Mono.just(2));",
|
||||
" // BUG: Diagnostic matches: ARGUMENT",
|
||||
" Mono.zip(Mono.just(1), Mono.just(2), voidMono);",
|
||||
"",
|
||||
" Mono.just(1).zipWith(Mono.just(2));",
|
||||
" Mono.just(1).zipWith(integerMono);",
|
||||
" Mono.just(1).zipWith(integerMono, (a, b) -> a + b);",
|
||||
"",
|
||||
" // BUG: Diagnostic matches: ARGUMENT",
|
||||
" Mono.just(1).zipWith(Mono.empty());",
|
||||
" // BUG: Diagnostic matches: ARGUMENT",
|
||||
" Mono.just(1).zipWith(voidMono);",
|
||||
" // BUG: Diagnostic matches: RECEIVER",
|
||||
" Mono.empty().zipWith(Mono.just(1));",
|
||||
" // BUG: Diagnostic matches: RECEIVER",
|
||||
" voidMono.zipWith(Mono.just(1));",
|
||||
" }",
|
||||
"",
|
||||
" abstract class MyMono extends Mono<Object> {",
|
||||
" void m() {",
|
||||
" zip(Mono.just(1), Mono.just(2));",
|
||||
" // BUG: Diagnostic matches: ARGUMENT",
|
||||
" zip(Mono.empty(), Mono.empty());",
|
||||
"",
|
||||
" zipWith(Mono.just(1));",
|
||||
" // BUG: Diagnostic matches: ARGUMENT",
|
||||
" zipWith(Mono.empty());",
|
||||
" }",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,80 +11,82 @@ final class ExplicitArgumentEnumerationTest {
|
||||
CompilationTestHelper.newInstance(ExplicitArgumentEnumeration.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
import org.jooq.impl.DSL;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
class A {
|
||||
// BUG: Diagnostic contains:
|
||||
private final int value = unaryMethod(ImmutableList.of(1, 2));
|
||||
|
||||
void m() {
|
||||
ImmutableList<String> list = ImmutableList.of();
|
||||
assertThat(ImmutableList.of()).containsAnyElementsOf(list);
|
||||
|
||||
ImmutableList.<ImmutableList<String>>builder().add(ImmutableList.of());
|
||||
|
||||
DSL.row(ImmutableList.of(1, 2));
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
unaryMethod(ImmutableList.of(1, 2));
|
||||
unaryMethodWithLessVisibleOverload(ImmutableList.of(1, 2));
|
||||
binaryMethod(ImmutableList.of(1, 2), 3);
|
||||
|
||||
ImmutableList.builder()
|
||||
// BUG: Diagnostic contains:
|
||||
.addAll(ImmutableList.of())
|
||||
// BUG: Diagnostic contains:
|
||||
.addAll(ImmutableList.copyOf(new String[0]))
|
||||
.addAll(ImmutableList.copyOf(ImmutableList.of()))
|
||||
.build();
|
||||
|
||||
assertThat(ImmutableList.of(1))
|
||||
// BUG: Diagnostic contains:
|
||||
.containsAnyElementsOf(ImmutableList.of(1))
|
||||
// BUG: Diagnostic contains:
|
||||
.isSubsetOf(ImmutableList.of(1));
|
||||
|
||||
Flux.just(1, 2)
|
||||
.as(StepVerifier::create)
|
||||
// BUG: Diagnostic contains:
|
||||
.expectNextSequence(ImmutableList.of(1, 2))
|
||||
.verifyComplete();
|
||||
|
||||
CompilationTestHelper.newInstance(BugChecker.class, getClass())
|
||||
// BUG: Diagnostic contains:
|
||||
.setArgs(ImmutableList.of("foo"))
|
||||
.withClasspath();
|
||||
}
|
||||
|
||||
private int unaryMethod(ImmutableList<Integer> args) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int unaryMethod(Integer... args) {
|
||||
return unaryMethod(ImmutableList.copyOf(args));
|
||||
}
|
||||
|
||||
void unaryMethodWithLessVisibleOverload(ImmutableList<Integer> args) {}
|
||||
|
||||
private void unaryMethodWithLessVisibleOverload(Integer... args) {
|
||||
unaryMethodWithLessVisibleOverload(ImmutableList.copyOf(args));
|
||||
}
|
||||
|
||||
private void binaryMethod(ImmutableList<Integer> args, int extraArg) {}
|
||||
|
||||
private void binaryMethod(Integer... args) {
|
||||
binaryMethod(ImmutableList.copyOf(args), 0);
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static org.assertj.core.api.Assertions.assertThat;",
|
||||
"",
|
||||
"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;",
|
||||
"",
|
||||
"class A {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" private final int value = unaryMethod(ImmutableList.of(1, 2));",
|
||||
"",
|
||||
" void m() {",
|
||||
" ImmutableList<String> list = ImmutableList.of();",
|
||||
" assertThat(ImmutableList.of()).containsAnyElementsOf(list);",
|
||||
"",
|
||||
" ImmutableList.<ImmutableList<String>>builder().add(ImmutableList.of());",
|
||||
"",
|
||||
" 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));",
|
||||
" binaryMethod(ImmutableList.of(1, 2), 3);",
|
||||
"",
|
||||
" ImmutableList.builder()",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" .addAll(ImmutableList.of())",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" .addAll(ImmutableList.copyOf(new String[0]))",
|
||||
" .addAll(ImmutableList.copyOf(ImmutableList.of()))",
|
||||
" .build();",
|
||||
"",
|
||||
" assertThat(ImmutableList.of(1))",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" .containsAnyElementsOf(ImmutableList.of(1))",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" .isSubsetOf(ImmutableList.of(1));",
|
||||
"",
|
||||
" Flux.just(1, 2)",
|
||||
" .as(StepVerifier::create)",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" .expectNextSequence(ImmutableList.of(1, 2))",
|
||||
" .verifyComplete();",
|
||||
"",
|
||||
" CompilationTestHelper.newInstance(BugChecker.class, getClass())",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" .setArgs(ImmutableList.of(\"foo\"))",
|
||||
" .withClasspath();",
|
||||
" }",
|
||||
"",
|
||||
" private int unaryMethod(ImmutableList<Integer> args) {",
|
||||
" return 0;",
|
||||
" }",
|
||||
"",
|
||||
" private int unaryMethod(Integer... args) {",
|
||||
" return unaryMethod(ImmutableList.copyOf(args));",
|
||||
" }",
|
||||
"",
|
||||
" void unaryMethodWithLessVisibleOverload(ImmutableList<Integer> args) {}",
|
||||
"",
|
||||
" private void unaryMethodWithLessVisibleOverload(Integer... args) {",
|
||||
" unaryMethodWithLessVisibleOverload(ImmutableList.copyOf(args));",
|
||||
" }",
|
||||
"",
|
||||
" private void binaryMethod(ImmutableList<Integer> args, int extraArg) {}",
|
||||
"",
|
||||
" private void binaryMethod(Integer... args) {",
|
||||
" binaryMethod(ImmutableList.copyOf(args), 0);",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -93,89 +95,85 @@ final class ExplicitArgumentEnumerationTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(ExplicitArgumentEnumeration.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMultiset;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
ImmutableList.builder().addAll(ImmutableList.of()).build();
|
||||
|
||||
assertThat(ImmutableList.of()).containsAnyElementsOf(ImmutableMultiset.of());
|
||||
assertThat(ImmutableList.of()).containsAll(ImmutableSet.of());
|
||||
assertThat(ImmutableList.of()).containsExactlyElementsOf(List.of());
|
||||
assertThat(ImmutableList.of()).containsExactlyInAnyOrderElementsOf(Set.of());
|
||||
assertThat(ImmutableList.of()).containsSequence(Arrays.asList());
|
||||
assertThat(ImmutableList.of()).containsSubsequence(ImmutableList.of(1));
|
||||
assertThat(ImmutableList.of()).doesNotContainAnyElementsOf(ImmutableMultiset.of(2));
|
||||
assertThat(ImmutableList.of()).doesNotContainSequence(ImmutableSet.of(3));
|
||||
assertThat(ImmutableList.of()).doesNotContainSubsequence(List.of(4));
|
||||
assertThat(ImmutableList.of()).hasSameElementsAs(Set.of(5));
|
||||
assertThat(ImmutableList.of()).isSubsetOf(Arrays.asList(6));
|
||||
|
||||
Flux.empty()
|
||||
.as(StepVerifier::create)
|
||||
.expectNextSequence(ImmutableList.of(1, 2))
|
||||
.verifyComplete();
|
||||
|
||||
BugCheckerRefactoringTestHelper.newInstance(BugChecker.class, getClass())
|
||||
.setArgs(ImmutableList.of("foo", "bar"));
|
||||
CompilationTestHelper.newInstance(BugChecker.class, getClass())
|
||||
.setArgs(ImmutableList.of("foo", "bar"));
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static org.assertj.core.api.Assertions.assertThat;",
|
||||
"",
|
||||
"import com.google.common.collect.ImmutableList;",
|
||||
"import com.google.common.collect.ImmutableMultiset;",
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import com.google.errorprone.BugCheckerRefactoringTestHelper;",
|
||||
"import com.google.errorprone.CompilationTestHelper;",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"import java.util.Arrays;",
|
||||
"import java.util.List;",
|
||||
"import java.util.Set;",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"import reactor.test.StepVerifier;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" ImmutableList.builder().addAll(ImmutableList.of()).build();",
|
||||
"",
|
||||
" assertThat(ImmutableList.of()).containsAnyElementsOf(ImmutableMultiset.of());",
|
||||
" assertThat(ImmutableList.of()).containsAll(ImmutableSet.of());",
|
||||
" assertThat(ImmutableList.of()).containsExactlyElementsOf(List.of());",
|
||||
" assertThat(ImmutableList.of()).containsExactlyInAnyOrderElementsOf(Set.of());",
|
||||
" assertThat(ImmutableList.of()).containsSequence(Arrays.asList());",
|
||||
" assertThat(ImmutableList.of()).containsSubsequence(ImmutableList.of(1));",
|
||||
" assertThat(ImmutableList.of()).doesNotContainAnyElementsOf(ImmutableMultiset.of(2));",
|
||||
" assertThat(ImmutableList.of()).doesNotContainSequence(ImmutableSet.of(3));",
|
||||
" assertThat(ImmutableList.of()).doesNotContainSubsequence(List.of(4));",
|
||||
" assertThat(ImmutableList.of()).hasSameElementsAs(Set.of(5));",
|
||||
" assertThat(ImmutableList.of()).isSubsetOf(Arrays.asList(6));",
|
||||
"",
|
||||
" Flux.empty()",
|
||||
" .as(StepVerifier::create)",
|
||||
" .expectNextSequence(ImmutableList.of(1, 2))",
|
||||
" .verifyComplete();",
|
||||
"",
|
||||
" BugCheckerRefactoringTestHelper.newInstance(BugChecker.class, getClass())",
|
||||
" .setArgs(ImmutableList.of(\"foo\", \"bar\"));",
|
||||
" CompilationTestHelper.newInstance(BugChecker.class, getClass())",
|
||||
" .setArgs(ImmutableList.of(\"foo\", \"bar\"));",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMultiset;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
import com.google.errorprone.CompilationTestHelper;
|
||||
import com.google.errorprone.bugpatterns.BugChecker;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
ImmutableList.builder().add().build();
|
||||
|
||||
assertThat(ImmutableList.of()).containsAnyOf();
|
||||
assertThat(ImmutableList.of()).contains();
|
||||
assertThat(ImmutableList.of()).containsExactly();
|
||||
assertThat(ImmutableList.of()).containsExactlyInAnyOrder();
|
||||
assertThat(ImmutableList.of()).containsSequence();
|
||||
assertThat(ImmutableList.of()).containsSubsequence(1);
|
||||
assertThat(ImmutableList.of()).doesNotContain(2);
|
||||
assertThat(ImmutableList.of()).doesNotContainSequence(3);
|
||||
assertThat(ImmutableList.of()).doesNotContainSubsequence(4);
|
||||
assertThat(ImmutableList.of()).containsOnly(5);
|
||||
assertThat(ImmutableList.of()).isSubsetOf(6);
|
||||
|
||||
Flux.empty().as(StepVerifier::create).expectNext(1, 2).verifyComplete();
|
||||
|
||||
BugCheckerRefactoringTestHelper.newInstance(BugChecker.class, getClass()).setArgs("foo", "bar");
|
||||
CompilationTestHelper.newInstance(BugChecker.class, getClass()).setArgs("foo", "bar");
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static org.assertj.core.api.Assertions.assertThat;",
|
||||
"",
|
||||
"import com.google.common.collect.ImmutableList;",
|
||||
"import com.google.common.collect.ImmutableMultiset;",
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import com.google.errorprone.BugCheckerRefactoringTestHelper;",
|
||||
"import com.google.errorprone.CompilationTestHelper;",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"import java.util.Arrays;",
|
||||
"import java.util.List;",
|
||||
"import java.util.Set;",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"import reactor.test.StepVerifier;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" ImmutableList.builder().add().build();",
|
||||
"",
|
||||
" assertThat(ImmutableList.of()).containsAnyOf();",
|
||||
" assertThat(ImmutableList.of()).contains();",
|
||||
" assertThat(ImmutableList.of()).containsExactly();",
|
||||
" assertThat(ImmutableList.of()).containsExactlyInAnyOrder();",
|
||||
" assertThat(ImmutableList.of()).containsSequence();",
|
||||
" assertThat(ImmutableList.of()).containsSubsequence(1);",
|
||||
" assertThat(ImmutableList.of()).doesNotContain(2);",
|
||||
" assertThat(ImmutableList.of()).doesNotContainSequence(3);",
|
||||
" assertThat(ImmutableList.of()).doesNotContainSubsequence(4);",
|
||||
" assertThat(ImmutableList.of()).containsOnly(5);",
|
||||
" assertThat(ImmutableList.of()).isSubsetOf(6);",
|
||||
"",
|
||||
" Flux.empty().as(StepVerifier::create).expectNext(1, 2).verifyComplete();",
|
||||
"",
|
||||
" BugCheckerRefactoringTestHelper.newInstance(BugChecker.class, getClass()).setArgs(\"foo\", \"bar\");",
|
||||
" CompilationTestHelper.newInstance(BugChecker.class, getClass()).setArgs(\"foo\", \"bar\");",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,78 +9,76 @@ final class ExplicitEnumOrderingTest {
|
||||
CompilationTestHelper.newInstance(ExplicitEnumOrdering.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static java.lang.annotation.RetentionPolicy.CLASS;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
import static java.lang.annotation.RetentionPolicy.SOURCE;
|
||||
import static java.time.chrono.IsoEra.BCE;
|
||||
import static java.time.chrono.IsoEra.CE;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Ordering;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.time.chrono.IsoEra;
|
||||
|
||||
class A {
|
||||
{
|
||||
// The `List`-accepting overload is currently ignored.
|
||||
Ordering.explicit(ImmutableList.of(RetentionPolicy.SOURCE, RetentionPolicy.CLASS));
|
||||
|
||||
Ordering.explicit(IsoEra.BCE, IsoEra.CE);
|
||||
// BUG: Diagnostic contains: IsoEra.CE
|
||||
Ordering.explicit(IsoEra.BCE);
|
||||
// BUG: Diagnostic contains: IsoEra.BCE
|
||||
Ordering.explicit(IsoEra.CE);
|
||||
|
||||
Ordering.explicit(RetentionPolicy.SOURCE, RetentionPolicy.CLASS, RetentionPolicy.RUNTIME);
|
||||
// BUG: Diagnostic contains: RetentionPolicy.CLASS, RetentionPolicy.RUNTIME
|
||||
Ordering.explicit(RetentionPolicy.SOURCE);
|
||||
// BUG: Diagnostic contains: RetentionPolicy.SOURCE, RetentionPolicy.RUNTIME
|
||||
Ordering.explicit(RetentionPolicy.CLASS);
|
||||
// BUG: Diagnostic contains: RetentionPolicy.SOURCE, RetentionPolicy.CLASS
|
||||
Ordering.explicit(RetentionPolicy.RUNTIME);
|
||||
// BUG: Diagnostic contains: RetentionPolicy.RUNTIME
|
||||
Ordering.explicit(RetentionPolicy.SOURCE, RetentionPolicy.CLASS);
|
||||
// BUG: Diagnostic contains: RetentionPolicy.CLASS
|
||||
Ordering.explicit(RetentionPolicy.SOURCE, RetentionPolicy.RUNTIME);
|
||||
// BUG: Diagnostic contains: RetentionPolicy.SOURCE
|
||||
Ordering.explicit(RetentionPolicy.CLASS, RetentionPolicy.RUNTIME);
|
||||
|
||||
Ordering.explicit(BCE, CE);
|
||||
// BUG: Diagnostic contains: IsoEra.CE
|
||||
Ordering.explicit(BCE);
|
||||
// BUG: Diagnostic contains: IsoEra.BCE
|
||||
Ordering.explicit(CE);
|
||||
|
||||
Ordering.explicit(SOURCE, CLASS, RUNTIME);
|
||||
// BUG: Diagnostic contains: RetentionPolicy.CLASS, RetentionPolicy.RUNTIME
|
||||
Ordering.explicit(SOURCE);
|
||||
// BUG: Diagnostic contains: RetentionPolicy.SOURCE, RetentionPolicy.RUNTIME
|
||||
Ordering.explicit(CLASS);
|
||||
// BUG: Diagnostic contains: RetentionPolicy.SOURCE, RetentionPolicy.CLASS
|
||||
Ordering.explicit(RUNTIME);
|
||||
// BUG: Diagnostic contains: RetentionPolicy.RUNTIME
|
||||
Ordering.explicit(SOURCE, CLASS);
|
||||
// BUG: Diagnostic contains: RetentionPolicy.CLASS
|
||||
Ordering.explicit(SOURCE, RUNTIME);
|
||||
// BUG: Diagnostic contains: RetentionPolicy.SOURCE
|
||||
Ordering.explicit(CLASS, RUNTIME);
|
||||
|
||||
Ordering.explicit(RetentionPolicy.SOURCE, BCE, RetentionPolicy.CLASS, CE, RUNTIME);
|
||||
Ordering.explicit(SOURCE, IsoEra.BCE, CLASS, IsoEra.CE, RetentionPolicy.RUNTIME);
|
||||
// BUG: Diagnostic contains: RetentionPolicy.CLASS
|
||||
Ordering.explicit(RetentionPolicy.SOURCE, BCE, CE, RUNTIME);
|
||||
// BUG: Diagnostic contains: RetentionPolicy.CLASS
|
||||
Ordering.explicit(IsoEra.BCE, SOURCE, IsoEra.CE, RetentionPolicy.RUNTIME);
|
||||
// BUG: Diagnostic contains: IsoEra.CE, RetentionPolicy.RUNTIME
|
||||
Ordering.explicit(IsoEra.BCE, SOURCE, RetentionPolicy.CLASS);
|
||||
// BUG: Diagnostic contains: RetentionPolicy.SOURCE, IsoEra.BCE
|
||||
Ordering.explicit(CLASS, RUNTIME, CE);
|
||||
|
||||
Ordering.explicit(BCE, null, CE);
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static java.lang.annotation.RetentionPolicy.CLASS;",
|
||||
"import static java.lang.annotation.RetentionPolicy.RUNTIME;",
|
||||
"import static java.lang.annotation.RetentionPolicy.SOURCE;",
|
||||
"import static java.time.chrono.IsoEra.BCE;",
|
||||
"import static java.time.chrono.IsoEra.CE;",
|
||||
"",
|
||||
"import com.google.common.collect.ImmutableList;",
|
||||
"import com.google.common.collect.Ordering;",
|
||||
"import java.lang.annotation.RetentionPolicy;",
|
||||
"import java.time.chrono.IsoEra;",
|
||||
"",
|
||||
"class A {",
|
||||
" {",
|
||||
" // The `List`-accepting overload is currently ignored.",
|
||||
" Ordering.explicit(ImmutableList.of(RetentionPolicy.SOURCE, RetentionPolicy.CLASS));",
|
||||
"",
|
||||
" Ordering.explicit(IsoEra.BCE, IsoEra.CE);",
|
||||
" // BUG: Diagnostic contains: IsoEra.CE",
|
||||
" Ordering.explicit(IsoEra.BCE);",
|
||||
" // BUG: Diagnostic contains: IsoEra.BCE",
|
||||
" Ordering.explicit(IsoEra.CE);",
|
||||
"",
|
||||
" Ordering.explicit(RetentionPolicy.SOURCE, RetentionPolicy.CLASS, RetentionPolicy.RUNTIME);",
|
||||
" // BUG: Diagnostic contains: RetentionPolicy.CLASS, RetentionPolicy.RUNTIME",
|
||||
" Ordering.explicit(RetentionPolicy.SOURCE);",
|
||||
" // BUG: Diagnostic contains: RetentionPolicy.SOURCE, RetentionPolicy.RUNTIME",
|
||||
" Ordering.explicit(RetentionPolicy.CLASS);",
|
||||
" // BUG: Diagnostic contains: RetentionPolicy.SOURCE, RetentionPolicy.CLASS",
|
||||
" Ordering.explicit(RetentionPolicy.RUNTIME);",
|
||||
" // BUG: Diagnostic contains: RetentionPolicy.RUNTIME",
|
||||
" Ordering.explicit(RetentionPolicy.SOURCE, RetentionPolicy.CLASS);",
|
||||
" // BUG: Diagnostic contains: RetentionPolicy.CLASS",
|
||||
" Ordering.explicit(RetentionPolicy.SOURCE, RetentionPolicy.RUNTIME);",
|
||||
" // BUG: Diagnostic contains: RetentionPolicy.SOURCE",
|
||||
" Ordering.explicit(RetentionPolicy.CLASS, RetentionPolicy.RUNTIME);",
|
||||
"",
|
||||
" Ordering.explicit(BCE, CE);",
|
||||
" // BUG: Diagnostic contains: IsoEra.CE",
|
||||
" Ordering.explicit(BCE);",
|
||||
" // BUG: Diagnostic contains: IsoEra.BCE",
|
||||
" Ordering.explicit(CE);",
|
||||
"",
|
||||
" Ordering.explicit(SOURCE, CLASS, RUNTIME);",
|
||||
" // BUG: Diagnostic contains: RetentionPolicy.CLASS, RetentionPolicy.RUNTIME",
|
||||
" Ordering.explicit(SOURCE);",
|
||||
" // BUG: Diagnostic contains: RetentionPolicy.SOURCE, RetentionPolicy.RUNTIME",
|
||||
" Ordering.explicit(CLASS);",
|
||||
" // BUG: Diagnostic contains: RetentionPolicy.SOURCE, RetentionPolicy.CLASS",
|
||||
" Ordering.explicit(RUNTIME);",
|
||||
" // BUG: Diagnostic contains: RetentionPolicy.RUNTIME",
|
||||
" Ordering.explicit(SOURCE, CLASS);",
|
||||
" // BUG: Diagnostic contains: RetentionPolicy.CLASS",
|
||||
" Ordering.explicit(SOURCE, RUNTIME);",
|
||||
" // BUG: Diagnostic contains: RetentionPolicy.SOURCE",
|
||||
" Ordering.explicit(CLASS, RUNTIME);",
|
||||
"",
|
||||
" Ordering.explicit(RetentionPolicy.SOURCE, BCE, RetentionPolicy.CLASS, CE, RUNTIME);",
|
||||
" Ordering.explicit(SOURCE, IsoEra.BCE, CLASS, IsoEra.CE, RetentionPolicy.RUNTIME);",
|
||||
" // BUG: Diagnostic contains: RetentionPolicy.CLASS",
|
||||
" Ordering.explicit(RetentionPolicy.SOURCE, BCE, CE, RUNTIME);",
|
||||
" // BUG: Diagnostic contains: RetentionPolicy.CLASS",
|
||||
" Ordering.explicit(IsoEra.BCE, SOURCE, IsoEra.CE, RetentionPolicy.RUNTIME);",
|
||||
" // BUG: Diagnostic contains: IsoEra.CE, RetentionPolicy.RUNTIME",
|
||||
" Ordering.explicit(IsoEra.BCE, SOURCE, RetentionPolicy.CLASS);",
|
||||
" // BUG: Diagnostic contains: RetentionPolicy.SOURCE, IsoEra.BCE",
|
||||
" Ordering.explicit(CLASS, RUNTIME, CE);",
|
||||
"",
|
||||
" Ordering.explicit(BCE, null, CE);",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,57 +12,55 @@ final class FluxFlatMapUsageTest {
|
||||
CompilationTestHelper.newInstance(FluxFlatMapUsage.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1).flatMap(Flux::just);
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1).<String>flatMap(i -> Flux.just(String.valueOf(i)));
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1).flatMapSequential(Flux::just);
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1).<String>flatMapSequential(i -> Flux.just(String.valueOf(i)));
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1, 2).groupBy(i -> i).flatMap(Flux::just);
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1, 2).groupBy(i -> i).<String>flatMap(i -> Flux.just(String.valueOf(i)));
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1, 2).groupBy(i -> i).flatMapSequential(Flux::just);
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1, 2).groupBy(i -> i).<String>flatMapSequential(i -> Flux.just(String.valueOf(i)));
|
||||
|
||||
Mono.just(1).flatMap(Mono::just);
|
||||
Flux.just(1).concatMap(Flux::just);
|
||||
|
||||
Flux.just(1).flatMap(Flux::just, 1);
|
||||
Flux.just(1).flatMap(Flux::just, 1, 1);
|
||||
Flux.just(1).flatMap(Flux::just, throwable -> Flux.empty(), Flux::empty);
|
||||
|
||||
Flux.just(1).flatMapSequential(Flux::just, 1);
|
||||
Flux.just(1).flatMapSequential(Flux::just, 1, 1);
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
this.<String, Flux<String>>sink(Flux::flatMap);
|
||||
// BUG: Diagnostic contains:
|
||||
this.<Integer, Flux<Integer>>sink(Flux::<Integer>flatMap);
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
this.<String, Flux<String>>sink(Flux::flatMapSequential);
|
||||
// BUG: Diagnostic contains:
|
||||
this.<Integer, Flux<Integer>>sink(Flux::<Integer>flatMapSequential);
|
||||
|
||||
this.<String, Mono<String>>sink(Mono::flatMap);
|
||||
}
|
||||
|
||||
private <T, P> void sink(BiFunction<P, Function<T, P>, P> fun) {}
|
||||
}
|
||||
""")
|
||||
"import java.util.function.BiFunction;",
|
||||
"import java.util.function.Function;",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"import reactor.core.publisher.Mono;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).flatMap(Flux::just);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).<String>flatMap(i -> Flux.just(String.valueOf(i)));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).flatMapSequential(Flux::just);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).<String>flatMapSequential(i -> Flux.just(String.valueOf(i)));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1, 2).groupBy(i -> i).flatMap(Flux::just);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1, 2).groupBy(i -> i).<String>flatMap(i -> Flux.just(String.valueOf(i)));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1, 2).groupBy(i -> i).flatMapSequential(Flux::just);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1, 2).groupBy(i -> i).<String>flatMapSequential(i -> Flux.just(String.valueOf(i)));",
|
||||
"",
|
||||
" Mono.just(1).flatMap(Mono::just);",
|
||||
" Flux.just(1).concatMap(Flux::just);",
|
||||
"",
|
||||
" Flux.just(1).flatMap(Flux::just, 1);",
|
||||
" Flux.just(1).flatMap(Flux::just, 1, 1);",
|
||||
" Flux.just(1).flatMap(Flux::just, throwable -> Flux.empty(), Flux::empty);",
|
||||
"",
|
||||
" Flux.just(1).flatMapSequential(Flux::just, 1);",
|
||||
" Flux.just(1).flatMapSequential(Flux::just, 1, 1);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" this.<String, Flux<String>>sink(Flux::flatMap);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" this.<Integer, Flux<Integer>>sink(Flux::<Integer>flatMap);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" this.<String, Flux<String>>sink(Flux::flatMapSequential);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" this.<Integer, Flux<Integer>>sink(Flux::<Integer>flatMapSequential);",
|
||||
"",
|
||||
" this.<String, Mono<String>>sink(Mono::flatMap);",
|
||||
" }",
|
||||
"",
|
||||
" private <T, P> void sink(BiFunction<P, Function<T, P>, P> fun) {}",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -71,36 +69,32 @@ final class FluxFlatMapUsageTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(FluxFlatMapUsage.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
class A {
|
||||
private static final int MAX_CONCURRENCY = 8;
|
||||
|
||||
void m() {
|
||||
Flux.just(1).flatMap(Flux::just);
|
||||
Flux.just(1).flatMapSequential(Flux::just);
|
||||
Flux.just(1, 2).groupBy(i -> i).flatMap(Flux::just);
|
||||
Flux.just(1, 2).groupBy(i -> i).flatMapSequential(Flux::just);
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"",
|
||||
"class A {",
|
||||
" private static final int MAX_CONCURRENCY = 8;",
|
||||
"",
|
||||
" void m() {",
|
||||
" Flux.just(1).flatMap(Flux::just);",
|
||||
" Flux.just(1).flatMapSequential(Flux::just);",
|
||||
" Flux.just(1, 2).groupBy(i -> i).flatMap(Flux::just);",
|
||||
" Flux.just(1, 2).groupBy(i -> i).flatMapSequential(Flux::just);",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
class A {
|
||||
private static final int MAX_CONCURRENCY = 8;
|
||||
|
||||
void m() {
|
||||
Flux.just(1).concatMap(Flux::just);
|
||||
Flux.just(1).concatMap(Flux::just);
|
||||
Flux.just(1, 2).groupBy(i -> i).flatMap(Flux::just, MAX_CONCURRENCY);
|
||||
Flux.just(1, 2).groupBy(i -> i).flatMapSequential(Flux::just, MAX_CONCURRENCY);
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"",
|
||||
"class A {",
|
||||
" private static final int MAX_CONCURRENCY = 8;",
|
||||
"",
|
||||
" void m() {",
|
||||
" Flux.just(1).concatMap(Flux::just);",
|
||||
" Flux.just(1).concatMap(Flux::just);",
|
||||
" Flux.just(1, 2).groupBy(i -> i).flatMap(Flux::just, MAX_CONCURRENCY);",
|
||||
" Flux.just(1, 2).groupBy(i -> i).flatMapSequential(Flux::just, MAX_CONCURRENCY);",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
|
||||
@@ -110,36 +104,32 @@ final class FluxFlatMapUsageTest {
|
||||
.setFixChooser(FixChoosers.SECOND)
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
class A {
|
||||
private static final int MAX_CONCURRENCY = 8;
|
||||
|
||||
void m() {
|
||||
Flux.just(1).flatMap(Flux::just);
|
||||
Flux.just(1).flatMapSequential(Flux::just);
|
||||
Flux.just(1, 2).groupBy(i -> i).flatMap(Flux::just);
|
||||
Flux.just(1, 2).groupBy(i -> i).flatMapSequential(Flux::just);
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"",
|
||||
"class A {",
|
||||
" private static final int MAX_CONCURRENCY = 8;",
|
||||
"",
|
||||
" void m() {",
|
||||
" Flux.just(1).flatMap(Flux::just);",
|
||||
" Flux.just(1).flatMapSequential(Flux::just);",
|
||||
" Flux.just(1, 2).groupBy(i -> i).flatMap(Flux::just);",
|
||||
" Flux.just(1, 2).groupBy(i -> i).flatMapSequential(Flux::just);",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
class A {
|
||||
private static final int MAX_CONCURRENCY = 8;
|
||||
|
||||
void m() {
|
||||
Flux.just(1).flatMap(Flux::just, MAX_CONCURRENCY);
|
||||
Flux.just(1).flatMapSequential(Flux::just, MAX_CONCURRENCY);
|
||||
Flux.just(1, 2).groupBy(i -> i).concatMap(Flux::just);
|
||||
Flux.just(1, 2).groupBy(i -> i).concatMap(Flux::just);
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"",
|
||||
"class A {",
|
||||
" private static final int MAX_CONCURRENCY = 8;",
|
||||
"",
|
||||
" void m() {",
|
||||
" Flux.just(1).flatMap(Flux::just, MAX_CONCURRENCY);",
|
||||
" Flux.just(1).flatMapSequential(Flux::just, MAX_CONCURRENCY);",
|
||||
" Flux.just(1, 2).groupBy(i -> i).concatMap(Flux::just);",
|
||||
" Flux.just(1, 2).groupBy(i -> i).concatMap(Flux::just);",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,38 +21,36 @@ final class FluxImplicitBlockTest {
|
||||
m -> Stream.of("SuppressWarnings", "toImmutableList", "toList").allMatch(m::contains))
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.util.stream.Stream;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
// BUG: Diagnostic matches: X
|
||||
Flux.just(1).toIterable();
|
||||
// BUG: Diagnostic matches: X
|
||||
Flux.just(2).toStream();
|
||||
// BUG: Diagnostic matches: X
|
||||
long count = Flux.just(3).toStream().count();
|
||||
|
||||
Flux.just(4).toIterable(1);
|
||||
Flux.just(5).toIterable(2, null);
|
||||
Flux.just(6).toStream(3);
|
||||
new Foo().toIterable();
|
||||
new Foo().toStream();
|
||||
}
|
||||
|
||||
class Foo<T> {
|
||||
Iterable<T> toIterable() {
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
Stream<T> toStream() {
|
||||
return Stream.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import com.google.common.collect.ImmutableList;",
|
||||
"import java.util.stream.Stream;",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" Flux.just(1).toIterable();",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" Flux.just(2).toStream();",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" long count = Flux.just(3).toStream().count();",
|
||||
"",
|
||||
" Flux.just(4).toIterable(1);",
|
||||
" Flux.just(5).toIterable(2, null);",
|
||||
" Flux.just(6).toStream(3);",
|
||||
" new Foo().toIterable();",
|
||||
" new Foo().toStream();",
|
||||
" }",
|
||||
"",
|
||||
" class Foo<T> {",
|
||||
" Iterable<T> toIterable() {",
|
||||
" return ImmutableList.of();",
|
||||
" }",
|
||||
"",
|
||||
" Stream<T> toStream() {",
|
||||
" return Stream.empty();",
|
||||
" }",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -63,18 +61,16 @@ final class FluxImplicitBlockTest {
|
||||
.expectErrorMessage("X", m -> !m.contains("toImmutableList"))
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
// BUG: Diagnostic matches: X
|
||||
Flux.just(1).toIterable();
|
||||
// BUG: Diagnostic matches: X
|
||||
Flux.just(2).toStream();
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" Flux.just(1).toIterable();",
|
||||
" // BUG: Diagnostic matches: X",
|
||||
" Flux.just(2).toStream();",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -83,29 +79,25 @@ final class FluxImplicitBlockTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(FluxImplicitBlock.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
Flux.just(1).toIterable();
|
||||
Flux.just(2).toStream();
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Flux.just(1).toIterable();",
|
||||
" Flux.just(2).toStream();",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
class A {
|
||||
@SuppressWarnings("FluxImplicitBlock")
|
||||
void m() {
|
||||
Flux.just(1).toIterable();
|
||||
Flux.just(2).toStream();
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"",
|
||||
"class A {",
|
||||
" @SuppressWarnings(\"FluxImplicitBlock\")",
|
||||
" void m() {",
|
||||
" Flux.just(1).toIterable();",
|
||||
" Flux.just(2).toStream();",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
|
||||
@@ -115,38 +107,34 @@ final class FluxImplicitBlockTest {
|
||||
.setFixChooser(SECOND)
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
Flux.just(1).toIterable();
|
||||
Flux.just(2).toStream();
|
||||
Flux.just(3).toIterable().iterator();
|
||||
Flux.just(4).toStream().count();
|
||||
Flux.just(5) /* a */./* b */ toIterable /* c */(/* d */ ) /* e */;
|
||||
Flux.just(6) /* a */./* b */ toStream /* c */(/* d */ ) /* e */;
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Flux.just(1).toIterable();",
|
||||
" Flux.just(2).toStream();",
|
||||
" Flux.just(3).toIterable().iterator();",
|
||||
" Flux.just(4).toStream().count();",
|
||||
" Flux.just(5) /* a */./* b */ toIterable /* c */(/* d */ ) /* e */;",
|
||||
" Flux.just(6) /* a */./* b */ toStream /* c */(/* d */ ) /* e */;",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
Flux.just(1).collect(toImmutableList()).block();
|
||||
Flux.just(2).collect(toImmutableList()).block().stream();
|
||||
Flux.just(3).collect(toImmutableList()).block().iterator();
|
||||
Flux.just(4).collect(toImmutableList()).block().stream().count();
|
||||
Flux.just(5).collect(toImmutableList()).block() /* e */;
|
||||
Flux.just(6).collect(toImmutableList()).block().stream() /* e */;
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static com.google.common.collect.ImmutableList.toImmutableList;",
|
||||
"",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Flux.just(1).collect(toImmutableList()).block();",
|
||||
" Flux.just(2).collect(toImmutableList()).block().stream();",
|
||||
" Flux.just(3).collect(toImmutableList()).block().iterator();",
|
||||
" Flux.just(4).collect(toImmutableList()).block().stream().count();",
|
||||
" Flux.just(5).collect(toImmutableList()).block() /* e */;",
|
||||
" Flux.just(6).collect(toImmutableList()).block().stream() /* e */;",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
|
||||
@@ -156,38 +144,34 @@ final class FluxImplicitBlockTest {
|
||||
.setFixChooser(THIRD)
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
Flux.just(1).toIterable();
|
||||
Flux.just(2).toStream();
|
||||
Flux.just(3).toIterable().iterator();
|
||||
Flux.just(4).toStream().count();
|
||||
Flux.just(5) /* a */./* b */ toIterable /* c */(/* d */ ) /* e */;
|
||||
Flux.just(6) /* a */./* b */ toStream /* c */(/* d */ ) /* e */;
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Flux.just(1).toIterable();",
|
||||
" Flux.just(2).toStream();",
|
||||
" Flux.just(3).toIterable().iterator();",
|
||||
" Flux.just(4).toStream().count();",
|
||||
" Flux.just(5) /* a */./* b */ toIterable /* c */(/* d */ ) /* e */;",
|
||||
" Flux.just(6) /* a */./* b */ toStream /* c */(/* d */ ) /* e */;",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
Flux.just(1).collect(toList()).block();
|
||||
Flux.just(2).collect(toList()).block().stream();
|
||||
Flux.just(3).collect(toList()).block().iterator();
|
||||
Flux.just(4).collect(toList()).block().stream().count();
|
||||
Flux.just(5).collect(toList()).block() /* e */;
|
||||
Flux.just(6).collect(toList()).block().stream() /* e */;
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static java.util.stream.Collectors.toList;",
|
||||
"",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Flux.just(1).collect(toList()).block();",
|
||||
" Flux.just(2).collect(toList()).block().stream();",
|
||||
" Flux.just(3).collect(toList()).block().iterator();",
|
||||
" Flux.just(4).collect(toList()).block().stream().count();",
|
||||
" Flux.just(5).collect(toList()).block() /* e */;",
|
||||
" Flux.just(6).collect(toList()).block().stream() /* e */;",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,296 +11,294 @@ final class FormatStringConcatenationTest {
|
||||
CompilationTestHelper.newInstance(FormatStringConcatenation.class, getClass())
|
||||
.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 org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.SoftAssertions.assertSoftly;
|
||||
|
||||
import java.util.Formatter;
|
||||
import java.util.Locale;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.assertj.core.api.BDDAssertions;
|
||||
import org.assertj.core.api.Fail;
|
||||
import org.assertj.core.api.ThrowableAssertAlternative;
|
||||
import org.assertj.core.api.WithAssertions;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.slf4j.Marker;
|
||||
|
||||
class A {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(A.class);
|
||||
|
||||
void negative() {
|
||||
hashCode();
|
||||
equals(new A());
|
||||
equals(toString());
|
||||
equals(0);
|
||||
equals("str");
|
||||
equals("str" + 0);
|
||||
equals(0 + 0);
|
||||
equals(0 - 0);
|
||||
equals("str " + toString());
|
||||
}
|
||||
|
||||
void assertj() {
|
||||
assertThat(0).overridingErrorMessage(toString());
|
||||
assertThat(0).overridingErrorMessage("str");
|
||||
assertThat(0).overridingErrorMessage("str " + 0);
|
||||
assertThat(0).overridingErrorMessage("str %s", 2 * 3);
|
||||
assertThat(0).overridingErrorMessage("str %s", toString());
|
||||
// BUG: Diagnostic contains:
|
||||
assertThat(0).overridingErrorMessage("str " + hashCode() / 2);
|
||||
// BUG: Diagnostic contains:
|
||||
assertThat(0).overridingErrorMessage(("str " + toString()));
|
||||
// BUG: Diagnostic contains:
|
||||
assertThat(0).overridingErrorMessage("str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
assertThat(0).overridingErrorMessage("%s " + toString(), "arg");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
assertThat(0).withFailMessage("str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
assertThat(0).withFailMessage("%s " + toString(), "arg");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
assertSoftly(softly -> softly.fail("str " + toString()));
|
||||
// BUG: Diagnostic contains:
|
||||
assertSoftly(softly -> softly.fail("%s " + toString(), "arg"));
|
||||
assertSoftly(softly -> softly.fail("str " + toString(), new Throwable()));
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
assertThat("").isEqualTo("str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
assertThat("").isEqualTo("%s " + toString(), "arg");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
assertThat(new Error()).hasMessage("str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
assertThat(new Error()).hasMessage("%s " + toString(), "arg");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
assertThat(new Error()).hasMessageContaining("str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
assertThat(new Error()).hasMessageContaining("%s " + toString(), "arg");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
assertThat(new Error()).hasMessageEndingWith("str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
assertThat(new Error()).hasMessageEndingWith("%s " + toString(), "arg");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
assertThat(new Error()).hasMessageStartingWith("str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
assertThat(new Error()).hasMessageStartingWith("%s " + toString(), "arg");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
assertThat(new Error()).hasRootCauseMessage("str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
assertThat(new Error()).hasRootCauseMessage("%s " + toString(), "arg");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
assertThat(new Error()).hasStackTraceContaining("str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
assertThat(new Error()).hasStackTraceContaining("%s " + toString(), "arg");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
assertThat(0).as("str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
assertThat(0).as("%s " + toString(), "arg");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
assertThat(0).describedAs("str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
assertThat(0).describedAs("%s " + toString(), "arg");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
((ThrowableAssertAlternative) null).withMessage("str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
((ThrowableAssertAlternative) null).withMessage("%s " + toString(), "arg");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
((ThrowableAssertAlternative) null).withMessageContaining("str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
((ThrowableAssertAlternative) null).withMessageContaining("%s " + toString(), "arg");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
((ThrowableAssertAlternative) null).withMessageEndingWith("str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
((ThrowableAssertAlternative) null).withMessageEndingWith("%s " + toString(), "arg");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
((ThrowableAssertAlternative) null).withMessageStartingWith("str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
((ThrowableAssertAlternative) null).withMessageStartingWith("%s " + toString(), "arg");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
((ThrowableAssertAlternative) null).withStackTraceContaining("str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
((ThrowableAssertAlternative) null).withStackTraceContaining("%s " + toString(), "arg");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
((WithAssertions) null).fail("str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
((WithAssertions) null).fail("%s " + toString(), "arg");
|
||||
((WithAssertions) null).fail("str " + toString(), new Throwable());
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Assertions.fail("str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
Assertions.fail("%s " + toString(), "arg");
|
||||
Assertions.fail("str " + toString(), new Throwable());
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
BDDAssertions.fail("str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
BDDAssertions.fail("%s " + toString(), "arg");
|
||||
BDDAssertions.fail("str " + toString(), new Throwable());
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Fail.fail("str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
Fail.fail("%s " + toString(), "arg");
|
||||
Fail.fail("str " + toString(), new Throwable());
|
||||
}
|
||||
|
||||
void guava() {
|
||||
checkArgument(true);
|
||||
checkArgument(true, toString());
|
||||
checkArgument(true, "str");
|
||||
checkArgument(true, "str " + 0);
|
||||
checkArgument(true, "str %s", 2 * 3);
|
||||
checkArgument(true, "str %s", toString());
|
||||
// BUG: Diagnostic contains:
|
||||
checkArgument(true, "str " + hashCode() / 2);
|
||||
// BUG: Diagnostic contains:
|
||||
checkArgument(true, ("str " + toString()));
|
||||
// BUG: Diagnostic contains:
|
||||
checkArgument(true, "str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
checkArgument(true, "%s " + toString(), "arg");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
checkNotNull(true, "str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
checkNotNull(true, "%s " + toString(), "arg");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
checkState(true, "str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
checkState(true, "%s " + toString(), "arg");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
verify(true, "str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
verify(true, "%s " + toString(), "arg");
|
||||
}
|
||||
|
||||
void jdk() {
|
||||
String.format("str");
|
||||
String.format("str " + 0);
|
||||
String.format("str {}", 2 * 3);
|
||||
String.format("str {}", toString());
|
||||
// BUG: Diagnostic contains:
|
||||
String.format("str " + hashCode() / 2);
|
||||
// BUG: Diagnostic contains:
|
||||
String.format(("str " + toString()));
|
||||
// BUG: Diagnostic contains:
|
||||
String.format("str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
String.format("{} " + toString(), "arg");
|
||||
|
||||
String.format(Locale.ROOT, "str");
|
||||
String.format(Locale.ROOT, "str " + 0);
|
||||
String.format(Locale.ROOT, "str {}", 2 * 3);
|
||||
String.format(Locale.ROOT, "str {}", toString());
|
||||
// BUG: Diagnostic contains:
|
||||
String.format(Locale.ROOT, ("str " + toString()));
|
||||
// BUG: Diagnostic contains:
|
||||
String.format(Locale.ROOT, "str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
String.format(Locale.ROOT, "{} " + toString(), "arg");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
new Formatter().format("str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
new Formatter().format("{} " + toString(), "arg");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
new Formatter().format(Locale.ROOT, "str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
new Formatter().format(Locale.ROOT, "{} " + toString(), "arg");
|
||||
}
|
||||
|
||||
void slf4j() {
|
||||
LOG.debug("str");
|
||||
LOG.debug("str " + 0);
|
||||
LOG.debug("str {}", 2 * 3);
|
||||
LOG.debug("str {}", toString());
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.debug("str " + hashCode() / 2);
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.debug(("str " + toString()));
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.debug("str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.debug("{} " + toString(), "arg");
|
||||
|
||||
LOG.debug((Marker) null, "str");
|
||||
LOG.debug((Marker) null, "str " + 0);
|
||||
LOG.debug((Marker) null, "str {}", 2 * 3);
|
||||
LOG.debug((Marker) null, "str {}", toString());
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.debug((Marker) null, ("str " + toString()));
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.debug((Marker) null, "str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.debug((Marker) null, "{} " + toString(), "arg");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.error("str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.error("{} " + toString(), "arg");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.error((Marker) null, "str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.error((Marker) null, "{} " + toString(), "arg");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.info("str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.info("{} " + toString(), "arg");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.info((Marker) null, "str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.info((Marker) null, "{} " + toString(), "arg");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.trace("str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.trace("{} " + toString(), "arg");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.trace((Marker) null, "str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.trace((Marker) null, "{} " + toString(), "arg");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.warn("str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.warn("{} " + toString(), "arg");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.warn((Marker) null, "str " + toString());
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.warn((Marker) null, "{} " + toString(), "arg");
|
||||
}
|
||||
}
|
||||
""")
|
||||
"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 org.assertj.core.api.Assertions.assertThat;",
|
||||
"import static org.assertj.core.api.SoftAssertions.assertSoftly;",
|
||||
"",
|
||||
"import java.util.Formatter;",
|
||||
"import java.util.Locale;",
|
||||
"import org.assertj.core.api.Assertions;",
|
||||
"import org.assertj.core.api.BDDAssertions;",
|
||||
"import org.assertj.core.api.Fail;",
|
||||
"import org.assertj.core.api.ThrowableAssertAlternative;",
|
||||
"import org.assertj.core.api.WithAssertions;",
|
||||
"import org.slf4j.Logger;",
|
||||
"import org.slf4j.LoggerFactory;",
|
||||
"import org.slf4j.Marker;",
|
||||
"",
|
||||
"class A {",
|
||||
" private static final Logger LOG = LoggerFactory.getLogger(A.class);",
|
||||
"",
|
||||
" void negative() {",
|
||||
" hashCode();",
|
||||
" equals(new A());",
|
||||
" equals(toString());",
|
||||
" equals(0);",
|
||||
" equals(\"str\");",
|
||||
" equals(\"str\" + 0);",
|
||||
" equals(0 + 0);",
|
||||
" equals(0 - 0);",
|
||||
" equals(\"str \" + toString());",
|
||||
" }",
|
||||
"",
|
||||
" void assertj() {",
|
||||
" assertThat(0).overridingErrorMessage(toString());",
|
||||
" assertThat(0).overridingErrorMessage(\"str\");",
|
||||
" assertThat(0).overridingErrorMessage(\"str \" + 0);",
|
||||
" assertThat(0).overridingErrorMessage(\"str %s\", 2 * 3);",
|
||||
" assertThat(0).overridingErrorMessage(\"str %s\", toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" assertThat(0).overridingErrorMessage(\"str \" + hashCode() / 2);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" assertThat(0).overridingErrorMessage((\"str \" + toString()));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" assertThat(0).overridingErrorMessage(\"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" assertThat(0).overridingErrorMessage(\"%s \" + toString(), \"arg\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" assertThat(0).withFailMessage(\"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" assertThat(0).withFailMessage(\"%s \" + toString(), \"arg\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" assertSoftly(softly -> softly.fail(\"str \" + toString()));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" assertSoftly(softly -> softly.fail(\"%s \" + toString(), \"arg\"));",
|
||||
" assertSoftly(softly -> softly.fail(\"str \" + toString(), new Throwable()));",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" assertThat(\"\").isEqualTo(\"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" assertThat(\"\").isEqualTo(\"%s \" + toString(), \"arg\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" assertThat(new Error()).hasMessage(\"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" assertThat(new Error()).hasMessage(\"%s \" + toString(), \"arg\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" assertThat(new Error()).hasMessageContaining(\"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" assertThat(new Error()).hasMessageContaining(\"%s \" + toString(), \"arg\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" assertThat(new Error()).hasMessageEndingWith(\"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" assertThat(new Error()).hasMessageEndingWith(\"%s \" + toString(), \"arg\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" assertThat(new Error()).hasMessageStartingWith(\"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" assertThat(new Error()).hasMessageStartingWith(\"%s \" + toString(), \"arg\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" assertThat(new Error()).hasRootCauseMessage(\"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" assertThat(new Error()).hasRootCauseMessage(\"%s \" + toString(), \"arg\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" assertThat(new Error()).hasStackTraceContaining(\"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" assertThat(new Error()).hasStackTraceContaining(\"%s \" + toString(), \"arg\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" assertThat(0).as(\"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" assertThat(0).as(\"%s \" + toString(), \"arg\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" assertThat(0).describedAs(\"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" assertThat(0).describedAs(\"%s \" + toString(), \"arg\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ((ThrowableAssertAlternative) null).withMessage(\"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ((ThrowableAssertAlternative) null).withMessage(\"%s \" + toString(), \"arg\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ((ThrowableAssertAlternative) null).withMessageContaining(\"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ((ThrowableAssertAlternative) null).withMessageContaining(\"%s \" + toString(), \"arg\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ((ThrowableAssertAlternative) null).withMessageEndingWith(\"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ((ThrowableAssertAlternative) null).withMessageEndingWith(\"%s \" + toString(), \"arg\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ((ThrowableAssertAlternative) null).withMessageStartingWith(\"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ((ThrowableAssertAlternative) null).withMessageStartingWith(\"%s \" + toString(), \"arg\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ((ThrowableAssertAlternative) null).withStackTraceContaining(\"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ((ThrowableAssertAlternative) null).withStackTraceContaining(\"%s \" + toString(), \"arg\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ((WithAssertions) null).fail(\"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ((WithAssertions) null).fail(\"%s \" + toString(), \"arg\");",
|
||||
" ((WithAssertions) null).fail(\"str \" + toString(), new Throwable());",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Assertions.fail(\"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Assertions.fail(\"%s \" + toString(), \"arg\");",
|
||||
" Assertions.fail(\"str \" + toString(), new Throwable());",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" BDDAssertions.fail(\"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" BDDAssertions.fail(\"%s \" + toString(), \"arg\");",
|
||||
" BDDAssertions.fail(\"str \" + toString(), new Throwable());",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Fail.fail(\"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Fail.fail(\"%s \" + toString(), \"arg\");",
|
||||
" Fail.fail(\"str \" + toString(), new Throwable());",
|
||||
" }",
|
||||
"",
|
||||
" void guava() {",
|
||||
" checkArgument(true);",
|
||||
" checkArgument(true, toString());",
|
||||
" checkArgument(true, \"str\");",
|
||||
" checkArgument(true, \"str \" + 0);",
|
||||
" checkArgument(true, \"str %s\", 2 * 3);",
|
||||
" checkArgument(true, \"str %s\", toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" checkArgument(true, \"str \" + hashCode() / 2);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" checkArgument(true, (\"str \" + toString()));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" checkArgument(true, \"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" checkArgument(true, \"%s \" + toString(), \"arg\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" checkNotNull(true, \"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" checkNotNull(true, \"%s \" + toString(), \"arg\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" checkState(true, \"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" checkState(true, \"%s \" + toString(), \"arg\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" verify(true, \"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" verify(true, \"%s \" + toString(), \"arg\");",
|
||||
" }",
|
||||
"",
|
||||
" void jdk() {",
|
||||
" String.format(\"str\");",
|
||||
" String.format(\"str \" + 0);",
|
||||
" String.format(\"str {}\", 2 * 3);",
|
||||
" String.format(\"str {}\", toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String.format(\"str \" + hashCode() / 2);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String.format((\"str \" + toString()));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String.format(\"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String.format(\"{} \" + toString(), \"arg\");",
|
||||
"",
|
||||
" String.format(Locale.ROOT, \"str\");",
|
||||
" String.format(Locale.ROOT, \"str \" + 0);",
|
||||
" String.format(Locale.ROOT, \"str {}\", 2 * 3);",
|
||||
" String.format(Locale.ROOT, \"str {}\", toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String.format(Locale.ROOT, (\"str \" + toString()));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String.format(Locale.ROOT, \"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String.format(Locale.ROOT, \"{} \" + toString(), \"arg\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" new Formatter().format(\"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" new Formatter().format(\"{} \" + toString(), \"arg\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" new Formatter().format(Locale.ROOT, \"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" new Formatter().format(Locale.ROOT, \"{} \" + toString(), \"arg\");",
|
||||
" }",
|
||||
"",
|
||||
" void slf4j() {",
|
||||
" LOG.debug(\"str\");",
|
||||
" LOG.debug(\"str \" + 0);",
|
||||
" LOG.debug(\"str {}\", 2 * 3);",
|
||||
" LOG.debug(\"str {}\", toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.debug(\"str \" + hashCode() / 2);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.debug((\"str \" + toString()));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.debug(\"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.debug(\"{} \" + toString(), \"arg\");",
|
||||
"",
|
||||
" LOG.debug((Marker) null, \"str\");",
|
||||
" LOG.debug((Marker) null, \"str \" + 0);",
|
||||
" LOG.debug((Marker) null, \"str {}\", 2 * 3);",
|
||||
" LOG.debug((Marker) null, \"str {}\", toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.debug((Marker) null, (\"str \" + toString()));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.debug((Marker) null, \"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.debug((Marker) null, \"{} \" + toString(), \"arg\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.error(\"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.error(\"{} \" + toString(), \"arg\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.error((Marker) null, \"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.error((Marker) null, \"{} \" + toString(), \"arg\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.info(\"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.info(\"{} \" + toString(), \"arg\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.info((Marker) null, \"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.info((Marker) null, \"{} \" + toString(), \"arg\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.trace(\"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.trace(\"{} \" + toString(), \"arg\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.trace((Marker) null, \"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.trace((Marker) null, \"{} \" + toString(), \"arg\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.warn(\"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.warn(\"{} \" + toString(), \"arg\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.warn((Marker) null, \"str \" + toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.warn((Marker) null, \"{} \" + toString(), \"arg\");",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -309,106 +307,102 @@ final class FormatStringConcatenationTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(FormatStringConcatenation.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
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);
|
||||
|
||||
void assertj() {
|
||||
assertThat(0).overridingErrorMessage(toString() + " str");
|
||||
assertThat(0).overridingErrorMessage("str " + toString());
|
||||
assertThat(0).overridingErrorMessage(toString() + toString());
|
||||
assertThat(0).overridingErrorMessage("str " + toString() + " word " + new A().hashCode());
|
||||
assertThat(0).overridingErrorMessage("str " + (toString() + " word ") + (hashCode() / 2));
|
||||
|
||||
// Flagged but not auto-fixed.
|
||||
assertThat(0).overridingErrorMessage("%s " + toString(), "arg");
|
||||
}
|
||||
|
||||
void guava() {
|
||||
checkArgument(true, "str " + toString());
|
||||
|
||||
// Flagged but not auto-fixed.
|
||||
checkArgument(true, "%s " + toString(), "arg");
|
||||
}
|
||||
|
||||
void jdk() {
|
||||
String.format("str " + toString());
|
||||
String.format(Locale.ROOT, "str " + toString());
|
||||
|
||||
// Flagged but not auto-fixed.
|
||||
String.format("{} " + toString(), "arg");
|
||||
String.format(Locale.ROOT, "{} " + toString(), "arg");
|
||||
}
|
||||
|
||||
void slf4j() {
|
||||
LOG.debug("str " + toString());
|
||||
LOG.debug((Marker) null, "str " + toString());
|
||||
|
||||
// Flagged but not auto-fixed.
|
||||
LOG.debug("{} " + toString(), "arg");
|
||||
LOG.debug((Marker) null, "{} " + toString(), "arg");
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static com.google.common.base.Preconditions.checkArgument;",
|
||||
"import static org.assertj.core.api.Assertions.assertThat;",
|
||||
"",
|
||||
"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);",
|
||||
"",
|
||||
" void assertj() {",
|
||||
" assertThat(0).overridingErrorMessage(toString() + \" str\");",
|
||||
" assertThat(0).overridingErrorMessage(\"str \" + toString());",
|
||||
" assertThat(0).overridingErrorMessage(toString() + toString());",
|
||||
" assertThat(0).overridingErrorMessage(\"str \" + toString() + \" word \" + new A().hashCode());",
|
||||
" assertThat(0).overridingErrorMessage(\"str \" + (toString() + \" word \") + (hashCode() / 2));",
|
||||
"",
|
||||
" // Flagged but not auto-fixed.",
|
||||
" assertThat(0).overridingErrorMessage(\"%s \" + toString(), \"arg\");",
|
||||
" }",
|
||||
"",
|
||||
" void guava() {",
|
||||
" checkArgument(true, \"str \" + toString());",
|
||||
"",
|
||||
" // Flagged but not auto-fixed.",
|
||||
" checkArgument(true, \"%s \" + toString(), \"arg\");",
|
||||
" }",
|
||||
"",
|
||||
" void jdk() {",
|
||||
" String.format(\"str \" + toString());",
|
||||
" String.format(Locale.ROOT, \"str \" + toString());",
|
||||
"",
|
||||
" // Flagged but not auto-fixed.",
|
||||
" String.format(\"{} \" + toString(), \"arg\");",
|
||||
" String.format(Locale.ROOT, \"{} \" + toString(), \"arg\");",
|
||||
" }",
|
||||
"",
|
||||
" void slf4j() {",
|
||||
" LOG.debug(\"str \" + toString());",
|
||||
" LOG.debug((Marker) null, \"str \" + toString());",
|
||||
"",
|
||||
" // Flagged but not auto-fixed.",
|
||||
" LOG.debug(\"{} \" + toString(), \"arg\");",
|
||||
" LOG.debug((Marker) null, \"{} \" + toString(), \"arg\");",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
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);
|
||||
|
||||
void assertj() {
|
||||
assertThat(0).overridingErrorMessage("%s str", toString());
|
||||
assertThat(0).overridingErrorMessage("str %s", toString());
|
||||
assertThat(0).overridingErrorMessage("%s%s", toString(), toString());
|
||||
assertThat(0).overridingErrorMessage("str %s word %s", toString(), new A().hashCode());
|
||||
assertThat(0).overridingErrorMessage("str %s word %s", toString(), hashCode() / 2);
|
||||
|
||||
// Flagged but not auto-fixed.
|
||||
assertThat(0).overridingErrorMessage("%s " + toString(), "arg");
|
||||
}
|
||||
|
||||
void guava() {
|
||||
checkArgument(true, "str %s", toString());
|
||||
|
||||
// Flagged but not auto-fixed.
|
||||
checkArgument(true, "%s " + toString(), "arg");
|
||||
}
|
||||
|
||||
void jdk() {
|
||||
String.format("str %s", toString());
|
||||
String.format(Locale.ROOT, "str %s", toString());
|
||||
|
||||
// Flagged but not auto-fixed.
|
||||
String.format("{} " + toString(), "arg");
|
||||
String.format(Locale.ROOT, "{} " + toString(), "arg");
|
||||
}
|
||||
|
||||
void slf4j() {
|
||||
LOG.debug("str {}", toString());
|
||||
LOG.debug((Marker) null, "str {}", toString());
|
||||
|
||||
// Flagged but not auto-fixed.
|
||||
LOG.debug("{} " + toString(), "arg");
|
||||
LOG.debug((Marker) null, "{} " + toString(), "arg");
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static com.google.common.base.Preconditions.checkArgument;",
|
||||
"import static org.assertj.core.api.Assertions.assertThat;",
|
||||
"",
|
||||
"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);",
|
||||
"",
|
||||
" void assertj() {",
|
||||
" assertThat(0).overridingErrorMessage(\"%s str\", toString());",
|
||||
" assertThat(0).overridingErrorMessage(\"str %s\", toString());",
|
||||
" assertThat(0).overridingErrorMessage(\"%s%s\", toString(), toString());",
|
||||
" assertThat(0).overridingErrorMessage(\"str %s word %s\", toString(), new A().hashCode());",
|
||||
" assertThat(0).overridingErrorMessage(\"str %s word %s\", toString(), hashCode() / 2);",
|
||||
"",
|
||||
" // Flagged but not auto-fixed.",
|
||||
" assertThat(0).overridingErrorMessage(\"%s \" + toString(), \"arg\");",
|
||||
" }",
|
||||
"",
|
||||
" void guava() {",
|
||||
" checkArgument(true, \"str %s\", toString());",
|
||||
"",
|
||||
" // Flagged but not auto-fixed.",
|
||||
" checkArgument(true, \"%s \" + toString(), \"arg\");",
|
||||
" }",
|
||||
"",
|
||||
" void jdk() {",
|
||||
" String.format(\"str %s\", toString());",
|
||||
" String.format(Locale.ROOT, \"str %s\", toString());",
|
||||
"",
|
||||
" // Flagged but not auto-fixed.",
|
||||
" String.format(\"{} \" + toString(), \"arg\");",
|
||||
" String.format(Locale.ROOT, \"{} \" + toString(), \"arg\");",
|
||||
" }",
|
||||
"",
|
||||
" void slf4j() {",
|
||||
" LOG.debug(\"str {}\", toString());",
|
||||
" LOG.debug((Marker) null, \"str {}\", toString());",
|
||||
"",
|
||||
" // Flagged but not auto-fixed.",
|
||||
" LOG.debug(\"{} \" + toString(), \"arg\");",
|
||||
" LOG.debug((Marker) null, \"{} \" + toString(), \"arg\");",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,176 +12,174 @@ final class IdentityConversionTest {
|
||||
CompilationTestHelper.newInstance(IdentityConversion.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static com.google.errorprone.matchers.Matchers.instanceMethod;
|
||||
import static com.google.errorprone.matchers.Matchers.staticMethod;
|
||||
|
||||
import com.google.common.collect.ImmutableBiMap;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableListMultimap;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.ImmutableMultiset;
|
||||
import com.google.common.collect.ImmutableRangeMap;
|
||||
import com.google.common.collect.ImmutableRangeSet;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSetMultimap;
|
||||
import com.google.common.collect.ImmutableTable;
|
||||
import com.google.errorprone.matchers.Matcher;
|
||||
import com.google.errorprone.matchers.Matchers;
|
||||
import java.time.Instant;
|
||||
import java.time.ZonedDateTime;
|
||||
import reactor.adapter.rxjava.RxJava2Adapter;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public final class A {
|
||||
public void m() {
|
||||
// BUG: Diagnostic contains:
|
||||
Boolean b1 = Boolean.valueOf(Boolean.FALSE);
|
||||
// BUG: Diagnostic contains:
|
||||
Boolean b2 = Boolean.valueOf(false);
|
||||
// BUG: Diagnostic contains:
|
||||
boolean b3 = Boolean.valueOf(Boolean.FALSE);
|
||||
// BUG: Diagnostic contains:
|
||||
boolean b4 = Boolean.valueOf(false);
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Byte byte1 = Byte.valueOf((Byte) Byte.MIN_VALUE);
|
||||
// BUG: Diagnostic contains:
|
||||
Byte byte2 = Byte.valueOf(Byte.MIN_VALUE);
|
||||
// BUG: Diagnostic contains:
|
||||
byte byte3 = Byte.valueOf((Byte) Byte.MIN_VALUE);
|
||||
// BUG: Diagnostic contains:
|
||||
byte byte4 = Byte.valueOf(Byte.MIN_VALUE);
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Character c1 = Character.valueOf((Character) 'a');
|
||||
// BUG: Diagnostic contains:
|
||||
Character c2 = Character.valueOf('a');
|
||||
// BUG: Diagnostic contains:
|
||||
char c3 = Character.valueOf((Character) 'a');
|
||||
// BUG: Diagnostic contains:
|
||||
char c4 = Character.valueOf('a');
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Double d1 = Double.valueOf((Double) 0.0);
|
||||
// BUG: Diagnostic contains:
|
||||
Double d2 = Double.valueOf(0.0);
|
||||
// BUG: Diagnostic contains:
|
||||
double d3 = Double.valueOf((Double) 0.0);
|
||||
// BUG: Diagnostic contains:
|
||||
double d4 = Double.valueOf(0.0);
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Float f1 = Float.valueOf((Float) 0.0F);
|
||||
// BUG: Diagnostic contains:
|
||||
Float f2 = Float.valueOf(0.0F);
|
||||
// BUG: Diagnostic contains:
|
||||
float f3 = Float.valueOf((Float) 0.0F);
|
||||
// BUG: Diagnostic contains:
|
||||
float f4 = Float.valueOf(0.0F);
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Integer i1 = Integer.valueOf((Integer) 1);
|
||||
// BUG: Diagnostic contains:
|
||||
Integer i2 = Integer.valueOf(1);
|
||||
// BUG: Diagnostic contains:
|
||||
int i3 = Integer.valueOf((Integer) 1);
|
||||
// BUG: Diagnostic contains:
|
||||
int i4 = Integer.valueOf(1);
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Long l1 = Long.valueOf((Long) 1L);
|
||||
// BUG: Diagnostic contains:
|
||||
Long l2 = Long.valueOf(1L);
|
||||
// BUG: Diagnostic contains:
|
||||
long l3 = Long.valueOf((Long) 1L);
|
||||
// BUG: Diagnostic contains:
|
||||
long l4 = Long.valueOf(1L);
|
||||
|
||||
Long l5 = Long.valueOf((Integer) 1);
|
||||
Long l6 = Long.valueOf(1);
|
||||
// BUG: Diagnostic contains:
|
||||
long l7 = Long.valueOf((Integer) 1);
|
||||
// BUG: Diagnostic contains:
|
||||
long l8 = Long.valueOf(1);
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Short s1 = Short.valueOf((Short) Short.MIN_VALUE);
|
||||
// BUG: Diagnostic contains:
|
||||
Short s2 = Short.valueOf(Short.MIN_VALUE);
|
||||
// BUG: Diagnostic contains:
|
||||
short s3 = Short.valueOf((Short) Short.MIN_VALUE);
|
||||
// BUG: Diagnostic contains:
|
||||
short s4 = Short.valueOf(Short.MIN_VALUE);
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
String boolStr = Boolean.valueOf(Boolean.FALSE).toString();
|
||||
int boolHash = Boolean.valueOf(false).hashCode();
|
||||
// BUG: Diagnostic contains:
|
||||
int byteHash = Byte.valueOf((Byte) Byte.MIN_VALUE).hashCode();
|
||||
String byteStr = Byte.valueOf(Byte.MIN_VALUE).toString();
|
||||
|
||||
String str1 = String.valueOf(0);
|
||||
// BUG: Diagnostic contains:
|
||||
String str2 = String.valueOf("1");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
ImmutableBiMap<Object, Object> o1 = ImmutableBiMap.copyOf(ImmutableBiMap.of());
|
||||
// BUG: Diagnostic contains:
|
||||
ImmutableList<Object> o2 = ImmutableList.copyOf(ImmutableList.of());
|
||||
ImmutableListMultimap<Object, Object> o3 =
|
||||
// BUG: Diagnostic contains:
|
||||
ImmutableListMultimap.copyOf(ImmutableListMultimap.of());
|
||||
// BUG: Diagnostic contains:
|
||||
ImmutableMap<Object, Object> o4 = ImmutableMap.copyOf(ImmutableMap.of());
|
||||
// BUG: Diagnostic contains:
|
||||
ImmutableMultimap<Object, Object> o5 = ImmutableMultimap.copyOf(ImmutableMultimap.of());
|
||||
// BUG: Diagnostic contains:
|
||||
ImmutableMultiset<Object> o6 = ImmutableMultiset.copyOf(ImmutableMultiset.of());
|
||||
// BUG: Diagnostic contains:
|
||||
ImmutableRangeMap<String, Object> o7 = ImmutableRangeMap.copyOf(ImmutableRangeMap.of());
|
||||
// BUG: Diagnostic contains:
|
||||
ImmutableRangeSet<String> o8 = ImmutableRangeSet.copyOf(ImmutableRangeSet.of());
|
||||
// BUG: Diagnostic contains:
|
||||
ImmutableSet<Object> o9 = ImmutableSet.copyOf(ImmutableSet.of());
|
||||
ImmutableSetMultimap<Object, Object> o10 =
|
||||
// BUG: Diagnostic contains:
|
||||
ImmutableSetMultimap.copyOf(ImmutableSetMultimap.of());
|
||||
// BUG: Diagnostic contains:
|
||||
ImmutableTable<Object, Object, Object> o11 = ImmutableTable.copyOf(ImmutableTable.of());
|
||||
|
||||
Instant instant1 = Instant.from(ZonedDateTime.now());
|
||||
// BUG: Diagnostic contains:
|
||||
Instant instant2 = Instant.from(Instant.now());
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Matcher allOf1 = Matchers.allOf(instanceMethod());
|
||||
Matcher allOf2 = Matchers.allOf(instanceMethod(), staticMethod());
|
||||
// BUG: Diagnostic contains:
|
||||
Matcher anyOf1 = Matchers.anyOf(staticMethod());
|
||||
Matcher anyOf2 = Matchers.anyOf(instanceMethod(), staticMethod());
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Flux<Integer> flux1 = Flux.just(1).flatMap(e -> RxJava2Adapter.fluxToFlowable(Flux.just(2)));
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Flux<Integer> flux2 = Flux.concat(Flux.just(1));
|
||||
// BUG: Diagnostic contains:
|
||||
Flux<Integer> flux3 = Flux.firstWithSignal(Flux.just(1));
|
||||
// BUG: Diagnostic contains:
|
||||
Flux<Integer> flux4 = Flux.from(Flux.just(1));
|
||||
// BUG: Diagnostic contains:
|
||||
Flux<Integer> flux5 = Flux.merge(Flux.just(1));
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Mono<Integer> mono1 = Mono.from(Mono.just(1));
|
||||
// BUG: Diagnostic contains:
|
||||
Mono<Integer> mono2 = Mono.fromDirect(Mono.just(1));
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static com.google.errorprone.matchers.Matchers.instanceMethod;",
|
||||
"import static com.google.errorprone.matchers.Matchers.staticMethod;",
|
||||
"",
|
||||
"import com.google.common.collect.ImmutableBiMap;",
|
||||
"import com.google.common.collect.ImmutableList;",
|
||||
"import com.google.common.collect.ImmutableListMultimap;",
|
||||
"import com.google.common.collect.ImmutableMap;",
|
||||
"import com.google.common.collect.ImmutableMultimap;",
|
||||
"import com.google.common.collect.ImmutableMultiset;",
|
||||
"import com.google.common.collect.ImmutableRangeMap;",
|
||||
"import com.google.common.collect.ImmutableRangeSet;",
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import com.google.common.collect.ImmutableSetMultimap;",
|
||||
"import com.google.common.collect.ImmutableTable;",
|
||||
"import com.google.errorprone.matchers.Matcher;",
|
||||
"import com.google.errorprone.matchers.Matchers;",
|
||||
"import java.time.Instant;",
|
||||
"import java.time.ZonedDateTime;",
|
||||
"import reactor.adapter.rxjava.RxJava2Adapter;",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"import reactor.core.publisher.Mono;",
|
||||
"",
|
||||
"public final class A {",
|
||||
" public void m() {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Boolean b1 = Boolean.valueOf(Boolean.FALSE);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Boolean b2 = Boolean.valueOf(false);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" boolean b3 = Boolean.valueOf(Boolean.FALSE);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" boolean b4 = Boolean.valueOf(false);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Byte byte1 = Byte.valueOf((Byte) Byte.MIN_VALUE);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Byte byte2 = Byte.valueOf(Byte.MIN_VALUE);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" byte byte3 = Byte.valueOf((Byte) Byte.MIN_VALUE);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" byte byte4 = Byte.valueOf(Byte.MIN_VALUE);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Character c1 = Character.valueOf((Character) 'a');",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Character c2 = Character.valueOf('a');",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" char c3 = Character.valueOf((Character) 'a');",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" char c4 = Character.valueOf('a');",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Double d1 = Double.valueOf((Double) 0.0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Double d2 = Double.valueOf(0.0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" double d3 = Double.valueOf((Double) 0.0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" double d4 = Double.valueOf(0.0);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Float f1 = Float.valueOf((Float) 0.0F);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Float f2 = Float.valueOf(0.0F);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" float f3 = Float.valueOf((Float) 0.0F);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" float f4 = Float.valueOf(0.0F);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Integer i1 = Integer.valueOf((Integer) 1);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Integer i2 = Integer.valueOf(1);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" int i3 = Integer.valueOf((Integer) 1);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" int i4 = Integer.valueOf(1);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Long l1 = Long.valueOf((Long) 1L);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Long l2 = Long.valueOf(1L);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" long l3 = Long.valueOf((Long) 1L);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" long l4 = Long.valueOf(1L);",
|
||||
"",
|
||||
" Long l5 = Long.valueOf((Integer) 1);",
|
||||
" Long l6 = Long.valueOf(1);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" long l7 = Long.valueOf((Integer) 1);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" long l8 = Long.valueOf(1);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Short s1 = Short.valueOf((Short) Short.MIN_VALUE);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Short s2 = Short.valueOf(Short.MIN_VALUE);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" short s3 = Short.valueOf((Short) Short.MIN_VALUE);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" short s4 = Short.valueOf(Short.MIN_VALUE);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String boolStr = Boolean.valueOf(Boolean.FALSE).toString();",
|
||||
" int boolHash = Boolean.valueOf(false).hashCode();",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" int byteHash = Byte.valueOf((Byte) Byte.MIN_VALUE).hashCode();",
|
||||
" String byteStr = Byte.valueOf(Byte.MIN_VALUE).toString();",
|
||||
"",
|
||||
" String str1 = String.valueOf(0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String str2 = String.valueOf(\"1\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableBiMap<Object, Object> o1 = ImmutableBiMap.copyOf(ImmutableBiMap.of());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableList<Object> o2 = ImmutableList.copyOf(ImmutableList.of());",
|
||||
" ImmutableListMultimap<Object, Object> o3 =",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableListMultimap.copyOf(ImmutableListMultimap.of());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableMap<Object, Object> o4 = ImmutableMap.copyOf(ImmutableMap.of());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableMultimap<Object, Object> o5 = ImmutableMultimap.copyOf(ImmutableMultimap.of());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableMultiset<Object> o6 = ImmutableMultiset.copyOf(ImmutableMultiset.of());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableRangeMap<String, Object> o7 = ImmutableRangeMap.copyOf(ImmutableRangeMap.of());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableRangeSet<String> o8 = ImmutableRangeSet.copyOf(ImmutableRangeSet.of());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableSet<Object> o9 = ImmutableSet.copyOf(ImmutableSet.of());",
|
||||
" ImmutableSetMultimap<Object, Object> o10 =",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableSetMultimap.copyOf(ImmutableSetMultimap.of());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableTable<Object, Object, Object> o11 = ImmutableTable.copyOf(ImmutableTable.of());",
|
||||
"",
|
||||
" Instant instant1 = Instant.from(ZonedDateTime.now());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Instant instant2 = Instant.from(Instant.now());",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Matcher allOf1 = Matchers.allOf(instanceMethod());",
|
||||
" Matcher allOf2 = Matchers.allOf(instanceMethod(), staticMethod());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Matcher anyOf1 = Matchers.anyOf(staticMethod());",
|
||||
" Matcher anyOf2 = Matchers.anyOf(instanceMethod(), staticMethod());",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux<Integer> flux1 = Flux.just(1).flatMap(e -> RxJava2Adapter.fluxToFlowable(Flux.just(2)));",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux<Integer> flux2 = Flux.concat(Flux.just(1));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux<Integer> flux3 = Flux.firstWithSignal(Flux.just(1));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux<Integer> flux4 = Flux.from(Flux.just(1));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux<Integer> flux5 = Flux.merge(Flux.just(1));",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Mono<Integer> mono1 = Mono.from(Mono.just(1));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Mono<Integer> mono2 = Mono.fromDirect(Mono.just(1));",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -190,108 +188,104 @@ final class IdentityConversionTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(IdentityConversion.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static com.google.errorprone.matchers.Matchers.staticMethod;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.google.common.collect.ImmutableCollection;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.errorprone.matchers.Matcher;
|
||||
import com.google.errorprone.matchers.Matchers;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import org.reactivestreams.Publisher;
|
||||
import reactor.adapter.rxjava.RxJava2Adapter;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public final class A {
|
||||
public void m() {
|
||||
ImmutableSet<Object> set1 = ImmutableSet.copyOf(ImmutableSet.of());
|
||||
ImmutableSet<Object> set2 = ImmutableSet.copyOf(ImmutableList.of());
|
||||
|
||||
ImmutableCollection<Integer> list1 = ImmutableList.copyOf(ImmutableList.of(1));
|
||||
ImmutableCollection<Integer> list2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1)));
|
||||
|
||||
Collection<Integer> c1 = ImmutableSet.copyOf(ImmutableSet.of(1));
|
||||
Collection<Integer> c2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1)));
|
||||
|
||||
Flux<Integer> f1 = Flux.just(1).flatMap(e -> RxJava2Adapter.fluxToFlowable(Flux.just(2)));
|
||||
Flux<Integer> f2 = Flux.concat(Flux.just(3));
|
||||
Publisher<Integer> f3 = Flux.firstWithSignal(Flux.just(4));
|
||||
Publisher<Integer> f4 = Flux.from(Flux.just(5));
|
||||
Publisher<Integer> f5 = Flux.merge(Flux.just(6));
|
||||
|
||||
Mono<Integer> m1 = Mono.from(Mono.just(7));
|
||||
Publisher<Integer> m2 = Mono.fromDirect(Mono.just(8));
|
||||
|
||||
bar(Flux.concat(Flux.just(9)));
|
||||
bar(Mono.from(Mono.just(10)));
|
||||
|
||||
Object o1 = ImmutableSet.copyOf(ImmutableList.of());
|
||||
Object o2 = ImmutableSet.copyOf(ImmutableSet.of());
|
||||
|
||||
Matcher matcher = Matchers.allOf(staticMethod());
|
||||
|
||||
when("foo".contains("f")).thenAnswer(inv -> ImmutableSet.copyOf(ImmutableList.of(1)));
|
||||
}
|
||||
|
||||
void bar(Publisher<Integer> publisher) {}
|
||||
}
|
||||
""")
|
||||
"import static com.google.errorprone.matchers.Matchers.staticMethod;",
|
||||
"import static org.mockito.Mockito.when;",
|
||||
"",
|
||||
"import com.google.common.collect.ImmutableCollection;",
|
||||
"import com.google.common.collect.ImmutableList;",
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import com.google.errorprone.matchers.Matcher;",
|
||||
"import com.google.errorprone.matchers.Matchers;",
|
||||
"import java.util.ArrayList;",
|
||||
"import java.util.Collection;",
|
||||
"import org.reactivestreams.Publisher;",
|
||||
"import reactor.adapter.rxjava.RxJava2Adapter;",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"import reactor.core.publisher.Mono;",
|
||||
"",
|
||||
"public final class A {",
|
||||
" public void m() {",
|
||||
" ImmutableSet<Object> set1 = ImmutableSet.copyOf(ImmutableSet.of());",
|
||||
" ImmutableSet<Object> set2 = ImmutableSet.copyOf(ImmutableList.of());",
|
||||
"",
|
||||
" ImmutableCollection<Integer> list1 = ImmutableList.copyOf(ImmutableList.of(1));",
|
||||
" ImmutableCollection<Integer> list2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1)));",
|
||||
"",
|
||||
" Collection<Integer> c1 = ImmutableSet.copyOf(ImmutableSet.of(1));",
|
||||
" Collection<Integer> c2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1)));",
|
||||
"",
|
||||
" Flux<Integer> f1 = Flux.just(1).flatMap(e -> RxJava2Adapter.fluxToFlowable(Flux.just(2)));",
|
||||
" Flux<Integer> f2 = Flux.concat(Flux.just(3));",
|
||||
" Publisher<Integer> f3 = Flux.firstWithSignal(Flux.just(4));",
|
||||
" Publisher<Integer> f4 = Flux.from(Flux.just(5));",
|
||||
" Publisher<Integer> f5 = Flux.merge(Flux.just(6));",
|
||||
"",
|
||||
" Mono<Integer> m1 = Mono.from(Mono.just(7));",
|
||||
" Publisher<Integer> m2 = Mono.fromDirect(Mono.just(8));",
|
||||
"",
|
||||
" bar(Flux.concat(Flux.just(9)));",
|
||||
" bar(Mono.from(Mono.just(10)));",
|
||||
"",
|
||||
" Object o1 = ImmutableSet.copyOf(ImmutableList.of());",
|
||||
" Object o2 = ImmutableSet.copyOf(ImmutableSet.of());",
|
||||
"",
|
||||
" Matcher matcher = Matchers.allOf(staticMethod());",
|
||||
"",
|
||||
" when(\"foo\".contains(\"f\")).thenAnswer(inv -> ImmutableSet.copyOf(ImmutableList.of(1)));",
|
||||
" }",
|
||||
"",
|
||||
" void bar(Publisher<Integer> publisher) {}",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static com.google.errorprone.matchers.Matchers.staticMethod;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.google.common.collect.ImmutableCollection;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.errorprone.matchers.Matcher;
|
||||
import com.google.errorprone.matchers.Matchers;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import org.reactivestreams.Publisher;
|
||||
import reactor.adapter.rxjava.RxJava2Adapter;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public final class A {
|
||||
public void m() {
|
||||
ImmutableSet<Object> set1 = ImmutableSet.of();
|
||||
ImmutableSet<Object> set2 = ImmutableSet.copyOf(ImmutableList.of());
|
||||
|
||||
ImmutableCollection<Integer> list1 = ImmutableList.of(1);
|
||||
ImmutableCollection<Integer> list2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1)));
|
||||
|
||||
Collection<Integer> c1 = ImmutableSet.of(1);
|
||||
Collection<Integer> c2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1)));
|
||||
|
||||
Flux<Integer> f1 = Flux.just(1).flatMap(e -> Flux.just(2));
|
||||
Flux<Integer> f2 = Flux.just(3);
|
||||
Publisher<Integer> f3 = Flux.just(4);
|
||||
Publisher<Integer> f4 = Flux.just(5);
|
||||
Publisher<Integer> f5 = Flux.just(6);
|
||||
|
||||
Mono<Integer> m1 = Mono.just(7);
|
||||
Publisher<Integer> m2 = Mono.just(8);
|
||||
|
||||
bar(Flux.just(9));
|
||||
bar(Mono.just(10));
|
||||
|
||||
Object o1 = ImmutableSet.copyOf(ImmutableList.of());
|
||||
Object o2 = ImmutableSet.of();
|
||||
|
||||
Matcher matcher = staticMethod();
|
||||
|
||||
when("foo".contains("f")).thenAnswer(inv -> ImmutableSet.copyOf(ImmutableList.of(1)));
|
||||
}
|
||||
|
||||
void bar(Publisher<Integer> publisher) {}
|
||||
}
|
||||
""")
|
||||
"import static com.google.errorprone.matchers.Matchers.staticMethod;",
|
||||
"import static org.mockito.Mockito.when;",
|
||||
"",
|
||||
"import com.google.common.collect.ImmutableCollection;",
|
||||
"import com.google.common.collect.ImmutableList;",
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import com.google.errorprone.matchers.Matcher;",
|
||||
"import com.google.errorprone.matchers.Matchers;",
|
||||
"import java.util.ArrayList;",
|
||||
"import java.util.Collection;",
|
||||
"import org.reactivestreams.Publisher;",
|
||||
"import reactor.adapter.rxjava.RxJava2Adapter;",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"import reactor.core.publisher.Mono;",
|
||||
"",
|
||||
"public final class A {",
|
||||
" public void m() {",
|
||||
" ImmutableSet<Object> set1 = ImmutableSet.of();",
|
||||
" ImmutableSet<Object> set2 = ImmutableSet.copyOf(ImmutableList.of());",
|
||||
"",
|
||||
" ImmutableCollection<Integer> list1 = ImmutableList.of(1);",
|
||||
" ImmutableCollection<Integer> list2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1)));",
|
||||
"",
|
||||
" Collection<Integer> c1 = ImmutableSet.of(1);",
|
||||
" Collection<Integer> c2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1)));",
|
||||
"",
|
||||
" Flux<Integer> f1 = Flux.just(1).flatMap(e -> Flux.just(2));",
|
||||
" Flux<Integer> f2 = Flux.just(3);",
|
||||
" Publisher<Integer> f3 = Flux.just(4);",
|
||||
" Publisher<Integer> f4 = Flux.just(5);",
|
||||
" Publisher<Integer> f5 = Flux.just(6);",
|
||||
"",
|
||||
" Mono<Integer> m1 = Mono.just(7);",
|
||||
" Publisher<Integer> m2 = Mono.just(8);",
|
||||
"",
|
||||
" bar(Flux.just(9));",
|
||||
" bar(Mono.just(10));",
|
||||
"",
|
||||
" Object o1 = ImmutableSet.copyOf(ImmutableList.of());",
|
||||
" Object o2 = ImmutableSet.of();",
|
||||
"",
|
||||
" Matcher matcher = staticMethod();",
|
||||
"",
|
||||
" when(\"foo\".contains(\"f\")).thenAnswer(inv -> ImmutableSet.copyOf(ImmutableList.of(1)));",
|
||||
" }",
|
||||
"",
|
||||
" void bar(Publisher<Integer> publisher) {}",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
|
||||
@@ -301,42 +295,38 @@ final class IdentityConversionTest {
|
||||
.setFixChooser(FixChoosers.SECOND)
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import com.google.common.collect.ImmutableCollection;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public final class A {
|
||||
public void m() {
|
||||
ImmutableSet<Object> set1 = ImmutableSet.copyOf(ImmutableSet.of());
|
||||
ImmutableSet<Object> set2 = ImmutableSet.copyOf(ImmutableList.of());
|
||||
|
||||
ImmutableCollection<Integer> list1 = ImmutableList.copyOf(ImmutableList.of(1));
|
||||
ImmutableCollection<Integer> list2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1)));
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import com.google.common.collect.ImmutableCollection;",
|
||||
"import com.google.common.collect.ImmutableList;",
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import java.util.ArrayList;",
|
||||
"",
|
||||
"public final class A {",
|
||||
" public void m() {",
|
||||
" ImmutableSet<Object> set1 = ImmutableSet.copyOf(ImmutableSet.of());",
|
||||
" ImmutableSet<Object> set2 = ImmutableSet.copyOf(ImmutableList.of());",
|
||||
"",
|
||||
" ImmutableCollection<Integer> list1 = ImmutableList.copyOf(ImmutableList.of(1));",
|
||||
" ImmutableCollection<Integer> list2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1)));",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import com.google.common.collect.ImmutableCollection;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public final class A {
|
||||
public void m() {
|
||||
@SuppressWarnings("IdentityConversion")
|
||||
ImmutableSet<Object> set1 = ImmutableSet.copyOf(ImmutableSet.of());
|
||||
ImmutableSet<Object> set2 = ImmutableSet.copyOf(ImmutableList.of());
|
||||
|
||||
@SuppressWarnings("IdentityConversion")
|
||||
ImmutableCollection<Integer> list1 = ImmutableList.copyOf(ImmutableList.of(1));
|
||||
ImmutableCollection<Integer> list2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1)));
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import com.google.common.collect.ImmutableCollection;",
|
||||
"import com.google.common.collect.ImmutableList;",
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import java.util.ArrayList;",
|
||||
"",
|
||||
"public final class A {",
|
||||
" public void m() {",
|
||||
" @SuppressWarnings(\"IdentityConversion\")",
|
||||
" ImmutableSet<Object> set1 = ImmutableSet.copyOf(ImmutableSet.of());",
|
||||
" ImmutableSet<Object> set2 = ImmutableSet.copyOf(ImmutableList.of());",
|
||||
"",
|
||||
" @SuppressWarnings(\"IdentityConversion\")",
|
||||
" ImmutableCollection<Integer> list1 = ImmutableList.copyOf(ImmutableList.of(1));",
|
||||
" ImmutableCollection<Integer> list2 = ImmutableList.copyOf(new ArrayList<>(ImmutableList.of(1)));",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,96 +11,94 @@ final class ImmutablesSortedSetComparatorTest {
|
||||
CompilationTestHelper.newInstance(ImmutablesSortedSetComparator.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import com.google.common.collect.ContiguousSet;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
import java.util.NavigableSet;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import org.immutables.value.Value;
|
||||
|
||||
interface A {
|
||||
@Value.Immutable
|
||||
interface ImmutableInterface {
|
||||
Set<String> set();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
SortedSet<String> sortedSet();
|
||||
|
||||
@Value.NaturalOrder
|
||||
SortedSet<String> sortedSet2();
|
||||
}
|
||||
|
||||
@Value.Modifiable
|
||||
interface ModifiableInterfaceWithDefaults {
|
||||
@Value.Default
|
||||
default Set<Integer> set() {
|
||||
return new TreeSet<>();
|
||||
}
|
||||
|
||||
@Value.Default
|
||||
// BUG: Diagnostic contains:
|
||||
default NavigableSet<Integer> navigableSet() {
|
||||
return new TreeSet<>();
|
||||
}
|
||||
|
||||
@Value.Default
|
||||
@Value.ReverseOrder
|
||||
default NavigableSet<Integer> navigableSet2() {
|
||||
return new TreeSet<>();
|
||||
}
|
||||
|
||||
default NavigableSet<Integer> nonPropertyNavigableSet() {
|
||||
return new TreeSet<>();
|
||||
}
|
||||
}
|
||||
|
||||
interface NonImmutablesInterface {
|
||||
SortedSet<String> sortedSet();
|
||||
}
|
||||
|
||||
@Value.Immutable
|
||||
abstract class AbstractImmutableWithDefaults {
|
||||
@Value.Default
|
||||
ImmutableSet<Integer> immutableSet() {
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
|
||||
@Value.Default
|
||||
// BUG: Diagnostic contains:
|
||||
ImmutableSortedSet<String> immutableSortedSet() {
|
||||
return ImmutableSortedSet.of();
|
||||
}
|
||||
|
||||
@Value.Default
|
||||
@Value.NaturalOrder
|
||||
ImmutableSortedSet<String> immutableSortedSet2() {
|
||||
return ImmutableSortedSet.of();
|
||||
}
|
||||
|
||||
ImmutableSortedSet<String> nonPropertyImmutableSortedSet() {
|
||||
return ImmutableSortedSet.of();
|
||||
}
|
||||
}
|
||||
|
||||
@Value.Modifiable
|
||||
abstract class AbstractModifiable {
|
||||
abstract ImmutableSet<Integer> immutableSet();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
abstract ContiguousSet<Integer> contiguousSet();
|
||||
|
||||
@Value.ReverseOrder
|
||||
abstract ContiguousSet<Integer> contiguousSet2();
|
||||
}
|
||||
|
||||
abstract class AbstractNonImmutables {
|
||||
abstract SortedSet<Integer> sortedSet();
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import com.google.common.collect.ContiguousSet;",
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import com.google.common.collect.ImmutableSortedSet;",
|
||||
"import java.util.NavigableSet;",
|
||||
"import java.util.Set;",
|
||||
"import java.util.SortedSet;",
|
||||
"import java.util.TreeSet;",
|
||||
"import org.immutables.value.Value;",
|
||||
"",
|
||||
"interface A {",
|
||||
" @Value.Immutable",
|
||||
" interface ImmutableInterface {",
|
||||
" Set<String> set();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" SortedSet<String> sortedSet();",
|
||||
"",
|
||||
" @Value.NaturalOrder",
|
||||
" SortedSet<String> sortedSet2();",
|
||||
" }",
|
||||
"",
|
||||
" @Value.Modifiable",
|
||||
" interface ModifiableInterfaceWithDefaults {",
|
||||
" @Value.Default",
|
||||
" default Set<Integer> set() {",
|
||||
" return new TreeSet<>();",
|
||||
" }",
|
||||
"",
|
||||
" @Value.Default",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" default NavigableSet<Integer> navigableSet() {",
|
||||
" return new TreeSet<>();",
|
||||
" }",
|
||||
"",
|
||||
" @Value.Default",
|
||||
" @Value.ReverseOrder",
|
||||
" default NavigableSet<Integer> navigableSet2() {",
|
||||
" return new TreeSet<>();",
|
||||
" }",
|
||||
"",
|
||||
" default NavigableSet<Integer> nonPropertyNavigableSet() {",
|
||||
" return new TreeSet<>();",
|
||||
" }",
|
||||
" }",
|
||||
"",
|
||||
" interface NonImmutablesInterface {",
|
||||
" SortedSet<String> sortedSet();",
|
||||
" }",
|
||||
"",
|
||||
" @Value.Immutable",
|
||||
" abstract class AbstractImmutableWithDefaults {",
|
||||
" @Value.Default",
|
||||
" ImmutableSet<Integer> immutableSet() {",
|
||||
" return ImmutableSet.of();",
|
||||
" }",
|
||||
"",
|
||||
" @Value.Default",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableSortedSet<String> immutableSortedSet() {",
|
||||
" return ImmutableSortedSet.of();",
|
||||
" }",
|
||||
"",
|
||||
" @Value.Default",
|
||||
" @Value.NaturalOrder",
|
||||
" ImmutableSortedSet<String> immutableSortedSet2() {",
|
||||
" return ImmutableSortedSet.of();",
|
||||
" }",
|
||||
"",
|
||||
" ImmutableSortedSet<String> nonPropertyImmutableSortedSet() {",
|
||||
" return ImmutableSortedSet.of();",
|
||||
" }",
|
||||
" }",
|
||||
"",
|
||||
" @Value.Modifiable",
|
||||
" abstract class AbstractModifiable {",
|
||||
" abstract ImmutableSet<Integer> immutableSet();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" abstract ContiguousSet<Integer> contiguousSet();",
|
||||
"",
|
||||
" @Value.ReverseOrder",
|
||||
" abstract ContiguousSet<Integer> contiguousSet2();",
|
||||
" }",
|
||||
"",
|
||||
" abstract class AbstractNonImmutables {",
|
||||
" abstract SortedSet<Integer> sortedSet();",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -109,40 +107,36 @@ final class ImmutablesSortedSetComparatorTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(ImmutablesSortedSetComparator.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
import java.util.SortedSet;
|
||||
import org.immutables.value.Value;
|
||||
|
||||
@Value.Immutable
|
||||
abstract class A {
|
||||
abstract ImmutableSortedSet<String> sortedSet();
|
||||
|
||||
@Value.Modifiable
|
||||
interface B {
|
||||
SortedSet<String> sortedSet();
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import com.google.common.collect.ImmutableSortedSet;",
|
||||
"import java.util.SortedSet;",
|
||||
"import org.immutables.value.Value;",
|
||||
"",
|
||||
"@Value.Immutable",
|
||||
"abstract class A {",
|
||||
" abstract ImmutableSortedSet<String> sortedSet();",
|
||||
"",
|
||||
" @Value.Modifiable",
|
||||
" interface B {",
|
||||
" SortedSet<String> sortedSet();",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
import java.util.SortedSet;
|
||||
import org.immutables.value.Value;
|
||||
|
||||
@Value.Immutable
|
||||
abstract class A {
|
||||
@Value.NaturalOrder
|
||||
abstract ImmutableSortedSet<String> sortedSet();
|
||||
|
||||
@Value.Modifiable
|
||||
interface B {
|
||||
@Value.NaturalOrder
|
||||
SortedSet<String> sortedSet();
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import com.google.common.collect.ImmutableSortedSet;",
|
||||
"import java.util.SortedSet;",
|
||||
"import org.immutables.value.Value;",
|
||||
"",
|
||||
"@Value.Immutable",
|
||||
"abstract class A {",
|
||||
" @Value.NaturalOrder",
|
||||
" abstract ImmutableSortedSet<String> sortedSet();",
|
||||
"",
|
||||
" @Value.Modifiable",
|
||||
" interface B {",
|
||||
" @Value.NaturalOrder",
|
||||
" SortedSet<String> sortedSet();",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
|
||||
@@ -151,37 +145,33 @@ final class ImmutablesSortedSetComparatorTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(ImmutablesSortedSetComparator.class, getClass())
|
||||
.addInputLines(
|
||||
"MySpringService.java",
|
||||
"""
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
||||
class MySpringService {
|
||||
MySpringService(@Value("${someProperty}") String prop) {}
|
||||
;
|
||||
|
||||
@org.immutables.value.Value.Immutable
|
||||
interface A {
|
||||
ImmutableSortedSet<String> sortedSet();
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import com.google.common.collect.ImmutableSortedSet;",
|
||||
"import org.springframework.beans.factory.annotation.Value;",
|
||||
"",
|
||||
"class MySpringService {",
|
||||
" MySpringService(@Value(\"${someProperty}\") String prop) {}",
|
||||
" ;",
|
||||
"",
|
||||
" @org.immutables.value.Value.Immutable",
|
||||
" interface A {",
|
||||
" ImmutableSortedSet<String> sortedSet();",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"MySpringService.java",
|
||||
"""
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
||||
class MySpringService {
|
||||
MySpringService(@Value("${someProperty}") String prop) {}
|
||||
;
|
||||
|
||||
@org.immutables.value.Value.Immutable
|
||||
interface A {
|
||||
@org.immutables.value.Value.NaturalOrder
|
||||
ImmutableSortedSet<String> sortedSet();
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import com.google.common.collect.ImmutableSortedSet;",
|
||||
"import org.springframework.beans.factory.annotation.Value;",
|
||||
"",
|
||||
"class MySpringService {",
|
||||
" MySpringService(@Value(\"${someProperty}\") String prop) {}",
|
||||
" ;",
|
||||
"",
|
||||
" @org.immutables.value.Value.Immutable",
|
||||
" interface A {",
|
||||
" @org.immutables.value.Value.NaturalOrder",
|
||||
" ImmutableSortedSet<String> sortedSet();",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,34 +11,32 @@ final class IsInstanceLambdaUsageTest {
|
||||
CompilationTestHelper.newInstance(IsInstanceLambdaUsage.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import java.util.stream.Stream;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
Integer localVariable = 0;
|
||||
|
||||
Stream.of(0).map(i -> i);
|
||||
Stream.of(1).map(i -> i + 1);
|
||||
Stream.of(2).filter(Integer.class::isInstance);
|
||||
Stream.of(3).filter(i -> i.getClass() instanceof Class);
|
||||
Stream.of(4).filter(i -> localVariable instanceof Integer);
|
||||
// XXX: Ideally this case is also flagged. Pick this up in the context of merging the
|
||||
// `IsInstanceLambdaUsage` and `MethodReferenceUsage` checks, or introduce a separate check that
|
||||
// simplifies unnecessary block lambda expressions.
|
||||
Stream.of(5)
|
||||
.filter(
|
||||
i -> {
|
||||
return i instanceof Integer;
|
||||
});
|
||||
Flux.just(6, "foo").distinctUntilChanged(v -> v, (a, b) -> a instanceof Integer);
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Stream.of(7).filter(i -> i instanceof Integer);
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import java.util.stream.Stream;",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Integer localVariable = 0;",
|
||||
"",
|
||||
" Stream.of(0).map(i -> i);",
|
||||
" Stream.of(1).map(i -> i + 1);",
|
||||
" Stream.of(2).filter(Integer.class::isInstance);",
|
||||
" Stream.of(3).filter(i -> i.getClass() instanceof Class);",
|
||||
" Stream.of(4).filter(i -> localVariable instanceof Integer);",
|
||||
" // XXX: Ideally this case is also flagged. Pick this up in the context of merging the",
|
||||
" // `IsInstanceLambdaUsage` and `MethodReferenceUsage` checks, or introduce a separate check that",
|
||||
" // simplifies unnecessary block lambda expressions.",
|
||||
" Stream.of(5)",
|
||||
" .filter(",
|
||||
" i -> {",
|
||||
" return i instanceof Integer;",
|
||||
" });",
|
||||
" Flux.just(6, \"foo\").distinctUntilChanged(v -> v, (a, b) -> a instanceof Integer);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Stream.of(7).filter(i -> i instanceof Integer);",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -47,26 +45,22 @@ final class IsInstanceLambdaUsageTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(IsInstanceLambdaUsage.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import java.util.stream.Stream;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
Stream.of(1).filter(i -> i instanceof Integer);
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import java.util.stream.Stream;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Stream.of(1).filter(i -> i instanceof Integer);",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import java.util.stream.Stream;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
Stream.of(1).filter(Integer.class::isInstance);
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import java.util.stream.Stream;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Stream.of(1).filter(Integer.class::isInstance);",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,85 +11,83 @@ final class JUnitClassModifiersTest {
|
||||
CompilationTestHelper.newInstance(JUnitClassModifiers.class, getClass())
|
||||
.addSourceLines(
|
||||
"Container.java",
|
||||
"""
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.springframework.boot.test.context.TestConfiguration;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
class Container {
|
||||
final class FinalAndPackagePrivate {
|
||||
@Test
|
||||
void foo() {}
|
||||
}
|
||||
|
||||
final class FinalAndPackagePrivateWithCustomTestMethod {
|
||||
@ParameterizedTest
|
||||
void foo() {}
|
||||
}
|
||||
|
||||
public abstract class Abstract {
|
||||
@Test
|
||||
void foo() {}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
class WithConfigurationAnnotation {
|
||||
@Test
|
||||
void foo() {}
|
||||
}
|
||||
|
||||
@TestConfiguration
|
||||
class WithConfigurationMetaAnnotation {
|
||||
@Test
|
||||
void foo() {}
|
||||
}
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
private final class Private {
|
||||
@Test
|
||||
void foo() {}
|
||||
}
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
protected final class Protected {
|
||||
@Test
|
||||
void foo() {}
|
||||
}
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
public final class Public {
|
||||
@Test
|
||||
void foo() {}
|
||||
}
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
class NonFinal {
|
||||
@Test
|
||||
void foo() {}
|
||||
}
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
class NonFinalWithCustomTestMethod {
|
||||
@ParameterizedTest
|
||||
void foo() {}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
// BUG: Diagnostic contains:
|
||||
public class PublicWithConfigurationAnnotation {
|
||||
@Test
|
||||
void foo() {}
|
||||
}
|
||||
|
||||
@TestConfiguration
|
||||
// BUG: Diagnostic contains:
|
||||
protected class ProtectedWithConfigurationMetaAnnotation {
|
||||
@Test
|
||||
void foo() {}
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import org.junit.jupiter.api.Test;",
|
||||
"import org.junit.jupiter.params.ParameterizedTest;",
|
||||
"import org.springframework.boot.test.context.TestConfiguration;",
|
||||
"import org.springframework.context.annotation.Configuration;",
|
||||
"",
|
||||
"class Container {",
|
||||
" final class FinalAndPackagePrivate {",
|
||||
" @Test",
|
||||
" void foo() {}",
|
||||
" }",
|
||||
"",
|
||||
" final class FinalAndPackagePrivateWithCustomTestMethod {",
|
||||
" @ParameterizedTest",
|
||||
" void foo() {}",
|
||||
" }",
|
||||
"",
|
||||
" public abstract class Abstract {",
|
||||
" @Test",
|
||||
" void foo() {}",
|
||||
" }",
|
||||
"",
|
||||
" @Configuration",
|
||||
" class WithConfigurationAnnotation {",
|
||||
" @Test",
|
||||
" void foo() {}",
|
||||
" }",
|
||||
"",
|
||||
" @TestConfiguration",
|
||||
" class WithConfigurationMetaAnnotation {",
|
||||
" @Test",
|
||||
" void foo() {}",
|
||||
" }",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" private final class Private {",
|
||||
" @Test",
|
||||
" void foo() {}",
|
||||
" }",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" protected final class Protected {",
|
||||
" @Test",
|
||||
" void foo() {}",
|
||||
" }",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" public final class Public {",
|
||||
" @Test",
|
||||
" void foo() {}",
|
||||
" }",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" class NonFinal {",
|
||||
" @Test",
|
||||
" void foo() {}",
|
||||
" }",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" class NonFinalWithCustomTestMethod {",
|
||||
" @ParameterizedTest",
|
||||
" void foo() {}",
|
||||
" }",
|
||||
"",
|
||||
" @Configuration",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" public class PublicWithConfigurationAnnotation {",
|
||||
" @Test",
|
||||
" void foo() {}",
|
||||
" }",
|
||||
"",
|
||||
" @TestConfiguration",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" protected class ProtectedWithConfigurationMetaAnnotation {",
|
||||
" @Test",
|
||||
" void foo() {}",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -98,38 +96,34 @@ final class JUnitClassModifiersTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(JUnitClassModifiers.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
public class A {
|
||||
@Test
|
||||
void foo() {}
|
||||
|
||||
@Configuration
|
||||
private static class B {
|
||||
@Test
|
||||
void bar() {}
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import org.junit.jupiter.api.Test;",
|
||||
"import org.springframework.context.annotation.Configuration;",
|
||||
"",
|
||||
"public class A {",
|
||||
" @Test",
|
||||
" void foo() {}",
|
||||
"",
|
||||
" @Configuration",
|
||||
" private static class B {",
|
||||
" @Test",
|
||||
" void bar() {}",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
final class A {
|
||||
@Test
|
||||
void foo() {}
|
||||
|
||||
@Configuration
|
||||
static class B {
|
||||
@Test
|
||||
void bar() {}
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import org.junit.jupiter.api.Test;",
|
||||
"import org.springframework.context.annotation.Configuration;",
|
||||
"",
|
||||
"final class A {",
|
||||
" @Test",
|
||||
" void foo() {}",
|
||||
"",
|
||||
" @Configuration",
|
||||
" static class B {",
|
||||
" @Test",
|
||||
" void bar() {}",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,338 +11,332 @@ final class JUnitMethodDeclarationTest {
|
||||
CompilationTestHelper.newInstance(JUnitMethodDeclaration.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static org.junit.jupiter.params.provider.Arguments.*;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
|
||||
class A {
|
||||
{
|
||||
arguments();
|
||||
}
|
||||
|
||||
@BeforeAll
|
||||
void setUp1() {}
|
||||
|
||||
@BeforeAll
|
||||
// BUG: Diagnostic contains:
|
||||
public void setUp2() {}
|
||||
|
||||
@BeforeAll
|
||||
// BUG: Diagnostic contains:
|
||||
protected void setUp3() {}
|
||||
|
||||
@BeforeAll
|
||||
// BUG: Diagnostic contains:
|
||||
private void setUp4() {}
|
||||
|
||||
@BeforeEach
|
||||
void setup5() {}
|
||||
|
||||
@BeforeEach
|
||||
// BUG: Diagnostic contains:
|
||||
public void setUp6() {}
|
||||
|
||||
@BeforeEach
|
||||
// BUG: Diagnostic contains:
|
||||
protected void setUp7() {}
|
||||
|
||||
@BeforeEach
|
||||
// BUG: Diagnostic contains:
|
||||
private void setUp8() {}
|
||||
|
||||
@AfterEach
|
||||
void tearDown1() {}
|
||||
|
||||
@AfterEach
|
||||
// BUG: Diagnostic contains:
|
||||
public void tearDown2() {}
|
||||
|
||||
@AfterEach
|
||||
// BUG: Diagnostic contains:
|
||||
protected void tearDown3() {}
|
||||
|
||||
@AfterEach
|
||||
// BUG: Diagnostic contains:
|
||||
private void tearDown4() {}
|
||||
|
||||
@AfterAll
|
||||
void tearDown5() {}
|
||||
|
||||
@AfterAll
|
||||
// BUG: Diagnostic contains:
|
||||
public void tearDown6() {}
|
||||
|
||||
@AfterAll
|
||||
// BUG: Diagnostic contains:
|
||||
protected void tearDown7() {}
|
||||
|
||||
@AfterAll
|
||||
// BUG: Diagnostic contains:
|
||||
private void tearDown8() {}
|
||||
|
||||
@Test
|
||||
void test() {}
|
||||
|
||||
@Test
|
||||
void method1() {}
|
||||
|
||||
@Test
|
||||
// BUG: Diagnostic contains:
|
||||
void testMethod2() {}
|
||||
|
||||
@Test
|
||||
// BUG: Diagnostic contains:
|
||||
public void method3() {}
|
||||
|
||||
@Test
|
||||
// BUG: Diagnostic contains:
|
||||
protected void method4() {}
|
||||
|
||||
@Test
|
||||
// BUG: Diagnostic contains:
|
||||
private void method5() {}
|
||||
|
||||
@ParameterizedTest
|
||||
void method6() {}
|
||||
|
||||
@ParameterizedTest
|
||||
// BUG: Diagnostic contains:
|
||||
void testMethod7() {}
|
||||
|
||||
@ParameterizedTest
|
||||
// BUG: Diagnostic contains:
|
||||
public void method8() {}
|
||||
|
||||
@ParameterizedTest
|
||||
// BUG: Diagnostic contains:
|
||||
protected void method9() {}
|
||||
|
||||
@ParameterizedTest
|
||||
// BUG: Diagnostic contains:
|
||||
private void method10() {}
|
||||
|
||||
@BeforeEach
|
||||
@BeforeAll
|
||||
@AfterEach
|
||||
@AfterAll
|
||||
void testNonTestMethod1() {}
|
||||
|
||||
public void testNonTestMethod2() {}
|
||||
|
||||
protected void testNonTestMethod3() {}
|
||||
|
||||
private void testNonTestMethod4() {}
|
||||
|
||||
@Test
|
||||
void test5() {}
|
||||
|
||||
@Test
|
||||
// BUG: Diagnostic contains: (but note that a method named `toString` is already defined in this
|
||||
// class or a supertype)
|
||||
void testToString() {}
|
||||
|
||||
@Test
|
||||
// BUG: Diagnostic contains: (but note that a method named `overload` is already defined in this
|
||||
// class or a supertype)
|
||||
void testOverload() {}
|
||||
|
||||
void overload() {}
|
||||
|
||||
@Test
|
||||
// BUG: Diagnostic contains: (but note that another method named `arguments` is in scope)
|
||||
void testArguments() {
|
||||
arguments();
|
||||
}
|
||||
|
||||
@Test
|
||||
// BUG: Diagnostic contains: (but note that `public` is not a valid identifier)
|
||||
void testPublic() {}
|
||||
|
||||
@Test
|
||||
// BUG: Diagnostic contains: (but note that `null` is not a valid identifier)
|
||||
void testNull() {}
|
||||
|
||||
@Test
|
||||
// BUG: Diagnostic contains:
|
||||
void testRecord() {}
|
||||
|
||||
@Test
|
||||
// BUG: Diagnostic contains:
|
||||
void testMethodThatIsOverriddenWithoutOverrideAnnotation() {}
|
||||
}
|
||||
""")
|
||||
"import static org.junit.jupiter.params.provider.Arguments.*;",
|
||||
"",
|
||||
"import org.junit.jupiter.api.AfterAll;",
|
||||
"import org.junit.jupiter.api.AfterEach;",
|
||||
"import org.junit.jupiter.api.BeforeAll;",
|
||||
"import org.junit.jupiter.api.BeforeEach;",
|
||||
"import org.junit.jupiter.api.Test;",
|
||||
"import org.junit.jupiter.params.ParameterizedTest;",
|
||||
"",
|
||||
"class A {",
|
||||
" {",
|
||||
" arguments();",
|
||||
" }",
|
||||
"",
|
||||
" @BeforeAll",
|
||||
" void setUp1() {}",
|
||||
"",
|
||||
" @BeforeAll",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" public void setUp2() {}",
|
||||
"",
|
||||
" @BeforeAll",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" protected void setUp3() {}",
|
||||
"",
|
||||
" @BeforeAll",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" private void setUp4() {}",
|
||||
"",
|
||||
" @BeforeEach",
|
||||
" void setup5() {}",
|
||||
"",
|
||||
" @BeforeEach",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" public void setUp6() {}",
|
||||
"",
|
||||
" @BeforeEach",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" protected void setUp7() {}",
|
||||
"",
|
||||
" @BeforeEach",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" private void setUp8() {}",
|
||||
"",
|
||||
" @AfterEach",
|
||||
" void tearDown1() {}",
|
||||
"",
|
||||
" @AfterEach",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" public void tearDown2() {}",
|
||||
"",
|
||||
" @AfterEach",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" protected void tearDown3() {}",
|
||||
"",
|
||||
" @AfterEach",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" private void tearDown4() {}",
|
||||
"",
|
||||
" @AfterAll",
|
||||
" void tearDown5() {}",
|
||||
"",
|
||||
" @AfterAll",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" public void tearDown6() {}",
|
||||
"",
|
||||
" @AfterAll",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" protected void tearDown7() {}",
|
||||
"",
|
||||
" @AfterAll",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" private void tearDown8() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" void test() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" void method1() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" void testMethod2() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" public void method3() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" protected void method4() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" private void method5() {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" void method6() {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" void testMethod7() {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" public void method8() {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" protected void method9() {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" private void method10() {}",
|
||||
"",
|
||||
" @BeforeEach",
|
||||
" @BeforeAll",
|
||||
" @AfterEach",
|
||||
" @AfterAll",
|
||||
" void testNonTestMethod1() {}",
|
||||
"",
|
||||
" public void testNonTestMethod2() {}",
|
||||
"",
|
||||
" protected void testNonTestMethod3() {}",
|
||||
"",
|
||||
" private void testNonTestMethod4() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" void test5() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" // BUG: Diagnostic contains: (but note that a method named `toString` is already defined in this",
|
||||
" // class or a supertype)",
|
||||
" void testToString() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" // BUG: Diagnostic contains: (but note that a method named `overload` is already defined in this",
|
||||
" // class or a supertype)",
|
||||
" void testOverload() {}",
|
||||
"",
|
||||
" void overload() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" // BUG: Diagnostic contains: (but note that another method named `arguments` is in scope)",
|
||||
" void testArguments() {",
|
||||
" arguments();",
|
||||
" }",
|
||||
"",
|
||||
" @Test",
|
||||
" // BUG: Diagnostic contains: (but note that `public` is not a valid identifier)",
|
||||
" void testPublic() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" // BUG: Diagnostic contains: (but note that `null` is not a valid identifier)",
|
||||
" void testNull() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" void testRecord() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" void testMethodThatIsOverriddenWithoutOverrideAnnotation() {}",
|
||||
"}")
|
||||
.addSourceLines(
|
||||
"B.java",
|
||||
"""
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
|
||||
class B extends A {
|
||||
@Override
|
||||
@BeforeAll
|
||||
void setUp1() {}
|
||||
|
||||
@Override
|
||||
@BeforeAll
|
||||
public void setUp2() {}
|
||||
|
||||
@Override
|
||||
@BeforeAll
|
||||
protected void setUp3() {}
|
||||
|
||||
@Override
|
||||
@BeforeEach
|
||||
void setup5() {}
|
||||
|
||||
@Override
|
||||
@BeforeEach
|
||||
public void setUp6() {}
|
||||
|
||||
@Override
|
||||
@BeforeEach
|
||||
protected void setUp7() {}
|
||||
|
||||
@Override
|
||||
@AfterEach
|
||||
void tearDown1() {}
|
||||
|
||||
@Override
|
||||
@AfterEach
|
||||
public void tearDown2() {}
|
||||
|
||||
@Override
|
||||
@AfterEach
|
||||
protected void tearDown3() {}
|
||||
|
||||
@Override
|
||||
@AfterAll
|
||||
void tearDown5() {}
|
||||
|
||||
@Override
|
||||
@AfterAll
|
||||
public void tearDown6() {}
|
||||
|
||||
@Override
|
||||
@AfterAll
|
||||
protected void tearDown7() {}
|
||||
|
||||
@Override
|
||||
@Test
|
||||
void test() {}
|
||||
|
||||
@Override
|
||||
@Test
|
||||
void method1() {}
|
||||
|
||||
@Override
|
||||
@Test
|
||||
void testMethod2() {}
|
||||
|
||||
@Override
|
||||
@Test
|
||||
public void method3() {}
|
||||
|
||||
@Override
|
||||
@Test
|
||||
protected void method4() {}
|
||||
|
||||
@Override
|
||||
@ParameterizedTest
|
||||
void method6() {}
|
||||
|
||||
@Override
|
||||
@ParameterizedTest
|
||||
void testMethod7() {}
|
||||
|
||||
@Override
|
||||
@ParameterizedTest
|
||||
public void method8() {}
|
||||
|
||||
@Override
|
||||
@ParameterizedTest
|
||||
protected void method9() {}
|
||||
|
||||
@Override
|
||||
@BeforeEach
|
||||
@BeforeAll
|
||||
@AfterEach
|
||||
@AfterAll
|
||||
void testNonTestMethod1() {}
|
||||
|
||||
@Override
|
||||
public void testNonTestMethod2() {}
|
||||
|
||||
@Override
|
||||
protected void testNonTestMethod3() {}
|
||||
|
||||
@Override
|
||||
@Test
|
||||
void test5() {}
|
||||
|
||||
@Override
|
||||
@Test
|
||||
void testToString() {}
|
||||
|
||||
@Override
|
||||
@Test
|
||||
void testOverload() {}
|
||||
|
||||
@Override
|
||||
void overload() {}
|
||||
|
||||
@Override
|
||||
@Test
|
||||
void testArguments() {}
|
||||
|
||||
@Override
|
||||
@Test
|
||||
void testPublic() {}
|
||||
|
||||
@Override
|
||||
@Test
|
||||
void testNull() {}
|
||||
|
||||
@Override
|
||||
@Test
|
||||
void testRecord() {}
|
||||
|
||||
@Test
|
||||
void testMethodThatIsOverriddenWithoutOverrideAnnotation() {}
|
||||
}
|
||||
""")
|
||||
"import org.junit.jupiter.api.AfterAll;",
|
||||
"import org.junit.jupiter.api.AfterEach;",
|
||||
"import org.junit.jupiter.api.BeforeAll;",
|
||||
"import org.junit.jupiter.api.BeforeEach;",
|
||||
"import org.junit.jupiter.api.Test;",
|
||||
"import org.junit.jupiter.params.ParameterizedTest;",
|
||||
"",
|
||||
"class B extends A {",
|
||||
" @Override",
|
||||
" @BeforeAll",
|
||||
" void setUp1() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" @BeforeAll",
|
||||
" public void setUp2() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" @BeforeAll",
|
||||
" protected void setUp3() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" @BeforeEach",
|
||||
" void setup5() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" @BeforeEach",
|
||||
" public void setUp6() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" @BeforeEach",
|
||||
" protected void setUp7() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" @AfterEach",
|
||||
" void tearDown1() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" @AfterEach",
|
||||
" public void tearDown2() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" @AfterEach",
|
||||
" protected void tearDown3() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" @AfterAll",
|
||||
" void tearDown5() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" @AfterAll",
|
||||
" public void tearDown6() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" @AfterAll",
|
||||
" protected void tearDown7() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" @Test",
|
||||
" void test() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" @Test",
|
||||
" void method1() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" @Test",
|
||||
" void testMethod2() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" @Test",
|
||||
" public void method3() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" @Test",
|
||||
" protected void method4() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" @ParameterizedTest",
|
||||
" void method6() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" @ParameterizedTest",
|
||||
" void testMethod7() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" @ParameterizedTest",
|
||||
" public void method8() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" @ParameterizedTest",
|
||||
" protected void method9() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" @BeforeEach",
|
||||
" @BeforeAll",
|
||||
" @AfterEach",
|
||||
" @AfterAll",
|
||||
" void testNonTestMethod1() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" public void testNonTestMethod2() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" protected void testNonTestMethod3() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" @Test",
|
||||
" void test5() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" @Test",
|
||||
" void testToString() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" @Test",
|
||||
" void testOverload() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" void overload() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" @Test",
|
||||
" void testArguments() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" @Test",
|
||||
" void testPublic() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" @Test",
|
||||
" void testNull() {}",
|
||||
"",
|
||||
" @Override",
|
||||
" @Test",
|
||||
" void testRecord() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" void testMethodThatIsOverriddenWithoutOverrideAnnotation() {}",
|
||||
"}")
|
||||
.addSourceLines(
|
||||
"C.java",
|
||||
"""
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
abstract class C {
|
||||
@BeforeAll
|
||||
public void setUp() {}
|
||||
|
||||
@Test
|
||||
void testMethod1() {}
|
||||
|
||||
@AfterAll
|
||||
// BUG: Diagnostic contains:
|
||||
private void tearDown() {}
|
||||
|
||||
@Test
|
||||
// BUG: Diagnostic contains:
|
||||
final void testMethod2() {}
|
||||
}
|
||||
""")
|
||||
"import org.junit.jupiter.api.AfterAll;",
|
||||
"import org.junit.jupiter.api.BeforeAll;",
|
||||
"import org.junit.jupiter.api.Test;",
|
||||
"",
|
||||
"abstract class C {",
|
||||
" @BeforeAll",
|
||||
" public void setUp() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" void testMethod1() {}",
|
||||
"",
|
||||
" @AfterAll",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" private void tearDown() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" final void testMethod2() {}",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -351,130 +345,126 @@ final class JUnitMethodDeclarationTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(JUnitMethodDeclaration.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static org.junit.jupiter.params.provider.Arguments.arguments;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.RepeatedTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
|
||||
class A {
|
||||
{
|
||||
arguments();
|
||||
}
|
||||
|
||||
@BeforeAll
|
||||
public void setUp1() {}
|
||||
|
||||
@BeforeEach
|
||||
protected void setUp2() {}
|
||||
|
||||
@AfterEach
|
||||
private void setUp3() {}
|
||||
|
||||
@AfterAll
|
||||
private void setUp4() {}
|
||||
|
||||
@Test
|
||||
void testFoo() {}
|
||||
|
||||
@ParameterizedTest
|
||||
void testBar() {}
|
||||
|
||||
@Test
|
||||
public void baz() {}
|
||||
|
||||
@RepeatedTest(2)
|
||||
private void qux() {}
|
||||
|
||||
@ParameterizedTest
|
||||
protected void quux() {}
|
||||
|
||||
@Test
|
||||
public void testToString() {}
|
||||
|
||||
@Test
|
||||
public void testOverload() {}
|
||||
|
||||
void overload() {}
|
||||
|
||||
@Test
|
||||
protected void testArguments() {}
|
||||
|
||||
@Test
|
||||
private void testClass() {}
|
||||
|
||||
@Test
|
||||
private void testTrue() {}
|
||||
}
|
||||
""")
|
||||
"import static org.junit.jupiter.params.provider.Arguments.arguments;",
|
||||
"",
|
||||
"import org.junit.jupiter.api.AfterAll;",
|
||||
"import org.junit.jupiter.api.AfterEach;",
|
||||
"import org.junit.jupiter.api.BeforeAll;",
|
||||
"import org.junit.jupiter.api.BeforeEach;",
|
||||
"import org.junit.jupiter.api.RepeatedTest;",
|
||||
"import org.junit.jupiter.api.Test;",
|
||||
"import org.junit.jupiter.params.ParameterizedTest;",
|
||||
"",
|
||||
"class A {",
|
||||
" {",
|
||||
" arguments();",
|
||||
" }",
|
||||
"",
|
||||
" @BeforeAll",
|
||||
" public void setUp1() {}",
|
||||
"",
|
||||
" @BeforeEach",
|
||||
" protected void setUp2() {}",
|
||||
"",
|
||||
" @AfterEach",
|
||||
" private void setUp3() {}",
|
||||
"",
|
||||
" @AfterAll",
|
||||
" private void setUp4() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" void testFoo() {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" void testBar() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" public void baz() {}",
|
||||
"",
|
||||
" @RepeatedTest(2)",
|
||||
" private void qux() {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" protected void quux() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" public void testToString() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" public void testOverload() {}",
|
||||
"",
|
||||
" void overload() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" protected void testArguments() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" private void testClass() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" private void testTrue() {}",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static org.junit.jupiter.params.provider.Arguments.arguments;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.RepeatedTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
|
||||
class A {
|
||||
{
|
||||
arguments();
|
||||
}
|
||||
|
||||
@BeforeAll
|
||||
void setUp1() {}
|
||||
|
||||
@BeforeEach
|
||||
void setUp2() {}
|
||||
|
||||
@AfterEach
|
||||
void setUp3() {}
|
||||
|
||||
@AfterAll
|
||||
void setUp4() {}
|
||||
|
||||
@Test
|
||||
void foo() {}
|
||||
|
||||
@ParameterizedTest
|
||||
void bar() {}
|
||||
|
||||
@Test
|
||||
void baz() {}
|
||||
|
||||
@RepeatedTest(2)
|
||||
void qux() {}
|
||||
|
||||
@ParameterizedTest
|
||||
void quux() {}
|
||||
|
||||
@Test
|
||||
void testToString() {}
|
||||
|
||||
@Test
|
||||
void testOverload() {}
|
||||
|
||||
void overload() {}
|
||||
|
||||
@Test
|
||||
void testArguments() {}
|
||||
|
||||
@Test
|
||||
void testClass() {}
|
||||
|
||||
@Test
|
||||
void testTrue() {}
|
||||
}
|
||||
""")
|
||||
"import static org.junit.jupiter.params.provider.Arguments.arguments;",
|
||||
"",
|
||||
"import org.junit.jupiter.api.AfterAll;",
|
||||
"import org.junit.jupiter.api.AfterEach;",
|
||||
"import org.junit.jupiter.api.BeforeAll;",
|
||||
"import org.junit.jupiter.api.BeforeEach;",
|
||||
"import org.junit.jupiter.api.RepeatedTest;",
|
||||
"import org.junit.jupiter.api.Test;",
|
||||
"import org.junit.jupiter.params.ParameterizedTest;",
|
||||
"",
|
||||
"class A {",
|
||||
" {",
|
||||
" arguments();",
|
||||
" }",
|
||||
"",
|
||||
" @BeforeAll",
|
||||
" void setUp1() {}",
|
||||
"",
|
||||
" @BeforeEach",
|
||||
" void setUp2() {}",
|
||||
"",
|
||||
" @AfterEach",
|
||||
" void setUp3() {}",
|
||||
"",
|
||||
" @AfterAll",
|
||||
" void setUp4() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" void foo() {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" void bar() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" void baz() {}",
|
||||
"",
|
||||
" @RepeatedTest(2)",
|
||||
" void qux() {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" void quux() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" void testToString() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" void testOverload() {}",
|
||||
"",
|
||||
" void overload() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" void testArguments() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" void testClass() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" void testTrue() {}",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,27 +11,25 @@ final class JUnitNullaryParameterizedTestDeclarationTest {
|
||||
CompilationTestHelper.newInstance(JUnitNullaryParameterizedTestDeclaration.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
class A {
|
||||
void nonTest() {}
|
||||
|
||||
@Test
|
||||
void nonParameterizedTest() {}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(ints = {0, 1})
|
||||
void goodParameterizedTest(int someInt) {}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(ints = {0, 1})
|
||||
// BUG: Diagnostic contains:
|
||||
void nullaryParameterizedTest() {}
|
||||
}
|
||||
""")
|
||||
"import org.junit.jupiter.api.Test;",
|
||||
"import org.junit.jupiter.params.ParameterizedTest;",
|
||||
"import org.junit.jupiter.params.provider.ValueSource;",
|
||||
"",
|
||||
"class A {",
|
||||
" void nonTest() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" void nonParameterizedTest() {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @ValueSource(ints = {0, 1})",
|
||||
" void goodParameterizedTest(int someInt) {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @ValueSource(ints = {0, 1})",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" void nullaryParameterizedTest() {}",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -41,125 +39,117 @@ final class JUnitNullaryParameterizedTestDeclarationTest {
|
||||
JUnitNullaryParameterizedTestDeclaration.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ArgumentsProvider;
|
||||
import org.junit.jupiter.params.provider.ArgumentsSource;
|
||||
import org.junit.jupiter.params.provider.ArgumentsSources;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
class A {
|
||||
@ParameterizedTest
|
||||
void withoutArgumentSource() {}
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(ArgumentsProvider.class)
|
||||
void withCustomArgumentSource() {}
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSources({
|
||||
@ArgumentsSource(ArgumentsProvider.class),
|
||||
@ArgumentsSource(ArgumentsProvider.class)
|
||||
})
|
||||
void withCustomerArgumentSources() {}
|
||||
|
||||
/** Foo. */
|
||||
@ParameterizedTest
|
||||
@ValueSource(ints = {0, 1})
|
||||
void withValueSourceAndJavadoc() {}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("nonexistentMethod")
|
||||
@SuppressWarnings("foo")
|
||||
void withMethodSourceAndUnrelatedAnnotation() {}
|
||||
|
||||
@org.junit.jupiter.params.ParameterizedTest
|
||||
@ArgumentsSource(ArgumentsProvider.class)
|
||||
@ValueSource(ints = {0, 1})
|
||||
@MethodSource("nonexistentMethod")
|
||||
void withMultipleArgumentSourcesAndFullyQualifiedImport() {}
|
||||
|
||||
class NestedWithTestAnnotationFirst {
|
||||
@ParameterizedTest
|
||||
@ValueSource(ints = {0, 1})
|
||||
void withValueSource() {}
|
||||
}
|
||||
|
||||
class NestedWithTestAnnotationSecond {
|
||||
@ValueSource(ints = {0, 1})
|
||||
@ParameterizedTest
|
||||
void withValueSource() {}
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import org.junit.jupiter.params.ParameterizedTest;",
|
||||
"import org.junit.jupiter.params.provider.ArgumentsProvider;",
|
||||
"import org.junit.jupiter.params.provider.ArgumentsSource;",
|
||||
"import org.junit.jupiter.params.provider.ArgumentsSources;",
|
||||
"import org.junit.jupiter.params.provider.MethodSource;",
|
||||
"import org.junit.jupiter.params.provider.ValueSource;",
|
||||
"",
|
||||
"class A {",
|
||||
" @ParameterizedTest",
|
||||
" void withoutArgumentSource() {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @ArgumentsSource(ArgumentsProvider.class)",
|
||||
" void withCustomArgumentSource() {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @ArgumentsSources({",
|
||||
" @ArgumentsSource(ArgumentsProvider.class),",
|
||||
" @ArgumentsSource(ArgumentsProvider.class)",
|
||||
" })",
|
||||
" void withCustomerArgumentSources() {}",
|
||||
"",
|
||||
" /** Foo. */",
|
||||
" @ParameterizedTest",
|
||||
" @ValueSource(ints = {0, 1})",
|
||||
" void withValueSourceAndJavadoc() {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"nonexistentMethod\")",
|
||||
" @SuppressWarnings(\"foo\")",
|
||||
" void withMethodSourceAndUnrelatedAnnotation() {}",
|
||||
"",
|
||||
" @org.junit.jupiter.params.ParameterizedTest",
|
||||
" @ArgumentsSource(ArgumentsProvider.class)",
|
||||
" @ValueSource(ints = {0, 1})",
|
||||
" @MethodSource(\"nonexistentMethod\")",
|
||||
" void withMultipleArgumentSourcesAndFullyQualifiedImport() {}",
|
||||
"",
|
||||
" class NestedWithTestAnnotationFirst {",
|
||||
" @ParameterizedTest",
|
||||
" @ValueSource(ints = {0, 1})",
|
||||
" void withValueSource() {}",
|
||||
" }",
|
||||
"",
|
||||
" class NestedWithTestAnnotationSecond {",
|
||||
" @ValueSource(ints = {0, 1})",
|
||||
" @ParameterizedTest",
|
||||
" void withValueSource() {}",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ArgumentsProvider;
|
||||
import org.junit.jupiter.params.provider.ArgumentsSource;
|
||||
import org.junit.jupiter.params.provider.ArgumentsSources;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
class A {
|
||||
@Test
|
||||
void withoutArgumentSource() {}
|
||||
|
||||
@Test
|
||||
void withCustomArgumentSource() {}
|
||||
|
||||
@Test
|
||||
void withCustomerArgumentSources() {}
|
||||
|
||||
/** Foo. */
|
||||
@Test
|
||||
void withValueSourceAndJavadoc() {}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("foo")
|
||||
void withMethodSourceAndUnrelatedAnnotation() {}
|
||||
|
||||
@Test
|
||||
void withMultipleArgumentSourcesAndFullyQualifiedImport() {}
|
||||
|
||||
class NestedWithTestAnnotationFirst {
|
||||
@Test
|
||||
void withValueSource() {}
|
||||
}
|
||||
|
||||
class NestedWithTestAnnotationSecond {
|
||||
@Test
|
||||
void withValueSource() {}
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import org.junit.jupiter.api.Test;",
|
||||
"import org.junit.jupiter.params.ParameterizedTest;",
|
||||
"import org.junit.jupiter.params.provider.ArgumentsProvider;",
|
||||
"import org.junit.jupiter.params.provider.ArgumentsSource;",
|
||||
"import org.junit.jupiter.params.provider.ArgumentsSources;",
|
||||
"import org.junit.jupiter.params.provider.MethodSource;",
|
||||
"import org.junit.jupiter.params.provider.ValueSource;",
|
||||
"",
|
||||
"class A {",
|
||||
" @Test",
|
||||
" void withoutArgumentSource() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" void withCustomArgumentSource() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" void withCustomerArgumentSources() {}",
|
||||
"",
|
||||
" /** Foo. */",
|
||||
" @Test",
|
||||
" void withValueSourceAndJavadoc() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" @SuppressWarnings(\"foo\")",
|
||||
" void withMethodSourceAndUnrelatedAnnotation() {}",
|
||||
"",
|
||||
" @Test",
|
||||
" void withMultipleArgumentSourcesAndFullyQualifiedImport() {}",
|
||||
"",
|
||||
" class NestedWithTestAnnotationFirst {",
|
||||
" @Test",
|
||||
" void withValueSource() {}",
|
||||
" }",
|
||||
"",
|
||||
" class NestedWithTestAnnotationSecond {",
|
||||
" @Test",
|
||||
" void withValueSource() {}",
|
||||
" }",
|
||||
"}")
|
||||
.addInputLines(
|
||||
"B.java",
|
||||
"""
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
|
||||
class B {
|
||||
@ParameterizedTest
|
||||
void scopeInWhichIdentifierTestIsAlreadyDeclared() {}
|
||||
|
||||
class Test {}
|
||||
}
|
||||
""")
|
||||
"import org.junit.jupiter.params.ParameterizedTest;",
|
||||
"",
|
||||
"class B {",
|
||||
" @ParameterizedTest",
|
||||
" void scopeInWhichIdentifierTestIsAlreadyDeclared() {}",
|
||||
"",
|
||||
" class Test {}",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"B.java",
|
||||
"""
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
|
||||
class B {
|
||||
@org.junit.jupiter.api.Test
|
||||
void scopeInWhichIdentifierTestIsAlreadyDeclared() {}
|
||||
|
||||
class Test {}
|
||||
}
|
||||
""")
|
||||
"import org.junit.jupiter.params.ParameterizedTest;",
|
||||
"",
|
||||
"class B {",
|
||||
" @org.junit.jupiter.api.Test",
|
||||
" void scopeInWhichIdentifierTestIsAlreadyDeclared() {}",
|
||||
"",
|
||||
" class Test {}",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,191 +11,189 @@ final class JUnitValueSourceTest {
|
||||
CompilationTestHelper.newInstance(JUnitValueSource.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static org.junit.jupiter.params.provider.Arguments.arguments;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
class A {
|
||||
private static Stream<Arguments> identificationTestCases() {
|
||||
return Stream.of(arguments(1), Arguments.of(2));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
// BUG: Diagnostic contains:
|
||||
@MethodSource("identificationTestCases")
|
||||
void identification(int foo) {}
|
||||
|
||||
private static int[] identificationWithParensTestCases() {
|
||||
return new int[] {1, 2};
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
// BUG: Diagnostic contains:
|
||||
@MethodSource("identificationWithParensTestCases()")
|
||||
void identificationWithParens(int foo) {}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("valueFactoryMissingTestCases")
|
||||
void valueFactoryMissing(int foo) {}
|
||||
|
||||
private static Stream<Arguments> multipleUsagesTestCases() {
|
||||
return Stream.of(arguments(1), Arguments.of(2));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("multipleUsagesTestCases")
|
||||
void multipleUsages1(int foo) {}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("multipleUsagesTestCases()")
|
||||
void multipleUsages2(int bar) {}
|
||||
|
||||
private static Stream<Arguments> valueFactoryRepeatedTestCases() {
|
||||
return Stream.of(arguments(1), arguments(2));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource({"valueFactoryRepeatedTestCases", "valueFactoryRepeatedTestCases"})
|
||||
void valueFactoryRepeated(int foo) {}
|
||||
|
||||
private static Stream<Arguments> multipleParametersTestCases() {
|
||||
return Stream.of(arguments(1, 2), arguments(3, 4));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("multipleParametersTestCases")
|
||||
void multipleParameters(int first, int second) {}
|
||||
|
||||
private static int[] arrayWithoutInitializersTestCases() {
|
||||
return new int[1];
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("arrayWithoutInitializersTestCases")
|
||||
void arrayWithoutInitializers(int foo) {}
|
||||
|
||||
private static Stream<Arguments> runtimeValueTestCases() {
|
||||
int second = 2;
|
||||
return Stream.of(arguments(1), arguments(second));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("runtimeValueTestCases")
|
||||
void runtimeValue(int foo) {}
|
||||
|
||||
private static Stream<Arguments> streamChainTestCases() {
|
||||
return Stream.of(1, 2).map(Arguments::arguments);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("streamChainTestCases")
|
||||
void streamChain(int number) {}
|
||||
|
||||
private static Stream<Arguments> multipleReturnsTestCases() {
|
||||
if (true) {
|
||||
return Stream.of(arguments(1), arguments(2));
|
||||
} else {
|
||||
return Stream.of(arguments(3), arguments(4));
|
||||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("multipleReturnsTestCases")
|
||||
void multipleReturns(int number) {}
|
||||
|
||||
private static Stream<Arguments> multipleFactoriesFooTestCases() {
|
||||
return Stream.of(arguments(1));
|
||||
}
|
||||
|
||||
private static Stream<Arguments> multipleFactoriesBarTestCases() {
|
||||
return Stream.of(arguments(1));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource({"multipleFactoriesFooTestCases", "multipleFactoriesBarTestCases"})
|
||||
void multipleFactories(int i) {}
|
||||
|
||||
private static Stream<Arguments> extraArgsTestCases() {
|
||||
return Stream.of(arguments(1), arguments(1, 2));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("extraArgsTestCases")
|
||||
void extraArgs(int... i) {}
|
||||
|
||||
private static Stream<Arguments> localClassTestCases() {
|
||||
class Foo {
|
||||
Stream<Arguments> foo() {
|
||||
return Stream.of(arguments(1), arguments(2));
|
||||
}
|
||||
}
|
||||
return Stream.of(arguments(1), arguments(2));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
// BUG: Diagnostic contains:
|
||||
@MethodSource("localClassTestCases")
|
||||
void localClass(int i) {}
|
||||
|
||||
private static Stream<Arguments> lambdaReturnTestCases() {
|
||||
int foo =
|
||||
Optional.of(10)
|
||||
.map(
|
||||
i -> {
|
||||
return i / 2;
|
||||
})
|
||||
.orElse(0);
|
||||
return Stream.of(arguments(1), arguments(1));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
// BUG: Diagnostic contains:
|
||||
@MethodSource("lambdaReturnTestCases")
|
||||
void lambdaReturn(int i) {}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("tech.picnic.errorprone.Foo#fooTestCases")
|
||||
void staticMethodReference(int foo) {}
|
||||
|
||||
private static Stream<Arguments> valueFactoryWithArgumentTestCases(int amount) {
|
||||
return Stream.of(arguments(1), arguments(2));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
// BUG: Diagnostic contains:
|
||||
@MethodSource("valueFactoryWithArgumentTestCases")
|
||||
void valueFactoryWithArgument(int foo) {}
|
||||
|
||||
private static Arguments[] emptyArrayValueFactoryTestCases() {
|
||||
return new Arguments[] {};
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("emptyArrayValueFactoryTestCases")
|
||||
void emptyArrayValueFactory(int foo) {}
|
||||
|
||||
private static Stream<Arguments> emptyStreamValueFactoryTestCases() {
|
||||
return Stream.of();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("emptyStreamValueFactoryTestCases")
|
||||
void emptyStreamValueFactory(int foo) {}
|
||||
|
||||
private static Arguments[] invalidValueFactoryArgumentsTestCases() {
|
||||
return new Arguments[] {arguments(1), arguments(new Object() {})};
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("invalidValueFactoryArgumentsTestCases")
|
||||
void invalidValueFactoryArguments(int foo) {}
|
||||
}
|
||||
""")
|
||||
"import static org.junit.jupiter.params.provider.Arguments.arguments;",
|
||||
"",
|
||||
"import java.util.Optional;",
|
||||
"import java.util.stream.Stream;",
|
||||
"import org.junit.jupiter.params.ParameterizedTest;",
|
||||
"import org.junit.jupiter.params.provider.Arguments;",
|
||||
"import org.junit.jupiter.params.provider.MethodSource;",
|
||||
"",
|
||||
"class A {",
|
||||
" private static Stream<Arguments> identificationTestCases() {",
|
||||
" return Stream.of(arguments(1), Arguments.of(2));",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @MethodSource(\"identificationTestCases\")",
|
||||
" void identification(int foo) {}",
|
||||
"",
|
||||
" private static int[] identificationWithParensTestCases() {",
|
||||
" return new int[] {1, 2};",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @MethodSource(\"identificationWithParensTestCases()\")",
|
||||
" void identificationWithParens(int foo) {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"valueFactoryMissingTestCases\")",
|
||||
" void valueFactoryMissing(int foo) {}",
|
||||
"",
|
||||
" private static Stream<Arguments> multipleUsagesTestCases() {",
|
||||
" return Stream.of(arguments(1), Arguments.of(2));",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"multipleUsagesTestCases\")",
|
||||
" void multipleUsages1(int foo) {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"multipleUsagesTestCases()\")",
|
||||
" void multipleUsages2(int bar) {}",
|
||||
"",
|
||||
" private static Stream<Arguments> valueFactoryRepeatedTestCases() {",
|
||||
" return Stream.of(arguments(1), arguments(2));",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource({\"valueFactoryRepeatedTestCases\", \"valueFactoryRepeatedTestCases\"})",
|
||||
" void valueFactoryRepeated(int foo) {}",
|
||||
"",
|
||||
" private static Stream<Arguments> multipleParametersTestCases() {",
|
||||
" return Stream.of(arguments(1, 2), arguments(3, 4));",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"multipleParametersTestCases\")",
|
||||
" void multipleParameters(int first, int second) {}",
|
||||
"",
|
||||
" private static int[] arrayWithoutInitializersTestCases() {",
|
||||
" return new int[1];",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"arrayWithoutInitializersTestCases\")",
|
||||
" void arrayWithoutInitializers(int foo) {}",
|
||||
"",
|
||||
" private static Stream<Arguments> runtimeValueTestCases() {",
|
||||
" int second = 2;",
|
||||
" return Stream.of(arguments(1), arguments(second));",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"runtimeValueTestCases\")",
|
||||
" void runtimeValue(int foo) {}",
|
||||
"",
|
||||
" private static Stream<Arguments> streamChainTestCases() {",
|
||||
" return Stream.of(1, 2).map(Arguments::arguments);",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"streamChainTestCases\")",
|
||||
" void streamChain(int number) {}",
|
||||
"",
|
||||
" private static Stream<Arguments> multipleReturnsTestCases() {",
|
||||
" if (true) {",
|
||||
" return Stream.of(arguments(1), arguments(2));",
|
||||
" } else {",
|
||||
" return Stream.of(arguments(3), arguments(4));",
|
||||
" }",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"multipleReturnsTestCases\")",
|
||||
" void multipleReturns(int number) {}",
|
||||
"",
|
||||
" private static Stream<Arguments> multipleFactoriesFooTestCases() {",
|
||||
" return Stream.of(arguments(1));",
|
||||
" }",
|
||||
"",
|
||||
" private static Stream<Arguments> multipleFactoriesBarTestCases() {",
|
||||
" return Stream.of(arguments(1));",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource({\"multipleFactoriesFooTestCases\", \"multipleFactoriesBarTestCases\"})",
|
||||
" void multipleFactories(int i) {}",
|
||||
"",
|
||||
" private static Stream<Arguments> extraArgsTestCases() {",
|
||||
" return Stream.of(arguments(1), arguments(1, 2));",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"extraArgsTestCases\")",
|
||||
" void extraArgs(int... i) {}",
|
||||
"",
|
||||
" private static Stream<Arguments> localClassTestCases() {",
|
||||
" class Foo {",
|
||||
" Stream<Arguments> foo() {",
|
||||
" return Stream.of(arguments(1), arguments(2));",
|
||||
" }",
|
||||
" }",
|
||||
" return Stream.of(arguments(1), arguments(2));",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @MethodSource(\"localClassTestCases\")",
|
||||
" void localClass(int i) {}",
|
||||
"",
|
||||
" private static Stream<Arguments> lambdaReturnTestCases() {",
|
||||
" int foo =",
|
||||
" Optional.of(10)",
|
||||
" .map(",
|
||||
" i -> {",
|
||||
" return i / 2;",
|
||||
" })",
|
||||
" .orElse(0);",
|
||||
" return Stream.of(arguments(1), arguments(1));",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @MethodSource(\"lambdaReturnTestCases\")",
|
||||
" void lambdaReturn(int i) {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"tech.picnic.errorprone.Foo#fooTestCases\")",
|
||||
" void staticMethodReference(int foo) {}",
|
||||
"",
|
||||
" private static Stream<Arguments> valueFactoryWithArgumentTestCases(int amount) {",
|
||||
" return Stream.of(arguments(1), arguments(2));",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @MethodSource(\"valueFactoryWithArgumentTestCases\")",
|
||||
" void valueFactoryWithArgument(int foo) {}",
|
||||
"",
|
||||
" private static Arguments[] emptyArrayValueFactoryTestCases() {",
|
||||
" return new Arguments[] {};",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"emptyArrayValueFactoryTestCases\")",
|
||||
" void emptyArrayValueFactory(int foo) {}",
|
||||
"",
|
||||
" private static Stream<Arguments> emptyStreamValueFactoryTestCases() {",
|
||||
" return Stream.of();",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"emptyStreamValueFactoryTestCases\")",
|
||||
" void emptyStreamValueFactory(int foo) {}",
|
||||
"",
|
||||
" private static Arguments[] invalidValueFactoryArgumentsTestCases() {",
|
||||
" return new Arguments[] {arguments(1), arguments(new Object() {})};",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"invalidValueFactoryArgumentsTestCases\")",
|
||||
" void invalidValueFactoryArguments(int foo) {}",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -204,299 +202,295 @@ final class JUnitValueSourceTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(JUnitValueSource.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static org.junit.jupiter.params.provider.Arguments.arguments;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.DoubleStream;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.stream.Stream;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
class A {
|
||||
private static final boolean CONST_BOOLEAN = false;
|
||||
private static final byte CONST_BYTE = 42;
|
||||
private static final char CONST_CHARACTER = 'a';
|
||||
private static final short CONST_SHORT = 42;
|
||||
private static final int CONST_INTEGER = 42;
|
||||
private static final long CONST_LONG = 42;
|
||||
private static final float CONST_FLOAT = 42;
|
||||
private static final double CONST_DOUBLE = 42;
|
||||
private static final String CONST_STRING = "foo";
|
||||
|
||||
private static Stream<Arguments> streamOfBooleanArguments() {
|
||||
return Stream.of(arguments(false), arguments(true), arguments(CONST_BOOLEAN));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("streamOfBooleanArguments")
|
||||
void primitiveBoolean(boolean b) {}
|
||||
|
||||
private static Stream<Object> streamOfBooleansAndBooleanArguments() {
|
||||
return Stream.of(false, arguments(true), CONST_BOOLEAN);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("streamOfBooleansAndBooleanArguments")
|
||||
void boxedBoolean(Boolean b) {}
|
||||
|
||||
private static List<Arguments> listOfByteArguments() {
|
||||
return List.of(arguments((byte) 0), arguments((byte) 1), arguments(CONST_BYTE));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("listOfByteArguments")
|
||||
void primitiveByte(byte b) {}
|
||||
|
||||
private static List<Object> listOfBytesAndByteArguments() {
|
||||
return List.of((byte) 0, arguments((byte) 1), CONST_BYTE);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("listOfBytesAndByteArguments")
|
||||
void boxedByte(Byte b) {}
|
||||
|
||||
private static Set<Arguments> setOfCharacterArguments() {
|
||||
return Set.of(arguments((char) 0), arguments((char) 1), arguments(CONST_CHARACTER));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("setOfCharacterArguments")
|
||||
void primitiveCharacter(char c) {}
|
||||
|
||||
private static Set<Object> setOfCharactersAndCharacterArguments() {
|
||||
return Set.of((char) 0, arguments((char) 1), CONST_CHARACTER);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("setOfCharactersAndCharacterArguments")
|
||||
void boxedCharacter(Character c) {}
|
||||
|
||||
private static Arguments[] arrayOfShortArguments() {
|
||||
return new Arguments[] {arguments((short) 0), arguments((short) 1), arguments(CONST_SHORT)};
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("arrayOfShortArguments")
|
||||
void primitiveShort(short s) {}
|
||||
|
||||
private static Object[] arrayOfShortsAndShortArguments() {
|
||||
return new Object[] {(short) 0, arguments((short) 1), CONST_SHORT};
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("arrayOfShortsAndShortArguments")
|
||||
void boxedShort(Short s) {}
|
||||
|
||||
private static IntStream intStream() {
|
||||
return IntStream.of(0, 1, CONST_INTEGER);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("intStream")
|
||||
void primitiveInteger(int i) {}
|
||||
|
||||
private static int[] intArray() {
|
||||
return new int[] {0, 1, CONST_INTEGER};
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("intArray")
|
||||
void boxedInteger(Integer i) {}
|
||||
|
||||
private static LongStream longStream() {
|
||||
return LongStream.of(0, 1, CONST_LONG);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("longStream")
|
||||
void primitiveLong(long l) {}
|
||||
|
||||
private static long[] longArray() {
|
||||
return new long[] {0, 1, CONST_LONG};
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("longArray")
|
||||
void boxedLong(Long l) {}
|
||||
|
||||
private static ImmutableList<Arguments> immutableListOfFloatArguments() {
|
||||
return ImmutableList.of(arguments(0.0F), arguments(1.0F), arguments(CONST_FLOAT));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("immutableListOfFloatArguments")
|
||||
void primitiveFloat(float f) {}
|
||||
|
||||
private static Stream<Object> streamOfFloatsAndFloatArguments() {
|
||||
return Stream.of(0.0F, arguments(1.0F), CONST_FLOAT);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("streamOfFloatsAndFloatArguments")
|
||||
void boxedFloat(Float f) {}
|
||||
|
||||
private static DoubleStream doubleStream() {
|
||||
return DoubleStream.of(0, 1, CONST_DOUBLE);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("doubleStream")
|
||||
void primitiveDouble(double d) {}
|
||||
|
||||
private static double[] doubleArray() {
|
||||
return new double[] {0, 1, CONST_DOUBLE};
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("doubleArray")
|
||||
void boxedDouble(Double d) {}
|
||||
|
||||
private static ImmutableSet<Arguments> immutableSetOfStringArguments() {
|
||||
return ImmutableSet.of(arguments("foo"), arguments("bar"), arguments(CONST_STRING));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("immutableSetOfStringArguments")
|
||||
void string(String s) {}
|
||||
|
||||
private static Stream<Class<?>> streamOfClasses() {
|
||||
return Stream.of(Stream.class, java.util.Map.class);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("streamOfClasses")
|
||||
void clazz(Class<?> c) {}
|
||||
|
||||
private static Stream<Arguments> sameNameFactoryTestCases() {
|
||||
return Stream.of(arguments(1));
|
||||
}
|
||||
|
||||
private static Stream<Arguments> sameNameFactoryTestCases(int overload) {
|
||||
return Stream.of(arguments(overload));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("sameNameFactoryTestCases")
|
||||
void sameNameFactory(int i) {}
|
||||
}
|
||||
""")
|
||||
"import static org.junit.jupiter.params.provider.Arguments.arguments;",
|
||||
"",
|
||||
"import com.google.common.collect.ImmutableList;",
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import java.util.List;",
|
||||
"import java.util.Set;",
|
||||
"import java.util.stream.DoubleStream;",
|
||||
"import java.util.stream.IntStream;",
|
||||
"import java.util.stream.LongStream;",
|
||||
"import java.util.stream.Stream;",
|
||||
"import org.junit.jupiter.params.ParameterizedTest;",
|
||||
"import org.junit.jupiter.params.provider.Arguments;",
|
||||
"import org.junit.jupiter.params.provider.MethodSource;",
|
||||
"",
|
||||
"class A {",
|
||||
" private static final boolean CONST_BOOLEAN = false;",
|
||||
" private static final byte CONST_BYTE = 42;",
|
||||
" private static final char CONST_CHARACTER = 'a';",
|
||||
" private static final short CONST_SHORT = 42;",
|
||||
" private static final int CONST_INTEGER = 42;",
|
||||
" private static final long CONST_LONG = 42;",
|
||||
" private static final float CONST_FLOAT = 42;",
|
||||
" private static final double CONST_DOUBLE = 42;",
|
||||
" private static final String CONST_STRING = \"foo\";",
|
||||
"",
|
||||
" private static Stream<Arguments> streamOfBooleanArguments() {",
|
||||
" return Stream.of(arguments(false), arguments(true), arguments(CONST_BOOLEAN));",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"streamOfBooleanArguments\")",
|
||||
" void primitiveBoolean(boolean b) {}",
|
||||
"",
|
||||
" private static Stream<Object> streamOfBooleansAndBooleanArguments() {",
|
||||
" return Stream.of(false, arguments(true), CONST_BOOLEAN);",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"streamOfBooleansAndBooleanArguments\")",
|
||||
" void boxedBoolean(Boolean b) {}",
|
||||
"",
|
||||
" private static List<Arguments> listOfByteArguments() {",
|
||||
" return List.of(arguments((byte) 0), arguments((byte) 1), arguments(CONST_BYTE));",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"listOfByteArguments\")",
|
||||
" void primitiveByte(byte b) {}",
|
||||
"",
|
||||
" private static List<Object> listOfBytesAndByteArguments() {",
|
||||
" return List.of((byte) 0, arguments((byte) 1), CONST_BYTE);",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"listOfBytesAndByteArguments\")",
|
||||
" void boxedByte(Byte b) {}",
|
||||
"",
|
||||
" private static Set<Arguments> setOfCharacterArguments() {",
|
||||
" return Set.of(arguments((char) 0), arguments((char) 1), arguments(CONST_CHARACTER));",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"setOfCharacterArguments\")",
|
||||
" void primitiveCharacter(char c) {}",
|
||||
"",
|
||||
" private static Set<Object> setOfCharactersAndCharacterArguments() {",
|
||||
" return Set.of((char) 0, arguments((char) 1), CONST_CHARACTER);",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"setOfCharactersAndCharacterArguments\")",
|
||||
" void boxedCharacter(Character c) {}",
|
||||
"",
|
||||
" private static Arguments[] arrayOfShortArguments() {",
|
||||
" return new Arguments[] {arguments((short) 0), arguments((short) 1), arguments(CONST_SHORT)};",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"arrayOfShortArguments\")",
|
||||
" void primitiveShort(short s) {}",
|
||||
"",
|
||||
" private static Object[] arrayOfShortsAndShortArguments() {",
|
||||
" return new Object[] {(short) 0, arguments((short) 1), CONST_SHORT};",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"arrayOfShortsAndShortArguments\")",
|
||||
" void boxedShort(Short s) {}",
|
||||
"",
|
||||
" private static IntStream intStream() {",
|
||||
" return IntStream.of(0, 1, CONST_INTEGER);",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"intStream\")",
|
||||
" void primitiveInteger(int i) {}",
|
||||
"",
|
||||
" private static int[] intArray() {",
|
||||
" return new int[] {0, 1, CONST_INTEGER};",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"intArray\")",
|
||||
" void boxedInteger(Integer i) {}",
|
||||
"",
|
||||
" private static LongStream longStream() {",
|
||||
" return LongStream.of(0, 1, CONST_LONG);",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"longStream\")",
|
||||
" void primitiveLong(long l) {}",
|
||||
"",
|
||||
" private static long[] longArray() {",
|
||||
" return new long[] {0, 1, CONST_LONG};",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"longArray\")",
|
||||
" void boxedLong(Long l) {}",
|
||||
"",
|
||||
" private static ImmutableList<Arguments> immutableListOfFloatArguments() {",
|
||||
" return ImmutableList.of(arguments(0.0F), arguments(1.0F), arguments(CONST_FLOAT));",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"immutableListOfFloatArguments\")",
|
||||
" void primitiveFloat(float f) {}",
|
||||
"",
|
||||
" private static Stream<Object> streamOfFloatsAndFloatArguments() {",
|
||||
" return Stream.of(0.0F, arguments(1.0F), CONST_FLOAT);",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"streamOfFloatsAndFloatArguments\")",
|
||||
" void boxedFloat(Float f) {}",
|
||||
"",
|
||||
" private static DoubleStream doubleStream() {",
|
||||
" return DoubleStream.of(0, 1, CONST_DOUBLE);",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"doubleStream\")",
|
||||
" void primitiveDouble(double d) {}",
|
||||
"",
|
||||
" private static double[] doubleArray() {",
|
||||
" return new double[] {0, 1, CONST_DOUBLE};",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"doubleArray\")",
|
||||
" void boxedDouble(Double d) {}",
|
||||
"",
|
||||
" private static ImmutableSet<Arguments> immutableSetOfStringArguments() {",
|
||||
" return ImmutableSet.of(arguments(\"foo\"), arguments(\"bar\"), arguments(CONST_STRING));",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"immutableSetOfStringArguments\")",
|
||||
" void string(String s) {}",
|
||||
"",
|
||||
" private static Stream<Class<?>> streamOfClasses() {",
|
||||
" return Stream.of(Stream.class, java.util.Map.class);",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"streamOfClasses\")",
|
||||
" void clazz(Class<?> c) {}",
|
||||
"",
|
||||
" private static Stream<Arguments> sameNameFactoryTestCases() {",
|
||||
" return Stream.of(arguments(1));",
|
||||
" }",
|
||||
"",
|
||||
" private static Stream<Arguments> sameNameFactoryTestCases(int overload) {",
|
||||
" return Stream.of(arguments(overload));",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @MethodSource(\"sameNameFactoryTestCases\")",
|
||||
" void sameNameFactory(int i) {}",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static org.junit.jupiter.params.provider.Arguments.arguments;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.DoubleStream;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.stream.Stream;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
class A {
|
||||
private static final boolean CONST_BOOLEAN = false;
|
||||
private static final byte CONST_BYTE = 42;
|
||||
private static final char CONST_CHARACTER = 'a';
|
||||
private static final short CONST_SHORT = 42;
|
||||
private static final int CONST_INTEGER = 42;
|
||||
private static final long CONST_LONG = 42;
|
||||
private static final float CONST_FLOAT = 42;
|
||||
private static final double CONST_DOUBLE = 42;
|
||||
private static final String CONST_STRING = "foo";
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {false, true, CONST_BOOLEAN})
|
||||
void primitiveBoolean(boolean b) {}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {false, true, CONST_BOOLEAN})
|
||||
void boxedBoolean(Boolean b) {}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(bytes = {(byte) 0, (byte) 1, CONST_BYTE})
|
||||
void primitiveByte(byte b) {}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(bytes = {(byte) 0, (byte) 1, CONST_BYTE})
|
||||
void boxedByte(Byte b) {}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(chars = {(char) 0, (char) 1, CONST_CHARACTER})
|
||||
void primitiveCharacter(char c) {}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(chars = {(char) 0, (char) 1, CONST_CHARACTER})
|
||||
void boxedCharacter(Character c) {}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(shorts = {(short) 0, (short) 1, CONST_SHORT})
|
||||
void primitiveShort(short s) {}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(shorts = {(short) 0, (short) 1, CONST_SHORT})
|
||||
void boxedShort(Short s) {}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(ints = {0, 1, CONST_INTEGER})
|
||||
void primitiveInteger(int i) {}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(ints = {0, 1, CONST_INTEGER})
|
||||
void boxedInteger(Integer i) {}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(longs = {0, 1, CONST_LONG})
|
||||
void primitiveLong(long l) {}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(longs = {0, 1, CONST_LONG})
|
||||
void boxedLong(Long l) {}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(floats = {0.0F, 1.0F, CONST_FLOAT})
|
||||
void primitiveFloat(float f) {}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(floats = {0.0F, 1.0F, CONST_FLOAT})
|
||||
void boxedFloat(Float f) {}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(doubles = {0, 1, CONST_DOUBLE})
|
||||
void primitiveDouble(double d) {}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(doubles = {0, 1, CONST_DOUBLE})
|
||||
void boxedDouble(Double d) {}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"foo", "bar", CONST_STRING})
|
||||
void string(String s) {}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(classes = {Stream.class, java.util.Map.class})
|
||||
void clazz(Class<?> c) {}
|
||||
|
||||
private static Stream<Arguments> sameNameFactoryTestCases(int overload) {
|
||||
return Stream.of(arguments(overload));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(ints = 1)
|
||||
void sameNameFactory(int i) {}
|
||||
}
|
||||
""")
|
||||
"import static org.junit.jupiter.params.provider.Arguments.arguments;",
|
||||
"",
|
||||
"import com.google.common.collect.ImmutableList;",
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import java.util.List;",
|
||||
"import java.util.Set;",
|
||||
"import java.util.stream.DoubleStream;",
|
||||
"import java.util.stream.IntStream;",
|
||||
"import java.util.stream.LongStream;",
|
||||
"import java.util.stream.Stream;",
|
||||
"import org.junit.jupiter.params.ParameterizedTest;",
|
||||
"import org.junit.jupiter.params.provider.Arguments;",
|
||||
"import org.junit.jupiter.params.provider.MethodSource;",
|
||||
"import org.junit.jupiter.params.provider.ValueSource;",
|
||||
"",
|
||||
"class A {",
|
||||
" private static final boolean CONST_BOOLEAN = false;",
|
||||
" private static final byte CONST_BYTE = 42;",
|
||||
" private static final char CONST_CHARACTER = 'a';",
|
||||
" private static final short CONST_SHORT = 42;",
|
||||
" private static final int CONST_INTEGER = 42;",
|
||||
" private static final long CONST_LONG = 42;",
|
||||
" private static final float CONST_FLOAT = 42;",
|
||||
" private static final double CONST_DOUBLE = 42;",
|
||||
" private static final String CONST_STRING = \"foo\";",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @ValueSource(booleans = {false, true, CONST_BOOLEAN})",
|
||||
" void primitiveBoolean(boolean b) {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @ValueSource(booleans = {false, true, CONST_BOOLEAN})",
|
||||
" void boxedBoolean(Boolean b) {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @ValueSource(bytes = {(byte) 0, (byte) 1, CONST_BYTE})",
|
||||
" void primitiveByte(byte b) {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @ValueSource(bytes = {(byte) 0, (byte) 1, CONST_BYTE})",
|
||||
" void boxedByte(Byte b) {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @ValueSource(chars = {(char) 0, (char) 1, CONST_CHARACTER})",
|
||||
" void primitiveCharacter(char c) {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @ValueSource(chars = {(char) 0, (char) 1, CONST_CHARACTER})",
|
||||
" void boxedCharacter(Character c) {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @ValueSource(shorts = {(short) 0, (short) 1, CONST_SHORT})",
|
||||
" void primitiveShort(short s) {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @ValueSource(shorts = {(short) 0, (short) 1, CONST_SHORT})",
|
||||
" void boxedShort(Short s) {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @ValueSource(ints = {0, 1, CONST_INTEGER})",
|
||||
" void primitiveInteger(int i) {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @ValueSource(ints = {0, 1, CONST_INTEGER})",
|
||||
" void boxedInteger(Integer i) {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @ValueSource(longs = {0, 1, CONST_LONG})",
|
||||
" void primitiveLong(long l) {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @ValueSource(longs = {0, 1, CONST_LONG})",
|
||||
" void boxedLong(Long l) {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @ValueSource(floats = {0.0F, 1.0F, CONST_FLOAT})",
|
||||
" void primitiveFloat(float f) {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @ValueSource(floats = {0.0F, 1.0F, CONST_FLOAT})",
|
||||
" void boxedFloat(Float f) {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @ValueSource(doubles = {0, 1, CONST_DOUBLE})",
|
||||
" void primitiveDouble(double d) {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @ValueSource(doubles = {0, 1, CONST_DOUBLE})",
|
||||
" void boxedDouble(Double d) {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @ValueSource(strings = {\"foo\", \"bar\", CONST_STRING})",
|
||||
" void string(String s) {}",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @ValueSource(classes = {Stream.class, java.util.Map.class})",
|
||||
" void clazz(Class<?> c) {}",
|
||||
"",
|
||||
" private static Stream<Arguments> sameNameFactoryTestCases(int overload) {",
|
||||
" return Stream.of(arguments(overload));",
|
||||
" }",
|
||||
"",
|
||||
" @ParameterizedTest",
|
||||
" @ValueSource(ints = 1)",
|
||||
" void sameNameFactory(int i) {}",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,178 +11,176 @@ final class LexicographicalAnnotationAttributeListingTest {
|
||||
CompilationTestHelper.newInstance(LexicographicalAnnotationAttributeListing.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static java.math.RoundingMode.DOWN;
|
||||
import static java.math.RoundingMode.UP;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import java.math.RoundingMode;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
|
||||
interface A {
|
||||
@interface Foo {
|
||||
String[] value() default {};
|
||||
|
||||
boolean[] bools() default {};
|
||||
|
||||
char[] chars() default {};
|
||||
|
||||
int[] ints() default {};
|
||||
|
||||
Class<?>[] cls() default {};
|
||||
|
||||
RoundingMode[] enums() default {};
|
||||
|
||||
Bar[] anns() default {};
|
||||
}
|
||||
|
||||
@interface Bar {
|
||||
String[] value() default {};
|
||||
}
|
||||
|
||||
@Foo({})
|
||||
A noString();
|
||||
|
||||
@Foo({"a"})
|
||||
A oneString();
|
||||
|
||||
@Foo({"a", "b"})
|
||||
A sortedStrings();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@Foo({"b", "a"})
|
||||
A unsortedString();
|
||||
|
||||
@Foo({"ab", "Ac"})
|
||||
A sortedStringCaseInsensitive();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@Foo({"ac", "Ab"})
|
||||
A unsortedStringCaseInsensitive();
|
||||
|
||||
@Foo({"A", "a"})
|
||||
A sortedStringCaseInsensitiveWithTotalOrderFallback();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@Foo({"a", "A"})
|
||||
A unsortedStringCaseInsensitiveWithTotalOrderFallback();
|
||||
|
||||
@Foo(bools = {})
|
||||
A noBools();
|
||||
|
||||
@Foo(bools = {false})
|
||||
A oneBool();
|
||||
|
||||
@Foo(bools = {false, true})
|
||||
A sortedBools();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@Foo(bools = {true, false})
|
||||
A unsortedBools();
|
||||
|
||||
@Foo(chars = {})
|
||||
A noChars();
|
||||
|
||||
@Foo(chars = {'a'})
|
||||
A oneChar();
|
||||
|
||||
@Foo(chars = {'a', 'b'})
|
||||
A sortedChars();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@Foo(chars = {'b', 'a'})
|
||||
A unsortedChars();
|
||||
|
||||
@Foo(ints = {})
|
||||
A noInts();
|
||||
|
||||
@Foo(ints = {0})
|
||||
A oneInt();
|
||||
|
||||
@Foo(ints = {0, 1})
|
||||
A sortedInts();
|
||||
|
||||
@Foo(ints = {1, 0})
|
||||
A unsortedInts();
|
||||
|
||||
@Foo(cls = {})
|
||||
A noClasses();
|
||||
|
||||
@Foo(cls = {int.class})
|
||||
A oneClass();
|
||||
|
||||
@Foo(cls = {int.class, long.class})
|
||||
A sortedClasses();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@Foo(cls = {long.class, int.class})
|
||||
A unsortedClasses();
|
||||
|
||||
@Foo(enums = {})
|
||||
A noEnums();
|
||||
|
||||
@Foo(enums = {DOWN})
|
||||
A oneEnum();
|
||||
|
||||
@Foo(enums = {DOWN, UP})
|
||||
A sortedEnums();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@Foo(enums = {UP, DOWN})
|
||||
A unsortedEnums();
|
||||
|
||||
@Foo(anns = {})
|
||||
A noAnns();
|
||||
|
||||
@Foo(anns = {@Bar("a")})
|
||||
A oneAnn();
|
||||
|
||||
@Foo(anns = {@Bar("a"), @Bar("b")})
|
||||
A sortedAnns();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@Foo(anns = {@Bar("b"), @Bar("a")})
|
||||
A unsortedAnns();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@Foo(anns = {@Bar("a"), @Bar({"b", "a"})})
|
||||
A unsortedInnderAnns();
|
||||
|
||||
@Foo({"a=foo", "a.b=bar", "a.c=baz"})
|
||||
A hierarchicallySorted();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@Foo({"a.b=bar", "a.c=baz", "a=foo"})
|
||||
A hierarchicallyUnsorted();
|
||||
|
||||
@JsonPropertyOrder({"field2", "field1"})
|
||||
A dto();
|
||||
|
||||
@ApiImplicitParams({@ApiImplicitParam("p2"), @ApiImplicitParam("p1")})
|
||||
A firstEndpoint();
|
||||
|
||||
@Parameters({@Parameter(name = "p2"), @Parameter(name = "p1")})
|
||||
A secondEndpoint();
|
||||
|
||||
@XmlType(propOrder = {"field2", "field1"})
|
||||
class XmlTypeDummy {}
|
||||
|
||||
@PropertySource({"field2", "field1"})
|
||||
class PropertySourceDummy {}
|
||||
|
||||
@TestPropertySource(locations = {"field2", "field1"})
|
||||
class FirstTestPropertySourceDummy {}
|
||||
|
||||
@TestPropertySource({"field2", "field1"})
|
||||
class SecondTestPropertySourceDummy {}
|
||||
}
|
||||
""")
|
||||
"import static java.math.RoundingMode.DOWN;",
|
||||
"import static java.math.RoundingMode.UP;",
|
||||
"",
|
||||
"import com.fasterxml.jackson.annotation.JsonPropertyOrder;",
|
||||
"import io.swagger.annotations.ApiImplicitParam;",
|
||||
"import io.swagger.annotations.ApiImplicitParams;",
|
||||
"import io.swagger.v3.oas.annotations.Parameter;",
|
||||
"import io.swagger.v3.oas.annotations.Parameters;",
|
||||
"import java.math.RoundingMode;",
|
||||
"import javax.xml.bind.annotation.XmlType;",
|
||||
"import org.springframework.context.annotation.PropertySource;",
|
||||
"import org.springframework.test.context.TestPropertySource;",
|
||||
"",
|
||||
"interface A {",
|
||||
" @interface Foo {",
|
||||
" String[] value() default {};",
|
||||
"",
|
||||
" boolean[] bools() default {};",
|
||||
"",
|
||||
" char[] chars() default {};",
|
||||
"",
|
||||
" int[] ints() default {};",
|
||||
"",
|
||||
" Class<?>[] cls() default {};",
|
||||
"",
|
||||
" RoundingMode[] enums() default {};",
|
||||
"",
|
||||
" Bar[] anns() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @interface Bar {",
|
||||
" String[] value() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @Foo({})",
|
||||
" A noString();",
|
||||
"",
|
||||
" @Foo({\"a\"})",
|
||||
" A oneString();",
|
||||
"",
|
||||
" @Foo({\"a\", \"b\"})",
|
||||
" A sortedStrings();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Foo({\"b\", \"a\"})",
|
||||
" A unsortedString();",
|
||||
"",
|
||||
" @Foo({\"ab\", \"Ac\"})",
|
||||
" A sortedStringCaseInsensitive();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Foo({\"ac\", \"Ab\"})",
|
||||
" A unsortedStringCaseInsensitive();",
|
||||
"",
|
||||
" @Foo({\"A\", \"a\"})",
|
||||
" A sortedStringCaseInsensitiveWithTotalOrderFallback();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Foo({\"a\", \"A\"})",
|
||||
" A unsortedStringCaseInsensitiveWithTotalOrderFallback();",
|
||||
"",
|
||||
" @Foo(bools = {})",
|
||||
" A noBools();",
|
||||
"",
|
||||
" @Foo(bools = {false})",
|
||||
" A oneBool();",
|
||||
"",
|
||||
" @Foo(bools = {false, true})",
|
||||
" A sortedBools();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Foo(bools = {true, false})",
|
||||
" A unsortedBools();",
|
||||
"",
|
||||
" @Foo(chars = {})",
|
||||
" A noChars();",
|
||||
"",
|
||||
" @Foo(chars = {'a'})",
|
||||
" A oneChar();",
|
||||
"",
|
||||
" @Foo(chars = {'a', 'b'})",
|
||||
" A sortedChars();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Foo(chars = {'b', 'a'})",
|
||||
" A unsortedChars();",
|
||||
"",
|
||||
" @Foo(ints = {})",
|
||||
" A noInts();",
|
||||
"",
|
||||
" @Foo(ints = {0})",
|
||||
" A oneInt();",
|
||||
"",
|
||||
" @Foo(ints = {0, 1})",
|
||||
" A sortedInts();",
|
||||
"",
|
||||
" @Foo(ints = {1, 0})",
|
||||
" A unsortedInts();",
|
||||
"",
|
||||
" @Foo(cls = {})",
|
||||
" A noClasses();",
|
||||
"",
|
||||
" @Foo(cls = {int.class})",
|
||||
" A oneClass();",
|
||||
"",
|
||||
" @Foo(cls = {int.class, long.class})",
|
||||
" A sortedClasses();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Foo(cls = {long.class, int.class})",
|
||||
" A unsortedClasses();",
|
||||
"",
|
||||
" @Foo(enums = {})",
|
||||
" A noEnums();",
|
||||
"",
|
||||
" @Foo(enums = {DOWN})",
|
||||
" A oneEnum();",
|
||||
"",
|
||||
" @Foo(enums = {DOWN, UP})",
|
||||
" A sortedEnums();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Foo(enums = {UP, DOWN})",
|
||||
" A unsortedEnums();",
|
||||
"",
|
||||
" @Foo(anns = {})",
|
||||
" A noAnns();",
|
||||
"",
|
||||
" @Foo(anns = {@Bar(\"a\")})",
|
||||
" A oneAnn();",
|
||||
"",
|
||||
" @Foo(anns = {@Bar(\"a\"), @Bar(\"b\")})",
|
||||
" A sortedAnns();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")})",
|
||||
" A unsortedAnns();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Foo(anns = {@Bar(\"a\"), @Bar({\"b\", \"a\"})})",
|
||||
" A unsortedInnderAnns();",
|
||||
"",
|
||||
" @Foo({\"a=foo\", \"a.b=bar\", \"a.c=baz\"})",
|
||||
" A hierarchicallySorted();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Foo({\"a.b=bar\", \"a.c=baz\", \"a=foo\"})",
|
||||
" A hierarchicallyUnsorted();",
|
||||
"",
|
||||
" @JsonPropertyOrder({\"field2\", \"field1\"})",
|
||||
" A dto();",
|
||||
"",
|
||||
" @ApiImplicitParams({@ApiImplicitParam(\"p2\"), @ApiImplicitParam(\"p1\")})",
|
||||
" A firstEndpoint();",
|
||||
"",
|
||||
" @Parameters({@Parameter(name = \"p2\"), @Parameter(name = \"p1\")})",
|
||||
" A secondEndpoint();",
|
||||
"",
|
||||
" @XmlType(propOrder = {\"field2\", \"field1\"})",
|
||||
" class XmlTypeDummy {}",
|
||||
"",
|
||||
" @PropertySource({\"field2\", \"field1\"})",
|
||||
" class PropertySourceDummy {}",
|
||||
"",
|
||||
" @TestPropertySource(locations = {\"field2\", \"field1\"})",
|
||||
" class FirstTestPropertySourceDummy {}",
|
||||
"",
|
||||
" @TestPropertySource({\"field2\", \"field1\"})",
|
||||
" class SecondTestPropertySourceDummy {}",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -195,102 +193,98 @@ final class LexicographicalAnnotationAttributeListingTest {
|
||||
LexicographicalAnnotationAttributeListing.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static java.math.RoundingMode.DOWN;
|
||||
import static java.math.RoundingMode.UP;
|
||||
|
||||
import java.math.RoundingMode;
|
||||
|
||||
interface A {
|
||||
@interface Foo {
|
||||
String[] value() default {};
|
||||
|
||||
boolean[] bools() default {};
|
||||
|
||||
char[] chars() default {};
|
||||
|
||||
Class<?>[] cls() default {};
|
||||
|
||||
RoundingMode[] enums() default {};
|
||||
|
||||
Bar[] anns() default {};
|
||||
}
|
||||
|
||||
@interface Bar {
|
||||
String[] value() default {};
|
||||
}
|
||||
|
||||
@Foo({" ", "", "b", "a"})
|
||||
A unsortedStrings();
|
||||
|
||||
@Foo(bools = {true, false})
|
||||
A unsortedBooleans();
|
||||
|
||||
@Foo(chars = {'b', 'a'})
|
||||
A unsortedChars();
|
||||
|
||||
@Foo(cls = {long.class, int.class})
|
||||
A unsortedClasses();
|
||||
|
||||
@Foo(enums = {UP, DOWN})
|
||||
A unsortedEnums();
|
||||
|
||||
@Foo(anns = {@Bar("b"), @Bar("a")})
|
||||
A unsortedAnns();
|
||||
|
||||
@Foo(anns = {@Bar("a"), @Bar({"b", "a"})})
|
||||
A unsortedInnderAnns();
|
||||
}
|
||||
""")
|
||||
"import static java.math.RoundingMode.DOWN;",
|
||||
"import static java.math.RoundingMode.UP;",
|
||||
"",
|
||||
"import java.math.RoundingMode;",
|
||||
"",
|
||||
"interface A {",
|
||||
" @interface Foo {",
|
||||
" String[] value() default {};",
|
||||
"",
|
||||
" boolean[] bools() default {};",
|
||||
"",
|
||||
" char[] chars() default {};",
|
||||
"",
|
||||
" Class<?>[] cls() default {};",
|
||||
"",
|
||||
" RoundingMode[] enums() default {};",
|
||||
"",
|
||||
" Bar[] anns() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @interface Bar {",
|
||||
" String[] value() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @Foo({\" \", \"\", \"b\", \"a\"})",
|
||||
" A unsortedStrings();",
|
||||
"",
|
||||
" @Foo(bools = {true, false})",
|
||||
" A unsortedBooleans();",
|
||||
"",
|
||||
" @Foo(chars = {'b', 'a'})",
|
||||
" A unsortedChars();",
|
||||
"",
|
||||
" @Foo(cls = {long.class, int.class})",
|
||||
" A unsortedClasses();",
|
||||
"",
|
||||
" @Foo(enums = {UP, DOWN})",
|
||||
" A unsortedEnums();",
|
||||
"",
|
||||
" @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")})",
|
||||
" A unsortedAnns();",
|
||||
"",
|
||||
" @Foo(anns = {@Bar(\"a\"), @Bar({\"b\", \"a\"})})",
|
||||
" A unsortedInnderAnns();",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static java.math.RoundingMode.DOWN;
|
||||
import static java.math.RoundingMode.UP;
|
||||
|
||||
import java.math.RoundingMode;
|
||||
|
||||
interface A {
|
||||
@interface Foo {
|
||||
String[] value() default {};
|
||||
|
||||
boolean[] bools() default {};
|
||||
|
||||
char[] chars() default {};
|
||||
|
||||
Class<?>[] cls() default {};
|
||||
|
||||
RoundingMode[] enums() default {};
|
||||
|
||||
Bar[] anns() default {};
|
||||
}
|
||||
|
||||
@interface Bar {
|
||||
String[] value() default {};
|
||||
}
|
||||
|
||||
@Foo({"", " ", "a", "b"})
|
||||
A unsortedStrings();
|
||||
|
||||
@Foo(bools = {false, true})
|
||||
A unsortedBooleans();
|
||||
|
||||
@Foo(chars = {'a', 'b'})
|
||||
A unsortedChars();
|
||||
|
||||
@Foo(cls = {int.class, long.class})
|
||||
A unsortedClasses();
|
||||
|
||||
@Foo(enums = {DOWN, UP})
|
||||
A unsortedEnums();
|
||||
|
||||
@Foo(anns = {@Bar("a"), @Bar("b")})
|
||||
A unsortedAnns();
|
||||
|
||||
@Foo(anns = {@Bar("a"), @Bar({"a", "b"})})
|
||||
A unsortedInnderAnns();
|
||||
}
|
||||
""")
|
||||
"import static java.math.RoundingMode.DOWN;",
|
||||
"import static java.math.RoundingMode.UP;",
|
||||
"",
|
||||
"import java.math.RoundingMode;",
|
||||
"",
|
||||
"interface A {",
|
||||
" @interface Foo {",
|
||||
" String[] value() default {};",
|
||||
"",
|
||||
" boolean[] bools() default {};",
|
||||
"",
|
||||
" char[] chars() default {};",
|
||||
"",
|
||||
" Class<?>[] cls() default {};",
|
||||
"",
|
||||
" RoundingMode[] enums() default {};",
|
||||
"",
|
||||
" Bar[] anns() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @interface Bar {",
|
||||
" String[] value() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @Foo({\"\", \" \", \"a\", \"b\"})",
|
||||
" A unsortedStrings();",
|
||||
"",
|
||||
" @Foo(bools = {false, true})",
|
||||
" A unsortedBooleans();",
|
||||
"",
|
||||
" @Foo(chars = {'a', 'b'})",
|
||||
" A unsortedChars();",
|
||||
"",
|
||||
" @Foo(cls = {int.class, long.class})",
|
||||
" A unsortedClasses();",
|
||||
"",
|
||||
" @Foo(enums = {DOWN, UP})",
|
||||
" A unsortedEnums();",
|
||||
"",
|
||||
" @Foo(anns = {@Bar(\"a\"), @Bar(\"b\")})",
|
||||
" A unsortedAnns();",
|
||||
"",
|
||||
" @Foo(anns = {@Bar(\"a\"), @Bar({\"a\", \"b\"})})",
|
||||
" A unsortedInnderAnns();",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
|
||||
@@ -303,50 +297,48 @@ final class LexicographicalAnnotationAttributeListingTest {
|
||||
"-XepOpt:LexicographicalAnnotationAttributeListing:Excludes=pkg.A.Bar#value")
|
||||
.addSourceLines(
|
||||
"pkg/A.java",
|
||||
"""
|
||||
package pkg;
|
||||
|
||||
interface A {
|
||||
@interface Foo {
|
||||
String[] value() default {};
|
||||
|
||||
String[] value2() default {};
|
||||
}
|
||||
|
||||
@interface Bar {
|
||||
String[] value() default {};
|
||||
|
||||
String[] value2() default {};
|
||||
}
|
||||
|
||||
@interface Baz {
|
||||
String[] value() default {};
|
||||
|
||||
String[] value2() default {};
|
||||
}
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@Foo({"b", "a"})
|
||||
A fooValue();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@Foo(value2 = {"b", "a"})
|
||||
A fooValue2();
|
||||
|
||||
@Bar({"b", "a"})
|
||||
A barValue();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@Bar(value2 = {"b", "a"})
|
||||
A barValue2();
|
||||
|
||||
@Baz({"b", "a"})
|
||||
A bazValue();
|
||||
|
||||
@Baz(value2 = {"b", "a"})
|
||||
A bazValue2();
|
||||
}
|
||||
""")
|
||||
"package pkg;",
|
||||
"",
|
||||
"interface A {",
|
||||
" @interface Foo {",
|
||||
" String[] value() default {};",
|
||||
"",
|
||||
" String[] value2() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @interface Bar {",
|
||||
" String[] value() default {};",
|
||||
"",
|
||||
" String[] value2() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @interface Baz {",
|
||||
" String[] value() default {};",
|
||||
"",
|
||||
" String[] value2() default {};",
|
||||
" }",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Foo({\"b\", \"a\"})",
|
||||
" A fooValue();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Foo(value2 = {\"b\", \"a\"})",
|
||||
" A fooValue2();",
|
||||
"",
|
||||
" @Bar({\"b\", \"a\"})",
|
||||
" A barValue();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Bar(value2 = {\"b\", \"a\"})",
|
||||
" A barValue2();",
|
||||
"",
|
||||
" @Baz({\"b\", \"a\"})",
|
||||
" A bazValue();",
|
||||
"",
|
||||
" @Baz(value2 = {\"b\", \"a\"})",
|
||||
" A bazValue2();",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,124 +11,122 @@ final class LexicographicalAnnotationListingTest {
|
||||
CompilationTestHelper.newInstance(LexicographicalAnnotationListing.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Repeatable;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
interface A {
|
||||
@Repeatable(Foos.class)
|
||||
@interface Foo {
|
||||
String[] value() default {};
|
||||
|
||||
int[] ints() default {};
|
||||
|
||||
Bar[] anns() default {};
|
||||
}
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@interface Bar {
|
||||
String[] value() default {};
|
||||
}
|
||||
|
||||
@interface Baz {
|
||||
String[] str() default {};
|
||||
}
|
||||
|
||||
@interface Foos {
|
||||
Foo[] value();
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE_USE)
|
||||
@interface FooTypeUse {
|
||||
String[] value() default {};
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE_USE)
|
||||
@interface BarTypeUse {
|
||||
String[] value() default {};
|
||||
}
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@Foo
|
||||
@Bar
|
||||
A unsortedSimpleCase();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@Foo()
|
||||
@Bar()
|
||||
A unsortedWithParens();
|
||||
|
||||
@Foo()
|
||||
A onlyOneAnnotation();
|
||||
|
||||
@Bar
|
||||
@Foo()
|
||||
A sortedAnnotationsOneWithParens();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@Foo
|
||||
@Baz
|
||||
@Bar
|
||||
A threeUnsortedAnnotationsSameInitialLetter();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@Bar
|
||||
@Foo()
|
||||
@Baz
|
||||
A firstOrderedWithTwoUnsortedAnnotations();
|
||||
|
||||
@Bar
|
||||
@Baz
|
||||
@Foo()
|
||||
A threeSortedAnnotations();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@Foo({"b"})
|
||||
@Bar({"a"})
|
||||
A unsortedWithStringAttributes();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@Baz(str = {"a", "b"})
|
||||
@Foo(ints = {1, 0})
|
||||
@Bar
|
||||
A unsortedWithAttributes();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@Bar
|
||||
@Foo(anns = {@Bar("b"), @Bar("a")})
|
||||
@Baz
|
||||
A unsortedWithNestedBar();
|
||||
|
||||
@Bar
|
||||
@Baz
|
||||
@Foo(anns = {@Bar("b"), @Bar("a")})
|
||||
A sortedWithNestedBar();
|
||||
|
||||
@Foo(anns = {@Bar("b"), @Bar("a")})
|
||||
@Foo(ints = {1, 2})
|
||||
@Foo({"b"})
|
||||
A sortedRepeatableAnnotation();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@Foo(anns = {@Bar("b"), @Bar("a")})
|
||||
@Bar
|
||||
@Foo(ints = {1, 2})
|
||||
A unsortedRepeatableAnnotation();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
default @FooTypeUse @BarTypeUse A unsortedTypeAnnotations() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@Baz
|
||||
@Bar
|
||||
default @FooTypeUse @BarTypeUse A unsortedTypeUseAndOtherAnnotations() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import java.lang.annotation.ElementType;",
|
||||
"import java.lang.annotation.Repeatable;",
|
||||
"import java.lang.annotation.Target;",
|
||||
"",
|
||||
"interface A {",
|
||||
" @Repeatable(Foos.class)",
|
||||
" @interface Foo {",
|
||||
" String[] value() default {};",
|
||||
"",
|
||||
" int[] ints() default {};",
|
||||
"",
|
||||
" Bar[] anns() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @Target(ElementType.METHOD)",
|
||||
" @interface Bar {",
|
||||
" String[] value() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @interface Baz {",
|
||||
" String[] str() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @interface Foos {",
|
||||
" Foo[] value();",
|
||||
" }",
|
||||
"",
|
||||
" @Target(ElementType.TYPE_USE)",
|
||||
" @interface FooTypeUse {",
|
||||
" String[] value() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @Target(ElementType.TYPE_USE)",
|
||||
" @interface BarTypeUse {",
|
||||
" String[] value() default {};",
|
||||
" }",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Foo",
|
||||
" @Bar",
|
||||
" A unsortedSimpleCase();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Foo()",
|
||||
" @Bar()",
|
||||
" A unsortedWithParens();",
|
||||
"",
|
||||
" @Foo()",
|
||||
" A onlyOneAnnotation();",
|
||||
"",
|
||||
" @Bar",
|
||||
" @Foo()",
|
||||
" A sortedAnnotationsOneWithParens();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Foo",
|
||||
" @Baz",
|
||||
" @Bar",
|
||||
" A threeUnsortedAnnotationsSameInitialLetter();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Bar",
|
||||
" @Foo()",
|
||||
" @Baz",
|
||||
" A firstOrderedWithTwoUnsortedAnnotations();",
|
||||
"",
|
||||
" @Bar",
|
||||
" @Baz",
|
||||
" @Foo()",
|
||||
" A threeSortedAnnotations();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Foo({\"b\"})",
|
||||
" @Bar({\"a\"})",
|
||||
" A unsortedWithStringAttributes();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Baz(str = {\"a\", \"b\"})",
|
||||
" @Foo(ints = {1, 0})",
|
||||
" @Bar",
|
||||
" A unsortedWithAttributes();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Bar",
|
||||
" @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")})",
|
||||
" @Baz",
|
||||
" A unsortedWithNestedBar();",
|
||||
"",
|
||||
" @Bar",
|
||||
" @Baz",
|
||||
" @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")})",
|
||||
" A sortedWithNestedBar();",
|
||||
"",
|
||||
" @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")})",
|
||||
" @Foo(ints = {1, 2})",
|
||||
" @Foo({\"b\"})",
|
||||
" A sortedRepeatableAnnotation();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")})",
|
||||
" @Bar",
|
||||
" @Foo(ints = {1, 2})",
|
||||
" A unsortedRepeatableAnnotation();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" default @FooTypeUse @BarTypeUse A unsortedTypeAnnotations() {",
|
||||
" return null;",
|
||||
" }",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @Baz",
|
||||
" @Bar",
|
||||
" default @FooTypeUse @BarTypeUse A unsortedTypeUseAndOtherAnnotations() {",
|
||||
" return null;",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -137,170 +135,166 @@ final class LexicographicalAnnotationListingTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(LexicographicalAnnotationListing.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Repeatable;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
interface A {
|
||||
@Repeatable(Foos.class)
|
||||
@interface Foo {
|
||||
String[] value() default {};
|
||||
|
||||
int[] ints() default {};
|
||||
|
||||
Bar[] anns() default {};
|
||||
}
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@interface Bar {
|
||||
String[] value() default {};
|
||||
}
|
||||
|
||||
@interface Baz {
|
||||
String[] str() default {};
|
||||
}
|
||||
|
||||
@interface Foos {
|
||||
Foo[] value();
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE_USE)
|
||||
@interface FooTypeUse {
|
||||
String[] value() default {};
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE_USE)
|
||||
@interface BarTypeUse {
|
||||
String[] value() default {};
|
||||
}
|
||||
|
||||
@Bar
|
||||
A singleAnnotation();
|
||||
|
||||
@Bar
|
||||
@Foo
|
||||
A sortedAnnotations();
|
||||
|
||||
@Foo
|
||||
@Bar
|
||||
A unsortedAnnotations();
|
||||
|
||||
@Foo()
|
||||
@Baz()
|
||||
@Bar
|
||||
A unsortedAnnotationsWithSomeParens();
|
||||
|
||||
@Bar
|
||||
@Baz(str = {"a", "b"})
|
||||
@Foo()
|
||||
A unsortedAnnotationsOneContainingAttributes();
|
||||
|
||||
@Baz(str = {"a", "b"})
|
||||
@Foo(anns = {@Bar("b"), @Bar("a")})
|
||||
@Bar({"b"})
|
||||
A unsortedAnnotationsWithAttributes();
|
||||
|
||||
@Foo(anns = {@Bar("b"), @Bar("a")})
|
||||
@Foo(ints = {1, 2})
|
||||
@Foo({"b"})
|
||||
A sortedRepeatableAnnotation();
|
||||
|
||||
@Foo(anns = {@Bar("b"), @Bar("a")})
|
||||
@Bar
|
||||
@Foo(ints = {1, 2})
|
||||
A unsortedRepeatableAnnotation();
|
||||
|
||||
@Baz
|
||||
@Bar
|
||||
default @FooTypeUse @BarTypeUse A unsortedWithTypeUseAnnotations() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import java.lang.annotation.ElementType;",
|
||||
"import java.lang.annotation.Repeatable;",
|
||||
"import java.lang.annotation.Target;",
|
||||
"",
|
||||
"interface A {",
|
||||
" @Repeatable(Foos.class)",
|
||||
" @interface Foo {",
|
||||
" String[] value() default {};",
|
||||
"",
|
||||
" int[] ints() default {};",
|
||||
"",
|
||||
" Bar[] anns() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @Target(ElementType.METHOD)",
|
||||
" @interface Bar {",
|
||||
" String[] value() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @interface Baz {",
|
||||
" String[] str() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @interface Foos {",
|
||||
" Foo[] value();",
|
||||
" }",
|
||||
"",
|
||||
" @Target(ElementType.TYPE_USE)",
|
||||
" @interface FooTypeUse {",
|
||||
" String[] value() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @Target(ElementType.TYPE_USE)",
|
||||
" @interface BarTypeUse {",
|
||||
" String[] value() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @Bar",
|
||||
" A singleAnnotation();",
|
||||
"",
|
||||
" @Bar",
|
||||
" @Foo",
|
||||
" A sortedAnnotations();",
|
||||
"",
|
||||
" @Foo",
|
||||
" @Bar",
|
||||
" A unsortedAnnotations();",
|
||||
"",
|
||||
" @Foo()",
|
||||
" @Baz()",
|
||||
" @Bar",
|
||||
" A unsortedAnnotationsWithSomeParens();",
|
||||
"",
|
||||
" @Bar",
|
||||
" @Baz(str = {\"a\", \"b\"})",
|
||||
" @Foo()",
|
||||
" A unsortedAnnotationsOneContainingAttributes();",
|
||||
"",
|
||||
" @Baz(str = {\"a\", \"b\"})",
|
||||
" @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")})",
|
||||
" @Bar({\"b\"})",
|
||||
" A unsortedAnnotationsWithAttributes();",
|
||||
"",
|
||||
" @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")})",
|
||||
" @Foo(ints = {1, 2})",
|
||||
" @Foo({\"b\"})",
|
||||
" A sortedRepeatableAnnotation();",
|
||||
"",
|
||||
" @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")})",
|
||||
" @Bar",
|
||||
" @Foo(ints = {1, 2})",
|
||||
" A unsortedRepeatableAnnotation();",
|
||||
"",
|
||||
" @Baz",
|
||||
" @Bar",
|
||||
" default @FooTypeUse @BarTypeUse A unsortedWithTypeUseAnnotations() {",
|
||||
" return null;",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Repeatable;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
interface A {
|
||||
@Repeatable(Foos.class)
|
||||
@interface Foo {
|
||||
String[] value() default {};
|
||||
|
||||
int[] ints() default {};
|
||||
|
||||
Bar[] anns() default {};
|
||||
}
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@interface Bar {
|
||||
String[] value() default {};
|
||||
}
|
||||
|
||||
@interface Baz {
|
||||
String[] str() default {};
|
||||
}
|
||||
|
||||
@interface Foos {
|
||||
Foo[] value();
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE_USE)
|
||||
@interface FooTypeUse {
|
||||
String[] value() default {};
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE_USE)
|
||||
@interface BarTypeUse {
|
||||
String[] value() default {};
|
||||
}
|
||||
|
||||
@Bar
|
||||
A singleAnnotation();
|
||||
|
||||
@Bar
|
||||
@Foo
|
||||
A sortedAnnotations();
|
||||
|
||||
@Bar
|
||||
@Foo
|
||||
A unsortedAnnotations();
|
||||
|
||||
@Bar
|
||||
@Baz()
|
||||
@Foo()
|
||||
A unsortedAnnotationsWithSomeParens();
|
||||
|
||||
@Bar
|
||||
@Baz(str = {"a", "b"})
|
||||
@Foo()
|
||||
A unsortedAnnotationsOneContainingAttributes();
|
||||
|
||||
@Bar({"b"})
|
||||
@Baz(str = {"a", "b"})
|
||||
@Foo(anns = {@Bar("b"), @Bar("a")})
|
||||
A unsortedAnnotationsWithAttributes();
|
||||
|
||||
@Foo(anns = {@Bar("b"), @Bar("a")})
|
||||
@Foo(ints = {1, 2})
|
||||
@Foo({"b"})
|
||||
A sortedRepeatableAnnotation();
|
||||
|
||||
@Bar
|
||||
@Foo(anns = {@Bar("b"), @Bar("a")})
|
||||
@Foo(ints = {1, 2})
|
||||
A unsortedRepeatableAnnotation();
|
||||
|
||||
@Bar
|
||||
@Baz
|
||||
default @BarTypeUse @FooTypeUse A unsortedWithTypeUseAnnotations() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import java.lang.annotation.ElementType;",
|
||||
"import java.lang.annotation.Repeatable;",
|
||||
"import java.lang.annotation.Target;",
|
||||
"",
|
||||
"interface A {",
|
||||
" @Repeatable(Foos.class)",
|
||||
" @interface Foo {",
|
||||
" String[] value() default {};",
|
||||
"",
|
||||
" int[] ints() default {};",
|
||||
"",
|
||||
" Bar[] anns() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @Target(ElementType.METHOD)",
|
||||
" @interface Bar {",
|
||||
" String[] value() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @interface Baz {",
|
||||
" String[] str() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @interface Foos {",
|
||||
" Foo[] value();",
|
||||
" }",
|
||||
"",
|
||||
" @Target(ElementType.TYPE_USE)",
|
||||
" @interface FooTypeUse {",
|
||||
" String[] value() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @Target(ElementType.TYPE_USE)",
|
||||
" @interface BarTypeUse {",
|
||||
" String[] value() default {};",
|
||||
" }",
|
||||
"",
|
||||
" @Bar",
|
||||
" A singleAnnotation();",
|
||||
"",
|
||||
" @Bar",
|
||||
" @Foo",
|
||||
" A sortedAnnotations();",
|
||||
"",
|
||||
" @Bar",
|
||||
" @Foo",
|
||||
" A unsortedAnnotations();",
|
||||
"",
|
||||
" @Bar",
|
||||
" @Baz()",
|
||||
" @Foo()",
|
||||
" A unsortedAnnotationsWithSomeParens();",
|
||||
"",
|
||||
" @Bar",
|
||||
" @Baz(str = {\"a\", \"b\"})",
|
||||
" @Foo()",
|
||||
" A unsortedAnnotationsOneContainingAttributes();",
|
||||
"",
|
||||
" @Bar({\"b\"})",
|
||||
" @Baz(str = {\"a\", \"b\"})",
|
||||
" @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")})",
|
||||
" A unsortedAnnotationsWithAttributes();",
|
||||
"",
|
||||
" @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")})",
|
||||
" @Foo(ints = {1, 2})",
|
||||
" @Foo({\"b\"})",
|
||||
" A sortedRepeatableAnnotation();",
|
||||
"",
|
||||
" @Bar",
|
||||
" @Foo(anns = {@Bar(\"b\"), @Bar(\"a\")})",
|
||||
" @Foo(ints = {1, 2})",
|
||||
" A unsortedRepeatableAnnotation();",
|
||||
"",
|
||||
" @Bar",
|
||||
" @Baz",
|
||||
" default @BarTypeUse @FooTypeUse A unsortedWithTypeUseAnnotations() {",
|
||||
" return null;",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,88 +11,86 @@ final class MockitoMockClassReferenceTest {
|
||||
CompilationTestHelper.newInstance(MockitoMockClassReference.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.withSettings;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
|
||||
class A {
|
||||
{
|
||||
Double d = Objects.requireNonNullElseGet(null, () -> mock(Double.class));
|
||||
Double d2 =
|
||||
Objects.requireNonNullElseGet(
|
||||
null,
|
||||
() -> {
|
||||
return mock(Double.class);
|
||||
});
|
||||
}
|
||||
|
||||
void m() {
|
||||
Number variableMock = 42;
|
||||
// BUG: Diagnostic contains:
|
||||
variableMock = mock(Number.class);
|
||||
// BUG: Diagnostic contains:
|
||||
variableMock = mock(Number.class, "name");
|
||||
// BUG: Diagnostic contains:
|
||||
variableMock = mock(Number.class, InvocationOnMock::callRealMethod);
|
||||
// BUG: Diagnostic contains:
|
||||
variableMock = mock(Number.class, withSettings());
|
||||
variableMock = mock(Integer.class);
|
||||
variableMock = 42;
|
||||
// BUG: Diagnostic contains:
|
||||
List rawMock = mock(List.class);
|
||||
// BUG: Diagnostic contains:
|
||||
List<String> genericMock = mock(List.class);
|
||||
var varMock = mock(Integer.class);
|
||||
Class<? extends Number> numberType = Integer.class;
|
||||
Number variableTypeMock = mock(numberType);
|
||||
Object subtypeMock = mock(Integer.class);
|
||||
|
||||
Number variableSpy = 42;
|
||||
// BUG: Diagnostic contains:
|
||||
variableSpy = spy(Number.class);
|
||||
variableSpy = spy(Integer.class);
|
||||
variableSpy = 42;
|
||||
// BUG: Diagnostic contains:
|
||||
List rawSpy = spy(List.class);
|
||||
// BUG: Diagnostic contains:
|
||||
List<String> genericSpy = spy(List.class);
|
||||
var varSpy = spy(Integer.class);
|
||||
Number variableTypeSpy = spy(numberType);
|
||||
Object subtypeSpy = spy(Integer.class);
|
||||
Object objectSpy = spy(new Object());
|
||||
|
||||
Objects.hash(mock(Integer.class));
|
||||
Integer i = mock(mock(Integer.class));
|
||||
String s = new String(mock(String.class));
|
||||
}
|
||||
|
||||
Double getDoubleMock() {
|
||||
return Objects.requireNonNullElseGet(
|
||||
null,
|
||||
() -> {
|
||||
return mock(Double.class);
|
||||
});
|
||||
}
|
||||
|
||||
Integer getIntegerMock() {
|
||||
// BUG: Diagnostic contains:
|
||||
return mock(Integer.class);
|
||||
}
|
||||
|
||||
<T> T getGenericMock(Class<T> clazz) {
|
||||
return mock(clazz);
|
||||
}
|
||||
|
||||
Number getSubTypeMock() {
|
||||
return mock(Integer.class);
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static org.mockito.Mockito.mock;",
|
||||
"import static org.mockito.Mockito.spy;",
|
||||
"import static org.mockito.Mockito.withSettings;",
|
||||
"",
|
||||
"import java.util.List;",
|
||||
"import java.util.Objects;",
|
||||
"import org.mockito.invocation.InvocationOnMock;",
|
||||
"",
|
||||
"class A {",
|
||||
" {",
|
||||
" Double d = Objects.requireNonNullElseGet(null, () -> mock(Double.class));",
|
||||
" Double d2 =",
|
||||
" Objects.requireNonNullElseGet(",
|
||||
" null,",
|
||||
" () -> {",
|
||||
" return mock(Double.class);",
|
||||
" });",
|
||||
" }",
|
||||
"",
|
||||
" void m() {",
|
||||
" Number variableMock = 42;",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" variableMock = mock(Number.class);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" variableMock = mock(Number.class, \"name\");",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" variableMock = mock(Number.class, InvocationOnMock::callRealMethod);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" variableMock = mock(Number.class, withSettings());",
|
||||
" variableMock = mock(Integer.class);",
|
||||
" variableMock = 42;",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" List rawMock = mock(List.class);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" List<String> genericMock = mock(List.class);",
|
||||
" var varMock = mock(Integer.class);",
|
||||
" Class<? extends Number> numberType = Integer.class;",
|
||||
" Number variableTypeMock = mock(numberType);",
|
||||
" Object subtypeMock = mock(Integer.class);",
|
||||
"",
|
||||
" Number variableSpy = 42;",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" variableSpy = spy(Number.class);",
|
||||
" variableSpy = spy(Integer.class);",
|
||||
" variableSpy = 42;",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" List rawSpy = spy(List.class);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" List<String> genericSpy = spy(List.class);",
|
||||
" var varSpy = spy(Integer.class);",
|
||||
" Number variableTypeSpy = spy(numberType);",
|
||||
" Object subtypeSpy = spy(Integer.class);",
|
||||
" Object objectSpy = spy(new Object());",
|
||||
"",
|
||||
" Objects.hash(mock(Integer.class));",
|
||||
" Integer i = mock(mock(Integer.class));",
|
||||
" String s = new String(mock(String.class));",
|
||||
" }",
|
||||
"",
|
||||
" Double getDoubleMock() {",
|
||||
" return Objects.requireNonNullElseGet(",
|
||||
" null,",
|
||||
" () -> {",
|
||||
" return mock(Double.class);",
|
||||
" });",
|
||||
" }",
|
||||
"",
|
||||
" Integer getIntegerMock() {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" return mock(Integer.class);",
|
||||
" }",
|
||||
"",
|
||||
" <T> T getGenericMock(Class<T> clazz) {",
|
||||
" return mock(clazz);",
|
||||
" }",
|
||||
"",
|
||||
" Number getSubTypeMock() {",
|
||||
" return mock(Integer.class);",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -101,42 +99,38 @@ final class MockitoMockClassReferenceTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(MockitoMockClassReference.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.withSettings;
|
||||
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
Number simpleMock = mock(Number.class);
|
||||
Number namedMock = mock(Number.class, "name");
|
||||
Number customAnswerMock = mock(Number.class, InvocationOnMock::callRealMethod);
|
||||
Number customSettingsMock = mock(Number.class, withSettings());
|
||||
Number simpleSpy = spy(Number.class);
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static org.mockito.Mockito.mock;",
|
||||
"import static org.mockito.Mockito.spy;",
|
||||
"import static org.mockito.Mockito.withSettings;",
|
||||
"",
|
||||
"import org.mockito.invocation.InvocationOnMock;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Number simpleMock = mock(Number.class);",
|
||||
" Number namedMock = mock(Number.class, \"name\");",
|
||||
" Number customAnswerMock = mock(Number.class, InvocationOnMock::callRealMethod);",
|
||||
" Number customSettingsMock = mock(Number.class, withSettings());",
|
||||
" Number simpleSpy = spy(Number.class);",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.withSettings;
|
||||
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
Number simpleMock = mock();
|
||||
Number namedMock = mock("name");
|
||||
Number customAnswerMock = mock(InvocationOnMock::callRealMethod);
|
||||
Number customSettingsMock = mock(withSettings());
|
||||
Number simpleSpy = spy();
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static org.mockito.Mockito.mock;",
|
||||
"import static org.mockito.Mockito.spy;",
|
||||
"import static org.mockito.Mockito.withSettings;",
|
||||
"",
|
||||
"import org.mockito.invocation.InvocationOnMock;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Number simpleMock = mock();",
|
||||
" Number namedMock = mock(\"name\");",
|
||||
" Number customAnswerMock = mock(InvocationOnMock::callRealMethod);",
|
||||
" Number customSettingsMock = mock(withSettings());",
|
||||
" Number simpleSpy = spy();",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,42 +11,40 @@ final class MockitoStubbingTest {
|
||||
CompilationTestHelper.newInstance(MockitoStubbing.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.notNull;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import org.mockito.ArgumentMatchers;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
Runnable runnable = mock(Runnable.class);
|
||||
doAnswer(inv -> null).when(runnable).run();
|
||||
|
||||
Consumer<String> consumer = mock(Consumer.class);
|
||||
doAnswer(inv -> null).when(consumer).accept("foo");
|
||||
doAnswer(inv -> null).when(consumer).accept(notNull());
|
||||
// BUG: Diagnostic contains:
|
||||
doAnswer(inv -> null).when(consumer).accept(ArgumentMatchers.eq("foo"));
|
||||
// BUG: Diagnostic contains:
|
||||
doAnswer(inv -> null).when(consumer).accept(eq(toString()));
|
||||
|
||||
BiConsumer<Integer, String> biConsumer = mock(BiConsumer.class);
|
||||
doAnswer(inv -> null).when(biConsumer).accept(0, "foo");
|
||||
doAnswer(inv -> null).when(biConsumer).accept(eq(0), notNull());
|
||||
doAnswer(inv -> null).when(biConsumer).accept(notNull(), eq("foo"));
|
||||
doAnswer(inv -> null)
|
||||
.when(biConsumer)
|
||||
// BUG: Diagnostic contains:
|
||||
.accept(ArgumentMatchers.eq(0), ArgumentMatchers.eq("foo"));
|
||||
// BUG: Diagnostic contains:
|
||||
doAnswer(inv -> null).when(biConsumer).accept(eq(hashCode()), eq(toString()));
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static org.mockito.ArgumentMatchers.eq;",
|
||||
"import static org.mockito.ArgumentMatchers.notNull;",
|
||||
"import static org.mockito.Mockito.doAnswer;",
|
||||
"import static org.mockito.Mockito.mock;",
|
||||
"",
|
||||
"import java.util.function.BiConsumer;",
|
||||
"import java.util.function.Consumer;",
|
||||
"import org.mockito.ArgumentMatchers;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Runnable runnable = mock(Runnable.class);",
|
||||
" doAnswer(inv -> null).when(runnable).run();",
|
||||
"",
|
||||
" Consumer<String> consumer = mock(Consumer.class);",
|
||||
" doAnswer(inv -> null).when(consumer).accept(\"foo\");",
|
||||
" doAnswer(inv -> null).when(consumer).accept(notNull());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" doAnswer(inv -> null).when(consumer).accept(ArgumentMatchers.eq(\"foo\"));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" doAnswer(inv -> null).when(consumer).accept(eq(toString()));",
|
||||
"",
|
||||
" BiConsumer<Integer, String> biConsumer = mock(BiConsumer.class);",
|
||||
" doAnswer(inv -> null).when(biConsumer).accept(0, \"foo\");",
|
||||
" doAnswer(inv -> null).when(biConsumer).accept(eq(0), notNull());",
|
||||
" doAnswer(inv -> null).when(biConsumer).accept(notNull(), eq(\"foo\"));",
|
||||
" doAnswer(inv -> null)",
|
||||
" .when(biConsumer)",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" .accept(ArgumentMatchers.eq(0), ArgumentMatchers.eq(\"foo\"));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" doAnswer(inv -> null).when(biConsumer).accept(eq(hashCode()), eq(toString()));",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -55,52 +53,48 @@ final class MockitoStubbingTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(MockitoStubbing.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import org.mockito.ArgumentMatchers;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
Consumer<String> consumer = mock(Consumer.class);
|
||||
doAnswer(inv -> null).when(consumer).accept(ArgumentMatchers.eq("foo"));
|
||||
doAnswer(inv -> null).when(consumer).accept(eq(toString()));
|
||||
|
||||
BiConsumer<Integer, String> biConsumer = mock(BiConsumer.class);
|
||||
doAnswer(inv -> null)
|
||||
.when(biConsumer)
|
||||
.accept(ArgumentMatchers.eq(0), ArgumentMatchers.eq("foo"));
|
||||
doAnswer(inv -> null).when(biConsumer).accept(eq(hashCode()), eq(toString()));
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static org.mockito.ArgumentMatchers.eq;",
|
||||
"import static org.mockito.Mockito.doAnswer;",
|
||||
"import static org.mockito.Mockito.mock;",
|
||||
"",
|
||||
"import java.util.function.BiConsumer;",
|
||||
"import java.util.function.Consumer;",
|
||||
"import org.mockito.ArgumentMatchers;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Consumer<String> consumer = mock(Consumer.class);",
|
||||
" doAnswer(inv -> null).when(consumer).accept(ArgumentMatchers.eq(\"foo\"));",
|
||||
" doAnswer(inv -> null).when(consumer).accept(eq(toString()));",
|
||||
"",
|
||||
" BiConsumer<Integer, String> biConsumer = mock(BiConsumer.class);",
|
||||
" doAnswer(inv -> null)",
|
||||
" .when(biConsumer)",
|
||||
" .accept(ArgumentMatchers.eq(0), ArgumentMatchers.eq(\"foo\"));",
|
||||
" doAnswer(inv -> null).when(biConsumer).accept(eq(hashCode()), eq(toString()));",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import org.mockito.ArgumentMatchers;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
Consumer<String> consumer = mock(Consumer.class);
|
||||
doAnswer(inv -> null).when(consumer).accept("foo");
|
||||
doAnswer(inv -> null).when(consumer).accept(toString());
|
||||
|
||||
BiConsumer<Integer, String> biConsumer = mock(BiConsumer.class);
|
||||
doAnswer(inv -> null).when(biConsumer).accept(0, "foo");
|
||||
doAnswer(inv -> null).when(biConsumer).accept(hashCode(), toString());
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static org.mockito.ArgumentMatchers.eq;",
|
||||
"import static org.mockito.Mockito.doAnswer;",
|
||||
"import static org.mockito.Mockito.mock;",
|
||||
"",
|
||||
"import java.util.function.BiConsumer;",
|
||||
"import java.util.function.Consumer;",
|
||||
"import org.mockito.ArgumentMatchers;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Consumer<String> consumer = mock(Consumer.class);",
|
||||
" doAnswer(inv -> null).when(consumer).accept(\"foo\");",
|
||||
" doAnswer(inv -> null).when(consumer).accept(toString());",
|
||||
"",
|
||||
" BiConsumer<Integer, String> biConsumer = mock(BiConsumer.class);",
|
||||
" doAnswer(inv -> null).when(biConsumer).accept(0, \"foo\");",
|
||||
" doAnswer(inv -> null).when(biConsumer).accept(hashCode(), toString());",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,20 +9,18 @@ final class MongoDBTextFilterUsageTest {
|
||||
CompilationTestHelper.newInstance(MongoDBTextFilterUsage.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import com.mongodb.client.model.Filters;
|
||||
import com.mongodb.client.model.TextSearchOptions;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
Filters.eq("foo", "bar");
|
||||
// BUG: Diagnostic contains:
|
||||
Filters.text("foo");
|
||||
// BUG: Diagnostic contains:
|
||||
Filters.text("foo", new TextSearchOptions());
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import com.mongodb.client.model.Filters;",
|
||||
"import com.mongodb.client.model.TextSearchOptions;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Filters.eq(\"foo\", \"bar\");",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Filters.text(\"foo\");",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Filters.text(\"foo\", new TextSearchOptions());",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,33 +9,31 @@ final class NestedOptionalsTest {
|
||||
CompilationTestHelper.newInstance(NestedOptionals.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
Optional.empty();
|
||||
Optional.of(1);
|
||||
// BUG: Diagnostic contains:
|
||||
Optional.of(Optional.empty());
|
||||
// BUG: Diagnostic contains:
|
||||
Optional.of(Optional.of(1));
|
||||
|
||||
Optional.ofNullable(null);
|
||||
// BUG: Diagnostic contains:
|
||||
Optional.ofNullable((Optional) null);
|
||||
|
||||
Optional.of("foo").map(String::length);
|
||||
// BUG: Diagnostic contains:
|
||||
Optional.of("foo").map(Optional::of);
|
||||
|
||||
Stream.of("foo").findFirst();
|
||||
// BUG: Diagnostic contains:
|
||||
Stream.of("foo").map(Optional::of).findFirst();
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import java.util.Optional;",
|
||||
"import java.util.stream.Stream;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Optional.empty();",
|
||||
" Optional.of(1);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Optional.of(Optional.empty());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Optional.of(Optional.of(1));",
|
||||
"",
|
||||
" Optional.ofNullable(null);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Optional.ofNullable((Optional) null);",
|
||||
"",
|
||||
" Optional.of(\"foo\").map(String::length);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Optional.of(\"foo\").map(Optional::of);",
|
||||
"",
|
||||
" Stream.of(\"foo\").findFirst();",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Stream.of(\"foo\").map(Optional::of).findFirst();",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,31 +9,29 @@ final class NestedPublishersTest {
|
||||
CompilationTestHelper.newInstance(NestedPublishers.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import org.reactivestreams.Publisher;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.GroupedFlux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
Mono.empty();
|
||||
Flux.just(1);
|
||||
Flux.just(1, 2).groupBy(i -> i).map(groupedFlux -> (GroupedFlux) groupedFlux);
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Mono.just(Mono.empty());
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(Flux.empty());
|
||||
// BUG: Diagnostic contains:
|
||||
Mono.just((Flux) Flux.just(1));
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just((Publisher) Mono.just(1));
|
||||
// BUG: Diagnostic contains:
|
||||
Mono.just(1).map(Mono::just);
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import org.reactivestreams.Publisher;",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"import reactor.core.publisher.GroupedFlux;",
|
||||
"import reactor.core.publisher.Mono;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Mono.empty();",
|
||||
" Flux.just(1);",
|
||||
" Flux.just(1, 2).groupBy(i -> i).map(groupedFlux -> (GroupedFlux) groupedFlux);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Mono.just(Mono.empty());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(Flux.empty());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Mono.just((Flux) Flux.just(1));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just((Publisher) Mono.just(1));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Mono.just(1).map(Mono::just);",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,97 +11,95 @@ final class NonEmptyMonoTest {
|
||||
CompilationTestHelper.newInstance(NonEmptyMono.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
import static java.util.function.Function.identity;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
Mono.just(1).defaultIfEmpty(2);
|
||||
Mono.just(1).single();
|
||||
Mono.just(1).switchIfEmpty(Mono.just(2));
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1).all(x -> true).defaultIfEmpty(true);
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1).any(x -> true).single();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1).collect(toImmutableList()).switchIfEmpty(Mono.just(ImmutableList.of()));
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1).collect(ArrayList::new, List::add).defaultIfEmpty(new ArrayList<>());
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1).collectList().single();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1).collectMap(identity()).switchIfEmpty(Mono.just(ImmutableMap.of()));
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1).collectMap(identity(), identity()).defaultIfEmpty(ImmutableMap.of());
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1).collectMap(identity(), identity(), HashMap::new).single();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1).collectMultimap(identity()).switchIfEmpty(Mono.just(ImmutableMap.of()));
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1).collectMultimap(identity(), identity()).defaultIfEmpty(ImmutableMap.of());
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1).collectMultimap(identity(), identity(), HashMap::new).single();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1).collectSortedList().defaultIfEmpty(ImmutableList.of());
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1).collectSortedList((o1, o2) -> 0).single();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1).count().switchIfEmpty(Mono.just(2L));
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1).elementAt(0).defaultIfEmpty(1);
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1).elementAt(0, 2).single();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1).hasElement(2).switchIfEmpty(Mono.just(true));
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1).hasElements().defaultIfEmpty(true);
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1).last().single();
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1).last(2).switchIfEmpty(Mono.just(3));
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1).reduceWith(() -> 0, Integer::sum).defaultIfEmpty(2);
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1).single().single();
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1).single(2).switchIfEmpty(Mono.just(3));
|
||||
|
||||
Flux.just(1).reduce(Integer::sum).defaultIfEmpty(2);
|
||||
// BUG: Diagnostic contains:
|
||||
Flux.just(1).reduce(2, Integer::sum).single();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Mono.just(1).defaultIfEmpty(1).switchIfEmpty(Mono.just(2));
|
||||
// BUG: Diagnostic contains:
|
||||
Mono.just(1).hasElement().defaultIfEmpty(true);
|
||||
// BUG: Diagnostic contains:
|
||||
Mono.just(1).single().single();
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static com.google.common.collect.ImmutableList.toImmutableList;",
|
||||
"import static java.util.function.Function.identity;",
|
||||
"",
|
||||
"import com.google.common.collect.ImmutableList;",
|
||||
"import com.google.common.collect.ImmutableMap;",
|
||||
"import java.util.ArrayList;",
|
||||
"import java.util.HashMap;",
|
||||
"import java.util.List;",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"import reactor.core.publisher.Mono;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Mono.just(1).defaultIfEmpty(2);",
|
||||
" Mono.just(1).single();",
|
||||
" Mono.just(1).switchIfEmpty(Mono.just(2));",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).all(x -> true).defaultIfEmpty(true);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).any(x -> true).single();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).collect(toImmutableList()).switchIfEmpty(Mono.just(ImmutableList.of()));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).collect(ArrayList::new, List::add).defaultIfEmpty(new ArrayList<>());",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).collectList().single();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).collectMap(identity()).switchIfEmpty(Mono.just(ImmutableMap.of()));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).collectMap(identity(), identity()).defaultIfEmpty(ImmutableMap.of());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).collectMap(identity(), identity(), HashMap::new).single();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).collectMultimap(identity()).switchIfEmpty(Mono.just(ImmutableMap.of()));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).collectMultimap(identity(), identity()).defaultIfEmpty(ImmutableMap.of());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).collectMultimap(identity(), identity(), HashMap::new).single();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).collectSortedList().defaultIfEmpty(ImmutableList.of());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).collectSortedList((o1, o2) -> 0).single();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).count().switchIfEmpty(Mono.just(2L));",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).elementAt(0).defaultIfEmpty(1);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).elementAt(0, 2).single();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).hasElement(2).switchIfEmpty(Mono.just(true));",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).hasElements().defaultIfEmpty(true);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).last().single();",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).last(2).switchIfEmpty(Mono.just(3));",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).reduceWith(() -> 0, Integer::sum).defaultIfEmpty(2);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).single().single();",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).single(2).switchIfEmpty(Mono.just(3));",
|
||||
"",
|
||||
" Flux.just(1).reduce(Integer::sum).defaultIfEmpty(2);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Flux.just(1).reduce(2, Integer::sum).single();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Mono.just(1).defaultIfEmpty(1).switchIfEmpty(Mono.just(2));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Mono.just(1).hasElement().defaultIfEmpty(true);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Mono.just(1).single().single();",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -110,46 +108,42 @@ final class NonEmptyMonoTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(NonEmptyMono.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
Flux.just(1).collect(toImmutableList()).single();
|
||||
Flux.just(1).collect(toImmutableList()).defaultIfEmpty(ImmutableList.of());
|
||||
Flux.just(1).collect(toImmutableList()).switchIfEmpty(Mono.just(ImmutableList.of()));
|
||||
|
||||
Mono.just(2).hasElement().single();
|
||||
Mono.just(2).hasElement().defaultIfEmpty(true);
|
||||
Mono.just(2).hasElement().switchIfEmpty(Mono.just(true));
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static com.google.common.collect.ImmutableList.toImmutableList;",
|
||||
"",
|
||||
"import com.google.common.collect.ImmutableList;",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"import reactor.core.publisher.Mono;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Flux.just(1).collect(toImmutableList()).single();",
|
||||
" Flux.just(1).collect(toImmutableList()).defaultIfEmpty(ImmutableList.of());",
|
||||
" Flux.just(1).collect(toImmutableList()).switchIfEmpty(Mono.just(ImmutableList.of()));",
|
||||
"",
|
||||
" Mono.just(2).hasElement().single();",
|
||||
" Mono.just(2).hasElement().defaultIfEmpty(true);",
|
||||
" Mono.just(2).hasElement().switchIfEmpty(Mono.just(true));",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
Flux.just(1).collect(toImmutableList());
|
||||
Flux.just(1).collect(toImmutableList());
|
||||
Flux.just(1).collect(toImmutableList());
|
||||
|
||||
Mono.just(2).hasElement();
|
||||
Mono.just(2).hasElement();
|
||||
Mono.just(2).hasElement();
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static com.google.common.collect.ImmutableList.toImmutableList;",
|
||||
"",
|
||||
"import com.google.common.collect.ImmutableList;",
|
||||
"import reactor.core.publisher.Flux;",
|
||||
"import reactor.core.publisher.Mono;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Flux.just(1).collect(toImmutableList());",
|
||||
" Flux.just(1).collect(toImmutableList());",
|
||||
" Flux.just(1).collect(toImmutableList());",
|
||||
"",
|
||||
" Mono.just(2).hasElement();",
|
||||
" Mono.just(2).hasElement();",
|
||||
" Mono.just(2).hasElement();",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,76 +40,81 @@ final class NonStaticImportTest {
|
||||
CompilationTestHelper.newInstance(NonStaticImport.class, getClass())
|
||||
.addSourceLines(
|
||||
"pkg/A.java",
|
||||
"""
|
||||
package pkg;
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
import static com.google.common.base.Strings.nullToEmpty;
|
||||
// BUG: Diagnostic contains:
|
||||
import static com.google.common.collect.ImmutableList.copyOf;
|
||||
// BUG: Diagnostic contains:
|
||||
import static java.lang.Integer.MAX_VALUE;
|
||||
// BUG: Diagnostic contains:
|
||||
import static java.lang.Integer.MIN_VALUE;
|
||||
// BUG: Diagnostic contains:
|
||||
import static java.time.Clock.systemUTC;
|
||||
// BUG: Diagnostic contains:
|
||||
import static java.time.Instant.MIN;
|
||||
// BUG: Diagnostic contains:
|
||||
import static java.time.ZoneOffset.SHORT_IDS;
|
||||
import static java.time.ZoneOffset.UTC;
|
||||
// BUG: Diagnostic contains:
|
||||
import static java.util.Collections.min;
|
||||
import static java.util.Locale.ENGLISH;
|
||||
// BUG: Diagnostic contains:
|
||||
import static java.util.Locale.ROOT;
|
||||
// BUG: Diagnostic contains:
|
||||
import static java.util.Optional.empty;
|
||||
import static pkg.A.WithMethodThatIsSelectivelyFlagged.list;
|
||||
// BUG: Diagnostic contains:
|
||||
import static reactor.core.publisher.Flux.just;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import pkg.A.Wrapper.INSTANCE;
|
||||
|
||||
class A {
|
||||
private Integer MIN_VALUE = 12;
|
||||
|
||||
void m() {
|
||||
nullToEmpty(null);
|
||||
copyOf(ImmutableList.of());
|
||||
int max = MAX_VALUE;
|
||||
int min = MIN_VALUE;
|
||||
systemUTC();
|
||||
Instant minInstant = MIN;
|
||||
Map<String, String> shortIds = SHORT_IDS;
|
||||
ZoneOffset utc = UTC;
|
||||
min(ImmutableSet.of());
|
||||
Locale english = ENGLISH;
|
||||
Locale root = ROOT;
|
||||
empty();
|
||||
just();
|
||||
|
||||
list();
|
||||
new INSTANCE();
|
||||
}
|
||||
|
||||
static final class WithMethodThatIsSelectivelyFlagged {
|
||||
static ImmutableList<String> list() {
|
||||
return ImmutableList.of();
|
||||
}
|
||||
}
|
||||
|
||||
static final class Wrapper {
|
||||
static final class INSTANCE {}
|
||||
}
|
||||
}
|
||||
""")
|
||||
"package pkg;",
|
||||
"",
|
||||
"// BUG: Diagnostic contains:",
|
||||
"import static com.google.common.base.Strings.nullToEmpty;",
|
||||
"// BUG: Diagnostic contains:",
|
||||
"import static com.google.common.collect.ImmutableList.copyOf;",
|
||||
"// BUG: Diagnostic contains:",
|
||||
"import static java.lang.Integer.MAX_VALUE;",
|
||||
"// BUG: Diagnostic contains:",
|
||||
"import static java.lang.Integer.MIN_VALUE;",
|
||||
"// BUG: Diagnostic contains:",
|
||||
"import static java.time.Clock.systemUTC;",
|
||||
"// 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:",
|
||||
"import static java.util.Collections.min;",
|
||||
"import static java.util.Locale.ENGLISH;",
|
||||
"// BUG: Diagnostic contains:",
|
||||
"import static java.util.Locale.ROOT;",
|
||||
"// BUG: Diagnostic contains:",
|
||||
"import static java.util.Optional.empty;",
|
||||
"import static pkg.A.WithMethodThatIsSelectivelyFlagged.list;",
|
||||
"// BUG: Diagnostic contains:",
|
||||
"import static reactor.core.publisher.Flux.just;",
|
||||
"",
|
||||
"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;",
|
||||
"import pkg.A.Wrapper.INSTANCE;",
|
||||
"",
|
||||
"class A {",
|
||||
" private Integer MIN_VALUE = 12;",
|
||||
"",
|
||||
" 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;",
|
||||
" ZoneOffset utc = UTC;",
|
||||
" min(ImmutableSet.of());",
|
||||
" Locale english = ENGLISH;",
|
||||
" Locale root = ROOT;",
|
||||
" empty();",
|
||||
" just();",
|
||||
"",
|
||||
" list();",
|
||||
" new INSTANCE();",
|
||||
" }",
|
||||
"",
|
||||
" static final class WithMethodThatIsSelectivelyFlagged {",
|
||||
" static ImmutableList<String> list() {",
|
||||
" return ImmutableList.of();",
|
||||
" }",
|
||||
" }",
|
||||
"",
|
||||
" static final class Wrapper {",
|
||||
" static final class INSTANCE {}",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -118,88 +123,84 @@ final class NonStaticImportTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(NonStaticImport.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static com.google.common.collect.ImmutableList.copyOf;
|
||||
import static com.google.common.collect.ImmutableSet.of;
|
||||
import static java.time.Clock.systemUTC;
|
||||
import static java.time.Instant.MAX;
|
||||
import static java.time.Instant.MIN;
|
||||
import static java.util.Collections.min;
|
||||
import static java.util.Locale.ROOT;
|
||||
import static java.util.Optional.empty;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.time.Clock;
|
||||
import java.time.Instant;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
systemUTC();
|
||||
Clock.systemUTC();
|
||||
|
||||
Optional<Integer> o1 = empty();
|
||||
Optional<Integer> o2 = Optional.empty();
|
||||
|
||||
Object l1 = copyOf(ImmutableList.of());
|
||||
Object l2 = ImmutableList.copyOf(ImmutableList.of());
|
||||
|
||||
Locale lo1 = ROOT;
|
||||
Locale lo2 = Locale.ROOT;
|
||||
|
||||
Instant i1 = MIN;
|
||||
Instant i2 = MAX;
|
||||
|
||||
ImmutableSet.of(min(of()));
|
||||
}
|
||||
|
||||
private static final class WithCustomConstant {
|
||||
private static final Instant MIN = Instant.EPOCH;
|
||||
private static final Instant OTHER = MIN;
|
||||
private static final Instant OTHER_MAX = MAX;
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static com.google.common.collect.ImmutableList.copyOf;",
|
||||
"import static com.google.common.collect.ImmutableSet.of;",
|
||||
"import static java.time.Clock.systemUTC;",
|
||||
"import static java.time.Instant.MAX;",
|
||||
"import static java.time.Instant.MIN;",
|
||||
"import static java.util.Collections.min;",
|
||||
"import static java.util.Locale.ROOT;",
|
||||
"import static java.util.Optional.empty;",
|
||||
"",
|
||||
"import com.google.common.collect.ImmutableList;",
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import java.time.Clock;",
|
||||
"import java.time.Instant;",
|
||||
"import java.util.Locale;",
|
||||
"import java.util.Optional;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" systemUTC();",
|
||||
" Clock.systemUTC();",
|
||||
"",
|
||||
" Optional<Integer> o1 = empty();",
|
||||
" Optional<Integer> o2 = Optional.empty();",
|
||||
"",
|
||||
" Object l1 = copyOf(ImmutableList.of());",
|
||||
" Object l2 = ImmutableList.copyOf(ImmutableList.of());",
|
||||
"",
|
||||
" Locale lo1 = ROOT;",
|
||||
" Locale lo2 = Locale.ROOT;",
|
||||
"",
|
||||
" Instant i1 = MIN;",
|
||||
" Instant i2 = MAX;",
|
||||
"",
|
||||
" ImmutableSet.of(min(of()));",
|
||||
" }",
|
||||
"",
|
||||
" private static final class WithCustomConstant {",
|
||||
" private static final Instant MIN = Instant.EPOCH;",
|
||||
" private static final Instant OTHER = MIN;",
|
||||
" private static final Instant OTHER_MAX = MAX;",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.time.Clock;
|
||||
import java.time.Instant;
|
||||
import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
Clock.systemUTC();
|
||||
Clock.systemUTC();
|
||||
|
||||
Optional<Integer> o1 = Optional.empty();
|
||||
Optional<Integer> o2 = Optional.empty();
|
||||
|
||||
Object l1 = ImmutableList.copyOf(ImmutableList.of());
|
||||
Object l2 = ImmutableList.copyOf(ImmutableList.of());
|
||||
|
||||
Locale lo1 = Locale.ROOT;
|
||||
Locale lo2 = Locale.ROOT;
|
||||
|
||||
Instant i1 = Instant.MIN;
|
||||
Instant i2 = Instant.MAX;
|
||||
|
||||
ImmutableSet.of(Collections.min(ImmutableSet.of()));
|
||||
}
|
||||
|
||||
private static final class WithCustomConstant {
|
||||
private static final Instant MIN = Instant.EPOCH;
|
||||
private static final Instant OTHER = MIN;
|
||||
private static final Instant OTHER_MAX = Instant.MAX;
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import com.google.common.collect.ImmutableList;",
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import java.time.Clock;",
|
||||
"import java.time.Instant;",
|
||||
"import java.util.Collections;",
|
||||
"import java.util.Locale;",
|
||||
"import java.util.Optional;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" Clock.systemUTC();",
|
||||
" Clock.systemUTC();",
|
||||
"",
|
||||
" Optional<Integer> o1 = Optional.empty();",
|
||||
" Optional<Integer> o2 = Optional.empty();",
|
||||
"",
|
||||
" Object l1 = ImmutableList.copyOf(ImmutableList.of());",
|
||||
" Object l2 = ImmutableList.copyOf(ImmutableList.of());",
|
||||
"",
|
||||
" Locale lo1 = Locale.ROOT;",
|
||||
" Locale lo2 = Locale.ROOT;",
|
||||
"",
|
||||
" Instant i1 = Instant.MIN;",
|
||||
" Instant i2 = Instant.MAX;",
|
||||
"",
|
||||
" ImmutableSet.of(Collections.min(ImmutableSet.of()));",
|
||||
" }",
|
||||
"",
|
||||
" private static final class WithCustomConstant {",
|
||||
" private static final Instant MIN = Instant.EPOCH;",
|
||||
" private static final Instant OTHER = MIN;",
|
||||
" private static final Instant OTHER_MAX = Instant.MAX;",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,61 +11,59 @@ final class OptionalOrElseGetTest {
|
||||
CompilationTestHelper.newInstance(OptionalOrElseGet.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import com.google.errorprone.refaster.Refaster;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
class A {
|
||||
private final Optional<Object> optional = Optional.empty();
|
||||
private final String string = optional.toString();
|
||||
|
||||
void m() {
|
||||
Optional.empty().orElse(null);
|
||||
optional.orElse(null);
|
||||
optional.orElse("constant");
|
||||
optional.orElse("constant" + 0);
|
||||
optional.orElse(Boolean.TRUE);
|
||||
optional.orElse(string);
|
||||
optional.orElse(this.string);
|
||||
optional.orElse(Refaster.anyOf("constant", "another"));
|
||||
Optional.<Supplier<String>>empty().orElse(() -> "constant");
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Optional.empty().orElse(string + "constant");
|
||||
// BUG: Diagnostic contains:
|
||||
optional.orElse(string + "constant");
|
||||
// BUG: Diagnostic contains:
|
||||
optional.orElse("constant".toString());
|
||||
// BUG: Diagnostic contains:
|
||||
optional.orElse(string.toString());
|
||||
// BUG: Diagnostic contains:
|
||||
optional.orElse(this.string.toString());
|
||||
// BUG: Diagnostic contains:
|
||||
optional.orElse(String.valueOf(42));
|
||||
// BUG: Diagnostic contains:
|
||||
optional.orElse(string.toString().length());
|
||||
// BUG: Diagnostic contains:
|
||||
optional.orElse("constant".equals(string));
|
||||
// BUG: Diagnostic contains:
|
||||
optional.orElse(string.equals(string));
|
||||
// BUG: Diagnostic contains:
|
||||
optional.orElse(this.string.equals(string));
|
||||
// BUG: Diagnostic contains:
|
||||
optional.orElse(foo());
|
||||
// BUG: Diagnostic contains:
|
||||
optional.orElse(this.foo());
|
||||
// BUG: Diagnostic contains:
|
||||
optional.orElse(new Object() {});
|
||||
// BUG: Diagnostic contains:
|
||||
optional.orElse(new int[0].length);
|
||||
}
|
||||
|
||||
private <T> T foo() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import com.google.errorprone.refaster.Refaster;",
|
||||
"import java.util.Optional;",
|
||||
"import java.util.function.Supplier;",
|
||||
"",
|
||||
"class A {",
|
||||
" private final Optional<Object> optional = Optional.empty();",
|
||||
" private final String string = optional.toString();",
|
||||
"",
|
||||
" void m() {",
|
||||
" Optional.empty().orElse(null);",
|
||||
" optional.orElse(null);",
|
||||
" optional.orElse(\"constant\");",
|
||||
" optional.orElse(\"constant\" + 0);",
|
||||
" optional.orElse(Boolean.TRUE);",
|
||||
" optional.orElse(string);",
|
||||
" optional.orElse(this.string);",
|
||||
" optional.orElse(Refaster.anyOf(\"constant\", \"another\"));",
|
||||
" Optional.<Supplier<String>>empty().orElse(() -> \"constant\");",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Optional.empty().orElse(string + \"constant\");",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" optional.orElse(string + \"constant\");",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" optional.orElse(\"constant\".toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" optional.orElse(string.toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" optional.orElse(this.string.toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" optional.orElse(String.valueOf(42));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" optional.orElse(string.toString().length());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" optional.orElse(\"constant\".equals(string));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" optional.orElse(string.equals(string));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" optional.orElse(this.string.equals(string));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" optional.orElse(foo());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" optional.orElse(this.foo());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" optional.orElse(new Object() {});",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" optional.orElse(new int[0].length);",
|
||||
" }",
|
||||
"",
|
||||
" private <T> T foo() {",
|
||||
" return null;",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -74,70 +72,66 @@ final class OptionalOrElseGetTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(OptionalOrElseGet.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import java.util.Optional;
|
||||
|
||||
class A {
|
||||
private final Optional<Object> optional = Optional.empty();
|
||||
private final String string = optional.toString();
|
||||
|
||||
void m() {
|
||||
optional.orElse(string + "constant");
|
||||
optional.orElse("constant".toString());
|
||||
optional.orElse(string.toString());
|
||||
optional.orElse(this.string.toString());
|
||||
optional.orElse(String.valueOf(42));
|
||||
optional.orElse(string.toString().length());
|
||||
optional.orElse(string.equals(string));
|
||||
optional.orElse(foo());
|
||||
optional.orElse(this.<Number>foo());
|
||||
optional.orElse(this.<String, Integer>bar());
|
||||
optional.orElse(new Object() {});
|
||||
optional.orElse(new int[0].length);
|
||||
}
|
||||
|
||||
private <T> T foo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private <S, T> T bar() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import java.util.Optional;",
|
||||
"",
|
||||
"class A {",
|
||||
" private final Optional<Object> optional = Optional.empty();",
|
||||
" private final String string = optional.toString();",
|
||||
"",
|
||||
" void m() {",
|
||||
" optional.orElse(string + \"constant\");",
|
||||
" optional.orElse(\"constant\".toString());",
|
||||
" optional.orElse(string.toString());",
|
||||
" optional.orElse(this.string.toString());",
|
||||
" optional.orElse(String.valueOf(42));",
|
||||
" optional.orElse(string.toString().length());",
|
||||
" optional.orElse(string.equals(string));",
|
||||
" optional.orElse(foo());",
|
||||
" optional.orElse(this.<Number>foo());",
|
||||
" optional.orElse(this.<String, Integer>bar());",
|
||||
" optional.orElse(new Object() {});",
|
||||
" optional.orElse(new int[0].length);",
|
||||
" }",
|
||||
"",
|
||||
" private <T> T foo() {",
|
||||
" return null;",
|
||||
" }",
|
||||
"",
|
||||
" private <S, T> T bar() {",
|
||||
" return null;",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import java.util.Optional;
|
||||
|
||||
class A {
|
||||
private final Optional<Object> optional = Optional.empty();
|
||||
private final String string = optional.toString();
|
||||
|
||||
void m() {
|
||||
optional.orElseGet(() -> string + "constant");
|
||||
optional.orElseGet("constant"::toString);
|
||||
optional.orElseGet(string::toString);
|
||||
optional.orElseGet(this.string::toString);
|
||||
optional.orElseGet(() -> String.valueOf(42));
|
||||
optional.orElseGet(() -> string.toString().length());
|
||||
optional.orElseGet(() -> string.equals(string));
|
||||
optional.orElseGet(() -> foo());
|
||||
optional.orElseGet(this::<Number>foo);
|
||||
optional.orElseGet(this::<String, Integer>bar);
|
||||
optional.orElseGet(() -> new Object() {});
|
||||
optional.orElseGet(() -> new int[0].length);
|
||||
}
|
||||
|
||||
private <T> T foo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private <S, T> T bar() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import java.util.Optional;",
|
||||
"",
|
||||
"class A {",
|
||||
" private final Optional<Object> optional = Optional.empty();",
|
||||
" private final String string = optional.toString();",
|
||||
"",
|
||||
" void m() {",
|
||||
" optional.orElseGet(() -> string + \"constant\");",
|
||||
" optional.orElseGet(\"constant\"::toString);",
|
||||
" optional.orElseGet(string::toString);",
|
||||
" optional.orElseGet(this.string::toString);",
|
||||
" optional.orElseGet(() -> String.valueOf(42));",
|
||||
" optional.orElseGet(() -> string.toString().length());",
|
||||
" optional.orElseGet(() -> string.equals(string));",
|
||||
" optional.orElseGet(() -> foo());",
|
||||
" optional.orElseGet(this::<Number>foo);",
|
||||
" optional.orElseGet(this::<String, Integer>bar);",
|
||||
" optional.orElseGet(() -> new Object() {});",
|
||||
" optional.orElseGet(() -> new int[0].length);",
|
||||
" }",
|
||||
"",
|
||||
" private <T> T foo() {",
|
||||
" return null;",
|
||||
" }",
|
||||
"",
|
||||
" private <S, T> T bar() {",
|
||||
" return null;",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,23 +14,21 @@ final class RedundantStringConversionTest {
|
||||
CompilationTestHelper.newInstance(RedundantStringConversion.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
class A {
|
||||
private final Object o = new Object();
|
||||
private final String s = o.toString();
|
||||
|
||||
String[] m() {
|
||||
return new String[] {
|
||||
o.toString(),
|
||||
// BUG: Diagnostic contains:
|
||||
s.toString(),
|
||||
String.valueOf(o),
|
||||
// BUG: Diagnostic contains:
|
||||
String.valueOf(s),
|
||||
};
|
||||
}
|
||||
}
|
||||
""")
|
||||
"class A {",
|
||||
" private final Object o = new Object();",
|
||||
" private final String s = o.toString();",
|
||||
"",
|
||||
" String[] m() {",
|
||||
" return new String[] {",
|
||||
" o.toString(),",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s.toString(),",
|
||||
" String.valueOf(o),",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String.valueOf(s),",
|
||||
" };",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -39,61 +37,59 @@ final class RedundantStringConversionTest {
|
||||
CompilationTestHelper.newInstance(RedundantStringConversion.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import java.math.BigInteger;
|
||||
import java.util.Objects;
|
||||
|
||||
class A {
|
||||
private final BigInteger i = BigInteger.ZERO;
|
||||
|
||||
void m1() {
|
||||
String s = i.toString();
|
||||
// BUG: Diagnostic contains:
|
||||
s += this.toString();
|
||||
s += super.toString();
|
||||
// BUG: Diagnostic contains:
|
||||
s += i.toString();
|
||||
s += i.toString(16);
|
||||
// BUG: Diagnostic contains:
|
||||
s += Objects.toString(i);
|
||||
// BUG: Diagnostic contains:
|
||||
s += Objects.toString(null);
|
||||
// BUG: Diagnostic contains:
|
||||
s += String.valueOf(i);
|
||||
// BUG: Diagnostic contains:
|
||||
s += String.valueOf(0);
|
||||
// BUG: Diagnostic contains:
|
||||
s += String.valueOf((String) null);
|
||||
s += String.valueOf(null);
|
||||
s += String.valueOf(new char[0]);
|
||||
s += String.valueOf(new char[0], 0, 0);
|
||||
// BUG: Diagnostic contains:
|
||||
s += Boolean.toString(false);
|
||||
// BUG: Diagnostic contains:
|
||||
s += Byte.toString((byte) 0);
|
||||
// BUG: Diagnostic contains:
|
||||
s += Character.toString((char) 0);
|
||||
// BUG: Diagnostic contains:
|
||||
s += Short.toString((short) 0);
|
||||
// BUG: Diagnostic contains:
|
||||
s += Integer.toString(0);
|
||||
// BUG: Diagnostic contains:
|
||||
s += Long.toString(0);
|
||||
// BUG: Diagnostic contains:
|
||||
s += Float.toString((float) 0.0);
|
||||
// BUG: Diagnostic contains:
|
||||
s += Double.toString(0.0);
|
||||
}
|
||||
|
||||
void m2() {
|
||||
int i = 0;
|
||||
i += 1;
|
||||
i -= 1;
|
||||
i *= 1;
|
||||
i /= 1;
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import java.math.BigInteger;",
|
||||
"import java.util.Objects;",
|
||||
"",
|
||||
"class A {",
|
||||
" private final BigInteger i = BigInteger.ZERO;",
|
||||
"",
|
||||
" void m1() {",
|
||||
" String s = i.toString();",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s += this.toString();",
|
||||
" s += super.toString();",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s += i.toString();",
|
||||
" s += i.toString(16);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s += Objects.toString(i);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s += Objects.toString(null);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s += String.valueOf(i);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s += String.valueOf(0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s += String.valueOf((String) null);",
|
||||
" s += String.valueOf(null);",
|
||||
" s += String.valueOf(new char[0]);",
|
||||
" s += String.valueOf(new char[0], 0, 0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s += Boolean.toString(false);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s += Byte.toString((byte) 0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s += Character.toString((char) 0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s += Short.toString((short) 0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s += Integer.toString(0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s += Long.toString(0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s += Float.toString((float) 0.0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s += Double.toString(0.0);",
|
||||
" }",
|
||||
"",
|
||||
" void m2() {",
|
||||
" int i = 0;",
|
||||
" i += 1;",
|
||||
" i -= 1;",
|
||||
" i *= 1;",
|
||||
" i /= 1;",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -102,95 +98,93 @@ final class RedundantStringConversionTest {
|
||||
CompilationTestHelper.newInstance(RedundantStringConversion.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import java.math.BigInteger;
|
||||
|
||||
class A {
|
||||
private final BigInteger i = BigInteger.ZERO;
|
||||
private final String s = i.toString();
|
||||
|
||||
String[] m1() {
|
||||
return new String[] {
|
||||
// BUG: Diagnostic contains:
|
||||
s + this.toString(),
|
||||
s + super.toString(),
|
||||
// BUG: Diagnostic contains:
|
||||
s + i.toString(),
|
||||
s + i.toString(16),
|
||||
// BUG: Diagnostic contains:
|
||||
s + String.valueOf(i),
|
||||
// BUG: Diagnostic contains:
|
||||
s + String.valueOf(0),
|
||||
// BUG: Diagnostic contains:
|
||||
s + String.valueOf((String) null),
|
||||
s + String.valueOf(null),
|
||||
s + String.valueOf(new char[0]),
|
||||
s + String.valueOf(new char[0], 0, 0),
|
||||
//
|
||||
42 + this.toString(),
|
||||
42 + super.toString(),
|
||||
42 + i.toString(),
|
||||
42 + i.toString(16),
|
||||
42 + String.valueOf(i),
|
||||
// BUG: Diagnostic contains:
|
||||
42 + String.valueOf((String) null),
|
||||
42 + String.valueOf(null),
|
||||
42 + String.valueOf(new char[0]),
|
||||
42 + String.valueOf(new char[0], 0, 0),
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
this.toString() + s,
|
||||
super.toString() + s,
|
||||
// BUG: Diagnostic contains:
|
||||
i.toString() + s,
|
||||
i.toString(16) + s,
|
||||
// BUG: Diagnostic contains:
|
||||
String.valueOf(i) + s,
|
||||
// BUG: Diagnostic contains:
|
||||
String.valueOf(0) + s,
|
||||
// BUG: Diagnostic contains:
|
||||
String.valueOf((String) null) + s,
|
||||
String.valueOf(null) + s,
|
||||
String.valueOf(new char[0]) + s,
|
||||
String.valueOf(new char[0], 0, 0) + s,
|
||||
//
|
||||
this.toString() + 42,
|
||||
super.toString() + 42,
|
||||
i.toString() + 42,
|
||||
i.toString(16) + 42,
|
||||
String.valueOf(i) + 42,
|
||||
String.valueOf(0) + 42,
|
||||
// BUG: Diagnostic contains:
|
||||
String.valueOf((String) null) + 42,
|
||||
String.valueOf(null) + 42,
|
||||
String.valueOf(new char[0]) + 42,
|
||||
String.valueOf(new char[0], 0, 0) + 42,
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
this.toString() + this.toString(),
|
||||
super.toString() + super.toString(),
|
||||
// BUG: Diagnostic contains:
|
||||
i.toString() + i.toString(),
|
||||
i.toString(16) + i.toString(16),
|
||||
// BUG: Diagnostic contains:
|
||||
String.valueOf(i) + String.valueOf(i),
|
||||
// BUG: Diagnostic contains:
|
||||
String.valueOf(0) + String.valueOf(0),
|
||||
// BUG: Diagnostic contains:
|
||||
String.valueOf((String) null) + String.valueOf((String) null),
|
||||
String.valueOf(null) + String.valueOf(null),
|
||||
String.valueOf(new char[0]) + String.valueOf(new char[0]),
|
||||
String.valueOf(new char[0], 0, 0) + String.valueOf(new char[0], 0, 0),
|
||||
};
|
||||
}
|
||||
|
||||
int[] m2() {
|
||||
return new int[] {
|
||||
1 + 1, 1 - 1, 1 * 1, 1 / 1,
|
||||
};
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import java.math.BigInteger;",
|
||||
"",
|
||||
"class A {",
|
||||
" private final BigInteger i = BigInteger.ZERO;",
|
||||
" private final String s = i.toString();",
|
||||
"",
|
||||
" String[] m1() {",
|
||||
" return new String[] {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s + this.toString(),",
|
||||
" s + super.toString(),",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s + i.toString(),",
|
||||
" s + i.toString(16),",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s + String.valueOf(i),",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s + String.valueOf(0),",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s + String.valueOf((String) null),",
|
||||
" s + String.valueOf(null),",
|
||||
" s + String.valueOf(new char[0]),",
|
||||
" s + String.valueOf(new char[0], 0, 0),",
|
||||
" //",
|
||||
" 42 + this.toString(),",
|
||||
" 42 + super.toString(),",
|
||||
" 42 + i.toString(),",
|
||||
" 42 + i.toString(16),",
|
||||
" 42 + String.valueOf(i),",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" 42 + String.valueOf((String) null),",
|
||||
" 42 + String.valueOf(null),",
|
||||
" 42 + String.valueOf(new char[0]),",
|
||||
" 42 + String.valueOf(new char[0], 0, 0),",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" this.toString() + s,",
|
||||
" super.toString() + s,",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" i.toString() + s,",
|
||||
" i.toString(16) + s,",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String.valueOf(i) + s,",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String.valueOf(0) + s,",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String.valueOf((String) null) + s,",
|
||||
" String.valueOf(null) + s,",
|
||||
" String.valueOf(new char[0]) + s,",
|
||||
" String.valueOf(new char[0], 0, 0) + s,",
|
||||
" //",
|
||||
" this.toString() + 42,",
|
||||
" super.toString() + 42,",
|
||||
" i.toString() + 42,",
|
||||
" i.toString(16) + 42,",
|
||||
" String.valueOf(i) + 42,",
|
||||
" String.valueOf(0) + 42,",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String.valueOf((String) null) + 42,",
|
||||
" String.valueOf(null) + 42,",
|
||||
" String.valueOf(new char[0]) + 42,",
|
||||
" String.valueOf(new char[0], 0, 0) + 42,",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" this.toString() + this.toString(),",
|
||||
" super.toString() + super.toString(),",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" i.toString() + i.toString(),",
|
||||
" i.toString(16) + i.toString(16),",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String.valueOf(i) + String.valueOf(i),",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String.valueOf(0) + String.valueOf(0),",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String.valueOf((String) null) + String.valueOf((String) null),",
|
||||
" String.valueOf(null) + String.valueOf(null),",
|
||||
" String.valueOf(new char[0]) + String.valueOf(new char[0]),",
|
||||
" String.valueOf(new char[0], 0, 0) + String.valueOf(new char[0], 0, 0),",
|
||||
" };",
|
||||
" }",
|
||||
"",
|
||||
" int[] m2() {",
|
||||
" return new int[] {",
|
||||
" 1 + 1, 1 - 1, 1 * 1, 1 / 1,",
|
||||
" };",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -199,54 +193,52 @@ final class RedundantStringConversionTest {
|
||||
CompilationTestHelper.newInstance(RedundantStringConversion.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import java.math.BigInteger;
|
||||
|
||||
class A {
|
||||
private final BigInteger i = BigInteger.ZERO;
|
||||
private final String s = i.toString();
|
||||
|
||||
void m() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append(1);
|
||||
sb.append(i);
|
||||
// BUG: Diagnostic contains:
|
||||
sb.append(i.toString());
|
||||
sb.append(i.toString(16));
|
||||
// BUG: Diagnostic contains:
|
||||
sb.append(String.valueOf(i));
|
||||
// BUG: Diagnostic contains:
|
||||
sb.append(String.valueOf(0));
|
||||
// BUG: Diagnostic contains:
|
||||
sb.append(String.valueOf((String) null));
|
||||
sb.append(String.valueOf(null));
|
||||
sb.append(String.valueOf(new char[0]));
|
||||
sb.append(String.valueOf(new char[0], 0, 0));
|
||||
sb.append(s);
|
||||
sb.append("constant");
|
||||
|
||||
sb.insert(0, 1);
|
||||
sb.insert(0, i);
|
||||
// BUG: Diagnostic contains:
|
||||
sb.insert(0, i.toString());
|
||||
sb.insert(0, i.toString(16));
|
||||
// BUG: Diagnostic contains:
|
||||
sb.insert(0, String.valueOf(i));
|
||||
// BUG: Diagnostic contains:
|
||||
sb.insert(0, String.valueOf(0));
|
||||
// BUG: Diagnostic contains:
|
||||
sb.insert(0, String.valueOf((String) null));
|
||||
sb.insert(0, String.valueOf(null));
|
||||
sb.insert(0, String.valueOf(new char[0]));
|
||||
sb.insert(0, String.valueOf(new char[0], 0, 0));
|
||||
sb.insert(0, s);
|
||||
sb.insert(0, "constant");
|
||||
|
||||
sb.replace(0, 1, i.toString());
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import java.math.BigInteger;",
|
||||
"",
|
||||
"class A {",
|
||||
" private final BigInteger i = BigInteger.ZERO;",
|
||||
" private final String s = i.toString();",
|
||||
"",
|
||||
" void m() {",
|
||||
" StringBuilder sb = new StringBuilder();",
|
||||
"",
|
||||
" sb.append(1);",
|
||||
" sb.append(i);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" sb.append(i.toString());",
|
||||
" sb.append(i.toString(16));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" sb.append(String.valueOf(i));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" sb.append(String.valueOf(0));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" sb.append(String.valueOf((String) null));",
|
||||
" sb.append(String.valueOf(null));",
|
||||
" sb.append(String.valueOf(new char[0]));",
|
||||
" sb.append(String.valueOf(new char[0], 0, 0));",
|
||||
" sb.append(s);",
|
||||
" sb.append(\"constant\");",
|
||||
"",
|
||||
" sb.insert(0, 1);",
|
||||
" sb.insert(0, i);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" sb.insert(0, i.toString());",
|
||||
" sb.insert(0, i.toString(16));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" sb.insert(0, String.valueOf(i));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" sb.insert(0, String.valueOf(0));",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" sb.insert(0, String.valueOf((String) null));",
|
||||
" sb.insert(0, String.valueOf(null));",
|
||||
" sb.insert(0, String.valueOf(new char[0]));",
|
||||
" sb.insert(0, String.valueOf(new char[0], 0, 0));",
|
||||
" sb.insert(0, s);",
|
||||
" sb.insert(0, \"constant\");",
|
||||
"",
|
||||
" sb.replace(0, 1, i.toString());",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -256,45 +248,43 @@ final class RedundantStringConversionTest {
|
||||
CompilationTestHelper.newInstance(RedundantStringConversion.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import java.util.Formattable;
|
||||
import java.util.Locale;
|
||||
|
||||
class A {
|
||||
private final Locale locale = Locale.ROOT;
|
||||
private final Formattable f = (formatter, flags, width, precision) -> {};
|
||||
private final Object o = new Object();
|
||||
private final String s = o.toString();
|
||||
|
||||
void m() {
|
||||
String.format(s, f);
|
||||
String.format(s, o);
|
||||
String.format(s, s);
|
||||
String.format(s, f.toString());
|
||||
// BUG: Diagnostic contains:
|
||||
String.format(s, o.toString());
|
||||
// BUG: Diagnostic contains:
|
||||
String.format(s, String.valueOf(o));
|
||||
|
||||
String.format(locale, s, f);
|
||||
String.format(locale, s, o);
|
||||
String.format(locale, s, s);
|
||||
String.format(locale, s, f.toString());
|
||||
// BUG: Diagnostic contains:
|
||||
String.format(locale, s, o.toString());
|
||||
// BUG: Diagnostic contains:
|
||||
String.format(locale, s, String.valueOf(o));
|
||||
|
||||
String.format(o.toString(), o);
|
||||
// BUG: Diagnostic contains:
|
||||
String.format(s.toString(), o);
|
||||
String.format(locale.toString(), s, o);
|
||||
String.format(locale, o.toString(), o);
|
||||
// BUG: Diagnostic contains:
|
||||
String.format(locale, s.toString(), o);
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import java.util.Formattable;",
|
||||
"import java.util.Locale;",
|
||||
"",
|
||||
"class A {",
|
||||
" private final Locale locale = Locale.ROOT;",
|
||||
" private final Formattable f = (formatter, flags, width, precision) -> {};",
|
||||
" private final Object o = new Object();",
|
||||
" private final String s = o.toString();",
|
||||
"",
|
||||
" void m() {",
|
||||
" String.format(s, f);",
|
||||
" String.format(s, o);",
|
||||
" String.format(s, s);",
|
||||
" String.format(s, f.toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String.format(s, o.toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String.format(s, String.valueOf(o));",
|
||||
"",
|
||||
" String.format(locale, s, f);",
|
||||
" String.format(locale, s, o);",
|
||||
" String.format(locale, s, s);",
|
||||
" String.format(locale, s, f.toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String.format(locale, s, o.toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String.format(locale, s, String.valueOf(o));",
|
||||
"",
|
||||
" String.format(o.toString(), o);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String.format(s.toString(), o);",
|
||||
" String.format(locale.toString(), s, o);",
|
||||
" String.format(locale, o.toString(), o);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" String.format(locale, s.toString(), o);",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -303,60 +293,58 @@ final class RedundantStringConversionTest {
|
||||
CompilationTestHelper.newInstance(RedundantStringConversion.class, getClass())
|
||||
.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 java.util.Formattable;
|
||||
|
||||
class A {
|
||||
private final Formattable f = (formatter, flags, width, precision) -> {};
|
||||
private final Object o = new Object();
|
||||
private final String s = o.toString();
|
||||
|
||||
void m() {
|
||||
checkState(true, s, f);
|
||||
// BUG: Diagnostic contains:
|
||||
checkState(true, s, f.toString());
|
||||
checkState(true, f.toString(), f);
|
||||
// BUG: Diagnostic contains:
|
||||
checkState(true, s.toString(), f);
|
||||
|
||||
checkArgument(true, s, f);
|
||||
// BUG: Diagnostic contains:
|
||||
checkArgument(true, s, f.toString());
|
||||
checkArgument(true, f.toString(), f);
|
||||
// BUG: Diagnostic contains:
|
||||
checkArgument(true, s.toString(), f);
|
||||
|
||||
checkNotNull(o, s, f);
|
||||
// BUG: Diagnostic contains:
|
||||
checkNotNull(o, s, f.toString());
|
||||
checkNotNull(o, f.toString(), f);
|
||||
// BUG: Diagnostic contains:
|
||||
checkNotNull(o, s.toString(), f);
|
||||
checkNotNull(o.toString(), s, f);
|
||||
|
||||
verify(true, s, f);
|
||||
// BUG: Diagnostic contains:
|
||||
verify(true, s, f.toString());
|
||||
verify(true, f.toString(), f);
|
||||
// BUG: Diagnostic contains:
|
||||
verify(true, s.toString(), f);
|
||||
|
||||
verifyNotNull(o, s, f);
|
||||
// BUG: Diagnostic contains:
|
||||
verifyNotNull(o, s, f.toString());
|
||||
verifyNotNull(o, f.toString(), f);
|
||||
// BUG: Diagnostic contains:
|
||||
verifyNotNull(o, s.toString(), f);
|
||||
verifyNotNull(o.toString(), s, f);
|
||||
}
|
||||
}
|
||||
""")
|
||||
"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 java.util.Formattable;",
|
||||
"",
|
||||
"class A {",
|
||||
" private final Formattable f = (formatter, flags, width, precision) -> {};",
|
||||
" private final Object o = new Object();",
|
||||
" private final String s = o.toString();",
|
||||
"",
|
||||
" void m() {",
|
||||
" checkState(true, s, f);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" checkState(true, s, f.toString());",
|
||||
" checkState(true, f.toString(), f);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" checkState(true, s.toString(), f);",
|
||||
"",
|
||||
" checkArgument(true, s, f);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" checkArgument(true, s, f.toString());",
|
||||
" checkArgument(true, f.toString(), f);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" checkArgument(true, s.toString(), f);",
|
||||
"",
|
||||
" checkNotNull(o, s, f);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" checkNotNull(o, s, f.toString());",
|
||||
" checkNotNull(o, f.toString(), f);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" checkNotNull(o, s.toString(), f);",
|
||||
" checkNotNull(o.toString(), s, f);",
|
||||
"",
|
||||
" verify(true, s, f);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" verify(true, s, f.toString());",
|
||||
" verify(true, f.toString(), f);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" verify(true, s.toString(), f);",
|
||||
"",
|
||||
" verifyNotNull(o, s, f);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" verifyNotNull(o, s, f.toString());",
|
||||
" verifyNotNull(o, f.toString(), f);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" verifyNotNull(o, s.toString(), f);",
|
||||
" verifyNotNull(o.toString(), s, f);",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -365,55 +353,53 @@ final class RedundantStringConversionTest {
|
||||
CompilationTestHelper.newInstance(RedundantStringConversion.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import java.util.Formattable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.slf4j.Marker;
|
||||
import org.slf4j.MarkerFactory;
|
||||
|
||||
class A {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(A.class);
|
||||
|
||||
private final Marker marker = MarkerFactory.getMarker(A.class.getName());
|
||||
private final Formattable f = (formatter, flags, width, precision) -> {};
|
||||
private final Object o = new Object();
|
||||
private final String s = f.toString();
|
||||
private final Throwable t = new Throwable();
|
||||
|
||||
void m() {
|
||||
LOG.trace(s, f);
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.debug(s, f.toString());
|
||||
LOG.info(s, t.toString());
|
||||
LOG.warn(s, o, t.toString());
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.error(s, o.toString(), t.toString());
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.trace(s, t.toString(), o);
|
||||
|
||||
LOG.trace(marker, s, f);
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.debug(marker, s, f.toString());
|
||||
LOG.info(marker, s, t.toString());
|
||||
LOG.warn(marker, s, o, t.toString());
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.error(marker, s, o.toString(), t.toString());
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.trace(marker, s, t.toString(), o);
|
||||
|
||||
LOG.trace(f.toString(), f);
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.debug(s.toString(), f);
|
||||
LOG.info(t.toString(), f);
|
||||
LOG.warn(marker.toString(), s, f);
|
||||
LOG.error(marker, o.toString(), f);
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.trace(marker, s.toString(), f);
|
||||
LOG.debug(marker, t.toString(), f);
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import java.util.Formattable;",
|
||||
"import org.slf4j.Logger;",
|
||||
"import org.slf4j.LoggerFactory;",
|
||||
"import org.slf4j.Marker;",
|
||||
"import org.slf4j.MarkerFactory;",
|
||||
"",
|
||||
"class A {",
|
||||
" private static final Logger LOG = LoggerFactory.getLogger(A.class);",
|
||||
"",
|
||||
" private final Marker marker = MarkerFactory.getMarker(A.class.getName());",
|
||||
" private final Formattable f = (formatter, flags, width, precision) -> {};",
|
||||
" private final Object o = new Object();",
|
||||
" private final String s = f.toString();",
|
||||
" private final Throwable t = new Throwable();",
|
||||
"",
|
||||
" void m() {",
|
||||
" LOG.trace(s, f);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.debug(s, f.toString());",
|
||||
" LOG.info(s, t.toString());",
|
||||
" LOG.warn(s, o, t.toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.error(s, o.toString(), t.toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.trace(s, t.toString(), o);",
|
||||
"",
|
||||
" LOG.trace(marker, s, f);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.debug(marker, s, f.toString());",
|
||||
" LOG.info(marker, s, t.toString());",
|
||||
" LOG.warn(marker, s, o, t.toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.error(marker, s, o.toString(), t.toString());",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.trace(marker, s, t.toString(), o);",
|
||||
"",
|
||||
" LOG.trace(f.toString(), f);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.debug(s.toString(), f);",
|
||||
" LOG.info(t.toString(), f);",
|
||||
" LOG.warn(marker.toString(), s, f);",
|
||||
" LOG.error(marker, o.toString(), f);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.trace(marker, s.toString(), f);",
|
||||
" LOG.debug(marker, t.toString(), f);",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -424,93 +410,91 @@ final class RedundantStringConversionTest {
|
||||
"-XepOpt:RedundantStringConversion:ExtraConversionMethods=java.lang.Enum#name(),A#name(),A.B#toString(int)")
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import java.math.RoundingMode;
|
||||
import java.util.Objects;
|
||||
|
||||
class A {
|
||||
static class B {
|
||||
String name() {
|
||||
return toString();
|
||||
}
|
||||
|
||||
static String toString(int i) {
|
||||
return Integer.toString(i);
|
||||
}
|
||||
|
||||
static String toString(int i, int j) {
|
||||
return Integer.toString(i * j);
|
||||
}
|
||||
}
|
||||
|
||||
enum E {
|
||||
ELEM;
|
||||
|
||||
public String toString() {
|
||||
return "__" + name() + "__";
|
||||
}
|
||||
}
|
||||
|
||||
private final B b = new B();
|
||||
private final String s = b.toString();
|
||||
|
||||
String[] builtin() {
|
||||
return new String[] {
|
||||
// BUG: Diagnostic contains:
|
||||
s + b.toString(),
|
||||
// BUG: Diagnostic contains:
|
||||
s + Objects.toString(b),
|
||||
// BUG: Diagnostic contains:
|
||||
s + String.valueOf(b),
|
||||
// BUG: Diagnostic contains:
|
||||
s + Boolean.toString(false),
|
||||
// BUG: Diagnostic contains:
|
||||
s + Byte.toString((byte) 0),
|
||||
// BUG: Diagnostic contains:
|
||||
s + Character.toString((char) 0),
|
||||
// BUG: Diagnostic contains:
|
||||
s + Short.toString((short) 0),
|
||||
// BUG: Diagnostic contains:
|
||||
s + Integer.toString(0),
|
||||
s + Integer.toString(0, 16),
|
||||
// BUG: Diagnostic contains:
|
||||
s + Long.toString(0),
|
||||
s + Long.toString(0, 16),
|
||||
// BUG: Diagnostic contains:
|
||||
s + Float.toString((float) 0.0),
|
||||
// BUG: Diagnostic contains:
|
||||
s + Double.toString(0.0),
|
||||
};
|
||||
}
|
||||
|
||||
String[] custom() {
|
||||
return new String[] {
|
||||
s + b.name(),
|
||||
// BUG: Diagnostic contains:
|
||||
s + RoundingMode.UP.name(),
|
||||
// BUG: Diagnostic contains:
|
||||
s + mode().name(),
|
||||
s + A.name(),
|
||||
s + A.toString(42),
|
||||
// BUG: Diagnostic contains:
|
||||
s + B.toString(42),
|
||||
s + B.toString(42, 42),
|
||||
};
|
||||
}
|
||||
|
||||
static String name() {
|
||||
return A.class.toString();
|
||||
}
|
||||
|
||||
RoundingMode mode() {
|
||||
return RoundingMode.UP;
|
||||
}
|
||||
|
||||
static String toString(int i) {
|
||||
return Integer.toString(i);
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import java.math.RoundingMode;",
|
||||
"import java.util.Objects;",
|
||||
"",
|
||||
"class A {",
|
||||
" static class B {",
|
||||
" String name() {",
|
||||
" return toString();",
|
||||
" }",
|
||||
"",
|
||||
" static String toString(int i) {",
|
||||
" return Integer.toString(i);",
|
||||
" }",
|
||||
"",
|
||||
" static String toString(int i, int j) {",
|
||||
" return Integer.toString(i * j);",
|
||||
" }",
|
||||
" }",
|
||||
"",
|
||||
" enum E {",
|
||||
" ELEM;",
|
||||
"",
|
||||
" public String toString() {",
|
||||
" return \"__\" + name() + \"__\";",
|
||||
" }",
|
||||
" }",
|
||||
"",
|
||||
" private final B b = new B();",
|
||||
" private final String s = b.toString();",
|
||||
"",
|
||||
" String[] builtin() {",
|
||||
" return new String[] {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s + b.toString(),",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s + Objects.toString(b),",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s + String.valueOf(b),",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s + Boolean.toString(false),",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s + Byte.toString((byte) 0),",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s + Character.toString((char) 0),",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s + Short.toString((short) 0),",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s + Integer.toString(0),",
|
||||
" s + Integer.toString(0, 16),",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s + Long.toString(0),",
|
||||
" s + Long.toString(0, 16),",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s + Float.toString((float) 0.0),",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s + Double.toString(0.0),",
|
||||
" };",
|
||||
" }",
|
||||
"",
|
||||
" String[] custom() {",
|
||||
" return new String[] {",
|
||||
" s + b.name(),",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s + RoundingMode.UP.name(),",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s + mode().name(),",
|
||||
" s + A.name(),",
|
||||
" s + A.toString(42),",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" s + B.toString(42),",
|
||||
" s + B.toString(42, 42),",
|
||||
" };",
|
||||
" }",
|
||||
"",
|
||||
" static String name() {",
|
||||
" return A.class.toString();",
|
||||
" }",
|
||||
"",
|
||||
" RoundingMode mode() {",
|
||||
" return RoundingMode.UP;",
|
||||
" }",
|
||||
"",
|
||||
" static String toString(int i) {",
|
||||
" return Integer.toString(i);",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -519,36 +503,32 @@ final class RedundantStringConversionTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(RedundantStringConversion.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
class A {
|
||||
private final Object o = new Object();
|
||||
private final String s = o.toString();
|
||||
|
||||
void m() {
|
||||
String v1 = s.toString();
|
||||
String v2 = "foo".toString();
|
||||
String v3 = v2 + super.toString();
|
||||
String v4 = 42 + String.valueOf((String) null);
|
||||
String.format("%s", o.toString());
|
||||
}
|
||||
}
|
||||
""")
|
||||
"class A {",
|
||||
" private final Object o = new Object();",
|
||||
" private final String s = o.toString();",
|
||||
"",
|
||||
" void m() {",
|
||||
" String v1 = s.toString();",
|
||||
" String v2 = \"foo\".toString();",
|
||||
" String v3 = v2 + super.toString();",
|
||||
" String v4 = 42 + String.valueOf((String) null);",
|
||||
" String.format(\"%s\", o.toString());",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
class A {
|
||||
private final Object o = new Object();
|
||||
private final String s = o.toString();
|
||||
|
||||
void m() {
|
||||
String v1 = s;
|
||||
String v2 = "foo";
|
||||
String v3 = v2 + super.toString();
|
||||
String v4 = 42 + (String) null;
|
||||
String.format("%s", o);
|
||||
}
|
||||
}
|
||||
""")
|
||||
"class A {",
|
||||
" private final Object o = new Object();",
|
||||
" private final String s = o.toString();",
|
||||
"",
|
||||
" void m() {",
|
||||
" String v1 = s;",
|
||||
" String v2 = \"foo\";",
|
||||
" String v3 = v2 + super.toString();",
|
||||
" String v4 = 42 + (String) null;",
|
||||
" String.format(\"%s\", o);",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,40 +11,38 @@ final class RedundantStringEscapeTest {
|
||||
CompilationTestHelper.newInstance(RedundantStringEscape.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
class A {
|
||||
List<String> m() {
|
||||
return Arrays.asList(
|
||||
"foo",
|
||||
"ß",
|
||||
"'",
|
||||
"\\"",
|
||||
"\\\\",
|
||||
"\\\\'",
|
||||
"'\\\\",
|
||||
// BUG: Diagnostic contains:
|
||||
"\\\\\\'",
|
||||
// BUG: Diagnostic contains:
|
||||
"\\'\\\\",
|
||||
// BUG: Diagnostic contains:
|
||||
"\\'",
|
||||
// BUG: Diagnostic contains:
|
||||
"'\\'",
|
||||
// BUG: Diagnostic contains:
|
||||
"\\''",
|
||||
// BUG: Diagnostic contains:
|
||||
"\\'\\'",
|
||||
(
|
||||
// BUG: Diagnostic contains:
|
||||
/* Leading comment. */ "\\'" /* Trailing comment. */),
|
||||
// BUG: Diagnostic contains:
|
||||
"\\'foo\\"bar\\'baz\\"qux\\'");
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import java.util.Arrays;",
|
||||
"import java.util.List;",
|
||||
"",
|
||||
"class A {",
|
||||
" List<String> m() {",
|
||||
" return Arrays.asList(",
|
||||
" \"foo\",",
|
||||
" \"ß\",",
|
||||
" \"'\",",
|
||||
" \"\\\"\",",
|
||||
" \"\\\\\",",
|
||||
" \"\\\\'\",",
|
||||
" \"'\\\\\",",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" \"\\\\\\'\",",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" \"\\'\\\\\",",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" \"\\'\",",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" \"'\\'\",",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" \"\\''\",",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" \"\\'\\'\",",
|
||||
" (",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" /* Leading comment. */ \"\\'\" /* Trailing comment. */),",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" \"\\'foo\\\"bar\\'baz\\\"qux\\'\");",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -53,44 +51,40 @@ final class RedundantStringEscapeTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(RedundantStringEscape.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
class A {
|
||||
List<String> m() {
|
||||
return Arrays.asList(
|
||||
"\\'",
|
||||
"'\\'",
|
||||
"\\''",
|
||||
"\\'\\'",
|
||||
"\\'ß\\'",
|
||||
(
|
||||
/* Leading comment. */ "\\'" /* Trailing comment. */),
|
||||
"\\'foo\\"bar\\'baz\\"qux\\'");
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import java.util.Arrays;",
|
||||
"import java.util.List;",
|
||||
"",
|
||||
"class A {",
|
||||
" List<String> m() {",
|
||||
" return Arrays.asList(",
|
||||
" \"\\'\",",
|
||||
" \"'\\'\",",
|
||||
" \"\\''\",",
|
||||
" \"\\'\\'\",",
|
||||
" \"\\'ß\\'\",",
|
||||
" (",
|
||||
" /* Leading comment. */ \"\\'\" /* Trailing comment. */),",
|
||||
" \"\\'foo\\\"bar\\'baz\\\"qux\\'\");",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
class A {
|
||||
List<String> m() {
|
||||
return Arrays.asList(
|
||||
"'",
|
||||
"''",
|
||||
"''",
|
||||
"''",
|
||||
"'ß'",
|
||||
(
|
||||
/* Leading comment. */ "'" /* Trailing comment. */),
|
||||
"'foo\\"bar'baz\\"qux'");
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import java.util.Arrays;",
|
||||
"import java.util.List;",
|
||||
"",
|
||||
"class A {",
|
||||
" List<String> m() {",
|
||||
" return Arrays.asList(",
|
||||
" \"'\",",
|
||||
" \"''\",",
|
||||
" \"''\",",
|
||||
" \"''\",",
|
||||
" \"'ß'\",",
|
||||
" (",
|
||||
" /* Leading comment. */ \"'\" /* Trailing comment. */),",
|
||||
" \"'foo\\\"bar'baz\\\"qux'\");",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,140 +9,138 @@ final class RequestMappingAnnotationTest {
|
||||
CompilationTestHelper.newInstance(RequestMappingAnnotation.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.InputStream;
|
||||
import java.time.ZoneId;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.security.core.annotation.CurrentSecurityContext;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PatchMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestAttribute;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RequestPart;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.util.UriBuilder;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
interface A {
|
||||
A noMapping();
|
||||
|
||||
A noMapping(String param);
|
||||
|
||||
@DeleteMapping
|
||||
A properNoParameters();
|
||||
|
||||
@GetMapping
|
||||
A properPathVariable(@PathVariable String param);
|
||||
|
||||
@PatchMapping
|
||||
A properRequestAttribute(@RequestAttribute String attribute);
|
||||
|
||||
@PostMapping
|
||||
A properRequestBody(@RequestBody String body);
|
||||
|
||||
@PutMapping
|
||||
A properRequestHeader(@RequestHeader String header);
|
||||
|
||||
@RequestMapping
|
||||
A properRequestParam(@RequestParam String param);
|
||||
|
||||
@RequestMapping
|
||||
A properRequestPart(@RequestPart String part);
|
||||
|
||||
@RequestMapping
|
||||
A properCurrentSecurityContext(
|
||||
@CurrentSecurityContext(expression = "authentication.name") String user);
|
||||
|
||||
@RequestMapping
|
||||
A properInputStream(InputStream input);
|
||||
|
||||
@RequestMapping
|
||||
A properZoneId(ZoneId zoneId);
|
||||
|
||||
@RequestMapping
|
||||
A properLocale(Locale locale);
|
||||
|
||||
@RequestMapping
|
||||
A properTimeZone(TimeZone timeZone);
|
||||
|
||||
@RequestMapping
|
||||
A properHttpServletRequest(HttpServletRequest request);
|
||||
|
||||
@RequestMapping
|
||||
A properHttpServletResponse(HttpServletResponse response);
|
||||
|
||||
@RequestMapping
|
||||
A properHttpMethod(HttpMethod method);
|
||||
|
||||
@RequestMapping
|
||||
A properModel(Model model);
|
||||
|
||||
@RequestMapping
|
||||
A properBindingResult(BindingResult result);
|
||||
|
||||
@RequestMapping
|
||||
A properNativeWebRequest(NativeWebRequest request);
|
||||
|
||||
@RequestMapping
|
||||
A properWebRequest(WebRequest request);
|
||||
|
||||
@RequestMapping
|
||||
A properServerWebExchange(ServerWebExchange exchange);
|
||||
|
||||
@RequestMapping
|
||||
A properServerUriBuilder(UriBuilder builder);
|
||||
|
||||
@RequestMapping
|
||||
A properServerUriComponentsBuilder(UriComponentsBuilder builder);
|
||||
|
||||
@DeleteMapping
|
||||
// BUG: Diagnostic contains:
|
||||
A delete(String param);
|
||||
|
||||
@GetMapping
|
||||
// BUG: Diagnostic contains:
|
||||
A get(String param);
|
||||
|
||||
@PatchMapping
|
||||
// BUG: Diagnostic contains:
|
||||
A patch(String param);
|
||||
|
||||
@PostMapping
|
||||
// BUG: Diagnostic contains:
|
||||
A post(String param);
|
||||
|
||||
@PutMapping
|
||||
// BUG: Diagnostic contains:
|
||||
A put(String param);
|
||||
|
||||
@RequestMapping
|
||||
// BUG: Diagnostic contains:
|
||||
A requestMultiple(String param, String param2);
|
||||
|
||||
@RequestMapping
|
||||
// BUG: Diagnostic contains:
|
||||
A requestFirstParamViolation(String param, @PathVariable String param2);
|
||||
|
||||
@RequestMapping
|
||||
// BUG: Diagnostic contains:
|
||||
A requestSecondParamViolation(@RequestBody String param, String param2);
|
||||
}
|
||||
""")
|
||||
"import jakarta.servlet.http.HttpServletRequest;",
|
||||
"import jakarta.servlet.http.HttpServletResponse;",
|
||||
"import java.io.InputStream;",
|
||||
"import java.time.ZoneId;",
|
||||
"import java.util.Locale;",
|
||||
"import java.util.TimeZone;",
|
||||
"import org.springframework.http.HttpMethod;",
|
||||
"import org.springframework.security.core.annotation.CurrentSecurityContext;",
|
||||
"import org.springframework.ui.Model;",
|
||||
"import org.springframework.validation.BindingResult;",
|
||||
"import org.springframework.web.bind.annotation.DeleteMapping;",
|
||||
"import org.springframework.web.bind.annotation.GetMapping;",
|
||||
"import org.springframework.web.bind.annotation.PatchMapping;",
|
||||
"import org.springframework.web.bind.annotation.PathVariable;",
|
||||
"import org.springframework.web.bind.annotation.PostMapping;",
|
||||
"import org.springframework.web.bind.annotation.PutMapping;",
|
||||
"import org.springframework.web.bind.annotation.RequestAttribute;",
|
||||
"import org.springframework.web.bind.annotation.RequestBody;",
|
||||
"import org.springframework.web.bind.annotation.RequestHeader;",
|
||||
"import org.springframework.web.bind.annotation.RequestMapping;",
|
||||
"import org.springframework.web.bind.annotation.RequestParam;",
|
||||
"import org.springframework.web.bind.annotation.RequestPart;",
|
||||
"import org.springframework.web.context.request.NativeWebRequest;",
|
||||
"import org.springframework.web.context.request.WebRequest;",
|
||||
"import org.springframework.web.server.ServerWebExchange;",
|
||||
"import org.springframework.web.util.UriBuilder;",
|
||||
"import org.springframework.web.util.UriComponentsBuilder;",
|
||||
"",
|
||||
"interface A {",
|
||||
" A noMapping();",
|
||||
"",
|
||||
" A noMapping(String param);",
|
||||
"",
|
||||
" @DeleteMapping",
|
||||
" A properNoParameters();",
|
||||
"",
|
||||
" @GetMapping",
|
||||
" A properPathVariable(@PathVariable String param);",
|
||||
"",
|
||||
" @PatchMapping",
|
||||
" A properRequestAttribute(@RequestAttribute String attribute);",
|
||||
"",
|
||||
" @PostMapping",
|
||||
" A properRequestBody(@RequestBody String body);",
|
||||
"",
|
||||
" @PutMapping",
|
||||
" A properRequestHeader(@RequestHeader String header);",
|
||||
"",
|
||||
" @RequestMapping",
|
||||
" A properRequestParam(@RequestParam String param);",
|
||||
"",
|
||||
" @RequestMapping",
|
||||
" A properRequestPart(@RequestPart String part);",
|
||||
"",
|
||||
" @RequestMapping",
|
||||
" A properCurrentSecurityContext(",
|
||||
" @CurrentSecurityContext(expression = \"authentication.name\") String user);",
|
||||
"",
|
||||
" @RequestMapping",
|
||||
" A properInputStream(InputStream input);",
|
||||
"",
|
||||
" @RequestMapping",
|
||||
" A properZoneId(ZoneId zoneId);",
|
||||
"",
|
||||
" @RequestMapping",
|
||||
" A properLocale(Locale locale);",
|
||||
"",
|
||||
" @RequestMapping",
|
||||
" A properTimeZone(TimeZone timeZone);",
|
||||
"",
|
||||
" @RequestMapping",
|
||||
" A properHttpServletRequest(HttpServletRequest request);",
|
||||
"",
|
||||
" @RequestMapping",
|
||||
" A properHttpServletResponse(HttpServletResponse response);",
|
||||
"",
|
||||
" @RequestMapping",
|
||||
" A properHttpMethod(HttpMethod method);",
|
||||
"",
|
||||
" @RequestMapping",
|
||||
" A properModel(Model model);",
|
||||
"",
|
||||
" @RequestMapping",
|
||||
" A properBindingResult(BindingResult result);",
|
||||
"",
|
||||
" @RequestMapping",
|
||||
" A properNativeWebRequest(NativeWebRequest request);",
|
||||
"",
|
||||
" @RequestMapping",
|
||||
" A properWebRequest(WebRequest request);",
|
||||
"",
|
||||
" @RequestMapping",
|
||||
" A properServerWebExchange(ServerWebExchange exchange);",
|
||||
"",
|
||||
" @RequestMapping",
|
||||
" A properServerUriBuilder(UriBuilder builder);",
|
||||
"",
|
||||
" @RequestMapping",
|
||||
" A properServerUriComponentsBuilder(UriComponentsBuilder builder);",
|
||||
"",
|
||||
" @DeleteMapping",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" A delete(String param);",
|
||||
"",
|
||||
" @GetMapping",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" A get(String param);",
|
||||
"",
|
||||
" @PatchMapping",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" A patch(String param);",
|
||||
"",
|
||||
" @PostMapping",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" A post(String param);",
|
||||
"",
|
||||
" @PutMapping",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" A put(String param);",
|
||||
"",
|
||||
" @RequestMapping",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" A requestMultiple(String param, String param2);",
|
||||
"",
|
||||
" @RequestMapping",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" A requestFirstParamViolation(String param, @PathVariable String param2);",
|
||||
"",
|
||||
" @RequestMapping",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" A requestSecondParamViolation(@RequestBody String param, String param2);",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,57 +9,55 @@ final class RequestParamTypeTest {
|
||||
CompilationTestHelper.newInstance(RequestParamType.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import com.google.common.collect.ImmutableBiMap;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
interface A {
|
||||
@PostMapping
|
||||
A properRequestParam(@RequestBody String body);
|
||||
|
||||
@GetMapping
|
||||
A properRequestParam(@RequestParam int param);
|
||||
|
||||
@GetMapping
|
||||
A properRequestParam(@RequestParam List<String> param);
|
||||
|
||||
@PostMapping
|
||||
A properRequestParam(@RequestBody String body, @RequestParam Set<String> param);
|
||||
|
||||
@PutMapping
|
||||
A properRequestParam(@RequestBody String body, @RequestParam Map<String, String> param);
|
||||
|
||||
@GetMapping
|
||||
// BUG: Diagnostic contains:
|
||||
A get(@RequestParam ImmutableBiMap<String, String> param);
|
||||
|
||||
@PostMapping
|
||||
// BUG: Diagnostic contains:
|
||||
A post(@Nullable @RequestParam ImmutableList<String> param);
|
||||
|
||||
@PutMapping
|
||||
// BUG: Diagnostic contains:
|
||||
A put(@RequestBody String body, @RequestParam ImmutableSet<String> param);
|
||||
|
||||
@DeleteMapping
|
||||
// BUG: Diagnostic contains:
|
||||
A delete(@RequestBody String body, @RequestParam ImmutableMap<String, String> param);
|
||||
|
||||
void negative(ImmutableSet<Integer> set, ImmutableMap<String, String> map);
|
||||
}
|
||||
""")
|
||||
"import com.google.common.collect.ImmutableBiMap;",
|
||||
"import com.google.common.collect.ImmutableList;",
|
||||
"import com.google.common.collect.ImmutableMap;",
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import java.util.List;",
|
||||
"import java.util.Map;",
|
||||
"import java.util.Set;",
|
||||
"import org.jspecify.annotations.Nullable;",
|
||||
"import org.springframework.web.bind.annotation.DeleteMapping;",
|
||||
"import org.springframework.web.bind.annotation.GetMapping;",
|
||||
"import org.springframework.web.bind.annotation.PostMapping;",
|
||||
"import org.springframework.web.bind.annotation.PutMapping;",
|
||||
"import org.springframework.web.bind.annotation.RequestBody;",
|
||||
"import org.springframework.web.bind.annotation.RequestParam;",
|
||||
"",
|
||||
"interface A {",
|
||||
" @PostMapping",
|
||||
" A properRequestParam(@RequestBody String body);",
|
||||
"",
|
||||
" @GetMapping",
|
||||
" A properRequestParam(@RequestParam int param);",
|
||||
"",
|
||||
" @GetMapping",
|
||||
" A properRequestParam(@RequestParam List<String> param);",
|
||||
"",
|
||||
" @PostMapping",
|
||||
" A properRequestParam(@RequestBody String body, @RequestParam Set<String> param);",
|
||||
"",
|
||||
" @PutMapping",
|
||||
" A properRequestParam(@RequestBody String body, @RequestParam Map<String, String> param);",
|
||||
"",
|
||||
" @GetMapping",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" A get(@RequestParam ImmutableBiMap<String, String> param);",
|
||||
"",
|
||||
" @PostMapping",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" A post(@Nullable @RequestParam ImmutableList<String> param);",
|
||||
"",
|
||||
" @PutMapping",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" A put(@RequestBody String body, @RequestParam ImmutableSet<String> param);",
|
||||
"",
|
||||
" @DeleteMapping",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" A delete(@RequestBody String body, @RequestParam ImmutableMap<String, String> param);",
|
||||
"",
|
||||
" void negative(ImmutableSet<Integer> set, ImmutableMap<String, String> map);",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -70,49 +68,47 @@ final class RequestParamTypeTest {
|
||||
"-XepOpt:RequestParamType:SupportedCustomTypes=com.google.common.collect.ImmutableSet,com.google.common.collect.ImmutableSortedMultiset")
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import com.google.common.collect.ImmutableBiMap;
|
||||
import com.google.common.collect.ImmutableCollection;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMultiset;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSortedMultiset;
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
interface A {
|
||||
@GetMapping
|
||||
// BUG: Diagnostic contains:
|
||||
A immutableCollection(@RequestParam ImmutableCollection<String> param);
|
||||
|
||||
@GetMapping
|
||||
// BUG: Diagnostic contains:
|
||||
A immutableList(@RequestParam ImmutableList<String> param);
|
||||
|
||||
@GetMapping
|
||||
A immutableSet(@RequestParam ImmutableSet<String> param);
|
||||
|
||||
@GetMapping
|
||||
A immutableSortedSet(@RequestParam ImmutableSortedSet<String> param);
|
||||
|
||||
@GetMapping
|
||||
// BUG: Diagnostic contains:
|
||||
A immutableMultiset(@RequestParam ImmutableMultiset<String> param);
|
||||
|
||||
@GetMapping
|
||||
A immutableSortedMultiset(@RequestParam ImmutableSortedMultiset<String> param);
|
||||
|
||||
@GetMapping
|
||||
// BUG: Diagnostic contains:
|
||||
A immutableMap(@RequestParam ImmutableMap<String, String> param);
|
||||
|
||||
@GetMapping
|
||||
// BUG: Diagnostic contains:
|
||||
A immutableBiMap(@RequestParam ImmutableBiMap<String, String> param);
|
||||
}
|
||||
""")
|
||||
"import com.google.common.collect.ImmutableBiMap;",
|
||||
"import com.google.common.collect.ImmutableCollection;",
|
||||
"import com.google.common.collect.ImmutableList;",
|
||||
"import com.google.common.collect.ImmutableMap;",
|
||||
"import com.google.common.collect.ImmutableMultiset;",
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import com.google.common.collect.ImmutableSortedMultiset;",
|
||||
"import com.google.common.collect.ImmutableSortedSet;",
|
||||
"import org.springframework.web.bind.annotation.GetMapping;",
|
||||
"import org.springframework.web.bind.annotation.RequestParam;",
|
||||
"",
|
||||
"interface A {",
|
||||
" @GetMapping",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" A immutableCollection(@RequestParam ImmutableCollection<String> param);",
|
||||
"",
|
||||
" @GetMapping",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" A immutableList(@RequestParam ImmutableList<String> param);",
|
||||
"",
|
||||
" @GetMapping",
|
||||
" A immutableSet(@RequestParam ImmutableSet<String> param);",
|
||||
"",
|
||||
" @GetMapping",
|
||||
" A immutableSortedSet(@RequestParam ImmutableSortedSet<String> param);",
|
||||
"",
|
||||
" @GetMapping",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" A immutableMultiset(@RequestParam ImmutableMultiset<String> param);",
|
||||
"",
|
||||
" @GetMapping",
|
||||
" A immutableSortedMultiset(@RequestParam ImmutableSortedMultiset<String> param);",
|
||||
"",
|
||||
" @GetMapping",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" A immutableMap(@RequestParam ImmutableMap<String, String> param);",
|
||||
"",
|
||||
" @GetMapping",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" A immutableBiMap(@RequestParam ImmutableBiMap<String, String> param);",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,81 +11,79 @@ final class Slf4jLogStatementTest {
|
||||
CompilationTestHelper.newInstance(Slf4jLogStatement.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.slf4j.Marker;
|
||||
import org.slf4j.MarkerFactory;
|
||||
|
||||
class A {
|
||||
private static final String FMT0 = "format-string-without-placeholders";
|
||||
private static final String FMT1 = "format-string-with-{}-placeholder";
|
||||
private static final String FMT_ERR = "format-string-with-%s-placeholder";
|
||||
private static final Logger LOG = LoggerFactory.getLogger(A.class);
|
||||
|
||||
private final Marker marker = MarkerFactory.getMarker(A.class.getName());
|
||||
private final Object o = new Object();
|
||||
private final String s = o.toString();
|
||||
private final Throwable t = new Throwable();
|
||||
|
||||
void m() {
|
||||
LOG.trace(s);
|
||||
LOG.debug(s, o);
|
||||
LOG.info(s, t);
|
||||
LOG.warn(s, o, t);
|
||||
LOG.error(marker, s);
|
||||
LOG.trace(marker, s, o);
|
||||
LOG.debug(marker, s, t);
|
||||
LOG.info(marker, s, o, t);
|
||||
|
||||
LOG.warn(FMT0);
|
||||
// BUG: Diagnostic contains: Log statement contains 0 placeholders, but specifies 1 matching
|
||||
// argument(s)
|
||||
LOG.error(FMT0, o);
|
||||
LOG.trace(FMT0, t);
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.debug(FMT0, o, t);
|
||||
LOG.info(marker, FMT0);
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.warn(marker, FMT0, o);
|
||||
LOG.error(marker, FMT0, t);
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.trace(marker, FMT0, o, t);
|
||||
|
||||
// BUG: Diagnostic contains: Log statement contains 1 placeholders, but specifies 0 matching
|
||||
// argument(s)
|
||||
LOG.debug(FMT1);
|
||||
LOG.info(FMT1, o);
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.warn(FMT1, t);
|
||||
LOG.error(FMT1, o, t);
|
||||
// BUG: Diagnostic contains: Log statement contains 1 placeholders, but specifies 2 matching
|
||||
// argument(s)
|
||||
LOG.trace(FMT1, o, o);
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.debug(FMT1, o, o, t);
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.info(marker, FMT1);
|
||||
LOG.warn(marker, FMT1, o);
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.error(marker, FMT1, t);
|
||||
LOG.trace(marker, FMT1, o, t);
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.debug(marker, FMT1, o, o);
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.info(marker, FMT1, o, o, t);
|
||||
|
||||
// BUG: Diagnostic contains: SLF4J log statement placeholders are of the form `{}`, not `%s`
|
||||
LOG.warn(FMT_ERR);
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.error(FMT_ERR, t);
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.trace(FMT_ERR, o);
|
||||
// BUG: Diagnostic contains:
|
||||
LOG.debug(FMT_ERR, o, t);
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import org.slf4j.Logger;",
|
||||
"import org.slf4j.LoggerFactory;",
|
||||
"import org.slf4j.Marker;",
|
||||
"import org.slf4j.MarkerFactory;",
|
||||
"",
|
||||
"class A {",
|
||||
" private static final String FMT0 = \"format-string-without-placeholders\";",
|
||||
" private static final String FMT1 = \"format-string-with-{}-placeholder\";",
|
||||
" private static final String FMT_ERR = \"format-string-with-%s-placeholder\";",
|
||||
" private static final Logger LOG = LoggerFactory.getLogger(A.class);",
|
||||
"",
|
||||
" private final Marker marker = MarkerFactory.getMarker(A.class.getName());",
|
||||
" private final Object o = new Object();",
|
||||
" private final String s = o.toString();",
|
||||
" private final Throwable t = new Throwable();",
|
||||
"",
|
||||
" void m() {",
|
||||
" LOG.trace(s);",
|
||||
" LOG.debug(s, o);",
|
||||
" LOG.info(s, t);",
|
||||
" LOG.warn(s, o, t);",
|
||||
" LOG.error(marker, s);",
|
||||
" LOG.trace(marker, s, o);",
|
||||
" LOG.debug(marker, s, t);",
|
||||
" LOG.info(marker, s, o, t);",
|
||||
"",
|
||||
" LOG.warn(FMT0);",
|
||||
" // BUG: Diagnostic contains: Log statement contains 0 placeholders, but specifies 1 matching",
|
||||
" // argument(s)",
|
||||
" LOG.error(FMT0, o);",
|
||||
" LOG.trace(FMT0, t);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.debug(FMT0, o, t);",
|
||||
" LOG.info(marker, FMT0);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.warn(marker, FMT0, o);",
|
||||
" LOG.error(marker, FMT0, t);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.trace(marker, FMT0, o, t);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains: Log statement contains 1 placeholders, but specifies 0 matching",
|
||||
" // argument(s)",
|
||||
" LOG.debug(FMT1);",
|
||||
" LOG.info(FMT1, o);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.warn(FMT1, t);",
|
||||
" LOG.error(FMT1, o, t);",
|
||||
" // BUG: Diagnostic contains: Log statement contains 1 placeholders, but specifies 2 matching",
|
||||
" // argument(s)",
|
||||
" LOG.trace(FMT1, o, o);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.debug(FMT1, o, o, t);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.info(marker, FMT1);",
|
||||
" LOG.warn(marker, FMT1, o);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.error(marker, FMT1, t);",
|
||||
" LOG.trace(marker, FMT1, o, t);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.debug(marker, FMT1, o, o);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.info(marker, FMT1, o, o, t);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains: SLF4J log statement placeholders are of the form `{}`, not `%s`",
|
||||
" LOG.warn(FMT_ERR);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.error(FMT_ERR, t);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.trace(FMT_ERR, o);",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" LOG.debug(FMT_ERR, o, t);",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -95,54 +93,50 @@ final class Slf4jLogStatementTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(Slf4jLogStatement.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.slf4j.Marker;
|
||||
import org.slf4j.MarkerFactory;
|
||||
|
||||
class A {
|
||||
private static final String FMT_ERR = "format-string-with-%s-placeholder";
|
||||
private static final Logger LOG = LoggerFactory.getLogger(A.class);
|
||||
|
||||
private final Marker marker = MarkerFactory.getMarker(A.class.getName());
|
||||
private final Object o = new Object();
|
||||
private final String s = o.toString();
|
||||
private final Throwable t = new Throwable();
|
||||
|
||||
void m() {
|
||||
LOG.error(FMT_ERR, o);
|
||||
LOG.error("format-string-with-'%s'-placeholder", o);
|
||||
LOG.error("format-string-with-\\"%s\\"-placeholder", o);
|
||||
LOG.error("format-string-with-%s" + "-placeholder", o);
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import org.slf4j.Logger;",
|
||||
"import org.slf4j.LoggerFactory;",
|
||||
"import org.slf4j.Marker;",
|
||||
"import org.slf4j.MarkerFactory;",
|
||||
"",
|
||||
"class A {",
|
||||
" private static final String FMT_ERR = \"format-string-with-%s-placeholder\";",
|
||||
" private static final Logger LOG = LoggerFactory.getLogger(A.class);",
|
||||
"",
|
||||
" private final Marker marker = MarkerFactory.getMarker(A.class.getName());",
|
||||
" private final Object o = new Object();",
|
||||
" private final String s = o.toString();",
|
||||
" private final Throwable t = new Throwable();",
|
||||
"",
|
||||
" void m() {",
|
||||
" LOG.error(FMT_ERR, o);",
|
||||
" LOG.error(\"format-string-with-'%s'-placeholder\", o);",
|
||||
" LOG.error(\"format-string-with-\\\"%s\\\"-placeholder\", o);",
|
||||
" LOG.error(\"format-string-with-%s\" + \"-placeholder\", o);",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.slf4j.Marker;
|
||||
import org.slf4j.MarkerFactory;
|
||||
|
||||
class A {
|
||||
private static final String FMT_ERR = "format-string-with-%s-placeholder";
|
||||
private static final Logger LOG = LoggerFactory.getLogger(A.class);
|
||||
|
||||
private final Marker marker = MarkerFactory.getMarker(A.class.getName());
|
||||
private final Object o = new Object();
|
||||
private final String s = o.toString();
|
||||
private final Throwable t = new Throwable();
|
||||
|
||||
void m() {
|
||||
LOG.error(FMT_ERR, o);
|
||||
LOG.error("format-string-with-'{}'-placeholder", o);
|
||||
LOG.error("format-string-with-\\"{}\\"-placeholder", o);
|
||||
LOG.error("format-string-with-{}" + "-placeholder", o);
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import org.slf4j.Logger;",
|
||||
"import org.slf4j.LoggerFactory;",
|
||||
"import org.slf4j.Marker;",
|
||||
"import org.slf4j.MarkerFactory;",
|
||||
"",
|
||||
"class A {",
|
||||
" private static final String FMT_ERR = \"format-string-with-%s-placeholder\";",
|
||||
" private static final Logger LOG = LoggerFactory.getLogger(A.class);",
|
||||
"",
|
||||
" private final Marker marker = MarkerFactory.getMarker(A.class.getName());",
|
||||
" private final Object o = new Object();",
|
||||
" private final String s = o.toString();",
|
||||
" private final Throwable t = new Throwable();",
|
||||
"",
|
||||
" void m() {",
|
||||
" LOG.error(FMT_ERR, o);",
|
||||
" LOG.error(\"format-string-with-'{}'-placeholder\", o);",
|
||||
" LOG.error(\"format-string-with-\\\"{}\\\"-placeholder\", o);",
|
||||
" LOG.error(\"format-string-with-{}\" + \"-placeholder\", o);",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,125 +11,123 @@ final class Slf4jLoggerDeclarationTest {
|
||||
CompilationTestHelper.newInstance(Slf4jLoggerDeclaration.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static java.lang.Class.forName;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
class A {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Logger LOG = LoggerFactory.getLogger(A.class);
|
||||
|
||||
abstract static class DynamicLogger {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
}
|
||||
|
||||
abstract static class DynamicLoggerWithExplicitThis {
|
||||
private final Logger log = LoggerFactory.getLogger(this.getClass());
|
||||
}
|
||||
|
||||
static final class StaticLogger {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(StaticLogger.class);
|
||||
}
|
||||
|
||||
static final class StaticLoggerWithCustomIdentifier {
|
||||
private static final Logger LOG = LoggerFactory.getLogger("custom-identifier");
|
||||
}
|
||||
|
||||
interface StaticLoggerForInterface {
|
||||
Logger LOG = LoggerFactory.getLogger(StaticLoggerForInterface.class);
|
||||
}
|
||||
|
||||
abstract static class DynamicLoggerForWrongTypeWithoutReceiver {
|
||||
// BUG: Diagnostic contains:
|
||||
private final Logger log = LoggerFactory.getLogger(forName("A.class"));
|
||||
|
||||
DynamicLoggerForWrongTypeWithoutReceiver() throws ClassNotFoundException {}
|
||||
}
|
||||
|
||||
abstract static class DynamicLoggerForWrongTypeWithoutSymbol {
|
||||
// BUG: Diagnostic contains:
|
||||
private final Logger log = LoggerFactory.getLogger("foo".getClass());
|
||||
}
|
||||
|
||||
abstract static class DynamicLoggerForWrongTypeWithSymbol {
|
||||
// BUG: Diagnostic contains:
|
||||
private final Logger log = LoggerFactory.getLogger(new A().getClass());
|
||||
}
|
||||
|
||||
static final class NonAbstractDynamicLogger {
|
||||
// BUG: Diagnostic contains:
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
}
|
||||
|
||||
abstract static class DynamicLoggerWithMissingModifier {
|
||||
// BUG: Diagnostic contains:
|
||||
final Logger log = LoggerFactory.getLogger(getClass());
|
||||
}
|
||||
|
||||
abstract static class DynamicLoggerWithExcessModifier {
|
||||
// BUG: Diagnostic contains:
|
||||
private final transient Logger log = LoggerFactory.getLogger(getClass());
|
||||
}
|
||||
|
||||
abstract static class MisnamedDynamicLogger {
|
||||
// BUG: Diagnostic contains:
|
||||
private final Logger LOG = LoggerFactory.getLogger(getClass());
|
||||
}
|
||||
|
||||
static final class StaticLoggerWithMissingModifier {
|
||||
// BUG: Diagnostic contains:
|
||||
static final Logger LOG = LoggerFactory.getLogger(StaticLoggerWithMissingModifier.class);
|
||||
}
|
||||
|
||||
static final class StaticLoggerWithExcessModifier {
|
||||
// BUG: Diagnostic contains:
|
||||
private static final transient Logger LOG =
|
||||
LoggerFactory.getLogger(StaticLoggerWithExcessModifier.class);
|
||||
}
|
||||
|
||||
static final class MisnamedStaticLogger {
|
||||
// BUG: Diagnostic contains:
|
||||
private static final Logger log = LoggerFactory.getLogger(MisnamedStaticLogger.class);
|
||||
}
|
||||
|
||||
static final class StaticLoggerWithIncorrectIdentifier {
|
||||
// BUG: Diagnostic contains:
|
||||
private static final Logger LOG = LoggerFactory.getLogger(A.class);
|
||||
}
|
||||
|
||||
static final class StaticLoggerWithCustomIdentifierAndMissingModifier {
|
||||
// BUG: Diagnostic contains:
|
||||
static final Logger LOG = LoggerFactory.getLogger("custom-identifier");
|
||||
}
|
||||
|
||||
static final class StaticLoggerWithCustomIdentifierAndExcessModifier {
|
||||
// BUG: Diagnostic contains:
|
||||
private static final transient Logger LOG = LoggerFactory.getLogger("custom-identifier");
|
||||
}
|
||||
|
||||
static final class MisnamedStaticLoggerWithCustomIdentifier {
|
||||
// BUG: Diagnostic contains:
|
||||
private static final Logger log = LoggerFactory.getLogger("custom-identifier");
|
||||
}
|
||||
|
||||
interface StaticLoggerForInterfaceWithExcessModifier {
|
||||
// BUG: Diagnostic contains:
|
||||
static Logger LOG = LoggerFactory.getLogger(StaticLoggerForInterfaceWithExcessModifier.class);
|
||||
}
|
||||
|
||||
interface MisnamedStaticLoggerForInterface {
|
||||
// BUG: Diagnostic contains:
|
||||
Logger log = LoggerFactory.getLogger(MisnamedStaticLoggerForInterface.class);
|
||||
}
|
||||
|
||||
interface StaticLoggerForInterfaceWithIncorrectIdentifier {
|
||||
// BUG: Diagnostic contains:
|
||||
Logger LOG = LoggerFactory.getLogger(A.class);
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import static java.lang.Class.forName;",
|
||||
"",
|
||||
"import org.slf4j.Logger;",
|
||||
"import org.slf4j.LoggerFactory;",
|
||||
"",
|
||||
"class A {",
|
||||
" private static final long serialVersionUID = 1L;",
|
||||
" private static final Logger LOG = LoggerFactory.getLogger(A.class);",
|
||||
"",
|
||||
" abstract static class DynamicLogger {",
|
||||
" private final Logger log = LoggerFactory.getLogger(getClass());",
|
||||
" }",
|
||||
"",
|
||||
" abstract static class DynamicLoggerWithExplicitThis {",
|
||||
" private final Logger log = LoggerFactory.getLogger(this.getClass());",
|
||||
" }",
|
||||
"",
|
||||
" static final class StaticLogger {",
|
||||
" private static final Logger LOG = LoggerFactory.getLogger(StaticLogger.class);",
|
||||
" }",
|
||||
"",
|
||||
" static final class StaticLoggerWithCustomIdentifier {",
|
||||
" private static final Logger LOG = LoggerFactory.getLogger(\"custom-identifier\");",
|
||||
" }",
|
||||
"",
|
||||
" interface StaticLoggerForInterface {",
|
||||
" Logger LOG = LoggerFactory.getLogger(StaticLoggerForInterface.class);",
|
||||
" }",
|
||||
"",
|
||||
" abstract static class DynamicLoggerForWrongTypeWithoutReceiver {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" private final Logger log = LoggerFactory.getLogger(forName(\"A.class\"));",
|
||||
"",
|
||||
" DynamicLoggerForWrongTypeWithoutReceiver() throws ClassNotFoundException {}",
|
||||
" }",
|
||||
"",
|
||||
" abstract static class DynamicLoggerForWrongTypeWithoutSymbol {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" private final Logger log = LoggerFactory.getLogger(\"foo\".getClass());",
|
||||
" }",
|
||||
"",
|
||||
" abstract static class DynamicLoggerForWrongTypeWithSymbol {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" private final Logger log = LoggerFactory.getLogger(new A().getClass());",
|
||||
" }",
|
||||
"",
|
||||
" static final class NonAbstractDynamicLogger {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" private final Logger log = LoggerFactory.getLogger(getClass());",
|
||||
" }",
|
||||
"",
|
||||
" abstract static class DynamicLoggerWithMissingModifier {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" final Logger log = LoggerFactory.getLogger(getClass());",
|
||||
" }",
|
||||
"",
|
||||
" abstract static class DynamicLoggerWithExcessModifier {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" private final transient Logger log = LoggerFactory.getLogger(getClass());",
|
||||
" }",
|
||||
"",
|
||||
" abstract static class MisnamedDynamicLogger {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" private final Logger LOG = LoggerFactory.getLogger(getClass());",
|
||||
" }",
|
||||
"",
|
||||
" static final class StaticLoggerWithMissingModifier {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" static final Logger LOG = LoggerFactory.getLogger(StaticLoggerWithMissingModifier.class);",
|
||||
" }",
|
||||
"",
|
||||
" static final class StaticLoggerWithExcessModifier {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" private static final transient Logger LOG =",
|
||||
" LoggerFactory.getLogger(StaticLoggerWithExcessModifier.class);",
|
||||
" }",
|
||||
"",
|
||||
" static final class MisnamedStaticLogger {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" private static final Logger log = LoggerFactory.getLogger(MisnamedStaticLogger.class);",
|
||||
" }",
|
||||
"",
|
||||
" static final class StaticLoggerWithIncorrectIdentifier {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" private static final Logger LOG = LoggerFactory.getLogger(A.class);",
|
||||
" }",
|
||||
"",
|
||||
" static final class StaticLoggerWithCustomIdentifierAndMissingModifier {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" static final Logger LOG = LoggerFactory.getLogger(\"custom-identifier\");",
|
||||
" }",
|
||||
"",
|
||||
" static final class StaticLoggerWithCustomIdentifierAndExcessModifier {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" private static final transient Logger LOG = LoggerFactory.getLogger(\"custom-identifier\");",
|
||||
" }",
|
||||
"",
|
||||
" static final class MisnamedStaticLoggerWithCustomIdentifier {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" private static final Logger log = LoggerFactory.getLogger(\"custom-identifier\");",
|
||||
" }",
|
||||
"",
|
||||
" interface StaticLoggerForInterfaceWithExcessModifier {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" static Logger LOG = LoggerFactory.getLogger(StaticLoggerForInterfaceWithExcessModifier.class);",
|
||||
" }",
|
||||
"",
|
||||
" interface MisnamedStaticLoggerForInterface {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Logger log = LoggerFactory.getLogger(MisnamedStaticLoggerForInterface.class);",
|
||||
" }",
|
||||
"",
|
||||
" interface StaticLoggerForInterfaceWithIncorrectIdentifier {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Logger LOG = LoggerFactory.getLogger(A.class);",
|
||||
" }",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -138,56 +136,52 @@ final class Slf4jLoggerDeclarationTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(Slf4jLoggerDeclaration.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
class A {
|
||||
static Logger foo = LoggerFactory.getLogger(Logger.class);
|
||||
|
||||
abstract static class DynamicLogger {
|
||||
transient Logger BAR = LoggerFactory.getLogger(getClass());
|
||||
}
|
||||
|
||||
static final class StaticLogger {
|
||||
transient Logger baz = LoggerFactory.getLogger(LoggerFactory.class);
|
||||
}
|
||||
|
||||
static final class StaticLoggerWithCustomIdentifier {
|
||||
transient Logger qux = LoggerFactory.getLogger("custom-identifier");
|
||||
}
|
||||
|
||||
interface StaticLoggerForInterface {
|
||||
public static final Logger quux = LoggerFactory.getLogger(A.class);
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import org.slf4j.Logger;",
|
||||
"import org.slf4j.LoggerFactory;",
|
||||
"",
|
||||
"class A {",
|
||||
" static Logger foo = LoggerFactory.getLogger(Logger.class);",
|
||||
"",
|
||||
" abstract static class DynamicLogger {",
|
||||
" transient Logger BAR = LoggerFactory.getLogger(getClass());",
|
||||
" }",
|
||||
"",
|
||||
" static final class StaticLogger {",
|
||||
" transient Logger baz = LoggerFactory.getLogger(LoggerFactory.class);",
|
||||
" }",
|
||||
"",
|
||||
" static final class StaticLoggerWithCustomIdentifier {",
|
||||
" transient Logger qux = LoggerFactory.getLogger(\"custom-identifier\");",
|
||||
" }",
|
||||
"",
|
||||
" interface StaticLoggerForInterface {",
|
||||
" public static final Logger quux = LoggerFactory.getLogger(A.class);",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
class A {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(A.class);
|
||||
|
||||
abstract static class DynamicLogger {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
}
|
||||
|
||||
static final class StaticLogger {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(StaticLogger.class);
|
||||
}
|
||||
|
||||
static final class StaticLoggerWithCustomIdentifier {
|
||||
private static final Logger LOG = LoggerFactory.getLogger("custom-identifier");
|
||||
}
|
||||
|
||||
interface StaticLoggerForInterface {
|
||||
Logger LOG = LoggerFactory.getLogger(StaticLoggerForInterface.class);
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import org.slf4j.Logger;",
|
||||
"import org.slf4j.LoggerFactory;",
|
||||
"",
|
||||
"class A {",
|
||||
" private static final Logger LOG = LoggerFactory.getLogger(A.class);",
|
||||
"",
|
||||
" abstract static class DynamicLogger {",
|
||||
" private final Logger log = LoggerFactory.getLogger(getClass());",
|
||||
" }",
|
||||
"",
|
||||
" static final class StaticLogger {",
|
||||
" private static final Logger LOG = LoggerFactory.getLogger(StaticLogger.class);",
|
||||
" }",
|
||||
"",
|
||||
" static final class StaticLoggerWithCustomIdentifier {",
|
||||
" private static final Logger LOG = LoggerFactory.getLogger(\"custom-identifier\");",
|
||||
" }",
|
||||
"",
|
||||
" interface StaticLoggerForInterface {",
|
||||
" Logger LOG = LoggerFactory.getLogger(StaticLoggerForInterface.class);",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
|
||||
@@ -197,32 +191,28 @@ final class Slf4jLoggerDeclarationTest {
|
||||
.setArgs("-XepOpt:Slf4jLoggerDeclaration:CanonicalStaticLoggerName=FOO_BAR")
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
class A {
|
||||
transient Logger LOG = LoggerFactory.getLogger(Logger.class);
|
||||
|
||||
abstract static class DynamicLogger {
|
||||
transient Logger log = LoggerFactory.getLogger(getClass());
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import org.slf4j.Logger;",
|
||||
"import org.slf4j.LoggerFactory;",
|
||||
"",
|
||||
"class A {",
|
||||
" transient Logger LOG = LoggerFactory.getLogger(Logger.class);",
|
||||
"",
|
||||
" abstract static class DynamicLogger {",
|
||||
" transient Logger log = LoggerFactory.getLogger(getClass());",
|
||||
" }",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
class A {
|
||||
private static final Logger FOO_BAR = LoggerFactory.getLogger(A.class);
|
||||
|
||||
abstract static class DynamicLogger {
|
||||
private final Logger fooBar = LoggerFactory.getLogger(getClass());
|
||||
}
|
||||
}
|
||||
""")
|
||||
"import org.slf4j.Logger;",
|
||||
"import org.slf4j.LoggerFactory;",
|
||||
"",
|
||||
"class A {",
|
||||
" private static final Logger FOO_BAR = LoggerFactory.getLogger(A.class);",
|
||||
"",
|
||||
" abstract static class DynamicLogger {",
|
||||
" private final Logger fooBar = LoggerFactory.getLogger(getClass());",
|
||||
" }",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,77 +11,75 @@ final class SpringMvcAnnotationTest {
|
||||
CompilationTestHelper.newInstance(SpringMvcAnnotation.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static org.springframework.web.bind.annotation.RequestMethod.DELETE;
|
||||
import static org.springframework.web.bind.annotation.RequestMethod.GET;
|
||||
import static org.springframework.web.bind.annotation.RequestMethod.HEAD;
|
||||
import static org.springframework.web.bind.annotation.RequestMethod.PATCH;
|
||||
import static org.springframework.web.bind.annotation.RequestMethod.POST;
|
||||
import static org.springframework.web.bind.annotation.RequestMethod.PUT;
|
||||
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PatchMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
interface A {
|
||||
@RequestMapping
|
||||
A simple();
|
||||
|
||||
@RequestMapping(method = {})
|
||||
A explicitDefault();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@RequestMapping(method = RequestMethod.GET)
|
||||
A get();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@RequestMapping(method = {RequestMethod.POST})
|
||||
A post();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@RequestMapping(method = {PUT})
|
||||
A put();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@RequestMapping(method = {DELETE})
|
||||
A delete();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@RequestMapping(method = {PATCH})
|
||||
A patch();
|
||||
|
||||
@RequestMapping(method = HEAD)
|
||||
A head();
|
||||
|
||||
@RequestMapping(method = RequestMethod.OPTIONS)
|
||||
A options();
|
||||
|
||||
@RequestMapping(method = {GET, POST})
|
||||
A simpleMix();
|
||||
|
||||
@RequestMapping(method = {RequestMethod.GET, RequestMethod.POST})
|
||||
A verboseMix();
|
||||
|
||||
@DeleteMapping
|
||||
A properDelete();
|
||||
|
||||
@GetMapping
|
||||
A properGet();
|
||||
|
||||
@PatchMapping
|
||||
A properPatch();
|
||||
|
||||
@PostMapping
|
||||
A properPost();
|
||||
|
||||
@PutMapping
|
||||
A properPut();
|
||||
}
|
||||
""")
|
||||
"import static org.springframework.web.bind.annotation.RequestMethod.DELETE;",
|
||||
"import static org.springframework.web.bind.annotation.RequestMethod.GET;",
|
||||
"import static org.springframework.web.bind.annotation.RequestMethod.HEAD;",
|
||||
"import static org.springframework.web.bind.annotation.RequestMethod.PATCH;",
|
||||
"import static org.springframework.web.bind.annotation.RequestMethod.POST;",
|
||||
"import static org.springframework.web.bind.annotation.RequestMethod.PUT;",
|
||||
"",
|
||||
"import org.springframework.web.bind.annotation.DeleteMapping;",
|
||||
"import org.springframework.web.bind.annotation.GetMapping;",
|
||||
"import org.springframework.web.bind.annotation.PatchMapping;",
|
||||
"import org.springframework.web.bind.annotation.PostMapping;",
|
||||
"import org.springframework.web.bind.annotation.PutMapping;",
|
||||
"import org.springframework.web.bind.annotation.RequestMapping;",
|
||||
"import org.springframework.web.bind.annotation.RequestMethod;",
|
||||
"",
|
||||
"interface A {",
|
||||
" @RequestMapping",
|
||||
" A simple();",
|
||||
"",
|
||||
" @RequestMapping(method = {})",
|
||||
" A explicitDefault();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @RequestMapping(method = RequestMethod.GET)",
|
||||
" A get();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @RequestMapping(method = {RequestMethod.POST})",
|
||||
" A post();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @RequestMapping(method = {PUT})",
|
||||
" A put();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @RequestMapping(method = {DELETE})",
|
||||
" A delete();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @RequestMapping(method = {PATCH})",
|
||||
" A patch();",
|
||||
"",
|
||||
" @RequestMapping(method = HEAD)",
|
||||
" A head();",
|
||||
"",
|
||||
" @RequestMapping(method = RequestMethod.OPTIONS)",
|
||||
" A options();",
|
||||
"",
|
||||
" @RequestMapping(method = {GET, POST})",
|
||||
" A simpleMix();",
|
||||
"",
|
||||
" @RequestMapping(method = {RequestMethod.GET, RequestMethod.POST})",
|
||||
" A verboseMix();",
|
||||
"",
|
||||
" @DeleteMapping",
|
||||
" A properDelete();",
|
||||
"",
|
||||
" @GetMapping",
|
||||
" A properGet();",
|
||||
"",
|
||||
" @PatchMapping",
|
||||
" A properPatch();",
|
||||
"",
|
||||
" @PostMapping",
|
||||
" A properPost();",
|
||||
"",
|
||||
" @PutMapping",
|
||||
" A properPut();",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -90,70 +88,66 @@ final class SpringMvcAnnotationTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(SpringMvcAnnotation.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static org.springframework.web.bind.annotation.RequestMethod.PATCH;
|
||||
import static org.springframework.web.bind.annotation.RequestMethod.POST;
|
||||
import static org.springframework.web.bind.annotation.RequestMethod.PUT;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
interface A {
|
||||
@RequestMapping(method = RequestMethod.GET)
|
||||
A simple();
|
||||
|
||||
@RequestMapping(path = "/foo/bar", method = POST)
|
||||
A prefixed();
|
||||
|
||||
@RequestMapping(
|
||||
method = {RequestMethod.DELETE},
|
||||
path = "/foo/bar")
|
||||
A suffixed();
|
||||
|
||||
@RequestMapping(
|
||||
path = "/foo/bar",
|
||||
method = {PUT},
|
||||
consumes = {"a", "b"})
|
||||
A surrounded();
|
||||
|
||||
@RequestMapping(method = {PATCH})
|
||||
A curly();
|
||||
}
|
||||
""")
|
||||
"import static org.springframework.web.bind.annotation.RequestMethod.PATCH;",
|
||||
"import static org.springframework.web.bind.annotation.RequestMethod.POST;",
|
||||
"import static org.springframework.web.bind.annotation.RequestMethod.PUT;",
|
||||
"",
|
||||
"import org.springframework.web.bind.annotation.RequestMapping;",
|
||||
"import org.springframework.web.bind.annotation.RequestMethod;",
|
||||
"",
|
||||
"interface A {",
|
||||
" @RequestMapping(method = RequestMethod.GET)",
|
||||
" A simple();",
|
||||
"",
|
||||
" @RequestMapping(path = \"/foo/bar\", method = POST)",
|
||||
" A prefixed();",
|
||||
"",
|
||||
" @RequestMapping(",
|
||||
" method = {RequestMethod.DELETE},",
|
||||
" path = \"/foo/bar\")",
|
||||
" A suffixed();",
|
||||
"",
|
||||
" @RequestMapping(",
|
||||
" path = \"/foo/bar\",",
|
||||
" method = {PUT},",
|
||||
" consumes = {\"a\", \"b\"})",
|
||||
" A surrounded();",
|
||||
"",
|
||||
" @RequestMapping(method = {PATCH})",
|
||||
" A curly();",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static org.springframework.web.bind.annotation.RequestMethod.PATCH;
|
||||
import static org.springframework.web.bind.annotation.RequestMethod.POST;
|
||||
import static org.springframework.web.bind.annotation.RequestMethod.PUT;
|
||||
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PatchMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
interface A {
|
||||
@GetMapping()
|
||||
A simple();
|
||||
|
||||
@PostMapping(path = "/foo/bar")
|
||||
A prefixed();
|
||||
|
||||
@DeleteMapping(path = "/foo/bar")
|
||||
A suffixed();
|
||||
|
||||
@PutMapping(
|
||||
path = "/foo/bar",
|
||||
consumes = {"a", "b"})
|
||||
A surrounded();
|
||||
|
||||
@PatchMapping()
|
||||
A curly();
|
||||
}
|
||||
""")
|
||||
"import static org.springframework.web.bind.annotation.RequestMethod.PATCH;",
|
||||
"import static org.springframework.web.bind.annotation.RequestMethod.POST;",
|
||||
"import static org.springframework.web.bind.annotation.RequestMethod.PUT;",
|
||||
"",
|
||||
"import org.springframework.web.bind.annotation.DeleteMapping;",
|
||||
"import org.springframework.web.bind.annotation.GetMapping;",
|
||||
"import org.springframework.web.bind.annotation.PatchMapping;",
|
||||
"import org.springframework.web.bind.annotation.PostMapping;",
|
||||
"import org.springframework.web.bind.annotation.PutMapping;",
|
||||
"import org.springframework.web.bind.annotation.RequestMapping;",
|
||||
"import org.springframework.web.bind.annotation.RequestMethod;",
|
||||
"",
|
||||
"interface A {",
|
||||
" @GetMapping()",
|
||||
" A simple();",
|
||||
"",
|
||||
" @PostMapping(path = \"/foo/bar\")",
|
||||
" A prefixed();",
|
||||
"",
|
||||
" @DeleteMapping(path = \"/foo/bar\")",
|
||||
" A suffixed();",
|
||||
"",
|
||||
" @PutMapping(",
|
||||
" path = \"/foo/bar\",",
|
||||
" consumes = {\"a\", \"b\"})",
|
||||
" A surrounded();",
|
||||
"",
|
||||
" @PatchMapping()",
|
||||
" A curly();",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,95 +34,93 @@ final class StaticImportTest {
|
||||
CompilationTestHelper.newInstance(StaticImport.class, getClass())
|
||||
.addSourceLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static com.google.common.collect.ImmutableMap.toImmutableMap;
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static java.util.function.Predicate.not;
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMultiset;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.errorprone.refaster.ImportPolicy;
|
||||
import com.google.errorprone.refaster.annotation.UseImportPolicy;
|
||||
import com.mongodb.client.model.Filters;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Predicate;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
// BUG: Diagnostic contains:
|
||||
ImmutableMap.toImmutableMap(v -> v, v -> v);
|
||||
ImmutableMap.<String, String, String>toImmutableMap(v -> v, v -> v);
|
||||
toImmutableMap(v -> v, v -> v);
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
ImmutableSet.toImmutableSet();
|
||||
ImmutableSet.<String>toImmutableSet();
|
||||
toImmutableSet();
|
||||
|
||||
// Not flagged because we define `#toImmutableMultiset` below.
|
||||
ImmutableMultiset.toImmutableMultiset();
|
||||
ImmutableMultiset.<String>toImmutableMultiset();
|
||||
toImmutableMultiset();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Predicate.not(null);
|
||||
not(null);
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Predicates.alwaysTrue();
|
||||
// BUG: Diagnostic contains:
|
||||
Predicates.alwaysFalse();
|
||||
// Not flagged because of `java.util.function.Predicate.not` import.
|
||||
Predicates.not(null);
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
UUID uuid = UUID.randomUUID();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Object o1 = StandardCharsets.UTF_8;
|
||||
Object o2 = UTF_8;
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Object e1 = WebEnvironment.RANDOM_PORT;
|
||||
Object e2 = RANDOM_PORT;
|
||||
|
||||
// Not flagged because `MediaType.ALL` is exempted.
|
||||
MediaType t1 = MediaType.ALL;
|
||||
// BUG: Diagnostic contains:
|
||||
MediaType t2 = MediaType.APPLICATION_JSON;
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
Filters.empty();
|
||||
Optional.empty();
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
ZoneOffset zo1 = ZoneOffset.UTC;
|
||||
ZoneOffset zo2 = ZoneOffset.MIN;
|
||||
}
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
|
||||
private static A jsonCreator(int a) {
|
||||
return new A();
|
||||
}
|
||||
|
||||
// BUG: Diagnostic contains:
|
||||
@UseImportPolicy(ImportPolicy.IMPORT_TOP_LEVEL)
|
||||
void refasterAfterTemplate() {}
|
||||
|
||||
void toImmutableMultiset() {}
|
||||
}
|
||||
""")
|
||||
"import static com.google.common.collect.ImmutableMap.toImmutableMap;",
|
||||
"import static com.google.common.collect.ImmutableSet.toImmutableSet;",
|
||||
"import static java.nio.charset.StandardCharsets.UTF_8;",
|
||||
"import static java.util.function.Predicate.not;",
|
||||
"import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;",
|
||||
"",
|
||||
"import com.fasterxml.jackson.annotation.JsonCreator;",
|
||||
"import com.google.common.base.Predicates;",
|
||||
"import com.google.common.collect.ImmutableMap;",
|
||||
"import com.google.common.collect.ImmutableMultiset;",
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import com.google.errorprone.refaster.ImportPolicy;",
|
||||
"import com.google.errorprone.refaster.annotation.UseImportPolicy;",
|
||||
"import com.mongodb.client.model.Filters;",
|
||||
"import java.nio.charset.StandardCharsets;",
|
||||
"import java.time.ZoneOffset;",
|
||||
"import java.util.Optional;",
|
||||
"import java.util.UUID;",
|
||||
"import java.util.function.Predicate;",
|
||||
"import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;",
|
||||
"import org.springframework.http.MediaType;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m() {",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableMap.toImmutableMap(v -> v, v -> v);",
|
||||
" ImmutableMap.<String, String, String>toImmutableMap(v -> v, v -> v);",
|
||||
" toImmutableMap(v -> v, v -> v);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ImmutableSet.toImmutableSet();",
|
||||
" ImmutableSet.<String>toImmutableSet();",
|
||||
" toImmutableSet();",
|
||||
"",
|
||||
" // Not flagged because we define `#toImmutableMultiset` below.",
|
||||
" ImmutableMultiset.toImmutableMultiset();",
|
||||
" ImmutableMultiset.<String>toImmutableMultiset();",
|
||||
" toImmutableMultiset();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Predicate.not(null);",
|
||||
" not(null);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Predicates.alwaysTrue();",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Predicates.alwaysFalse();",
|
||||
" // Not flagged because of `java.util.function.Predicate.not` import.",
|
||||
" Predicates.not(null);",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" UUID uuid = UUID.randomUUID();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Object o1 = StandardCharsets.UTF_8;",
|
||||
" Object o2 = UTF_8;",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Object e1 = WebEnvironment.RANDOM_PORT;",
|
||||
" Object e2 = RANDOM_PORT;",
|
||||
"",
|
||||
" // Not flagged because `MediaType.ALL` is exempted.",
|
||||
" MediaType t1 = MediaType.ALL;",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" MediaType t2 = MediaType.APPLICATION_JSON;",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" Filters.empty();",
|
||||
" Optional.empty();",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" ZoneOffset zo1 = ZoneOffset.UTC;",
|
||||
" ZoneOffset zo2 = ZoneOffset.MIN;",
|
||||
" }",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @JsonCreator(mode = JsonCreator.Mode.DELEGATING)",
|
||||
" private static A jsonCreator(int a) {",
|
||||
" return new A();",
|
||||
" }",
|
||||
"",
|
||||
" // BUG: Diagnostic contains:",
|
||||
" @UseImportPolicy(ImportPolicy.IMPORT_TOP_LEVEL)",
|
||||
" void refasterAfterTemplate() {}",
|
||||
"",
|
||||
" void toImmutableMultiset() {}",
|
||||
"}")
|
||||
.doTest();
|
||||
}
|
||||
|
||||
@@ -131,171 +129,167 @@ final class StaticImportTest {
|
||||
BugCheckerRefactoringTestHelper.newInstance(StaticImport.class, getClass())
|
||||
.addInputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static java.util.function.Predicate.not;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.BugPattern.SeverityLevel;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Pattern;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.springframework.format.annotation.DateTimeFormat.ISO;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
class A {
|
||||
void m1() {
|
||||
ImmutableMap.toImmutableMap(v -> v, v -> v);
|
||||
ImmutableMap.<String, String, String>toImmutableMap(v -> v, v -> v);
|
||||
|
||||
ImmutableSet.toImmutableSet();
|
||||
ImmutableSet.<String>toImmutableSet();
|
||||
|
||||
Collections.disjoint(ImmutableSet.of(), ImmutableSet.of());
|
||||
Collections.reverse(new ArrayList<>());
|
||||
|
||||
Predicates.not(null);
|
||||
not(null);
|
||||
|
||||
Arguments.arguments("foo");
|
||||
|
||||
Objects.requireNonNull("bar");
|
||||
|
||||
Object o = StandardCharsets.UTF_8;
|
||||
|
||||
ImmutableSet.of(
|
||||
MediaType.ALL,
|
||||
MediaType.APPLICATION_XHTML_XML,
|
||||
MediaType.TEXT_HTML,
|
||||
MediaType.valueOf("image/webp"));
|
||||
|
||||
Pattern.compile("", Pattern.CASE_INSENSITIVE);
|
||||
}
|
||||
|
||||
void m2(
|
||||
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE) String date,
|
||||
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) String dateTime,
|
||||
@DateTimeFormat(iso = DateTimeFormat.ISO.TIME) String time) {}
|
||||
|
||||
void m3(
|
||||
@DateTimeFormat(iso = ISO.DATE) String date,
|
||||
@DateTimeFormat(iso = ISO.DATE_TIME) String dateTime,
|
||||
@DateTimeFormat(iso = ISO.TIME) String time) {}
|
||||
|
||||
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
|
||||
private static A jsonCreator(int a) {
|
||||
return new A();
|
||||
}
|
||||
|
||||
@BugPattern(
|
||||
summary = "",
|
||||
linkType = BugPattern.LinkType.NONE,
|
||||
severity = SeverityLevel.SUGGESTION,
|
||||
tags = BugPattern.StandardTags.SIMPLIFICATION)
|
||||
static final class TestBugPattern {}
|
||||
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
|
||||
final class Test {}
|
||||
}
|
||||
""")
|
||||
"import static java.util.function.Predicate.not;",
|
||||
"",
|
||||
"import com.fasterxml.jackson.annotation.JsonCreator;",
|
||||
"import com.google.common.base.Predicates;",
|
||||
"import com.google.common.collect.ImmutableMap;",
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import com.google.errorprone.BugPattern;",
|
||||
"import com.google.errorprone.BugPattern.SeverityLevel;",
|
||||
"import java.nio.charset.StandardCharsets;",
|
||||
"import java.util.ArrayList;",
|
||||
"import java.util.Collections;",
|
||||
"import java.util.Objects;",
|
||||
"import java.util.regex.Pattern;",
|
||||
"import org.junit.jupiter.params.provider.Arguments;",
|
||||
"import org.springframework.boot.test.context.SpringBootTest;",
|
||||
"import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;",
|
||||
"import org.springframework.format.annotation.DateTimeFormat;",
|
||||
"import org.springframework.format.annotation.DateTimeFormat.ISO;",
|
||||
"import org.springframework.http.MediaType;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m1() {",
|
||||
" ImmutableMap.toImmutableMap(v -> v, v -> v);",
|
||||
" ImmutableMap.<String, String, String>toImmutableMap(v -> v, v -> v);",
|
||||
"",
|
||||
" ImmutableSet.toImmutableSet();",
|
||||
" ImmutableSet.<String>toImmutableSet();",
|
||||
"",
|
||||
" Collections.disjoint(ImmutableSet.of(), ImmutableSet.of());",
|
||||
" Collections.reverse(new ArrayList<>());",
|
||||
"",
|
||||
" Predicates.not(null);",
|
||||
" not(null);",
|
||||
"",
|
||||
" Arguments.arguments(\"foo\");",
|
||||
"",
|
||||
" Objects.requireNonNull(\"bar\");",
|
||||
"",
|
||||
" Object o = StandardCharsets.UTF_8;",
|
||||
"",
|
||||
" ImmutableSet.of(",
|
||||
" MediaType.ALL,",
|
||||
" MediaType.APPLICATION_XHTML_XML,",
|
||||
" MediaType.TEXT_HTML,",
|
||||
" MediaType.valueOf(\"image/webp\"));",
|
||||
"",
|
||||
" Pattern.compile(\"\", Pattern.CASE_INSENSITIVE);",
|
||||
" }",
|
||||
"",
|
||||
" void m2(",
|
||||
" @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) String date,",
|
||||
" @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) String dateTime,",
|
||||
" @DateTimeFormat(iso = DateTimeFormat.ISO.TIME) String time) {}",
|
||||
"",
|
||||
" void m3(",
|
||||
" @DateTimeFormat(iso = ISO.DATE) String date,",
|
||||
" @DateTimeFormat(iso = ISO.DATE_TIME) String dateTime,",
|
||||
" @DateTimeFormat(iso = ISO.TIME) String time) {}",
|
||||
"",
|
||||
" @JsonCreator(mode = JsonCreator.Mode.DELEGATING)",
|
||||
" private static A jsonCreator(int a) {",
|
||||
" return new A();",
|
||||
" }",
|
||||
"",
|
||||
" @BugPattern(",
|
||||
" summary = \"\",",
|
||||
" linkType = BugPattern.LinkType.NONE,",
|
||||
" severity = SeverityLevel.SUGGESTION,",
|
||||
" tags = BugPattern.StandardTags.SIMPLIFICATION)",
|
||||
" static final class TestBugPattern {}",
|
||||
"",
|
||||
" @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)",
|
||||
" final class Test {}",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"A.java",
|
||||
"""
|
||||
import static com.fasterxml.jackson.annotation.JsonCreator.Mode.DELEGATING;
|
||||
import static com.google.common.collect.ImmutableMap.toImmutableMap;
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
import static com.google.errorprone.BugPattern.LinkType.NONE;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION;
|
||||
import static com.google.errorprone.BugPattern.StandardTags.SIMPLIFICATION;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static java.util.Collections.disjoint;
|
||||
import static java.util.Collections.reverse;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static java.util.function.Predicate.not;
|
||||
import static java.util.regex.Pattern.CASE_INSENSITIVE;
|
||||
import static org.junit.jupiter.params.provider.Arguments.arguments;
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
|
||||
import static org.springframework.format.annotation.DateTimeFormat.ISO.DATE;
|
||||
import static org.springframework.format.annotation.DateTimeFormat.ISO.DATE_TIME;
|
||||
import static org.springframework.format.annotation.DateTimeFormat.ISO.TIME;
|
||||
import static org.springframework.http.MediaType.APPLICATION_XHTML_XML;
|
||||
import static org.springframework.http.MediaType.TEXT_HTML;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.BugPattern.SeverityLevel;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Pattern;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.springframework.format.annotation.DateTimeFormat.ISO;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
class A {
|
||||
void m1() {
|
||||
toImmutableMap(v -> v, v -> v);
|
||||
ImmutableMap.<String, String, String>toImmutableMap(v -> v, v -> v);
|
||||
|
||||
toImmutableSet();
|
||||
ImmutableSet.<String>toImmutableSet();
|
||||
|
||||
disjoint(ImmutableSet.of(), ImmutableSet.of());
|
||||
reverse(new ArrayList<>());
|
||||
|
||||
Predicates.not(null);
|
||||
not(null);
|
||||
|
||||
arguments("foo");
|
||||
|
||||
requireNonNull("bar");
|
||||
|
||||
Object o = UTF_8;
|
||||
|
||||
ImmutableSet.of(
|
||||
MediaType.ALL, APPLICATION_XHTML_XML, TEXT_HTML, MediaType.valueOf("image/webp"));
|
||||
|
||||
Pattern.compile("", CASE_INSENSITIVE);
|
||||
}
|
||||
|
||||
void m2(
|
||||
@DateTimeFormat(iso = DATE) String date,
|
||||
@DateTimeFormat(iso = DATE_TIME) String dateTime,
|
||||
@DateTimeFormat(iso = TIME) String time) {}
|
||||
|
||||
void m3(
|
||||
@DateTimeFormat(iso = DATE) String date,
|
||||
@DateTimeFormat(iso = DATE_TIME) String dateTime,
|
||||
@DateTimeFormat(iso = TIME) String time) {}
|
||||
|
||||
@JsonCreator(mode = DELEGATING)
|
||||
private static A jsonCreator(int a) {
|
||||
return new A();
|
||||
}
|
||||
|
||||
@BugPattern(summary = "", linkType = NONE, severity = SUGGESTION, tags = SIMPLIFICATION)
|
||||
static final class TestBugPattern {}
|
||||
|
||||
@SpringBootTest(webEnvironment = RANDOM_PORT)
|
||||
final class Test {}
|
||||
}
|
||||
""")
|
||||
"import static com.fasterxml.jackson.annotation.JsonCreator.Mode.DELEGATING;",
|
||||
"import static com.google.common.collect.ImmutableMap.toImmutableMap;",
|
||||
"import static com.google.common.collect.ImmutableSet.toImmutableSet;",
|
||||
"import static com.google.errorprone.BugPattern.LinkType.NONE;",
|
||||
"import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION;",
|
||||
"import static com.google.errorprone.BugPattern.StandardTags.SIMPLIFICATION;",
|
||||
"import static java.nio.charset.StandardCharsets.UTF_8;",
|
||||
"import static java.util.Collections.disjoint;",
|
||||
"import static java.util.Collections.reverse;",
|
||||
"import static java.util.Objects.requireNonNull;",
|
||||
"import static java.util.function.Predicate.not;",
|
||||
"import static java.util.regex.Pattern.CASE_INSENSITIVE;",
|
||||
"import static org.junit.jupiter.params.provider.Arguments.arguments;",
|
||||
"import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;",
|
||||
"import static org.springframework.format.annotation.DateTimeFormat.ISO.DATE;",
|
||||
"import static org.springframework.format.annotation.DateTimeFormat.ISO.DATE_TIME;",
|
||||
"import static org.springframework.format.annotation.DateTimeFormat.ISO.TIME;",
|
||||
"import static org.springframework.http.MediaType.APPLICATION_XHTML_XML;",
|
||||
"import static org.springframework.http.MediaType.TEXT_HTML;",
|
||||
"",
|
||||
"import com.fasterxml.jackson.annotation.JsonCreator;",
|
||||
"import com.google.common.base.Predicates;",
|
||||
"import com.google.common.collect.ImmutableMap;",
|
||||
"import com.google.common.collect.ImmutableSet;",
|
||||
"import com.google.errorprone.BugPattern;",
|
||||
"import com.google.errorprone.BugPattern.SeverityLevel;",
|
||||
"import java.nio.charset.StandardCharsets;",
|
||||
"import java.util.ArrayList;",
|
||||
"import java.util.Collections;",
|
||||
"import java.util.Objects;",
|
||||
"import java.util.regex.Pattern;",
|
||||
"import org.junit.jupiter.params.provider.Arguments;",
|
||||
"import org.springframework.boot.test.context.SpringBootTest;",
|
||||
"import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;",
|
||||
"import org.springframework.format.annotation.DateTimeFormat;",
|
||||
"import org.springframework.format.annotation.DateTimeFormat.ISO;",
|
||||
"import org.springframework.http.MediaType;",
|
||||
"",
|
||||
"class A {",
|
||||
" void m1() {",
|
||||
" toImmutableMap(v -> v, v -> v);",
|
||||
" ImmutableMap.<String, String, String>toImmutableMap(v -> v, v -> v);",
|
||||
"",
|
||||
" toImmutableSet();",
|
||||
" ImmutableSet.<String>toImmutableSet();",
|
||||
"",
|
||||
" disjoint(ImmutableSet.of(), ImmutableSet.of());",
|
||||
" reverse(new ArrayList<>());",
|
||||
"",
|
||||
" Predicates.not(null);",
|
||||
" not(null);",
|
||||
"",
|
||||
" arguments(\"foo\");",
|
||||
"",
|
||||
" requireNonNull(\"bar\");",
|
||||
"",
|
||||
" Object o = UTF_8;",
|
||||
"",
|
||||
" ImmutableSet.of(",
|
||||
" MediaType.ALL, APPLICATION_XHTML_XML, TEXT_HTML, MediaType.valueOf(\"image/webp\"));",
|
||||
"",
|
||||
" Pattern.compile(\"\", CASE_INSENSITIVE);",
|
||||
" }",
|
||||
"",
|
||||
" void m2(",
|
||||
" @DateTimeFormat(iso = DATE) String date,",
|
||||
" @DateTimeFormat(iso = DATE_TIME) String dateTime,",
|
||||
" @DateTimeFormat(iso = TIME) String time) {}",
|
||||
"",
|
||||
" void m3(",
|
||||
" @DateTimeFormat(iso = DATE) String date,",
|
||||
" @DateTimeFormat(iso = DATE_TIME) String dateTime,",
|
||||
" @DateTimeFormat(iso = TIME) String time) {}",
|
||||
"",
|
||||
" @JsonCreator(mode = DELEGATING)",
|
||||
" private static A jsonCreator(int a) {",
|
||||
" return new A();",
|
||||
" }",
|
||||
"",
|
||||
" @BugPattern(summary = \"\", linkType = NONE, severity = SUGGESTION, tags = SIMPLIFICATION)",
|
||||
" static final class TestBugPattern {}",
|
||||
"",
|
||||
" @SpringBootTest(webEnvironment = RANDOM_PORT)",
|
||||
" final class Test {}",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user