Compare commits

..

74 Commits

Author SHA1 Message Date
Gijs de Jong
c8c354617d update submodules 2023-10-13 16:26:57 +02:00
Gijs de Jong
0a0c09c447 Clean up action 2023-10-13 16:20:43 +02:00
Gijs de Jong
2cd6b2dc15 Add on-demand integration test workflow 2023-10-13 16:08:55 +02:00
Gijs de Jong
8846614513 Improve integration scripts 2023-10-13 16:00:53 +02:00
Gijs de Jong
9af80ce1ae Skip StaticImport Lexigraphical sort 2023-10-13 16:00:53 +02:00
Gijs de Jong
df89f6d83b Add calcite integration test 2023-10-13 16:00:53 +02:00
Gijs de Jong
0bcd6f081f Finalise processing module 2023-10-13 16:00:52 +02:00
Gijs de Jong
bcd33f42e5 druid progress 2023-10-13 16:00:52 +02:00
Gijs de Jong
f3a6f35fd4 Initial druid integration test 2023-10-13 16:00:52 +02:00
Gijs de Jong
d9a687de4a Finalize dropwizard/metrics integration test 2023-10-13 16:00:52 +02:00
Gijs de Jong
87bc9492b1 Add metrics as integration test 2023-10-13 16:00:52 +02:00
Gijs de Jong
397a299db6 Finalise guava integration test! 2023-10-13 16:00:52 +02:00
Gijs de Jong
1a077529c7 update init patch 2023-10-13 16:00:52 +02:00
Gijs de Jong
07d7c8aad2 Update init.patch 2023-10-13 16:00:51 +02:00
Gijs de Jong
7ffceb5e41 Add suppressions for Preconditions rule 2023-10-13 16:00:51 +02:00
Gijs de Jong
9af5031ea2 update guava patches 2023-10-13 16:00:51 +02:00
Gijs de Jong
c445f0cce9 update guava init patch 2023-10-13 16:00:51 +02:00
Gijs de Jong
42acd1a192 add guava 2023-10-13 16:00:51 +02:00
Gijs de Jong
b91ae01c26 Add expected warnings file 2023-10-13 16:00:51 +02:00
Gijs de Jong
d3e5b20a05 Update checkstyle integration test 2023-10-13 16:00:51 +02:00
Gijs de Jong
65a13c84b4 Update checkstyle to 10.9.3 2023-10-13 16:00:50 +02:00
Stephan Schroevers
696999505f WIP: Introduce Checkstyle integration test 2023-10-13 16:00:50 +02:00
Vincent Koeman
4e2ceeb252 Introduce StreamOf{1,2,3,4,5} Refaster rules (#814) 2023-10-11 17:52:52 +02:00
Picnic-Bot
05809b1c85 Upgrade Byte Buddy 1.14.8 -> 1.14.9 (#827)
See:
- https://github.com/raphw/byte-buddy/releases/tag/byte-buddy-1.14.9
- https://github.com/raphw/byte-buddy/compare/byte-buddy-1.14.8...byte-buddy-1.14.9
2023-10-11 09:14:28 +02:00
Stephan Schroevers
75679396df Introduce PatternRules Refaster rule collection (#771)
While there, configure `StaticImport` to not require static importing of
`com.google.common.base.Predicates.contains`.

The new rules triggered cleanup of some `CompilationTestHelper` usages.

See google/guava#6483.
2023-10-11 08:36:26 +02:00
Picnic-Bot
f1882caf88 Upgrade pitest-maven-plugin 1.15.0 -> 1.15.1 (#830)
See:
- https://github.com/hcoles/pitest/releases/tag/1.15.1
- https://github.com/hcoles/pitest/compare/1.15.0...1.15.1
2023-10-11 08:18:44 +02:00
Picnic-Bot
605d045760 Upgrade ossf/scorecard-action v2.2.0 -> v2.3.0 (#821)
See:
- https://github.com/ossf/scorecard-action/releases/tag/v2.3.0
2023-10-10 09:22:48 +02:00
Rick Ossendrijver
b492a4afd3 Fix and enable ClassRules Refaster rule collection tests (#826) 2023-10-10 08:37:43 +02:00
Phil Werli
583e51c9b0 Introduce {Mono,Flux}OfType Refaster rules (#810) 2023-10-09 11:57:36 +02:00
Vincent Koeman
9ada0783dd Introduce Flux{Empty,Just} Refaster rules (#815) 2023-10-09 11:30:50 +02:00
Picnic-Bot
7ed3e63d2e Upgrade CodeQL v2.21.9 -> v2.22.0 (#824)
See:
- https://github.com/github/codeql-action/blob/main/CHANGELOG.md
- https://github.com/github/codeql-action/compare/v2.21.9...v2.22.0
2023-10-09 11:20:56 +02:00
Picnic-Bot
465f83b855 Upgrade Arcmutate 1.2.0 -> 1.2.1 (#818) 2023-10-09 10:42:34 +02:00
Picnic-Bot
24f8b2f499 Upgrade Google Java Format 1.18.0 -> 1.18.1 (#819)
See:
- https://github.com/google/google-java-format/releases/tag/v1.18.1
- https://github.com/google/google-java-format/compare/v1.18.0...v1.18.1
2023-10-09 10:33:52 +02:00
Picnic-Bot
f466c75bf3 Upgrade ruby/setup-ruby v1.152.0 -> v1.155.0 (#825)
See:
- https://github.com/ruby/setup-ruby/releases/tag/v1.155.0
- https://github.com/ruby/setup-ruby/releases/tag/v1.154.0
- https://github.com/ruby/setup-ruby/releases/tag/v1.153.0
2023-10-09 09:31:53 +02:00
Stephan Schroevers
c48db5202c Introduce additional Mockito Refaster rules (#777) 2023-10-09 09:23:47 +02:00
Picnic-Bot
629cb577ea Upgrade Immutables Annotations 2.9.3 -> 2.10.0 (#823)
See:
- https://github.com/immutables/immutables/releases/tag/2.10.0
- https://github.com/immutables/immutables/compare/2.9.3...2.10.0
2023-10-09 09:06:03 +02:00
Picnic-Bot
b13d445e56 Upgrade Mockito 5.5.0 -> 5.6.0 (#820)
See:
- https://github.com/mockito/mockito/releases/tag/v5.6.0
- https://github.com/mockito/mockito/compare/v5.5.0...v5.6.0
2023-10-09 08:05:29 +02:00
Stephan Schroevers
b1683a31e9 Introduce ClassRules Refaster rule collection (#811) 2023-10-09 07:42:02 +02:00
Vincent Koeman
ffe4db2cf8 Extend StepVerifierLastStepVerifyErrorClass Refaster rule (#813) 2023-10-08 16:22:36 +02:00
Stephan Schroevers
da5eea8329 Introduce assorted Reactor Refaster rules (#763) 2023-10-06 21:45:22 +02:00
Stephan Schroevers
5596b584ac [maven-release-plugin] prepare for next development iteration 2023-10-04 16:40:37 +02:00
Stephan Schroevers
4800522a09 [maven-release-plugin] prepare release v0.14.0 2023-10-04 16:40:37 +02:00
Stephan Schroevers
9a77a3f35f Drop ScheduledTransactionTrace check (#788)
As well as any other references to New Relic.
2023-10-04 15:30:13 +02:00
Picnic-Bot
ef75b80e7b Upgrade Error Prone 2.21.1 -> 2.22.0 (#800)
See:
- https://github.com/google/error-prone/releases/tag/v2.22.0
- https://github.com/google/error-prone/compare/v2.21.1...v2.22.0
- https://github.com/PicnicSupermarket/error-prone/compare/v2.21.1-picnic-1...v2.22.0-picnic-1
2023-10-04 14:43:27 +02:00
Picnic-Bot
7c618f7e2d Upgrade sonar-maven-plugin 3.9.1.2184 -> 3.10.0.2594 (#792)
See:
- https://github.com/SonarSource/sonar-scanner-maven/releases/tag/3.10.0.2594
- https://github.com/SonarSource/sonar-scanner-maven/compare/3.9.1.2184...3.10.0.2594
2023-10-04 13:44:51 +02:00
Stephan Schroevers
c03ead9e5d Upgrade JDKs used by GitHub Actions builds (#780)
Summary of changes:
- Use JDK 11.0.20 instead of 11.0.19.
- Use JDK 17.0.8 instead of 17.0.7.
- Use JDK 20.0.2 instead of 20.0.1.

See:
- https://www.oracle.com/java/technologies/javase/11-0-20-relnotes.html
- https://www.oracle.com/java/technologies/javase/17-0-8-relnotes.html
- https://www.oracle.com/java/technologies/javase/20-0-2-relnotes.html
2023-10-04 11:22:16 +02:00
Picnic-Bot
8fd87a5b6b Upgrade SLF4J 2.0.7 -> 2.0.9 (#778)
See:
- https://www.slf4j.org/news.html
- https://github.com/qos-ch/slf4j/compare/v_2.0.7...v_2.0.9
2023-10-04 10:59:37 +02:00
Picnic-Bot
82025a729f Upgrade fmt-maven-plugin 2.20 -> 2.21.1 (#804)
See:
- https://github.com/spotify/fmt-maven-plugin/releases/tag/2.21
- https://github.com/spotify/fmt-maven-plugin/releases/tag/2.21.1
- https://github.com/spotify/fmt-maven-plugin/compare/fmt-maven-plugin-2.20...2.21.1
2023-10-04 10:29:27 +02:00
Picnic-Bot
7d912d1b04 Upgrade Swagger 2.2.15 -> 2.2.16 (#795)
See:
- https://github.com/swagger-api/swagger-core/releases/tag/v2.2.16
- https://github.com/swagger-api/swagger-core/compare/v2.2.15...v2.2.16
2023-10-04 08:45:30 +02:00
Picnic-Bot
a726514e98 Upgrade AspectJ 1.9.20 -> 1.9.20.1 (#781)
See:
- https://github.com/eclipse-aspectj/aspectj/releases/tag/V1_9_20_1
- https://github.com/eclipse/org.aspectj/compare/V1_9_20...V1_9_20_1
2023-10-04 08:36:58 +02:00
Picnic-Bot
aa7de5777c Upgrade Spring 5.3.29 -> 5.3.30 (#791)
See:
- https://github.com/spring-projects/spring-framework/releases/tag/v5.3.30
- https://github.com/spring-projects/spring-framework/compare/v5.3.29...v5.3.30
2023-10-04 08:25:50 +02:00
Picnic-Bot
6e6efb3c13 Upgrade Project Reactor 2022.0.10 -> 2022.0.11 (#789)
See:
- https://github.com/reactor/reactor/releases/tag/2022.0.11
- https://github.com/reactor/reactor/compare/2022.0.10...2022.0.11
2023-10-03 16:54:15 +02:00
Picnic-Bot
03fd050eae Upgrade AutoValue 1.10.3 -> 1.10.4 (#784)
See:
- https://github.com/google/auto/releases/tag/auto-value-1.10.4
- https://github.com/google/auto/compare/auto-value-1.10.3...auto-value-1.10.4
2023-10-03 16:42:00 +02:00
Picnic-Bot
d1467e0424 Upgrade actions/upload-artifact v3.1.2 -> v3.1.3 (#782)
See:
- https://github.com/actions/upload-artifact/releases/tag/v3.1.3
2023-10-03 16:08:59 +02:00
Picnic-Bot
a2e32ed147 Upgrade maven-enforcer-plugin 3.4.0 -> 3.4.1 (#787)
See:
- https://github.com/apache/maven-enforcer/releases/tag/enforcer-3.4.1
- https://github.com/apache/maven-enforcer/compare/enforcer-3.4.0...enforcer-3.4.1
2023-10-03 15:58:07 +02:00
Picnic-Bot
258708e6a8 Upgrade New Relic Java Agent 8.5.0 -> 8.6.0 (#785)
See:
- https://github.com/newrelic/newrelic-java-agent/releases/tag/v8.6.0
- https://github.com/newrelic/newrelic-java-agent/compare/v8.5.0...v8.6.0
2023-10-03 13:23:08 +02:00
Picnic-Bot
67106a9725 Upgrade actions/setup-java v3.12.0 -> v3.13.0 (#798)
See:
- https://github.com/actions/setup-java/releases/tag/v3.13.0
2023-10-03 13:14:33 +02:00
Picnic-Bot
f979576ab5 Upgrade maven-javadoc-plugin 3.5.0 -> 3.6.0 (#793)
See:
- https://github.com/apache/maven-javadoc-plugin/releases/tag/maven-javadoc-plugin-3.6.0
- https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.5.0...maven-javadoc-plugin-3.6.0
2023-10-03 12:53:51 +02:00
Picnic-Bot
aa3fd03569 Upgrade dawidd6/action-download-artifact v2.27.0 -> v2.28.0 (#796)
See:
- https://github.com/dawidd6/action-download-artifact/compare/v2.27.0...v2.28.0
2023-10-03 11:59:38 +02:00
Picnic-Bot
5602251667 Upgrade actions/checkout v3.6.0 -> v4.1.0 (#779)
See:
- https://github.com/actions/checkout/blob/HEAD/CHANGELOG.md#v410
- https://github.com/actions/checkout/blob/HEAD/CHANGELOG.md#v400
2023-10-03 11:51:20 +02:00
Picnic-Bot
05cb6387b9 Upgrade Checkstyle 10.12.3 -> 10.12.4 (#807)
See:
- https://checkstyle.sourceforge.io/releasenotes.html
- https://github.com/checkstyle/checkstyle/releases/tag/checkstyle-10.12.4
- https://github.com/checkstyle/checkstyle/compare/checkstyle-10.12.3...checkstyle-10.12.4
2023-10-03 11:38:31 +02:00
Picnic-Bot
4e242a5b11 Upgrade Byte Buddy 1.14.7 -> 1.14.8 (#790)
See:
- https://github.com/raphw/byte-buddy/releases/tag/byte-buddy-1.14.8
- https://github.com/raphw/byte-buddy/compare/byte-buddy-1.14.7...byte-buddy-1.14.8
2023-10-03 10:31:08 +02:00
Picnic-Bot
87297c9a1d Upgrade versions-maven-plugin 2.16.0 -> 2.16.1 (#797)
See:
- https://github.com/mojohaus/versions/releases/tag/2.16.1
- https://github.com/mojohaus/versions-maven-plugin/compare/2.16.0...2.16.1
2023-10-03 10:17:14 +02:00
Picnic-Bot
15ff85c4ea Upgrade Checker Framework Annotations 3.38.0 -> 3.39.0 (#808)
See:
- https://github.com/typetools/checker-framework/releases/tag/checker-framework-3.39.0
- https://github.com/typetools/checker-framework/compare/checker-framework-3.38.0...checker-framework-3.39.0
2023-10-03 10:00:24 +02:00
Picnic-Bot
2c8469fa93 Upgrade Google Java Format 1.17.0 -> 1.18.0 (#809)
See:
- https://github.com/google/google-java-format/releases/tag/v1.18.0
- https://github.com/google/google-java-format/compare/v1.17.0...v1.18.0
2023-10-03 09:28:21 +02:00
Picnic-Bot
f4e0fd2cc3 Upgrade Modernizer Maven Plugin 2.6.0 -> 2.7.0 (#801)
See:
- https://github.com/gaul/modernizer-maven-plugin/releases/tag/modernizer-maven-plugin-2.7.0
- https://github.com/gaul/modernizer-maven-plugin/compare/modernizer-maven-plugin-2.6.0...modernizer-maven-plugin-2.7.0
2023-10-03 08:55:08 +02:00
Picnic-Bot
34fd692064 Upgrade pitest-maven-plugin 1.14.4 -> 1.15.0 (#803)
See:
- https://github.com/hcoles/pitest/releases/tag/1.15.0
- https://github.com/hcoles/pitest/compare/1.14.4...1.15.0
2023-10-03 08:07:16 +02:00
Stephan Schroevers
26bc7e6e8e Disallow autovalue.shaded.* imports (#774) 2023-10-02 18:00:57 +02:00
Picnic-Bot
56cb86a7e1 Upgrade Checker Framework Annotations 3.37.0 -> 3.38.0 (#773)
See:
- https://github.com/typetools/checker-framework/releases/tag/checker-framework-3.38.0
- https://github.com/typetools/checker-framework/compare/checker-framework-3.37.0...checker-framework-3.38.0
2023-10-02 17:43:17 +02:00
Picnic-Bot
19cd802ec5 Upgrade NullAway 0.10.12 -> 0.10.14 (#776)
See:
- https://github.com/uber/NullAway/blob/master/CHANGELOG.md
- https://github.com/uber/NullAway/releases/tag/v0.10.13
- https://github.com/uber/NullAway/releases/tag/v0.10.14
- https://github.com/uber/NullAway/compare/v0.10.12...v0.10.14
2023-10-02 16:29:33 +02:00
Picnic-Bot
1fabb26ed2 Upgrade Spring Boot 2.7.15 -> 2.7.16 (#799)
See:
- https://github.com/spring-projects/spring-boot/releases/tag/v2.7.16
- https://github.com/spring-projects/spring-boot/compare/v2.7.15...v2.7.16
2023-10-02 16:17:58 +02:00
Picnic-Bot
c1ced1e962 Upgrade CodeQL v2.21.4 -> v2.21.9 (#786)
See:
- https://github.com/github/codeql-action/blob/main/CHANGELOG.md
- https://github.com/github/codeql-action/compare/v2.21.4...v2.21.9
2023-10-02 09:57:34 +02:00
Picnic-Bot
030ed25be8 Upgrade Forbidden APIs plugin 3.5.1 -> 3.6 (#806)
See:
- https://github.com/policeman-tools/forbidden-apis/wiki/Changes
- https://github.com/policeman-tools/forbidden-apis/compare/3.5.1...3.6
2023-10-02 09:20:01 +02:00
Picnic-Bot
ee0c04a44e Upgrade Arcmutate 1.1.3 -> 1.2.0 (#805) 2023-10-02 07:10:41 +02:00
80 changed files with 197962 additions and 834 deletions

View File

@@ -42,7 +42,7 @@ Please replace this sentence with log output, if applicable.
<!-- Please complete the following information: -->
- Operating system (e.g. MacOS Monterey).
- Java version (i.e. `java --version`, e.g. `17.0.7`).
- Java version (i.e. `java --version`, e.g. `17.0.8`).
- Error Prone version (e.g. `2.18.0`).
- Error Prone Support version (e.g. `0.9.0`).

View File

@@ -10,16 +10,16 @@ jobs:
strategy:
matrix:
os: [ ubuntu-22.04 ]
jdk: [ 11.0.19, 17.0.7, 20.0.1 ]
jdk: [ 11.0.20, 17.0.8, 20.0.2 ]
distribution: [ temurin ]
experimental: [ false ]
include:
- os: macos-12
jdk: 17.0.7
jdk: 17.0.8
distribution: temurin
experimental: false
- os: windows-2022
jdk: 17.0.7
jdk: 17.0.8
distribution: temurin
experimental: false
runs-on: ${{ matrix.os }}
@@ -31,11 +31,11 @@ jobs:
# additionally enabling all checks defined in this project and any Error
# Prone checks available only from other artifact repositories.
- name: Check out code
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
with:
persist-credentials: false
- name: Set up JDK
uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3.12.0
uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3.13.0
with:
java-version: ${{ matrix.jdk }}
distribution: ${{ matrix.distribution }}

View File

@@ -22,23 +22,23 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Check out code
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
with:
persist-credentials: false
- name: Set up JDK
uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3.12.0
uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3.13.0
with:
java-version: 17.0.7
java-version: 17.0.8
distribution: temurin
cache: maven
- name: Initialize CodeQL
uses: github/codeql-action/init@a09933a12a80f87b87005513f0abb1494c27a716 # v2.21.4
uses: github/codeql-action/init@2cb752a87e96af96708ab57187ab6372ee1973ab # v2.22.0
with:
languages: ${{ matrix.language }}
- name: Perform minimal build
if: matrix.language == 'java'
run: mvn -T1C clean install -DskipTests -Dverification.skip
- name: Perform CodeQL analysis
uses: github/codeql-action/analyze@a09933a12a80f87b87005513f0abb1494c27a716 # v2.21.4
uses: github/codeql-action/analyze@2cb752a87e96af96708ab57187ab6372ee1973ab # v2.22.0
with:
category: /language:${{ matrix.language }}

View File

@@ -12,10 +12,10 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Check out code
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
with:
persist-credentials: false
- uses: ruby/setup-ruby@250fcd6a742febb1123a77a841497ccaa8b9e939 # v1.152.0
- uses: ruby/setup-ruby@d37167af451eb51448db3354e1057b75c4b268f7 # v1.155.0
with:
working-directory: ./website
bundler-cache: true

36
.github/workflows/integration-test.yml vendored Normal file
View File

@@ -0,0 +1,36 @@
name: On-demand integration test
on:
# run action every time a new comment is created
issue_comment:
types: [ created ]
permissions:
contents: read
jobs:
on_demand_integration_test:
name: On-demand integration test
# Only run the integration test if the created comment is on a pull request
# and contains the string `/integration-test`
if: |
github.event.issue.pull_request &&
contains(github.event.comment.body, '/integration-test')
# XXX TODO: Device matrix?
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1
with:
submodules: 'recursive'
persist-credentials: false
- name: Set up JDK
uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3.13.0
with:
# XXX TODO: java version matrix?
java-version: 17.0.8
distribution: temurin
cache: maven
- name: Display build environment details
run: mvn --version
- name: Install error-prone-support snapshot
run: mvn -T1C install -DskipTests -Dverification.skip
- name: Run integration test
run: echo "running integration test"

View File

@@ -21,16 +21,16 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Check out code
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
with:
persist-credentials: false
- name: Run OpenSSF Scorecard analysis
uses: ossf/scorecard-action@08b4669551908b1024bb425080c797723083c031 # v2.2.0
uses: ossf/scorecard-action@483ef80eb98fb506c348f7d62e28055e49fe2398 # v2.3.0
with:
results_file: results.sarif
results_format: sarif
publish_results: ${{ github.ref == 'refs/heads/master' }}
- name: Update GitHub's code scanning dashboard
uses: github/codeql-action/upload-sarif@a09933a12a80f87b87005513f0abb1494c27a716 # v2.21.4
uses: github/codeql-action/upload-sarif@2cb752a87e96af96708ab57187ab6372ee1973ab # v2.22.0
with:
sarif_file: results.sarif

View File

@@ -12,14 +12,14 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Check out code
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
with:
fetch-depth: 2
persist-credentials: false
- name: Set up JDK
uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3.12.0
uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3.13.0
with:
java-version: 17.0.7
java-version: 17.0.8
distribution: temurin
cache: maven
- name: Run Pitest
@@ -32,7 +32,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@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
with:
name: pitest-reports
path: ./target/pit-reports-ci

View File

@@ -20,17 +20,17 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Check out code
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
with:
persist-credentials: false
- name: Set up JDK
uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3.12.0
uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3.13.0
with:
java-version: 17.0.7
java-version: 17.0.8
distribution: temurin
cache: maven
- name: Download Pitest analysis artifact
uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 # v2.27.0
uses: dawidd6/action-download-artifact@268677152d06ba59fcec7a7f0b5d961b6ccd7e1e # v2.28.0
with:
workflow: ${{ github.event.workflow_run.workflow_id }}
name: pitest-reports

View File

@@ -16,14 +16,14 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Check out code
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
with:
fetch-depth: 0
persist-credentials: false
- name: Set up JDK
uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3.12.0
uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3.13.0
with:
java-version: 17.0.7
java-version: 17.0.8
distribution: temurin
cache: maven
- name: Create missing `test` directory

15
.gitmodules vendored Normal file
View File

@@ -0,0 +1,15 @@
[submodule "integration-tests/checkstyle"]
path = integration-tests/checkstyle
url = git@github.com:checkstyle/checkstyle.git
[submodule "integration-tests/guava"]
path = integration-tests/guava
url = https://github.com/google/guava
[submodule "integration-tests/metrics"]
path = integration-tests/metrics
url = https://github.com/dropwizard/metrics
[submodule "integration-tests/druid"]
path = integration-tests/druid
url = https://github.com/apache/druid
[submodule "integration-tests/calcite"]
path = integration-tests/calcite
url = https://github.com/apache/calcite

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.13.1-SNAPSHOT</version>
<version>0.14.1-SNAPSHOT</version>
</parent>
<artifactId>documentation-support</artifactId>
@@ -83,10 +83,5 @@
<artifactId>junit-jupiter-params</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@@ -1,13 +0,0 @@
package tech.picnic.errorprone.documentation;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import org.jspecify.annotations.Nullable;
// XXX: Rename all this stuff.
@Data
@SuppressWarnings("EqualsMissingNullable") // XXX: Drop after EP upgrade.
final class LombokCanary {
@JsonProperty("custom_field_name")
private @Nullable String field;
}

View File

@@ -125,9 +125,6 @@ The following is a list of checks we'd like to see implemented:
statement. Idem for other exception types.
- A Guava-specific check that replaces simple anonymous `CacheLoader` subclass
declarations with `CacheLoader.from(someLambda)`.
- A Spring-specific check that enforces that methods with the `@Scheduled`
annotation are also annotated with New Relic's `@Trace` annotation. Such
methods should ideally not also represent Spring MVC endpoints.
- A Spring-specific check that enforces that `@RequestMapping` annotations,
when applied to a method, explicitly specify one or more target HTTP methods.
- A Spring-specific check that looks for classes in which all `@RequestMapping`

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.13.1-SNAPSHOT</version>
<version>0.14.1-SNAPSHOT</version>
</parent>
<artifactId>error-prone-contrib</artifactId>
@@ -81,11 +81,6 @@
<artifactId>guava</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.newrelic.agent.java</groupId>
<artifactId>newrelic-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
@@ -181,11 +176,6 @@
<artifactId>mongodb-driver-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.reactivestreams</groupId>
<artifactId>reactive-streams</artifactId>

View File

@@ -51,11 +51,6 @@ public final class CanonicalAnnotationSyntax extends BugChecker implements Annot
@Override
public Description matchAnnotation(AnnotationTree tree, VisitorState state) {
// if (!isSourceAccurateCodeAvailable(tree, state)) {
// /* Without the source code there's not much we can do. */
// return Description.NO_MATCH;
// }
return FIX_FACTORIES.stream()
.map(op -> op.apply(tree, state))
.flatMap(Optional::stream)
@@ -64,14 +59,6 @@ public final class CanonicalAnnotationSyntax extends BugChecker implements Annot
.orElse(Description.NO_MATCH);
}
// XXX: Explain, link to Lombok issue.
// private static boolean isSourceAccurateCodeAvailable(AnnotationTree tree, VisitorState state)
// {
// String source = state.getSourceForNode(tree);
// String parentSource = state.getSourceForNode(state.getPath().getParentPath().getLeaf());
// return source != null && parentSource != null && parentSource.contains(source);
// }
private static Optional<Fix> dropRedundantParentheses(AnnotationTree tree, VisitorState state) {
if (!tree.getArguments().isEmpty()) {
/* Parentheses are necessary. */
@@ -111,8 +98,8 @@ public final class CanonicalAnnotationSyntax extends BugChecker implements Annot
}
ExpressionTree expr = AnnotationMatcherUtils.getArgument(tree, "value");
if (expr == null || !SourceCode.isAccurateSourceLikelyAvailable(state)) {
/* This is (probably) not an explicit assignment to the `value` attribute. */
if (expr == null) {
/* This is not an explicit assignment to the `value` attribute. */
return Optional.empty();
}

View File

@@ -59,6 +59,7 @@ import tech.picnic.errorprone.bugpatterns.util.SourceCode;
public final class FormatStringConcatenation extends BugChecker
implements MethodInvocationTreeMatcher {
private static final long serialVersionUID = 1L;
/**
* AssertJ exposes varargs {@code fail} methods with a {@link Throwable}-accepting overload, the
* latter of which should not be flagged.
@@ -68,6 +69,7 @@ public final class FormatStringConcatenation extends BugChecker
.anyClass()
.withAnyName()
.withParameters(String.class.getName(), Throwable.class.getName());
// XXX: Drop some of these methods if we use Refaster to replace some with others.
private static final Matcher<ExpressionTree> ASSERTJ_FORMAT_METHOD =
anyOf(

View File

@@ -76,6 +76,7 @@ public final class LexicographicalAnnotationAttributeListing extends BugChecker
private static final String FLAG_PREFIX = "LexicographicalAnnotationAttributeListing:";
private static final String INCLUDED_ANNOTATIONS_FLAG = FLAG_PREFIX + "Includes";
private static final String EXCLUDED_ANNOTATIONS_FLAG = FLAG_PREFIX + "Excludes";
/**
* The splitter applied to string-typed annotation arguments prior to lexicographical sorting. By
* splitting on {@code =}, strings that represent e.g. inline Spring property declarations are
@@ -219,7 +220,10 @@ public final class LexicographicalAnnotationAttributeListing extends BugChecker
private static AnnotationAttributeMatcher createAnnotationAttributeMatcher(
ErrorProneFlags flags) {
return AnnotationAttributeMatcher.create(
flags.getList(INCLUDED_ANNOTATIONS_FLAG), excludedAnnotations(flags));
flags.get(INCLUDED_ANNOTATIONS_FLAG).isPresent()
? Optional.of(flags.getListOrEmpty(INCLUDED_ANNOTATIONS_FLAG))
: Optional.empty(),
excludedAnnotations(flags));
}
private static ImmutableList<String> excludedAnnotations(ErrorProneFlags flags) {

View File

@@ -46,6 +46,7 @@ import tech.picnic.errorprone.bugpatterns.util.SourceCode;
public final class LexicographicalAnnotationListing extends BugChecker
implements MethodTreeMatcher {
private static final long serialVersionUID = 1L;
/**
* A comparator that minimally reorders {@link AnnotationType}s, such that declaration annotations
* are placed before type annotations.

View File

@@ -1,94 +0,0 @@
package tech.picnic.errorprone.bugpatterns;
import static com.google.errorprone.BugPattern.LinkType.CUSTOM;
import static com.google.errorprone.BugPattern.SeverityLevel.ERROR;
import static com.google.errorprone.BugPattern.StandardTags.LIKELY_ERROR;
import static com.google.errorprone.matchers.ChildMultiMatcher.MatchType.AT_LEAST_ONE;
import static com.google.errorprone.matchers.Matchers.annotations;
import static com.google.errorprone.matchers.Matchers.hasAnnotation;
import static com.google.errorprone.matchers.Matchers.isType;
import static tech.picnic.errorprone.bugpatterns.util.Documentation.BUG_PATTERNS_BASE_URL;
import com.google.auto.common.AnnotationMirrors;
import com.google.auto.service.AutoService;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.errorprone.BugPattern;
import com.google.errorprone.VisitorState;
import com.google.errorprone.bugpatterns.BugChecker;
import com.google.errorprone.bugpatterns.BugChecker.MethodTreeMatcher;
import com.google.errorprone.fixes.SuggestedFix;
import com.google.errorprone.fixes.SuggestedFixes;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.matchers.Matcher;
import com.google.errorprone.matchers.MultiMatcher;
import com.google.errorprone.util.ASTHelpers;
import com.sun.source.tree.AnnotationTree;
import com.sun.source.tree.MethodTree;
import com.sun.source.tree.Tree;
import tech.picnic.errorprone.bugpatterns.util.ThirdPartyLibrary;
/**
* A {@link BugChecker} that flags methods with Spring's {@code @Scheduled} annotation that lack New
* Relic Agent's {@code @Trace(dispatcher = true)}.
*/
@AutoService(BugChecker.class)
@BugPattern(
summary = "Scheduled operation must start a new New Relic transaction",
link = BUG_PATTERNS_BASE_URL + "ScheduledTransactionTrace",
linkType = CUSTOM,
severity = ERROR,
tags = LIKELY_ERROR)
public final class ScheduledTransactionTrace extends BugChecker implements MethodTreeMatcher {
private static final long serialVersionUID = 1L;
private static final String TRACE_ANNOTATION_FQCN = "com.newrelic.api.agent.Trace";
private static final Matcher<Tree> IS_SCHEDULED =
hasAnnotation("org.springframework.scheduling.annotation.Scheduled");
private static final MultiMatcher<Tree, AnnotationTree> TRACE_ANNOTATION =
annotations(AT_LEAST_ONE, isType(TRACE_ANNOTATION_FQCN));
/** Instantiates a new {@link ScheduledTransactionTrace} instance. */
public ScheduledTransactionTrace() {}
@Override
public Description matchMethod(MethodTree tree, VisitorState state) {
if (!ThirdPartyLibrary.NEW_RELIC_AGENT_API.isIntroductionAllowed(state)
|| !IS_SCHEDULED.matches(tree, state)) {
return Description.NO_MATCH;
}
ImmutableList<AnnotationTree> traceAnnotations =
TRACE_ANNOTATION.multiMatchResult(tree, state).matchingNodes();
if (traceAnnotations.isEmpty()) {
/* This method completely lacks the `@Trace` annotation; add it. */
return describeMatch(
tree,
SuggestedFix.builder()
.addImport(TRACE_ANNOTATION_FQCN)
.prefixWith(tree, "@Trace(dispatcher = true)")
.build());
}
AnnotationTree traceAnnotation = Iterables.getOnlyElement(traceAnnotations);
if (isCorrectAnnotation(traceAnnotation)) {
return Description.NO_MATCH;
}
/*
* The `@Trace` annotation is present but does not specify `dispatcher = true`. Add or update
* the `dispatcher` annotation element.
*/
return describeMatch(
traceAnnotation,
SuggestedFixes.updateAnnotationArgumentValues(
traceAnnotation, state, "dispatcher", ImmutableList.of("true"))
.build());
}
private static boolean isCorrectAnnotation(AnnotationTree traceAnnotation) {
return Boolean.TRUE.equals(
AnnotationMirrors.getAnnotationValue(
ASTHelpers.getAnnotationMirror(traceAnnotation), "dispatcher")
.getValue());
}
}

View File

@@ -1,84 +0,0 @@
package tech.picnic.errorprone.bugpatterns;
import static com.google.common.base.Verify.verify;
import static com.google.errorprone.BugPattern.LinkType.CUSTOM;
import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION;
import static java.util.stream.Collectors.joining;
import static tech.picnic.errorprone.bugpatterns.util.Documentation.BUG_PATTERNS_BASE_URL;
import com.google.auto.service.AutoService;
import com.google.common.collect.ImmutableSet;
import com.google.errorprone.BugPattern;
import com.google.errorprone.VisitorState;
import com.google.errorprone.bugpatterns.BugChecker;
import com.google.errorprone.bugpatterns.BugChecker.CompilationUnitTreeMatcher;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.util.ASTHelpers;
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.Tree;
import com.sun.source.util.TreePath;
import com.sun.source.util.TreeScanner;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.LinkedHashSet;
import java.util.Set;
import org.jspecify.annotations.Nullable;
import tech.picnic.errorprone.bugpatterns.util.SourceCode;
/** A {@link BugChecker} that files for which no accurate source code appears to be available. */
@AutoService(BugChecker.class)
@BugPattern(
summary = "This type's source code is unavailable or inaccurate",
link = BUG_PATTERNS_BASE_URL + "SourceCodeAvailability",
linkType = CUSTOM,
severity = SUGGESTION)
public final class SourceCodeAvailability extends BugChecker implements CompilationUnitTreeMatcher {
private static final long serialVersionUID = 1L;
/** Instantiates a new {@link SourceCodeAvailability} instance. */
public SourceCodeAvailability() {}
@Override
public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState state) {
Deque<Boolean> seenAccurateSource = new ArrayDeque<>();
Set<Tree> maximalAccurateSubtrees = new LinkedHashSet<>();
new TreeScanner<@Nullable Void, TreePath>() {
@Override
public @Nullable Void scan(Tree node, TreePath treePath) {
if (node == null) {
return null;
}
TreePath path = new TreePath(treePath, node);
boolean isAccurate = SourceCode.isAccurateSourceLikelyAvailable(state.withPath(path));
if (!isAccurate) {
verify(!Boolean.TRUE.equals(seenAccurateSource.peek()));
} else if (!Boolean.TRUE.equals(seenAccurateSource.peek())) {
maximalAccurateSubtrees.add(node);
}
seenAccurateSource.push(isAccurate);
try {
return super.scan(node, path);
} finally {
seenAccurateSource.pop();
}
}
}.scan(tree, state.getPath());
if (maximalAccurateSubtrees.equals(ImmutableSet.of(tree))) {
return Description.NO_MATCH;
}
String accurateSubtrees =
maximalAccurateSubtrees.stream()
.map(
t ->
String.format(
"%s tree at position %s:\n%s",
t.getKind(), ASTHelpers.getStartPosition(t), state.getSourceForNode(t)))
.collect(joining("\n\n", "Maximally accurate subtrees found:\n\n", ""));
return buildDescription(tree).setMessage(accurateSubtrees).build();
}
}

View File

@@ -155,6 +155,7 @@ public final class StaticImport extends BugChecker implements MemberSelectTreeMa
@VisibleForTesting
static final ImmutableSetMultimap<String, String> STATIC_IMPORT_EXEMPTED_MEMBERS =
ImmutableSetMultimap.<String, String>builder()
.put("com.google.common.base.Predicates", "contains")
.put("com.mongodb.client.model.Filters", "empty")
.putAll(
"java.util.Collections",

View File

@@ -16,10 +16,7 @@ public final class Flags {
* provided, or if the flag's value is the empty string.
*/
public static ImmutableList<String> getList(ErrorProneFlags errorProneFlags, String name) {
return errorProneFlags
.getList(name)
.map(ImmutableList::copyOf)
.filter(flags -> !flags.equals(ImmutableList.of("")))
.orElseGet(ImmutableList::of);
ImmutableList<String> list = errorProneFlags.getListOrEmpty(name);
return list.equals(ImmutableList.of("")) ? ImmutableList.of() : list;
}
}

View File

@@ -17,6 +17,7 @@ public final class JavaKeywords {
*/
private static final ImmutableSet<String> BOOLEAN_AND_NULL_LITERALS =
ImmutableSet.of("true", "false", "null");
/**
* List of all reserved keywords in the Java language.
*
@@ -76,6 +77,7 @@ public final class JavaKeywords {
"void",
"volatile",
"while");
/**
* List of all contextual keywords in the Java language.
*
@@ -100,6 +102,7 @@ public final class JavaKeywords {
"var",
"with",
"yield");
/** List of all keywords in the Java language. */
private static final ImmutableSet<String> ALL_KEYWORDS =
Sets.union(RESERVED_KEYWORDS, CONTEXTUAL_KEYWORDS).immutableCopy();

View File

@@ -18,6 +18,7 @@ import java.util.regex.Pattern;
public final class MethodMatcherFactory {
private static final Splitter ARGUMENT_TYPE_SPLITTER =
Splitter.on(',').trimResults().omitEmptyStrings();
// XXX: Check whether we can use a parser for "standard" Java signatures here. Maybe
// `sun.reflect.generics.parser.SignatureParser`?
@SuppressWarnings("java:S5998" /* In practice there will be only modest recursion. */)

View File

@@ -34,6 +34,7 @@ public final class MoreJUnitMatchers {
anyOf(
isType("org.junit.jupiter.api.Test"),
hasMetaAnnotation("org.junit.jupiter.api.TestTemplate")));
/** Matches JUnit Jupiter setup and teardown methods. */
public static final MultiMatcher<MethodTree, AnnotationTree> SETUP_OR_TEARDOWN_METHOD =
annotations(
@@ -43,6 +44,7 @@ public final class MoreJUnitMatchers {
isType("org.junit.jupiter.api.AfterEach"),
isType("org.junit.jupiter.api.BeforeAll"),
isType("org.junit.jupiter.api.BeforeEach")));
/**
* Matches methods that have a {@link org.junit.jupiter.params.provider.MethodSource} annotation.
*/

View File

@@ -1,40 +1,22 @@
package tech.picnic.errorprone.bugpatterns.util;
import static com.sun.source.tree.Tree.Kind.*;
import static com.sun.tools.javac.parser.Tokens.TokenKind.RPAREN;
import static com.sun.tools.javac.util.Position.NOPOS;
import static java.util.stream.Collectors.joining;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.CharMatcher;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Range;
import com.google.common.collect.Sets;
import com.google.common.collect.Streams;
import com.google.errorprone.VisitorState;
import com.google.errorprone.fixes.SuggestedFix;
import com.google.errorprone.util.ASTHelpers;
import com.google.errorprone.util.ErrorProneToken;
import com.google.errorprone.util.ErrorProneTokens;
import com.sun.source.tree.AnnotationTree;
import com.sun.source.tree.AssignmentTree;
import com.sun.source.tree.ExpressionStatementTree;
import com.sun.source.tree.IdentifierTree;
import com.sun.source.tree.MethodInvocationTree;
import com.sun.source.tree.MethodTree;
import com.sun.source.tree.ModifiersTree;
import com.sun.source.tree.Tree;
import com.sun.source.util.TreePath;
import com.sun.source.util.TreeScanner;
import com.sun.tools.javac.code.Kinds;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.Position;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Stream;
import org.jspecify.annotations.Nullable;
/**
* A collection of Error Prone utility methods for dealing with the source code representation of
@@ -44,136 +26,8 @@ public final class SourceCode {
/** The complement of {@link CharMatcher#whitespace()}. */
private static final CharMatcher NON_WHITESPACE_MATCHER = CharMatcher.whitespace().negate();
// XXX: Document.
// XXX: Once we raise the baseline to JDK 17+, review whether `BINDING_PATTERN` and
// `GUARDED_PATTERN` should be added.
// XXX: Review which JDK >17 tree kinds should be added.
private static final ImmutableSet<Tree.Kind> TREE_KINDS_WITHOUT_EXPLICIT_SYNTAX =
Sets.immutableEnumSet(COMPILATION_UNIT, MODIFIERS, ERRONEOUS, OTHER);
private SourceCode() {}
// XXX: Document that that the test is relative to the state's current path.
public static boolean isAccurateSourceLikelyAvailable(VisitorState state) {
return new IsAccurateSourceLikelyAvailable().test(state);
}
// XXX: Move this class down or to a separate file.
// XXX: Cache data in `VisitorState.config`.
private static final class IsAccurateSourceLikelyAvailable
extends TreeScanner<@Nullable Boolean, VisitorState> implements Predicate<VisitorState> {
@Override
public boolean test(VisitorState state) {
return isValidAncestorSourceContainment(state) && isValidDescendantSourceContainment(state);
}
@Override
public @Nullable Boolean scan(@Nullable Tree tree, VisitorState parentState) {
if (tree == null) {
return Boolean.TRUE;
}
VisitorState childState = parentState.withPath(new TreePath(parentState.getPath(), tree));
return isValidSourceContainment(childState) ? super.scan(tree, childState) : Boolean.FALSE;
}
@Override
public @Nullable Boolean reduce(@Nullable Boolean a, @Nullable Boolean b) {
return !(Boolean.FALSE.equals(a) || Boolean.FALSE.equals(b));
}
private boolean isValidDescendantSourceContainment(VisitorState state) {
return !Boolean.FALSE.equals(super.scan(state.getPath().getLeaf(), state));
}
private static boolean isValidAncestorSourceContainment(VisitorState state) {
return Stream.iterate(state.getPath(), Objects::nonNull, TreePath::getParentPath)
.allMatch(path -> isValidSourceContainment(state.withPath(path)));
}
private static boolean isValidSourceContainment(VisitorState state) {
Tree tree = state.getPath().getLeaf();
TreePath parentPath = state.getPath().getParentPath();
if (parentPath == null) {
return getSourceRange(tree, state) != null;
}
Tree enclosingTree = parentPath.getLeaf();
@Nullable Range<Integer> enclosingSourceRange = getSourceRange(enclosingTree, state);
@Nullable Range<Integer> sourceRange = getSourceRange(tree, state);
if (enclosingSourceRange == null) {
return sourceRange == null || mayBeImplicit(enclosingTree, state);
// XXX: Test code; drop.
// return sourceRange == null && mayBeImplicit(enclosingTree, state);
// (sourceRange == null || mayBeImplicit(enclosingTree, state)) != (sourceRange ==
// null && mayBeImplicit(enclosingTree, state))
}
if (sourceRange == null) {
return mayBeImplicit(tree, state);
}
return enclosingSourceRange.encloses(sourceRange)
&& (TREE_KINDS_WITHOUT_EXPLICIT_SYNTAX.contains(enclosingTree.getKind())
|| !enclosingSourceRange.equals(sourceRange));
}
private static boolean mayBeImplicit(Tree tree, VisitorState state) {
if (tree instanceof ModifiersTree) {
ModifiersTree modifiers = (ModifiersTree) tree;
return modifiers.getAnnotations().isEmpty() && modifiers.getFlags().isEmpty();
}
// XXX: We could even *require* the generated constructor subtree to not have any associated
// source.
if (ASTHelpers.isGeneratedConstructor(state.findEnclosing(MethodTree.class))) {
return true;
}
AnnotationTree annotation = state.findEnclosing(AnnotationTree.class);
if (annotation != null && annotation.getArguments().size() == 1) {
// XXX: The `IdentifierTree` check here has no impact because its parent will in practice be
// `null`, which prevents `mayBeImplicit` being called review how we can be stricter.
Symbol symbol =
tree instanceof AssignmentTree
? ASTHelpers.getSymbol(((AssignmentTree) tree).getVariable())
: tree instanceof IdentifierTree ? ASTHelpers.getSymbol(tree) : null;
/* The `value` attribute may be omitted from single-argument annotation declarations. */
return symbol != null
&& symbol.kind == Kinds.Kind.MTH
&& symbol.name.contentEquals("value");
}
// XXX: Many branches aren't covered yet.
return isSuperInvocation(tree)
|| (tree instanceof IdentifierTree
&& isSuperInvocation(state.getPath().getParentPath().getLeaf()));
}
private static boolean isSuperInvocation(Tree tree) {
if (tree instanceof ExpressionStatementTree) {
return isSuperInvocation(((ExpressionStatementTree) tree).getExpression());
}
if (!(tree instanceof MethodInvocationTree)) {
return false;
}
MethodInvocationTree invocation = (MethodInvocationTree) tree;
return invocation.getArguments().isEmpty()
&& ASTHelpers.isSuper(invocation.getMethodSelect());
}
private static @Nullable Range<Integer> getSourceRange(Tree tree, VisitorState state) {
int startPosition = ASTHelpers.getStartPosition(tree);
int endPosition = state.getEndPosition(tree);
return startPosition == Position.NOPOS || endPosition == Position.NOPOS
? null
: Range.closedOpen(startPosition, endPosition);
}
}
/**
* Returns a string representation of the given {@link Tree}, preferring the original source code
* (if available) over its prettified representation.
@@ -204,7 +58,7 @@ public final class SourceCode {
public static SuggestedFix deleteWithTrailingWhitespace(Tree tree, VisitorState state) {
CharSequence sourceCode = state.getSourceCode();
int endPos = state.getEndPosition(tree);
if (sourceCode == null || endPos == Position.NOPOS) {
if (sourceCode == null || endPos == NOPOS) {
/* We can't identify the trailing whitespace; delete just the tree. */
return SuggestedFix.delete(tree);
}

View File

@@ -32,13 +32,6 @@ public enum ThirdPartyLibrary {
* @see <a href="https://github.com/google/guava">Guava on GitHub</a>
*/
GUAVA("com.google.common.collect.ImmutableList"),
/**
* New Relic's Java agent API.
*
* @see <a href="https://github.com/newrelic/newrelic-java-agent/tree/main/newrelic-api">New Relic
* Java agent API on GitHub</a>
*/
NEW_RELIC_AGENT_API("com.newrelic.api.agent.Agent"),
/**
* VMWare's Project Reactor.
*

View File

@@ -103,8 +103,7 @@ final class AssortedRules {
}
@AfterTemplate
@Nullable
T after(Iterator<T> iterator, T defaultValue) {
@Nullable T after(Iterator<T> iterator, T defaultValue) {
return Iterators.getNext(iterator, defaultValue);
}
}

View File

@@ -0,0 +1,65 @@
package tech.picnic.errorprone.refasterrules;
import com.google.errorprone.refaster.Refaster;
import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import java.util.function.Predicate;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to expressions dealing with classes. */
@OnlineDocumentation
final class ClassRules {
private ClassRules() {}
/** Prefer {@link Class#isInstance(Object)} over more contrived alternatives. */
static final class ClassIsInstance<T, S> {
@BeforeTemplate
boolean before(Class<T> clazz, S object) {
return clazz.isAssignableFrom(object.getClass());
}
@AfterTemplate
boolean after(Class<T> clazz, S object) {
return clazz.isInstance(object);
}
}
/** Prefer using the {@code instanceof} keyword over less idiomatic alternatives. */
static final class Instanceof<T, S> {
@BeforeTemplate
boolean before(S object) {
return Refaster.<T>clazz().isInstance(object);
}
@AfterTemplate
boolean after(S object) {
return Refaster.<T>isInstance(object);
}
}
/** Prefer {@link Class#isInstance(Object)} method references over more verbose alternatives. */
static final class ClassLiteralIsInstancePredicate<T, S> {
@BeforeTemplate
Predicate<S> before() {
return o -> Refaster.<T>isInstance(o);
}
@AfterTemplate
Predicate<S> after() {
return Refaster.<T>clazz()::isInstance;
}
}
/** Prefer {@link Class#isInstance(Object)} method references over more verbose alternatives. */
static final class ClassReferenceIsInstancePredicate<T, S> {
@BeforeTemplate
Predicate<S> before(Class<T> clazz) {
return o -> clazz.isInstance(o);
}
@AfterTemplate
Predicate<S> after(Class<T> clazz) {
return clazz::isInstance;
}
}
}

View File

@@ -33,14 +33,12 @@ final class MapRules {
static final class MapGetOrNull<K, V, T> {
@BeforeTemplate
@Nullable
V before(Map<K, V> map, T key) {
@Nullable V before(Map<K, V> map, T key) {
return map.getOrDefault(key, null);
}
@AfterTemplate
@Nullable
V after(Map<K, V> map, T key) {
@Nullable V after(Map<K, V> map, T key) {
return map.get(key);
}
}

View File

@@ -5,10 +5,12 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import com.google.errorprone.refaster.Refaster;
import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import com.google.errorprone.refaster.annotation.UseImportPolicy;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.verification.VerificationMode;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
@@ -50,4 +52,30 @@ final class MockitoRules {
return verify(mock);
}
}
static final class InvocationOnMockGetArguments {
@BeforeTemplate
Object before(InvocationOnMock invocation, int i) {
return invocation.getArguments()[i];
}
@AfterTemplate
Object after(InvocationOnMock invocation, int i) {
return invocation.getArgument(i);
}
}
static final class InvocationOnMockGetArgumentsWithTypeParameter<T> {
@BeforeTemplate
@SuppressWarnings("unchecked")
T before(InvocationOnMock invocation, int i) {
return Refaster.anyOf(
invocation.getArgument(i, Refaster.<T>clazz()), (T) invocation.getArgument(i));
}
@AfterTemplate
T after(InvocationOnMock invocation, int i) {
return invocation.<T>getArgument(i);
}
}
}

View File

@@ -50,8 +50,7 @@ final class MultimapRules {
*/
static final class MultimapGet<K, V> {
@BeforeTemplate
@Nullable
Collection<V> before(Multimap<K, V> multimap, K key) {
@Nullable Collection<V> before(Multimap<K, V> multimap, K key) {
return Refaster.anyOf(multimap.asMap(), Multimaps.asMap(multimap)).get(key);
}

View File

@@ -0,0 +1,46 @@
package tech.picnic.errorprone.refasterrules;
import static com.google.common.base.Predicates.containsPattern;
import com.google.common.base.Predicates;
import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to code dealing with regular expressions. */
@OnlineDocumentation
final class PatternRules {
private PatternRules() {}
/** Prefer {@link Pattern#asPredicate()} over non-JDK alternatives. */
// XXX: This rule could also replace `s -> pattern.matcher(s).find()`, though the lambda
// expression may match functional interfaces other than `Predicate`. If we do add such a rule, we
// should also add a rule that replaces `s -> pattern.matcher(s).matches()` with
// `pattern.asMatchPredicate()`.
static final class PatternAsPredicate {
@BeforeTemplate
Predicate<CharSequence> before(Pattern pattern) {
return Predicates.contains(pattern);
}
@AfterTemplate
Predicate<String> after(Pattern pattern) {
return pattern.asPredicate();
}
}
/** Prefer {@link Pattern#asPredicate()} over non-JDK alternatives. */
static final class PatternCompileAsPredicate {
@BeforeTemplate
Predicate<CharSequence> before(String pattern) {
return containsPattern(pattern);
}
@AfterTemplate
Predicate<String> after(String pattern) {
return Pattern.compile(pattern).asPredicate();
}
}
}

View File

@@ -247,11 +247,43 @@ final class ReactorRules {
}
}
/** Prefer {@link Flux#zipWithIterable(Iterable)} over more contrived alternatives. */
static final class FluxZipWithIterable<T, S> {
@BeforeTemplate
Flux<Tuple2<T, S>> before(Flux<T> flux, Iterable<S> iterable) {
return Flux.zip(flux, Flux.fromIterable(iterable));
}
@AfterTemplate
Flux<Tuple2<T, S>> after(Flux<T> flux, Iterable<S> iterable) {
return flux.zipWithIterable(iterable);
}
}
/** Prefer {@link Flux#zipWithIterable(Iterable, BiFunction)} over more contrived alternatives. */
static final class FluxZipWithIterableBiFunction<T, S, R> {
@BeforeTemplate
Flux<R> before(
Flux<T> flux,
Iterable<S> iterable,
BiFunction<? super T, ? super S, ? extends R> function) {
return flux.zipWith(Flux.fromIterable(iterable), function);
}
@AfterTemplate
Flux<R> after(
Flux<T> flux,
Iterable<S> iterable,
BiFunction<? super T, ? super S, ? extends R> function) {
return flux.zipWithIterable(iterable, function);
}
}
/**
* Prefer {@link Flux#zipWithIterable(Iterable)} with a chained combinator over {@link
* Flux#zipWithIterable(Iterable, BiFunction)}, as the former generally yields more readable code.
*/
static final class FluxZipWithIterable<T, S, R> {
static final class FluxZipWithIterableMapFunction<T, S, R> {
@BeforeTemplate
Flux<R> before(Flux<T> flux, Iterable<S> iterable, BiFunction<T, S, R> combinator) {
return flux.zipWithIterable(iterable, combinator);
@@ -328,7 +360,10 @@ final class ReactorRules {
static final class MonoThenReturn<T, S> {
@BeforeTemplate
Mono<S> before(Mono<T> mono, S object) {
return mono.then(Mono.just(object));
return Refaster.anyOf(
mono.ignoreElement().thenReturn(object),
mono.then().thenReturn(object),
mono.then(Mono.just(object)));
}
@AfterTemplate
@@ -391,6 +426,74 @@ final class ReactorRules {
}
}
/** Prefer {@link Flux#empty()} over more contrived alternatives. */
// XXX: In combination with the `IsEmpty` matcher introduced by
// https://github.com/PicnicSupermarket/error-prone-support/pull/744, the non-varargs overloads of
// most methods referenced here can be rewritten as well. Additionally, some invocations of
// methods such as `Flux#fromIterable`, `Flux#fromArray` and `Flux#justOrEmpty` can also be
// rewritten.
static final class FluxEmpty<T, S extends Comparable<? super S>> {
@BeforeTemplate
Flux<T> before(
int prefetch,
Function<? super Object[], ? extends T> combinator,
Comparator<? super T> comparator) {
return Refaster.anyOf(
Flux.concat(),
Flux.concatDelayError(),
Flux.firstWithSignal(),
Flux.just(),
Flux.merge(),
Flux.merge(prefetch),
Flux.mergeComparing(comparator),
Flux.mergeComparing(prefetch, comparator),
Flux.mergeComparingDelayError(prefetch, comparator),
Flux.mergeDelayError(prefetch),
Flux.mergePriority(comparator),
Flux.mergePriority(prefetch, comparator),
Flux.mergePriorityDelayError(prefetch, comparator),
Flux.mergeSequential(),
Flux.mergeSequential(prefetch),
Flux.mergeSequentialDelayError(prefetch),
Flux.zip(combinator),
Flux.zip(combinator, prefetch));
}
@BeforeTemplate
Flux<T> before(int prefetch, Function<Object[], T> combinator) {
return Refaster.anyOf(
Flux.combineLatest(combinator), Flux.combineLatest(combinator, prefetch));
}
@BeforeTemplate
Flux<S> before() {
return Refaster.anyOf(Flux.mergeComparing(), Flux.mergePriority());
}
@BeforeTemplate
Flux<Integer> before(int start) {
return Flux.range(start, 0);
}
@AfterTemplate
Flux<T> after() {
return Flux.empty();
}
}
/** Prefer {@link Flux#just(Object)} over more contrived alternatives. */
static final class FluxJust {
@BeforeTemplate
Flux<Integer> before(int start) {
return Flux.range(start, 1);
}
@AfterTemplate
Flux<Integer> after(int start) {
return Flux.just(start);
}
}
/** Don't unnecessarily transform a {@link Mono} to an equivalent instance. */
static final class MonoIdentity<T> {
@BeforeTemplate
@@ -401,7 +504,7 @@ final class ReactorRules {
@BeforeTemplate
Mono<@Nullable Void> before2(Mono<@Nullable Void> mono) {
return mono.then();
return Refaster.anyOf(mono.ignoreElement(), mono.then());
}
// XXX: Replace this rule with an extension of the `IdentityConversion` rule, supporting
@@ -485,14 +588,46 @@ final class ReactorRules {
}
}
/** Avoid contrived alternatives to {@link Mono#flatMapIterable(Function)}. */
static final class MonoFlatMapIterable<T, S> {
@BeforeTemplate
Flux<S> before(Mono<T> mono, Function<? super T, ? extends Iterable<? extends S>> function) {
return Refaster.anyOf(
mono.map(function).flatMapIterable(identity()), mono.flux().concatMapIterable(function));
}
@AfterTemplate
Flux<S> after(Mono<T> mono, Function<? super T, ? extends Iterable<? extends S>> function) {
return mono.flatMapIterable(function);
}
}
/**
* Prefer {@link Flux#concatMapIterable(Function)} over {@link Flux#flatMapIterable(Function)}, as
* the former has equivalent semantics but a clearer name.
* Prefer {@link Mono#flatMapIterable(Function)} to flatten a {@link Mono} of some {@link
* Iterable} over less efficient alternatives.
*/
static final class MonoFlatMapIterableIdentity<T, S extends Iterable<T>> {
@BeforeTemplate
Flux<T> before(Mono<S> mono) {
return mono.flatMapMany(Flux::fromIterable);
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
Flux<T> after(Mono<S> mono) {
return mono.flatMapIterable(identity());
}
}
/**
* Prefer {@link Flux#concatMapIterable(Function)} over alternatives with less clear syntax or
* semantics.
*/
static final class FluxConcatMapIterable<T, S> {
@BeforeTemplate
Flux<S> before(Flux<T> flux, Function<? super T, ? extends Iterable<? extends S>> function) {
return flux.flatMapIterable(function);
return Refaster.anyOf(
flux.flatMapIterable(function), flux.map(function).concatMapIterable(identity()));
}
@AfterTemplate
@@ -502,14 +637,16 @@ final class ReactorRules {
}
/**
* Prefer {@link Flux#concatMapIterable(Function, int)} over {@link Flux#flatMapIterable(Function,
* int)}, as the former has equivalent semantics but a clearer name.
* Prefer {@link Flux#concatMapIterable(Function, int)} over alternatives with less clear syntax
* or semantics.
*/
static final class FluxConcatMapIterableWithPrefetch<T, S> {
@BeforeTemplate
Flux<S> before(
Flux<T> flux, Function<? super T, ? extends Iterable<? extends S>> function, int prefetch) {
return flux.flatMapIterable(function, prefetch);
return Refaster.anyOf(
flux.flatMapIterable(function, prefetch),
flux.map(function).concatMapIterable(identity(), prefetch));
}
@AfterTemplate
@@ -741,7 +878,7 @@ final class ReactorRules {
static final class MonoThen<T> {
@BeforeTemplate
Mono<@Nullable Void> before(Mono<T> mono) {
return mono.flux().then();
return Refaster.anyOf(mono.ignoreElement().then(), mono.flux().then());
}
@AfterTemplate
@@ -750,6 +887,128 @@ final class ReactorRules {
}
}
/** Avoid vacuous invocations of {@link Flux#ignoreElements()}. */
static final class FluxThen<T> {
@BeforeTemplate
Mono<@Nullable Void> before(Flux<T> flux) {
return flux.ignoreElements().then();
}
@BeforeTemplate
Mono<@Nullable Void> before2(Flux<@Nullable Void> flux) {
return flux.ignoreElements();
}
@AfterTemplate
Mono<@Nullable Void> after(Flux<T> flux) {
return flux.then();
}
}
/** Avoid vacuous invocations of {@link Mono#ignoreElement()}. */
static final class MonoThenEmpty<T> {
@BeforeTemplate
Mono<@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) {
return mono.thenEmpty(publisher);
}
}
/** Avoid vacuous invocations of {@link Flux#ignoreElements()}. */
static final class FluxThenEmpty<T> {
@BeforeTemplate
Mono<@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) {
return flux.thenEmpty(publisher);
}
}
/** Avoid vacuous invocations of {@link Mono#ignoreElement()}. */
static final class MonoThenMany<T, S> {
@BeforeTemplate
Flux<S> before(Mono<T> mono, Publisher<S> publisher) {
return mono.ignoreElement().thenMany(publisher);
}
@AfterTemplate
Flux<S> after(Mono<T> mono, Publisher<S> publisher) {
return mono.thenMany(publisher);
}
}
/**
* Prefer explicit invocation of {@link Mono#flux()} over implicit conversions from {@link Mono}
* to {@link Flux}.
*/
static final class MonoThenMonoFlux<T, S> {
@BeforeTemplate
Flux<S> before(Mono<T> mono1, Mono<S> mono2) {
return mono1.thenMany(mono2);
}
@AfterTemplate
Flux<S> after(Mono<T> mono1, Mono<S> mono2) {
return mono1.then(mono2).flux();
}
}
/** Avoid vacuous invocations of {@link Flux#ignoreElements()}. */
static final class FluxThenMany<T, S> {
@BeforeTemplate
Flux<S> before(Flux<T> flux, Publisher<S> publisher) {
return flux.ignoreElements().thenMany(publisher);
}
@AfterTemplate
Flux<S> after(Flux<T> flux, Publisher<S> publisher) {
return flux.thenMany(publisher);
}
}
/** Avoid vacuous invocations of {@link Mono#ignoreElement()}. */
static final class MonoThenMono<T, S> {
@BeforeTemplate
Mono<S> before(Mono<T> mono1, Mono<S> mono2) {
return mono1.ignoreElement().then(mono2);
}
@BeforeTemplate
Mono<@Nullable Void> before2(Mono<T> mono1, Mono<@Nullable Void> mono2) {
return mono1.thenEmpty(mono2);
}
@AfterTemplate
Mono<S> after(Mono<T> mono1, Mono<S> mono2) {
return mono1.then(mono2);
}
}
/** Avoid vacuous invocations of {@link Flux#ignoreElements()}. */
static final class FluxThenMono<T, S> {
@BeforeTemplate
Mono<S> before(Flux<T> flux, Mono<S> mono) {
return flux.ignoreElements().then(mono);
}
@BeforeTemplate
Mono<@Nullable Void> before2(Flux<T> flux, Mono<@Nullable Void> mono) {
return flux.thenEmpty(mono);
}
@AfterTemplate
Mono<S> after(Flux<T> flux, Mono<S> mono) {
return flux.then(mono);
}
}
/** Prefer {@link Mono#singleOptional()} over more contrived alternatives. */
// XXX: Consider creating a plugin that flags/discourages `Mono<Optional<T>>` method return
// types, just as we discourage nullable `Boolean`s and `Optional`s.
@@ -794,6 +1053,32 @@ final class ReactorRules {
}
}
/** Prefer {@link Mono#ofType(Class)} over more contrived alternatives. */
static final class MonoOfType<T, S> {
@BeforeTemplate
Mono<S> before(Mono<T> mono, Class<S> clazz) {
return mono.filter(clazz::isInstance).cast(clazz);
}
@AfterTemplate
Mono<S> after(Mono<T> mono, Class<S> clazz) {
return mono.ofType(clazz);
}
}
/** Prefer {@link Flux#ofType(Class)} over more contrived alternatives. */
static final class FluxOfType<T, S> {
@BeforeTemplate
Flux<S> before(Flux<T> flux, Class<S> clazz) {
return flux.filter(clazz::isInstance).cast(clazz);
}
@AfterTemplate
Flux<S> after(Flux<T> flux, Class<S> clazz) {
return flux.ofType(clazz);
}
}
/** Prefer {@link Mono#flatMap(Function)} over more contrived alternatives. */
static final class MonoFlatMap<S, T> {
@BeforeTemplate
@@ -812,8 +1097,30 @@ final class ReactorRules {
static final class MonoFlatMapMany<S, T> {
@BeforeTemplate
@SuppressWarnings("NestedPublishers")
Flux<T> before(Mono<S> mono, Function<? super S, ? extends Publisher<? extends T>> function) {
return mono.map(function).flatMapMany(identity());
Flux<T> before(
Mono<S> mono,
Function<? super S, ? extends Publisher<? extends T>> function,
boolean delayUntilEnd,
int maxConcurrency,
int prefetch) {
return Refaster.anyOf(
mono.map(function).flatMapMany(identity()),
mono.flux().concatMap(function),
mono.flux().concatMap(function, prefetch),
mono.flux().concatMapDelayError(function),
mono.flux().concatMapDelayError(function, prefetch),
mono.flux().concatMapDelayError(function, delayUntilEnd, prefetch),
mono.flux().flatMap(function, maxConcurrency),
mono.flux().flatMap(function, maxConcurrency, prefetch),
mono.flux().flatMapDelayError(function, maxConcurrency, prefetch),
mono.flux().flatMapSequential(function, maxConcurrency),
mono.flux().flatMapSequential(function, maxConcurrency, prefetch),
mono.flux().flatMapSequentialDelayError(function, maxConcurrency, prefetch));
}
@BeforeTemplate
Flux<T> before(Mono<S> mono, Function<? super S, Publisher<? extends T>> function) {
return mono.flux().switchMap(function);
}
@AfterTemplate
@@ -1381,6 +1688,7 @@ final class ReactorRules {
Duration before(StepVerifier.LastStep step, Class<T> clazz) {
return Refaster.anyOf(
step.expectError(clazz).verify(),
step.verifyErrorMatches(clazz::isInstance),
step.verifyErrorSatisfies(t -> assertThat(t).isInstanceOf(clazz)));
}

View File

@@ -20,6 +20,7 @@ import static java.util.stream.Collectors.summingDouble;
import static java.util.stream.Collectors.summingInt;
import static java.util.stream.Collectors.summingLong;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Streams;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.refaster.Refaster;
@@ -668,4 +669,74 @@ final class StreamRules {
return Stream.iterate(seed, hasNext, next);
}
}
/** Prefer {@link Stream#of(Object)} over more contrived alternatives. */
// XXX: Generalize this and similar rules using an Error Prone check.
static final class StreamOf1<T> {
@BeforeTemplate
Stream<T> before(T e1) {
return ImmutableList.of(e1).stream();
}
@AfterTemplate
Stream<T> after(T e1) {
return Stream.of(e1);
}
}
/** Prefer {@link Stream#of(Object[])} over more contrived alternatives. */
// XXX: Generalize this and similar rules using an Error Prone check.
static final class StreamOf2<T> {
@BeforeTemplate
Stream<T> before(T e1, T e2) {
return ImmutableList.of(e1, e2).stream();
}
@AfterTemplate
Stream<T> after(T e1, T e2) {
return Stream.of(e1, e2);
}
}
/** Prefer {@link Stream#of(Object[])} over more contrived alternatives. */
// XXX: Generalize this and similar rules using an Error Prone check.
static final class StreamOf3<T> {
@BeforeTemplate
Stream<T> before(T e1, T e2, T e3) {
return ImmutableList.of(e1, e2, e3).stream();
}
@AfterTemplate
Stream<T> after(T e1, T e2, T e3) {
return Stream.of(e1, e2, e3);
}
}
/** Prefer {@link Stream#of(Object[])} over more contrived alternatives. */
// XXX: Generalize this and similar rules using an Error Prone check.
static final class StreamOf4<T> {
@BeforeTemplate
Stream<T> before(T e1, T e2, T e3, T e4) {
return ImmutableList.of(e1, e2, e3, e4).stream();
}
@AfterTemplate
Stream<T> after(T e1, T e2, T e3, T e4) {
return Stream.of(e1, e2, e3, e4);
}
}
/** Prefer {@link Stream#of(Object[])} over more contrived alternatives. */
// XXX: Generalize this and similar rules using an Error Prone check.
static final class StreamOf5<T> {
@BeforeTemplate
Stream<T> before(T e1, T e2, T e3, T e4, T e5) {
return ImmutableList.of(e1, e2, e3, e4, e5).stream();
}
@AfterTemplate
Stream<T> after(T e1, T e2, T e3, T e4, T e5) {
return Stream.of(e1, e2, e3, e4, e5);
}
}
}

View File

@@ -1,7 +1,5 @@
package tech.picnic.errorprone.bugpatterns;
import static com.google.common.base.Predicates.containsPattern;
import com.google.errorprone.BugCheckerRefactoringTestHelper;
import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;
import com.google.errorprone.CompilationTestHelper;
@@ -12,7 +10,7 @@ final class AmbiguousJsonCreatorTest {
void identification() {
CompilationTestHelper.newInstance(AmbiguousJsonCreator.class, getClass())
.expectErrorMessage(
"X", containsPattern("`JsonCreator.Mode` should be set for single-argument creators"))
"X", m -> m.contains("`JsonCreator.Mode` should be set for single-argument creators"))
.addSourceLines(
"Container.java",
"import com.fasterxml.jackson.annotation.JsonCreator;",

View File

@@ -276,25 +276,4 @@ final class CanonicalAnnotationSyntaxTest {
"}")
.doTest(TestMode.TEXT_MATCH);
}
@Test
void ignoreLombokViolations() {
CompilationTestHelper.newInstance(CanonicalAnnotationSyntax.class, getClass())
.setArgs("-processor", "lombok.launch.AnnotationProcessorHider$AnnotationProcessor")
.addSourceLines(
"A.java",
"import com.fasterxml.jackson.annotation.JsonProperty;",
"import lombok.Data;",
"",
"@Data",
"class A {",
" @JsonProperty(\"custom_field_name\")",
" private String field;",
"",
" // Should be flagged because of the redundant parentheses, but Lombok doesn't properly link the",
" // annotation to its source code.",
" @JsonProperty() private String field2;",
"}")
.doTest();
}
}

View File

@@ -1,14 +1,12 @@
package tech.picnic.errorprone.bugpatterns;
import static com.google.common.base.Predicates.and;
import static com.google.common.base.Predicates.containsPattern;
import static com.google.common.base.Predicates.not;
import static com.google.errorprone.BugCheckerRefactoringTestHelper.FixChoosers.SECOND;
import static com.google.errorprone.BugCheckerRefactoringTestHelper.FixChoosers.THIRD;
import com.google.errorprone.BugCheckerRefactoringTestHelper;
import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;
import com.google.errorprone.CompilationTestHelper;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.reactivestreams.Publisher;
import reactor.core.CorePublisher;
@@ -20,10 +18,7 @@ final class FluxImplicitBlockTest {
CompilationTestHelper.newInstance(FluxImplicitBlock.class, getClass())
.expectErrorMessage(
"X",
and(
containsPattern("SuppressWarnings"),
containsPattern("toImmutableList"),
containsPattern("toList")))
m -> Stream.of("SuppressWarnings", "toImmutableList", "toList").allMatch(m::contains))
.addSourceLines(
"A.java",
"import com.google.common.collect.ImmutableList;",
@@ -63,7 +58,7 @@ final class FluxImplicitBlockTest {
void identificationWithoutGuavaOnClasspath() {
CompilationTestHelper.newInstance(FluxImplicitBlock.class, getClass())
.withClasspath(CorePublisher.class, Flux.class, Publisher.class)
.expectErrorMessage("X", not(containsPattern("toImmutableList")))
.expectErrorMessage("X", m -> !m.contains("toImmutableList"))
.addSourceLines(
"A.java",
"import reactor.core.publisher.Flux;",

View File

@@ -1,105 +0,0 @@
package tech.picnic.errorprone.bugpatterns;
import com.google.errorprone.BugCheckerRefactoringTestHelper;
import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;
import com.google.errorprone.CompilationTestHelper;
import org.junit.jupiter.api.Test;
import org.springframework.scheduling.annotation.Scheduled;
final class ScheduledTransactionTraceTest {
@Test
void identification() {
CompilationTestHelper.newInstance(ScheduledTransactionTrace.class, getClass())
.addSourceLines(
"A.java",
"import com.newrelic.api.agent.Trace;",
"import org.springframework.scheduling.annotation.Scheduled;",
"",
"class A {",
" void notScheduled() {}",
"",
" @Scheduled(fixedDelay = 1)",
" // BUG: Diagnostic contains:",
" void scheduledButNotTraced() {}",
"",
" @Scheduled(fixedDelay = 1)",
" // BUG: Diagnostic contains:",
" @Trace",
" void scheduledButImproperlyTraced1() {}",
"",
" @Scheduled(fixedDelay = 1)",
" // BUG: Diagnostic contains:",
" @Trace(dispatcher = false)",
" void scheduledButImproperlyTraced2() {}",
"",
" @Scheduled(fixedDelay = 1)",
" @Trace(dispatcher = true)",
" void scheduledAndProperlyTraced() {}",
"}")
.doTest();
}
@Test
void identificationWithoutNewRelicAgentApiOnClasspath() {
CompilationTestHelper.newInstance(ScheduledTransactionTrace.class, getClass())
.withClasspath(Scheduled.class)
.addSourceLines(
"A.java",
"import org.springframework.scheduling.annotation.Scheduled;",
"",
"class A {",
" @Scheduled(fixedDelay = 1)",
" void scheduledButNotTraced() {}",
"}")
.doTest();
}
@Test
void replacement() {
BugCheckerRefactoringTestHelper.newInstance(ScheduledTransactionTrace.class, getClass())
.addInputLines(
"A.java",
"import com.newrelic.api.agent.Trace;",
"import org.springframework.scheduling.annotation.Scheduled;",
"",
"class A {",
" @Scheduled(fixedDelay = 1)",
" void scheduledButNotTraced() {}",
"",
" @Scheduled(fixedDelay = 1)",
" @Trace",
" void scheduledButImproperlyTraced1() {}",
"",
" @Scheduled(fixedDelay = 1)",
" @Trace(dispatcher = false)",
" void scheduledButImproperlyTraced2() {}",
"",
" @Scheduled(fixedDelay = 1)",
" @Trace(leaf = true)",
" void scheduledButImproperlyTraced3() {}",
"}")
.addOutputLines(
"A.java",
"import com.newrelic.api.agent.Trace;",
"import org.springframework.scheduling.annotation.Scheduled;",
"",
"class A {",
" @Trace(dispatcher = true)",
" @Scheduled(fixedDelay = 1)",
" void scheduledButNotTraced() {}",
"",
" @Scheduled(fixedDelay = 1)",
" @Trace(dispatcher = true)",
" void scheduledButImproperlyTraced1() {}",
"",
" @Scheduled(fixedDelay = 1)",
" @Trace(dispatcher = true)",
" void scheduledButImproperlyTraced2() {}",
"",
" @Scheduled(fixedDelay = 1)",
" @Trace(dispatcher = true, leaf = true)",
" void scheduledButImproperlyTraced3() {}",
"}")
.doTest(TestMode.TEXT_MATCH);
}
}

View File

@@ -1,7 +1,5 @@
package tech.picnic.errorprone.bugpatterns;
import static com.google.common.base.Predicates.containsPattern;
import com.google.errorprone.BugCheckerRefactoringTestHelper;
import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;
import com.google.errorprone.CompilationTestHelper;
@@ -12,8 +10,8 @@ final class StringJoinTest {
void identification() {
CompilationTestHelper.newInstance(StringJoin.class, getClass())
.expectErrorMessage(
"valueOf", containsPattern("Prefer `String#valueOf` over `String#format`"))
.expectErrorMessage("join", containsPattern("Prefer `String#join` over `String#format`"))
"valueOf", m -> m.contains("Prefer `String#valueOf` over `String#format`"))
.expectErrorMessage("join", m -> m.contains("Prefer `String#join` over `String#format`"))
.addSourceLines(
"A.java",
"import java.util.Formattable;",

View File

@@ -1,8 +1,6 @@
package tech.picnic.errorprone.bugpatterns.util;
import static com.google.errorprone.BugPattern.SeverityLevel.ERROR;
import static java.util.stream.Collectors.joining;
import static org.assertj.core.api.Assertions.assertThat;
import com.google.errorprone.BugCheckerRefactoringTestHelper;
import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;
@@ -10,92 +8,18 @@ import com.google.errorprone.BugPattern;
import com.google.errorprone.VisitorState;
import com.google.errorprone.bugpatterns.BugChecker;
import com.google.errorprone.bugpatterns.BugChecker.AnnotationTreeMatcher;
import com.google.errorprone.bugpatterns.BugChecker.CompilationUnitTreeMatcher;
import com.google.errorprone.bugpatterns.BugChecker.MethodInvocationTreeMatcher;
import com.google.errorprone.bugpatterns.BugChecker.MethodTreeMatcher;
import com.google.errorprone.fixes.SuggestedFix;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.util.ASTHelpers;
import com.sun.source.tree.AnnotationTree;
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.MethodInvocationTree;
import com.sun.source.tree.MethodTree;
import com.sun.source.tree.Tree;
import com.sun.source.util.TreePath;
import com.sun.source.util.TreeScanner;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.LinkedHashSet;
import java.util.Set;
import javax.lang.model.element.Name;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test;
final class SourceCodeTest {
@Test
void isAccurateSourceLikelyAvailable() {
BugCheckerRefactoringTestHelper.newInstance(
IsAccurateSourceLikelyAvailableTestChecker.class, getClass())
.setArgs("-processor", "lombok.launch.AnnotationProcessorHider$AnnotationProcessor")
.allowBreakingChanges()
.addInputLines(
"A.java",
"import com.fasterxml.jackson.annotation.JsonProperty;",
"import lombok.Data;",
"",
"class A {",
" class WithExplicitNullaryConstructor {",
" WithExplicitNullaryConstructor() {}",
" }",
"",
" class WithoutLombok {",
" @JsonProperty(\"custom_field_name\")",
" private String field;",
" }",
"",
" // BUG: Diagnostic contains:",
" @Data",
" class WithLombok {",
" // BUG: Diagnostic contains:",
" @JsonProperty(\"custom_field_name\")",
" private String field;",
" }",
"}")
.addOutputLines(
"A.java",
"Maximally accurate subtrees found:",
"",
"IMPORT tree at position 0:",
"import com.fasterxml.jackson.annotation.JsonProperty;",
"",
"IMPORT tree at position 54:",
"import lombok.Data;",
"",
"MODIFIERS tree at position -1:",
"null",
"",
"METHOD tree at position 75:",
"null",
"",
"CLASS tree at position 87:",
"class WithExplicitNullaryConstructor {",
" WithExplicitNullaryConstructor() {}",
" }",
"",
"CLASS tree at position 173:",
"class WithoutLombok {",
" @JsonProperty(\"custom_field_name\")",
" private String field;",
" }",
"",
"MODIFIERS tree at position 298:",
"@Data",
"",
"IDENTIFIER tree at position 409:",
"String")
.doTest(TestMode.TEXT_MATCH);
}
@Test
void deleteWithTrailingWhitespaceAnnotations() {
BugCheckerRefactoringTestHelper.newInstance(
@@ -304,56 +228,6 @@ final class SourceCodeTest {
.doTest(TestMode.TEXT_MATCH);
}
/**
* A {@link BugChecker} that uses {@link SourceCode#isAccurateSourceLikelyAvailable(VisitorState)}
* to flag AST nodes for which accurate source code does not appear to be available.
*/
@BugPattern(severity = ERROR, summary = "Interacts with `SourceCode` for testing purposes")
public static final class IsAccurateSourceLikelyAvailableTestChecker extends BugChecker
implements CompilationUnitTreeMatcher {
private static final long serialVersionUID = 1L;
@Override
public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState state) {
Deque<Boolean> seenAccurateSource = new ArrayDeque<>();
Set<Tree> maximalAccurateSubtrees = new LinkedHashSet<>();
new TreeScanner<@Nullable Void, TreePath>() {
@Override
public @Nullable Void scan(Tree node, TreePath treePath) {
if (node == null) {
return null;
}
TreePath path = new TreePath(treePath, node);
boolean isAccurate = SourceCode.isAccurateSourceLikelyAvailable(state.withPath(path));
if (!isAccurate) {
assertThat(seenAccurateSource.peek()).isNotIn(Boolean.TRUE);
} else if (!Boolean.TRUE.equals(seenAccurateSource.peek())) {
maximalAccurateSubtrees.add(node);
}
seenAccurateSource.push(isAccurate);
try {
return super.scan(node, path);
} finally {
seenAccurateSource.pop();
}
}
}.scan(tree, state.getPath());
String accurateSubtrees =
maximalAccurateSubtrees.stream()
.map(
t ->
String.format(
"%s tree at position %s:\n%s",
t.getKind(), ASTHelpers.getStartPosition(t), state.getSourceForNode(t)))
.collect(joining("\n\n", "Maximally accurate subtrees found:\n\n", ""));
return describeMatch(tree, SuggestedFix.replace(tree, accurateSubtrees));
}
}
/**
* A {@link BugChecker} that uses {@link SourceCode#deleteWithTrailingWhitespace(Tree,
* VisitorState)} to suggest the deletion of annotations and methods with a name containing

View File

@@ -23,7 +23,7 @@ final class ThirdPartyLibraryTest {
CompilationTestHelper.newInstance(TestChecker.class, getClass())
.addSourceLines(
"A.java",
"// BUG: Diagnostic contains: ASSERTJ: true, GUAVA: true, NEW_RELIC_AGENT_API: true, REACTOR: true",
"// BUG: Diagnostic contains: ASSERTJ: true, GUAVA: true, REACTOR: true",
"class A {}")
.doTest();
}
@@ -34,16 +34,14 @@ final class ThirdPartyLibraryTest {
.addSourceLines(
"A.java",
"import com.google.common.collect.ImmutableList;",
"import com.newrelic.api.agent.Agent;",
"import org.assertj.core.api.Assertions;",
"import reactor.core.publisher.Flux;",
"",
"// BUG: Diagnostic contains: ASSERTJ: true, GUAVA: true, NEW_RELIC_AGENT_API: true, REACTOR: true",
"// BUG: Diagnostic contains: ASSERTJ: true, GUAVA: true, REACTOR: true",
"class A {",
" void m(Class<?> clazz) {",
" m(Assertions.class);",
" m(ImmutableList.class);",
" m(Agent.class);",
" m(Flux.class);",
" }",
"}")
@@ -56,7 +54,7 @@ final class ThirdPartyLibraryTest {
.withClasspath(ImmutableList.class, Flux.class)
.addSourceLines(
"A.java",
"// BUG: Diagnostic contains: ASSERTJ: false, GUAVA: true, NEW_RELIC_AGENT_API: false, REACTOR: true",
"// BUG: Diagnostic contains: ASSERTJ: false, GUAVA: true, REACTOR: true",
"class A {}")
.doTest();
}
@@ -67,7 +65,7 @@ final class ThirdPartyLibraryTest {
.withClasspath()
.addSourceLines(
"A.java",
"// BUG: Diagnostic contains: ASSERTJ: false, GUAVA: false, NEW_RELIC_AGENT_API: false, REACTOR:",
"// BUG: Diagnostic contains: ASSERTJ: false, GUAVA: false, REACTOR:",
"// false",
"class A {}")
.doTest();
@@ -82,8 +80,8 @@ final class ThirdPartyLibraryTest {
.addSourceLines(
"A.java",
String.format(
"// BUG: Diagnostic contains: ASSERTJ: %s, GUAVA: true, NEW_RELIC_AGENT_API: %s, REACTOR: true",
ignoreClassPath, ignoreClassPath),
"// BUG: Diagnostic contains: ASSERTJ: %s, GUAVA: true, REACTOR: true",
ignoreClassPath),
"class A {}")
.doTest();
}

View File

@@ -36,6 +36,7 @@ final class RefasterRulesTest {
AssortedRules.class,
BigDecimalRules.class,
BugCheckerRules.class,
ClassRules.class,
CollectionRules.class,
ComparatorRules.class,
DoubleStreamRules.class,
@@ -60,6 +61,7 @@ final class RefasterRulesTest {
MultimapRules.class,
NullRules.class,
OptionalRules.class,
PatternRules.class,
PreconditionsRules.class,
PrimitiveRules.class,
ReactorRules.class,

View File

@@ -0,0 +1,26 @@
package tech.picnic.errorprone.refasterrules;
import com.google.common.collect.ImmutableSet;
import java.io.IOException;
import java.util.function.Predicate;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
final class ClassRulesTest implements RefasterRuleCollectionTestCase {
boolean testClassIsInstance() throws IOException {
return CharSequence.class.isAssignableFrom("foo".getClass());
}
ImmutableSet<Boolean> testInstanceof() throws IOException {
Class<?> clazz = CharSequence.class;
return ImmutableSet.of(CharSequence.class.isInstance("foo"), clazz.isInstance("bar"));
}
Predicate<String> testClassLiteralIsInstancePredicate() throws IOException {
return s -> s instanceof CharSequence;
}
Predicate<String> testClassReferenceIsInstancePredicate() throws IOException {
Class<?> clazz = CharSequence.class;
return s -> clazz.isInstance(s);
}
}

View File

@@ -0,0 +1,26 @@
package tech.picnic.errorprone.refasterrules;
import com.google.common.collect.ImmutableSet;
import java.io.IOException;
import java.util.function.Predicate;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
final class ClassRulesTest implements RefasterRuleCollectionTestCase {
boolean testClassIsInstance() throws IOException {
return CharSequence.class.isInstance("foo");
}
ImmutableSet<Boolean> testInstanceof() throws IOException {
Class<?> clazz = CharSequence.class;
return ImmutableSet.of("foo" instanceof CharSequence, clazz.isInstance("bar"));
}
Predicate<String> testClassLiteralIsInstancePredicate() throws IOException {
return CharSequence.class::isInstance;
}
Predicate<String> testClassReferenceIsInstancePredicate() throws IOException {
Class<?> clazz = CharSequence.class;
return clazz::isInstance;
}
}

View File

@@ -5,6 +5,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import com.google.common.collect.ImmutableSet;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.verification.VerificationMode;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
@@ -21,4 +22,14 @@ final class MockitoRulesTest implements RefasterRuleCollectionTestCase {
Object testVerifyOnce() {
return verify(mock(Object.class), times(1));
}
Object testInvocationOnMockGetArguments() {
return ((InvocationOnMock) null).getArguments()[0];
}
ImmutableSet<Number> testInvocationOnMockGetArgumentsWithTypeParameter() {
return ImmutableSet.of(
((InvocationOnMock) null).getArgument(0, Integer.class),
(Double) ((InvocationOnMock) null).getArgument(1));
}
}

View File

@@ -6,6 +6,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import com.google.common.collect.ImmutableSet;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.verification.VerificationMode;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
@@ -22,4 +23,14 @@ final class MockitoRulesTest implements RefasterRuleCollectionTestCase {
Object testVerifyOnce() {
return verify(mock(Object.class));
}
Object testInvocationOnMockGetArguments() {
return ((InvocationOnMock) null).getArgument(0);
}
ImmutableSet<Number> testInvocationOnMockGetArgumentsWithTypeParameter() {
return ImmutableSet.of(
((InvocationOnMock) null).<Integer>getArgument(0),
((InvocationOnMock) null).<Double>getArgument(1));
}
}

View File

@@ -0,0 +1,22 @@
package tech.picnic.errorprone.refasterrules;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableSet;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
final class PatternRulesTest implements RefasterRuleCollectionTestCase {
@Override
public ImmutableSet<Object> elidedTypesAndStaticImports() {
return ImmutableSet.of(Predicates.class);
}
Predicate<?> testPatternAsPredicate() {
return Predicates.contains(Pattern.compile("foo"));
}
Predicate<?> testPatternCompileAsPredicate() {
return Predicates.containsPattern("foo");
}
}

View File

@@ -0,0 +1,22 @@
package tech.picnic.errorprone.refasterrules;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableSet;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
final class PatternRulesTest implements RefasterRuleCollectionTestCase {
@Override
public ImmutableSet<Object> elidedTypesAndStaticImports() {
return ImmutableSet.of(Predicates.class);
}
Predicate<?> testPatternAsPredicate() {
return Pattern.compile("foo").asPredicate();
}
Predicate<?> testPatternCompileAsPredicate() {
return Pattern.compile("foo").asPredicate();
}
}

View File

@@ -98,7 +98,16 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
return Flux.just("foo", "bar").zipWith(Flux.just(1, 2), String::repeat);
}
Flux<String> testFluxZipWithIterable() {
Flux<Tuple2<String, Integer>> testFluxZipWithIterable() {
return Flux.zip(Flux.just("foo", "bar"), Flux.fromIterable(ImmutableSet.of(1, 2)));
}
Flux<String> testFluxZipWithIterableBiFunction() {
return Flux.just("foo", "bar")
.zipWith(Flux.fromIterable(ImmutableSet.of(1, 2)), String::repeat);
}
Flux<String> testFluxZipWithIterableMapFunction() {
return Flux.just("foo", "bar").zipWithIterable(ImmutableSet.of(1, 2), String::repeat);
}
@@ -118,8 +127,11 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
return Flux.error(() -> ((Supplier<RuntimeException>) null).get());
}
Mono<String> testMonoThenReturn() {
return Mono.empty().then(Mono.just("foo"));
ImmutableSet<Mono<String>> testMonoThenReturn() {
return ImmutableSet.of(
Mono.just(1).ignoreElement().thenReturn("foo"),
Mono.just(2).then().thenReturn("bar"),
Mono.just(3).then(Mono.just("baz")));
}
Flux<Integer> testFluxTake() {
@@ -136,11 +148,43 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
Flux.just("baz").switchIfEmpty(Flux.just("qux")));
}
ImmutableSet<Flux<?>> testFluxEmpty() {
return ImmutableSet.of(
Flux.concat(),
Flux.concatDelayError(),
Flux.firstWithSignal(),
Flux.just(),
Flux.merge(),
Flux.merge(1),
Flux.mergeComparing((a, b) -> 0),
Flux.mergeComparing(1, (a, b) -> 0),
Flux.mergeComparingDelayError(1, (a, b) -> 0),
Flux.mergeDelayError(1),
Flux.mergePriority((a, b) -> 0),
Flux.mergePriority(1, (a, b) -> 0),
Flux.mergePriorityDelayError(1, (a, b) -> 0),
Flux.mergeSequential(),
Flux.mergeSequential(1),
Flux.mergeSequentialDelayError(1),
Flux.zip(v -> v),
Flux.zip(v -> v, 1),
Flux.combineLatest(v -> v),
Flux.combineLatest(v -> v, 1),
Flux.mergeComparing(),
Flux.mergePriority(),
Flux.range(0, 0));
}
Flux<Integer> testFluxJust() {
return Flux.range(0, 1);
}
ImmutableSet<Mono<?>> testMonoIdentity() {
return ImmutableSet.of(
Mono.just(1).switchIfEmpty(Mono.empty()),
Mono.just(2).flux().next(),
Mono.just(3).flux().singleOrEmpty(),
Mono.<Void>empty().ignoreElement(),
Mono.<Void>empty().then(),
Mono.<ImmutableList<String>>empty().map(ImmutableList::copyOf));
}
@@ -168,12 +212,26 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
Flux.just(3).map(Mono::just).concatMap(identity(), 5));
}
Flux<Integer> testFluxConcatMapIterable() {
return Flux.just(1, 2).flatMapIterable(ImmutableList::of);
ImmutableSet<Flux<Integer>> testMonoFlatMapIterable() {
return ImmutableSet.of(
Mono.just(1).map(ImmutableSet::of).flatMapIterable(identity()),
Mono.just(2).flux().concatMapIterable(ImmutableSet::of));
}
Flux<Integer> testFluxConcatMapIterableWithPrefetch() {
return Flux.just(1, 2).flatMapIterable(ImmutableList::of, 3);
Flux<Integer> testMonoFlatMapIterableIdentity() {
return Mono.just(ImmutableSet.of(1)).flatMapMany(Flux::fromIterable);
}
ImmutableSet<Flux<Integer>> testFluxConcatMapIterable() {
return ImmutableSet.of(
Flux.just(1).flatMapIterable(ImmutableList::of),
Flux.just(2).map(ImmutableList::of).concatMapIterable(identity()));
}
ImmutableSet<Flux<Integer>> testFluxConcatMapIterableWithPrefetch() {
return ImmutableSet.of(
Flux.just(1).flatMapIterable(ImmutableList::of, 3),
Flux.just(2).map(ImmutableList::of).concatMapIterable(identity(), 3));
}
Flux<String> testMonoFlatMapToFlux() {
@@ -251,8 +309,45 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
Flux.concat(Mono.just("baz")));
}
Mono<Void> testMonoThen() {
return Mono.just("foo").flux().then();
ImmutableSet<Mono<Void>> testMonoThen() {
return ImmutableSet.of(Mono.just("foo").ignoreElement().then(), Mono.just("bar").flux().then());
}
ImmutableSet<Mono<Void>> testFluxThen() {
return ImmutableSet.of(
Flux.just("foo").ignoreElements().then(), Flux.<Void>empty().ignoreElements());
}
Mono<Void> testMonoThenEmpty() {
return Mono.just("foo").ignoreElement().thenEmpty(Mono.empty());
}
Mono<Void> testFluxThenEmpty() {
return Flux.just("foo").ignoreElements().thenEmpty(Mono.empty());
}
Flux<String> testMonoThenMany() {
return Mono.just("foo").ignoreElement().thenMany(Flux.just("bar"));
}
Flux<String> testMonoThenMonoFlux() {
return Mono.just("foo").thenMany(Mono.just("bar"));
}
Flux<String> testFluxThenMany() {
return Flux.just("foo").ignoreElements().thenMany(Flux.just("bar"));
}
ImmutableSet<Mono<?>> testMonoThenMono() {
return ImmutableSet.of(
Mono.just("foo").ignoreElement().then(Mono.just("bar")),
Mono.just("baz").thenEmpty(Mono.<Void>empty()));
}
ImmutableSet<Mono<?>> testFluxThenMono() {
return ImmutableSet.of(
Flux.just("foo").ignoreElements().then(Mono.just("bar")),
Flux.just("baz").thenEmpty(Mono.<Void>empty()));
}
ImmutableSet<Mono<Optional<String>>> testMonoSingleOptional() {
@@ -269,12 +364,33 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
return Flux.just(1).map(Number.class::cast);
}
Mono<Number> testMonoOfType() {
return Mono.just(1).filter(Number.class::isInstance).cast(Number.class);
}
Flux<Number> testFluxOfType() {
return Flux.just(1).filter(Number.class::isInstance).cast(Number.class);
}
Mono<String> testMonoFlatMap() {
return Mono.just("foo").map(Mono::just).flatMap(identity());
}
Flux<String> testMonoFlatMapMany() {
return Mono.just("foo").map(Mono::just).flatMapMany(identity());
ImmutableSet<Flux<Integer>> testMonoFlatMapMany() {
return ImmutableSet.of(
Mono.just(1).map(Mono::just).flatMapMany(identity()),
Mono.just(2).flux().concatMap(Mono::just),
Mono.just(3).flux().concatMap(Mono::just, 2),
Mono.just(4).flux().concatMapDelayError(Mono::just),
Mono.just(5).flux().concatMapDelayError(Mono::just, 2),
Mono.just(6).flux().concatMapDelayError(Mono::just, false, 2),
Mono.just(7).flux().flatMap(Mono::just, 2),
Mono.just(8).flux().flatMap(Mono::just, 2, 3),
Mono.just(9).flux().flatMapDelayError(Mono::just, 2, 3),
Mono.just(10).flux().flatMapSequential(Mono::just, 2),
Mono.just(11).flux().flatMapSequential(Mono::just, 2, 3),
Mono.just(12).flux().flatMapSequentialDelayError(Mono::just, 2, 3),
Mono.just(13).flux().switchMap(Mono::just));
}
ImmutableSet<Flux<String>> testConcatMapIterableIdentity() {
@@ -441,7 +557,9 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
return ImmutableSet.of(
StepVerifier.create(Mono.empty()).expectError(IllegalArgumentException.class).verify(),
StepVerifier.create(Mono.empty())
.verifyErrorSatisfies(t -> assertThat(t).isInstanceOf(IllegalStateException.class)));
.verifyErrorMatches(IllegalStateException.class::isInstance),
StepVerifier.create(Mono.empty())
.verifyErrorSatisfies(t -> assertThat(t).isInstanceOf(AssertionError.class)));
}
Duration testStepVerifierLastStepVerifyErrorMatches() {

View File

@@ -102,7 +102,15 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
.map(TupleUtils.function(String::repeat));
}
Flux<String> testFluxZipWithIterable() {
Flux<Tuple2<String, Integer>> testFluxZipWithIterable() {
return Flux.just("foo", "bar").zipWithIterable(ImmutableSet.of(1, 2));
}
Flux<String> testFluxZipWithIterableBiFunction() {
return Flux.just("foo", "bar").zipWithIterable(ImmutableSet.of(1, 2), String::repeat);
}
Flux<String> testFluxZipWithIterableMapFunction() {
return Flux.just("foo", "bar")
.zipWithIterable(ImmutableSet.of(1, 2))
.map(function(String::repeat));
@@ -124,8 +132,11 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
return Flux.error(((Supplier<RuntimeException>) null));
}
Mono<String> testMonoThenReturn() {
return Mono.empty().thenReturn("foo");
ImmutableSet<Mono<String>> testMonoThenReturn() {
return ImmutableSet.of(
Mono.just(1).thenReturn("foo"),
Mono.just(2).thenReturn("bar"),
Mono.just(3).thenReturn("baz"));
}
Flux<Integer> testFluxTake() {
@@ -141,12 +152,44 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
Flux.just("foo").defaultIfEmpty("bar"), Flux.just("baz").defaultIfEmpty("qux"));
}
ImmutableSet<Flux<?>> testFluxEmpty() {
return ImmutableSet.of(
Flux.empty(),
Flux.empty(),
Flux.empty(),
Flux.empty(),
Flux.empty(),
Flux.empty(),
Flux.empty(),
Flux.empty(),
Flux.empty(),
Flux.empty(),
Flux.empty(),
Flux.empty(),
Flux.empty(),
Flux.empty(),
Flux.empty(),
Flux.empty(),
Flux.empty(),
Flux.empty(),
Flux.empty(),
Flux.empty(),
Flux.empty(),
Flux.empty(),
Flux.empty());
}
Flux<Integer> testFluxJust() {
return Flux.just(0);
}
ImmutableSet<Mono<?>> testMonoIdentity() {
return ImmutableSet.of(
Mono.just(1),
Mono.just(2),
Mono.just(3),
Mono.<Void>empty(),
Mono.<Void>empty(),
Mono.<ImmutableList<String>>empty());
}
@@ -172,12 +215,26 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
Flux.just(3).concatMap(Mono::just, 5));
}
Flux<Integer> testFluxConcatMapIterable() {
return Flux.just(1, 2).concatMapIterable(ImmutableList::of);
ImmutableSet<Flux<Integer>> testMonoFlatMapIterable() {
return ImmutableSet.of(
Mono.just(1).flatMapIterable(ImmutableSet::of),
Mono.just(2).flatMapIterable(ImmutableSet::of));
}
Flux<Integer> testFluxConcatMapIterableWithPrefetch() {
return Flux.just(1, 2).concatMapIterable(ImmutableList::of, 3);
Flux<Integer> testMonoFlatMapIterableIdentity() {
return Mono.just(ImmutableSet.of(1)).flatMapIterable(identity());
}
ImmutableSet<Flux<Integer>> testFluxConcatMapIterable() {
return ImmutableSet.of(
Flux.just(1).concatMapIterable(ImmutableList::of),
Flux.just(2).concatMapIterable(ImmutableList::of));
}
ImmutableSet<Flux<Integer>> testFluxConcatMapIterableWithPrefetch() {
return ImmutableSet.of(
Flux.just(1).concatMapIterable(ImmutableList::of, 3),
Flux.just(2).concatMapIterable(ImmutableList::of, 3));
}
Flux<String> testMonoFlatMapToFlux() {
@@ -250,8 +307,42 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
Mono.just("foo").flux(), Mono.just("bar").flux(), Mono.just("baz").flux());
}
Mono<Void> testMonoThen() {
return Mono.just("foo").then();
ImmutableSet<Mono<Void>> testMonoThen() {
return ImmutableSet.of(Mono.just("foo").then(), Mono.just("bar").then());
}
ImmutableSet<Mono<Void>> testFluxThen() {
return ImmutableSet.of(Flux.just("foo").then(), Flux.<Void>empty().then());
}
Mono<Void> testMonoThenEmpty() {
return Mono.just("foo").thenEmpty(Mono.empty());
}
Mono<Void> testFluxThenEmpty() {
return Flux.just("foo").thenEmpty(Mono.empty());
}
Flux<String> testMonoThenMany() {
return Mono.just("foo").thenMany(Flux.just("bar"));
}
Flux<String> testMonoThenMonoFlux() {
return Mono.just("foo").then(Mono.just("bar")).flux();
}
Flux<String> testFluxThenMany() {
return Flux.just("foo").thenMany(Flux.just("bar"));
}
ImmutableSet<Mono<?>> testMonoThenMono() {
return ImmutableSet.of(
Mono.just("foo").then(Mono.just("bar")), Mono.just("baz").then(Mono.<Void>empty()));
}
ImmutableSet<Mono<?>> testFluxThenMono() {
return ImmutableSet.of(
Flux.just("foo").then(Mono.just("bar")), Flux.just("baz").then(Mono.<Void>empty()));
}
ImmutableSet<Mono<Optional<String>>> testMonoSingleOptional() {
@@ -266,12 +357,33 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
return Flux.just(1).cast(Number.class);
}
Mono<Number> testMonoOfType() {
return Mono.just(1).ofType(Number.class);
}
Flux<Number> testFluxOfType() {
return Flux.just(1).ofType(Number.class);
}
Mono<String> testMonoFlatMap() {
return Mono.just("foo").flatMap(Mono::just);
}
Flux<String> testMonoFlatMapMany() {
return Mono.just("foo").flatMapMany(Mono::just);
ImmutableSet<Flux<Integer>> testMonoFlatMapMany() {
return ImmutableSet.of(
Mono.just(1).flatMapMany(Mono::just),
Mono.just(2).flatMapMany(Mono::just),
Mono.just(3).flatMapMany(Mono::just),
Mono.just(4).flatMapMany(Mono::just),
Mono.just(5).flatMapMany(Mono::just),
Mono.just(6).flatMapMany(Mono::just),
Mono.just(7).flatMapMany(Mono::just),
Mono.just(8).flatMapMany(Mono::just),
Mono.just(9).flatMapMany(Mono::just),
Mono.just(10).flatMapMany(Mono::just),
Mono.just(11).flatMapMany(Mono::just),
Mono.just(12).flatMapMany(Mono::just),
Mono.just(13).flatMapMany(Mono::just));
}
ImmutableSet<Flux<String>> testConcatMapIterableIdentity() {
@@ -428,7 +540,8 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
ImmutableSet<Duration> testStepVerifierLastStepVerifyErrorClass() {
return ImmutableSet.of(
StepVerifier.create(Mono.empty()).verifyError(IllegalArgumentException.class),
StepVerifier.create(Mono.empty()).verifyError(IllegalStateException.class));
StepVerifier.create(Mono.empty()).verifyError(IllegalStateException.class),
StepVerifier.create(Mono.empty()).verifyError(AssertionError.class));
}
Duration testStepVerifierLastStepVerifyErrorMatches() {

View File

@@ -20,6 +20,7 @@ import static java.util.stream.Collectors.summingDouble;
import static java.util.stream.Collectors.summingInt;
import static java.util.stream.Collectors.summingLong;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Streams;
import java.util.DoubleSummaryStatistics;
@@ -36,6 +37,7 @@ final class StreamRulesTest implements RefasterRuleCollectionTestCase {
@Override
public ImmutableSet<Object> elidedTypesAndStaticImports() {
return ImmutableSet.of(
ImmutableList.class,
Objects.class,
Streams.class,
counting(),
@@ -266,4 +268,24 @@ final class StreamRulesTest implements RefasterRuleCollectionTestCase {
Stream<Integer> testStreamIterate() {
return Stream.iterate(0, i -> i + 1).takeWhile(i -> i < 10);
}
Stream<Integer> testStreamOf1() {
return ImmutableList.of(1).stream();
}
Stream<Integer> testStreamOf2() {
return ImmutableList.of(1, 2).stream();
}
Stream<Integer> testStreamOf3() {
return ImmutableList.of(1, 2, 3).stream();
}
Stream<Integer> testStreamOf4() {
return ImmutableList.of(1, 2, 3, 4).stream();
}
Stream<Integer> testStreamOf5() {
return ImmutableList.of(1, 2, 3, 4, 5).stream();
}
}

View File

@@ -21,6 +21,7 @@ import static java.util.stream.Collectors.summingDouble;
import static java.util.stream.Collectors.summingInt;
import static java.util.stream.Collectors.summingLong;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Streams;
import java.util.Arrays;
@@ -38,6 +39,7 @@ final class StreamRulesTest implements RefasterRuleCollectionTestCase {
@Override
public ImmutableSet<Object> elidedTypesAndStaticImports() {
return ImmutableSet.of(
ImmutableList.class,
Objects.class,
Streams.class,
counting(),
@@ -266,4 +268,24 @@ final class StreamRulesTest implements RefasterRuleCollectionTestCase {
Stream<Integer> testStreamIterate() {
return Stream.iterate(0, i -> i < 10, i -> i + 1);
}
Stream<Integer> testStreamOf1() {
return Stream.of(1);
}
Stream<Integer> testStreamOf2() {
return Stream.of(1, 2);
}
Stream<Integer> testStreamOf3() {
return Stream.of(1, 2, 3);
}
Stream<Integer> testStreamOf4() {
return Stream.of(1, 2, 3, 4);
}
Stream<Integer> testStreamOf5() {
return Stream.of(1, 2, 3, 4, 5);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,183 @@
diff --git a/build.gradle.kts b/build.gradle.kts
index a9a6c0692..3695e9d9f 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -91,7 +91,8 @@ fun reportsForHumans() = !(System.getenv()["CI"]?.toBoolean() ?: false)
val skipJavadoc by props()
val enableMavenLocal by props()
val enableGradleMetadata by props()
-val werror by props(true) // treat javac warnings as errors
+// disable, as error prone will be producing lots of warnings
+val werror by props(false) // treat javac warnings as errors
// Inherited from stage-vote-release-plugin: skipSign, useGpgCmd
// Inherited from gradle-extensions-plugin: slowSuiteLogThreshold=0L, slowTestLogThreshold=2000L
@@ -510,8 +511,8 @@ fun com.github.autostyle.gradle.BaseFormatExtension.license() {
plugins.withType<JavaPlugin> {
configure<JavaPluginConvention> {
- sourceCompatibility = JavaVersion.VERSION_1_8
- targetCompatibility = JavaVersion.VERSION_1_8
+ sourceCompatibility = JavaVersion.VERSION_17
+ targetCompatibility = JavaVersion.VERSION_17
}
configure<JavaPluginExtension> {
consistentResolution {
@@ -548,6 +549,7 @@ fun com.github.autostyle.gradle.BaseFormatExtension.license() {
if (!skipAutostyle) {
autostyle {
java {
+ googleJavaFormat()
filter.exclude(*javaccGeneratedPatterns +
"**/test/java/*.java" +
"**/RelRule.java" /** remove as part of CALCITE-4831 **/)
@@ -640,7 +642,7 @@ fun com.github.autostyle.gradle.BaseFormatExtension.license() {
replace("hamcrest: nullValue", "org.hamcrest.Matchers.nullValue", "org.hamcrest.CoreMatchers.nullValue")
replace("hamcrest: sameInstance", "org.hamcrest.core.IsSame.sameInstance", "org.hamcrest.CoreMatchers.sameInstance")
replace("hamcrest: startsWith", "org.hamcrest.core.StringStartsWith.startsWith", "org.hamcrest.CoreMatchers.startsWith")
- replaceRegex("hamcrest: size", "\\.size\\(\\), (is|equalTo)\\(", ", hasSize\\(")
+ // replaceRegex("hamcrest: size", "\\.size\\(\\), (is|equalTo)\\(", ", hasSize\\(")
custom("((() preventer", 1) { contents: String ->
ParenthesisBalancer.apply(contents)
}
@@ -685,17 +687,26 @@ fun com.github.autostyle.gradle.BaseFormatExtension.license() {
if (enableErrorprone) {
apply(plugin = "net.ltgt.errorprone")
+ repositories {
+ mavenLocal()
+ }
+
+ val errorProneFlags = System.getProperty("error-prone.flags")
+ val errorProneSupportVersion = System.getProperty("error-prone-support.version")
+
dependencies {
"errorprone"("com.google.errorprone:error_prone_core:${"errorprone".v}")
+ "annotationProcessor"("tech.picnic.error-prone-support:error-prone-contrib:$errorProneSupportVersion")
+ "annotationProcessor"("tech.picnic.error-prone-support:refaster-runner:$errorProneSupportVersion")
"annotationProcessor"("com.google.guava:guava-beta-checker:1.0")
}
tasks.withType<JavaCompile>().configureEach {
options.errorprone {
+ allErrorsAsWarnings.set(true)
disableWarningsInGeneratedCode.set(true)
errorproneArgs.add("-XepExcludedPaths:.*/javacc/.*")
- enable(
- "MethodCanBeStatic"
- )
+ errorproneArgs.addAll(errorProneFlags.toString().split(" "))
+ errorproneArgs.add("-XepOpt:Refaster:NamePattern=^((?!((JUnitTo)?AssertJ)).*)")
disable(
"ComplexBooleanConstant",
"EqualsGetClass",
@@ -704,7 +715,12 @@ fun com.github.autostyle.gradle.BaseFormatExtension.license() {
"MutableConstantField",
"ReferenceEquality",
"SameNameButDifferent",
- "TypeParameterUnusedInFormals"
+ "TypeParameterUnusedInFormals",
+ "CollectorMutability",
+ "MethodCanBeStatic",
+ "StaticImport",
+ "LexicographicalAnnotationListing",
+ "LexicographicalAnnotationAttributeListing"
)
// Analyze issues, and enable the check
disable(
diff --git a/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java b/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java
index 3cd45f455..1887d0a54 100644
--- a/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java
+++ b/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java
@@ -1463,6 +1463,8 @@ private AggregateOnCalcToAggregateUnifyRule() {
operand(MutableAggregate.class, target(0)), 1);
}
+
+ @SuppressWarnings("MapEntryComparingByKey")
@Override protected @Nullable UnifyResult apply(UnifyRuleCall call) {
final MutableAggregate query = (MutableAggregate) call.query;
final MutableCalc qInput = (MutableCalc) query.getInput();
diff --git a/core/src/main/java/org/apache/calcite/plan/volcano/RelSubset.java b/core/src/main/java/org/apache/calcite/plan/volcano/RelSubset.java
index 29b26adb3..5de5d25cd 100644
--- a/core/src/main/java/org/apache/calcite/plan/volcano/RelSubset.java
+++ b/core/src/main/java/org/apache/calcite/plan/volcano/RelSubset.java
@@ -621,6 +621,7 @@ private static String traitDiff(RelTraitSet original, RelTraitSet desired) {
.collect(Collectors.joining(", ", "[", "]"));
}
+ @SuppressWarnings("MapEntryComparingByValue")
public RelNode visit(
RelNode p,
int ordinal,
diff --git a/core/src/main/java/org/apache/calcite/util/ImmutableIntList.java b/core/src/main/java/org/apache/calcite/util/ImmutableIntList.java
index cb34fe3d5..5dbae21f5 100644
--- a/core/src/main/java/org/apache/calcite/util/ImmutableIntList.java
+++ b/core/src/main/java/org/apache/calcite/util/ImmutableIntList.java
@@ -324,10 +324,12 @@ private static class EmptyImmutableIntList extends ImmutableIntList {
return a;
}
+ @SuppressWarnings("ImmutableListOf")
@Override public Iterator<Integer> iterator() {
return Collections.<Integer>emptyList().iterator();
}
+ @SuppressWarnings("ImmutableListOf")
@Override public ListIterator<Integer> listIterator() {
return Collections.<Integer>emptyList().listIterator();
}
diff --git a/gradle.properties b/gradle.properties
index 3b0776230..42cfa56f3 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -53,7 +53,7 @@ com.google.protobuf.version=0.8.10
de.thetaphi.forbiddenapis.version=3.5.1
jacoco.version=0.8.10
kotlin.version=1.7.10
-net.ltgt.errorprone.version=1.3.0
+net.ltgt.errorprone.version=3.1.0
me.champeau.gradle.jmh.version=0.5.3
org.jetbrains.gradle.plugin.idea-ext.version=0.5
org.nosphere.apache.rat.version=0.7.0
@@ -75,7 +75,7 @@ kotlin.stdlib.default.dependency=false
checkerframework.version=3.10.0
checkstyle.version=8.28
spotbugs.version=3.1.11
-errorprone.version=2.5.1
+errorprone.version=HEAD-SNAPSHOT
# The property is used in https://github.com/wildfly/jandex regression testing, so avoid renaming
jandex.version=2.2.3.Final
@@ -109,7 +109,7 @@ foodmart-data-hsqldb.version=0.5
foodmart-data-json.version=0.4
foodmart-queries.version=0.4.1
geode-core.version=1.15.1
-guava.version=19.0
+guava.version=31.1-jre
h2.version=2.1.210
hadoop.version=2.7.5
hamcrest-date.version=2.0.4
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/Linq4j.java b/linq4j/src/main/java/org/apache/calcite/linq4j/Linq4j.java
index 482a30757..1b22df621 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/Linq4j.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/Linq4j.java
@@ -417,6 +417,7 @@ public static <T> boolean equals(T t0, T t1) {
* above.
*/
@Deprecated // to be removed before 2.0
+ @SuppressWarnings("RequireNonNullStatement")
public static <T> T requireNonNull(T o) {
if (o == null) {
throw new NullPointerException();
diff --git a/testkit/src/main/java/org/apache/calcite/sql/parser/SqlParserTest.java b/testkit/src/main/java/org/apache/calcite/sql/parser/SqlParserTest.java
index d78fab432..449c2ebdd 100644
--- a/testkit/src/main/java/org/apache/calcite/sql/parser/SqlParserTest.java
+++ b/testkit/src/main/java/org/apache/calcite/sql/parser/SqlParserTest.java
@@ -98,6 +98,7 @@
* @see SqlParserFixture
* @see SqlParserListFixture
*/
+@SuppressWarnings("JUnitClassModifiers")
public class SqlParserTest {
/**
* List of reserved keywords.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,253 @@
diff --git a/pom.xml b/pom.xml
index 0f453706b..a478db73f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -233,7 +233,8 @@
<junit.version>5.9.1</junit.version>
<forbiddenapis.version>3.4</forbiddenapis.version>
<json-schema-validator.version>1.2.0</json-schema-validator.version>
- <error-prone.version>2.15.0</error-prone.version>
+ <error-prone.version>v2.17.0-picnic-3</error-prone.version>
+ <error-prone-support.version>0.7.0</error-prone-support.version>
<checkerframework.version>3.27.0</checkerframework.version>
</properties>
@@ -333,6 +334,12 @@
<version>1.1.3</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <version>3.24.1</version>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>nl.jqno.equalsverifier</groupId>
<artifactId>equalsverifier</artifactId>
@@ -2322,15 +2329,25 @@
<arg>-Xpkginfo:always</arg>
<arg>-XDcompilePolicy=simple</arg>
<arg>
- -Xplugin:ErrorProne
+ -Xplugin:ErrorProne ${error-prone.flags}
</arg>
</compilerArgs>
<annotationProcessorPaths>
<path>
- <groupId>com.google.errorprone</groupId>
+ <groupId>com.github.PicnicSupermarket.error-prone</groupId>
<artifactId>error_prone_core</artifactId>
<version>${error-prone.version}</version>
</path>
+ <path>
+ <groupId>tech.picnic.error-prone-support</groupId>
+ <artifactId>error-prone-contrib</artifactId>
+ <version>${error-prone-support.version}</version>
+ </path>
+ <path>
+ <groupId>tech.picnic.error-prone-support</groupId>
+ <artifactId>refaster-runner</artifactId>
+ <version>${error-prone-support.version}</version>
+ </path>
</annotationProcessorPaths>
</configuration>
</execution>
@@ -2375,15 +2392,26 @@
<arg>-XDcompilePolicy=simple</arg>
<arg>
-Xplugin:ErrorProne \
- -XepExcludedPaths:.*[\\/]resources[\\/].*
+ -XepExcludedPaths:.*[\\/]resources[\\/].* \
+ ${error-prone.flags}
</arg>
</compilerArgs>
<annotationProcessorPaths>
<path>
- <groupId>com.google.errorprone</groupId>
+ <groupId>com.github.PicnicSupermarket.error-prone</groupId>
<artifactId>error_prone_core</artifactId>
<version>${error-prone.version}</version>
</path>
+ <path>
+ <groupId>tech.picnic.error-prone-support</groupId>
+ <artifactId>error-prone-contrib</artifactId>
+ <version>${error-prone-support.version}</version>
+ </path>
+ <path>
+ <groupId>tech.picnic.error-prone-support</groupId>
+ <artifactId>refaster-runner</artifactId>
+ <version>${error-prone-support.version}</version>
+ </path>
</annotationProcessorPaths>
</configuration>
</execution>
diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/DetailNodeTreeStringPrinter.java b/src/main/java/com/puppycrawl/tools/checkstyle/DetailNodeTreeStringPrinter.java
index de390a42c..a0ff7a866 100644
--- a/src/main/java/com/puppycrawl/tools/checkstyle/DetailNodeTreeStringPrinter.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/DetailNodeTreeStringPrinter.java
@@ -63,6 +63,7 @@ public final class DetailNodeTreeStringPrinter {
* @return DetailNode tree
* @throws IllegalArgumentException if there is an error parsing the Javadoc.
*/
+ @SuppressWarnings("CheckArgumentWithMessage")
public static DetailNode parseJavadocAsDetailNode(DetailAST blockComment) {
final JavadocDetailNodeParser parser = new JavadocDetailNodeParser();
final ParseStatus status = parser.parseJavadocAsDetailNode(blockComment);
diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/PackageObjectFactory.java b/src/main/java/com/puppycrawl/tools/checkstyle/PackageObjectFactory.java
index bec9669bf..2ad0f4467 100644
--- a/src/main/java/com/puppycrawl/tools/checkstyle/PackageObjectFactory.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/PackageObjectFactory.java
@@ -300,6 +300,7 @@ public class PackageObjectFactory implements ModuleFactory {
* @return the map of third party Checkstyle module names to the set of their fully qualified
* names
*/
+ @SuppressWarnings("CollectorMutability")
private Map<String, Set<String>> generateThirdPartyNameToFullModuleName(ClassLoader loader) {
Map<String, Set<String>> returnValue;
try {
diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/SarifLogger.java b/src/main/java/com/puppycrawl/tools/checkstyle/SarifLogger.java
index 399893f40..aa93aca80 100644
--- a/src/main/java/com/puppycrawl/tools/checkstyle/SarifLogger.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/SarifLogger.java
@@ -140,6 +140,7 @@ public class SarifLogger extends AutomaticBean implements AuditListener {
@Override
public void auditFinished(AuditEvent event) {
final String version = SarifLogger.class.getPackage().getImplementationVersion();
+ @SuppressWarnings("IdentityConversion")
final String rendered = report
.replace(VERSION_PLACEHOLDER, String.valueOf(version))
.replace(RESULTS_PLACEHOLDER, String.join(",\n", results));
diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/checks/coding/IllegalCatchCheck.java b/src/main/java/com/puppycrawl/tools/checkstyle/checks/coding/IllegalCatchCheck.java
index fd1d9d729..d5d891d6e 100644
--- a/src/main/java/com/puppycrawl/tools/checkstyle/checks/coding/IllegalCatchCheck.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/checks/coding/IllegalCatchCheck.java
@@ -152,6 +152,7 @@ public final class IllegalCatchCheck extends AbstractCheck {
public static final String MSG_KEY = "illegal.catch";
/** Specify exception class names to reject. */
+ @SuppressWarnings("CollectorMutability")
private final Set<String> illegalClassNames = Arrays.stream(new String[] {"Exception", "Error",
"RuntimeException", "Throwable", "java.lang.Error", "java.lang.Exception",
"java.lang.RuntimeException", "java.lang.Throwable", }).collect(Collectors.toSet());
diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/checks/coding/IllegalThrowsCheck.java b/src/main/java/com/puppycrawl/tools/checkstyle/checks/coding/IllegalThrowsCheck.java
index d00cd2fdf..4a0d9220d 100644
--- a/src/main/java/com/puppycrawl/tools/checkstyle/checks/coding/IllegalThrowsCheck.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/checks/coding/IllegalThrowsCheck.java
@@ -159,10 +159,12 @@ public final class IllegalThrowsCheck extends AbstractCheck {
public static final String MSG_KEY = "illegal.throw";
/** Specify names of methods to ignore. */
+ @SuppressWarnings("CollectorMutability")
private final Set<String> ignoredMethodNames =
Arrays.stream(new String[] {"finalize", }).collect(Collectors.toSet());
/** Specify throw class names to reject. */
+ @SuppressWarnings("CollectorMutability")
private final Set<String> illegalClassNames = Arrays.stream(
new String[] {"Error", "RuntimeException", "Throwable", "java.lang.Error",
"java.lang.RuntimeException", "java.lang.Throwable", })
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/AbstractModuleTestSupport.java b/src/test/java/com/puppycrawl/tools/checkstyle/AbstractModuleTestSupport.java
index 157e65406..239c2ecc6 100644
--- a/src/test/java/com/puppycrawl/tools/checkstyle/AbstractModuleTestSupport.java
+++ b/src/test/java/com/puppycrawl/tools/checkstyle/AbstractModuleTestSupport.java
@@ -553,6 +553,7 @@ public abstract class AbstractModuleTestSupport extends AbstractPathTestSupport
*/
protected static String[] removeSuppressed(String[] actualViolations,
String... suppressedViolations) {
+ @SuppressWarnings("CollectorMutability")
final List<String> actualViolationsList =
Arrays.stream(actualViolations).collect(Collectors.toList());
actualViolationsList.removeAll(Arrays.asList(suppressedViolations));
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/CheckerTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/CheckerTest.java
index 8fee6bfed..7e20a1580 100644
--- a/src/test/java/com/puppycrawl/tools/checkstyle/CheckerTest.java
+++ b/src/test/java/com/puppycrawl/tools/checkstyle/CheckerTest.java
@@ -90,6 +90,7 @@ import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
* @noinspectionreason ClassWithTooManyDependencies - complex tests require a large number
* of imports
*/
+@SuppressWarnings("JUnitClassModifiers")
public class CheckerTest extends AbstractModuleTestSupport {
@TempDir
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/ConfigurationLoaderTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/ConfigurationLoaderTest.java
index 72881222e..9e81ede00 100644
--- a/src/test/java/com/puppycrawl/tools/checkstyle/ConfigurationLoaderTest.java
+++ b/src/test/java/com/puppycrawl/tools/checkstyle/ConfigurationLoaderTest.java
@@ -46,6 +46,7 @@ import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil;
/**
* Unit test for ConfigurationLoader.
*/
+@SuppressWarnings("JUnitClassModifiers")
public class ConfigurationLoaderTest extends AbstractPathTestSupport {
@Override
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/JavaAstVisitorTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/JavaAstVisitorTest.java
index 5280ab216..2b984fe89 100644
--- a/src/test/java/com/puppycrawl/tools/checkstyle/JavaAstVisitorTest.java
+++ b/src/test/java/com/puppycrawl/tools/checkstyle/JavaAstVisitorTest.java
@@ -106,6 +106,7 @@ public class JavaAstVisitorTest extends AbstractModuleTestSupport {
.map(Method::getName)
.collect(Collectors.toSet());
+ @SuppressWarnings("CollectorMutability")
final Set<String> filteredVisitMethodNames = Arrays.stream(visitMethods)
.filter(method -> method.getName().contains("visit"))
.filter(method -> method.getModifiers() == Modifier.PUBLIC)
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/PackageObjectFactoryTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/PackageObjectFactoryTest.java
index 41636ec4b..9ada7757d 100644
--- a/src/test/java/com/puppycrawl/tools/checkstyle/PackageObjectFactoryTest.java
+++ b/src/test/java/com/puppycrawl/tools/checkstyle/PackageObjectFactoryTest.java
@@ -98,6 +98,7 @@ public class PackageObjectFactoryTest {
public void testCtorNullPackageException1() {
final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
try {
+ @SuppressWarnings("ImmutableSetOf1")
final Object test = new PackageObjectFactory(Collections.singleton(null), classLoader);
assertWithMessage("Exception is expected but got " + test).fail();
}
@@ -126,6 +127,7 @@ public class PackageObjectFactoryTest {
public void testCtorNullPackageException3() {
final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
try {
+ @SuppressWarnings("ImmutableSetOf1")
final Object test = new PackageObjectFactory(Collections.singleton(null), classLoader,
TRY_IN_ALL_REGISTERED_PACKAGES);
assertWithMessage("Exception is expected but got " + test).fail();
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/TreeWalkerTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/TreeWalkerTest.java
index da5d8f2af..4b6f85e95 100644
--- a/src/test/java/com/puppycrawl/tools/checkstyle/TreeWalkerTest.java
+++ b/src/test/java/com/puppycrawl/tools/checkstyle/TreeWalkerTest.java
@@ -79,6 +79,7 @@ import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
* @noinspectionreason ClassWithTooManyDependencies - complex tests require a
* large number of imports
*/
+@SuppressWarnings("JUnitClassModifiers")
public class TreeWalkerTest extends AbstractModuleTestSupport {
@TempDir
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/internal/XpathRegressionTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/internal/XpathRegressionTest.java
index 2e5ce578c..ebf661993 100644
--- a/src/test/java/com/puppycrawl/tools/checkstyle/internal/XpathRegressionTest.java
+++ b/src/test/java/com/puppycrawl/tools/checkstyle/internal/XpathRegressionTest.java
@@ -180,6 +180,7 @@ public class XpathRegressionTest extends AbstractModuleTestSupport {
@Test
public void validateIncompatibleJavadocCheckNames() throws IOException {
// subclasses of AbstractJavadocCheck
+ @SuppressWarnings("CollectorMutability")
final Set<Class<?>> abstractJavadocCheckNames = CheckUtil.getCheckstyleChecks()
.stream()
.filter(AbstractJavadocCheck.class::isAssignableFrom)
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/internal/utils/CheckUtil.java b/src/test/java/com/puppycrawl/tools/checkstyle/internal/utils/CheckUtil.java
index ae779e07b..55f68955e 100644
--- a/src/test/java/com/puppycrawl/tools/checkstyle/internal/utils/CheckUtil.java
+++ b/src/test/java/com/puppycrawl/tools/checkstyle/internal/utils/CheckUtil.java
@@ -78,6 +78,7 @@ public final class CheckUtil {
* @param checks class instances.
* @return a set of simple names.
*/
+ @SuppressWarnings("CollectorMutability")
public static Set<String> getSimpleNames(Set<Class<?>> checks) {
return checks.stream().map(check -> {
String name = check.getSimpleName();

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,136 @@
diff --git a/config/archunit-store/slices-should-be-free-of-cycles-suppressions b/config/archunit-store/slices-should-be-free-of-cycles-suppressions
index 476efc1b9..4eab67306 100644
--- a/config/archunit-store/slices-should-be-free-of-cycles-suppressions
+++ b/config/archunit-store/slices-should-be-free-of-cycles-suppressions
@@ -1351,8 +1351,8 @@ Cycle detected: Slice checks.javadoc -> \
- Constructor <com.puppycrawl.tools.checkstyle.checks.javadoc.AtclauseOrderCheck.<init>()> calls method <com.puppycrawl.tools.checkstyle.utils.TokenUtil.asBitSet([I)> in (AtclauseOrderCheck.java:177)\
- Method <com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocTagContinuationIndentationCheck.visitJavadocToken(com.puppycrawl.tools.checkstyle.api.DetailNode)> calls method <com.puppycrawl.tools.checkstyle.utils.JavadocUtil.getNextSibling(com.puppycrawl.tools.checkstyle.api.DetailNode)> in (JavadocTagContinuationIndentationCheck.java:177)\
- Method <com.puppycrawl.tools.checkstyle.checks.javadoc.RequireEmptyLineBeforeBlockTagGroupCheck.isAnotherTagBefore(com.puppycrawl.tools.checkstyle.api.DetailNode)> calls method <com.puppycrawl.tools.checkstyle.utils.JavadocUtil.getPreviousSibling(com.puppycrawl.tools.checkstyle.api.DetailNode)> in (RequireEmptyLineBeforeBlockTagGroupCheck.java:177)\
+ - Method <com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocNodeImpl.toString()> calls method <com.puppycrawl.tools.checkstyle.utils.JavadocUtil.getTokenName(int)> in (JavadocNodeImpl.java:178)\
- Method <com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocTagInfo$8.isValidOn(com.puppycrawl.tools.checkstyle.api.DetailAST)> calls method <com.puppycrawl.tools.checkstyle.utils.ScopeUtil.isLocalVariableDef(com.puppycrawl.tools.checkstyle.api.DetailAST)> in (JavadocTagInfo.java:178)\
- - Method <com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocNodeImpl.toString()> calls method <com.puppycrawl.tools.checkstyle.utils.JavadocUtil.getTokenName(int)> in (JavadocNodeImpl.java:179)\
- Method <com.puppycrawl.tools.checkstyle.checks.javadoc.AbstractJavadocCheck.setJavadocTokens([Ljava.lang.String;)> calls method <com.puppycrawl.tools.checkstyle.utils.JavadocUtil.getTokenId(java.lang.String)> in (AbstractJavadocCheck.java:181)\
- Method <com.puppycrawl.tools.checkstyle.checks.javadoc.RequireEmptyLineBeforeBlockTagGroupCheck.isAnotherTagBefore(com.puppycrawl.tools.checkstyle.api.DetailNode)> calls method <com.puppycrawl.tools.checkstyle.utils.JavadocUtil.getPreviousSibling(com.puppycrawl.tools.checkstyle.api.DetailNode)> in (RequireEmptyLineBeforeBlockTagGroupCheck.java:183)\
- Method <com.puppycrawl.tools.checkstyle.checks.javadoc.NonEmptyAtclauseDescriptionCheck.hasOnlyEmptyText(com.puppycrawl.tools.checkstyle.api.DetailNode)> calls method <com.puppycrawl.tools.checkstyle.utils.CommonUtil.isBlank(java.lang.String)> in (NonEmptyAtclauseDescriptionCheck.java:185)\
diff --git a/pom.xml b/pom.xml
index e47bd227e..304b565ed 100644
--- a/pom.xml
+++ b/pom.xml
@@ -230,10 +230,12 @@
<pitest.junit5.plugin.version>1.1.2</pitest.junit5.plugin.version>
<pitest.accelerator.junit5.plugin.version>1.0.4</pitest.accelerator.junit5.plugin.version>
<sonar.test.exclusions>**/test/resources/**/*,**/it/resources/**/*</sonar.test.exclusions>
+ <assertj.version>3.24.2</assertj.version>
<junit.version>5.9.2</junit.version>
<forbiddenapis.version>3.4</forbiddenapis.version>
<json-schema-validator.version>1.2.0</json-schema-validator.version>
- <error-prone.version>2.18.0</error-prone.version>
+ <error-prone.version>2.18.0-picnic-1</error-prone.version>
+ <error-prone-support.version>0.9.0</error-prone-support.version>
<checkerframework.version>3.27.0</checkerframework.version>
</properties>
@@ -277,6 +279,12 @@
</dependency>
<!-- test scope stuff -->
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <version>${assertj.version}</version>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
@@ -2308,15 +2316,25 @@
<arg>-Xpkginfo:always</arg>
<arg>-XDcompilePolicy=simple</arg>
<arg>
- -Xplugin:ErrorProne
+ -Xplugin:ErrorProne ${error-prone.flags}
</arg>
</compilerArgs>
<annotationProcessorPaths>
<path>
- <groupId>com.google.errorprone</groupId>
+ <groupId>com.github.PicnicSupermarket.error-prone</groupId>
<artifactId>error_prone_core</artifactId>
<version>${error-prone.version}</version>
</path>
+ <path>
+ <groupId>tech.picnic.error-prone-support</groupId>
+ <artifactId>error-prone-contrib</artifactId>
+ <version>${error-prone-support.version}</version>
+ </path>
+ <path>
+ <groupId>tech.picnic.error-prone-support</groupId>
+ <artifactId>refaster-runner</artifactId>
+ <version>${error-prone-support.version}</version>
+ </path>
</annotationProcessorPaths>
</configuration>
</execution>
@@ -2361,15 +2379,26 @@
<arg>-XDcompilePolicy=simple</arg>
<arg>
-Xplugin:ErrorProne \
- -XepExcludedPaths:.*[\\/]resources[\\/].*
+ -XepExcludedPaths:.*[\\/]resources[\\/].* \
+ ${error-prone.flags}
</arg>
</compilerArgs>
<annotationProcessorPaths>
<path>
- <groupId>com.google.errorprone</groupId>
+ <groupId>com.github.PicnicSupermarket.error-prone</groupId>
<artifactId>error_prone_core</artifactId>
<version>${error-prone.version}</version>
</path>
+ <path>
+ <groupId>tech.picnic.error-prone-support</groupId>
+ <artifactId>error-prone-contrib</artifactId>
+ <version>${error-prone-support.version}</version>
+ </path>
+ <path>
+ <groupId>tech.picnic.error-prone-support</groupId>
+ <artifactId>refaster-runner</artifactId>
+ <version>${error-prone-support.version}</version>
+ </path>
</annotationProcessorPaths>
</configuration>
</execution>
diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/DetailNodeTreeStringPrinter.java b/src/main/java/com/puppycrawl/tools/checkstyle/DetailNodeTreeStringPrinter.java
index 61c59b613..9019964ad 100644
--- a/src/main/java/com/puppycrawl/tools/checkstyle/DetailNodeTreeStringPrinter.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/DetailNodeTreeStringPrinter.java
@@ -63,6 +63,7 @@ public final class DetailNodeTreeStringPrinter {
* @return DetailNode tree
* @throws IllegalArgumentException if there is an error parsing the Javadoc.
*/
+ @SuppressWarnings("CheckArgumentWithMessage")
public static DetailNode parseJavadocAsDetailNode(DetailAST blockComment) {
final JavadocDetailNodeParser parser = new JavadocDetailNodeParser();
final ParseStatus status = parser.parseJavadocAsDetailNode(blockComment);
diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/checks/javadoc/JavadocNodeImpl.java b/src/main/java/com/puppycrawl/tools/checkstyle/checks/javadoc/JavadocNodeImpl.java
index fd90c4259..0c1b4f141 100644
--- a/src/main/java/com/puppycrawl/tools/checkstyle/checks/javadoc/JavadocNodeImpl.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/checks/javadoc/JavadocNodeImpl.java
@@ -20,7 +20,6 @@
package com.puppycrawl.tools.checkstyle.checks.javadoc;
import java.util.Arrays;
-import java.util.Objects;
import java.util.Optional;
import com.puppycrawl.tools.checkstyle.api.DetailNode;
@@ -180,7 +179,7 @@ public class JavadocNodeImpl implements DetailNode {
+ ", text='" + text + '\''
+ ", lineNumber=" + lineNumber
+ ", columnNumber=" + columnNumber
- + ", children=" + Objects.hashCode(children)
+ + ", children=" + Arrays.hashCode(children)
+ ", parent=" + parent + ']';
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,929 @@
diff --git a/guava/src/com/google/common/collect/Iterables.java b/guava/src/com/google/common/collect/Iterables.java
index 7928b15d67..f86ac443ba 100644
--- a/guava/src/com/google/common/collect/Iterables.java
+++ b/guava/src/com/google/common/collect/Iterables.java
@@ -1041,6 +1041,7 @@ public final class Iterables {
*
* @return {@code true} if the iterable contains no elements
*/
+ @SuppressWarnings("IterableIsEmpty")
public static boolean isEmpty(Iterable<?> iterable) {
if (iterable instanceof Collection) {
return ((Collection<?>) iterable).isEmpty();
diff --git a/guava-testlib/test/com/google/common/testing/NullPointerTesterTest.java b/guava-testlib/test/com/google/common/testing/NullPointerTesterTest.java
index a5a20ec3ad..9bad916fe3 100644
--- a/guava-testlib/test/com/google/common/testing/NullPointerTesterTest.java
+++ b/guava-testlib/test/com/google/common/testing/NullPointerTesterTest.java
@@ -839,6 +839,7 @@ public class NullPointerTesterTest extends TestCase {
@SuppressWarnings("unused") // for NullPointerTester
private static class ClassThatFailsToThrowForStatic {
+ @SuppressWarnings("EmptyMethod")
static void staticOneArg(String s) {}
}
@@ -854,6 +855,7 @@ public class NullPointerTesterTest extends TestCase {
private static class SubclassThatTriesToOverrideBadStaticMethod
extends ClassThatFailsToThrowForStatic {
+ @SuppressWarnings("EmptyMethod")
static void staticOneArg(@Nullable String s) {}
}
diff --git a/guava-testlib/test/com/google/common/testing/ClassSanityTesterTest.java b/guava-testlib/test/com/google/common/testing/ClassSanityTesterTest.java
index c5db2d575c..4aa3d60ff0 100644
--- a/guava-testlib/test/com/google/common/testing/ClassSanityTesterTest.java
+++ b/guava-testlib/test/com/google/common/testing/ClassSanityTesterTest.java
@@ -1338,7 +1338,7 @@ public class ClassSanityTesterTest extends TestCase {
private enum EnumFailsToCheckNull {
A;
- @SuppressWarnings("unused")
+ @SuppressWarnings({"unused", "EmptyMethod"})
public void failToCheckNull(String s) {}
}
diff --git a/guava/src/com/google/common/base/Platform.java b/guava/src/com/google/common/base/Platform.java
index 644e89cbfa..137f879603 100644
--- a/guava/src/com/google/common/base/Platform.java
+++ b/guava/src/com/google/common/base/Platform.java
@@ -55,6 +55,7 @@ final class Platform {
return String.format(Locale.ROOT, "%.4g", value);
}
+ @SuppressWarnings("StringIsNullOrEmpty")
static boolean stringIsNullOrEmpty(@CheckForNull String string) {
return string == null || string.isEmpty();
}
diff --git a/guava/src/com/google/common/base/Preconditions.java b/guava/src/com/google/common/base/Preconditions.java
index 13ff77b7f7..1d9729951c 100644
--- a/guava/src/com/google/common/base/Preconditions.java
+++ b/guava/src/com/google/common/base/Preconditions.java
@@ -126,6 +126,7 @@ public final class Preconditions {
* @param expression a boolean expression
* @throws IllegalArgumentException if {@code expression} is false
*/
+ @SuppressWarnings("CheckArgument")
public static void checkArgument(boolean expression) {
if (!expression) {
throw new IllegalArgumentException();
@@ -140,6 +141,7 @@ public final class Preconditions {
* string using {@link String#valueOf(Object)}
* @throws IllegalArgumentException if {@code expression} is false
*/
+ @SuppressWarnings("CheckArgumentWithMessage")
public static void checkArgument(boolean expression, @CheckForNull Object errorMessage) {
if (!expression) {
throw new IllegalArgumentException(String.valueOf(errorMessage));
@@ -159,6 +161,7 @@ public final class Preconditions {
* are converted to strings using {@link String#valueOf(Object)}.
* @throws IllegalArgumentException if {@code expression} is false
*/
+ @SuppressWarnings("CheckArgumentWithMessage")
public static void checkArgument(
boolean expression,
String errorMessageTemplate,
@@ -175,6 +178,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckArgumentWithMessage")
public static void checkArgument(boolean b, String errorMessageTemplate, char p1) {
if (!b) {
throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1));
@@ -267,6 +271,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckArgumentWithMessage")
public static void checkArgument(
boolean b, String errorMessageTemplate, char p1, @CheckForNull Object p2) {
if (!b) {
@@ -281,6 +286,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckArgumentWithMessage")
public static void checkArgument(boolean b, String errorMessageTemplate, int p1, char p2) {
if (!b) {
throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2));
@@ -294,6 +300,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckArgumentWithMessage")
public static void checkArgument(boolean b, String errorMessageTemplate, int p1, int p2) {
if (!b) {
throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2));
@@ -307,6 +314,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckArgumentWithMessage")
public static void checkArgument(boolean b, String errorMessageTemplate, int p1, long p2) {
if (!b) {
throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2));
@@ -320,6 +328,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckArgumentWithMessage")
public static void checkArgument(
boolean b, String errorMessageTemplate, int p1, @CheckForNull Object p2) {
if (!b) {
@@ -334,6 +343,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckArgumentWithMessage")
public static void checkArgument(boolean b, String errorMessageTemplate, long p1, char p2) {
if (!b) {
throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2));
@@ -347,6 +357,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckArgumentWithMessage")
public static void checkArgument(boolean b, String errorMessageTemplate, long p1, int p2) {
if (!b) {
throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2));
@@ -360,6 +371,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckArgumentWithMessage")
public static void checkArgument(boolean b, String errorMessageTemplate, long p1, long p2) {
if (!b) {
throw new IllegalArgumentException(lenientFormat(errorMessageTemplate, p1, p2));
@@ -373,6 +385,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckArgumentWithMessage")
public static void checkArgument(
boolean b, String errorMessageTemplate, long p1, @CheckForNull Object p2) {
if (!b) {
@@ -387,6 +400,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckArgumentWithMessage")
public static void checkArgument(
boolean b, String errorMessageTemplate, @CheckForNull Object p1, char p2) {
if (!b) {
@@ -401,6 +415,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckArgumentWithMessage")
public static void checkArgument(
boolean b, String errorMessageTemplate, @CheckForNull Object p1, int p2) {
if (!b) {
@@ -415,6 +430,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckArgumentWithMessage")
public static void checkArgument(
boolean b, String errorMessageTemplate, @CheckForNull Object p1, long p2) {
if (!b) {
@@ -429,6 +445,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckArgumentWithMessage")
public static void checkArgument(
boolean b, String errorMessageTemplate, @CheckForNull Object p1, @CheckForNull Object p2) {
if (!b) {
@@ -443,6 +460,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckArgumentWithMessage")
public static void checkArgument(
boolean b,
String errorMessageTemplate,
@@ -461,6 +479,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckArgumentWithMessage")
public static void checkArgument(
boolean b,
String errorMessageTemplate,
@@ -481,6 +500,7 @@ public final class Preconditions {
* @throws IllegalStateException if {@code expression} is false
* @see Verify#verify Verify.verify()
*/
+ @SuppressWarnings("CheckState")
public static void checkState(boolean expression) {
if (!expression) {
throw new IllegalStateException();
@@ -497,6 +517,7 @@ public final class Preconditions {
* @throws IllegalStateException if {@code expression} is false
* @see Verify#verify Verify.verify()
*/
+ @SuppressWarnings("CheckStateWithMessage")
public static void checkState(boolean expression, @CheckForNull Object errorMessage) {
if (!expression) {
throw new IllegalStateException(String.valueOf(errorMessage));
@@ -518,6 +539,7 @@ public final class Preconditions {
* @throws IllegalStateException if {@code expression} is false
* @see Verify#verify Verify.verify()
*/
+ @SuppressWarnings("CheckStateWithMessage")
public static void checkState(
boolean expression,
/*
@@ -543,6 +565,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckStateWithMessage")
public static void checkState(boolean b, String errorMessageTemplate, char p1) {
if (!b) {
throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1));
@@ -557,6 +580,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckStateWithMessage")
public static void checkState(boolean b, String errorMessageTemplate, int p1) {
if (!b) {
throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1));
@@ -571,6 +595,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckStateWithMessage")
public static void checkState(boolean b, String errorMessageTemplate, long p1) {
if (!b) {
throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1));
@@ -585,6 +610,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckStateWithMessage")
public static void checkState(boolean b, String errorMessageTemplate, @CheckForNull Object p1) {
if (!b) {
throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1));
@@ -599,6 +625,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckStateWithMessage")
public static void checkState(boolean b, String errorMessageTemplate, char p1, char p2) {
if (!b) {
throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2));
@@ -613,6 +640,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckStateWithMessage")
public static void checkState(boolean b, String errorMessageTemplate, char p1, int p2) {
if (!b) {
throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2));
@@ -627,6 +655,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckStateWithMessage")
public static void checkState(boolean b, String errorMessageTemplate, char p1, long p2) {
if (!b) {
throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2));
@@ -641,6 +670,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckStateWithMessage")
public static void checkState(
boolean b, String errorMessageTemplate, char p1, @CheckForNull Object p2) {
if (!b) {
@@ -656,6 +686,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckStateWithMessage")
public static void checkState(boolean b, String errorMessageTemplate, int p1, char p2) {
if (!b) {
throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2));
@@ -670,6 +701,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckStateWithMessage")
public static void checkState(boolean b, String errorMessageTemplate, int p1, int p2) {
if (!b) {
throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2));
@@ -684,6 +716,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckStateWithMessage")
public static void checkState(boolean b, String errorMessageTemplate, int p1, long p2) {
if (!b) {
throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2));
@@ -698,6 +731,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckStateWithMessage")
public static void checkState(
boolean b, String errorMessageTemplate, int p1, @CheckForNull Object p2) {
if (!b) {
@@ -713,6 +747,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckStateWithMessage")
public static void checkState(boolean b, String errorMessageTemplate, long p1, char p2) {
if (!b) {
throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2));
@@ -727,6 +762,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckStateWithMessage")
public static void checkState(boolean b, String errorMessageTemplate, long p1, int p2) {
if (!b) {
throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2));
@@ -741,6 +777,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckStateWithMessage")
public static void checkState(boolean b, String errorMessageTemplate, long p1, long p2) {
if (!b) {
throw new IllegalStateException(lenientFormat(errorMessageTemplate, p1, p2));
@@ -755,6 +792,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckStateWithMessage")
public static void checkState(
boolean b, String errorMessageTemplate, long p1, @CheckForNull Object p2) {
if (!b) {
@@ -770,6 +808,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckStateWithMessage")
public static void checkState(
boolean b, String errorMessageTemplate, @CheckForNull Object p1, char p2) {
if (!b) {
@@ -785,6 +824,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckStateWithMessage")
public static void checkState(
boolean b, String errorMessageTemplate, @CheckForNull Object p1, int p2) {
if (!b) {
@@ -800,6 +840,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckStateWithMessage")
public static void checkState(
boolean b, String errorMessageTemplate, @CheckForNull Object p1, long p2) {
if (!b) {
@@ -815,6 +856,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckStateWithMessage")
public static void checkState(
boolean b, String errorMessageTemplate, @CheckForNull Object p1, @CheckForNull Object p2) {
if (!b) {
@@ -830,6 +872,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckStateWithMessage")
public static void checkState(
boolean b,
String errorMessageTemplate,
@@ -849,6 +892,7 @@ public final class Preconditions {
*
* @since 20.0 (varargs overload since 2.0)
*/
+ @SuppressWarnings("CheckStateWithMessage")
public static void checkState(
boolean b,
String errorMessageTemplate,
@@ -884,6 +928,7 @@ public final class Preconditions {
* @see Verify#verifyNotNull Verify.verifyNotNull()
*/
@CanIgnoreReturnValue
+ @SuppressWarnings("RequireNonNullStatement")
public static <T> T checkNotNull(@CheckForNull T reference) {
if (reference == null) {
throw new NullPointerException();
@@ -902,6 +947,7 @@ public final class Preconditions {
* @see Verify#verifyNotNull Verify.verifyNotNull()
*/
@CanIgnoreReturnValue
+ @SuppressWarnings("RequireNonNullWithMessageStatement")
public static <T> T checkNotNull(@CheckForNull T reference, @CheckForNull Object errorMessage) {
if (reference == null) {
throw new NullPointerException(String.valueOf(errorMessage));
@@ -925,6 +971,7 @@ public final class Preconditions {
* @see Verify#verifyNotNull Verify.verifyNotNull()
*/
@CanIgnoreReturnValue
+ @SuppressWarnings("RequireNonNullWithMessageStatement")
public static <T> T checkNotNull(
@CheckForNull T reference,
String errorMessageTemplate,
@@ -943,6 +990,7 @@ public final class Preconditions {
* @since 20.0 (varargs overload since 2.0)
*/
@CanIgnoreReturnValue
+ @SuppressWarnings("RequireNonNullWithMessageStatement")
public static <T> T checkNotNull(@CheckForNull T obj, String errorMessageTemplate, char p1) {
if (obj == null) {
throw new NullPointerException(lenientFormat(errorMessageTemplate, p1));
@@ -958,6 +1006,7 @@ public final class Preconditions {
* @since 20.0 (varargs overload since 2.0)
*/
@CanIgnoreReturnValue
+ @SuppressWarnings("RequireNonNullWithMessageStatement")
public static <T> T checkNotNull(@CheckForNull T obj, String errorMessageTemplate, int p1) {
if (obj == null) {
throw new NullPointerException(lenientFormat(errorMessageTemplate, p1));
@@ -973,6 +1022,7 @@ public final class Preconditions {
* @since 20.0 (varargs overload since 2.0)
*/
@CanIgnoreReturnValue
+ @SuppressWarnings("RequireNonNullWithMessageStatement")
public static <T> T checkNotNull(@CheckForNull T obj, String errorMessageTemplate, long p1) {
if (obj == null) {
throw new NullPointerException(lenientFormat(errorMessageTemplate, p1));
@@ -988,6 +1038,7 @@ public final class Preconditions {
* @since 20.0 (varargs overload since 2.0)
*/
@CanIgnoreReturnValue
+ @SuppressWarnings("RequireNonNullWithMessageStatement")
public static <T> T checkNotNull(
@CheckForNull T obj, String errorMessageTemplate, @CheckForNull Object p1) {
if (obj == null) {
@@ -1004,6 +1055,7 @@ public final class Preconditions {
* @since 20.0 (varargs overload since 2.0)
*/
@CanIgnoreReturnValue
+ @SuppressWarnings("RequireNonNullWithMessageStatement")
public static <T> T checkNotNull(
@CheckForNull T obj, String errorMessageTemplate, char p1, char p2) {
if (obj == null) {
@@ -1020,6 +1072,7 @@ public final class Preconditions {
* @since 20.0 (varargs overload since 2.0)
*/
@CanIgnoreReturnValue
+ @SuppressWarnings("RequireNonNullWithMessageStatement")
public static <T> T checkNotNull(
@CheckForNull T obj, String errorMessageTemplate, char p1, int p2) {
if (obj == null) {
@@ -1036,6 +1089,7 @@ public final class Preconditions {
* @since 20.0 (varargs overload since 2.0)
*/
@CanIgnoreReturnValue
+ @SuppressWarnings("RequireNonNullWithMessageStatement")
public static <T> T checkNotNull(
@CheckForNull T obj, String errorMessageTemplate, char p1, long p2) {
if (obj == null) {
@@ -1052,6 +1106,7 @@ public final class Preconditions {
* @since 20.0 (varargs overload since 2.0)
*/
@CanIgnoreReturnValue
+ @SuppressWarnings("RequireNonNullWithMessageStatement")
public static <T> T checkNotNull(
@CheckForNull T obj, String errorMessageTemplate, char p1, @CheckForNull Object p2) {
if (obj == null) {
@@ -1068,6 +1123,7 @@ public final class Preconditions {
* @since 20.0 (varargs overload since 2.0)
*/
@CanIgnoreReturnValue
+ @SuppressWarnings("RequireNonNullWithMessageStatement")
public static <T> T checkNotNull(
@CheckForNull T obj, String errorMessageTemplate, int p1, char p2) {
if (obj == null) {
@@ -1084,6 +1140,7 @@ public final class Preconditions {
* @since 20.0 (varargs overload since 2.0)
*/
@CanIgnoreReturnValue
+ @SuppressWarnings("RequireNonNullWithMessageStatement")
public static <T> T checkNotNull(
@CheckForNull T obj, String errorMessageTemplate, int p1, int p2) {
if (obj == null) {
@@ -1100,6 +1157,7 @@ public final class Preconditions {
* @since 20.0 (varargs overload since 2.0)
*/
@CanIgnoreReturnValue
+ @SuppressWarnings("RequireNonNullWithMessageStatement")
public static <T> T checkNotNull(
@CheckForNull T obj, String errorMessageTemplate, int p1, long p2) {
if (obj == null) {
@@ -1116,6 +1174,7 @@ public final class Preconditions {
* @since 20.0 (varargs overload since 2.0)
*/
@CanIgnoreReturnValue
+ @SuppressWarnings("RequireNonNullWithMessageStatement")
public static <T> T checkNotNull(
@CheckForNull T obj, String errorMessageTemplate, int p1, @CheckForNull Object p2) {
if (obj == null) {
@@ -1132,6 +1191,7 @@ public final class Preconditions {
* @since 20.0 (varargs overload since 2.0)
*/
@CanIgnoreReturnValue
+ @SuppressWarnings("RequireNonNullWithMessageStatement")
public static <T> T checkNotNull(
@CheckForNull T obj, String errorMessageTemplate, long p1, char p2) {
if (obj == null) {
@@ -1148,6 +1208,7 @@ public final class Preconditions {
* @since 20.0 (varargs overload since 2.0)
*/
@CanIgnoreReturnValue
+ @SuppressWarnings("RequireNonNullWithMessageStatement")
public static <T> T checkNotNull(
@CheckForNull T obj, String errorMessageTemplate, long p1, int p2) {
if (obj == null) {
@@ -1164,6 +1225,7 @@ public final class Preconditions {
* @since 20.0 (varargs overload since 2.0)
*/
@CanIgnoreReturnValue
+ @SuppressWarnings("RequireNonNullWithMessageStatement")
public static <T> T checkNotNull(
@CheckForNull T obj, String errorMessageTemplate, long p1, long p2) {
if (obj == null) {
@@ -1180,6 +1242,7 @@ public final class Preconditions {
* @since 20.0 (varargs overload since 2.0)
*/
@CanIgnoreReturnValue
+ @SuppressWarnings("RequireNonNullWithMessageStatement")
public static <T> T checkNotNull(
@CheckForNull T obj, String errorMessageTemplate, long p1, @CheckForNull Object p2) {
if (obj == null) {
@@ -1196,6 +1259,7 @@ public final class Preconditions {
* @since 20.0 (varargs overload since 2.0)
*/
@CanIgnoreReturnValue
+ @SuppressWarnings("RequireNonNullWithMessageStatement")
public static <T> T checkNotNull(
@CheckForNull T obj, String errorMessageTemplate, @CheckForNull Object p1, char p2) {
if (obj == null) {
@@ -1212,6 +1276,7 @@ public final class Preconditions {
* @since 20.0 (varargs overload since 2.0)
*/
@CanIgnoreReturnValue
+ @SuppressWarnings("RequireNonNullWithMessageStatement")
public static <T> T checkNotNull(
@CheckForNull T obj, String errorMessageTemplate, @CheckForNull Object p1, int p2) {
if (obj == null) {
@@ -1228,6 +1293,7 @@ public final class Preconditions {
* @since 20.0 (varargs overload since 2.0)
*/
@CanIgnoreReturnValue
+ @SuppressWarnings("RequireNonNullWithMessageStatement")
public static <T> T checkNotNull(
@CheckForNull T obj, String errorMessageTemplate, @CheckForNull Object p1, long p2) {
if (obj == null) {
@@ -1244,6 +1310,7 @@ public final class Preconditions {
* @since 20.0 (varargs overload since 2.0)
*/
@CanIgnoreReturnValue
+ @SuppressWarnings("RequireNonNullWithMessageStatement")
public static <T> T checkNotNull(
@CheckForNull T obj,
String errorMessageTemplate,
@@ -1263,6 +1330,7 @@ public final class Preconditions {
* @since 20.0 (varargs overload since 2.0)
*/
@CanIgnoreReturnValue
+ @SuppressWarnings("RequireNonNullWithMessageStatement")
public static <T> T checkNotNull(
@CheckForNull T obj,
String errorMessageTemplate,
@@ -1283,6 +1351,7 @@ public final class Preconditions {
* @since 20.0 (varargs overload since 2.0)
*/
@CanIgnoreReturnValue
+ @SuppressWarnings("RequireNonNullWithMessageStatement")
public static <T> T checkNotNull(
@CheckForNull T obj,
String errorMessageTemplate,
@@ -1349,6 +1418,7 @@ public final class Preconditions {
* @throws IllegalArgumentException if {@code size} is negative
*/
@CanIgnoreReturnValue
+ @SuppressWarnings("CheckElementIndexWithMessage")
public static int checkElementIndex(int index, int size, String desc) {
// Carefully optimized for execution by hotspot (explanatory comment above)
if (index < 0 || index >= size) {
@@ -1394,6 +1464,7 @@ public final class Preconditions {
* @throws IllegalArgumentException if {@code size} is negative
*/
@CanIgnoreReturnValue
+ @SuppressWarnings("CheckPositionIndexWithMessage")
public static int checkPositionIndex(int index, int size, String desc) {
// Carefully optimized for execution by hotspot (explanatory comment above)
if (index < 0 || index > size) {
diff --git a/guava/src/com/google/common/base/Strings.java b/guava/src/com/google/common/base/Strings.java
index e56bf1c481..459acbca1a 100644
--- a/guava/src/com/google/common/base/Strings.java
+++ b/guava/src/com/google/common/base/Strings.java
@@ -265,6 +265,7 @@ public final class Strings {
* @since 25.1
*/
// TODO(diamondm) consider using Arrays.toString() for array parameters
+ @SuppressWarnings("IdentityConversion")
public static String lenientFormat(
@CheckForNull String template, @CheckForNull @Nullable Object... args) {
template = String.valueOf(template); // null -> "null"
diff --git a/guava/src/com/google/common/graph/UndirectedNetworkConnections.java b/guava/src/com/google/common/graph/UndirectedNetworkConnections.java
index 190897f882..f11f98867c 100644
--- a/guava/src/com/google/common/graph/UndirectedNetworkConnections.java
+++ b/guava/src/com/google/common/graph/UndirectedNetworkConnections.java
@@ -43,6 +43,7 @@ final class UndirectedNetworkConnections<N, E> extends AbstractUndirectedNetwork
return new UndirectedNetworkConnections<>(HashBiMap.<E, N>create(EXPECTED_DEGREE));
}
+ @SuppressWarnings("IdentityConversion")
static <N, E> UndirectedNetworkConnections<N, E> ofImmutable(Map<E, N> incidentEdges) {
return new UndirectedNetworkConnections<>(ImmutableBiMap.copyOf(incidentEdges));
}
diff --git a/guava/src/com/google/common/graph/DirectedNetworkConnections.java b/guava/src/com/google/common/graph/DirectedNetworkConnections.java
index e1db65708e..9d70c790ee 100644
--- a/guava/src/com/google/common/graph/DirectedNetworkConnections.java
+++ b/guava/src/com/google/common/graph/DirectedNetworkConnections.java
@@ -44,6 +44,7 @@ final class DirectedNetworkConnections<N, E> extends AbstractDirectedNetworkConn
HashBiMap.<E, N>create(EXPECTED_DEGREE), HashBiMap.<E, N>create(EXPECTED_DEGREE), 0);
}
+ @SuppressWarnings("IdentityConversion")
static <N, E> DirectedNetworkConnections<N, E> ofImmutable(
Map<E, N> inEdges, Map<E, N> outEdges, int selfLoopCount) {
return new DirectedNetworkConnections<>(
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/MapGenerators.java b/guava-testlib/src/com/google/common/collect/testing/google/MapGenerators.java
index 35063e815d..3f445ca116 100644
--- a/guava-testlib/src/com/google/common/collect/testing/google/MapGenerators.java
+++ b/guava-testlib/src/com/google/common/collect/testing/google/MapGenerators.java
@@ -60,6 +60,7 @@ public class MapGenerators {
public static class ImmutableMapCopyOfGenerator extends TestStringMapGenerator {
@Override
+ @SuppressWarnings("IdentityConversion")
protected Map<String, String> create(Entry<String, String>[] entries) {
Map<String, String> builder = Maps.newLinkedHashMap();
for (Entry<String, String> entry : entries) {
@@ -71,6 +72,7 @@ public class MapGenerators {
public static class ImmutableMapCopyOfEntriesGenerator extends TestStringMapGenerator {
@Override
+ @SuppressWarnings("IdentityConversion")
protected Map<String, String> create(Entry<String, String>[] entries) {
return ImmutableMap.copyOf(Arrays.asList(entries));
}
@@ -162,6 +164,7 @@ public class MapGenerators {
public static class ImmutableMapCopyOfEnumMapGenerator extends TestEnumMapGenerator {
@Override
+ @SuppressWarnings("IdentityConversion")
protected Map<AnEnum, String> create(Entry<AnEnum, String>[] entries) {
EnumMap<AnEnum, String> map = new EnumMap<>(AnEnum.class);
for (Entry<AnEnum, String> entry : entries) {
diff --git a/guava/src/com/google/common/collect/RegularImmutableSortedSet.java b/guava/src/com/google/common/collect/RegularImmutableSortedSet.java
index 572e0acbf5..fa17e67916 100644
--- a/guava/src/com/google/common/collect/RegularImmutableSortedSet.java
+++ b/guava/src/com/google/common/collect/RegularImmutableSortedSet.java
@@ -324,6 +324,7 @@ final class RegularImmutableSortedSet<E> extends ImmutableSortedSet<E> {
@Override
ImmutableSortedSet<E> createDescendingSet() {
+ @SuppressWarnings("StaticImport")
Comparator<? super E> reversedOrder = Collections.reverseOrder(comparator);
return isEmpty()
? emptySet(reversedOrder)
diff --git a/pom.xml b/pom.xml
index 13dd0985d3..30c1060d1c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,6 +22,9 @@
<maven-javadoc-plugin.additionalJOptions></maven-javadoc-plugin.additionalJOptions>
<maven-source-plugin.version>3.2.1</maven-source-plugin.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <error-prone.version>v2.19.1-picnic-1</error-prone.version> <java.version>11</java.version>
+ <error-prone-support.version>0.11.2-SNAPSHOT</error-prone-support.version>
+ <maven.compiler.plugin.version>3.11.0</maven.compiler.plugin.version>
</properties>
<issueManagement>
<system>GitHub Issues</system>
@@ -347,50 +350,163 @@
</dependencyManagement>
<profiles>
<profile>
- <id>sonatype-oss-release</id>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
- <version>${maven-source-plugin.version}</version>
- <executions>
- <execution>
- <id>attach-sources</id>
- <goals>
- <goal>jar-no-fork</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-javadoc-plugin</artifactId>
- <version>${maven-javadoc-plugin.version}</version>
- <executions>
- <execution>
- <id>attach-javadocs</id>
- <goals>
- <goal>jar</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-gpg-plugin</artifactId>
- <version>1.6</version>
- <executions>
- <execution>
- <id>sign-artifacts</id>
- <phase>verify</phase>
- <goals>
- <goal>sign</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
+ <id>error-prone-compile</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>${maven.compiler.plugin.version}</version>
+ <executions>
+ <execution>
+ <id>error-prone-compile</id>
+ <phase>compile</phase>
+ <goals>
+ <goal>compile</goal>
+ </goals>
+ <configuration>
+ <failOnError>false</failOnError>
+ <source>1.8</source>
+ <target>1.8</target>
+ <compilerArgs>
+ <arg>-Xpkginfo:always</arg>
+ <arg>-XDcompilePolicy=simple</arg>
+ <arg>
+ -Xplugin:ErrorProne ${error-prone.flags} -Xep:CollectorMutability:OFF -Xep:FluxImplicitBlock:OFF -Xep:ScheduledTransactionTrace:OFF -XepOpt:Refaster:NamePattern=^((?!(Immutable|PrimitiveRules|AssortedRules\$CheckIndex|NullRules\$RequireNonNullElse|MapEntryRules\$MapEntry|OptionalRules\$OptionalOrElseThrow|OptionalRules\$OptionalIsEmpty)).*)
+ </arg>
+ </compilerArgs>
+ <annotationProcessorPaths>
+ <path>
+ <groupId>com.github.PicnicSupermarket.error-prone</groupId>
+ <artifactId>error_prone_core</artifactId>
+ <version>${error-prone.version}</version>
+ </path>
+ <path>
+ <groupId>tech.picnic.error-prone-support</groupId>
+ <artifactId>error-prone-contrib</artifactId>
+ <version>${error-prone-support.version}</version>
+ </path>
+ <path>
+ <groupId>tech.picnic.error-prone-support</groupId>
+ <artifactId>refaster-runner</artifactId>
+ <version>${error-prone-support.version}</version>
+ </path>
+ </annotationProcessorPaths>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>error-prone-test-compile</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>${maven.compiler.plugin.version}</version>
+ <executions>
+ <!-- Skip the default-testCompile execution as we don't want to execute the testCompile goal twice -->
+ <execution>
+ <id>default-testCompile</id>
+ <phase>test-compile</phase>
+ <goals>
+ <goal>testCompile</goal>
+ </goals>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </execution>
+ <execution>
+ <id>error-prone-test-compile</id>
+ <phase>test-compile</phase>
+ <goals>
+ <goal>testCompile</goal>
+ </goals>
+ <configuration>
+ <failOnError>false</failOnError>
+ <source>${java.version}</source>
+ <target>${java.version}</target>
+ <compilerArgs>
+ <arg>-Xpkginfo:always</arg>
+ <arg>-XDcompilePolicy=simple</arg>
+ <arg>
+ -Xplugin:ErrorProne \
+
+ ${error-prone.flags}
+ </arg>
+ </compilerArgs>
+ <annotationProcessorPaths>
+ <path>
+ <groupId>com.github.PicnicSupermarket.error-prone</groupId>
+ <artifactId>error_prone_core</artifactId>
+ <version>${error-prone.version}</version>
+ </path>
+ <path>
+ <groupId>tech.picnic.error-prone-support</groupId>
+ <artifactId>error-prone-contrib</artifactId>
+ <version>${error-prone-support.version}</version>
+ </path>
+ <path>
+ <groupId>tech.picnic.error-prone-support</groupId>
+ <artifactId>refaster-runner</artifactId>
+ <version>${error-prone-support.version}</version>
+ </path>
+ </annotationProcessorPaths>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>sonatype-oss-release</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>${maven-source-plugin.version}</version>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <goals>
+ <goal>jar-no-fork</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>${maven-javadoc-plugin.version}</version>
+ <executions>
+ <execution>
+ <id>attach-javadocs</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-gpg-plugin</artifactId>
+ <version>1.6</version>
+ <executions>
+ <execution>
+ <id>sign-artifacts</id>
+ <phase>verify</phase>
+ <goals>
+ <goal>sign</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
</build>
</profile>
<profile>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
metrics-core/src/main/java/com/codahale/metrics/CsvReporter.java:[382,36] [FormatStringConcatenation] Defer string concatenation to the invoked method
metrics-graphite/src/main/java/com/codahale/metrics/graphite/GraphiteReporter.java:[431,18] [Slf4jLogStatement] Log statement contains 0 placeholders, but specifies 1 matching argument(s)
metrics-graphite/src/main/java/com/codahale/metrics/graphite/GraphiteReporter.java:[436,20] [Slf4jLogStatement] Log statement contains 0 placeholders, but specifies 1 matching argument(s)
metrics-graphite/src/main/java/com/codahale/metrics/graphite/GraphiteReporter.java:[449,21] [Slf4jLogStatement] Log statement contains 0 placeholders, but specifies 1 matching argument(s)
metrics-healthchecks/src/test/java/com/codahale/metrics/health/HealthCheckTest.java:[189,47] [TimeZoneUsage] Derive the current time from an existing `Clock` Spring bean, and don't rely on a `Clock`'s time zone
metrics-healthchecks/src/test/java/com/codahale/metrics/health/HealthCheckTest.java:[203,47] [TimeZoneUsage] Derive the current time from an existing `Clock` Spring bean, and don't rely on a `Clock`'s time zone
metrics-jakarta-servlets/src/test/java/io/dropwizard/metrics/servlets/HealthCheckServletTest.java:[29,68] [TimeZoneUsage] Derive the current time from an existing `Clock` Spring bean, and don't rely on a `Clock`'s time zone
metrics-servlets/src/test/java/com/codahale/metrics/servlets/HealthCheckServletTest.java:[30,68] [TimeZoneUsage] Derive the current time from an existing `Clock` Spring bean, and don't rely on a `Clock`'s time zone

View File

@@ -0,0 +1,231 @@
diff --git a/pom.xml b/pom.xml
index 6192b52f..b8e38fbc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -66,7 +66,9 @@
<junit.version>4.13.1</junit.version>
<hamcrest.version>1.3</hamcrest.version>
<maven-compiler-plugin.version>3.11.0</maven-compiler-plugin.version>
- <errorprone.version>2.19.1</errorprone.version>
+ <errorprone.version>v2.19.1-picnic-1</errorprone.version>
+ <error-prone-support.version>0.11.2-SNAPSHOT</error-prone-support.version>
+ <error-prone-support.flags>-Xplugin:ErrorProne ${error-prone.flags} -Xep:CollectorMutability:OFF -XepOpt:Refaster:NamePattern=^((?!(Immutable|Preconditions|StringRules\$StringIsNullOrEmpty)).*)</error-prone-support.flags>
<errorprone.javac.version>9+181-r4173-1</errorprone.javac.version>
<sonar.projectKey>dropwizard_metrics</sonar.projectKey>
@@ -137,60 +139,118 @@
<profiles>
<profile>
- <id>jdk8</id>
- <activation>
- <jdk>1.8</jdk>
- </activation>
+ <id>error-prone-compile</id>
<build>
<plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>${maven-compiler-plugin.version}</version>
+ <executions>
+ <execution>
+ <id>error-prone-compile</id>
+ <phase>compile</phase>
+ <goals>
+ <goal>compile</goal>
+ </goals>
<configuration>
- <compilerArgs combine.children="append">
- <arg>-J-Xbootclasspath/p:${settings.localRepository}/com/google/errorprone/javac/${errorprone.javac.version}/javac-${errorprone.javac.version}.jar</arg>
- </compilerArgs>
+ <failOnError>true</failOnError>
+ <compilerArgs combine.children="append">
+ <arg>-Xpkginfo:always</arg>
+ <arg>-XDcompilePolicy=simple</arg>
+ <arg>${error-prone-support.flags}</arg>
+ <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</arg>
+ <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED</arg>
+ <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED</arg>
+ <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED</arg>
+ <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED</arg>
+ <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED</arg>
+ <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED</arg>
+ <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED</arg>
+ <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED</arg>
+ <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED</arg>
+ </compilerArgs>
+ <annotationProcessorPaths combine.children="append">
+ <path>
+ <groupId>com.github.PicnicSupermarket.error-prone</groupId>
+ <artifactId>error_prone_core</artifactId>
+ <version>${errorprone.version}</version>
+ </path>
+ <path>
+ <groupId>tech.picnic.error-prone-support</groupId>
+ <artifactId>error-prone-contrib</artifactId>
+ <version>${error-prone-support.version}</version>
+ </path>
+ <path>
+ <groupId>tech.picnic.error-prone-support</groupId>
+ <artifactId>refaster-runner</artifactId>
+ <version>${error-prone-support.version}</version>
+ </path>
+ </annotationProcessorPaths>
</configuration>
- </plugin>
+ </execution>
+ </executions>
+ </plugin>
</plugins>
- </build>
+ </build>
</profile>
<profile>
- <id>jdk17</id>
- <activation>
- <jdk>[17,)</jdk>
- </activation>
+ <id>error-prone-test-compile</id>
<build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <compilerArgs>
- <arg>-Xlint:all</arg>
- <arg>-XDcompilePolicy=simple</arg>
- <arg>-Xplugin:ErrorProne -XepExcludedPaths:.*/target/generated-sources/.*</arg>
- <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</arg>
- <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED</arg>
- <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED</arg>
- <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED</arg>
- <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED</arg>
- <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED</arg>
- <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED</arg>
- <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED</arg>
- <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED</arg>
- <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED</arg>
- </compilerArgs>
- <annotationProcessorPaths>
- <path>
- <groupId>com.google.errorprone</groupId>
- <artifactId>error_prone_core</artifactId>
- <version>${errorprone.version}</version>
- </path>
- </annotationProcessorPaths>
- </configuration>
- </plugin>
- </plugins>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>${maven-compiler-plugin.version}</version>
+ <executions>
+ <!-- Skip the default-testCompile execution as we don't want to execute the testCompile goal twice -->
+ <execution>
+ <id>default-testCompile</id>
+ <phase>test-compile</phase>
+ <goals>
+ <goal>testCompile</goal>
+ </goals>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </execution>
+ <execution>
+ <id>error-prone-test-compile</id>
+ <phase>test-compile</phase>
+ <goals>
+ <goal>testCompile</goal>
+ </goals>
+ <configuration>
+ <failOnError>false</failOnError>
+ <source>1.8</source>
+ <target>1.8</target>
+ <compilerArgs combine.children="append">
+ <arg>-Xpkginfo:always</arg>
+ <arg>-XDcompilePolicy=simple</arg>
+ <arg>${error-prone-support.flags}</arg>
+ </compilerArgs>
+ <annotationProcessorPaths>
+ <path>
+ <groupId>com.github.PicnicSupermarket.error-prone</groupId>
+ <artifactId>error_prone_core</artifactId>
+ <version>${errorprone.version}</version>
+ </path>
+ <path>
+ <groupId>tech.picnic.error-prone-support</groupId>
+ <artifactId>error-prone-contrib</artifactId>
+ <version>${error-prone-support.version}</version>
+ </path>
+ <path>
+ <groupId>tech.picnic.error-prone-support</groupId>
+ <artifactId>refaster-runner</artifactId>
+ <version>${error-prone-support.version}</version>
+ </path>
+ </annotationProcessorPaths>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
</build>
</profile>
<profile>
@@ -315,23 +375,13 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
- <source>1.8</source>
- <target>1.8</target>
- <fork>true</fork>
+ <fork>false</fork>
<parameters>true</parameters>
<showWarnings>true</showWarnings>
<compilerArgs>
<arg>-Xlint:all</arg>
<arg>-XDcompilePolicy=simple</arg>
- <arg>-Xplugin:ErrorProne -XepExcludedPaths:.*/target/generated-sources/.*</arg>
</compilerArgs>
- <annotationProcessorPaths>
- <path>
- <groupId>com.google.errorprone</groupId>
- <artifactId>error_prone_core</artifactId>
- <version>${errorprone.version}</version>
- </path>
- </annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
diff --git a/metrics-jakarta-servlets/src/main/java/io/dropwizard/metrics/servlets/MetricsServlet.java b/metrics-jakarta-servlets/src/main/java/io/dropwizard/metrics/servlets/MetricsServlet.java
index a248dd81..64d00eb1 100644
--- a/metrics-jakarta-servlets/src/main/java/io/dropwizard/metrics/servlets/MetricsServlet.java
+++ b/metrics-jakarta-servlets/src/main/java/io/dropwizard/metrics/servlets/MetricsServlet.java
@@ -188,6 +188,7 @@ public class MetricsServlet extends HttpServlet {
return mapper.writer();
}
+ @SuppressWarnings("IdentityConversion")
protected TimeUnit parseTimeUnit(String value, TimeUnit defaultValue) {
try {
return TimeUnit.valueOf(String.valueOf(value).toUpperCase(Locale.US));
diff --git a/metrics-servlets/src/main/java/com/codahale/metrics/servlets/MetricsServlet.java b/metrics-servlets/src/main/java/com/codahale/metrics/servlets/MetricsServlet.java
index 0bd1297d..22fc1c54 100644
--- a/metrics-servlets/src/main/java/com/codahale/metrics/servlets/MetricsServlet.java
+++ b/metrics-servlets/src/main/java/com/codahale/metrics/servlets/MetricsServlet.java
@@ -189,6 +189,7 @@ public class MetricsServlet extends HttpServlet {
return mapper.writer();
}
+ @SuppressWarnings("IdentityConversion")
protected TimeUnit parseTimeUnit(String value, TimeUnit defaultValue) {
try {
return TimeUnit.valueOf(String.valueOf(value).toUpperCase(Locale.US));

104
integration-tests/run-gradle.sh Executable file
View File

@@ -0,0 +1,104 @@
#!/usr/bin/env bash
set -e -u -o pipefail
project=calcite
revision=calcite-1.35.0
if [ "${#}" -gt 1 ] || [[ ${1:---sync} != '--sync' ]]; then
echo "Usage: ${0} [--sync]"
exit 1
fi
do_sync="${1:-}"
error_prone_support_version="$(
mvn -f .. help:evaluate -Dexpression=project.version -q -DforceStdout
)"
error_prone_shared_flags='-XepExcludedPaths:(\Q${project.basedir}${file.separator}src${file.separator}\E(it|test)\Q${file.separator}resources\E|\Q${project.build.directory}${file.separator}\E).*'
error_prone_patch_flags="${error_prone_shared_flags} -XepPatchLocation:IN_PLACE -XepPatchChecks:$(
find .. -path "*/META-INF/services/com.google.errorprone.bugpatterns.BugChecker" \
| xargs grep -hoP '[^.]+$' \
| paste -s -d ','
)"
error_prone_validation_flags="${error_prone_shared_flags} -XepDisableAllChecks $(
find .. -path "*/META-INF/services/com.google.errorprone.bugpatterns.BugChecker" \
| xargs grep -hoP '[^.]+$' \
| sed -r 's,(.*),-Xep:\1:WARN,' \
| paste -s -d ' '
)"
validation_log_file="$(mktemp)"
trap 'rm -rf -- "${validation_log_file}"' INT TERM HUP EXIT
echo "Error Prone Support version: ${error_prone_support_version}"
echo "Error Prone patch flags: ${error_prone_patch_flags}"
echo "Error Prone validation flags: ${error_prone_validation_flags}"
pushd "${project}"
git checkout -f "${revision}"
git apply < "../${project}-${revision}-init.patch"
git commit -m 'dependency: Introduce Error Prone Support' .
# XXX: autostyleApply is only available in calcite, need to find better approach
./gradlew clean autostyleApply --no-build-cache
git commit -m 'minor: Reformat using Google Java Format' .
function apply_patch() {
local current_diff="${1}"
./gradlew clean autostyleApply compileJava -PenableErrorprone \
-Derror-prone.flags="${error_prone_patch_flags}" \
-Derror-prone-support.version="${error_prone_support_version}" \
--no-build-cache
local new_diff="$(git diff | shasum --algorithm 256)"
if [ "${current_diff}" != "${new_diff}" ]; then
apply_patch "${new_diff}"
fi
}
echo "Running patches..."
apply_patch "$(git diff | shasum --algorithm 256)"
baseline_patch="../${project}-${revision}-expected-changes.patch"
if [ -n "${do_sync}" ]; then
echo 'Saving changes...'
git diff > "${baseline_patch}"
else
echo 'Inspecting changes...'
if ! diff -u "${baseline_patch}" <(git diff); then
echo 'There are unexpected changes.'
exit 1
fi
fi
# Validate the results.
#
# - The `metadataFilesGenerationAllFiles` test is skipped because is makes line
# number assertions that will fail when the code is formatted or patched.
# - The `allCheckSectionJavaDocs` test is skipped because is validates that
# Javadoc has certain closing tags that are removed by Google Java Format.
# XXX: Figure out why the `validateCliDocSections` test fails.
./gradlew clean autostyleApply compileJava -PenableErrorprone \
-Derror-prone.flags="${error_prone_patch_flags}" \
-Derror-prone-support.version="${error_prone_support_version}" \
--no-build-cache \
| tee "${validation_log_file}"
baseline_warnings="../${project}-${revision}-expected-warnings.txt"
generated_warnngs="$(grep -oP "(?<=^\\Q[WARNING] ${PWD}/\\E).*" "${validation_log_file}" | grep -P '\]*\[')"
if [ -n "${do_sync}" ]; then
echo 'Saving emitted warnings...'
echo "${generated_warnngs}" > "${baseline_warnings}"
else
echo 'Inspecting emitted warnings...'
if ! diff -u "${baseline_warnings}" <(echo "${generated_warnngs}"); then
echo 'Diagnostics output changed.'
exit 1
fi
fi

109
integration-tests/run.sh Executable file
View File

@@ -0,0 +1,109 @@
#!/usr/bin/env bash
set -e -u -o pipefail
project=checkstyle
revision=checkstyle-10.9.3
if [ "${#}" -gt 1 ] || [[ ${1:---sync} != '--sync' ]]; then
echo "Usage: ${0} [--sync]"
exit 1
fi
do_sync="${1:-}"
error_prone_support_version="$(
mvn -f .. help:evaluate -Dexpression=project.version -q -DforceStdout
)"
error_prone_shared_flags='-XepExcludedPaths:(\Q${project.basedir}${file.separator}src${file.separator}\E(it|test)\Q${file.separator}resources\E|\Q${project.build.directory}${file.separator}\E).*'
error_prone_patch_flags="${error_prone_shared_flags} -XepPatchLocation:IN_PLACE -XepPatchChecks:$(
find .. -path "*/META-INF/services/com.google.errorprone.bugpatterns.BugChecker" \
| xargs grep -hoP '[^.]+$' \
| paste -s -d ','
)"
error_prone_validation_flags="${error_prone_shared_flags} -XepDisableAllChecks $(
find .. -path "*/META-INF/services/com.google.errorprone.bugpatterns.BugChecker" \
| xargs grep -hoP '[^.]+$' \
| sed -r 's,(.*),-Xep:\1:WARN,' \
| paste -s -d ' '
)"
validation_log_file="$(mktemp)"
trap 'rm -rf -- "${validation_log_file}"' INT TERM HUP EXIT
echo "Error Prone Support version: ${error_prone_support_version}"
echo "Error Prone patch flags: ${error_prone_patch_flags}"
echo "Error Prone validation flags: ${error_prone_validation_flags}"
pushd "${project}"
git checkout -f "${revision}"
git apply < "../${project}-${revision}-init.patch"
git commit -m 'dependency: Introduce Error Prone Support' .
mvn com.spotify.fmt:fmt-maven-plugin:2.19:format \
-DadditionalSourceDirectories='${project.basedir}${file.separator}src${file.separator}it${file.separator}java'
git commit -m 'minor: Reformat using Google Java Format' .
function apply_patch() {
local current_diff="${1}"
mvn clean package com.spotify.fmt:fmt-maven-plugin:2.19:format \
-DadditionalSourceDirectories='${project.basedir}${file.separator}src${file.separator}it${file.separator}java' \
-Perror-prone-compile,error-prone-test-compile \
-Derror-prone.flags="${error_prone_patch_flags}" \
-Derror-prone-support.version="${error_prone_support_version}" \
-DskipTests
local new_diff="$(git diff | shasum --algorithm 256)"
if [ "${current_diff}" != "${new_diff}" ]; then
apply_patch "${new_diff}"
fi
}
apply_patch "$(git diff | shasum --algorithm 256)"
baseline_patch="../${project}-${revision}-expected-changes.patch"
if [ -n "${do_sync}" ]; then
echo 'Saving changes...'
git diff > "${baseline_patch}"
else
echo 'Inspecting changes...'
if ! diff -u "${baseline_patch}" <(git diff); then
echo 'There are unexpected changes.'
exit 1
fi
fi
# Validate the results.
#
# - The `metadataFilesGenerationAllFiles` test is skipped because is makes line
# number assertions that will fail when the code is formatted or patched.
# - The `allCheckSectionJavaDocs` test is skipped because is validates that
# Javadoc has certain closing tags that are removed by Google Java Format.
# XXX: Figure out why the `validateCliDocSections` test fails.
echo "Validation file: ${validation_log_file}"
mvn clean package \
-Perror-prone-compile,error-prone-test-compile \
-Derror-prone.flags="${error_prone_validation_flags}" \
-Derror-prone-support.version="${error_prone_support_version}" \
-Dmaven.compiler.showWarnings \
| tee "${validation_log_file}"
echo "Finished validation run!"
baseline_warnings="../${project}-${revision}-expected-warnings.txt"
# note: added '*' in the final grep, required in order to get matches in GNU grep 3.11
generated_warnings="$(grep -oP "(?<=^\\Q[WARNING] ${PWD}/\\E).*" "${validation_log_file}" | grep -P '\]*\[')"
if [ -n "${do_sync}" ]; then
echo 'Saving emitted warnings...'
echo "${generated_warnings}" > "${baseline_warnings}"
else
echo 'Inspecting emitted warnings...'
if ! diff -u "${baseline_warnings}" <(echo "${generated_warnings}"); then
echo 'Diagnostics output changed.'
exit 1
fi
fi

95
pom.xml
View File

@@ -4,7 +4,7 @@
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.13.1-SNAPSHOT</version>
<version>0.14.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Picnic :: Error Prone Support</name>
@@ -141,7 +141,7 @@
<groupId.error-prone>com.google.errorprone</groupId.error-prone>
<!-- The build timestamp is derived from the most recent commit
timestamp in support of reproducible builds. -->
<project.build.outputTimestamp>2023-08-28T16:22:11Z</project.build.outputTimestamp>
<project.build.outputTimestamp>2023-10-04T14:40:37Z</project.build.outputTimestamp>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- Glob pattern identifying Refaster rule definition files. These
Java classes don't contain "regular" code, and thus require special
@@ -198,18 +198,17 @@
one place. We use these to keep dependencies in sync. Version numbers
that need to be referenced only once should *not* be listed here. -->
<version.auto-service>1.1.1</version.auto-service>
<version.auto-value>1.10.3</version.auto-value>
<version.auto-value>1.10.4</version.auto-value>
<version.error-prone>${version.error-prone-orig}</version.error-prone>
<version.error-prone-fork>v${version.error-prone-orig}-picnic-1</version.error-prone-fork>
<!--<version.error-prone-orig>HEAD-SNAPSHOT</version.error-prone-orig>-->
<version.error-prone-orig>2.21.1</version.error-prone-orig>
<version.error-prone-orig>2.22.0</version.error-prone-orig>
<version.error-prone-slf4j>0.1.20</version.error-prone-slf4j>
<version.guava-beta-checker>1.0</version.guava-beta-checker>
<version.jdk>11</version.jdk>
<version.maven>3.8.7</version.maven>
<version.mockito>5.5.0</version.mockito>
<version.mockito>5.6.0</version.mockito>
<version.nopen-checker>1.0.1</version.nopen-checker>
<version.nullaway>0.10.12</version.nullaway>
<version.nullaway>0.10.14</version.nullaway>
<version.pitest-git>1.1.2</version.pitest-git>
<version.surefire>3.1.2</version.surefire>
</properties>
@@ -296,7 +295,7 @@
<dependency>
<groupId>com.google.googlejavaformat</groupId>
<artifactId>google-java-format</artifactId>
<version>1.17.0</version>
<version>1.18.1</version>
</dependency>
<!-- Specified as a workaround for
https://github.com/mojohaus/versions-maven-plugin/issues/244. -->
@@ -324,11 +323,6 @@
<artifactId>nopen-checker</artifactId>
<version>${version.nopen-checker}</version>
</dependency>
<dependency>
<groupId>com.newrelic.agent.java</groupId>
<artifactId>newrelic-api</artifactId>
<version>8.5.0</version>
</dependency>
<!-- Specified as a workaround for
https://github.com/mojohaus/versions-maven-plugin/issues/244. -->
<dependency>
@@ -339,7 +333,7 @@
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-bom</artifactId>
<version>2022.0.10</version>
<version>2022.0.11</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@@ -356,7 +350,7 @@
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
<version>2.2.15</version>
<version>2.2.16</version>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
@@ -388,7 +382,7 @@
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>1.14.7</version>
<version>1.14.9</version>
</dependency>
<!-- Specified so that Renovate will file Maven upgrade PRs, which
subsequently will cause `maven-enforcer-plugin` to require that
@@ -401,7 +395,7 @@
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.20</version>
<version>1.9.20.1</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
@@ -413,7 +407,7 @@
<dependency>
<groupId>org.checkerframework</groupId>
<artifactId>checker-qual</artifactId>
<version>3.37.0</version>
<version>3.39.0</version>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
@@ -423,7 +417,7 @@
<dependency>
<groupId>org.immutables</groupId>
<artifactId>value-annotations</artifactId>
<version>2.9.3</version>
<version>2.10.0</version>
</dependency>
<dependency>
<groupId>org.jspecify</groupId>
@@ -457,27 +451,24 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.7</version>
<artifactId>slf4j-bom</artifactId>
<version>2.0.9</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>5.3.29</version>
<version>5.3.30</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<version>2.7.15</version>
<version>2.7.16</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
@@ -530,7 +521,7 @@
<plugin>
<groupId>com.spotify.fmt</groupId>
<artifactId>fmt-maven-plugin</artifactId>
<version>2.20</version>
<version>2.21.1</version>
<configuration>
<additionalSourceDirectories>
<additionalSourceDirectory>${basedir}/src/test/resources</additionalSourceDirectory>
@@ -542,7 +533,7 @@
<plugin>
<groupId>de.thetaphi</groupId>
<artifactId>forbiddenapis</artifactId>
<version>3.5.1</version>
<version>3.6</version>
<configuration>
<bundledSignatures>
<bundledSignature>jdk-internal</bundledSignature>
@@ -725,13 +716,13 @@
<!-- Instead, please use
`org.jspecify.annotations.Nullable`. -->
</property>
<property name="illegalPkgs" value="autovalue.shaded" />
<property name="illegalPkgs" value="com.amazonaws.annotation" />
<property name="illegalPkgs" value="com.beust.jcommander.internal" />
<property name="illegalPkgs" value="com.google.api.client.repackaged" />
<property name="illegalPkgs" value="com.google.common.cache">
<!-- Instead, please use Caffeine. -->
</property>
<property name="illegalPkgs" value="com.newrelic.agent.deps" />
<property name="illegalPkgs" value="com.tngtech.archunit.thirdparty" />
<property name="illegalPkgs" value="jdk" />
<property name="illegalPkgs" value="jersey.repackaged" />
@@ -858,7 +849,7 @@
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>10.12.3</version>
<version>10.12.4</version>
</dependency>
<dependency>
<groupId>io.spring.nohttp</groupId>
@@ -924,17 +915,16 @@
<artifactId>nullaway</artifactId>
<version>${version.nullaway}</version>
</path>
<path>
<groupId>jp.skypencil.errorprone.slf4j</groupId>
<artifactId>errorprone-slf4j</artifactId>
<version>${version.error-prone-slf4j}</version>
</path>
<path>
<groupId>org.mockito</groupId>
<artifactId>mockito-errorprone</artifactId>
<version>${version.mockito}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<!-- Replace version. -->
<version>1.18.28</version>
</path>
</annotationProcessorPaths>
<compilerArgs>
<arg>--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</arg>
@@ -983,7 +973,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.4.0</version>
<version>3.4.1</version>
<configuration>
<fail>false</fail>
<rules>
@@ -1122,7 +1112,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.5.0</version>
<version>3.6.0</version>
<configuration>
<additionalJOptions>
<additionalJOption>--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</additionalJOption>
@@ -1316,7 +1306,7 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.16.0</version>
<version>2.16.1</version>
<configuration>
<updateBuildOutputTimestampPolicy>never</updateBuildOutputTimestampPolicy>
</configuration>
@@ -1324,7 +1314,7 @@
<plugin>
<groupId>org.gaul</groupId>
<artifactId>modernizer-maven-plugin</artifactId>
<version>2.6.0</version>
<version>2.7.0</version>
<configuration>
<exclusionPatterns>
<!-- The plugin suggests replacing usages of
@@ -1367,7 +1357,7 @@
<plugin>
<groupId>org.pitest</groupId>
<artifactId>pitest-maven</artifactId>
<version>1.14.4</version>
<version>1.15.1</version>
<configuration>
<excludedClasses>
<!-- AutoValue generated classes. -->
@@ -1396,7 +1386,7 @@
<dependency>
<groupId>com.groupcdg.arcmutate</groupId>
<artifactId>base</artifactId>
<version>1.1.3</version>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>com.groupcdg.pitest</groupId>
@@ -1421,7 +1411,7 @@
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>3.9.1.2184</version>
<version>3.10.0.2594</version>
</plugin>
</plugins>
</pluginManagement>
@@ -1434,19 +1424,6 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<!--<plugin>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<version>1.18.20.0</version>
<executions>
<execution>
<goals>
<goal>delombok</goal>
</goals>
<phase>generate-sources</phase>
</execution>
</executions>
</plugin>-->
</plugins>
</build>
@@ -1756,8 +1733,6 @@
false-positives.
-XepOpt:CheckReturnValue:CheckAllMethods=true -->
-XepOpt:InlineMe:SkipInliningsWithComments=false
-XepOpt:NamedLikeContextualKeyword:EnableClassNames=true
-XepOpt:NamedLikeContextualKeyword:EnableMethodNames=true
-XepOpt:NullAway:AnnotatedPackages=tech.picnic
-XepOpt:NullAway:AssertsEnabled=true
-XepOpt:NullAway:CheckOptionalEmptiness=true

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.13.1-SNAPSHOT</version>
<version>0.14.1-SNAPSHOT</version>
</parent>
<artifactId>refaster-compiler</artifactId>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.13.1-SNAPSHOT</version>
<version>0.14.1-SNAPSHOT</version>
</parent>
<artifactId>refaster-runner</artifactId>

View File

@@ -1,6 +1,5 @@
package tech.picnic.errorprone.refaster.runner;
import static com.google.common.base.Predicates.containsPattern;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.errorprone.BugPattern.SeverityLevel.ERROR;
import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION;
@@ -24,35 +23,33 @@ import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
final class RefasterTest {
private final CompilationTestHelper compilationHelper =
CompilationTestHelper.newInstance(Refaster.class, getClass())
.matchAllDiagnostics()
.expectErrorMessage(
"StringOfSizeZeroRule",
containsPattern(
"\\[Refaster Rule\\] FooRules\\.StringOfSizeZeroRule: Refactoring opportunity\\s+.+\\s+"))
.expectErrorMessage(
"StringOfSizeOneRule",
containsPattern(
"\\[Refaster Rule\\] FooRules\\.StringOfSizeOneRule: "
+ "A custom description about matching single-char strings\\s+.+\\s+"
+ "\\(see https://error-prone.picnic.tech/refasterrules/FooRules#StringOfSizeOneRule\\)"))
.expectErrorMessage(
"StringOfSizeTwoRule",
containsPattern(
"\\[Refaster Rule\\] FooRules\\.ExtraGrouping\\.StringOfSizeTwoRule: "
+ "A custom subgroup description\\s+.+\\s+"
+ "\\(see https://example.com/rule/FooRules#ExtraGrouping.StringOfSizeTwoRule\\)"))
.expectErrorMessage(
"StringOfSizeThreeRule",
containsPattern(
"\\[Refaster Rule\\] FooRules\\.ExtraGrouping\\.StringOfSizeThreeRule: "
+ "A custom description about matching three-char strings\\s+.+\\s+"
+ "\\(see https://example.com/custom\\)"));
private static final Pattern DIAGNOSTIC_STRING_OF_SIZE_ZERO =
Pattern.compile(
"\\[Refaster Rule\\] FooRules\\.StringOfSizeZeroRule: Refactoring opportunity\\s+.+\\s+");
private static final Pattern DIAGNOSTIC_STRING_OF_SIZE_ONE =
Pattern.compile(
"\\[Refaster Rule\\] FooRules\\.StringOfSizeOneRule: "
+ "A custom description about matching single-char strings\\s+.+\\s+"
+ "\\(see https://error-prone.picnic.tech/refasterrules/FooRules#StringOfSizeOneRule\\)");
private static final Pattern DIAGNOSTIC_STRING_OF_SIZE_TWO =
Pattern.compile(
"\\[Refaster Rule\\] FooRules\\.ExtraGrouping\\.StringOfSizeTwoRule: "
+ "A custom subgroup description\\s+.+\\s+"
+ "\\(see https://example.com/rule/FooRules#ExtraGrouping.StringOfSizeTwoRule\\)");
private static final Pattern DIAGNOSTIC_STRING_OF_SIZE_THREE =
Pattern.compile(
"\\[Refaster Rule\\] FooRules\\.ExtraGrouping\\.StringOfSizeThreeRule: "
+ "A custom description about matching three-char strings\\s+.+\\s+"
+ "\\(see https://example.com/custom\\)");
@Test
void identification() {
compilationHelper
CompilationTestHelper.newInstance(Refaster.class, getClass())
.matchAllDiagnostics()
.expectErrorMessage("StringOfSizeZeroRule", DIAGNOSTIC_STRING_OF_SIZE_ZERO.asPredicate())
.expectErrorMessage("StringOfSizeOneRule", DIAGNOSTIC_STRING_OF_SIZE_ONE.asPredicate())
.expectErrorMessage("StringOfSizeTwoRule", DIAGNOSTIC_STRING_OF_SIZE_TWO.asPredicate())
.expectErrorMessage("StringOfSizeThreeRule", DIAGNOSTIC_STRING_OF_SIZE_THREE.asPredicate())
.addSourceLines(
"A.java",
"class A {",
@@ -153,7 +150,7 @@ final class RefasterTest {
void severityAssignment(
ImmutableList<String> arguments, ImmutableList<SeverityLevel> expectedSeverities) {
CompilationTestHelper compilationTestHelper =
compilationHelper
CompilationTestHelper.newInstance(Refaster.class, getClass())
.setArgs(arguments)
.addSourceLines(
"A.java",
@@ -167,13 +164,18 @@ final class RefasterTest {
" };",
" }",
"}");
assertThatThrownBy(compilationTestHelper::doTest)
.isInstanceOf(AssertionError.class)
.message()
.satisfies(
message ->
assertThat(extractRefasterSeverities("A.java", message))
.containsExactlyElementsOf(expectedSeverities));
if (expectedSeverities.isEmpty()) {
compilationTestHelper.doTest();
} else {
assertThatThrownBy(compilationTestHelper::doTest)
.isInstanceOf(AssertionError.class)
.message()
.satisfies(
message ->
assertThat(extractRefasterSeverities("A.java", message))
.containsExactlyElementsOf(expectedSeverities));
}
}
private static ImmutableList<SeverityLevel> extractRefasterSeverities(

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.13.1-SNAPSHOT</version>
<version>0.14.1-SNAPSHOT</version>
</parent>
<artifactId>refaster-support</artifactId>

View File

@@ -23,6 +23,7 @@ public @interface OnlineDocumentation {
* the annotated Refaster rule is located.
*/
String TOP_LEVEL_CLASS_URL_PLACEHOLDER = "${topLevelClassName}";
/**
* The URL placeholder value that will be replaced with the name of the nested class in which the
* annotated Refaster rule is located, if applicable.

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.13.1-SNAPSHOT</version>
<version>0.14.1-SNAPSHOT</version>
</parent>
<artifactId>refaster-test-support</artifactId>

View File

@@ -42,7 +42,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Pattern;
import javax.inject.Inject;
import org.jspecify.annotations.Nullable;
@@ -180,7 +179,7 @@ public final class RefasterRuleCollection extends BugChecker implements Compilat
for (Description description : matches) {
String ruleName = extractRefasterRuleName(description);
Set<Replacement> replacements =
ImmutableSet<Replacement> replacements =
Iterables.getOnlyElement(description.fixes).getReplacements(endPositions);
for (Replacement replacement : replacements) {
ruleMatches.put(replacement.range(), ruleName);