Compare commits

...

139 Commits

Author SHA1 Message Date
Rick Ossendrijver
8ba4f872be Add tests and more context in the StringRules file 2024-09-03 16:45:28 +02:00
Rick Ossendrijver
3d5678e20e Introduce comment for the String#copyValueOf rewrite 2024-09-03 16:45:27 +02:00
Stephan Schroevers
c679a3fc0c Improve Optional#orElse{,Get} support (#1283)
Summary of changes:
- Consolidate the `OptionalOrElseGet` Refaster rule and the 
  `OptionalOrElse` bug checker into the latter, keeping the best of
  both.
- Rename the `OptionalOrElse` bug checker to `OptionalOrElseGet` to
  avoid confusion.
- Replace the `IsLikelyTrivialComputation` matcher with the inverse
  `RequiresComputation` variant.
- Introduce an `OptionalOrElse` Refaster rule that simplifies
  expressions in the "opposite direction".
2024-09-03 16:00:33 +02:00
Stephan Schroevers
de54b4bf64 Introduce assorted unsigned int/long Refaster rules (#1291) 2024-09-03 15:35:15 +02:00
Picnic-DevPla-Bot
ea60241782 Upgrade Maven 3.9.8 -> 3.9.9 (#1295)
See:
- https://maven.apache.org/release-notes-all.html
- https://github.com/apache/maven/compare/maven-3.9.8...maven-3.9.9
2024-09-03 15:26:41 +02:00
Picnic-Bot
e4f928addb Upgrade fmt-maven-plugin 2.22.1 -> 2.24 (#1069)
See:
- https://github.com/spotify/fmt-maven-plugin/releases/tag/2.23
- https://github.com/spotify/fmt-maven-plugin/releases/tag/2.24
- https://github.com/spotify/fmt-maven-plugin/compare/2.22.1...2.24
2024-09-03 13:13:18 +02:00
Picnic-DevPla-Bot
059cc9e2db Upgrade Error Prone 2.30.0 -> 2.31.0 (#1314)
See:
- https://github.com/google/error-prone/releases/tag/v2.31.0
- https://github.com/google/error-prone/compare/v2.30.0...v2.31.0
2024-09-03 12:19:04 +02:00
Picnic-DevPla-Bot
1e43c28c95 Upgrade Byte Buddy 1.15.0 -> 1.15.1 (#1316)
See:
- https://github.com/raphw/byte-buddy/releases/tag/byte-buddy-1.15.1
- https://github.com/raphw/byte-buddy/compare/byte-buddy-1.15.0...byte-buddy-1.15.1
2024-09-02 21:10:41 +02:00
Picnic-DevPla-Bot
a07e9b3115 Upgrade Swagger 2.2.22 -> 2.2.23 (#1312)
See:
- https://github.com/swagger-api/swagger-core/releases/tag/v2.2.23
- https://github.com/swagger-api/swagger-core/compare/v2.2.22...v2.2.23
2024-08-29 09:23:09 +02:00
Picnic-DevPla-Bot
aec38d2e33 Upgrade Mockito 5.12.0 -> 5.13.0 (#1309)
See:
- https://github.com/mockito/mockito/releases/tag/v5.13.0
- https://github.com/mockito/mockito/compare/v5.12.0...v5.13.0
2024-08-28 09:32:16 +02:00
Picnic-DevPla-Bot
5b77663288 Upgrade Spring 6.1.11 -> 6.1.12 (#1288)
See:
- https://github.com/spring-projects/spring-framework/releases/tag/v6.1.12
- https://github.com/spring-projects/spring-framework/compare/v6.1.11...v6.1.12
2024-08-27 15:48:14 +02:00
Stephan Schroevers
97c2bbd4b1 Introduce MonoFromFutureAsyncLoadingCacheGet Refaster rule (#1290) 2024-08-26 16:33:57 +02:00
Picnic-DevPla-Bot
9c8fbfd36a Upgrade OpenRewrite Templating 1.13.0 -> 1.14.0 (#1294)
See:
- https://github.com/openrewrite/rewrite-templating/releases/tag/v1.14.0
- https://github.com/openrewrite/rewrite-templating/compare/v1.13.0...v1.14.0
2024-08-26 13:42:53 +02:00
Picnic-DevPla-Bot
38e6c3fdb5 Upgrade OpenRewrite 2.16.0 -> 2.17.0 (#1286)
See:
- https://github.com/openrewrite/rewrite-recipe-bom/releases/tag/v2.17.0
- https://github.com/openrewrite/rewrite-recipe-bom/compare/v2.16.0...v2.17.0
2024-08-26 13:24:42 +02:00
Picnic-DevPla-Bot
5b1d82cfeb Upgrade Guava 33.2.1-jre -> 33.3.0-jre (#1293)
And drop some Refaster rules now covered by `@InlineMe` instructions.

See:
- https://guava.dev/releases/33.3.0-jre/api/diffs/
- https://github.com/google/guava/releases/tag/v33.3.0
- https://github.com/google/guava/compare/v33.2.0...v33.3.0
2024-08-26 13:02:15 +02:00
Picnic-DevPla-Bot
0821a95fcc Upgrade Spring Security 6.3.1 -> 6.3.3 (#1303)
See:
- https://github.com/spring-projects/spring-security/releases/tag/6.3.2
- https://github.com/spring-projects/spring-security/releases/tag/6.3.3
- https://github.com/spring-projects/spring-security/compare/6.3.1...6.3.3
2024-08-26 12:50:25 +02:00
Picnic-DevPla-Bot
f4afe457cb Upgrade Checkstyle 10.17.0 -> 10.18.0 (#1308)
See:
- https://checkstyle.sourceforge.io/releasenotes.html
- https://github.com/checkstyle/checkstyle/releases/tag/checkstyle-10.18.0
- https://github.com/checkstyle/checkstyle/compare/checkstyle-10.17.0...checkstyle-10.18.0
2024-08-26 09:19:52 +02:00
Picnic-DevPla-Bot
fd56ca8b6e Upgrade Spring Boot 3.3.2 -> 3.3.3 (#1305)
See:
- https://github.com/spring-projects/spring-boot/releases/tag/v3.3.3
- https://github.com/spring-projects/spring-boot/compare/v3.3.2...v3.3.3
2024-08-26 09:04:43 +02:00
Picnic-DevPla-Bot
882794d63b Upgrade maven-checkstyle-plugin 3.4.0 -> 3.5.0 (#1307)
See:
- https://issues.apache.org/jira/issues/?jql=project%20%3D%20MCHECKSTYLE%20AND%20fixVersion%20%3E%203.4.0%20AND%20fixVersion%20%3C%3D%203.5.0
- https://github.com/apache/maven-checkstyle-plugin/compare/maven-checkstyle-plugin-3.4.0...maven-checkstyle-plugin-3.5.0
2024-08-26 08:22:34 +02:00
Mohamed Sameh
73ed6e32c7 Introduce Collections{Max,Min,Sort} Refaster rules (#1297)
While there, rename `{Max,Min}OfCollection` to
`Collections{Max,Min}WithComparator`.
2024-08-26 07:38:26 +02:00
Picnic-DevPla-Bot
ca5c3dd3b4 Upgrade Byte Buddy 1.14.19 -> 1.15.0 (#1306)
See:
- https://github.com/raphw/byte-buddy/releases/tag/byte-buddy-1.15.0
- https://github.com/raphw/byte-buddy/compare/byte-buddy-1.14.19...byte-buddy-1.15.0
2024-08-26 07:28:00 +02:00
Picnic-DevPla-Bot
f6e9dbb996 Upgrade Byte Buddy 1.14.18 -> 1.14.19 (#1292)
See:
- https://github.com/raphw/byte-buddy/releases/tag/byte-buddy-1.14.19
- https://github.com/raphw/byte-buddy/compare/byte-buddy-1.14.18...byte-buddy-1.14.19
2024-08-23 19:39:59 +02:00
Picnic-DevPla-Bot
260021c961 Upgrade NullAway 0.11.1 -> 0.11.2 (#1299)
See:
- https://github.com/uber/NullAway/blob/master/CHANGELOG.md
- https://github.com/uber/NullAway/releases/tag/v0.11.2
- https://github.com/uber/NullAway/compare/v0.11.1...v0.11.2
2024-08-23 19:31:03 +02:00
Stephan Schroevers
ec54e79f3e Introduce {Max,Min}Of{Array,Collection} Refaster rules (#1276)
While there, generalize the `{Max,Min}OfVarargs` rules.
2024-08-23 08:47:35 +02:00
Stephan Schroevers
4cbfdba521 Introduce additional File and Path Refaster rules (#1282) 2024-08-22 09:58:09 +02:00
Picnic-DevPla-Bot
d94f65a1f0 Upgrade JUnit 5 5.10.3 -> 5.11.0 (#1289)
See:
- https://junit.org/junit5/docs/current/release-notes/
- https://github.com/junit-team/junit5/releases/tag/r5.11.0-M1
- https://github.com/junit-team/junit5/releases/tag/r5.11.0-M2
- https://github.com/junit-team/junit5/releases/tag/r5.11.0-RC1
- https://github.com/junit-team/junit5/releases/tag/r5.11.0
- https://github.com/junit-team/junit5/compare/r5.10.3...r5.11.0
2024-08-15 09:21:45 +02:00
Picnic-DevPla-Bot
9afdf2ddf3 Upgrade OpenRewrite Templating 1.12.3 -> 1.13.0 (#1287)
See:
- https://github.com/openrewrite/rewrite-templating/releases/tag/v1.13.0
- https://github.com/openrewrite/rewrite-templating/compare/v1.12.3...v1.13.0
2024-08-14 11:35:36 +02:00
Picnic-DevPla-Bot
060c901479 Upgrade maven-gpg-plugin 3.2.4 -> 3.2.5 (#1284)
See:
- https://github.com/apache/maven-gpg-plugin/releases/tag/maven-gpg-plugin-3.2.5
- https://github.com/apache/maven-gpg-plugin/compare/maven-gpg-plugin-3.2.4...maven-gpg-plugin-3.2.5
2024-08-14 08:56:02 +02:00
Picnic-DevPla-Bot
1feee4f64a Upgrade Project Reactor 2023.0.8 -> 2023.0.9 (#1285)
See:
- https://github.com/reactor/reactor/releases/tag/2023.0.9
- https://github.com/reactor/reactor/compare/2023.0.8...2023.0.9
2024-08-14 08:26:16 +02:00
Picnic-Bot
552ddf6a7d Upgrade Maven API 3.9.5 -> 3.9.8 (#701)
See:
- https://maven.apache.org/release-notes-all.html
- https://github.com/apache/maven/releases/tag/maven-3.9.6
- https://github.com/apache/maven/releases/tag/maven-3.9.7
- https://github.com/apache/maven/releases/tag/maven-3.9.8
- https://github.com/apache/maven/compare/maven-3.9.5...maven-3.9.8
2024-08-12 16:14:46 +02:00
Stephan Schroevers
5d92c6c6ce Update Error Prone compatibility matrix (#1281) 2024-08-12 08:28:56 +02:00
Stephan Schroevers
fa8ca80040 [maven-release-plugin] prepare for next development iteration 2024-08-11 15:05:54 +02:00
Stephan Schroevers
b733179cd0 [maven-release-plugin] prepare release v0.18.0 2024-08-11 15:05:54 +02:00
Mohamed Sameh
3d9aab7c5b Introduce Class{Literal,Reference}Cast Refaster rules (#1269) 2024-08-11 15:01:53 +02:00
Picnic-DevPla-Bot
366cdda3d8 Upgrade Error Prone 2.29.2 -> 2.30.0 (#1280)
See:
- https://github.com/google/error-prone/releases/tag/v2.30.0
- https://github.com/google/error-prone/compare/v2.29.2...v2.30.0
- https://github.com/PicnicSupermarket/error-prone/compare/v2.29.2-picnic-1...v2.30.0-picnic-1
2024-08-11 12:48:15 +02:00
Picnic-DevPla-Bot
5b6dd147ef Upgrade MongoDB driver 5.1.2 -> 5.1.3 (#1274)
See:
- https://jira.mongodb.org/issues/?jql=project%20%3D%20JAVA%20AND%20fixVersion%20%3E%204.11.2%20AND%20fixVersion%20%3C%3D%204.11.3
- https://github.com/mongodb/mongo-java-driver/releases/tag/r4.11.3
- https://github.com/mongodb/mongo-java-driver/compare/r4.11.2...r4.11.3
2024-08-11 12:23:58 +02:00
Picnic-DevPla-Bot
a868b03130 Upgrade SLF4J 2.0.15 -> 2.0.16 (#1279)
See:
- https://www.slf4j.org/news.html
- https://github.com/qos-ch/slf4j/compare/v_2.0.15...v_2.0.16
2024-08-11 12:11:31 +02:00
Stephan Schroevers
fdf9bb5d25 Make the build JDK 22-compatible (#1277)
And verify the build with JDK 22.0.2.
2024-08-10 23:13:23 +02:00
Mohamed Sameh
363b0c22c7 Introduce ArraysAsList Refaster rule (#1275) 2024-08-10 16:49:44 +02:00
Picnic-DevPla-Bot
32ec35a354 Upgrade SLF4J 2.0.13 -> 2.0.15 (#1272)
See:
- https://www.slf4j.org/news.html
- https://github.com/qos-ch/slf4j/compare/v_2.0.13...v_2.0.15
2024-08-09 14:37:40 +02:00
Picnic-DevPla-Bot
635fe280f8 Upgrade OpenRewrite Templating 1.12.1 -> 1.12.3 (#1273)
See:
- https://github.com/openrewrite/rewrite-templating/releases/tag/v1.12.2
- https://github.com/openrewrite/rewrite-templating/releases/tag/v1.12.3
- https://github.com/openrewrite/rewrite-templating/compare/v1.12.1...v1.12.3
2024-08-09 09:49:34 +02:00
Stephan Schroevers
aac9b6bf10 Package OpenRewrite recipes in separate JAR, targeting Java 8 (#1270)
This is a prerequisite for openrewrite/rewrite-third-party#11. The new JAR has
classifier `recipes`.
2024-08-07 23:21:35 +02:00
Rick Ossendrijver
c322ea1bbc Introduce generic run-integration-test.sh script (#1141)
This new script contains reusable logic extracted from
`integration-tests/checkstyle.sh`, facilitating the introduction of additional
integration tests.
2024-08-07 23:12:55 +02:00
Stephan Schroevers
a433a90673 Introduce FilesCreateTempFileToFile Refaster rule (#1162) 2024-08-07 15:41:45 +02:00
Picnic-DevPla-Bot
5a37d65632 Upgrade Checker Framework Annotations 3.45.0 -> 3.46.0 (#1268)
See:
- https://github.com/typetools/checker-framework/releases/tag/checker-framework-3.46.0
- https://github.com/typetools/checker-framework/compare/checker-framework-3.45.0...checker-framework-3.46.0
2024-08-07 11:46:32 +02:00
Rick Ossendrijver
77d183f8fd Introduce FluxFromStreamSupplier Refaster rule (#1261) 2024-08-07 10:44:41 +02:00
Picnic-DevPla-Bot
2eb4e853c5 Upgrade OpenRewrite Templating 1.12.0 -> 1.12.1 (#1265)
See:
- https://github.com/openrewrite/rewrite-templating/releases/tag/v1.12.1
- https://github.com/openrewrite/rewrite-templating/compare/v1.12.0...v1.12.1
2024-08-06 16:34:53 +02:00
Picnic-DevPla-Bot
45a7242cf5 Upgrade OpenRewrite 2.15.0 -> 2.16.0 (#1266)
See:
- https://github.com/openrewrite/rewrite-recipe-bom/releases/tag/v2.16.0
- https://github.com/openrewrite/rewrite-recipe-bom/compare/v2.15.0...v2.16.0
2024-08-06 16:17:43 +02:00
Picnic-DevPla-Bot
c85070ba23 Upgrade org.hamcrest:hamcrest-core 2.2 -> 3.0 (#1267)
See:
- https://github.com/hamcrest/JavaHamcrest/releases/tag/v3.0-rc1
- https://github.com/hamcrest/JavaHamcrest/releases/tag/v3.0
- https://github.com/hamcrest/JavaHamcrest/compare/v2.2...v3.0
2024-08-06 14:34:47 +02:00
Mohamed Sameh
a687f09bf0 Introduce SetStream Refaster rule (#1264) 2024-08-06 14:05:53 +02:00
Picnic-DevPla-Bot
2e4fdcb0db Upgrade maven-javadoc-plugin 3.7.0 -> 3.8.0 (#1259)
See:
- https://issues.apache.org/jira/issues/?jql=project%20%3D%20MJAVADOC%20AND%20fixVersion%20%3E%203.7.0%20AND%20fixVersion%20%3C%3D%203.8.0
- https://github.com/apache/maven-javadoc-plugin/releases/tag/maven-javadoc-plugin-3.8.0
- https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.7.0...maven-javadoc-plugin-3.8.0
2024-08-06 08:53:06 +02:00
Stephan Schroevers
1005d93b7e Update step-security/harden-runner configuration (#1271)
While apparently the build doesn't fail without this, it is reasonable
for SonarCloud analysis to access the two additional domains.

While there, introduce subdomain wildcards for `sigstore.dev` and
`sonarcloud.io`.
2024-08-05 09:31:25 +02:00
Picnic-DevPla-Bot
136123f6b4 Upgrade NullAway 0.11.0 -> 0.11.1 (#1262)
See:
- https://github.com/uber/NullAway/blob/master/CHANGELOG.md
- https://github.com/uber/NullAway/releases/tag/v0.11.1
- https://github.com/uber/NullAway/compare/v0.11.0...v0.11.1
2024-08-05 09:03:14 +02:00
Picnic-DevPla-Bot
4cb5f0079d Upgrade Google Java Format 1.22.0 -> 1.23.0 (#1263)
See:
- https://github.com/google/google-java-format/releases/tag/v1.23.0
- https://github.com/google/google-java-format/compare/v1.22.0...v1.23.0
2024-08-05 08:15:16 +02:00
Stephan Schroevers
290ddf1972 [maven-release-plugin] prepare for next development iteration 2024-07-20 14:15:44 +02:00
Stephan Schroevers
5a163ce2e9 [maven-release-plugin] prepare release v0.17.0 2024-07-20 14:15:43 +02:00
Picnic-DevPla-Bot
4eb0aae452 Upgrade versions-maven-plugin 2.17.0 -> 2.17.1 (#1250)
See:
- https://github.com/mojohaus/versions/releases/tag/2.17.1
- https://github.com/mojohaus/versions-maven-plugin/compare/2.17.0...2.17.1
2024-07-20 14:09:49 +02:00
Picnic-DevPla-Bot
b5b98d899b Upgrade OpenRewrite Templating 1.11.2 -> 1.12.0 (#1252)
See:
- https://github.com/openrewrite/rewrite-templating/releases/tag/v1.12.0
- https://github.com/openrewrite/rewrite-templating/compare/v1.11.2...v1.12.0
2024-07-20 14:00:07 +02:00
Picnic-DevPla-Bot
bbf3d79d9a Upgrade Error Prone 2.29.1 -> 2.29.2 (#1258)
See:
- https://github.com/google/error-prone/releases/tag/v2.29.2
- https://github.com/google/error-prone/compare/v2.29.1...v2.29.2
- https://github.com/PicnicSupermarket/error-prone/compare/v2.29.1-picnic-1...v2.29.2-picnic-1
2024-07-20 13:52:09 +02:00
Picnic-DevPla-Bot
1164270589 Upgrade OpenRewrite 2.14.0 -> 2.15.0 (#1251)
See:
- https://github.com/openrewrite/rewrite-recipe-bom/releases/tag/v2.15.0
- https://github.com/openrewrite/rewrite-recipe-bom/compare/v2.14.0...v2.15.0
2024-07-20 13:39:50 +02:00
Picnic-DevPla-Bot
f03d72388a Upgrade JSpecify 0.3.0 -> 1.0.0 (#1256)
See:
- https://github.com/jspecify/jspecify/releases/tag/v1.0.0
- https://github.com/jspecify/jspecify/compare/v0.3.0...v1.0.0
2024-07-20 13:08:33 +02:00
tijana-ninkovic
2e5d1f1e87 Extend FluxJust Refaster rule (#1253) 2024-07-20 12:57:45 +02:00
Vincent Koeman
4b1c892f04 Introduce MonoFromFutureSupplier{,Boolean} Refaster rules (#1244) 2024-07-20 12:44:37 +02:00
Picnic-DevPla-Bot
2b6b8de150 Upgrade Spring Boot 3.3.1 -> 3.3.2 (#1257)
See:
- https://github.com/spring-projects/spring-boot/releases/tag/v3.3.2
- https://github.com/spring-projects/spring-boot/compare/v3.3.1...v3.3.2
2024-07-20 00:10:21 +02:00
Picnic-DevPla-Bot
b275a33eb8 Upgrade Error Prone 2.28.0 -> 2.29.1 (#1255)
See:
- https://github.com/google/error-prone/releases/tag/v2.29.0
- https://github.com/google/error-prone/releases/tag/v2.29.1
- https://github.com/google/error-prone/compare/v2.28.0...v2.29.1
- https://github.com/PicnicSupermarket/error-prone/compare/v2.28.0-picnic-1...v2.29.1-picnic-1
2024-07-19 23:57:01 +02:00
Picnic-DevPla-Bot
7a9aeca248 Upgrade AssertJ 3.26.0 -> 3.26.3 (#1254)
See:
- https://github.com/assertj/assertj/releases/tag/assertj-build-3.26.3
- https://github.com/assertj/assertj/compare/assertj-build-3.26.0...assertj-build-3.26.3
2024-07-18 09:59:17 +02:00
Picnic-DevPla-Bot
bd5cdefea9 Upgrade maven-release-plugin 3.1.0 -> 3.1.1 (#1249)
See:
- https://github.com/apache/maven-release/releases/tag/maven-release-3.1.1
- https://github.com/apache/maven-release/compare/maven-release-3.1.0...maven-release-3.1.1
2024-07-18 07:37:50 +02:00
Picnic-Bot
a265a450f9 Upgrade AssertJ 3.25.3 -> 3.26.0 (#1197)
See:
- https://github.com/assertj/assertj/releases/tag/assertj-build-3.26.0
- https://github.com/assertj/assertj/compare/assertj-build-3.25.3...assertj-build-3.26.0
2024-07-17 16:14:56 +02:00
Stephan Schroevers
5fbb0636aa Suppress new SonarCloud warning (#1248) 2024-07-15 09:53:49 +02:00
Picnic-DevPla-Bot
6eb22da201 Upgrade MongoDB driver 5.1.1 -> 5.1.2 (#1241)
See:
- https://github.com/mongodb/mongo-java-driver/releases/tag/r5.1.2
- https://github.com/mongodb/mongo-java-driver/compare/r5.1.1...r5.1.2
2024-07-15 08:29:54 +02:00
Picnic-DevPla-Bot
781b4d0c57 Upgrade Truth 1.4.3 -> 1.4.4 (#1247)
See:
- https://github.com/google/truth/releases/tag/v1.4.4
- https://github.com/google/truth/compare/v1.4.3...v1.4.4
2024-07-15 07:34:33 +02:00
Picnic-DevPla-Bot
5234fca96d Upgrade Spring 6.1.10 -> 6.1.11 (#1245)
See:
- https://github.com/spring-projects/spring-framework/releases/tag/v6.1.11
- https://github.com/spring-projects/spring-framework/compare/v6.1.10...v6.1.11
2024-07-14 15:01:43 +02:00
Stephan Schroevers
8daedccaea Update step-security/harden-runner configuration (#1246)
While apparently the build doesn't fail without this, it is reasonable
for SonarCloud analysis to access the `api.sonarcloud.io` domain.
2024-07-14 14:11:41 +02:00
Mohamed Sameh
886e65d7ac Introduce EnumReferenceEqualityLambda Refaster rule (#1239) 2024-07-14 14:00:18 +02:00
Picnic-DevPla-Bot
ec502cef20 Upgrade Surefire 3.3.0 -> 3.3.1 (#1243)
See:
- https://github.com/apache/maven-surefire/releases/tag/surefire-3.3.1
- https://github.com/apache/maven-surefire/compare/surefire-3.3.0...surefire-3.3.1
2024-07-11 15:59:36 +02:00
Picnic-DevPla-Bot
f3ff515271 Upgrade Project Reactor 2023.0.7 -> 2023.0.8 (#1242)
See:
- https://github.com/reactor/reactor/releases/tag/2023.0.8
- https://github.com/reactor/reactor/compare/2023.0.7...2023.0.8
2024-07-11 10:25:38 +02:00
Picnic-DevPla-Bot
d662eb1cbc Upgrade git-commit-id-maven-plugin 9.0.0 -> 9.0.1 (#1235)
See:
- https://github.com/git-commit-id/git-commit-id-maven-plugin/releases/tag/v9.0.1
- https://github.com/git-commit-id/git-commit-id-maven-plugin/compare/v9.0.0...v9.0.1
2024-07-10 10:08:46 +02:00
Picnic-DevPla-Bot
c40b73186b Upgrade OpenRewrite 2.13.2 -> 2.14.0 (#1236)
See:
- https://github.com/openrewrite/rewrite-recipe-bom/releases/tag/v2.14.0
- https://github.com/openrewrite/rewrite-recipe-bom/compare/v2.13.2...v2.14.0See:
- https://github.com/openrewrite/rewrite-recipe-bom/releases/tag/v2.14.0
2024-07-09 11:20:17 +02:00
Picnic-DevPla-Bot
6734af6742 Upgrade Jackson 2.17.1 -> 2.17.2 (#1238)
See:
- https://github.com/FasterXML/jackson/wiki/Jackson-Release-2.17.2
- https://github.com/FasterXML/jackson-bom/compare/jackson-bom-2.17.1...jackson-bom-2.17.2
2024-07-09 10:54:57 +02:00
Picnic-DevPla-Bot
c5ec2a552d Upgrade OpenRewrite Templating 1.11.1 -> 1.11.2 (#1234)
See:
- https://github.com/openrewrite/rewrite-templating/releases/tag/v1.11.2
- https://github.com/openrewrite/rewrite-templating/compare/v1.11.1...v1.11.2
2024-07-09 10:37:50 +02:00
Picnic-DevPla-Bot
a3e3a32332 Upgrade Byte Buddy 1.14.17 -> 1.14.18 (#1240)
See:
- https://github.com/raphw/byte-buddy/releases/tag/byte-buddy-1.14.18
- https://github.com/raphw/byte-buddy/compare/byte-buddy-1.14.17...byte-buddy-1.14.18
2024-07-09 08:38:51 +02:00
Picnic-DevPla-Bot
8c3756c4f7 Upgrade versions-maven-plugin 2.16.2 -> 2.17.0 (#1232)
See:
- https://github.com/mojohaus/versions/releases/tag/2.17.0
- https://github.com/mojohaus/versions-maven-plugin/compare/2.16.2...2.17.0
2024-07-03 08:59:39 +02:00
Picnic-DevPla-Bot
c472225f9c Upgrade Checker Framework Annotations 3.44.0 -> 3.45.0 (#1233)
See:
- https://github.com/typetools/checker-framework/releases/tag/checker-framework-3.45.0
- https://github.com/typetools/checker-framework/compare/checker-framework-3.44.0...checker-framework-3.45.0
2024-07-03 08:45:02 +02:00
Picnic-DevPla-Bot
7a8538a87a Upgrade Truth 1.4.2 -> 1.4.3 (#1230)
See:
- https://github.com/google/truth/releases/tag/v1.4.3
- https://github.com/google/truth/compare/v1.4.2...v1.4.3
2024-07-02 15:36:18 +02:00
Picnic-DevPla-Bot
dba37a3f23 Upgrade JUnit 5 5.10.2 -> 5.10.3 (#1231)
See:
- https://junit.org/junit5/docs/current/release-notes/
- https://github.com/junit-team/junit5/releases/tag/r5.10.3
- https://github.com/junit-team/junit5/compare/r5.10.2...r5.10.3
2024-07-01 14:35:22 +02:00
Picnic-DevPla-Bot
e89cfe0aef Upgrade Error Prone 2.27.1 -> 2.28.0 (#1200)
See:
- https://github.com/google/error-prone/releases/tag/v2.28.0
- https://github.com/google/error-prone/compare/v2.27.1...v2.28.0
- https://github.com/PicnicSupermarket/error-prone/compare/v2.27.1-picnic-1...v2.28.0-picnic-1
2024-06-30 11:55:32 +02:00
Picnic-DevPla-Bot
9c1993e5a7 Upgrade maven-jar-plugin 3.4.1 -> 3.4.2 (#1224)
See:
- https://github.com/apache/maven-jar-plugin/releases/tag/maven-jar-plugin-3.4.2
- https://github.com/apache/maven-jar-plugin/compare/maven-jar-plugin-3.4.1...maven-jar-plugin-3.4.2
2024-06-28 10:18:53 +02:00
Picnic-DevPla-Bot
d586014379 Upgrade Spring Boot 3.3.0 -> 3.3.1 (#1228)
See:
- https://github.com/spring-projects/spring-boot/releases/tag/v3.3.1
- https://github.com/spring-projects/spring-boot/compare/v3.3.0...v3.3.1
2024-06-27 09:23:36 +02:00
Picnic-DevPla-Bot
3a441487a3 Upgrade Spring 6.1.8 -> 6.1.10 (#1219)
See:
- https://github.com/spring-projects/spring-framework/releases/tag/v6.1.9
- https://github.com/spring-projects/spring-framework/releases/tag/v6.1.10
- https://github.com/spring-projects/spring-framework/compare/v6.1.8...v6.1.10
2024-06-26 11:14:09 +02:00
Picnic-DevPla-Bot
6f6a4c481e Upgrade Project Reactor 2023.0.6 -> 2023.0.7 (#1215)
See:
- https://github.com/reactor/reactor/releases/tag/2023.0.7
- https://github.com/reactor/reactor/compare/2023.0.6...2023.0.7
2024-06-26 10:57:35 +02:00
Picnic-DevPla-Bot
56f0cc81c9 Upgrade OpenRewrite 2.12.0 -> 2.13.2 (#1225)
See:
- https://github.com/openrewrite/rewrite-recipe-bom/releases/tag/v2.13.0
- https://github.com/openrewrite/rewrite-recipe-bom/releases/tag/v2.13.1
- https://github.com/openrewrite/rewrite-recipe-bom/releases/tag/v2.13.2
- https://github.com/openrewrite/rewrite-recipe-bom/compare/v2.12.0...v2.13.2
2024-06-26 10:34:42 +02:00
Picnic-DevPla-Bot
6c58d4cc01 Upgrade maven-clean-plugin 3.3.2 -> 3.4.0 (#1227)
See:
- https://github.com/apache/maven-clean-plugin/releases/tag/maven-clean-plugin-3.4.0
- https://github.com/apache/maven-clean-plugin/compare/maven-clean-plugin-3.3.2...maven-clean-plugin-3.4.0
2024-06-26 10:21:42 +02:00
Picnic-DevPla-Bot
a1e47542e7 Upgrade Surefire 3.2.5 -> 3.3.0 (#1220)
See:
- https://github.com/apache/maven-surefire/releases/tag/surefire-3.3.0
- https://github.com/apache/maven-surefire/compare/surefire-3.2.5...surefire-3.3.0
2024-06-26 09:44:47 +02:00
Picnic-DevPla-Bot
eff958d4c1 Upgrade OpenRewrite Templating 1.10.0 -> 1.11.1 (#1226)
See:
- https://github.com/openrewrite/rewrite-templating/releases/tag/v1.11.1
- https://github.com/openrewrite/rewrite-templating/releases/tag/v1.11.0
2024-06-26 08:42:22 +02:00
Picnic-DevPla-Bot
81704c6534 Upgrade maven-dependency-plugin 3.7.0 -> 3.7.1 (#1229)
See:
- https://github.com/apache/maven-dependency-plugin/releases/tag/maven-dependency-plugin-3.7.1
- https://github.com/apache/maven-dependency-plugin/compare/maven-dependency-plugin-3.7.0...maven-dependency-plugin-3.7.1
2024-06-25 16:31:46 +02:00
Picnic-DevPla-Bot
1e229949fc Upgrade Jakarta Servlet 6.0.0 -> 6.1.0 (#1216)
See:
- https://github.com/eclipse-ee4j/servlet-api/compare/6.0.0-RELEASE...6.1.0-RELEASE
2024-06-18 11:04:56 +02:00
Picnic-DevPla-Bot
28a93e949e Upgrade maven-dependency-plugin 3.6.1 -> 3.7.0 (#1217)
See:
- https://github.com/apache/maven-dependency-plugin/releases/tag/maven-dependency-plugin-3.7.0
- https://github.com/apache/maven-dependency-plugin/compare/maven-dependency-plugin-3.6.1...maven-dependency-plugin-3.7.0
2024-06-18 09:11:59 +02:00
Picnic-DevPla-Bot
40ad38bc2a Upgrade maven-release-plugin 3.0.1 -> 3.1.0 (#1221)
See:
- https://github.com/apache/maven-release/releases/tag/maven-release-3.1.0
- https://github.com/apache/maven-release/compare/maven-release-3.0.1...maven-release-3.1.0
2024-06-18 09:02:56 +02:00
Picnic-DevPla-Bot
e125c6b7e2 Upgrade Spring Security 6.3.0 -> 6.3.1 (#1222)
See:
- https://github.com/spring-projects/spring-security/releases/tag/6.3.1
- https://github.com/spring-projects/spring-security/compare/6.3.0...6.3.1
2024-06-18 08:36:10 +02:00
Picnic-DevPla-Bot
5596c4530d Upgrade MongoDB driver 5.1.0 -> 5.1.1 (#1218)
See:
- https://jira.mongodb.org/issues/?jql=project%20%3D%20JAVA%20AND%20fixVersion%20%3E%205.1.0%20AND%20fixVersion%20%3C%3D%205.1.1
- https://github.com/mongodb/mongo-java-driver/releases/tag/r5.1.1
- https://github.com/mongodb/mongo-java-driver/compare/r5.1.0...r5.1.1
2024-06-17 14:03:25 +02:00
Stephan Schroevers
d81fe19836 Extend FluxConcatMap Refaster rule (#1213) 2024-06-10 15:34:16 +02:00
Picnic-DevPla-Bot
d6838ec947 Upgrade errorprone-slf4j 0.1.24 -> 0.1.25 (#1212)
See:
- https://github.com/KengoTODA/errorprone-slf4j/releases/tag/v0.1.25
- https://github.com/KengoTODA/errorprone-slf4j/compare/v0.1.24...v0.1.25
2024-06-10 09:13:54 +02:00
Picnic-DevPla-Bot
b36a69aa5f Upgrade git-commit-id-maven-plugin 8.0.2 -> 9.0.0 (#1211)
See:
- https://github.com/git-commit-id/git-commit-id-maven-plugin/releases/tag/v9.0.0
- https://github.com/git-commit-id/git-commit-id-maven-plugin/compare/v8.0.2...v9.0.0
2024-06-10 08:32:32 +02:00
Picnic-DevPla-Bot
831b757bb1 Upgrade OpenRewrite Templating 1.9.2 -> 1.10.0 (#1210)
See:
- https://github.com/openrewrite/rewrite-templating/releases/tag/v1.10.0
- https://github.com/openrewrite/rewrite-templating/compare/v1.9.2...v1.10.0
2024-06-08 23:23:26 +02:00
Picnic-DevPla-Bot
527fc5785b Upgrade OpenRewrite 2.11.1 -> 2.12.0 (#1209)
See:
- https://github.com/openrewrite/rewrite-recipe-bom/releases/tag/v2.12.0
- https://github.com/openrewrite/rewrite-recipe-bom/compare/v2.11.1...v2.12.0
2024-06-08 12:18:41 +02:00
Picnic-DevPla-Bot
8c8055d381 Upgrade maven-checkstyle-plugin 3.3.1 -> 3.4.0 (#1208)
See https://github.com/apache/maven-checkstyle-plugin/compare/maven-checkstyle-plugin-3.3.1...maven-checkstyle-plugin-3.4.0
2024-06-07 11:08:31 +02:00
Picnic-Bot
b658c19c03 Upgrade Spring Boot 3.2.5 -> 3.3.0 (#1196)
See:
- https://github.com/spring-projects/spring-boot/releases/tag/v3.2.6
- https://github.com/spring-projects/spring-boot/releases/tag/v3.3.0-M1
- https://github.com/spring-projects/spring-boot/releases/tag/v3.3.0-M2
- https://github.com/spring-projects/spring-boot/releases/tag/v3.3.0-M3
- https://github.com/spring-projects/spring-boot/releases/tag/v3.3.0-RC1
- https://github.com/spring-projects/spring-boot/releases/tag/v3.3.0
- https://github.com/spring-projects/spring-boot/compare/v3.2.5...v3.3.0
2024-06-05 09:42:42 +02:00
Picnic-DevPla-Bot
85976e199f Upgrade Checker Framework Annotations 3.43.0 -> 3.44.0 (#1207)
See:
- https://github.com/typetools/checker-framework/releases/tag/checker-framework-3.44.0
- https://github.com/typetools/checker-framework/compare/checker-framework-3.43.0...checker-framework-3.44.0
2024-06-05 09:20:12 +02:00
Picnic-DevPla-Bot
f6a392e118 Upgrade Guava 33.2.0-jre -> 33.2.1-jre (#1202)
See:
- https://guava.dev/releases/33.2.1-jre/api/diffs/
- https://github.com/google/guava/releases/tag/v33.2.1
- https://github.com/google/guava/compare/v33.2.0...v33.2.1
2024-06-04 16:39:05 +02:00
Picnic-DevPla-Bot
539fcae745 Upgrade maven-javadoc-plugin 3.6.3 -> 3.7.0 (#1205)
See:
- https://issues.apache.org/jira/issues/?jql=project%20%3D%20MJAVADOC%20AND%20fixVersion%20%3E%203.6.3%20AND%20fixVersion%20%3C%3D%203.7.0
- https://github.com/apache/maven-javadoc-plugin/releases/tag/maven-javadoc-plugin-3.7.0
- https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.6.3...maven-javadoc-plugin-3.7.0
2024-06-04 14:47:57 +02:00
Picnic-DevPla-Bot
29f1a3d2a6 Upgrade maven-enforcer-plugin 3.4.1 -> 3.5.0 (#1201)
See:
- https://github.com/apache/maven-enforcer/releases/tag/enforcer-3.5.0
- https://github.com/apache/maven-enforcer/compare/enforcer-3.4.1...enforcer-3.5.0
2024-06-04 13:56:07 +02:00
Picnic-DevPla-Bot
01f139b6a4 Upgrade NullAway 0.10.26 -> 0.11.0 (#1204)
See:
- https://github.com/uber/NullAway/blob/master/CHANGELOG.md
- https://github.com/uber/NullAway/releases/tag/v0.11.0
- https://github.com/uber/NullAway/compare/v0.10.26...v0.11.0
2024-06-04 13:37:52 +02:00
Picnic-DevPla-Bot
c61980721e Upgrade AutoValue 1.10.4 -> 1.11.0 (#1203)
See:
- https://github.com/google/auto/releases/tag/auto-value-1.11.0
- https://github.com/google/auto/compare/auto-value-1.10.4...auto-value-1.11.0
2024-06-04 13:06:01 +02:00
Picnic-DevPla-Bot
471a1ebff1 Upgrade Byte Buddy 1.14.16 -> 1.14.17 (#1199)
See:
- https://github.com/raphw/byte-buddy/releases/tag/byte-buddy-1.14.17
- https://github.com/raphw/byte-buddy/compare/byte-buddy-1.14.16...byte-buddy-1.14.17
2024-06-04 07:55:19 +02:00
Picnic-DevPla-Bot
b8d9ff0971 Upgrade sonar-maven-plugin 3.11.0.3922 -> 4.0.0.4121 (#1206)
See:
- https://github.com/SonarSource/sonar-scanner-maven/releases/tag/4.0.0.4121
- https://github.com/SonarSource/sonar-scanner-maven/compare/3.11.0.3922...4.0.0.4121
2024-06-04 07:37:39 +02:00
Picnic-Bot
e02d836c12 Upgrade Modernizer Maven Plugin 2.8.0 -> 2.9.0 (#1195)
See:
- https://github.com/gaul/modernizer-maven-plugin/releases/tag/modernizer-maven-plugin-2.9.0
- https://github.com/gaul/modernizer-maven-plugin/compare/modernizer-maven-plugin-2.8.0...modernizer-maven-plugin-2.9.0
2024-05-27 16:09:23 +02:00
Picnic-Bot
abd47eb269 Upgrade Checkstyle 10.16.0 -> 10.17.0 (#1198)
See:
- https://checkstyle.sourceforge.io/releasenotes.html
- https://github.com/checkstyle/checkstyle/releases/tag/checkstyle-10.17.0
- https://github.com/checkstyle/checkstyle/compare/checkstyle-10.16.0...checkstyle-10.17.0
2024-05-27 14:42:20 +02:00
Stephan Schroevers
5219fd8f6c Allow OpenSSF Scorecard analysis to access api.scorecard.dev (#1193) 2024-05-25 19:02:02 +02:00
Picnic-Bot
588fc38f81 Upgrade OpenRewrite 2.11.0 -> 2.11.1 (#1190)
See:
- https://github.com/openrewrite/rewrite-recipe-bom/releases/tag/v2.11.1
- https://github.com/openrewrite/rewrite-recipe-bom/compare/v2.11.0...v2.11.1
2024-05-24 13:49:50 +02:00
Picnic-Bot
e3aa8a5d12 Upgrade OpenRewrite Templating 1.9.0 -> 1.9.2 (#1191)
See:
- https://github.com/openrewrite/rewrite-templating/releases/tag/v1.9.1
- https://github.com/openrewrite/rewrite-templating/releases/tag/v1.9.2
- https://github.com/openrewrite/rewrite-templating/compare/v1.9.0...v1.9.2
2024-05-24 13:31:25 +02:00
Picnic-Bot
3255c0b6eb Upgrade Spring 6.1.7 -> 6.1.8 (#1192)
See:
- https://github.com/spring-projects/spring-framework/releases/tag/v6.1.8
- https://github.com/spring-projects/spring-framework/compare/v6.1.7...v6.1.8
2024-05-24 13:21:50 +02:00
Picnic-Bot
d2dbd88f25 Upgrade Byte Buddy 1.14.15 -> 1.14.16 (#1189)
See:
- https://github.com/raphw/byte-buddy/releases/tag/byte-buddy-1.14.16
- https://github.com/raphw/byte-buddy/compare/byte-buddy-1.14.15...byte-buddy-1.14.16
2024-05-24 11:41:07 +02:00
Picnic-Bot
ff824cfa20 Upgrade Spring Security 6.2.4 -> 6.3.0 (#1186)
See:
- https://github.com/spring-projects/spring-security/releases/tag/6.3.0-M1
- https://github.com/spring-projects/spring-security/releases/tag/6.3.0-M2
- https://github.com/spring-projects/spring-security/releases/tag/6.3.0-M3
- https://github.com/spring-projects/spring-security/releases/tag/6.3.0-RC1
- https://github.com/spring-projects/spring-security/releases/tag/6.3.0
- https://github.com/spring-projects/spring-security/compare/6.2.4...6.3.0
2024-05-23 16:39:20 +02:00
Picnic-Bot
43303e770a Upgrade actions/checkout v4.1.4 -> v4.1.6 (#1184)
See:
- https://github.com/actions/checkout/blob/HEAD/CHANGELOG.md#v416
- https://github.com/actions/checkout/blob/HEAD/CHANGELOG.md#v415
2024-05-23 10:36:32 +02:00
Picnic-Bot
cfadbca32a Upgrade ossf/scorecard-action v2.3.1 -> v2.3.3 (#1185)
See:
- https://github.com/ossf/scorecard-action/releases/tag/v2.3.3
- https://github.com/ossf/scorecard-action/compare/v2.3.1...v2.3.2
2024-05-23 09:05:16 +02:00
Picnic-Bot
e7ca4a5325 Upgrade s4u/setup-maven-action v1.12.0 -> v1.13.0 (#1187)
See:
- https://github.com/s4u/setup-maven-action/releases/tag/v1.13.0
2024-05-22 10:23:23 +02:00
Picnic-Bot
7bab1eb7fd Upgrade step-security/harden-runner v2.7.1 -> v2.8.0 (#1188)
See:
- https://github.com/step-security/harden-runner/releases/tag/v2.8.0
2024-05-22 08:36:34 +02:00
Picnic-DevPla-Bot
072e39da32 Upgrade build-helper-maven-plugin 3.5.0 -> 3.6.0 (#1182)
See:
- https://github.com/mojohaus/build-helper-maven-plugin/releases/tag/3.6.0
- https://github.com/mojohaus/build-helper-maven-plugin/compare/3.5.0...3.6.0
2024-05-21 09:49:09 +02:00
Picnic-DevPla-Bot
ec7e84ac45 Upgrade Swagger 2.2.21 -> 2.2.22 (#1178)
See:
- https://github.com/swagger-api/swagger-core/releases/tag/v2.2.22
- https://github.com/swagger-api/swagger-core/compare/v2.2.21...v2.2.22
2024-05-21 09:39:03 +02:00
Picnic-DevPla-Bot
4228a63ad1 Upgrade Project Reactor 2023.0.5 -> 2023.0.6 (#1176)
See:
- https://github.com/reactor/reactor/releases/tag/2023.0.6
- https://github.com/reactor/reactor/compare/2023.0.5...2023.0.6
2024-05-21 09:16:03 +02:00
Picnic-DevPla-Bot
6093e6f322 Upgrade OpenRewrite Templating 1.8.1 -> 1.9.0 (#1181)
See:
- https://github.com/openrewrite/rewrite-templating/releases/tag/v1.9.0
- https://github.com/openrewrite/rewrite-templating/compare/v1.8.1...v1.9.0
2024-05-21 09:06:51 +02:00
Picnic-DevPla-Bot
ee103a99f6 Upgrade Spring 6.1.6 -> 6.1.7 (#1180)
See:
- https://github.com/spring-projects/spring-framework/releases/tag/v6.1.7
- https://github.com/spring-projects/spring-framework/compare/v6.1.6...v6.1.7
2024-05-21 08:58:01 +02:00
Pieter Dirk Soels
c34065beab Improve Renovate configuration (#1179) 2024-05-21 07:29:26 +02:00
Picnic-DevPla-Bot
d9e1f3ad5d Upgrade sortpom-maven-plugin 3.4.1 -> 4.0.0 (#1183)
See:
- https://github.com/Ekryd/sortpom/wiki/Versions
- https://github.com/Ekryd/sortpom/compare/sortpom-parent-3.4.1...sortpom-parent-4.0.0
2024-05-20 21:28:31 +02:00
Stephan Schroevers
8a8290587a Update step-security/harden-runner configuration (#1177)
This resolves recent build failures by ensuring that JDKs can be
downloaded.
2024-05-19 14:14:20 +02:00
Picnic-DevPla-Bot
162aa0d458 Upgrade tidy-maven-plugin 1.2.0 -> 1.3.0 (#1175)
See:
- https://github.com/mojohaus/tidy-maven-plugin/releases/tag/1.3.0
- https://github.com/mojohaus/tidy-maven-plugin/compare/tidy-maven-plugin-1.2.0...1.3.0
2024-05-13 08:07:12 +02:00
Picnic-DevPla-Bot
0fb37c45b5 Upgrade Mockito 5.11.0 -> 5.12.0 (#1174)
See:
- https://github.com/mockito/mockito/releases/tag/v5.12.0
- https://github.com/mockito/mockito/compare/v5.11.0...v5.12.0
2024-05-12 10:16:02 +02:00
Picnic-DevPla-Bot
0c2ce44742 Upgrade AspectJ 1.9.22 -> 1.9.22.1 (#1173)
See:
- https://github.com/eclipse-aspectj/aspectj/releases/tag/V1_9_22_1
- https://github.com/eclipse-aspectj/aspectj/compare/V1_9_22...V1_9_22_1
2024-05-12 10:03:43 +02:00
Picnic-DevPla-Bot
f089157443 Upgrade Byte Buddy 1.14.14 -> 1.14.15 (#1169)
See:
- https://github.com/raphw/byte-buddy/releases/tag/byte-buddy-1.14.15
- https://github.com/raphw/byte-buddy/compare/byte-buddy-1.14.14...byte-buddy-1.14.15
2024-05-11 14:59:23 +02:00
62 changed files with 1586 additions and 596 deletions

View File

@@ -10,7 +10,7 @@ jobs:
strategy:
matrix:
os: [ ubuntu-22.04 ]
jdk: [ 17.0.10, 21.0.2 ]
jdk: [ 17.0.10, 21.0.2, 22.0.2 ]
distribution: [ temurin ]
experimental: [ false ]
include:
@@ -26,13 +26,15 @@ jobs:
continue-on-error: ${{ matrix.experimental }}
steps:
- name: Install Harden-Runner
uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v2.7.1
uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0
with:
disable-sudo: true
egress-policy: block
allowed-endpoints: >
api.adoptium.net:443
github.com:443
jitpack.io:443
objects.githubusercontent.com:443
repo.maven.apache.org:443
# We run the build twice for each supported JDK: once against the
# original Error Prone release, using only Error Prone checks available
@@ -40,11 +42,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 and set up JDK and Maven
uses: s4u/setup-maven-action@6d44c18d67d9e1549907b8815efa5e4dada1801b # v1.12.0
uses: s4u/setup-maven-action@489441643219d2b93ee2a127b2402eb640a1b947 # v1.13.0
with:
java-version: ${{ matrix.jdk }}
java-distribution: ${{ matrix.distribution }}
maven-version: 3.9.6
maven-version: 3.9.9
- name: Display build environment details
run: mvn --version
- name: Build project against vanilla Error Prone, compile Javadoc

View File

@@ -22,22 +22,23 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Install Harden-Runner
uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v2.7.1
uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0
with:
disable-sudo: true
egress-policy: block
allowed-endpoints: >
api.adoptium.net:443
api.github.com:443
github.com:443
objects.githubusercontent.com:443
repo.maven.apache.org:443
uploads.github.com:443
- name: Check out code and set up JDK and Maven
uses: s4u/setup-maven-action@6d44c18d67d9e1549907b8815efa5e4dada1801b # v1.12.0
uses: s4u/setup-maven-action@489441643219d2b93ee2a127b2402eb640a1b947 # v1.13.0
with:
java-version: 17.0.10
java-distribution: temurin
maven-version: 3.9.6
maven-version: 3.9.9
- name: Initialize CodeQL
uses: github/codeql-action/init@c7f9125735019aa87cfc361530512d50ea439c71 # v3.25.1
with:

View File

@@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Install Harden-Runner
uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v2.7.1
uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0
with:
disable-sudo: true
egress-policy: block
@@ -39,7 +39,7 @@ jobs:
www.youtube.com:443
youtrack.jetbrains.com:443
- name: Check out code
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
persist-credentials: false
- uses: ruby/setup-ruby@6bd3d993c602f6b675728ebaecb2b569ff86e99b # v1.174.0
@@ -74,7 +74,7 @@ jobs:
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Install Harden-Runner
uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v2.7.1
uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0
with:
disable-sudo: true
egress-policy: block

View File

@@ -21,26 +21,25 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Install Harden-Runner
uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v2.7.1
uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0
with:
disable-sudo: true
egress-policy: block
allowed-endpoints: >
api.github.com:443
api.osv.dev:443
api.scorecard.dev:443
api.securityscorecards.dev:443
fulcio.sigstore.dev:443
github.com:443
oss-fuzz-build-logs.storage.googleapis.com:443
rekor.sigstore.dev:443
tuf-repo-cdn.sigstore.dev:443
*.sigstore.dev:443
www.bestpractices.dev:443
- name: Check out code
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
persist-credentials: false
- name: Run OpenSSF Scorecard analysis
uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3
with:
results_file: results.sarif
results_format: sarif

View File

@@ -12,20 +12,22 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Install Harden-Runner
uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v2.7.1
uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0
with:
disable-sudo: true
egress-policy: block
allowed-endpoints: >
api.adoptium.net:443
github.com:443
objects.githubusercontent.com:443
repo.maven.apache.org:443
- name: Check out code and set up JDK and Maven
uses: s4u/setup-maven-action@6d44c18d67d9e1549907b8815efa5e4dada1801b # v1.12.0
uses: s4u/setup-maven-action@489441643219d2b93ee2a127b2402eb640a1b947 # v1.13.0
with:
checkout-fetch-depth: 2
java-version: 17.0.10
java-distribution: temurin
maven-version: 3.9.6
maven-version: 3.9.9
- name: Run Pitest
# By running with features `+GIT(from[HEAD~1]), +gitci`, Pitest only
# analyzes lines changed in the associated pull request, as GitHub

View File

@@ -20,20 +20,22 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Install Harden-Runner
uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v2.7.1
uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0
with:
disable-sudo: true
egress-policy: block
allowed-endpoints: >
api.adoptium.net:443
api.github.com:443
github.com:443
objects.githubusercontent.com:443
repo.maven.apache.org:443
- name: Check out code and set up JDK and Maven
uses: s4u/setup-maven-action@6d44c18d67d9e1549907b8815efa5e4dada1801b # v1.12.0
uses: s4u/setup-maven-action@489441643219d2b93ee2a127b2402eb640a1b947 # v1.13.0
with:
java-version: 17.0.10
java-distribution: temurin
maven-version: 3.9.6
maven-version: 3.9.9
- name: Download Pitest analysis artifact
uses: dawidd6/action-download-artifact@09f2f74827fd3a8607589e5ad7f9398816f540fe # v3.1.4
with:

View File

@@ -19,24 +19,26 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Install Harden-Runner
uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v2.7.1
uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0
with:
disable-sudo: true
egress-policy: block
allowed-endpoints: >
api.adoptium.net:443
checkstyle.org:443
github.com:443
objects.githubusercontent.com:443
oss.sonatype.org:443
raw.githubusercontent.com:443
repo.maven.apache.org:443
repository.sonatype.org:443
- name: Check out code and set up JDK and Maven
uses: s4u/setup-maven-action@6d44c18d67d9e1549907b8815efa5e4dada1801b # v1.12.0
uses: s4u/setup-maven-action@489441643219d2b93ee2a127b2402eb640a1b947 # v1.13.0
with:
checkout-ref: "refs/pull/${{ github.event.issue.number }}/head"
java-version: 17.0.10
java-distribution: temurin
maven-version: 3.9.6
maven-version: 3.9.9
- name: Install project to local Maven repository
run: mvn -T1C install -DskipTests -Dverification.skip
- name: Run integration test

View File

@@ -19,24 +19,28 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Install Harden-Runner
uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v2.7.1
uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0
with:
disable-sudo: true
egress-policy: block
allowed-endpoints: >
analysis-sensorcache-eu-central-1-prod.s3.amazonaws.com:443
api.adoptium.net:443
api.nuget.org:443
ea6ne4j2sb.execute-api.eu-central-1.amazonaws.com:443
github.com:443
objects.githubusercontent.com:443
repo.maven.apache.org:443
sc-cleancode-sensorcache-eu-central-1-prod.s3.amazonaws.com:443
scanner.sonarcloud.io:443
*.sonarcloud.io:443
sonarcloud.io:443
- name: Check out code and set up JDK and Maven
uses: s4u/setup-maven-action@6d44c18d67d9e1549907b8815efa5e4dada1801b # v1.12.0
uses: s4u/setup-maven-action@489441643219d2b93ee2a127b2402eb640a1b947 # v1.13.0
with:
checkout-fetch-depth: 0
java-version: 17.0.10
java-distribution: temurin
maven-version: 3.9.6
maven-version: 3.9.9
- name: Create missing `test` directory
# XXX: Drop this step in favour of actually having a test.
run: mkdir refaster-compiler/src/test

View File

@@ -12,7 +12,7 @@
"separateMinorPatch": true
},
{
"matchDepNames": [
"matchPackageNames": [
"dawidd6/action-download-artifact",
"github/codeql-action",
"ruby/setup-ruby"

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.16.2-SNAPSHOT</version>
<version>0.18.1-SNAPSHOT</version>
</parent>
<artifactId>documentation-support</artifactId>

View File

@@ -14,7 +14,6 @@ import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ServiceLoader;
import javax.tools.JavaFileObject;
@@ -87,6 +86,6 @@ final class DocumentationGeneratorTaskListener implements TaskListener {
}
private static String getSimpleClassName(URI path) {
return Paths.get(path).getFileName().toString().replace(".java", "");
return Path.of(path).getFileName().toString().replace(".java", "");
}
}

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.16.2-SNAPSHOT</version>
<version>0.18.1-SNAPSHOT</version>
</parent>
<artifactId>error-prone-contrib</artifactId>
@@ -67,6 +67,11 @@
<artifactId>jackson-annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.auto.service</groupId>
<artifactId>auto-service-annotations</artifactId>
@@ -122,6 +127,11 @@
<artifactId>jakarta.servlet-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>

View File

@@ -51,6 +51,7 @@ import tech.picnic.errorprone.utils.SourceCode;
// is effectively the identity operation.
// XXX: Also flag nullary instance method invocations that represent an identity conversion, such as
// `Boolean#booleanValue()`, `Byte#byteValue()` and friends.
// XXX: Also flag redundant round-trip conversions such as `path.toFile().toPath()`.
@AutoService(BugChecker.class)
@BugPattern(
summary = "Avoid or clarify identity conversions",

View File

@@ -18,14 +18,12 @@ import com.google.errorprone.fixes.SuggestedFixes;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.matchers.Matcher;
import com.google.errorprone.refaster.Refaster;
import com.google.errorprone.util.ASTHelpers;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.IdentifierTree;
import com.sun.source.tree.LiteralTree;
import com.sun.source.tree.MemberSelectTree;
import com.sun.source.tree.MethodInvocationTree;
import java.util.Optional;
import java.util.function.Supplier;
import tech.picnic.errorprone.refaster.matchers.RequiresComputation;
import tech.picnic.errorprone.utils.SourceCode;
/**
@@ -36,12 +34,12 @@ import tech.picnic.errorprone.utils.SourceCode;
* it does, the suggested fix changes the program's semantics. Such fragile code must instead be
* refactored such that the side-effectful code does not appear accidental.
*/
// XXX: Consider also implementing the inverse, in which `.orElseGet(() -> someConstant)` is
// flagged.
// XXX: Once the `MethodReferenceUsageCheck` becomes generally usable, consider leaving the method
// reference cleanup to that check, and express the remainder of the logic in this class using a
// Refaster template, i.c.w. a `@Matches` constraint that implements the `requiresComputation`
// logic.
// XXX: This rule may introduce a compilation error: the `value` expression may reference a
// non-effectively final variable, which is not allowed in the replacement lambda expression.
// Review whether a `@Matcher` can be used to avoid this.
// XXX: Once the `MethodReferenceUsageCheck` bug checker becomes generally usable, consider leaving
// the method reference cleanup to that check, and express the remainder of the logic in this class
// using a Refaster template, i.c.w. a `@NotMatches(RequiresComputation.class)` constraint.
@AutoService(BugChecker.class)
@BugPattern(
summary =
@@ -51,16 +49,17 @@ import tech.picnic.errorprone.utils.SourceCode;
linkType = NONE,
severity = WARNING,
tags = PERFORMANCE)
public final class OptionalOrElse extends BugChecker implements MethodInvocationTreeMatcher {
public final class OptionalOrElseGet extends BugChecker implements MethodInvocationTreeMatcher {
private static final long serialVersionUID = 1L;
private static final Matcher<ExpressionTree> REQUIRES_COMPUTATION = new RequiresComputation();
private static final Matcher<ExpressionTree> OPTIONAL_OR_ELSE_METHOD =
instanceMethod().onExactClass(Optional.class.getCanonicalName()).namedAnyOf("orElse");
// XXX: Also exclude invocations of `@Placeholder`-annotated methods.
private static final Matcher<ExpressionTree> REFASTER_METHOD =
staticMethod().onClass(Refaster.class.getCanonicalName());
/** Instantiates a new {@link OptionalOrElse} instance. */
public OptionalOrElse() {}
/** Instantiates a new {@link OptionalOrElseGet} instance. */
public OptionalOrElseGet() {}
@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
@@ -69,7 +68,8 @@ public final class OptionalOrElse extends BugChecker implements MethodInvocation
}
ExpressionTree argument = Iterables.getOnlyElement(tree.getArguments());
if (!requiresComputation(argument) || REFASTER_METHOD.matches(argument, state)) {
if (!REQUIRES_COMPUTATION.matches(argument, state)
|| REFASTER_METHOD.matches(argument, state)) {
return Description.NO_MATCH;
}
@@ -91,18 +91,6 @@ public final class OptionalOrElse extends BugChecker implements MethodInvocation
return describeMatch(tree, fix);
}
/**
* Tells whether the given expression contains anything other than a literal or a (possibly
* dereferenced) variable or constant.
*/
private static boolean requiresComputation(ExpressionTree tree) {
return !(tree instanceof IdentifierTree
|| tree instanceof LiteralTree
|| (tree instanceof MemberSelectTree memberSelect
&& !requiresComputation(memberSelect.getExpression()))
|| ASTHelpers.constValue(tree) != null);
}
/** Returns the nullary method reference matching the given expression, if any. */
private static Optional<String> tryMethodReferenceConversion(
ExpressionTree tree, VisitorState state) {
@@ -118,7 +106,7 @@ public final class OptionalOrElse extends BugChecker implements MethodInvocation
return Optional.empty();
}
if (requiresComputation(memberSelect.getExpression())) {
if (REQUIRES_COMPUTATION.matches(memberSelect.getExpression(), state)) {
return Optional.empty();
}

View File

@@ -3,6 +3,7 @@ package tech.picnic.errorprone.refasterrules;
import com.google.errorprone.refaster.Refaster;
import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import java.util.function.Function;
import java.util.function.Predicate;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
@@ -37,7 +38,12 @@ final class ClassRules {
}
}
/** Prefer {@link Class#isInstance(Object)} method references over more verbose alternatives. */
/**
* Prefer {@link Class#isInstance(Object)} method references over lambda expressions that require
* naming a variable.
*/
// XXX: Once the `ClassReferenceIsInstancePredicate` rule is dropped, rename this rule to just
// `ClassIsInstancePredicate`.
static final class ClassLiteralIsInstancePredicate<T, S> {
@BeforeTemplate
Predicate<S> before() {
@@ -50,7 +56,11 @@ final class ClassRules {
}
}
/** Prefer {@link Class#isInstance(Object)} method references over more verbose alternatives. */
/**
* Prefer {@link Class#isInstance(Object)} method references over lambda expressions that require
* naming a variable.
*/
// XXX: Drop this rule once the `MethodReferenceUsage` rule is enabled by default.
static final class ClassReferenceIsInstancePredicate<T, S> {
@BeforeTemplate
Predicate<S> before(Class<T> clazz) {
@@ -62,4 +72,39 @@ final class ClassRules {
return clazz::isInstance;
}
}
/**
* Prefer {@link Class#cast(Object)} method references over lambda expressions that require naming
* a variable.
*/
// XXX: Once the `ClassReferenceCast` rule is dropped, rename this rule to just `ClassCast`.
static final class ClassLiteralCast<T, S> {
@BeforeTemplate
@SuppressWarnings("unchecked")
Function<T, S> before() {
return t -> (S) t;
}
@AfterTemplate
Function<T, S> after() {
return Refaster.<S>clazz()::cast;
}
}
/**
* Prefer {@link Class#cast(Object)} method references over lambda expressions that require naming
* a variable.
*/
// XXX: Drop this rule once the `MethodReferenceUsage` rule is enabled by default.
static final class ClassReferenceCast<T, S> {
@BeforeTemplate
Function<T, S> before(Class<? extends S> clazz) {
return o -> clazz.cast(o);
}
@AfterTemplate
Function<T, S> after(Class<? extends S> clazz) {
return clazz::cast;
}
}
}

View File

@@ -8,7 +8,9 @@ import com.google.errorprone.refaster.Refaster;
import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.AlsoNegation;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import com.google.errorprone.refaster.annotation.NotMatches;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
@@ -21,6 +23,7 @@ import java.util.function.Consumer;
import java.util.function.IntFunction;
import java.util.stream.Stream;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
import tech.picnic.errorprone.refaster.matchers.IsRefasterAsVarargs;
/** Refaster rules related to expressions dealing with (arbitrary) collections. */
// XXX: There are other Guava `Iterables` methods that should not be called if the input is known to
@@ -184,6 +187,24 @@ final class CollectionRules {
}
}
/** Don't unnecessarily call {@link Stream#distinct()} on an already-unique stream of elements. */
// XXX: This rule assumes that the `Set` relies on `Object#equals`, rather than a custom
// equivalence relation.
// XXX: Expressions that drop or reorder elements from the stream, such as `.filter`, `.skip` and
// `sorted`, can similarly be simplified. Covering all cases is better done using an Error Prone
// check.
static final class SetStream<T> {
@BeforeTemplate
Stream<?> before(Set<T> set) {
return set.stream().distinct();
}
@AfterTemplate
Stream<?> after(Set<T> set) {
return set.stream();
}
}
/** Prefer {@link ArrayList#ArrayList(Collection)} over the Guava alternative. */
@SuppressWarnings(
"NonApiType" /* Matching against `List` would unnecessarily constrain the rule. */)
@@ -276,6 +297,23 @@ final class CollectionRules {
}
}
/** Prefer {@link Arrays#asList(Object[])} over more contrived alternatives. */
// XXX: Consider moving this rule to `ImmutableListRules` and having it suggest
// `ImmutableList#copyOf`. That would retain immutability, at the cost of no longer handling
// `null`s.
static final class ArraysAsList<T> {
// XXX: This expression produces an unmodifiable list, while the alternative doesn't.
@BeforeTemplate
List<T> before(@NotMatches(IsRefasterAsVarargs.class) T[] array) {
return Arrays.stream(array).toList();
}
@AfterTemplate
List<T> after(T[] array) {
return Arrays.asList(array);
}
}
/** Prefer calling {@link Collection#toArray()} over more contrived alternatives. */
static final class CollectionToArray<T> {
@BeforeTemplate

View File

@@ -24,8 +24,10 @@ import com.google.errorprone.refaster.annotation.Placeholder;
import com.google.errorprone.refaster.annotation.Repeated;
import com.google.errorprone.refaster.annotation.UseImportPolicy;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.function.BinaryOperator;
import java.util.function.Function;
@@ -243,18 +245,77 @@ final class ComparatorRules {
}
}
/** Prefer {@link Collections#sort(List)} over more verbose alternatives. */
static final class CollectionsSort<T extends Comparable<? super T>> {
@BeforeTemplate
void before(List<T> collection) {
Collections.sort(collection, naturalOrder());
}
@AfterTemplate
void after(List<T> collection) {
Collections.sort(collection);
}
}
/** Prefer {@link Collections#min(Collection)} over more verbose alternatives. */
static final class CollectionsMin<T extends Comparable<? super T>> {
@BeforeTemplate
T before(Collection<T> collection) {
return Refaster.anyOf(
Collections.min(collection, naturalOrder()), Collections.max(collection, reverseOrder()));
}
@AfterTemplate
T after(Collection<T> collection) {
return Collections.min(collection);
}
}
/**
* Avoid unnecessary creation of a {@link Stream} to determine the minimum of a known collection
* of values.
*/
static final class MinOfVarargs<T> {
static final class MinOfArray<S, T extends S> {
@BeforeTemplate
T before(@Repeated T value, Comparator<T> cmp) {
T before(T[] array, Comparator<S> cmp) {
return Arrays.stream(array).min(cmp).orElseThrow();
}
@AfterTemplate
T after(T[] array, Comparator<S> cmp) {
return Collections.min(Arrays.asList(array), cmp);
}
}
/**
* Avoid unnecessary creation of a {@link Stream} to determine the minimum of a known collection
* of values.
*/
static final class CollectionsMinWithComparator<S, T extends S> {
@BeforeTemplate
T before(Collection<T> collection, Comparator<S> cmp) {
return collection.stream().min(cmp).orElseThrow();
}
@AfterTemplate
T after(Collection<T> collection, Comparator<S> cmp) {
return Collections.min(collection, cmp);
}
}
/**
* Avoid unnecessary creation of a {@link Stream} to determine the minimum of a known collection
* of values.
*/
static final class MinOfVarargs<S, T extends S> {
@BeforeTemplate
T before(@Repeated T value, Comparator<S> cmp) {
return Stream.of(Refaster.asVarargs(value)).min(cmp).orElseThrow();
}
@AfterTemplate
T after(@Repeated T value, Comparator<T> cmp) {
T after(@Repeated T value, Comparator<S> cmp) {
return Collections.min(Arrays.asList(value), cmp);
}
}
@@ -310,18 +371,64 @@ final class ComparatorRules {
}
}
/** Prefer {@link Collections#max(Collection)} over more verbose alternatives. */
static final class CollectionsMax<T extends Comparable<? super T>> {
@BeforeTemplate
T before(Collection<T> collection) {
return Refaster.anyOf(
Collections.max(collection, naturalOrder()), Collections.min(collection, reverseOrder()));
}
@AfterTemplate
T after(Collection<T> collection) {
return Collections.max(collection);
}
}
/**
* Avoid unnecessary creation of a {@link Stream} to determine the maximum of a known collection
* of values.
*/
static final class MaxOfVarargs<T> {
static final class MaxOfArray<S, T extends S> {
@BeforeTemplate
T before(@Repeated T value, Comparator<T> cmp) {
T before(T[] array, Comparator<S> cmp) {
return Arrays.stream(array).max(cmp).orElseThrow();
}
@AfterTemplate
T after(T[] array, Comparator<S> cmp) {
return Collections.max(Arrays.asList(array), cmp);
}
}
/**
* Avoid unnecessary creation of a {@link Stream} to determine the maximum of a known collection
* of values.
*/
static final class CollectionsMaxWithComparator<S, T extends S> {
@BeforeTemplate
T before(Collection<T> collection, Comparator<S> cmp) {
return collection.stream().max(cmp).orElseThrow();
}
@AfterTemplate
T after(Collection<T> collection, Comparator<S> cmp) {
return Collections.max(collection, cmp);
}
}
/**
* Avoid unnecessary creation of a {@link Stream} to determine the maximum of a known collection
* of values.
*/
static final class MaxOfVarargs<S, T extends S> {
@BeforeTemplate
T before(@Repeated T value, Comparator<S> cmp) {
return Stream.of(Refaster.asVarargs(value)).max(cmp).orElseThrow();
}
@AfterTemplate
T after(@Repeated T value, Comparator<T> cmp) {
T after(@Repeated T value, Comparator<S> cmp) {
return Collections.max(Arrays.asList(value), cmp);
}
}

View File

@@ -1,5 +1,6 @@
package tech.picnic.errorprone.refasterrules;
import static java.util.function.Predicate.isEqual;
import static java.util.function.Predicate.not;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
@@ -19,9 +20,9 @@ import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
final class EqualityRules {
private EqualityRules() {}
/** Prefer reference-based quality for enums. */
// Primitive value comparisons are not listed, because Error Prone flags those out of the box.
static final class PrimitiveOrReferenceEquality<T extends Enum<T>> {
/** Prefer reference-based equality for enums. */
// Primitive value comparisons are not matched, because Error Prone flags those out of the box.
static final class EnumReferenceEquality<T extends Enum<T>> {
/**
* Enums can be compared by reference. It is safe to do so even in the face of refactorings,
* because if the type is ever converted to a non-enum, then Error-Prone will complain about any
@@ -43,6 +44,20 @@ final class EqualityRules {
}
}
/** Prefer reference-based equality for enums. */
static final class EnumReferenceEqualityLambda<T extends Enum<T>> {
@BeforeTemplate
Predicate<T> before(T e) {
return Refaster.anyOf(isEqual(e), e::equals);
}
@AfterTemplate
@SuppressWarnings("java:S1698" /* Reference comparison is valid for enums. */)
Predicate<T> after(T e) {
return v -> v == e;
}
}
/** Prefer {@link Object#equals(Object)} over the equivalent lambda function. */
// XXX: As it stands, this rule is a special case of what `MethodReferenceUsage` tries to achieve.
// If/when `MethodReferenceUsage` becomes production ready, we should simply drop this check.

View File

@@ -2,12 +2,18 @@ package tech.picnic.errorprone.refasterrules;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.errorprone.refaster.Refaster;
import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import com.google.errorprone.refaster.annotation.Repeated;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.FileAttribute;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
/** Refaster rules related to expressions dealing with files. */
@@ -15,6 +21,49 @@ import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
final class FileRules {
private FileRules() {}
/** Prefer the more idiomatic {@link Path#of(URI)} over {@link Paths#get(URI)}. */
static final class PathOfUri {
@BeforeTemplate
Path before(URI uri) {
return Paths.get(uri);
}
@AfterTemplate
Path after(URI uri) {
return Path.of(uri);
}
}
/**
* Prefer the more idiomatic {@link Path#of(String, String...)} over {@link Paths#get(String,
* String...)}.
*/
static final class PathOfString {
@BeforeTemplate
Path before(String first, @Repeated String more) {
return Paths.get(first, more);
}
@AfterTemplate
Path after(String first, @Repeated String more) {
return Path.of(first, more);
}
}
/** Avoid redundant conversions from {@link Path} to {@link File}. */
// XXX: Review whether a rule such as this one is better handled by the `IdentityConversion` rule.
static final class PathInstance {
@BeforeTemplate
Path before(Path path) {
return path.toFile().toPath();
}
@AfterTemplate
Path after(Path path) {
return path;
}
}
/** Prefer {@link Files#readString(Path, Charset)} over more contrived alternatives. */
static final class FilesReadStringWithCharset {
@BeforeTemplate
@@ -40,4 +89,44 @@ final class FileRules {
return Files.readString(path);
}
}
/**
* Prefer {@link Files#createTempFile(String, String, FileAttribute[])} over alternatives that
* create files with more liberal permissions.
*/
static final class FilesCreateTempFileToFile {
@BeforeTemplate
@SuppressWarnings({
"FilesCreateTempFileInCustomDirectoryToFile" /* This is a more specific template. */,
"java:S5443" /* This violation will be rewritten. */,
"key-to-resolve-AnnotationUseStyle-and-TrailingComment-check-conflict"
})
File before(String prefix, String suffix) throws IOException {
return Refaster.anyOf(
File.createTempFile(prefix, suffix), File.createTempFile(prefix, suffix, null));
}
@AfterTemplate
@SuppressWarnings(
"java:S5443" /* On POSIX systems the file will only have user read-write permissions. */)
File after(String prefix, String suffix) throws IOException {
return Files.createTempFile(prefix, suffix).toFile();
}
}
/**
* Prefer {@link Files#createTempFile(Path, String, String, FileAttribute[])} over alternatives
* that create files with more liberal permissions.
*/
static final class FilesCreateTempFileInCustomDirectoryToFile {
@BeforeTemplate
File before(File directory, String prefix, String suffix) throws IOException {
return File.createTempFile(prefix, suffix, directory);
}
@AfterTemplate
File after(File directory, String prefix, String suffix) throws IOException {
return Files.createTempFile(directory.toPath(), prefix, suffix).toFile();
}
}
}

View File

@@ -302,16 +302,22 @@ import tech.picnic.errorprone.refaster.annotation.TypeMigration;
final class JUnitToAssertJRules {
private JUnitToAssertJRules() {}
static final class ThrowNewAssertionError {
static final class Fail<T> {
@BeforeTemplate
void before() {
Assertions.fail();
T before() {
return Assertions.fail();
}
// XXX: Add `@UseImportPolicy(STATIC_IMPORT_ALWAYS)` once
// https://github.com/google/error-prone/pull/3584 is resolved. Until that time, statically
// importing AssertJ's `fail` is likely to clash with an existing static import of JUnit's
// `fail`. Note that combining Error Prone's `RemoveUnusedImports` and
// `UnnecessarilyFullyQualified` checks and our `StaticImport` check will anyway cause the
// method to be imported statically if possible; just in a less efficient manner.
@AfterTemplate
@DoNotCall
void after() {
throw new AssertionError();
T after() {
return fail();
}
}
@@ -321,12 +327,7 @@ final class JUnitToAssertJRules {
return Assertions.fail(message);
}
// XXX: Add `@UseImportPolicy(STATIC_IMPORT_ALWAYS)` once
// https://github.com/google/error-prone/pull/3584 is resolved. Until that time, statically
// importing AssertJ's `fail` is likely to clash with an existing static import of JUnit's
// `fail`. Note that combining Error Prone's `RemoveUnusedImports` and
// `UnnecessarilyFullyQualified` checks and our `StaticImport` check will anyway cause the
// method to be imported statically if possible; just in a less efficient manner.
// XXX: Add `@UseImportPolicy(STATIC_IMPORT_ALWAYS)`. See `Fail` comment.
@AfterTemplate
T after(String message) {
return fail(message);
@@ -339,28 +340,24 @@ final class JUnitToAssertJRules {
return Assertions.fail(message, throwable);
}
// XXX: Add `@UseImportPolicy(STATIC_IMPORT_ALWAYS)` once
// https://github.com/google/error-prone/pull/3584 is resolved. Until that time, statically
// importing AssertJ's `fail` is likely to clash with an existing static import of JUnit's
// `fail`. Note that combining Error Prone's `RemoveUnusedImports` and
// `UnnecessarilyFullyQualified` checks and our `StaticImport` check will anyway cause the
// method to be imported statically if possible; just in a less efficient manner.
// XXX: Add `@UseImportPolicy(STATIC_IMPORT_ALWAYS)`. See `Fail` comment.
@AfterTemplate
T after(String message, Throwable throwable) {
return fail(message, throwable);
}
}
static final class FailWithThrowable {
static final class FailWithThrowable<T> {
@BeforeTemplate
void before(Throwable throwable) {
Assertions.fail(throwable);
T before(Throwable throwable) {
return Assertions.fail(throwable);
}
// XXX: Add `@UseImportPolicy(STATIC_IMPORT_ALWAYS)`. See `Fail` comment.
@AfterTemplate
@DoNotCall
void after(Throwable throwable) {
throw new AssertionError(throwable);
T after(Throwable throwable) {
return fail(throwable);
}
}

View File

@@ -20,7 +20,7 @@ import java.util.function.Supplier;
import java.util.stream.Stream;
import org.jspecify.annotations.Nullable;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;
import tech.picnic.errorprone.refaster.matchers.IsLikelyTrivialComputation;
import tech.picnic.errorprone.refaster.matchers.RequiresComputation;
/** Refaster rules related to expressions dealing with {@link Optional}s. */
@OnlineDocumentation
@@ -255,24 +255,21 @@ final class OptionalRules {
}
/**
* Prefer {@link Optional#orElseGet(Supplier)} over {@link Optional#orElse(Object)} if the
* fallback value is not the result of a trivial computation.
* Prefer {@link Optional#orElse(Object)} over {@link Optional#orElseGet(Supplier)} if the
* fallback value does not require non-trivial computation.
*/
// XXX: This rule may introduce a compilation error: the `value` expression may reference a
// non-effectively final variable, which is not allowed in the replacement lambda expression.
// Review whether a `@Matcher` can be used to avoid this.
// XXX: Once `MethodReferenceUsage` is "production ready", replace
// `@NotMatches(IsLikelyTrivialComputation.class)` with `@Matches(RequiresComputation.class)` (and
// reimplement the matcher accordingly).
static final class OptionalOrElseGet<T> {
// XXX: This rule is the counterpart to the `OptionalOrElseGet` bug checker. Once the
// `MethodReferenceUsage` bug checker is "production ready", that bug checker may similarly be
// replaced with a Refaster rule.
static final class OptionalOrElse<T> {
@BeforeTemplate
T before(Optional<T> optional, @NotMatches(IsLikelyTrivialComputation.class) T value) {
return optional.orElse(value);
T before(Optional<T> optional, @NotMatches(RequiresComputation.class) T value) {
return optional.orElseGet(() -> value);
}
@AfterTemplate
T after(Optional<T> optional, T value) {
return optional.orElseGet(() -> value);
return optional.orElse(value);
}
}
@@ -373,7 +370,12 @@ final class OptionalRules {
/** Prefer {@link Optional#or(Supplier)} over more verbose alternatives. */
static final class OptionalOrOtherOptional<T> {
@BeforeTemplate
@SuppressWarnings("NestedOptionals")
@SuppressWarnings({
"LexicographicalAnnotationAttributeListing" /* `key-*` entry must remain last. */,
"NestedOptionals" /* This violation will be rewritten. */,
"OptionalOrElse" /* Parameters represent expressions that may require computation. */,
"key-to-resolve-AnnotationUseStyle-and-TrailingComment-check-conflict"
})
Optional<T> before(Optional<T> optional1, Optional<T> optional2) {
// XXX: Note that rewriting the first and third variant will change the code's behavior if
// `optional2` has side-effects.

View File

@@ -8,6 +8,8 @@ import com.google.common.primitives.Floats;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
import com.google.common.primitives.Shorts;
import com.google.common.primitives.UnsignedInts;
import com.google.common.primitives.UnsignedLongs;
import com.google.errorprone.refaster.Refaster;
import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.AlsoNegation;
@@ -76,6 +78,8 @@ final class PrimitiveRules {
}
/** Prefer {@link Math#toIntExact(long)} over the Guava alternative. */
// XXX: This rule changes the exception possibly thrown from `IllegalArgumentException` to
// `ArithmeticException`.
static final class LongToIntExact {
@BeforeTemplate
int before(long l) {
@@ -192,72 +196,8 @@ final class PrimitiveRules {
}
}
/** Prefer {@link Boolean#compare(boolean, boolean)} over the Guava alternative. */
static final class BooleanCompare {
@BeforeTemplate
int before(boolean a, boolean b) {
return Booleans.compare(a, b);
}
@AfterTemplate
int after(boolean a, boolean b) {
return Boolean.compare(a, b);
}
}
/** Prefer {@link Character#compare(char, char)} over the Guava alternative. */
static final class CharacterCompare {
@BeforeTemplate
int before(char a, char b) {
return Chars.compare(a, b);
}
@AfterTemplate
int after(char a, char b) {
return Character.compare(a, b);
}
}
/** Prefer {@link Short#compare(short, short)} over the Guava alternative. */
static final class ShortCompare {
@BeforeTemplate
int before(short a, short b) {
return Shorts.compare(a, b);
}
@AfterTemplate
int after(short a, short b) {
return Short.compare(a, b);
}
}
/** Prefer {@link Integer#compare(int, int)} over the Guava alternative. */
static final class IntegerCompare {
@BeforeTemplate
int before(int a, int b) {
return Ints.compare(a, b);
}
@AfterTemplate
int after(int a, int b) {
return Integer.compare(a, b);
}
}
/** Prefer {@link Long#compare(long, long)} over the Guava alternative. */
static final class LongCompare {
@BeforeTemplate
int before(long a, long b) {
return Longs.compare(a, b);
}
@AfterTemplate
int after(long a, long b) {
return Long.compare(a, b);
}
}
/** Prefer {@link Float#compare(float, float)} over the Guava alternative. */
// XXX: Drop this rule once https://github.com/google/guava/pull/7371 is released.
static final class FloatCompare {
@BeforeTemplate
int before(float a, float b) {
@@ -271,6 +211,7 @@ final class PrimitiveRules {
}
/** Prefer {@link Double#compare(double, double)} over the Guava alternative. */
// XXX: Drop this rule once https://github.com/google/guava/pull/7371 is released.
static final class DoubleCompare {
@BeforeTemplate
int before(double a, double b) {
@@ -442,4 +383,205 @@ final class PrimitiveRules {
return Long.signum(l) == -1;
}
}
/** Prefer JDK's {@link Integer#compareUnsigned(int, int)} over third-party alternatives. */
static final class IntegerCompareUnsigned {
@BeforeTemplate
int before(int x, int y) {
return UnsignedInts.compare(x, y);
}
@AfterTemplate
int after(int x, int y) {
return Integer.compareUnsigned(x, y);
}
}
/** Prefer JDK's {@link Long#compareUnsigned(long, long)} over third-party alternatives. */
static final class LongCompareUnsigned {
@BeforeTemplate
long before(long x, long y) {
return UnsignedLongs.compare(x, y);
}
@AfterTemplate
long after(long x, long y) {
return Long.compareUnsigned(x, y);
}
}
/** Prefer JDK's {@link Integer#divideUnsigned(int, int)} over third-party alternatives. */
static final class IntegerDivideUnsigned {
@BeforeTemplate
int before(int x, int y) {
return UnsignedInts.divide(x, y);
}
@AfterTemplate
int after(int x, int y) {
return Integer.divideUnsigned(x, y);
}
}
/** Prefer JDK's {@link Long#divideUnsigned(long, long)} over third-party alternatives. */
static final class LongDivideUnsigned {
@BeforeTemplate
long before(long x, long y) {
return UnsignedLongs.divide(x, y);
}
@AfterTemplate
long after(long x, long y) {
return Long.divideUnsigned(x, y);
}
}
/** Prefer JDK's {@link Integer#remainderUnsigned(int, int)} over third-party alternatives. */
static final class IntegerRemainderUnsigned {
@BeforeTemplate
int before(int x, int y) {
return UnsignedInts.remainder(x, y);
}
@AfterTemplate
int after(int x, int y) {
return Integer.remainderUnsigned(x, y);
}
}
/** Prefer JDK's {@link Long#remainderUnsigned(long, long)} over third-party alternatives. */
static final class LongRemainderUnsigned {
@BeforeTemplate
long before(long x, long y) {
return UnsignedLongs.remainder(x, y);
}
@AfterTemplate
long after(long x, long y) {
return Long.remainderUnsigned(x, y);
}
}
/**
* Prefer JDK's {@link Integer#parseUnsignedInt(String)} over third-party or more verbose
* alternatives.
*/
static final class IntegerParseUnsignedInt {
@BeforeTemplate
int before(String string) {
return Refaster.anyOf(
UnsignedInts.parseUnsignedInt(string), Integer.parseUnsignedInt(string, 10));
}
@AfterTemplate
int after(String string) {
return Integer.parseUnsignedInt(string);
}
}
/**
* Prefer JDK's {@link Long#parseUnsignedLong(String)} over third-party or more verbose
* alternatives.
*/
static final class LongParseUnsignedLong {
@BeforeTemplate
long before(String string) {
return Refaster.anyOf(
UnsignedLongs.parseUnsignedLong(string), Long.parseUnsignedLong(string, 10));
}
@AfterTemplate
long after(String string) {
return Long.parseUnsignedLong(string);
}
}
/** Prefer JDK's {@link Integer#parseUnsignedInt(String, int)} over third-party alternatives. */
static final class IntegerParseUnsignedIntWithRadix {
@BeforeTemplate
int before(String string, int radix) {
return UnsignedInts.parseUnsignedInt(string, radix);
}
@AfterTemplate
int after(String string, int radix) {
return Integer.parseUnsignedInt(string, radix);
}
}
/** Prefer JDK's {@link Long#parseUnsignedLong(String, int)} over third-party alternatives. */
static final class LongParseUnsignedLongWithRadix {
@BeforeTemplate
long before(String string, int radix) {
return UnsignedLongs.parseUnsignedLong(string, radix);
}
@AfterTemplate
long after(String string, int radix) {
return Long.parseUnsignedLong(string, radix);
}
}
/**
* Prefer JDK's {@link Integer#toUnsignedString(int)} over third-party or more verbose
* alternatives.
*/
static final class IntegerToUnsignedString {
@BeforeTemplate
String before(int i) {
return Refaster.anyOf(UnsignedInts.toString(i), Integer.toUnsignedString(i, 10));
}
@AfterTemplate
String after(int i) {
return Integer.toUnsignedString(i);
}
}
/**
* Prefer JDK's {@link Long#toUnsignedString(long)} over third-party or more verbose alternatives.
*/
static final class LongToUnsignedString {
@BeforeTemplate
String before(long i) {
return Refaster.anyOf(UnsignedLongs.toString(i), Long.toUnsignedString(i, 10));
}
@AfterTemplate
String after(long i) {
return Long.toUnsignedString(i);
}
}
/**
* Prefer JDK's {@link Integer#toUnsignedString(int,int)} over third-party or more verbose
* alternatives.
*/
static final class IntegerToUnsignedStringWithRadix {
@BeforeTemplate
String before(int i, int radix) {
return UnsignedInts.toString(i, radix);
}
@AfterTemplate
String after(int i, int radix) {
return Integer.toUnsignedString(i, radix);
}
}
/**
* Prefer JDK's {@link Long#toUnsignedString(long,int)} over third-party or more verbose
* alternatives.
*/
static final class LongToUnsignedStringWithRadix {
@BeforeTemplate
String before(long i, int radix) {
return UnsignedLongs.toString(i, radix);
}
@AfterTemplate
String after(long i, int radix) {
return Long.toUnsignedString(i, radix);
}
}
}

View File

@@ -13,6 +13,7 @@ import static java.util.stream.Collectors.toCollection;
import static org.assertj.core.api.Assertions.assertThat;
import static reactor.function.TupleUtils.function;
import com.github.benmanes.caffeine.cache.AsyncLoadingCache;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@@ -33,6 +34,7 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
@@ -40,6 +42,7 @@ import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collector;
import java.util.stream.Stream;
import org.jspecify.annotations.Nullable;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Flux;
@@ -480,15 +483,20 @@ final class ReactorRules {
}
/** Prefer {@link Flux#just(Object)} over more contrived alternatives. */
static final class FluxJust {
static final class FluxJust<T> {
@BeforeTemplate
Flux<Integer> before(int start) {
return Flux.range(start, 1);
Flux<Integer> before(int value) {
return Flux.range(value, 1);
}
@BeforeTemplate
Flux<T> before(T value) {
return Mono.just(value).repeat().take(1);
}
@AfterTemplate
Flux<Integer> after(int start) {
return Flux.just(start);
Flux<T> after(T value) {
return Flux.just(value);
}
}
@@ -557,6 +565,7 @@ final class ReactorRules {
@Matches(IsIdentityOperation.class)
Function<? super P, ? extends Publisher<? extends S>> identityOperation) {
return Refaster.anyOf(
flux.concatMap(function, 0),
flux.flatMap(function, 1),
flux.flatMapSequential(function, 1),
flux.map(function).concatMap(identityOperation));
@@ -1197,10 +1206,17 @@ final class ReactorRules {
}
/** Prefer {@link Flux#fromIterable(Iterable)} over less efficient alternatives. */
// XXX: Once the `FluxFromStreamSupplier` rule is constrained using
// `@NotMatches(IsIdentityOperation.class)`, this rule should also cover
// `Flux.fromStream(collection.stream())`.
static final class FluxFromIterable<T> {
// XXX: Once the `MethodReferenceUsage` check is generally enabled, drop the second
// `Refaster.anyOf` variant.
@BeforeTemplate
Flux<T> before(Collection<T> collection) {
return Flux.fromStream(collection.stream());
return Flux.fromStream(
Refaster.<Supplier<Stream<? extends T>>>anyOf(
collection::stream, () -> collection.stream()));
}
@AfterTemplate
@@ -1903,4 +1919,76 @@ final class ReactorRules {
return step.verifyTimeout(duration);
}
}
/**
* Prefer {@link Mono#fromFuture(Supplier)} over {@link Mono#fromFuture(CompletableFuture)}, as
* the former may defer initiation of the asynchronous computation until subscription.
*/
static final class MonoFromFutureSupplier<T> {
// XXX: Constrain the `future` parameter using `@NotMatches(IsIdentityOperation.class)` once
// `IsIdentityOperation` no longer matches nullary method invocations.
@BeforeTemplate
Mono<T> before(CompletableFuture<T> future) {
return Mono.fromFuture(future);
}
@AfterTemplate
Mono<T> after(CompletableFuture<T> future) {
return Mono.fromFuture(() -> future);
}
}
/**
* Prefer {@link Mono#fromFuture(Supplier, boolean)} over {@link
* Mono#fromFuture(CompletableFuture, boolean)}, as the former may defer initiation of the
* asynchronous computation until subscription.
*/
static final class MonoFromFutureSupplierBoolean<T> {
// XXX: Constrain the `future` parameter using `@NotMatches(IsIdentityOperation.class)` once
// `IsIdentityOperation` no longer matches nullary method invocations.
@BeforeTemplate
Mono<T> before(CompletableFuture<T> future, boolean suppressCancel) {
return Mono.fromFuture(future, suppressCancel);
}
@AfterTemplate
Mono<T> after(CompletableFuture<T> future, boolean suppressCancel) {
return Mono.fromFuture(() -> future, suppressCancel);
}
}
/**
* Don't propagate {@link Mono} cancellations to an upstream cache value computation, as
* completion of such computations may benefit concurrent or subsequent cache usages.
*/
static final class MonoFromFutureAsyncLoadingCacheGet<K, V> {
@BeforeTemplate
Mono<V> before(AsyncLoadingCache<K, V> cache, K key) {
return Mono.fromFuture(() -> cache.get(key));
}
@AfterTemplate
Mono<V> after(AsyncLoadingCache<K, V> cache, K key) {
return Mono.fromFuture(() -> cache.get(key), /* suppressCancel= */ true);
}
}
/**
* Prefer {@link Flux#fromStream(Supplier)} over {@link Flux#fromStream(Stream)}, as the former
* yields a {@link Flux} that is more likely to behave as expected when subscribed to more than
* once.
*/
static final class FluxFromStreamSupplier<T> {
// XXX: Constrain the `stream` parameter using `@NotMatches(IsIdentityOperation.class)` once
// `IsIdentityOperation` no longer matches nullary method invocations.
@BeforeTemplate
Flux<T> before(Stream<T> stream) {
return Flux.fromStream(stream);
}
@AfterTemplate
Flux<T> after(Stream<T> stream) {
return Flux.fromStream(() -> stream);
}
}
}

View File

@@ -244,4 +244,11 @@ final class StringRules {
return Utf8.encodedLength(str);
}
}
// Rewrite `String#copyValueOf(char[])` to `new String(char[])`.
// Example:
// String.copyValueOf(new char[]);
// -->
// new String(new char[]);
}

View File

@@ -161,8 +161,9 @@ final class TestNGToAssertJRules {
@AfterTemplate
@DoNotCall
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
void after() {
throw new AssertionError();
fail();
}
}

View File

@@ -5,14 +5,15 @@ import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;
import com.google.errorprone.CompilationTestHelper;
import org.junit.jupiter.api.Test;
final class OptionalOrElseTest {
final class OptionalOrElseGetTest {
@Test
void identification() {
CompilationTestHelper.newInstance(OptionalOrElse.class, getClass())
CompilationTestHelper.newInstance(OptionalOrElseGet.class, getClass())
.addSourceLines(
"A.java",
"import com.google.errorprone.refaster.Refaster;",
"import java.util.Optional;",
"import java.util.function.Supplier;",
"",
"class A {",
" private final Optional<Object> optional = Optional.empty();",
@@ -27,6 +28,7 @@ final class OptionalOrElseTest {
" optional.orElse(string);",
" optional.orElse(this.string);",
" optional.orElse(Refaster.anyOf(\"constant\", \"another\"));",
" Optional.<Supplier<String>>empty().orElse(() -> \"constant\");",
"",
" // BUG: Diagnostic contains:",
" Optional.empty().orElse(string + \"constant\");",
@@ -67,7 +69,7 @@ final class OptionalOrElseTest {
@Test
void replacement() {
BugCheckerRefactoringTestHelper.newInstance(OptionalOrElse.class, getClass())
BugCheckerRefactoringTestHelper.newInstance(OptionalOrElseGet.class, getClass())
.addInputLines(
"A.java",
"import java.util.Optional;",

View File

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

View File

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

View File

@@ -6,9 +6,11 @@ import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.TreeSet;
import java.util.stream.Stream;
@@ -70,6 +72,10 @@ final class CollectionRulesTest implements RefasterRuleCollectionTestCase {
}
}
Stream<Integer> testSetStream() {
return ImmutableSet.of(1).stream().distinct();
}
ArrayList<String> testNewArrayListFromCollection() {
return Lists.newArrayList(ImmutableList.of("foo"));
}
@@ -94,6 +100,10 @@ final class CollectionRulesTest implements RefasterRuleCollectionTestCase {
return ImmutableSet.of(1).asList().toString();
}
List<String> testArraysAsList() {
return Arrays.stream(new String[0]).toList();
}
ImmutableSet<Object[]> testCollectionToArray() {
return ImmutableSet.of(
ImmutableSet.of(1).toArray(new Object[1]),

View File

@@ -6,9 +6,11 @@ import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.TreeSet;
import java.util.stream.Stream;
@@ -62,6 +64,10 @@ final class CollectionRulesTest implements RefasterRuleCollectionTestCase {
new HashSet<Number>().removeAll(ImmutableSet.of(2));
}
Stream<Integer> testSetStream() {
return ImmutableSet.of(1).stream();
}
ArrayList<String> testNewArrayListFromCollection() {
return new ArrayList<>(ImmutableList.of("foo"));
}
@@ -86,6 +92,10 @@ final class CollectionRulesTest implements RefasterRuleCollectionTestCase {
return ImmutableSet.of(1).toString();
}
List<String> testArraysAsList() {
return Arrays.asList(new String[0]);
}
ImmutableSet<Object[]> testCollectionToArray() {
return ImmutableSet.of(
ImmutableSet.of(1).toArray(), ImmutableSet.of(2).toArray(), ImmutableSet.of(3).toArray());

View File

@@ -107,6 +107,24 @@ final class ComparatorRulesTest implements RefasterRuleCollectionTestCase {
Comparator.<String>reverseOrder().compare("baz", "qux"));
}
void testCollectionsSort() {
Collections.sort(ImmutableList.of("foo", "bar"), naturalOrder());
}
ImmutableSet<String> testCollectionsMin() {
return ImmutableSet.of(
Collections.min(ImmutableList.of("foo"), naturalOrder()),
Collections.max(ImmutableList.of("bar"), reverseOrder()));
}
String testMinOfArray() {
return Arrays.stream(new String[0]).min(naturalOrder()).orElseThrow();
}
String testCollectionsMinWithComparator() {
return ImmutableSet.of("foo", "bar").stream().min(naturalOrder()).orElseThrow();
}
int testMinOfVarargs() {
return Stream.of(1, 2).min(naturalOrder()).orElseThrow();
}
@@ -135,6 +153,20 @@ final class ComparatorRulesTest implements RefasterRuleCollectionTestCase {
Collections.min(ImmutableSet.of("a", "b"), (a, b) -> 1));
}
ImmutableSet<String> testCollectionsMax() {
return ImmutableSet.of(
Collections.max(ImmutableList.of("foo"), naturalOrder()),
Collections.min(ImmutableList.of("bar"), reverseOrder()));
}
String testMaxOfArray() {
return Arrays.stream(new String[0]).max(naturalOrder()).orElseThrow();
}
String testCollectionsMaxWithComparator() {
return ImmutableSet.of("foo", "bar").stream().max(naturalOrder()).orElseThrow();
}
int testMaxOfVarargs() {
return Stream.of(1, 2).max(naturalOrder()).orElseThrow();
}

View File

@@ -98,6 +98,23 @@ final class ComparatorRulesTest implements RefasterRuleCollectionTestCase {
return ImmutableSet.of("foo".compareTo("bar"), "qux".compareTo("baz"));
}
void testCollectionsSort() {
Collections.sort(ImmutableList.of("foo", "bar"));
}
ImmutableSet<String> testCollectionsMin() {
return ImmutableSet.of(
Collections.min(ImmutableList.of("foo")), Collections.min(ImmutableList.of("bar")));
}
String testMinOfArray() {
return Collections.min(Arrays.asList(new String[0]), naturalOrder());
}
String testCollectionsMinWithComparator() {
return Collections.min(ImmutableSet.of("foo", "bar"), naturalOrder());
}
int testMinOfVarargs() {
return Collections.min(Arrays.asList(1, 2), naturalOrder());
}
@@ -126,6 +143,19 @@ final class ComparatorRulesTest implements RefasterRuleCollectionTestCase {
Comparators.min("a", "b", (a, b) -> 1));
}
ImmutableSet<String> testCollectionsMax() {
return ImmutableSet.of(
Collections.max(ImmutableList.of("foo")), Collections.max(ImmutableList.of("bar")));
}
String testMaxOfArray() {
return Collections.max(Arrays.asList(new String[0]), naturalOrder());
}
String testCollectionsMaxWithComparator() {
return Collections.max(ImmutableSet.of("foo", "bar"), naturalOrder());
}
int testMaxOfVarargs() {
return Collections.max(Arrays.asList(1, 2), naturalOrder());
}

View File

@@ -1,5 +1,6 @@
package tech.picnic.errorprone.refasterrules;
import static java.util.function.Predicate.isEqual;
import static java.util.function.Predicate.not;
import com.google.common.collect.BoundType;
@@ -14,10 +15,10 @@ import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
final class EqualityRulesTest implements RefasterRuleCollectionTestCase {
@Override
public ImmutableSet<Object> elidedTypesAndStaticImports() {
return ImmutableSet.of(Objects.class, Optional.class, not(null));
return ImmutableSet.of(Objects.class, Optional.class, isEqual(null), not(null));
}
ImmutableSet<Boolean> testPrimitiveOrReferenceEquality() {
ImmutableSet<Boolean> testEnumReferenceEquality() {
return ImmutableSet.of(
RoundingMode.UP.equals(RoundingMode.DOWN),
Objects.equals(RoundingMode.UP, RoundingMode.DOWN),
@@ -27,6 +28,10 @@ final class EqualityRulesTest implements RefasterRuleCollectionTestCase {
RoundingMode.UP.ordinal() != RoundingMode.DOWN.ordinal());
}
ImmutableSet<Predicate<RoundingMode>> testEnumReferenceEqualityLambda() {
return ImmutableSet.of(isEqual(RoundingMode.DOWN), RoundingMode.UP::equals);
}
boolean testEqualsPredicate() {
// XXX: When boxing is involved this rule seems to break. Example:
// Stream.of(1).anyMatch(e -> Integer.MIN_VALUE.equals(e));

View File

@@ -1,5 +1,6 @@
package tech.picnic.errorprone.refasterrules;
import static java.util.function.Predicate.isEqual;
import static java.util.function.Predicate.not;
import com.google.common.collect.BoundType;
@@ -14,10 +15,10 @@ import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
final class EqualityRulesTest implements RefasterRuleCollectionTestCase {
@Override
public ImmutableSet<Object> elidedTypesAndStaticImports() {
return ImmutableSet.of(Objects.class, Optional.class, not(null));
return ImmutableSet.of(Objects.class, Optional.class, isEqual(null), not(null));
}
ImmutableSet<Boolean> testPrimitiveOrReferenceEquality() {
ImmutableSet<Boolean> testEnumReferenceEquality() {
return ImmutableSet.of(
RoundingMode.UP == RoundingMode.DOWN,
RoundingMode.UP == RoundingMode.DOWN,
@@ -27,6 +28,10 @@ final class EqualityRulesTest implements RefasterRuleCollectionTestCase {
RoundingMode.UP != RoundingMode.DOWN);
}
ImmutableSet<Predicate<RoundingMode>> testEnumReferenceEqualityLambda() {
return ImmutableSet.of(v -> v == RoundingMode.DOWN, v -> v == RoundingMode.UP);
}
boolean testEqualsPredicate() {
// XXX: When boxing is involved this rule seems to break. Example:
// Stream.of(1).anyMatch(e -> Integer.MIN_VALUE.equals(e));

View File

@@ -1,12 +1,28 @@
package tech.picnic.errorprone.refasterrules;
import com.google.common.collect.ImmutableSet;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
final class FileRulesTest implements RefasterRuleCollectionTestCase {
Path testPathOfUri() {
return Paths.get(URI.create("foo"));
}
ImmutableSet<Path> testPathOfString() {
return ImmutableSet.of(Paths.get("foo"), Paths.get("bar", "baz", "qux"));
}
Path testPathInstance() {
return Path.of("foo").toFile().toPath();
}
String testFilesReadStringWithCharset() throws IOException {
return new String(Files.readAllBytes(Paths.get("foo")), StandardCharsets.ISO_8859_1);
}
@@ -14,4 +30,13 @@ final class FileRulesTest implements RefasterRuleCollectionTestCase {
String testFilesReadString() throws IOException {
return Files.readString(Paths.get("foo"), StandardCharsets.UTF_8);
}
ImmutableSet<File> testFilesCreateTempFileToFile() throws IOException {
return ImmutableSet.of(
File.createTempFile("foo", "bar"), File.createTempFile("baz", "qux", null));
}
File testFilesCreateTempFileInCustomDirectoryToFile() throws IOException {
return File.createTempFile("foo", "bar", new File("baz"));
}
}

View File

@@ -1,12 +1,28 @@
package tech.picnic.errorprone.refasterrules;
import com.google.common.collect.ImmutableSet;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
final class FileRulesTest implements RefasterRuleCollectionTestCase {
Path testPathOfUri() {
return Path.of(URI.create("foo"));
}
ImmutableSet<Path> testPathOfString() {
return ImmutableSet.of(Path.of("foo"), Path.of("bar", "baz", "qux"));
}
Path testPathInstance() {
return Path.of("foo");
}
String testFilesReadStringWithCharset() throws IOException {
return Files.readString(Paths.get("foo"), StandardCharsets.ISO_8859_1);
}
@@ -14,4 +30,13 @@ final class FileRulesTest implements RefasterRuleCollectionTestCase {
String testFilesReadString() throws IOException {
return Files.readString(Paths.get("foo"));
}
ImmutableSet<File> testFilesCreateTempFileToFile() throws IOException {
return ImmutableSet.of(
Files.createTempFile("foo", "bar").toFile(), Files.createTempFile("baz", "qux").toFile());
}
File testFilesCreateTempFileInCustomDirectoryToFile() throws IOException {
return Files.createTempFile(new File("baz").toPath(), "foo", "bar").toFile();
}
}

View File

@@ -32,8 +32,8 @@ final class JUnitToAssertJRulesTest implements RefasterRuleCollectionTestCase {
(Runnable) () -> assertTrue(true));
}
void testThrowNewAssertionError() {
Assertions.fail();
Object testFail() {
return Assertions.fail();
}
Object testFailWithMessage() {
@@ -44,8 +44,8 @@ final class JUnitToAssertJRulesTest implements RefasterRuleCollectionTestCase {
return Assertions.fail("foo", new IllegalStateException());
}
void testFailWithThrowable() {
Assertions.fail(new IllegalStateException());
Object testFailWithThrowable() {
return Assertions.fail(new IllegalStateException());
}
void testAssertThatIsTrue() {

View File

@@ -35,8 +35,8 @@ final class JUnitToAssertJRulesTest implements RefasterRuleCollectionTestCase {
(Runnable) () -> assertTrue(true));
}
void testThrowNewAssertionError() {
throw new AssertionError();
Object testFail() {
return org.assertj.core.api.Assertions.fail();
}
Object testFailWithMessage() {
@@ -47,8 +47,8 @@ final class JUnitToAssertJRulesTest implements RefasterRuleCollectionTestCase {
return org.assertj.core.api.Assertions.fail("foo", new IllegalStateException());
}
void testFailWithThrowable() {
throw new AssertionError(new IllegalStateException());
Object testFailWithThrowable() {
return org.assertj.core.api.Assertions.fail(new IllegalStateException());
}
void testAssertThatIsTrue() {

View File

@@ -83,11 +83,9 @@ final class OptionalRulesTest implements RefasterRuleCollectionTestCase {
return Optional.of("foo").orElseGet(() -> Optional.of("bar").orElseThrow());
}
ImmutableSet<String> testOptionalOrElseGet() {
ImmutableSet<String> testOptionalOrElse() {
return ImmutableSet.of(
Optional.of("foo").orElse("bar"),
Optional.of("baz").orElse(toString()),
Optional.of("qux").orElse(String.valueOf(true)));
Optional.of("foo").orElseGet(() -> "bar"), Optional.of("baz").orElseGet(() -> toString()));
}
ImmutableSet<Object> testStreamFlatMapOptional() {

View File

@@ -80,11 +80,9 @@ final class OptionalRulesTest implements RefasterRuleCollectionTestCase {
return Optional.of("foo").or(() -> Optional.of("bar")).orElseThrow();
}
ImmutableSet<String> testOptionalOrElseGet() {
ImmutableSet<String> testOptionalOrElse() {
return ImmutableSet.of(
Optional.of("foo").orElse("bar"),
Optional.of("baz").orElse(toString()),
Optional.of("qux").orElseGet(() -> String.valueOf(true)));
Optional.of("foo").orElse("bar"), Optional.of("baz").orElseGet(() -> toString()));
}
ImmutableSet<Object> testStreamFlatMapOptional() {

View File

@@ -9,6 +9,8 @@ import com.google.common.primitives.Floats;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
import com.google.common.primitives.Shorts;
import com.google.common.primitives.UnsignedInts;
import com.google.common.primitives.UnsignedLongs;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
final class PrimitiveRulesTest implements RefasterRuleCollectionTestCase {
@@ -22,7 +24,9 @@ final class PrimitiveRulesTest implements RefasterRuleCollectionTestCase {
Floats.class,
Ints.class,
Longs.class,
Shorts.class);
Shorts.class,
UnsignedInts.class,
UnsignedLongs.class);
}
ImmutableSet<Boolean> testLessThan() {
@@ -105,26 +109,6 @@ final class PrimitiveRulesTest implements RefasterRuleCollectionTestCase {
return Doubles.hashCode(1);
}
int testBooleanCompare() {
return Booleans.compare(false, true);
}
int testCharacterCompare() {
return Chars.compare('a', 'b');
}
int testShortCompare() {
return Shorts.compare((short) 1, (short) 2);
}
int testIntegerCompare() {
return Ints.compare(1, 2);
}
int testLongCompare() {
return Longs.compare(1, 2);
}
int testFloatCompare() {
return Floats.compare(1, 2);
}
@@ -190,4 +174,60 @@ final class PrimitiveRulesTest implements RefasterRuleCollectionTestCase {
return ImmutableSet.of(
Long.signum(1L) < 0, Long.signum(2L) <= -1, Long.signum(3L) >= 0, Long.signum(4L) > -1);
}
int testIntegerCompareUnsigned() {
return UnsignedInts.compare(1, 2);
}
long testLongCompareUnsigned() {
return UnsignedLongs.compare(1, 2);
}
int testIntegerDivideUnsigned() {
return UnsignedInts.divide(1, 2);
}
long testLongDivideUnsigned() {
return UnsignedLongs.divide(1, 2);
}
int testIntegerRemainderUnsigned() {
return UnsignedInts.remainder(1, 2);
}
long testLongRemainderUnsigned() {
return UnsignedLongs.remainder(1, 2);
}
ImmutableSet<Integer> testIntegerParseUnsignedInt() {
return ImmutableSet.of(UnsignedInts.parseUnsignedInt("1"), Integer.parseUnsignedInt("2", 10));
}
ImmutableSet<Long> testLongParseUnsignedLong() {
return ImmutableSet.of(UnsignedLongs.parseUnsignedLong("1"), Long.parseUnsignedLong("2", 10));
}
int testIntegerParseUnsignedIntWithRadix() {
return UnsignedInts.parseUnsignedInt("1", 2);
}
long testLongParseUnsignedLongWithRadix() {
return UnsignedLongs.parseUnsignedLong("1", 2);
}
ImmutableSet<String> testIntegerToUnsignedString() {
return ImmutableSet.of(UnsignedInts.toString(1), Integer.toUnsignedString(2, 10));
}
ImmutableSet<String> testLongToUnsignedString() {
return ImmutableSet.of(UnsignedLongs.toString(1), Long.toUnsignedString(2, 10));
}
String testIntegerToUnsignedStringWithRadix() {
return UnsignedInts.toString(1, 2);
}
String testLongToUnsignedStringWithRadix() {
return UnsignedLongs.toString(1, 2);
}
}

View File

@@ -9,6 +9,8 @@ import com.google.common.primitives.Floats;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
import com.google.common.primitives.Shorts;
import com.google.common.primitives.UnsignedInts;
import com.google.common.primitives.UnsignedLongs;
import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase;
final class PrimitiveRulesTest implements RefasterRuleCollectionTestCase {
@@ -22,7 +24,9 @@ final class PrimitiveRulesTest implements RefasterRuleCollectionTestCase {
Floats.class,
Ints.class,
Longs.class,
Shorts.class);
Shorts.class,
UnsignedInts.class,
UnsignedLongs.class);
}
ImmutableSet<Boolean> testLessThan() {
@@ -105,26 +109,6 @@ final class PrimitiveRulesTest implements RefasterRuleCollectionTestCase {
return Double.hashCode(1);
}
int testBooleanCompare() {
return Boolean.compare(false, true);
}
int testCharacterCompare() {
return Character.compare('a', 'b');
}
int testShortCompare() {
return Short.compare((short) 1, (short) 2);
}
int testIntegerCompare() {
return Integer.compare(1, 2);
}
int testLongCompare() {
return Long.compare(1, 2);
}
int testFloatCompare() {
return Float.compare(1, 2);
}
@@ -190,4 +174,60 @@ final class PrimitiveRulesTest implements RefasterRuleCollectionTestCase {
return ImmutableSet.of(
Long.signum(1L) == -1, Long.signum(2L) == -1, Long.signum(3L) != -1, Long.signum(4L) != -1);
}
int testIntegerCompareUnsigned() {
return Integer.compareUnsigned(1, 2);
}
long testLongCompareUnsigned() {
return Long.compareUnsigned(1, 2);
}
int testIntegerDivideUnsigned() {
return Integer.divideUnsigned(1, 2);
}
long testLongDivideUnsigned() {
return Long.divideUnsigned(1, 2);
}
int testIntegerRemainderUnsigned() {
return Integer.remainderUnsigned(1, 2);
}
long testLongRemainderUnsigned() {
return Long.remainderUnsigned(1, 2);
}
ImmutableSet<Integer> testIntegerParseUnsignedInt() {
return ImmutableSet.of(Integer.parseUnsignedInt("1"), Integer.parseUnsignedInt("2"));
}
ImmutableSet<Long> testLongParseUnsignedLong() {
return ImmutableSet.of(Long.parseUnsignedLong("1"), Long.parseUnsignedLong("2"));
}
int testIntegerParseUnsignedIntWithRadix() {
return Integer.parseUnsignedInt("1", 2);
}
long testLongParseUnsignedLongWithRadix() {
return Long.parseUnsignedLong("1", 2);
}
ImmutableSet<String> testIntegerToUnsignedString() {
return ImmutableSet.of(Integer.toUnsignedString(1), Integer.toUnsignedString(2));
}
ImmutableSet<String> testLongToUnsignedString() {
return ImmutableSet.of(Long.toUnsignedString(1), Long.toUnsignedString(2));
}
String testIntegerToUnsignedStringWithRadix() {
return Integer.toUnsignedString(1, 2);
}
String testLongToUnsignedStringWithRadix() {
return Long.toUnsignedString(1, 2);
}
}

View File

@@ -10,6 +10,7 @@ import static java.util.stream.Collectors.minBy;
import static java.util.stream.Collectors.toCollection;
import static org.assertj.core.api.Assertions.assertThat;
import com.github.benmanes.caffeine.cache.AsyncLoadingCache;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -21,7 +22,9 @@ import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;
import java.util.stream.Stream;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.math.MathFlux;
@@ -182,8 +185,8 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
Flux.range(0, 0));
}
Flux<Integer> testFluxJust() {
return Flux.range(0, 1);
ImmutableSet<Flux<Integer>> testFluxJust() {
return ImmutableSet.of(Flux.range(0, 1), Mono.just(2).repeat().take(1));
}
ImmutableSet<Mono<?>> testMonoIdentity() {
@@ -207,11 +210,12 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
ImmutableSet<Flux<Integer>> testFluxConcatMap() {
return ImmutableSet.of(
Flux.just(1).flatMap(Mono::just, 1),
Flux.just(2).flatMapSequential(Mono::just, 1),
Flux.just(3).map(Mono::just).concatMap(identity()),
Flux.just(4).map(Mono::just).concatMap(v -> v),
Flux.just(5).map(Mono::just).concatMap(v -> Mono.empty()));
Flux.just(1).concatMap(Mono::just, 0),
Flux.just(2).flatMap(Mono::just, 1),
Flux.just(3).flatMapSequential(Mono::just, 1),
Flux.just(4).map(Mono::just).concatMap(identity()),
Flux.just(5).map(Mono::just).concatMap(v -> v),
Flux.just(6).map(Mono::just).concatMap(v -> Mono.empty()));
}
ImmutableSet<Flux<Integer>> testFluxConcatMapWithPrefetch() {
@@ -432,8 +436,10 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
Flux.just(ImmutableList.of("bar")).concatMap(Flux::fromIterable, 2));
}
Flux<String> testFluxFromIterable() {
return Flux.fromStream(ImmutableList.of("foo").stream());
ImmutableSet<Flux<String>> testFluxFromIterable() {
return ImmutableSet.of(
Flux.fromStream(ImmutableList.of("foo")::stream),
Flux.fromStream(() -> ImmutableList.of("bar").stream()));
}
ImmutableSet<Mono<Integer>> testFluxCountMapMathToIntExact() {
@@ -650,4 +656,20 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
Duration testStepVerifierLastStepVerifyTimeout() {
return Mono.empty().as(StepVerifier::create).expectTimeout(Duration.ZERO).verify();
}
Mono<Void> testMonoFromFutureSupplier() {
return Mono.fromFuture(CompletableFuture.completedFuture(null));
}
Mono<Void> testMonoFromFutureSupplierBoolean() {
return Mono.fromFuture(CompletableFuture.completedFuture(null), true);
}
Mono<String> testMonoFromFutureAsyncLoadingCacheGet() {
return Mono.fromFuture(() -> ((AsyncLoadingCache<Integer, String>) null).get(0));
}
Flux<Integer> testFluxFromStreamSupplier() {
return Flux.fromStream(Stream.of(1));
}
}

View File

@@ -12,6 +12,7 @@ import static java.util.stream.Collectors.toCollection;
import static org.assertj.core.api.Assertions.assertThat;
import static reactor.function.TupleUtils.function;
import com.github.benmanes.caffeine.cache.AsyncLoadingCache;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -23,7 +24,9 @@ import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;
import java.util.stream.Stream;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.function.TupleUtils;
@@ -186,8 +189,8 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
Flux.empty());
}
Flux<Integer> testFluxJust() {
return Flux.just(0);
ImmutableSet<Flux<Integer>> testFluxJust() {
return ImmutableSet.of(Flux.just(0), Flux.just(2));
}
ImmutableSet<Mono<?>> testMonoIdentity() {
@@ -214,7 +217,8 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
Flux.just(2).concatMap(Mono::just),
Flux.just(3).concatMap(Mono::just),
Flux.just(4).concatMap(Mono::just),
Flux.just(5).map(Mono::just).concatMap(v -> Mono.empty()));
Flux.just(5).concatMap(Mono::just),
Flux.just(6).map(Mono::just).concatMap(v -> Mono.empty()));
}
ImmutableSet<Flux<Integer>> testFluxConcatMapWithPrefetch() {
@@ -427,8 +431,9 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
Flux.just(ImmutableList.of("bar")).concatMapIterable(identity(), 2));
}
Flux<String> testFluxFromIterable() {
return Flux.fromIterable(ImmutableList.of("foo"));
ImmutableSet<Flux<String>> testFluxFromIterable() {
return ImmutableSet.of(
Flux.fromIterable(ImmutableList.of("foo")), Flux.fromIterable(ImmutableList.of("bar")));
}
ImmutableSet<Mono<Integer>> testFluxCountMapMathToIntExact() {
@@ -631,4 +636,20 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
Duration testStepVerifierLastStepVerifyTimeout() {
return Mono.empty().as(StepVerifier::create).verifyTimeout(Duration.ZERO);
}
Mono<Void> testMonoFromFutureSupplier() {
return Mono.fromFuture(() -> CompletableFuture.completedFuture(null));
}
Mono<Void> testMonoFromFutureSupplierBoolean() {
return Mono.fromFuture(() -> CompletableFuture.completedFuture(null), true);
}
Mono<String> testMonoFromFutureAsyncLoadingCacheGet() {
return Mono.fromFuture(() -> ((AsyncLoadingCache<Integer, String>) null).get(0), true);
}
Flux<Integer> testFluxFromStreamSupplier() {
return Flux.fromStream(() -> Stream.of(1));
}
}

View File

@@ -96,4 +96,8 @@ final class StringRulesTest implements RefasterRuleCollectionTestCase {
int testUtf8EncodedLength() {
return "foo".getBytes(UTF_8).length;
}
String testNewStringChar() {
return String.copyValueOf(new char[] {'f', 'o', 'o'});
}
}

View File

@@ -96,4 +96,8 @@ final class StringRulesTest implements RefasterRuleCollectionTestCase {
int testUtf8EncodedLength() {
return Utf8.encodedLength("foo");
}
String testNewStringChar() {
return new String(new char[] {'f', 'o', 'o'});
}
}

View File

@@ -41,7 +41,7 @@ final class TestNGToAssertJRulesTest implements RefasterRuleCollectionTestCase {
}
void testFail() {
throw new AssertionError();
fail();
}
void testFailWithMessage() {

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.16.2-SNAPSHOT</version>
<version>0.18.1-SNAPSHOT</version>
</parent>
<artifactId>error-prone-experimental</artifactId>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.16.2-SNAPSHOT</version>
<version>0.18.1-SNAPSHOT</version>
</parent>
<artifactId>error-prone-guidelines</artifactId>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.16.2-SNAPSHOT</version>
<version>0.18.1-SNAPSHOT</version>
</parent>
<artifactId>error-prone-utils</artifactId>

View File

@@ -2,205 +2,35 @@
set -e -u -o pipefail
integration_test_root="$(cd "$(dirname -- "${0}")" && pwd)"
error_prone_support_root="${integration_test_root}/.."
repos_root="${integration_test_root}/.repos"
test_name="$(basename "${0}" .sh)"
project=checkstyle
repository=https://github.com/checkstyle/checkstyle.git
revision=checkstyle-10.14.0
if [ "${#}" -gt 2 ] || ([ "${#}" = 2 ] && [ "${1:---sync}" != '--sync' ]); then
echo "Usage: ${0} [--sync] [<report_directory>]"
exit 1
fi
do_sync="$([ "${#}" = 0 ] || [ "${1:-}" != '--sync' ] || echo 1)"
report_directory="$([ "${#}" = 0 ] || ([ -z "${do_sync}" ] && echo "${1}") || ([ "${#}" = 1 ] || echo "${2}"))"
if [ -n "${report_directory}" ]; then
mkdir -p "${report_directory}"
else
report_directory="$(mktemp -d)"
trap 'rm -rf -- "${report_directory}"' INT TERM HUP EXIT
fi
case "$(uname -s)" in
Linux*)
grep_command=grep
sed_command=sed
;;
Darwin*)
grep_command=ggrep
sed_command=gsed
;;
*)
echo "Unsupported distribution $(uname -s) for this script."
exit 1
;;
esac
project='checkstyle'
repository='https://github.com/checkstyle/checkstyle.git'
revision='checkstyle-10.14.0'
# XXX: Configure Renovate to manage the AssertJ version declared here.
shared_build_flags="
-Perror-prone-compile,error-prone-test-compile
-Dassertj.version=3.24.2
-Derror-prone.version=$(
mvn -f "${error_prone_support_root}" help:evaluate -Dexpression=version.error-prone -q -DforceStdout
)
-Derror-prone-support.version=$(
mvn -f "${error_prone_support_root}" help:evaluate -Dexpression=project.version -q -DforceStdout
)
-DadditionalSourceDirectories=\${project.basedir}\${file.separator}src\${file.separator}it\${file.separator}java,\${project.basedir}\${file.separator}src\${file.separator}xdocs-examples\${file.separator}java
"
# XXX: Configure Renovate to manage the fmt-maven-plugin version declared here.
# XXX: Once GitHub actions uses Maven 3.9.2+, we can inline this variable with
# version reference `${fmt.version}`, and `-Dfmt.version=2.21.1` added to
# `shared_build_flags`.
format_goal='com.spotify.fmt:fmt-maven-plugin:2.21.1:format'
error_prone_shared_flags='-XepExcludedPaths:(\Q${project.basedir}${file.separator}src${file.separator}\E(it|test|xdocs-examples)\Q${file.separator}resources\E|\Q${project.build.directory}${file.separator}\E).*'
error_prone_patch_flags="${error_prone_shared_flags} -XepPatchLocation:IN_PLACE -XepPatchChecks:$(
find "${error_prone_support_root}" \
-path "*/META-INF/services/com.google.errorprone.bugpatterns.BugChecker" \
-not -path "*/error-prone-experimental/*" \
-not -path "*/error-prone-guidelines/*" \
-print0 \
| xargs -0 "${grep_command}" -hoP '[^.]+$' \
| paste -s -d ',' -
)"
error_prone_validation_flags="${error_prone_shared_flags} -XepDisableAllChecks $(
find "${error_prone_support_root}" \
-path "*/META-INF/services/com.google.errorprone.bugpatterns.BugChecker" \
-not -path "*/error-prone-experimental/*" \
-not -path "*/error-prone-guidelines/*" \
-print0 \
| xargs -0 "${grep_command}" -hoP '[^.]+$' \
| "${sed_command}" -r 's,(.*),-Xep:\1:WARN,' \
| paste -s -d ' ' -
)"
echo "Shared build flags: ${shared_build_flags}"
echo "Error Prone patch flags: ${error_prone_patch_flags}"
echo "Error Prone validation flags: ${error_prone_validation_flags}"
mkdir -p "${repos_root}"
# Make sure that the targeted tag of the project's Git repository is checked
# out.
project_root="${repos_root}/${project}"
if [ ! -d "${project_root}" ]; then
# The repository has not yet been cloned; create a shallow clone.
git clone --branch "${revision}" --depth 1 "${repository}" "${project_root}"
else
# The repository does already appear to exist. Try to check out the requested
# tag if possible, and fetch it otherwise.
#
# Under certain circumstances this does not cause the relevant tag to be
# created, so if necessary we manually create it.
git -C "${project_root}" checkout --force "${revision}" 2>/dev/null \
|| (
git -C "${project_root}" fetch --depth 1 "${repository}" "${revision}" \
&& git -C "${project_root}" checkout --force FETCH_HEAD \
&& (git -C "${project_root}" tag "${revision}" || true)
)
fi
pushd "${project_root}"
# Make sure that Git is sufficiently configured to enable committing to the
# project's Git repository.
git config user.email || git config user.email "integration-test@example.com"
git config user.name || git config user.name "Integration Test"
# Prepare the code for analysis by (a) applying the minimal set of changes
# required to run Error Prone with Error Prone Support and (b) formatting the
# code using the same method by which it will be formatted after each
# compilation round. The initial formatting operation ensures that subsequent
# modifications can be rendered in a clean manner.
git clean -fdx
git apply < "${integration_test_root}/${test_name}-init.patch"
git commit -m 'dependency: Introduce Error Prone Support' .
mvn ${shared_build_flags} "${format_goal}"
git commit -m 'minor: Reformat using Google Java Format' .
diff_base="$(git rev-parse HEAD)"
# Apply Error Prone Support-suggested changes until a fixed point is reached.
function apply_patch() {
local extra_build_args="${1}"
mvn ${shared_build_flags} ${extra_build_args} \
package "${format_goal}" \
-Derror-prone.configuration-args="${error_prone_patch_flags}" \
-DskipTests
if ! git diff --exit-code; then
git commit -m 'minor: Apply patches' .
# Changes were applied, so another compilation round may apply yet more
# changes. For performance reasons we perform incremental compilation,
# enabled using a misleading flag. (See
# https://issues.apache.org/jira/browse/MCOMPILER-209 for details.)
apply_patch '-Dmaven.compiler.useIncrementalCompilation=false'
elif [ "${extra_build_args}" != 'clean' ]; then
# No changes were applied. We'll attempt one more round in which all files
# are recompiled, because there are cases in which violations are missed
# during incremental compilation.
apply_patch 'clean'
fi
}
apply_patch ''
# Run one more full build and log the output.
#
# By also running the tests, we validate that the (majority of) applied changes
# are behavior preserving. Some tests are skipped:
additional_build_flags='-Dassertj.version=3.24.2'
additional_source_directories='${project.basedir}${file.separator}src${file.separator}it${file.separator}java,${project.basedir}${file.separator}src${file.separator}xdocs-examples${file.separator}java'
patch_error_prone_flags=''
validation_error_prone_flags=''
# Validation skips some tests:
# - The `metadataFilesGenerationAllFiles` test is skipped because it makes line
# number assertions that will fail when the code is formatted or patched.
# - The `allCheckSectionJavaDocs` test is skipped because is validates that
# - The `allCheckSectionJavaDocs` test is skipped because it validates that
# Javadoc has certain closing tags that are removed by Google Java Format.
validation_build_log="${report_directory}/${test_name}-validation-build-log.txt"
mvn ${shared_build_flags} \
clean package \
-Derror-prone.configuration-args="${error_prone_validation_flags}" \
-Dtest='
!MetadataGeneratorUtilTest#metadataFilesGenerationAllFiles,
!XdocsJavaDocsTest#allCheckSectionJavaDocs' \
| tee "${validation_build_log}" \
|| failure=1
validation_build_flags='-Dtest=!MetadataGeneratorUtilTest#metadataFilesGenerationAllFiles,!XdocsJavaDocsTest#allCheckSectionJavaDocs'
# Collect the applied changes.
expected_changes="${integration_test_root}/${test_name}-expected-changes.patch"
actual_changes="${report_directory}/${test_name}-changes.patch"
(git diff "${diff_base}"..HEAD | "${grep_command}" -vP '^(diff|index)' || true) > "${actual_changes}"
# Collect the warnings reported by Error Prone Support checks.
expected_warnings="${integration_test_root}/${test_name}-expected-warnings.txt"
actual_warnings="${report_directory}/${test_name}-validation-build-warnings.txt"
("${grep_command}" -oP "(?<=^\\Q[WARNING] ${PWD}/\\E).*" "${validation_build_log}" | "${grep_command}" -P '\] \[' || true) | LC_ALL=C sort > "${actual_warnings}"
# Persist or validate the applied changes and reported warnings.
if [ -n "${do_sync}" ]; then
echo 'Saving changes...'
cp "${actual_changes}" "${expected_changes}"
cp "${actual_warnings}" "${expected_warnings}"
else
echo 'Inspecting changes...'
# XXX: This "diff of diffs" also contains vacuous sections, introduced due to
# line offset differences. Try to omit those from the final output.
if ! diff -u "${expected_changes}" "${actual_changes}"; then
echo 'There are unexpected changes. Inspect the preceding output for details.'
failure=1
fi
echo 'Inspecting emitted warnings...'
if ! diff -u "${expected_warnings}" "${actual_warnings}"; then
echo 'Diagnostics output changed. Inspect the preceding output for details.'
failure=1
fi
fi
if [ -n "${failure:-}" ]; then
if [ "${#}" -gt 2 ] || ([ "${#}" = 2 ] && [ "${1:---sync}" != '--sync' ]); then
>&2 echo "Usage: ${0} [--sync] [<report_directory>]"
exit 1
fi
"$(dirname "${0}")/run-integration-test.sh" \
"${test_name}" \
"${project}" \
"${repository}" \
"${revision}" \
"${additional_build_flags}" \
"${additional_source_directories}" \
"${patch_error_prone_flags}" \
"${validation_error_prone_flags}" \
"${validation_build_flags}" \
$@

View File

@@ -0,0 +1,210 @@
#!/usr/bin/env bash
# Integration test framework for Maven builds.
#
# This script is not meant to be invoked manually. Instead it should be invoked
# through one of the top-level integration test scripts, such as
# `checkstyle.sh`.
set -e -u -o pipefail
integration_test_root="$(cd "$(dirname -- "${0}")" && pwd)"
error_prone_support_root="${integration_test_root}/.."
repos_root="${integration_test_root}/.repos"
if [ "${#}" -lt 9 ] || [ "${#}" -gt 11 ] || ([ "${#}" = 11 ] && [ "${10:---sync}" != '--sync' ]); then
>&2 echo "Usage: $(basename "${0}") <test_name> <project> <repository> <revision> <additional_build_flags> <additional_source_directories> <patch_error_prone_flags> <validation_error_prone_flags> <validation_build_flags> [--sync] [<report_directory>]"
exit 1
fi
test_name="${1}"
project="${2}"
repository="${3}"
revision="${4}"
additional_build_flags="${5}"
additional_source_directories="${6}"
patch_error_prone_flags="${7}"
validation_error_prone_flags="${8}"
validation_build_flags="${9}"
do_sync="$([ "${#}" = 9 ] || [ "${10:-}" != '--sync' ] || echo 1)"
report_directory="$([ "${#}" = 9 ] || ([ -z "${do_sync}" ] && echo "${10}") || ([ "${#}" = 10 ] || echo "${11}"))"
if [ -n "${report_directory}" ]; then
mkdir -p "${report_directory}"
else
report_directory="$(mktemp -d)"
trap 'rm -rf -- "${report_directory}"' INT TERM HUP EXIT
fi
case "$(uname -s)" in
Linux*)
grep_command=grep
sed_command=sed
;;
Darwin*)
grep_command=ggrep
sed_command=gsed
;;
*)
echo "Unsupported distribution $(uname -s) for this script."
exit 1
;;
esac
shared_build_flags="
-Perror-prone-compile,error-prone-test-compile
-Derror-prone.version=$(
mvn -f "${error_prone_support_root}" help:evaluate -Dexpression=version.error-prone -q -DforceStdout
)
-Derror-prone-support.version=$(
mvn -f "${error_prone_support_root}" help:evaluate -Dexpression=project.version -q -DforceStdout
)
-DadditionalSourceDirectories=${additional_source_directories}
${additional_build_flags}
"
# XXX: Configure Renovate to manage the fmt-maven-plugin version declared here.
# XXX: Once GitHub actions uses Maven 3.9.2+, we can inline this variable with
# version reference `${fmt.version}`, and `-Dfmt.version=2.21.1` added to
# `shared_build_flags`.
format_goal='com.spotify.fmt:fmt-maven-plugin:2.21.1:format'
error_prone_shared_flags='-XepExcludedPaths:(\Q${project.basedir}${file.separator}src${file.separator}\E(it|test|xdocs-examples)\Q${file.separator}resources\E|\Q${project.build.directory}${file.separator}\E).*'
error_prone_patch_flags="${error_prone_shared_flags} -XepPatchLocation:IN_PLACE -XepPatchChecks:$(
find "${error_prone_support_root}" \
-path "*/META-INF/services/com.google.errorprone.bugpatterns.BugChecker" \
-not -path "*/error-prone-experimental/*" \
-not -path "*/error-prone-guidelines/*" \
-print0 \
| xargs -0 "${grep_command}" -hoP '[^.]+$' \
| paste -s -d ',' -
) ${patch_error_prone_flags}"
error_prone_validation_flags="${error_prone_shared_flags} -XepDisableAllChecks $(
find "${error_prone_support_root}" \
-path "*/META-INF/services/com.google.errorprone.bugpatterns.BugChecker" \
-not -path "*/error-prone-experimental/*" \
-not -path "*/error-prone-guidelines/*" \
-print0 \
| xargs -0 "${grep_command}" -hoP '[^.]+$' \
| "${sed_command}" -r 's,(.*),-Xep:\1:WARN,' \
| paste -s -d ' ' -
) ${validation_error_prone_flags}"
echo "Shared build flags: ${shared_build_flags}"
echo "Error Prone patch flags: ${error_prone_patch_flags}"
echo "Error Prone validation flags: ${error_prone_validation_flags}"
mkdir -p "${repos_root}"
# Make sure that the targeted tag of the project's Git repository is checked
# out.
project_root="${repos_root}/${project}"
if [ ! -d "${project_root}" ]; then
# The repository has not yet been cloned; create a shallow clone.
git clone --branch "${revision}" --depth 1 "${repository}" "${project_root}"
else
# The repository does already appear to exist. Try to check out the requested
# tag if possible, and fetch it otherwise.
#
# Under certain circumstances this does not cause the relevant tag to be
# created, so if necessary we manually create it.
git -C "${project_root}" checkout --force "${revision}" 2>/dev/null \
|| (
git -C "${project_root}" fetch --depth 1 "${repository}" "${revision}" \
&& git -C "${project_root}" checkout --force FETCH_HEAD \
&& (git -C "${project_root}" tag "${revision}" || true)
)
fi
pushd "${project_root}"
# Make sure that Git is sufficiently configured to enable committing to the
# project's Git repository.
git config user.email || git config user.email 'integration-test@example.com'
git config user.name || git config user.name 'Integration Test'
# Prepare the code for analysis by (a) applying the minimal set of changes
# required to run Error Prone with Error Prone Support and (b) formatting the
# code using the same method by which it will be formatted after each
# compilation round. The initial formatting operation ensures that subsequent
# modifications can be rendered in a clean manner.
git clean -fdx
git apply < "${integration_test_root}/${test_name}-init.patch"
git commit -m 'dependency: Introduce Error Prone Support' .
mvn ${shared_build_flags} "${format_goal}"
git commit -m 'minor: Reformat using Google Java Format' .
diff_base="$(git rev-parse HEAD)"
# Apply Error Prone Support-suggested changes until a fixed point is reached.
function apply_patch() {
local extra_build_args="${1}"
mvn ${shared_build_flags} ${extra_build_args} \
package "${format_goal}" \
-Derror-prone.configuration-args="${error_prone_patch_flags}" \
-DskipTests
if ! git diff --exit-code; then
git commit -m 'minor: Apply patches' .
# Changes were applied, so another compilation round may apply yet more
# changes. For performance reasons we perform incremental compilation,
# enabled using a misleading flag. (See
# https://issues.apache.org/jira/browse/MCOMPILER-209 for details.)
apply_patch '-Dmaven.compiler.useIncrementalCompilation=false'
elif [ "${extra_build_args}" != 'clean' ]; then
# No changes were applied. We'll attempt one more round in which all files
# are recompiled, because there are cases in which violations are missed
# during incremental compilation.
apply_patch 'clean'
fi
}
apply_patch ''
# Run one more full build and log the output.
#
# By also running the tests, we validate that the (majority of) applied changes
# are behavior preserving.
validation_build_log="${report_directory}/${test_name}-validation-build-log.txt"
mvn ${shared_build_flags} \
clean package \
-Derror-prone.configuration-args="${error_prone_validation_flags}" \
${validation_build_flags} \
| tee "${validation_build_log}" \
|| failure=1
# Collect the applied changes.
expected_changes="${integration_test_root}/${test_name}-expected-changes.patch"
actual_changes="${report_directory}/${test_name}-changes.patch"
(git diff "${diff_base}"..HEAD | "${grep_command}" -vP '^(diff|index)' || true) > "${actual_changes}"
# Collect the warnings reported by Error Prone Support checks.
expected_warnings="${integration_test_root}/${test_name}-expected-warnings.txt"
actual_warnings="${report_directory}/${test_name}-validation-build-warnings.txt"
("${grep_command}" -oP "(?<=^\\Q[WARNING] ${PWD}/\\E).*" "${validation_build_log}" | "${grep_command}" -P '\] \[' || true) | LC_ALL=C sort > "${actual_warnings}"
# Persist or validate the applied changes and reported warnings.
if [ -n "${do_sync}" ]; then
echo 'Saving changes...'
cp "${actual_changes}" "${expected_changes}"
cp "${actual_warnings}" "${expected_warnings}"
else
echo 'Inspecting changes...'
# XXX: This "diff of diffs" also contains vacuous sections, introduced due to
# line offset differences. Try to omit those from the final output.
if ! diff -u "${expected_changes}" "${actual_changes}"; then
echo 'There are unexpected changes. Inspect the preceding output for details.'
failure=1
fi
echo 'Inspecting emitted warnings...'
if ! diff -u "${expected_warnings}" "${actual_warnings}"; then
echo 'Diagnostics output changed. Inspect the preceding output for details.'
failure=1
fi
fi
if [ -n "${failure:-}" ]; then
exit 1
fi

174
pom.xml
View File

@@ -4,7 +4,7 @@
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.16.2-SNAPSHOT</version>
<version>0.18.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Picnic :: Error Prone Support</name>
@@ -148,7 +148,7 @@
<groupId.error-prone>com.google.errorprone</groupId.error-prone>
<!-- The build timestamp is derived from the most recent commit
timestamp in support of reproducible builds. -->
<project.build.outputTimestamp>2024-03-15T12:04:44Z</project.build.outputTimestamp>
<project.build.outputTimestamp>2024-08-11T13:05:54Z</project.build.outputTimestamp>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- Glob pattern identifying Refaster rule definition files. These
Java classes don't contain "regular" code, and thus require special
@@ -205,19 +205,19 @@
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.4</version.auto-value>
<version.auto-value>1.11.0</version.auto-value>
<version.error-prone>${version.error-prone-orig}</version.error-prone>
<version.error-prone-fork>v${version.error-prone-orig}-picnic-1</version.error-prone-fork>
<version.error-prone-orig>2.27.1</version.error-prone-orig>
<version.error-prone-slf4j>0.1.24</version.error-prone-slf4j>
<version.error-prone-orig>2.31.0</version.error-prone-orig>
<version.error-prone-slf4j>0.1.25</version.error-prone-slf4j>
<version.guava-beta-checker>1.0</version.guava-beta-checker>
<version.jdk>17</version.jdk>
<version.maven>3.9.5</version.maven>
<version.mockito>5.11.0</version.mockito>
<version.maven>3.9.9</version.maven>
<version.mockito>5.13.0</version.mockito>
<version.nopen-checker>1.0.1</version.nopen-checker>
<version.nullaway>0.10.26</version.nullaway>
<version.nullaway>0.11.2</version.nullaway>
<version.pitest-git>1.1.4</version.pitest-git>
<version.rewrite-templating>1.8.1</version.rewrite-templating>
<version.rewrite-templating>1.14.0</version.rewrite-templating>
<version.surefire>3.2.3</version.surefire>
</properties>
@@ -296,10 +296,15 @@
<dependency>
<groupId>com.fasterxml.jackson</groupId>
<artifactId>jackson-bom</artifactId>
<version>2.17.1</version>
<version>2.17.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>3.1.8</version>
</dependency>
<dependency>
<groupId>com.google.auto</groupId>
<artifactId>auto-common</artifactId>
@@ -328,7 +333,7 @@
<dependency>
<groupId>com.google.googlejavaformat</groupId>
<artifactId>google-java-format</artifactId>
<version>1.22.0</version>
<version>1.23.0</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
@@ -338,14 +343,14 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava-bom</artifactId>
<version>33.2.0-jre</version>
<version>33.3.0-jre</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.google.truth</groupId>
<artifactId>truth</artifactId>
<version>1.4.2</version>
<version>1.4.4</version>
</dependency>
<dependency>
<groupId>com.jakewharton.nopen</groupId>
@@ -360,7 +365,7 @@
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-bom</artifactId>
<version>2023.0.5</version>
<version>2023.0.9</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@@ -377,12 +382,17 @@
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
<version>2.2.21</version>
<version>2.2.23</version>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.0.0</version>
<version>6.1.0</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
@@ -407,7 +417,7 @@
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>1.14.14</version>
<version>1.15.1</version>
</dependency>
<!-- Specified so that Renovate will file Maven upgrade PRs, which
subsequently will cause `maven-enforcer-plugin` to require that
@@ -420,24 +430,24 @@
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.22</version>
<version>1.9.22.1</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-bom</artifactId>
<version>3.25.3</version>
<version>3.26.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.checkerframework</groupId>
<artifactId>checker-qual</artifactId>
<version>3.43.0</version>
<version>3.46.0</version>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>2.2</version>
<version>3.0</version>
</dependency>
<dependency>
<groupId>org.immutables</groupId>
@@ -447,12 +457,12 @@
<dependency>
<groupId>org.jspecify</groupId>
<artifactId>jspecify</artifactId>
<version>0.3.0</version>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.10.2</version>
<version>5.11.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@@ -466,7 +476,7 @@
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-core</artifactId>
<version>5.1.0</version>
<version>5.1.3</version>
</dependency>
<dependency>
<groupId>org.openrewrite</groupId>
@@ -476,33 +486,33 @@
<dependency>
<groupId>org.openrewrite.recipe</groupId>
<artifactId>rewrite-recipe-bom</artifactId>
<version>2.11.0</version>
<version>2.17.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-bom</artifactId>
<version>2.0.13</version>
<version>2.0.16</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>6.1.6</version>
<version>6.1.12</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<version>3.2.5</version>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-bom</artifactId>
<version>6.2.4</version>
<version>6.3.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@@ -520,7 +530,7 @@
<plugin>
<groupId>com.github.ekryd.sortpom</groupId>
<artifactId>sortpom-maven-plugin</artifactId>
<version>3.4.1</version>
<version>4.0.0</version>
<configuration>
<createBackupFile>false</createBackupFile>
<encoding>${project.build.sourceEncoding}</encoding>
@@ -557,7 +567,7 @@
<plugin>
<groupId>com.spotify.fmt</groupId>
<artifactId>fmt-maven-plugin</artifactId>
<version>2.22.1</version>
<version>2.24</version>
<configuration>
<additionalSourceDirectories>
<additionalSourceDirectory>${basedir}/src/test/resources</additionalSourceDirectory>
@@ -624,7 +634,7 @@
<plugin>
<groupId>io.github.git-commit-id</groupId>
<artifactId>git-commit-id-maven-plugin</artifactId>
<version>8.0.2</version>
<version>9.0.1</version>
<configuration>
<injectAllReactorProjects>true</injectAllReactorProjects>
<runOnlyOnce>true</runOnlyOnce>
@@ -643,7 +653,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.3.1</version>
<version>3.5.0</version>
<configuration>
<checkstyleRules>
<!-- We only enable rules that are not enforced by
@@ -679,6 +689,7 @@
<property name="allowNonPrintableEscapes" value="true" />
</module>
<module name="AvoidNoArgumentSuperConstructorCall" />
<module name="ConstructorsDeclarationGrouping" />
<module name="DeclarationOrder">
<!-- We don't enforce sorting fields by
their visibility modifier, for two
@@ -891,7 +902,7 @@
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>10.16.0</version>
<version>10.18.0</version>
</dependency>
<dependency>
<groupId>io.spring.nohttp</groupId>
@@ -911,7 +922,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>3.3.2</version>
<version>3.4.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -959,11 +970,43 @@
https://issues.apache.org/jira/browse/MCOMPILER-209. -->
<useIncrementalCompilation>false</useIncrementalCompilation>
</configuration>
<executions>
<!-- OpenRewrite recipe sources, generated by the
`rewrite-templating` annotation processor and
identified as classes whose name ends in `Recipes`, are
compiled to target Java 8 for compatibility with the
wider OpenRewrite ecosystem. The `maven-jar-plugin` is
configured to package these files into a separate JAR. -->
<execution>
<id>compile-recipes</id>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<compilerArgs combine.self="override">
<!-- When Java 8 is targeted we can't use
the `add-exports` flag. And since this goal
only recompiles already-compiled code,
static analysis is irrelevant. As such we
clear all compiler arguments, and only
suppress source/target/bootstrap classpath
warnings. -->
<arg>-Xlint:-options</arg>
</compilerArgs>
<source>8</source>
<target>8</target>
<includes>
<include>**/*Recipes.java</include>
</includes>
<outputDirectory>${project.build.directory}/openrewrite-recipes</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.6.1</version>
<version>3.7.1</version>
<configuration>
<!-- XXX: Drop `ignoreAllNonTestScoped` once
https://issues.apache.org/jira/browse/MNG-6058 is
@@ -986,7 +1029,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.4.1</version>
<version>3.5.0</version>
<configuration>
<fail>false</fail>
<rules>
@@ -1041,6 +1084,9 @@
<requireJavaVersion>
<version>${version.jdk}</version>
</requireJavaVersion>
<requireMatchingCoordinates>
<moduleNameMustMatchArtifactId>true</moduleNameMustMatchArtifactId>
</requireMatchingCoordinates>
<requireMavenVersion>
<version>${version.maven}</version>
</requireMavenVersion>
@@ -1068,7 +1114,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>3.2.4</version>
<version>3.2.5</version>
<executions>
<execution>
<id>sign-artifacts</id>
@@ -1086,7 +1132,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.4.1</version>
<version>3.4.2</version>
<configuration>
<skipIfEmpty>true</skipIfEmpty>
<archive>
@@ -1103,6 +1149,39 @@
</archive>
</configuration>
<executions>
<execution>
<id>default-jar</id>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<!-- These Java 17 bytecode classes are omitted
from the default JAR, as instead we produce a
separate artifact with Java 8 bytecode variants. -->
<excludes>
<excludes>**/*Recipe$*.class</excludes>
<excludes>**/*Recipe.class</excludes>
<excludes>**/*Recipes.class</excludes>
</excludes>
</configuration>
</execution>
<execution>
<!-- Creates a custom JAR with Java 8-compatible
OpenRewrite recipe classes. -->
<id>create-openrewrite-recipes-jar</id>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classesDirectory>${project.build.directory}/openrewrite-recipes</classesDirectory>
<classifier>recipes</classifier>
<includes>
<includes>**/*Recipe$*.class</includes>
<includes>**/*Recipe.class</includes>
<includes>**/*Recipes.class</includes>
</includes>
</configuration>
</execution>
<execution>
<id>create-test-jar</id>
<goals>
@@ -1114,7 +1193,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.6.3</version>
<version>3.8.0</version>
<configuration>
<additionalJOptions>
<additionalJOption>--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</additionalJOption>
@@ -1143,7 +1222,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>3.0.1</version>
<version>3.1.1</version>
<configuration>
<autoVersionSubmodules>true</autoVersionSubmodules>
<preparationProfiles>release</preparationProfiles>
@@ -1184,7 +1263,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
<version>3.3.1</version>
<configuration>
<includes>
<include>**/*Test.java</include>
@@ -1200,7 +1279,7 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.5.0</version>
<version>3.6.0</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
@@ -1296,6 +1375,7 @@
<!-- -->
GPL-2.0-with-classpath-exception
| CDDL/GPLv2+CE
| CDDL + GPLv2 with classpath exception
| GNU General Public License, version 2 (GPL2), with the classpath exception
| GNU General Public License, version 2, with the Classpath Exception
| GPL2 w/ CPE
@@ -1330,7 +1410,7 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tidy-maven-plugin</artifactId>
<version>1.2.0</version>
<version>1.3.0</version>
<executions>
<execution>
<id>check-pom</id>
@@ -1343,7 +1423,7 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.16.2</version>
<version>2.17.1</version>
<configuration>
<updateBuildOutputTimestampPolicy>never</updateBuildOutputTimestampPolicy>
</configuration>
@@ -1351,7 +1431,7 @@
<plugin>
<groupId>org.gaul</groupId>
<artifactId>modernizer-maven-plugin</artifactId>
<version>2.8.0</version>
<version>2.9.0</version>
<configuration>
<exclusionPatterns>
<!-- The plugin suggests replacing usages of
@@ -1466,7 +1546,7 @@
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>3.11.0.3922</version>
<version>4.0.0.4121</version>
</plugin>
</plugins>
</pluginManagement>

View File

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

View File

@@ -21,7 +21,6 @@ import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.PackageSymbol;
import com.sun.tools.javac.main.JavaCompiler;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Name;
import java.io.IOException;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
@@ -137,10 +136,10 @@ final class RefasterRuleCompilerTaskListener implements TaskListener {
return enclosingPackage == null ? "" : enclosingPackage.toString();
}
private static CharSequence toSimpleFlatName(ClassSymbol symbol) {
Name flatName = symbol.flatName();
private static String toSimpleFlatName(ClassSymbol symbol) {
String flatName = symbol.flatName().toString();
int lastDot = flatName.lastIndexOf((byte) '.');
return lastDot < 0 ? flatName : flatName.subSequence(lastDot + 1, flatName.length());
return lastDot < 0 ? flatName : flatName.substring(lastDot + 1);
}
private static void outputCodeTransformer(CodeTransformer codeTransformer, FileObject target)

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.16.2-SNAPSHOT</version>
<version>0.18.1-SNAPSHOT</version>
</parent>
<artifactId>refaster-runner</artifactId>
@@ -58,6 +58,11 @@
<artifactId>guava</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>

View File

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

View File

@@ -2,6 +2,7 @@ package tech.picnic.errorprone.refaster.matchers;
import com.google.errorprone.VisitorState;
import com.google.errorprone.matchers.Matcher;
import com.google.errorprone.util.ASTHelpers;
import com.sun.source.tree.ArrayAccessTree;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.IdentifierTree;
@@ -9,34 +10,19 @@ import com.sun.source.tree.LambdaExpressionTree;
import com.sun.source.tree.LiteralTree;
import com.sun.source.tree.MemberReferenceTree;
import com.sun.source.tree.MemberSelectTree;
import com.sun.source.tree.MethodInvocationTree;
import com.sun.source.tree.ParenthesizedTree;
import com.sun.source.tree.TypeCastTree;
import com.sun.source.tree.UnaryTree;
/** A matcher of expressions that likely require little to no computation. */
public final class IsLikelyTrivialComputation implements Matcher<ExpressionTree> {
/** A matcher of expressions that may a non-trivial amount of computation. */
public final class RequiresComputation implements Matcher<ExpressionTree> {
private static final long serialVersionUID = 1L;
/** Instantiates a new {@link IsLikelyTrivialComputation} instance. */
public IsLikelyTrivialComputation() {}
/** Instantiates a new {@link RequiresComputation} instance. */
public RequiresComputation() {}
@Override
public boolean matches(ExpressionTree expressionTree, VisitorState state) {
if (expressionTree instanceof MethodInvocationTree methodInvocation) {
// XXX: Method invocations are generally *not* trivial computations, but we make an exception
// for nullary method invocations on the result of a trivial computation. This exception
// allows this `Matcher` to by the `OptionalOrElseGet` Refaster rule, such that it does not
// suggest the introduction of lambda expressions that are better expressed as method
// references. Once the `MethodReferenceUsage` bug checker is production-ready, this exception
// should be removed. (But at that point, instead defining a `RequiresComputation` matcher may
// be more appropriate.)
if (methodInvocation.getArguments().isEmpty()
&& matches(methodInvocation.getMethodSelect())) {
return true;
}
}
return matches(expressionTree);
}
@@ -44,11 +30,11 @@ public final class IsLikelyTrivialComputation implements Matcher<ExpressionTree>
// Depending on feedback such trees may be matched in the future.
private static boolean matches(ExpressionTree expressionTree) {
if (expressionTree instanceof ArrayAccessTree arrayAccess) {
return matches(arrayAccess.getExpression()) && matches(arrayAccess.getIndex());
return matches(arrayAccess.getExpression()) || matches(arrayAccess.getIndex());
}
if (expressionTree instanceof LiteralTree) {
return true;
return false;
}
if (expressionTree instanceof LambdaExpressionTree) {
@@ -56,11 +42,14 @@ public final class IsLikelyTrivialComputation implements Matcher<ExpressionTree>
* Lambda expressions encapsulate computations, but their definition does not involve
* significant computation.
*/
return true;
return false;
}
if (expressionTree instanceof IdentifierTree) {
return true;
// XXX: Generally identifiers don't by themselves represent a computation, though they may be
// a stand-in for one if they are a Refaster template method argument. Can we identify such
// cases, also when the `Matcher` is invoked by Refaster?
return false;
}
if (expressionTree instanceof MemberReferenceTree memberReference) {
@@ -80,11 +69,11 @@ public final class IsLikelyTrivialComputation implements Matcher<ExpressionTree>
}
if (expressionTree instanceof UnaryTree unary) {
// XXX: Arguably side-effectful options such as pre- and post-increment and -decrement are not
// trivial.
// XXX: Arguably side-effectful options such as pre- and post-increment and -decrement
// represent non-trivial computations.
return matches(unary.getExpression());
}
return false;
return ASTHelpers.constValue(expressionTree) == null;
}
}

View File

@@ -8,54 +8,69 @@ import com.google.errorprone.bugpatterns.BugChecker;
import com.sun.source.tree.ReturnTree;
import org.junit.jupiter.api.Test;
final class IsLikelyTrivialComputationTest {
final class RequiresComputationTest {
@Test
void matches() {
CompilationTestHelper.newInstance(MatcherTestChecker.class, getClass())
.addSourceLines(
"A.java",
"import java.io.OutputStream;",
"import java.util.Comparator;",
"import java.util.function.Predicate;",
"",
"class A {",
" String negative1() {",
" return String.valueOf(1);",
" int negative1() {",
" int[] arr = new int[0];",
" return arr[0];",
" }",
"",
" String negative2() {",
" return toString().toString();",
" return null;",
" }",
"",
" String negative3() {",
" return \"foo\" + toString();",
" boolean negative3() {",
" return false;",
" }",
"",
" byte negative4() {",
" return \"foo\".getBytes()[0];",
" int negative4() {",
" return 0;",
" }",
"",
" int negative5() {",
" int[] arr = new int[0];",
" return arr[hashCode()];",
" String negative5() {",
" return \"foo\" + \"bar\";",
" }",
"",
" int negative6() {",
" return 1 * 2;",
" Predicate<String> negative6() {",
" return v -> \"foo\".equals(v);",
" }",
"",
" Predicate<String> negative7() {",
" return toString()::equals;",
" A negative7() {",
" return this;",
" }",
"",
" String negative8() {",
" return (toString());",
" Predicate<String> negative8() {",
" return \"foo\"::equals;",
" }",
"",
" Object negative9() {",
" return (Object) toString();",
" OutputStream negative9() {",
" return System.out;",
" }",
"",
" int negative10() {",
" return -hashCode();",
" A negative10() {",
" return (this);",
" }",
"",
" Object negative11() {",
" return (Object) this;",
" }",
"",
" boolean negative12() {",
" boolean[] arr = new boolean[0];",
" return !arr[0];",
" }",
"",
" String negative13() {",
" return \"foo\" + 0;",
" }",
"",
" String positive1() {",
@@ -68,68 +83,63 @@ final class IsLikelyTrivialComputationTest {
" return this.toString();",
" }",
"",
" int positive3() {",
" int[] arr = new int[0];",
" String positive3() {",
" // BUG: Diagnostic contains:",
" return arr[0];",
" return String.valueOf(1);",
" }",
"",
" String positive4() {",
" // BUG: Diagnostic contains:",
" return null;",
" return toString().toString();",
" }",
"",
" boolean positive5() {",
" String positive5() {",
" // BUG: Diagnostic contains:",
" return false;",
" return \"foo\" + toString();",
" }",
"",
" int positive6() {",
" byte positive6() {",
" // BUG: Diagnostic contains:",
" return 0;",
" return \"foo\".getBytes()[0];",
" }",
"",
" String positive7() {",
" int positive7() {",
" int[] arr = new int[0];",
" // BUG: Diagnostic contains:",
" return \"foo\" + \"bar\";",
" return arr[hashCode()];",
" }",
"",
" Predicate<String> positive8() {",
" // BUG: Diagnostic contains:",
" return v -> \"foo\".equals(v);",
" return toString()::equals;",
" }",
"",
" A positive9() {",
" Comparator<String> positive9() {",
" // BUG: Diagnostic contains:",
" return this;",
" return toString().CASE_INSENSITIVE_ORDER;",
" }",
"",
" Predicate<String> positive10() {",
" String positive10() {",
" // BUG: Diagnostic contains:",
" return \"foo\"::equals;",
" return (toString());",
" }",
"",
" A positive11() {",
" Object positive11() {",
" // BUG: Diagnostic contains:",
" return (this);",
" return (Object) toString();",
" }",
"",
" Object positive12() {",
" int positive12() {",
" // BUG: Diagnostic contains:",
" return (Object) this;",
" }",
"",
" boolean positive13() {",
" // BUG: Diagnostic contains:",
" return !false;",
" return -hashCode();",
" }",
"}")
.doTest();
}
/** A {@link BugChecker} that simply delegates to {@link IsLikelyTrivialComputation}. */
/** A {@link BugChecker} that simply delegates to {@link RequiresComputation}. */
@BugPattern(
summary = "Flags return statement expressions matched by `IsLikelyTrivialComputation`",
summary = "Flags return statement expressions matched by `RequiresComputation`",
severity = ERROR)
public static final class MatcherTestChecker extends AbstractMatcherTestChecker {
private static final long serialVersionUID = 1L;
@@ -141,7 +151,7 @@ final class IsLikelyTrivialComputationTest {
super(
(expressionTree, state) ->
state.getPath().getParentPath().getLeaf() instanceof ReturnTree
&& new IsLikelyTrivialComputation().matches(expressionTree, state));
&& new RequiresComputation().matches(expressionTree, state));
}
}
}

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.16.2-SNAPSHOT</version>
<version>0.18.1-SNAPSHOT</version>
</parent>
<artifactId>refaster-test-support</artifactId>
@@ -50,6 +50,11 @@
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>

View File

@@ -319,7 +319,7 @@ public final class RefasterRuleCollection extends BugChecker implements Compilat
return indexedMatches.subRangeMap(Range.closedOpen(startPosition, endPosition));
}
private ImmutableListMultimap<Long, String> getUnexpectedMatchesByLineNumber(
private static ImmutableListMultimap<Long, String> getUnexpectedMatchesByLineNumber(
ImmutableRangeMap<Integer, String> matches, String ruleUnderTest, VisitorState state) {
LineMap lineMap = state.getPath().getCompilationUnit().getLineMap();
return matches.asMapOfRanges().entrySet().stream()

View File

@@ -1,8 +1,30 @@
# An overview of Error Prone Support releases, along with compatible Error
# Prone releases. This data was generated by `generate-version-compatibility-overview.sh`.
releases:
- version: 0.18.0
compatible:
- "2.30.0"
- "2.31.0"
- version: 0.17.0
compatible:
- "2.29.2"
- "2.29.1"
- "2.29.0"
- "2.28.0"
- "2.27.1"
- "2.27.0"
- "2.26.1"
- "2.26.0"
- "2.25.0"
- "2.24.1"
- "2.24.0"
- "2.23.0"
- version: 0.16.1
compatible:
- "2.29.2"
- "2.29.1"
- "2.29.0"
- "2.28.0"
- "2.27.1"
- "2.27.0"
- "2.26.1"
@@ -13,6 +35,10 @@ releases:
- "2.23.0"
- version: 0.16.0
compatible:
- "2.29.2"
- "2.29.1"
- "2.29.0"
- "2.28.0"
- "2.27.1"
- "2.27.0"
- "2.26.1"
@@ -23,6 +49,10 @@ releases:
- "2.23.0"
- version: 0.15.0
compatible:
- "2.29.2"
- "2.29.1"
- "2.29.0"
- "2.28.0"
- "2.27.1"
- "2.27.0"
- "2.26.1"
@@ -33,6 +63,10 @@ releases:
- "2.23.0"
- version: 0.14.0
compatible:
- "2.29.2"
- "2.29.1"
- "2.29.0"
- "2.28.0"
- "2.27.1"
- "2.27.0"
- "2.26.1"