Compare commits

...

135 Commits

Author SHA1 Message Date
Rick Ossendrijver
044a30121e Merge branch 'master' into sschroevers/refaster-speed-up 2025-04-07 08:14:53 +02:00
Rick Ossendrijver
1cffbd0763 Revert this after testing 2025-04-07 08:08:49 +02:00
Picnic-DevPla-Bot
f0ad9d21e6 Upgrade Google Java Format 1.25.2 -> 1.26.0 (#1619)
See:
- https://github.com/google/google-java-format/releases/tag/v1.26.0
- https://github.com/google/google-java-format/compare/v1.25.2...v1.26.0
2025-04-07 08:02:37 +02:00
Picnic-DevPla-Bot
7138aa2100 Upgrade extra-enforcer-rules 1.9.0 -> 1.10.0 (#1626)
See:
- https://github.com/mojohaus/extra-enforcer-rules/releases/tag/extra-enforcer-rules-1.10.0
- https://github.com/mojohaus/extra-enforcer-rules/compare/1.9.0...extra-enforcer-rules-1.10.0
2025-04-06 21:59:19 +02:00
Picnic-DevPla-Bot
de4667628f Upgrade OpenRewrite 3.4.0 -> 3.5.0 (#1620)
See:
- https://github.com/openrewrite/rewrite-recipe-bom/releases/tag/v3.5.0
- https://github.com/openrewrite/rewrite-recipe-bom/compare/v3.4.0...v3.5.0
2025-04-06 18:21:40 +02:00
Picnic-DevPla-Bot
5e958fe20b Upgrade Forbidden APIs plugin 3.8 -> 3.9 (#1630)
See:
- https://github.com/policeman-tools/forbidden-apis/wiki/Changes
- https://github.com/policeman-tools/forbidden-apis/compare/3.8...3.9
2025-04-06 17:28:38 +02:00
Picnic-DevPla-Bot
baa921caac Upgrade Mockito 5.16.1 -> 5.17.0 (#1631)
See:
- https://github.com/mockito/mockito/releases/tag/v5.17.0
- https://github.com/mockito/mockito/compare/v5.16.1...v5.17.0
2025-04-06 16:55:07 +02:00
Picnic-DevPla-Bot
ba040bd191 Upgrade Byte Buddy 1.17.4 -> 1.17.5 (#1624)
See:
- https://github.com/raphw/byte-buddy/releases/tag/byte-buddy-1.17.5
- https://github.com/raphw/byte-buddy/compare/byte-buddy-1.17.4...byte-buddy-1.17.5
2025-04-06 11:22:24 +02:00
Picnic-DevPla-Bot
a3a20b52e5 Upgrade jacoco-maven-plugin 0.8.12 -> 0.8.13 (#1628)
See:
- https://github.com/jacoco/jacoco/releases/tag/v0.8.13
- https://github.com/jacoco/jacoco/compare/v0.8.12...v0.8.13
2025-04-04 13:58:35 +02:00
Rick Ossendrijver
afcb9abb32 Try to drop it then 2025-04-04 11:48:56 +02:00
Rick Ossendrijver
5a4c4feab2 Another try to keep it running 2025-04-04 11:24:09 +02:00
Rick Ossendrijver
168d19c046 Continue running if one IT fails 2025-04-04 10:20:47 +02:00
Rick Ossendrijver
e2569c48ae Run other IT although Checkstyle fails 2025-04-04 10:05:02 +02:00
Rick Ossendrijver
c59cb4a947 Add Refaster#AnyOf use cases 2025-04-04 08:17:42 +02:00
Rick Ossendrijver
899fe6fc42 Merge branch master into sschroevers/refaster-speed-up 2025-04-03 21:56:42 +02:00
Picnic-DevPla-Bot
5d8d27176b Upgrade sonar-maven-plugin 5.0.0.4389 -> 5.1.0.4751 (#1614)
See:
- https://github.com/SonarSource/sonar-scanner-maven/releases/tag/5.1.0.4751
- https://github.com/SonarSource/sonar-scanner-maven/compare/5.0.0.4389...5.1.0.4751
2025-04-02 14:25:42 +02:00
Picnic-DevPla-Bot
d878a57a8e Upgrade OpenRewrite Templating 1.24.1 -> 1.24.2 (#1617)
See:
- https://github.com/openrewrite/rewrite-templating/releases/tag/v1.24.2
- https://github.com/openrewrite/rewrite-templating/compare/v1.24.1...v1.24.2
2025-04-01 09:12:07 +02:00
Picnic-DevPla-Bot
eaec12f460 Upgrade Checkstyle 10.21.4 -> 10.22.0 (#1623)
See:
- https://checkstyle.sourceforge.io/releasenotes.html
- https://github.com/checkstyle/checkstyle/releases/tag/checkstyle-10.22.0
- https://github.com/checkstyle/checkstyle/compare/checkstyle-10.21.4...checkstyle-10.22.0
2025-03-31 21:17:40 +02:00
Picnic-DevPla-Bot
da7dafb6e7 Upgrade Surefire 3.5.2 -> 3.5.3 (#1622)
See:
- https://github.com/apache/maven-surefire/releases/tag/maven-surefire-3.5.3
- https://github.com/apache/maven-surefire/compare/surefire-3.5.2...maven-surefire-3.5.3
2025-03-31 11:38:52 +02:00
Picnic-DevPla-Bot
5a7aaf12d6 Upgrade NullAway 0.12.4 -> 0.12.5 (#1615)
See:
- https://github.com/uber/NullAway/blob/master/CHANGELOG.md
- https://github.com/uber/NullAway/releases/tag/v0.12.5
- https://github.com/uber/NullAway/compare/v0.12.4...v0.12.5
2025-03-27 14:08:05 +01:00
Stephan Schroevers
92e4d74e4b Update Error Prone compatibility matrix (#1613) 2025-03-25 18:56:11 +01:00
Stephan Schroevers
4a0bc0c210 [maven-release-plugin] prepare for next development iteration 2025-03-24 11:41:07 +01:00
Stephan Schroevers
53152499d6 [maven-release-plugin] prepare release v0.21.0 2025-03-24 11:41:07 +01:00
Picnic-DevPla-Bot
61d92fb33f Upgrade CodeQL v3.28.10 -> v3.28.12 (#1611)
See:
- https://github.com/github/codeql-action/blob/main/CHANGELOG.md
- https://github.com/github/codeql-action/releases/tag/v3.28.11
- https://github.com/github/codeql-action/releases/tag/v3.28.12
- https://github.com/github/codeql-action/compare/v3.28.10...v3.28.12
2025-03-24 10:44:45 +01:00
Picnic-DevPla-Bot
8690f49c35 Upgrade Byte Buddy 1.17.3 -> 1.17.4 (#1610)
See:
- https://github.com/raphw/byte-buddy/releases/tag/byte-buddy-1.17.4
- https://github.com/raphw/byte-buddy/compare/byte-buddy-1.17.3...byte-buddy-1.17.4
2025-03-24 10:30:40 +01:00
Picnic-DevPla-Bot
d808f664ec Upgrade ruby/setup-ruby v1.221.0 -> v1.227.0 (#1612)
See:
- https://github.com/ruby/setup-ruby/releases/tag/v1.227.0
- https://github.com/ruby/setup-ruby/releases/tag/v1.226.0
- https://github.com/ruby/setup-ruby/releases/tag/v1.225.0
- https://github.com/ruby/setup-ruby/releases/tag/v1.224.0
- https://github.com/ruby/setup-ruby/releases/tag/v1.223.0
- https://github.com/ruby/setup-ruby/releases/tag/v1.222.0
2025-03-24 09:39:01 +01:00
Picnic-DevPla-Bot
7f5f4820e9 Upgrade Pitest Git plugins 2.1.0 -> 2.2.0 (#1607) 2025-03-23 17:54:05 +01:00
Picnic-DevPla-Bot
f7a4427852 Upgrade Arcmutate 1.3.2 -> 1.4.0 (#1606) 2025-03-23 17:24:51 +01:00
Picnic-DevPla-Bot
0e956bcd44 Upgrade MongoDB driver 5.3.1 -> 5.4.0 (#1605)
See:
- https://jira.mongodb.org/issues/?jql=project%20%3D%20JAVA%20AND%20fixVersion%20%3E%205.3.1%20AND%20fixVersion%20%3C%3D%205.4.0
- https://github.com/mongodb/mongo-java-driver/releases/tag/r5.4.0-alpha0
- https://github.com/mongodb/mongo-java-driver/releases/tag/r5.4.0
- https://github.com/mongodb/mongo-java-driver/compare/r5.3.1...r5.4.0
2025-03-23 15:53:47 +01:00
Picnic-DevPla-Bot
5395fc60e1 Upgrade Spring Boot 3.4.3 -> 3.4.4 (#1604)
See:
- https://github.com/spring-projects/spring-boot/releases/tag/v3.4.4
- https://github.com/spring-projects/spring-boot/compare/v3.4.3...v3.4.4
2025-03-23 15:13:32 +01:00
Picnic-DevPla-Bot
d8cae04a98 Upgrade Byte Buddy 1.17.2 -> 1.17.3 (#1603)
See:
- https://github.com/raphw/byte-buddy/releases/tag/byte-buddy-1.17.3
- https://github.com/raphw/byte-buddy/compare/byte-buddy-1.17.2...byte-buddy-1.17.3
2025-03-23 11:59:48 +01:00
Julian Broudy
7b14711ecf Extend FluxJust Refaster rule (#1581) 2025-03-23 11:26:19 +01:00
Tim te Beek
c3351b9ee1 Introduce two FileRules Refaster rules (#1596)
Invoking `File#mkdirs` before testing for existence of the specified
path, rather than the other way around, avoids a subtle concurrency
issue.

See also openrewrite/rewrite#5189.
2025-03-23 11:13:24 +01:00
Picnic-DevPla-Bot
40b3c87b72 Upgrade Spring 6.2.4 -> 6.2.5 (#1602)
See:
- https://github.com/spring-projects/spring-framework/releases/tag/v6.2.5
- https://github.com/spring-projects/spring-framework/compare/v6.2.4...v6.2.5
2025-03-22 12:54:04 +01:00
Picnic-DevPla-Bot
726db5ce5b Upgrade Error Prone 2.36.0 -> 2.37.0 (#1601)
Resolves #1597.

See:
- https://github.com/google/error-prone/releases/tag/v2.37.0
- https://github.com/google/error-prone/compare/v2.36.0...v2.37.0
- https://github.com/PicnicSupermarket/error-prone/compare/v2.36.0-picnic-4...v2.37.0-picnic-1
2025-03-21 09:47:13 +01:00
Picnic-DevPla-Bot
99d359c548 Upgrade OpenRewrite Templating 1.24.0 -> 1.24.1 (#1599)
See:
- https://github.com/openrewrite/rewrite-templating/releases/tag/v1.24.1
- https://github.com/openrewrite/rewrite-templating/compare/v1.24.0...v1.24.1
2025-03-20 16:42:24 +01:00
Picnic-DevPla-Bot
4744113411 Upgrade actions/upload-artifact v4.6.1 -> v4.6.2 (#1600)
See:
- https://github.com/actions/upload-artifact/releases/tag/v4.6.2
2025-03-20 12:40:33 +01:00
Picnic-DevPla-Bot
ae8f940f55 Upgrade AspectJ 1.9.22.1 -> 1.9.23 (#1587)
See:
- https://github.com/eclipse-aspectj/aspectj/releases/tag/V1_9_23
- https://github.com/eclipse-aspectj/aspectj/compare/V1_9_22_1...V1_9_23
2025-03-19 21:28:29 +01:00
Picnic-DevPla-Bot
8d7633df2d Upgrade pitest-maven-plugin 1.18.2 -> 1.19.0 (#1593)
See:
- https://github.com/hcoles/pitest/releases/tag/1.19.0
- https://github.com/hcoles/pitest/compare/1.18.2...1.19.0
2025-03-19 21:16:34 +01:00
Picnic-DevPla-Bot
4a351cfbe3 Upgrade JUnit 5 5.12.0 -> 5.12.1 (#1589)
See:
- https://junit.org/junit5/docs/current/release-notes/
- https://github.com/junit-team/junit5/releases/tag/r5.12.1
- https://github.com/junit-team/junit5/compare/r5.12.0...r5.12.1
2025-03-19 09:30:32 +01:00
Stephan Schroevers
bb01447760 Relocate Arcmutate license file (#1594)
This former location is deprecated.
2025-03-18 15:31:18 +01:00
Picnic-DevPla-Bot
f12ed17b96 Upgrade Spring Security 6.4.3 -> 6.4.4 (#1592)
See:
- https://github.com/spring-projects/spring-security/releases/tag/6.4.4
- https://github.com/spring-projects/spring-security/compare/6.4.3...6.4.4
2025-03-18 12:06:47 +01:00
Stephan Schroevers
854e05f044 Upgrade Arcmutate plugins (#1586)
These upgrades were not picked up automatically due to a groupId change.

Summary of changes:
- Upgrade Pitest Git plugins 1.1.4 -> 2.1.0
- Upgrade Arcmutate 1.2.2 -> 1.3.2
- Upgrade pitest-accelerator-junit5 1.0.6 -> 1.2.0
2025-03-18 11:47:21 +01:00
Picnic-DevPla-Bot
82c22682c0 Upgrade Mockito 5.16.0 -> 5.16.1 (#1590)
See:
- https://github.com/mockito/mockito/releases/tag/v5.16.1
- https://github.com/mockito/mockito/compare/v5.16.0...v5.16.1
2025-03-18 11:16:24 +01:00
Stephan Schroevers
25b3817876 Upgrade Error Prone fork 2.36.0-picnic-2 -> 2.36.0-picnic-4 (#1591)
See:
- https://github.com/PicnicSupermarket/error-prone/releases/tag/v2.36.0-picnic-3
- https://github.com/PicnicSupermarket/error-prone/releases/tag/v2.36.0-picnic-4
- https://github.com/PicnicSupermarket/error-prone/compare/v2.36.0-picnic-2...v2.36.0-picnic-4
2025-03-18 09:10:40 +01:00
Picnic-DevPla-Bot
e2a2b086ad Upgrade Spring 6.2.3 -> 6.2.4 (#1588)
See:
- https://github.com/spring-projects/spring-framework/releases/tag/v6.2.4
- https://github.com/spring-projects/spring-framework/compare/v6.2.3...v6.2.4
2025-03-15 13:39:30 +01:00
Picnic-DevPla-Bot
5f9a0c5e17 Upgrade Project Reactor 2024.0.3 -> 2024.0.4 (#1583)
See:
- https://github.com/reactor/reactor/releases/tag/2024.0.4
- https://github.com/reactor/reactor/compare/2024.0.3...2024.0.4
2025-03-15 11:37:49 +01:00
Picnic-DevPla-Bot
2a0ae0af13 Upgrade OpenRewrite Templating 1.23.0 -> 1.24.0 (#1585)
See:
- https://github.com/openrewrite/rewrite-templating/releases/tag/v1.24.0
- https://github.com/openrewrite/rewrite-templating/compare/v1.23.0...v1.24.0
2025-03-14 17:35:28 +01:00
Picnic-DevPla-Bot
7a051146b6 Upgrade Micrometer 1.14.4 -> 1.14.5 (#1582)
See:
- https://github.com/micrometer-metrics/micrometer/releases/tag/v1.14.5
- https://github.com/micrometer-metrics/micrometer/compare/v1.14.4...v1.14.5
2025-03-13 08:49:57 +01:00
Picnic-DevPla-Bot
d9398001cb Upgrade OpenRewrite 3.2.0 -> 3.4.0 (#1557)
See:
- https://github.com/openrewrite/rewrite-recipe-bom/releases/tag/v3.3.0
- https://github.com/openrewrite/rewrite-recipe-bom/releases/tag/v3.4.0
- https://github.com/openrewrite/rewrite-recipe-bom/compare/v3.2.0...v3.4.0
2025-03-12 15:06:25 +01:00
Picnic-DevPla-Bot
0be99cb12a Upgrade Swagger 2.2.28 -> 2.2.29 (#1584)
See:
- https://github.com/swagger-api/swagger-core/releases/tag/v2.2.29
- https://github.com/swagger-api/swagger-core/compare/v2.2.28...v2.2.29
2025-03-12 13:07:45 +01:00
Picnic-DevPla-Bot
70e2d3d43f Upgrade tidy-maven-plugin 1.3.0 -> 1.4.0 (#1580)
See:
- https://github.com/mojohaus/tidy-maven-plugin/releases/tag/1.4.0
- https://github.com/mojohaus/tidy-maven-plugin/compare/tidy-maven-plugin-1.3.0...1.4.0
2025-03-12 09:30:27 +01:00
Picnic-DevPla-Bot
441258f9f2 Upgrade maven-deploy-plugin 3.1.3 -> 3.1.4 (#1573)
See:
- https://github.com/apache/maven-deploy-plugin/releases/tag/maven-deploy-plugin-3.1.4
2025-03-10 14:37:20 +01:00
Picnic-DevPla-Bot
b96efb533c Upgrade Checkstyle 10.21.3 -> 10.21.4 (#1579)
See:
- https://checkstyle.sourceforge.io/releasenotes.html
- https://github.com/checkstyle/checkstyle/releases/tag/checkstyle-10.21.4
- https://github.com/checkstyle/checkstyle/compare/checkstyle-10.21.3...checkstyle-10.21.4
2025-03-09 12:35:28 +01:00
Picnic-DevPla-Bot
5af067cc23 Upgrade Mockito 5.15.2 -> 5.16.0 (#1578)
See:
- https://github.com/mockito/mockito/releases/tag/v5.16.0
- https://github.com/mockito/mockito/compare/v5.15.2...v5.16.0
2025-03-09 12:05:58 +01:00
Picnic-DevPla-Bot
0c84665e38 Upgrade maven-install-plugin 3.1.3 -> 3.1.4 (#1574)
See:
- https://github.com/apache/maven-install-plugin/releases/tag/maven-install-plugin-3.1.4
- https://github.com/apache/maven-install-plugin/compare/maven-install-plugin-3.1.3...maven-install-plugin-3.1.4
2025-03-09 11:52:58 +01:00
Picnic-DevPla-Bot
9316d81fe3 Upgrade Jackson 2.18.2 -> 2.18.3 (#1575)
See:
- https://github.com/FasterXML/jackson/wiki/Jackson-Release-2.18.3
- https://github.com/FasterXML/jackson-bom/compare/jackson-bom-2.18.2...jackson-bom-2.18.3
2025-03-09 11:43:33 +01:00
Picnic-DevPla-Bot
ec96c044d5 Upgrade NullAway 0.12.3 -> 0.12.4 (#1572)
See:
- https://github.com/uber/NullAway/blob/master/CHANGELOG.md
- https://github.com/uber/NullAway/releases/tag/v0.12.4
- https://github.com/uber/NullAway/compare/v0.12.3...v0.12.4
2025-03-09 11:33:22 +01:00
Picnic-DevPla-Bot
ae4ed9273f Upgrade Checker Framework Annotations 3.49.0 -> 3.49.1 (#1577)
See:
- https://github.com/typetools/checker-framework/releases/tag/checker-framework-3.49.1
- https://github.com/typetools/checker-framework/compare/checker-framework-3.49.0...checker-framework-3.49.1
2025-03-09 11:24:08 +01:00
Picnic-DevPla-Bot
0ec882e62e Upgrade Byte Buddy 1.17.1 -> 1.17.2 (#1576)
See:
- https://github.com/raphw/byte-buddy/releases/tag/byte-buddy-1.17.2
- https://github.com/raphw/byte-buddy/compare/byte-buddy-1.17.1...byte-buddy-1.17.2
2025-03-09 09:47:31 +01:00
Picnic-DevPla-Bot
fef9ba23f4 Upgrade org.pitest:pitest-junit5-plugin 1.2.1 -> 1.2.2 (#1570)
See:
- https://github.com/pitest/pitest-junit5-plugin/releases/tag/1.2.2
- https://github.com/pitest/pitest-junit5-plugin/compare/1.2.1...1.2.2
2025-03-04 09:25:13 +01:00
Picnic-DevPla-Bot
3bd415b910 Upgrade SLF4J 2.0.16 -> 2.0.17 (#1571)
See:
- https://www.slf4j.org/news.html
- https://github.com/qos-ch/slf4j/compare/v_2.0.16...v_2.0.17
2025-02-27 10:12:40 +01:00
Picnic-DevPla-Bot
2128624261 Upgrade ruby/setup-ruby v1.213.0 -> v1.221.0 (#1568)
See:
- https://github.com/ruby/setup-ruby/releases/tag/v1.221.0
- https://github.com/ruby/setup-ruby/releases/tag/v1.220.0
- https://github.com/ruby/setup-ruby/releases/tag/v1.219.0
- https://github.com/ruby/setup-ruby/releases/tag/v1.218.0
- https://github.com/ruby/setup-ruby/releases/tag/v1.217.0
- https://github.com/ruby/setup-ruby/releases/tag/v1.216.0
- https://github.com/ruby/setup-ruby/releases/tag/v1.215.0
- https://github.com/ruby/setup-ruby/releases/tag/v1.214.0
2025-02-24 12:53:58 +01:00
Picnic-DevPla-Bot
c53fcace76 Upgrade CodeQL v3.28.5 -> v3.28.10 (#1567)
See:
- https://github.com/github/codeql-action/blob/main/CHANGELOG.md
- https://github.com/github/codeql-action/releases/tag/v3.28.6
- https://github.com/github/codeql-action/releases/tag/v3.28.7
- https://github.com/github/codeql-action/releases/tag/v3.28.8
- https://github.com/github/codeql-action/releases/tag/v3.28.9
- https://github.com/github/codeql-action/releases/tag/v3.28.10
- https://github.com/github/codeql-action/compare/v3.28.5...v3.28.10
2025-02-24 10:56:49 +01:00
Picnic-DevPla-Bot
ff3759984c Upgrade Checkstyle 10.21.2 -> 10.21.3 (#1566)
See:
- https://checkstyle.sourceforge.io/releasenotes.html
- https://github.com/checkstyle/checkstyle/releases/tag/checkstyle-10.21.3
- https://github.com/checkstyle/checkstyle/compare/checkstyle-10.21.2...checkstyle-10.21.3
2025-02-24 09:58:19 +01:00
Phil Werli
6358d1e2e1 Extend MonoSingleOptional Refaster rule (#1553) 2025-02-24 09:25:30 +01:00
Mohamed Sameh
db53631e76 Extend MonoThen Refaster rule (#1556) 2025-02-24 09:09:27 +01:00
Picnic-DevPla-Bot
86b2d929ab Upgrade OpenRewrite Templating 1.22.1 -> 1.23.0 (#1558)
See:
- https://github.com/openrewrite/rewrite-templating/releases/tag/v1.23.0
- https://github.com/openrewrite/rewrite-templating/compare/v1.22.1...v1.23.0
2025-02-23 22:22:38 +01:00
Picnic-DevPla-Bot
0db4462a64 Upgrade ossf/scorecard-action v2.4.0 -> v2.4.1 (#1563)
See:
- https://github.com/ossf/scorecard-action/releases/tag/v2.4.1
2025-02-23 22:12:53 +01:00
Picnic-DevPla-Bot
f8667fc655 Upgrade pitest-maven-plugin 1.18.1 -> 1.18.2 (#1552)
See:
- https://github.com/hcoles/pitest/releases/tag/1.18.2
- https://github.com/hcoles/pitest/compare/1.18.1...1.18.2
2025-02-23 18:06:49 +01:00
Picnic-DevPla-Bot
d91f94e879 Upgrade actions/upload-artifact v4.6.0 -> v4.6.1 (#1562)
See:
- https://github.com/actions/upload-artifact/releases/tag/v4.6.1
2025-02-23 17:43:58 +01:00
Picnic-DevPla-Bot
ad6c8593f2 Upgrade JUnit 5 5.11.4 -> 5.12.0 (#1564)
See:
- https://junit.org/junit5/docs/current/release-notes/
- https://github.com/junit-team/junit5/releases/tag/r5.12.0-M1
- https://github.com/junit-team/junit5/releases/tag/r5.12.0-RC1
- https://github.com/junit-team/junit5/releases/tag/r5.12.0-RC2
- https://github.com/junit-team/junit5/releases/tag/r5.12.0
- https://github.com/junit-team/junit5/compare/r5.11.4...r5.12.0
2025-02-23 17:30:14 +01:00
Picnic-DevPla-Bot
873ee47e8d Upgrade maven-compiler-plugin 3.13.0 -> 3.14.0 (#1565)
See:
- https://github.com/apache/maven-compiler-plugin/releases/tag/maven-compiler-plugin-3.14.0
- https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.13.0...maven-compiler-plugin-3.14.0
2025-02-23 17:13:46 +01:00
Picnic-DevPla-Bot
fed281dc2b Upgrade Spring Boot 3.4.2 -> 3.4.3 (#1561)
See:
- https://github.com/spring-projects/spring-boot/releases/tag/v3.4.3
- https://github.com/spring-projects/spring-boot/compare/v3.4.2...v3.4.3
2025-02-22 13:36:10 +01:00
Picnic-DevPla-Bot
277d30467d Upgrade Spring Security 6.4.2 -> 6.4.3 (#1554)
See:
- https://github.com/spring-projects/spring-security/releases/tag/6.4.3
- https://github.com/spring-projects/spring-security/compare/6.4.2...6.4.3
2025-02-21 14:55:42 +01:00
Rick Ossendrijver
9673572114 Merge branch 'master' into sschroevers/refaster-speed-up 2025-02-12 09:06:24 +01:00
Rick Ossendrijver
6833ac582c Merge master into sschroevers/refaster-speed-up 2025-01-17 15:14:13 +01:00
Rick Ossendrijver
8d99611af7 Post-merge-fix 2024-12-24 13:35:11 +01:00
Rick Ossendrijver
424b520b05 Merge branch 'master' into sschroevers/refaster-speed-up 2024-12-24 13:22:51 +01:00
Rick Ossendrijver
2687322720 Merge branch master into sschroevers/refaster-speed-up 2024-12-24 13:20:12 +01:00
Stephan Schroevers
77bc1079d6 Merge branch 'master' into sschroevers/refaster-speed-up 2023-12-26 20:10:25 +01:00
Stephan Schroevers
72f888125a Suggestions 2022-10-09 19:26:45 +02:00
Stephan Schroevers
0157692fbe Merge remote-tracking branch 'origin/sschroevers/refaster-custom-urls' into sschroevers/refaster-speed-up 2022-10-09 16:27:53 +02:00
Stephan Schroevers
5ba70753f6 Introduce AnnotatedCompositeCodeTransformerTest 2022-10-09 16:11:47 +02:00
Stephan Schroevers
d59b62612e Merge remote-tracking branch 'origin/sschroevers/refaster-custom-urls' into sschroevers/refaster-speed-up 2022-10-09 13:22:09 +02:00
Rick Ossendrijver
c34fa4decd Fix typo 2022-10-09 10:53:28 +02:00
Stephan Schroevers
2cb4bd0e57 Suggestions 2022-10-08 19:20:12 +02:00
Ivan Babiankou
0cf891c87b Suggestions 2022-10-08 19:20:12 +02:00
Rick Ossendrijver
63ad14e76e Fix typo 2022-10-08 19:20:12 +02:00
Stephan Schroevers
457a8e229e Comment style, explain both performance-only pieces of code
Since PIT correctly flags these as "redundant".

Also for JDK 11 compatibility.
2022-10-08 19:20:12 +02:00
Stephan Schroevers
ab037393f1 Optimize code, introduce benchmark, simplify test 2022-10-08 19:20:12 +02:00
Stephan Schroevers
afdcf5222c Apply some suggestions 2022-10-08 19:20:12 +02:00
Rick Ossendrijver
7889148cae Reorder methods in RefasterIntrospection 2022-10-08 19:20:12 +02:00
Rick Ossendrijver
2003bd201b Introduce getClass method to deduplicate 2022-10-08 19:20:12 +02:00
Rick Ossendrijver
a27d635467 Extract the TreeScanners to their own classes 2022-10-08 19:20:12 +02:00
Rick Ossendrijver
9151287560 Suggestion 2022-10-08 19:20:12 +02:00
Stephan Schroevers
c3a5106343 Push sorting requirements into Node, minimize tree, add tests 2022-10-08 19:20:12 +02:00
Stephan Schroevers
2c137c0024 Move all RefasterRuleSelector construction logic into the relevant class 2022-10-08 19:20:12 +02:00
Stephan Schroevers
1c5077f65d Create selector only once per Refaster instantiation 2022-10-08 19:20:12 +02:00
Stephan Schroevers
2a93011046 Merge RefasterRuleSelector type hierarchy 2022-10-08 19:20:12 +02:00
Rick Ossendrijver
39dc9aa4c8 Add XXXs 2022-10-08 19:20:12 +02:00
Rick Ossendrijver
72ff8aed75 Drop unnecessary @AutoService annotation 2022-10-08 19:20:12 +02:00
Rick Ossendrijver
6739cb4a95 Improve code and algorithm for Refaster 2022-10-08 19:20:12 +02:00
Rick Ossendrijver
344f4e4058 Initial copy over of the improved algorithm 2022-10-08 19:20:12 +02:00
Stephan Schroevers
ee74279ef9 Compatibility with stock Error Prone 2022-10-08 19:20:12 +02:00
Stephan Schroevers
1624ebf4c6 WIP: Speed up Refaster check
This code assumes a modification of Error Prone; see the
`sschroevers/refaster-tree-tweaks` branch on the fork.
2022-10-08 19:20:12 +02:00
Stephan Schroevers
04847628f5 Suggestions 2022-10-08 15:57:08 +02:00
Stephan Schroevers
d21ac59cb5 Apply StringJoin suggestion 2022-10-08 11:13:38 +02:00
Pieter Dirk Soels
32300ff2e5 Tweak AnnotatedCompositeCodeTransformer Javadoc 2022-10-08 11:13:38 +02:00
Rick Ossendrijver
302e20b212 Revert changes in OptionalTemplates 2022-10-08 11:13:38 +02:00
Rick Ossendrijver
8bd88bbe01 Improve Javadoc AnnotatedCompositeCodeTransformer 2022-10-08 11:13:38 +02:00
Rick Ossendrijver
b2ef63107b s/information/content/ 2022-10-08 11:13:38 +02:00
Rick Ossendrijver
e6caceba60 Move AnnotatedCompositeCodeTransformer and ErrorProneFork to refaster-support 2022-10-08 11:13:38 +02:00
Stephan Schroevers
594f51c9d0 Tweaks 2022-10-08 11:13:38 +02:00
Pieter Dirk Soels
7e49b08a7e Pass null for urlLink to Description.Builder 2022-10-08 11:13:38 +02:00
Pieter Dirk Soels
50443d179f Suggestion 2022-10-08 11:13:38 +02:00
Pieter Dirk Soels
ad1c98d3eb Align documentation of reported description names by the Refaster check 2022-10-08 11:13:38 +02:00
Stephan Schroevers
20d194b4d4 Clarify how the default Refaster hit severity comes to be
Plus other tweaks.
2022-10-08 11:13:38 +02:00
Stephan Schroevers
d899a8a10c Also this 2022-10-08 11:13:38 +02:00
Stephan Schroevers
c4b6a5fbe4 Suggestions, introduce ErrorProneFork 2022-10-08 11:13:38 +02:00
Rick Ossendrijver
74d6c9a46b Tweak 2022-10-08 11:13:38 +02:00
Rick Ossendrijver
12d09ad496 Support AllSuggestionsAsWarnings and add a suggestion 2022-10-08 11:13:38 +02:00
Rick Ossendrijver
34826413da Use @AutoValue for the AnnotatedCompositeCodeTransformer 2022-10-08 11:13:38 +02:00
Rick Ossendrijver
01b7e5b78d Improve text and minor improvements 2022-10-08 11:13:38 +02:00
Stephan Schroevers
d26bc18b0c Flag classpath issue 2022-10-08 11:13:38 +02:00
Stephan Schroevers
cf772c47cd Expand test coverage 2022-10-08 11:13:38 +02:00
Stephan Schroevers
abb6cea861 Properly document URL placeholder usage 2022-10-08 11:13:38 +02:00
Stephan Schroevers
db8cf3c860 Improve logic and test coverage 2022-10-08 11:13:38 +02:00
Stephan Schroevers
458fb99d4e Flag why build currently doesn't fail, while it should. 2022-10-08 11:13:38 +02:00
Stephan Schroevers
914d30a7ed Better annotation support, simplify setup 2022-10-08 11:13:38 +02:00
Stephan Schroevers
0e46f9cf5f Tweaks 2022-10-08 11:13:38 +02:00
Stephan Schroevers
0f44844c51 Another round 2022-10-08 11:13:38 +02:00
Stephan Schroevers
827880bc45 WIP: Some plumbing for annotation support
To be used for custom links, custom error messages, custom other stuff...
2022-10-08 11:13:38 +02:00
Stephan Schroevers
84061fcd06 More extensible approach 2022-10-08 11:13:38 +02:00
Stephan Schroevers
69386f0b3d Emit website link along with Refaster refactor suggestions 2022-10-08 11:13:38 +02:00
47 changed files with 1528 additions and 531 deletions

View File

@@ -40,13 +40,13 @@ jobs:
java-distribution: temurin
maven-version: 3.9.9
- name: Initialize CodeQL
uses: github/codeql-action/init@f6091c0113d1dcf9b98e269ee48e8a7e51b7bdd4 # v3.28.5
uses: github/codeql-action/init@5f8171a638ada777af81d42b55959a643bb29017 # v3.28.12
with:
languages: ${{ matrix.language }}
- name: Perform minimal build
if: matrix.language == 'java'
run: mvn -T1C clean package -DskipTests -Dverification.skip
- name: Perform CodeQL analysis
uses: github/codeql-action/analyze@f6091c0113d1dcf9b98e269ee48e8a7e51b7bdd4 # v3.28.5
uses: github/codeql-action/analyze@5f8171a638ada777af81d42b55959a643bb29017 # v3.28.12
with:
category: /language:${{ matrix.language }}

View File

@@ -43,7 +43,7 @@ jobs:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- uses: ruby/setup-ruby@28c4deda893d5a96a6b2d958c5b47fc18d65c9d3 # v1.213.0
- uses: ruby/setup-ruby@1a615958ad9d422dd932dc1d5823942ee002799f # v1.227.0
with:
working-directory: ./website
bundler-cache: true

View File

@@ -42,12 +42,12 @@ jobs:
with:
persist-credentials: false
- name: Run OpenSSF Scorecard analysis
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1
with:
results_file: results.sarif
results_format: sarif
publish_results: ${{ github.ref == 'refs/heads/master' }}
- name: Update GitHub's code scanning dashboard
uses: github/codeql-action/upload-sarif@f6091c0113d1dcf9b98e269ee48e8a7e51b7bdd4 # v3.28.5
uses: github/codeql-action/upload-sarif@5f8171a638ada777af81d42b55959a643bb29017 # v3.28.12
with:
sarif_file: results.sarif

View File

@@ -38,7 +38,7 @@ jobs:
- name: Aggregate Pitest reports
run: mvn pitest-git:aggregate -DkilledEmoji=":tada:" -DmutantEmoji=":zombie:" -DtrailingText="Mutation testing report by [Pitest](https://pitest.org/). Review any surviving mutants by inspecting the line comments under [_Files changed_](${{ github.event.number }}/files)."
- name: Upload Pitest reports as artifact
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: pitest-reports
path: ./target/pit-reports-ci

View File

@@ -7,19 +7,21 @@
# https://docs.github.com/en/actions/learn-github-actions/expressions#example-returning-a-json-object
name: "Integration tests"
on:
issue_comment:
types: [ created ]
# issue_comment:
# types: [ created ]
pull_request:
permissions:
contents: read
jobs:
run-integration-tests:
name: On-demand integration test
if: |
github.event.issue.pull_request && contains(github.event.comment.body, '/integration-test')
# if: |
# github.event.issue.pull_request && contains(github.event.comment.body, '/integration-test')
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
integration-test: [ "checkstyle", "metrics", "prometheus-java-client" ]
integration-test: [ "metrics", "prometheus-java-client" ] # XXX: Dropped checkstyle.
steps:
- name: Install Harden-Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
@@ -45,17 +47,18 @@ jobs:
- name: Check out code and set up JDK and Maven
uses: s4u/setup-maven-action@4f7fb9d9675e899ca81c6161dadbba0189a4ebb1 # v1.18.0
with:
checkout-ref: "refs/pull/${{ github.event.issue.number }}/head"
# checkout-ref: "refs/pull/${{ github.event.issue.number }}/head"
java-version: 17.0.13
java-distribution: temurin
maven-version: 3.9.9
- name: Install project to local Maven repository
run: mvn -T1C install -DskipTests -Dverification.skip
- name: Run integration test
continue-on-error: true
run: xvfb-run "./integration-tests/${{ matrix.integration-test }}.sh" "${{ runner.temp }}/artifacts"
- name: Upload artifacts on failure
if: ${{ failure() }}
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: "integration-test-${{ matrix.integration-test }}"
path: "${{ runner.temp }}/artifacts"

View File

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

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.20.1-SNAPSHOT</version>
<version>0.21.1-SNAPSHOT</version>
</parent>
<artifactId>error-prone-contrib</artifactId>

View File

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

View File

@@ -489,9 +489,16 @@ final class ReactorRules {
return Flux.range(value, 1);
}
// XXX: Consider generalizing part of this template using an Error Prone check that covers any
// sequence of explicitly enumerated values passed to an iteration order-preserving collection
// factory method.
@BeforeTemplate
Flux<T> before(T value) {
return Mono.just(value).repeat().take(1);
return Refaster.anyOf(
Mono.just(value).flux(),
Mono.just(value).repeat().take(1),
Flux.fromIterable(ImmutableList.of(value)),
Flux.fromIterable(ImmutableSet.of(value)));
}
@AfterTemplate
@@ -939,7 +946,11 @@ final class ReactorRules {
static final class MonoThen<T> {
@BeforeTemplate
Mono<@Nullable Void> before(Mono<T> mono) {
return Refaster.anyOf(mono.ignoreElement().then(), mono.flux().then());
return Refaster.anyOf(
mono.ignoreElement().then(),
mono.flux().then(),
Mono.when(mono),
Mono.whenDelayError(mono));
}
@AfterTemplate
@@ -1078,10 +1089,12 @@ final class ReactorRules {
// rule. Consider introducing an Error Prone check for this.
static final class MonoSingleOptional<T> {
@BeforeTemplate
Mono<Optional<T>> before(Mono<T> mono) {
Mono<Optional<T>> before(Mono<T> mono, Optional<T> optional, Mono<Optional<T>> alternate) {
return Refaster.anyOf(
mono.flux().collect(toOptional()),
mono.map(Optional::of).defaultIfEmpty(Optional.empty()),
mono.map(Optional::of),
mono.singleOptional().defaultIfEmpty(optional),
mono.singleOptional().switchIfEmpty(alternate),
mono.transform(Mono::singleOptional));
}

View File

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

View File

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

View File

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

View File

@@ -188,7 +188,12 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
}
ImmutableSet<Flux<Integer>> testFluxJust() {
return ImmutableSet.of(Flux.range(0, 1), Mono.just(2).repeat().take(1));
return ImmutableSet.of(
Flux.range(0, 1),
Mono.just(2).flux(),
Mono.just(3).repeat().take(1),
Flux.fromIterable(ImmutableList.of(4)),
Flux.fromIterable(ImmutableSet.of(5)));
}
ImmutableSet<Mono<?>> testMonoIdentity() {
@@ -342,7 +347,11 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
}
ImmutableSet<Mono<Void>> testMonoThen() {
return ImmutableSet.of(Mono.just("foo").ignoreElement().then(), Mono.just("bar").flux().then());
return ImmutableSet.of(
Mono.just("foo").ignoreElement().then(),
Mono.just("bar").flux().then(),
Mono.when(Mono.just("baz")),
Mono.whenDelayError(Mono.just("qux")));
}
ImmutableSet<Mono<Void>> testFluxThen() {
@@ -388,8 +397,10 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
ImmutableSet<Mono<Optional<String>>> testMonoSingleOptional() {
return ImmutableSet.of(
Mono.just("foo").flux().collect(toOptional()),
Mono.just("bar").map(Optional::of).defaultIfEmpty(Optional.empty()),
Mono.just("baz").transform(Mono::singleOptional));
Mono.just("bar").map(Optional::of),
Mono.just("baz").singleOptional().defaultIfEmpty(Optional.empty()),
Mono.just("quux").singleOptional().switchIfEmpty(Mono.just(Optional.empty())),
Mono.just("quuz").transform(Mono::singleOptional));
}
Mono<Number> testMonoCast() {

View File

@@ -192,7 +192,7 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
}
ImmutableSet<Flux<Integer>> testFluxJust() {
return ImmutableSet.of(Flux.just(0), Flux.just(2));
return ImmutableSet.of(Flux.just(0), Flux.just(2), Flux.just(3), Flux.just(4), Flux.just(5));
}
ImmutableSet<Mono<?>> testMonoIdentity() {
@@ -340,7 +340,11 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
}
ImmutableSet<Mono<Void>> testMonoThen() {
return ImmutableSet.of(Mono.just("foo").then(), Mono.just("bar").then());
return ImmutableSet.of(
Mono.just("foo").then(),
Mono.just("bar").then(),
Mono.just("baz").then(),
Mono.just("qux").then());
}
ImmutableSet<Mono<Void>> testFluxThen() {
@@ -384,7 +388,9 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
return ImmutableSet.of(
Mono.just("foo").singleOptional(),
Mono.just("bar").singleOptional(),
Mono.just("baz").singleOptional());
Mono.just("baz").singleOptional(),
Mono.just("quux").singleOptional(),
Mono.just("quuz").singleOptional());
}
Mono<Number> testMonoCast() {

View File

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

View File

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

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.20.1-SNAPSHOT</version>
<version>0.21.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.20.1-SNAPSHOT</version>
<version>0.21.1-SNAPSHOT</version>
</parent>
<artifactId>error-prone-guidelines</artifactId>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

225
pom.xml
View File

@@ -4,7 +4,7 @@
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.20.1-SNAPSHOT</version>
<version>0.21.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Picnic :: Error Prone Support</name>
@@ -146,7 +146,7 @@
<error-prone.self-check-args />
<!-- The build timestamp is derived from the most recent commit
timestamp in support of reproducible builds. -->
<project.build.outputTimestamp>2025-02-02T12:19:40Z</project.build.outputTimestamp>
<project.build.outputTimestamp>2025-03-24T10:41:07Z</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,17 +205,21 @@
<version.auto-service>1.1.1</version.auto-service>
<version.auto-value>1.11.0</version.auto-value>
<version.error-prone>${version.error-prone-orig}</version.error-prone>
<version.error-prone-fork>${version.error-prone-orig}-picnic-2</version.error-prone-fork>
<version.error-prone-orig>2.36.0</version.error-prone-orig>
<version.error-prone-fork>${version.error-prone-orig}-picnic-1</version.error-prone-fork>
<version.error-prone-orig>2.37.0</version.error-prone-orig>
<version.error-prone-slf4j>0.1.28</version.error-prone-slf4j>
<version.guava-beta-checker>1.0</version.guava-beta-checker>
<version.jdk>17</version.jdk>
<version.jmh>1.37</version.jmh>
<version.maven>3.9.9</version.maven>
<version.mockito>5.15.2</version.mockito>
<version.nopen-checker>1.0.1</version.nopen-checker>
<version.nullaway>0.12.3</version.nullaway>
<version.pitest-git>1.1.4</version.pitest-git>
<version.rewrite-templating>1.22.1</version.rewrite-templating>
<version.mockito>5.17.0</version.mockito>
<!-- XXX: Consider providing our own implementation with similar
functionality, and designing it such that JMH classes would not need to
be annotated `@Open`. -->
<version.nopen>1.0.1</version.nopen>
<version.nullaway>0.12.5</version.nullaway>
<version.pitest-git>2.2.0</version.pitest-git>
<version.rewrite-templating>1.24.2</version.rewrite-templating>
<version.surefire>3.2.3</version.surefire>
</properties>
@@ -269,7 +273,7 @@
<dependency>
<groupId>com.fasterxml.jackson</groupId>
<artifactId>jackson-bom</artifactId>
<version>2.18.2</version>
<version>2.18.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@@ -331,7 +335,7 @@
<dependency>
<groupId>com.google.googlejavaformat</groupId>
<artifactId>google-java-format</artifactId>
<version>1.25.2</version>
<version>1.26.0</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
@@ -350,10 +354,15 @@
<artifactId>truth</artifactId>
<version>1.4.4</version>
</dependency>
<dependency>
<groupId>com.jakewharton.nopen</groupId>
<artifactId>nopen-annotations</artifactId>
<version>${version.nopen}</version>
</dependency>
<dependency>
<groupId>com.jakewharton.nopen</groupId>
<artifactId>nopen-checker</artifactId>
<version>${version.nopen-checker}</version>
<version>${version.nopen}</version>
</dependency>
<dependency>
<groupId>com.uber.nullaway</groupId>
@@ -363,14 +372,14 @@
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-bom</artifactId>
<version>1.14.4</version>
<version>1.14.5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-bom</artifactId>
<version>2024.0.3</version>
<version>2024.0.4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@@ -387,7 +396,7 @@
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
<version>2.2.28</version>
<version>2.2.29</version>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
@@ -422,7 +431,7 @@
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>1.17.1</version>
<version>1.17.5</version>
</dependency>
<!-- Specified so that Renovate will file Maven upgrade PRs, which
subsequently will cause `maven-enforcer-plugin` to require that
@@ -435,7 +444,7 @@
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.22.1</version>
<version>1.9.23</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
@@ -447,7 +456,7 @@
<dependency>
<groupId>org.checkerframework</groupId>
<artifactId>checker-qual</artifactId>
<version>3.49.0</version>
<version>3.49.1</version>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
@@ -472,7 +481,7 @@
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.11.4</version>
<version>5.12.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@@ -485,8 +494,20 @@
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-core</artifactId>
<version>5.3.1</version>
<artifactId>mongodb-driver-bom</artifactId>
<version>5.4.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>${version.jmh}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>${version.jmh}</version>
</dependency>
<dependency>
<groupId>org.openrewrite</groupId>
@@ -496,33 +517,33 @@
<dependency>
<groupId>org.openrewrite.recipe</groupId>
<artifactId>rewrite-recipe-bom</artifactId>
<version>3.2.0</version>
<version>3.5.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-bom</artifactId>
<version>2.0.16</version>
<version>2.0.17</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>6.2.3</version>
<version>6.2.5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<version>3.4.2</version>
<version>3.4.4</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-bom</artifactId>
<version>6.4.2</version>
<version>6.4.4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@@ -548,6 +569,16 @@
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>com.arcmutate</groupId>
<artifactId>pitest-git-maven-plugin</artifactId>
<version>${version.pitest-git}</version>
</plugin>
<plugin>
<groupId>com.arcmutate</groupId>
<artifactId>pitest-github-maven-plugin</artifactId>
<version>${version.pitest-git}</version>
</plugin>
<plugin>
<groupId>com.github.ekryd.sortpom</groupId>
<artifactId>sortpom-maven-plugin</artifactId>
@@ -575,16 +606,6 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.groupcdg</groupId>
<artifactId>pitest-git-maven-plugin</artifactId>
<version>${version.pitest-git}</version>
</plugin>
<plugin>
<groupId>com.groupcdg</groupId>
<artifactId>pitest-github-maven-plugin</artifactId>
<version>${version.pitest-git}</version>
</plugin>
<plugin>
<groupId>com.spotify.fmt</groupId>
<artifactId>fmt-maven-plugin</artifactId>
@@ -608,11 +629,10 @@
<plugin>
<groupId>de.thetaphi</groupId>
<artifactId>forbiddenapis</artifactId>
<version>3.8</version>
<version>3.9</version>
<configuration>
<bundledSignatures>
<bundledSignature>jdk-internal</bundledSignature>
<bundledSignature>jdk-reflection</bundledSignature>
<bundledSignature>jdk-system-out</bundledSignature>
<!-- Other bundles are available but currently not
enabled:
@@ -622,6 +642,10 @@
- jdk-deprecated: we compile with `-Xlint:all`,
which causes the build to fail when _any_
deprecated method is called.
- jdk-reflection: this bundle should probably be
enabled, but currently
`java.lang.reflect.AccessibleObject#setAccessible`
is still called in various places.
- jdk-non-portable: the Error Prone integration
crucially relies on some of these APIs.
- jdk-unsafe: see
@@ -923,7 +947,7 @@
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>10.21.2</version>
<version>10.22.0</version>
</dependency>
<dependency>
<groupId>io.spring.nohttp</groupId>
@@ -948,7 +972,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<version>3.14.0</version>
<configuration>
<annotationProcessorPaths>
<!-- XXX: Inline and drop the version
@@ -959,6 +983,11 @@
<artifactId>auto-value</artifactId>
<version>${version.auto-value}</version>
</path>
<path>
<groupId>com.google.auto.value</groupId>
<artifactId>auto-value</artifactId>
<version>${version.auto-value}</version>
</path>
<path>
<groupId>com.google.auto.service</groupId>
<artifactId>auto-service</artifactId>
@@ -969,6 +998,10 @@
<artifactId>rewrite-templating</artifactId>
<version>${version.rewrite-templating}</version>
</path>
<path>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
</path>
</annotationProcessorPaths>
<compilerArgs>
<arg>--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</arg>
@@ -1056,7 +1089,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>3.1.3</version>
<version>3.1.4</version>
<configuration>
<retryFailedDeploymentCount>3</retryFailedDeploymentCount>
</configuration>
@@ -1134,7 +1167,7 @@
<dependency>
<groupId>org.codehaus.mojo</groupId>
<artifactId>extra-enforcer-rules</artifactId>
<version>1.9.0</version>
<version>1.10.0</version>
</dependency>
</dependencies>
<executions>
@@ -1162,7 +1195,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>3.1.3</version>
<version>3.1.4</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -1298,7 +1331,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.5.2</version>
<version>3.5.3</version>
<configuration>
<includes>
<include>**/*Test.java</include>
@@ -1306,11 +1339,17 @@
<properties>
<configurationParameters>junit.jupiter.execution.parallel.enabled=true
junit.jupiter.execution.parallel.mode.default=concurrent
junit.jupiter.execution.timeout.threaddump.enabled=true
junit.platform.stacktrace.pruning.enabled=false</configurationParameters>
</properties>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.1.1</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>license-maven-plugin</artifactId>
@@ -1408,6 +1447,7 @@
GPL-2.0-with-classpath-exception
| CDDL/GPLv2+CE
| CDDL + GPLv2 with classpath exception
| GNU General Public License (GPL), version 2, with the 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
@@ -1442,7 +1482,7 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tidy-maven-plugin</artifactId>
<version>1.3.0</version>
<version>1.4.0</version>
<executions>
<execution>
<id>check-pom</id>
@@ -1494,7 +1534,7 @@
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.12</version>
<version>0.8.13</version>
<configuration>
<excludes>
<!-- Refaster rules are tested using a custom method
@@ -1524,7 +1564,7 @@
<plugin>
<groupId>org.pitest</groupId>
<artifactId>pitest-maven</artifactId>
<version>1.18.1</version>
<version>1.19.0</version>
<configuration>
<excludedClasses>
<!-- AutoValue generated classes. -->
@@ -1546,24 +1586,24 @@
</configuration>
<dependencies>
<dependency>
<groupId>com.groupcdg</groupId>
<groupId>com.arcmutate</groupId>
<artifactId>base</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>com.arcmutate</groupId>
<artifactId>pitest-accelerator-junit5</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>com.arcmutate</groupId>
<artifactId>pitest-git-plugin</artifactId>
<version>${version.pitest-git}</version>
</dependency>
<dependency>
<groupId>com.groupcdg.arcmutate</groupId>
<artifactId>base</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>com.groupcdg.pitest</groupId>
<artifactId>pitest-accelerator-junit5</artifactId>
<version>1.0.6</version>
</dependency>
<dependency>
<groupId>org.pitest</groupId>
<artifactId>pitest-junit5-plugin</artifactId>
<version>1.2.1</version>
<version>1.2.2</version>
</dependency>
</dependencies>
<executions>
@@ -1578,7 +1618,7 @@
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>5.0.0.4389</version>
<version>5.1.0.4751</version>
</plugin>
</plugins>
</pluginManagement>
@@ -1865,7 +1905,7 @@
<path>
<groupId>com.jakewharton.nopen</groupId>
<artifactId>nopen-checker</artifactId>
<version>${version.nopen-checker}</version>
<version>${version.nopen}</version>
</path>
<path>
<groupId>com.uber.nullaway</groupId>
@@ -1938,9 +1978,7 @@
-XepOpt:NullAway:AssertsEnabled=true
-XepOpt:NullAway:CheckOptionalEmptiness=true
-XepOpt:Nullness:Conservative=false
-XepOpt:StatementSwitchToExpressionSwitch:EnableAssignmentSwitchConversion=true
-XepOpt:StatementSwitchToExpressionSwitch:EnableDirectConversion=true
-XepOpt:StatementSwitchToExpressionSwitch:EnableReturnSwitchConversion=true
<!-- Append additional custom arguments. -->
${error-prone.patch-args}
${error-prone.self-check-args}
@@ -2154,5 +2192,66 @@
</plugins>
</build>
</profile>
<profile>
<!-- Enables execution of a JMH benchmark. Given a benchmark class
`tech.picnic.MyBenchmark`, the following command (executed against
the (sub)module in which the benchmark resides) will compile and
execute said benchmark:
mvn process-test-classes -Dverification.skip \
-Djmh.run-benchmark=tech.picnic.MyBenchmark
-->
<id>run-jmh-benchmark</id>
<activation>
<property>
<name>jmh.run-benchmark</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>build-jmh-runtime-classpath</id>
<goals>
<goal>build-classpath</goal>
</goals>
<configuration>
<outputProperty>testClasspath</outputProperty>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<id>run-jmh-benchmark</id>
<goals>
<goal>java</goal>
</goals>
<phase>process-test-classes</phase>
<configuration>
<classpathScope>test</classpathScope>
<mainClass>${jmh.run-benchmark}</mainClass>
<systemProperties>
<!-- The runtime classpath is defined
in this way so that any JVMs forked by
JMH will have the desired classpath. -->
<systemProperty>
<key>java.class.path</key>
<value>${project.build.testOutputDirectory}${path.separator}${project.build.outputDirectory}${path.separator}${testClasspath}</value>
</systemProperty>
</systemProperties>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

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

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>tech.picnic.error-prone-support</groupId>
<artifactId>error-prone-support</artifactId>
<version>0.20.1-SNAPSHOT</version>
<version>0.21.1-SNAPSHOT</version>
</parent>
<artifactId>refaster-runner</artifactId>
@@ -26,13 +26,21 @@
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>refaster-support</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.google.auto</groupId>
<artifactId>auto-common</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.auto.service</groupId>
<artifactId>auto-service-annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.auto.value</groupId>
<artifactId>auto-value-annotations</artifactId>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_annotation</artifactId>
@@ -48,6 +56,11 @@
<artifactId>error_prone_check_api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_test_helpers</artifactId>
@@ -58,6 +71,11 @@
<artifactId>guava</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.jakewharton.nopen</groupId>
<artifactId>nopen-annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
@@ -95,6 +113,11 @@
<artifactId>junit-jupiter-params</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.openrewrite</groupId>
<artifactId>rewrite-core</artifactId>

View File

@@ -0,0 +1,126 @@
package tech.picnic.errorprone.refaster.runner;
import static java.util.Comparator.comparingInt;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Maps;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
/**
* A node in an immutable tree.
*
* <p>The tree's edges are string-labeled, while its leaves store values of type {@code T}.
*/
@AutoValue
abstract class Node<T> {
// XXX: Review: should this method accept a `SetMultimap<V, ? extends Set<String>>`, or should
// there be such an overload?
static <T> Node<T> create(
Set<T> values, Function<? super T, ? extends Set<? extends Set<String>>> pathExtractor) {
Builder<T> tree = Builder.create();
tree.register(values, pathExtractor);
return tree.build();
}
abstract ImmutableMap<String, Node<T>> children();
abstract ImmutableList<T> values();
// XXX: Consider having `RefasterRuleSelector` already collect the candidate edges into a
// `SortedSet`, as that would likely speed up `ImmutableSortedSet#copyOf`.
// XXX: If this ^ proves worthwhile, then the test code and benchmark should be updated
// accordingly.
void collectReachableValues(Set<String> candidateEdges, Consumer<T> sink) {
collectReachableValues(ImmutableSortedSet.copyOf(candidateEdges).asList(), sink);
}
private void collectReachableValues(ImmutableList<String> candidateEdges, Consumer<T> sink) {
values().forEach(sink);
if (candidateEdges.isEmpty() || children().isEmpty()) {
return;
}
/*
* For performance reasons we iterate over the smallest set of edges. In case there are fewer
* children than candidate edges we iterate over the former, at the cost of not pruning the set
* of candidate edges if a transition is made.
*/
int candidateEdgeCount = candidateEdges.size();
if (children().size() < candidateEdgeCount) {
for (Map.Entry<String, Node<T>> e : children().entrySet()) {
if (candidateEdges.contains(e.getKey())) {
e.getValue().collectReachableValues(candidateEdges, sink);
}
}
} else {
for (int i = 0; i < candidateEdgeCount; i++) {
Node<T> child = children().get(candidateEdges.get(i));
if (child != null) {
child.collectReachableValues(candidateEdges.subList(i + 1, candidateEdgeCount), sink);
}
}
}
}
@AutoValue
@SuppressWarnings("AutoValueImmutableFields" /* Type is used only during `Node` construction. */)
abstract static class Builder<T> {
private static <T> Builder<T> create() {
return new AutoValue_Node_Builder<>(new HashMap<>(), new ArrayList<>());
}
abstract Map<String, Builder<T>> children();
abstract List<T> values();
/**
* Registers all paths to each of the given values.
*
* <p>Shorter paths are registered first, so that longer paths can be skipped if a strict prefix
* leads to the same value.
*/
private void register(
Set<T> values, Function<? super T, ? extends Set<? extends Set<String>>> pathsExtractor) {
for (T value : values) {
List<? extends Set<String>> paths = new ArrayList<>(pathsExtractor.apply(value));
/*
* We sort paths by length ascending, so that in case of two paths where one is an initial
* prefix of the other, only the former is encoded (thus saving some space).
*/
paths.sort(comparingInt(Set::size));
paths.forEach(path -> registerPath(value, ImmutableList.sortedCopyOf(path)));
}
}
private void registerPath(T value, ImmutableList<String> path) {
if (values().contains(value)) {
/* Another (shorter) path already leads to this value. */
return;
}
if (path.isEmpty()) {
values().add(value);
} else {
children()
.computeIfAbsent(path.get(0), k -> create())
.registerPath(value, path.subList(1, path.size()));
}
}
private Node<T> build() {
return new AutoValue_Node<>(
ImmutableMap.copyOf(Maps.transformValues(children(), Builder::build)),
ImmutableList.copyOf(values()));
}
}
}

View File

@@ -21,7 +21,6 @@ import com.google.common.collect.TreeRangeSet;
import com.google.errorprone.BugPattern;
import com.google.errorprone.BugPattern.SeverityLevel;
import com.google.errorprone.CodeTransformer;
import com.google.errorprone.CompositeCodeTransformer;
import com.google.errorprone.ErrorProneFlags;
import com.google.errorprone.ErrorProneOptions.Severity;
import com.google.errorprone.SubContext;
@@ -39,6 +38,7 @@ import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import javax.inject.Inject;
@@ -64,8 +64,9 @@ public final class Refaster extends BugChecker implements CompilationUnitTreeMat
private static final long serialVersionUID = 1L;
// XXX: Review this suppression.
@SuppressWarnings({"java:S1948", "serial"} /* Concrete instance will be `Serializable`. */)
private final CodeTransformer codeTransformer;
private final RefasterRuleSelector ruleSelector;
/** Instantiates a default {@link Refaster} instance. */
public Refaster() {
@@ -80,16 +81,29 @@ public final class Refaster extends BugChecker implements CompilationUnitTreeMat
@Inject
@VisibleForTesting
public Refaster(ErrorProneFlags flags) {
codeTransformer = createCompositeCodeTransformer(flags);
ruleSelector = createRefasterRuleSelector(flags);
}
@CanIgnoreReturnValue
@Override
public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState state) {
/* First, collect all matches. */
List<Description> matches = new ArrayList<>();
codeTransformer.apply(state.getPath(), new SubContext(state.context), matches::add);
Set<CodeTransformer> candidateTransformers = ruleSelector.selectCandidateRules(tree);
/* First, collect all matches. */
SubContext context = new SubContext(state.context);
List<Description> matches = new ArrayList<>();
for (CodeTransformer transformer : candidateTransformers) {
try {
transformer.apply(state.getPath(), context, matches::add);
} catch (LinkageError e) {
// XXX: This `try/catch` block handles the issue described and resolved in
// https://github.com/google/error-prone/pull/2456. Drop this block once that change is
// released.
// XXX: Find a way to identify that we're running Picnic's Error Prone fork and disable this
// fallback if so, as it might hide other bugs.
return Description.NO_MATCH;
}
}
/* Then apply them. */
applyMatches(matches, ((JCCompilationUnit) tree).endPositions, state);
@@ -193,10 +207,12 @@ public final class Refaster extends BugChecker implements CompilationUnitTreeMat
return description.fixes.stream().flatMap(fix -> fix.getReplacements(endPositions).stream());
}
private static CodeTransformer createCompositeCodeTransformer(ErrorProneFlags flags) {
// XXX: Add a flag to disable the optimized `RefasterRuleSelector`. That would allow us to verify
// that we're not prematurely pruning rules.
private static RefasterRuleSelector createRefasterRuleSelector(ErrorProneFlags flags) {
ImmutableListMultimap<String, CodeTransformer> allTransformers =
CodeTransformers.getAllCodeTransformers();
return CompositeCodeTransformer.compose(
return RefasterRuleSelector.create(
flags
.get(INCLUDED_RULES_PATTERN_FLAG)
.map(Pattern::compile)

View File

@@ -0,0 +1,510 @@
package tech.picnic.errorprone.refaster.runner;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static java.util.Collections.newSetFromMap;
import static java.util.stream.Collectors.toCollection;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.errorprone.CodeTransformer;
import com.google.errorprone.CompositeCodeTransformer;
import com.google.errorprone.refaster.BlockTemplate;
import com.google.errorprone.refaster.ExpressionTemplate;
import com.google.errorprone.refaster.RefasterRule;
import com.google.errorprone.refaster.UAnyOf;
import com.google.errorprone.refaster.UExpression;
import com.google.errorprone.refaster.UStatement;
import com.google.errorprone.refaster.UStaticIdent;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import com.sun.source.tree.AssignmentTree;
import com.sun.source.tree.BinaryTree;
import com.sun.source.tree.ClassTree;
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.CompoundAssignmentTree;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.IdentifierTree;
import com.sun.source.tree.MemberReferenceTree;
import com.sun.source.tree.MemberSelectTree;
import com.sun.source.tree.MethodTree;
import com.sun.source.tree.PackageTree;
import com.sun.source.tree.Tree;
import com.sun.source.tree.UnaryTree;
import com.sun.source.tree.VariableTree;
import com.sun.source.util.TreeScanner;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jspecify.annotations.Nullable;
import tech.picnic.errorprone.refaster.AnnotatedCompositeCodeTransformer;
// XXX: Add some examples of which source files would match what templates in the tree.
// XXX: Consider this text in general.
/**
* A {@link RefasterRuleSelector} algorithm that selects Refaster templates based on the content of
* a {@link CompilationUnitTree}.
*
* <p>The algorithm consists of the following steps:
*
* <ol>
* <li>Create a {@link Node tree} structure based on the provided Refaster templates.
* <ol>
* <li>Extract all identifiers from the {@link BeforeTemplate}s.
* <li>Sort identifiers lexicographically and collect into a set.
* <li>Add a path to the tree based on the sorted identifiers.
* </ol>
* <li>Extract all identifiers from the {@link CompilationUnitTree} and sort them
* lexicographically.
* <li>Traverse the tree based on the identifiers from the {@link CompilationUnitTree}. Every node
* can contain Refaster templates. Once a node is we found a candidate Refaster template that
* might match some code and will therefore be added to the list of candidates.
* </ol>
*
* <p>This is an example to explain the algorithm. Consider the templates with identifiers; {@code
* T1 = [A, B, C]}, {@code T2 = [B]}, and {@code T3 = [B, D]}. This will result in the following
* tree structure:
*
* <pre>{@code
* <root>
* ├── A
* │ └── B
* │ └── C -- T1
* └── B -- T2
* └── D -- T3
* }</pre>
*
* <p>The tree is traversed based on the identifiers in the {@link CompilationUnitTree}. When a node
* containing a template is reached, we can be certain that the identifiers from the {@link
* BeforeTemplate} are at least present in the {@link CompilationUnitTree}.
*
* <p>Since the identifiers are sorted, we can skip parts of the {@link Node tree} while we are
* traversing it. Instead of trying to match all Refaster templates against every expression in a
* {@link CompilationUnitTree} we now only matching a subset of the templates that at least have a
* chance of matching. As a result, the performance of Refaster increases significantly.
*/
final class RefasterRuleSelector {
private final Node<CodeTransformer> codeTransformers;
private RefasterRuleSelector(Node<CodeTransformer> codeTransformers) {
this.codeTransformers = codeTransformers;
}
/**
* Instantiates a new {@link RefasterRuleSelector} backed by the given {@link CodeTransformer}s.
*/
static RefasterRuleSelector create(ImmutableCollection<CodeTransformer> refasterRules) {
Map<CodeTransformer, ImmutableSet<ImmutableSet<String>>> ruleIdentifiersByTransformer =
indexRuleIdentifiers(refasterRules);
return new RefasterRuleSelector(
Node.create(ruleIdentifiersByTransformer.keySet(), ruleIdentifiersByTransformer::get));
}
/**
* Retrieves a set of Refaster templates that can possibly match based on a {@link
* CompilationUnitTree}.
*
* @param tree The {@link CompilationUnitTree} for which candidate Refaster templates are
* selected.
* @return Set of Refaster templates that can possibly match in the provided {@link
* CompilationUnitTree}.
*/
Set<CodeTransformer> selectCandidateRules(CompilationUnitTree tree) {
Set<CodeTransformer> candidateRules = newSetFromMap(new IdentityHashMap<>());
codeTransformers.collectReachableValues(extractSourceIdentifiers(tree), candidateRules::add);
return candidateRules;
}
private static Map<CodeTransformer, ImmutableSet<ImmutableSet<String>>> indexRuleIdentifiers(
ImmutableCollection<CodeTransformer> codeTransformers) {
IdentityHashMap<CodeTransformer, ImmutableSet<ImmutableSet<String>>> identifiers =
new IdentityHashMap<>();
for (CodeTransformer transformer : codeTransformers) {
collectRuleIdentifiers(transformer, identifiers);
}
return identifiers;
}
private static void collectRuleIdentifiers(
CodeTransformer codeTransformer,
Map<CodeTransformer, ImmutableSet<ImmutableSet<String>>> identifiers) {
if (codeTransformer instanceof CompositeCodeTransformer compositeCodeTransformer) {
for (CodeTransformer transformer : compositeCodeTransformer.transformers()) {
collectRuleIdentifiers(transformer, identifiers);
}
} else if (codeTransformer instanceof AnnotatedCompositeCodeTransformer annotatedTransformer) {
for (Map.Entry<CodeTransformer, ImmutableSet<ImmutableSet<String>>> e :
indexRuleIdentifiers(annotatedTransformer.transformers()).entrySet()) {
identifiers.put(annotatedTransformer.withTransformers(e.getKey()), e.getValue());
}
} else if (codeTransformer instanceof RefasterRule) {
identifiers.put(
codeTransformer, extractRuleIdentifiers((RefasterRule<?, ?>) codeTransformer));
} else {
/* Unrecognized `CodeTransformer` types are indexed such that they always apply. */
identifiers.put(codeTransformer, ImmutableSet.of(ImmutableSet.of()));
}
}
// XXX: Consider decomposing `RefasterRule`s such that each rule has exactly one
// `@BeforeTemplate`.
private static ImmutableSet<ImmutableSet<String>> extractRuleIdentifiers(
RefasterRule<?, ?> refasterRule) {
ImmutableSet.Builder<ImmutableSet<String>> results = ImmutableSet.builder();
for (Object template : RefasterIntrospection.getBeforeTemplates(refasterRule)) {
if (template instanceof ExpressionTemplate expressionTemplate) {
UExpression expr = RefasterIntrospection.getExpression(expressionTemplate);
results.addAll(extractRuleIdentifiers(ImmutableList.of(expr)));
} else if (template instanceof BlockTemplate blockTemplate) {
ImmutableList<UStatement> statements =
RefasterIntrospection.getTemplateStatements(blockTemplate);
results.addAll(extractRuleIdentifiers(statements));
} else {
throw new IllegalStateException(
String.format("Unexpected template type '%s'", template.getClass()));
}
}
return results.build();
}
// XXX: Consider interning the strings (once a benchmark is in place).
private static ImmutableSet<ImmutableSet<String>> extractRuleIdentifiers(
ImmutableList<? extends Tree> trees) {
List<Set<String>> identifierCombinations = new ArrayList<>();
identifierCombinations.add(new HashSet<>());
TemplateIdentifierExtractor.INSTANCE.scan(trees, identifierCombinations);
return identifierCombinations.stream().map(ImmutableSet::copyOf).collect(toImmutableSet());
}
private static Set<String> extractSourceIdentifiers(Tree tree) {
Set<String> identifiers = new HashSet<>();
SourceIdentifierExtractor.INSTANCE.scan(tree, identifiers);
return identifiers;
}
/**
* Returns a unique string representation of the given {@link Tree.Kind}.
*
* @return A string representation of the operator, if known
* @throws IllegalArgumentException If the given input is not supported.
*/
// XXX: Extend list to cover remaining cases; at least for any `Kind` that may appear in a
// Refaster template. (E.g. keywords such as `if`, `instanceof`, `new`, ...)
private static String treeKindToString(Tree.Kind kind) {
return switch (kind) {
case ASSIGNMENT -> "=";
case POSTFIX_INCREMENT -> "x++";
case PREFIX_INCREMENT -> "++x";
case POSTFIX_DECREMENT -> "x--";
case PREFIX_DECREMENT -> "--x";
case UNARY_PLUS -> "+x";
case UNARY_MINUS -> "-x";
case BITWISE_COMPLEMENT -> "~";
case LOGICAL_COMPLEMENT -> "!";
case MULTIPLY -> "*";
case DIVIDE -> "/";
case REMAINDER -> "%";
case PLUS -> "+";
case MINUS -> "-";
case LEFT_SHIFT -> "<<";
case RIGHT_SHIFT -> ">>";
case UNSIGNED_RIGHT_SHIFT -> ">>>";
case LESS_THAN -> "<";
case GREATER_THAN -> ">";
case LESS_THAN_EQUAL -> "<=";
case GREATER_THAN_EQUAL -> ">=";
case EQUAL_TO -> "==";
case NOT_EQUAL_TO -> "!=";
case AND -> "&";
case XOR -> "^";
case OR -> "|";
case CONDITIONAL_AND -> "&&";
case CONDITIONAL_OR -> "||";
case MULTIPLY_ASSIGNMENT -> "*=";
case DIVIDE_ASSIGNMENT -> "/=";
case REMAINDER_ASSIGNMENT -> "%=";
case PLUS_ASSIGNMENT -> "+=";
case MINUS_ASSIGNMENT -> "-=";
case LEFT_SHIFT_ASSIGNMENT -> "<<=";
case RIGHT_SHIFT_ASSIGNMENT -> ">>=";
case UNSIGNED_RIGHT_SHIFT_ASSIGNMENT -> ">>>=";
case AND_ASSIGNMENT -> "&=";
case XOR_ASSIGNMENT -> "^=";
case OR_ASSIGNMENT -> "|=";
default -> throw new IllegalStateException("Cannot convert Tree.Kind to a String: " + kind);
};
}
private static final class RefasterIntrospection {
// XXX: Update `ErrorProneRuntimeClasspath` to not suggest inaccessible types.
@SuppressWarnings("ErrorProneRuntimeClasspath")
private static final String UCLASS_IDENT_FQCN = "com.google.errorprone.refaster.UClassIdent";
private static final Class<?> UCLASS_IDENT = getClass(UCLASS_IDENT_FQCN);
private static final Method METHOD_REFASTER_RULE_BEFORE_TEMPLATES =
getMethod(RefasterRule.class, "beforeTemplates");
private static final Method METHOD_EXPRESSION_TEMPLATE_EXPRESSION =
getMethod(ExpressionTemplate.class, "expression");
private static final Method METHOD_BLOCK_TEMPLATE_TEMPLATE_STATEMENTS =
getMethod(BlockTemplate.class, "templateStatements");
private static final Method METHOD_USTATIC_IDENT_CLASS_IDENT =
getMethod(UStaticIdent.class, "classIdent");
private static final Method METHOD_UCLASS_IDENT_GET_TOP_LEVEL_CLASS =
getMethod(UCLASS_IDENT, "getTopLevelClass");
private static final Method METHOD_UANY_OF_EXPRESSIONS = getMethod(UAnyOf.class, "expressions");
static boolean isUClassIdent(IdentifierTree tree) {
return UCLASS_IDENT.isInstance(tree);
}
static ImmutableList<?> getBeforeTemplates(RefasterRule<?, ?> refasterRule) {
return invokeMethod(METHOD_REFASTER_RULE_BEFORE_TEMPLATES, refasterRule);
}
static UExpression getExpression(ExpressionTemplate template) {
return invokeMethod(METHOD_EXPRESSION_TEMPLATE_EXPRESSION, template);
}
static ImmutableList<UStatement> getTemplateStatements(BlockTemplate template) {
return invokeMethod(METHOD_BLOCK_TEMPLATE_TEMPLATE_STATEMENTS, template);
}
static IdentifierTree getClassIdent(UStaticIdent tree) {
return invokeMethod(METHOD_USTATIC_IDENT_CLASS_IDENT, tree);
}
// Arguments to this method must actually be of the package-private type `UClassIdent`.
static String getTopLevelClass(IdentifierTree uClassIdent) {
return invokeMethod(METHOD_UCLASS_IDENT_GET_TOP_LEVEL_CLASS, uClassIdent);
}
static ImmutableList<UExpression> getExpressions(UAnyOf tree) {
return invokeMethod(METHOD_UANY_OF_EXPRESSIONS, tree);
}
private static Class<?> getClass(String fqcn) {
try {
return RefasterIntrospection.class.getClassLoader().loadClass(fqcn);
} catch (ClassNotFoundException e) {
throw new IllegalStateException(String.format("Failed to load class `%s`", fqcn), e);
}
}
private static Method getMethod(Class<?> clazz, String methodName) {
try {
Method method = clazz.getDeclaredMethod(methodName);
method.setAccessible(true);
return method;
} catch (NoSuchMethodException e) {
throw new IllegalStateException(
String.format("No method `%s` on class `%s`", methodName, clazz.getName()), e);
}
}
@SuppressWarnings({"TypeParameterUnusedInFormals", "unchecked"})
private static <T> T invokeMethod(Method method, Object instance) {
try {
return (T) method.invoke(instance);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new IllegalStateException(String.format("Failed to invoke method `%s`", method), e);
}
}
}
private static final class TemplateIdentifierExtractor
extends TreeScanner<@Nullable Void, List<Set<String>>> {
private static final TemplateIdentifierExtractor INSTANCE = new TemplateIdentifierExtractor();
@Override
public @Nullable Void visitIdentifier(
IdentifierTree node, List<Set<String>> identifierCombinations) {
// XXX: Also include the package name if not `java.lang`; it must be present.
if (RefasterIntrospection.isUClassIdent(node)) {
for (Set<String> ids : identifierCombinations) {
ids.add(getSimpleName(RefasterIntrospection.getTopLevelClass(node)));
ids.add(getIdentifier(node));
}
} else if (node instanceof UStaticIdent uStaticIdent) {
IdentifierTree subNode = RefasterIntrospection.getClassIdent(uStaticIdent);
for (Set<String> ids : identifierCombinations) {
ids.add(getSimpleName(RefasterIntrospection.getTopLevelClass(subNode)));
ids.add(getIdentifier(subNode));
ids.add(node.getName().toString());
}
}
return null;
}
private static String getIdentifier(IdentifierTree tree) {
return getSimpleName(tree.getName().toString());
}
private static String getSimpleName(String fqcn) {
int index = fqcn.lastIndexOf('.');
return index < 0 ? fqcn : fqcn.substring(index + 1);
}
@Override
public @Nullable Void visitMemberReference(
MemberReferenceTree node, List<Set<String>> identifierCombinations) {
super.visitMemberReference(node, identifierCombinations);
String id = node.getName().toString();
identifierCombinations.forEach(ids -> ids.add(id));
return null;
}
@Override
public @Nullable Void visitMemberSelect(
MemberSelectTree node, List<Set<String>> identifierCombinations) {
super.visitMemberSelect(node, identifierCombinations);
String id = node.getIdentifier().toString();
identifierCombinations.forEach(ids -> ids.add(id));
return null;
}
@Override
public @Nullable Void visitAssignment(
AssignmentTree node, List<Set<String>> identifierCombinations) {
registerOperator(node, identifierCombinations);
return super.visitAssignment(node, identifierCombinations);
}
@Override
public @Nullable Void visitCompoundAssignment(
CompoundAssignmentTree node, List<Set<String>> identifierCombinations) {
registerOperator(node, identifierCombinations);
return super.visitCompoundAssignment(node, identifierCombinations);
}
@Override
public @Nullable Void visitUnary(UnaryTree node, List<Set<String>> identifierCombinations) {
registerOperator(node, identifierCombinations);
return super.visitUnary(node, identifierCombinations);
}
@Override
public @Nullable Void visitBinary(BinaryTree node, List<Set<String>> identifierCombinations) {
registerOperator(node, identifierCombinations);
return super.visitBinary(node, identifierCombinations);
}
private static void registerOperator(
ExpressionTree node, List<Set<String>> identifierCombinations) {
String id = treeKindToString(node.getKind());
identifierCombinations.forEach(ids -> ids.add(id));
}
@Override
public @Nullable Void visitOther(Tree node, List<Set<String>> identifierCombinations) {
if (node instanceof UAnyOf uAnyOf) {
List<Set<String>> base = copy(identifierCombinations);
identifierCombinations.clear();
for (UExpression expr : RefasterIntrospection.getExpressions(uAnyOf)) {
List<Set<String>> branch = copy(base);
scan(expr, branch);
identifierCombinations.addAll(branch);
}
}
return null;
}
private static List<Set<String>> copy(List<Set<String>> identifierCombinations) {
return identifierCombinations.stream()
.map(HashSet::new)
.collect(toCollection(ArrayList::new));
}
}
private static final class SourceIdentifierExtractor
extends TreeScanner<@Nullable Void, Set<String>> {
private static final SourceIdentifierExtractor INSTANCE = new SourceIdentifierExtractor();
@Override
public @Nullable Void visitPackage(PackageTree node, Set<String> identifiers) {
/* Refaster rules never match package declarations. */
return null;
}
@Override
public @Nullable Void visitClass(ClassTree node, Set<String> identifiers) {
/*
* Syntactic details of a class declaration other than the definition of its members do not
* need to be reflected in a Refaster rule for it to apply to the class's code.
*/
return scan(node.getMembers(), identifiers);
}
@Override
public @Nullable Void visitMethod(MethodTree node, Set<String> identifiers) {
/*
* Syntactic details of a method declaration other than its body do not need to be reflected
* in a Refaster rule for it to apply to the method's code.
*/
return scan(node.getBody(), identifiers);
}
@Override
public @Nullable Void visitVariable(VariableTree node, Set<String> identifiers) {
/* A variable's modifiers and name do not influence where a Refaster rule matches. */
return reduce(scan(node.getInitializer(), identifiers), scan(node.getType(), identifiers));
}
@Override
public @Nullable Void visitIdentifier(IdentifierTree node, Set<String> identifiers) {
identifiers.add(node.getName().toString());
return null;
}
@Override
public @Nullable Void visitMemberReference(MemberReferenceTree node, Set<String> identifiers) {
super.visitMemberReference(node, identifiers);
identifiers.add(node.getName().toString());
return null;
}
@Override
public @Nullable Void visitMemberSelect(MemberSelectTree node, Set<String> identifiers) {
super.visitMemberSelect(node, identifiers);
identifiers.add(node.getIdentifier().toString());
return null;
}
@Override
public @Nullable Void visitAssignment(AssignmentTree node, Set<String> identifiers) {
registerOperator(node, identifiers);
return super.visitAssignment(node, identifiers);
}
@Override
public @Nullable Void visitCompoundAssignment(
CompoundAssignmentTree node, Set<String> identifiers) {
registerOperator(node, identifiers);
return super.visitCompoundAssignment(node, identifiers);
}
@Override
public @Nullable Void visitUnary(UnaryTree node, Set<String> identifiers) {
registerOperator(node, identifiers);
return super.visitUnary(node, identifiers);
}
@Override
public @Nullable Void visitBinary(BinaryTree node, Set<String> identifiers) {
registerOperator(node, identifiers);
return super.visitBinary(node, identifiers);
}
private static void registerOperator(ExpressionTree node, Set<String> identifiers) {
identifiers.add(treeKindToString(node.getKind()));
}
}
}

View File

@@ -0,0 +1,83 @@
package tech.picnic.errorprone.refaster.runner;
import static com.google.common.collect.ImmutableListMultimap.flatteningToImmutableListMultimap;
import static java.util.function.Function.identity;
import com.google.common.collect.ImmutableListMultimap;
import com.jakewharton.nopen.annotation.Open;
import java.util.Collection;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.infra.Blackhole;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import tech.picnic.errorprone.refaster.runner.NodeTestCase.NodeTestCaseEntry;
@Open
@State(Scope.Benchmark)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Fork(jvmArgs = {"-Xms1G", "-Xmx1G"})
@Warmup(iterations = 5)
@Measurement(iterations = 10)
public class NodeBenchmark {
@SuppressWarnings("NullAway" /* Initialized by `@Setup` method. */)
private ImmutableListMultimap<NodeTestCase<Integer>, NodeTestCaseEntry<Integer>> testCases;
public static void main(String[] args) throws RunnerException {
// XXX: Update `ErrorProneRuntimeClasspath` to allow same-package `Class` references.
@SuppressWarnings("ErrorProneRuntimeClasspath")
String testRegex = Pattern.quote(NodeBenchmark.class.getCanonicalName());
new Runner(new OptionsBuilder().include(testRegex).forks(1).build()).run();
}
@Setup
public final void setUp() {
Random random = new Random(0);
testCases =
Stream.of(
NodeTestCase.generate(100, 5, 10, 10, random),
NodeTestCase.generate(100, 5, 10, 100, random),
NodeTestCase.generate(100, 5, 10, 1000, random),
NodeTestCase.generate(1000, 10, 20, 10, random),
NodeTestCase.generate(1000, 10, 20, 100, random),
NodeTestCase.generate(1000, 10, 20, 1000, random),
NodeTestCase.generate(1000, 10, 20, 10000, random))
.collect(
flatteningToImmutableListMultimap(
identity(), testCase -> testCase.generateTestCaseEntries(random)));
}
@Benchmark
public final void create(Blackhole bh) {
for (NodeTestCase<Integer> testCase : testCases.keySet()) {
bh.consume(testCase.buildTree());
}
}
@Benchmark
public final void collectReachableValues(Blackhole bh) {
for (Map.Entry<NodeTestCase<Integer>, Collection<NodeTestCaseEntry<Integer>>> e :
testCases.asMap().entrySet()) {
Node<Integer> tree = e.getKey().buildTree();
for (NodeTestCaseEntry<Integer> testCaseEntry : e.getValue()) {
tree.collectReachableValues(testCaseEntry.candidateEdges(), bh::consume);
}
}
}
}

View File

@@ -0,0 +1,47 @@
package tech.picnic.errorprone.refaster.runner;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.params.provider.Arguments.arguments;
import com.google.common.collect.ImmutableSet;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
final class NodeTest {
private static Stream<Arguments> collectReachableValuesTestCases() {
Random random = new Random(0);
return Stream.of(
NodeTestCase.generate(0, 0, 0, 0, random),
NodeTestCase.generate(1, 1, 1, 1, random),
NodeTestCase.generate(2, 2, 2, 10, random),
NodeTestCase.generate(10, 2, 5, 10, random),
NodeTestCase.generate(10, 2, 5, 100, random),
NodeTestCase.generate(100, 5, 10, 100, random),
NodeTestCase.generate(100, 5, 10, 1000, random))
.flatMap(
testCase -> {
Node<Integer> tree = testCase.buildTree();
return testCase
.generateTestCaseEntries(random)
.map(e -> arguments(tree, e.candidateEdges(), e.reachableValues()));
});
}
@MethodSource("collectReachableValuesTestCases")
@ParameterizedTest
void collectReachableValues(
Node<Integer> tree,
ImmutableSet<String> candidateEdges,
Collection<Integer> expectedReachable) {
List<Integer> actualReachable = new ArrayList<>();
tree.collectReachableValues(candidateEdges, actualReachable::add);
assertThat(actualReachable).hasSameElementsAs(expectedReachable);
}
}

View File

@@ -0,0 +1,140 @@
package tech.picnic.errorprone.refaster.runner;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.collect.ImmutableSetMultimap.flatteningToImmutableSetMultimap;
import static java.util.function.Function.identity;
import static java.util.stream.Collectors.collectingAndThen;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Random;
import java.util.stream.Stream;
@AutoValue
abstract class NodeTestCase<V> {
static NodeTestCase<Integer> generate(
int entryCount, int maxPathCount, int maxPathLength, int pathValueDomainSize, Random random) {
return random
.ints(entryCount)
.boxed()
.collect(
collectingAndThen(
flatteningToImmutableSetMultimap(
identity(),
i ->
random
.ints(random.nextInt(maxPathCount + 1))
.mapToObj(
p ->
random
.ints(
random.nextInt(maxPathLength + 1),
0,
pathValueDomainSize)
.mapToObj(String::valueOf)
.collect(toImmutableSet()))),
AutoValue_NodeTestCase::new));
}
abstract ImmutableSetMultimap<V, ImmutableSet<String>> input();
final Node<V> buildTree() {
return Node.create(input().keySet(), input()::get);
}
final Stream<NodeTestCaseEntry<V>> generateTestCaseEntries(Random random) {
return generatePathTestCases(input(), random);
}
private static <V> Stream<NodeTestCaseEntry<V>> generatePathTestCases(
ImmutableSetMultimap<V, ImmutableSet<String>> treeInput, Random random) {
ImmutableSet<String> allEdges =
treeInput.values().stream().flatMap(ImmutableSet::stream).collect(toImmutableSet());
return Stream.concat(
Stream.of(ImmutableSet.<String>of()), shuffle(treeInput.values(), random).stream())
// XXX: Use `random.nextInt(20, 100)` once we no longer target JDK 11. (And consider
// introducing a Refaster template for this case.)
.limit(20 + random.nextInt(80))
.flatMap(edges -> generateVariations(edges, allEdges, "unused", random))
.distinct()
.map(edges -> createTestCaseEntry(treeInput, edges));
}
private static <T> Stream<ImmutableSet<T>> generateVariations(
ImmutableSet<T> baseEdges, ImmutableSet<T> allEdges, T unusedEdge, Random random) {
Optional<T> knownEdge = selectRandomElement(allEdges, random);
return Stream.of(
random.nextBoolean() ? null : baseEdges,
random.nextBoolean() ? null : shuffle(baseEdges, random),
random.nextBoolean() ? null : insertValue(baseEdges, unusedEdge, random),
baseEdges.isEmpty() || random.nextBoolean()
? null
: randomStrictSubset(baseEdges, random),
baseEdges.isEmpty() || random.nextBoolean()
? null
: insertValue(randomStrictSubset(baseEdges, random), unusedEdge, random),
baseEdges.isEmpty() || random.nextBoolean()
? null
: knownEdge
.map(edge -> insertValue(randomStrictSubset(baseEdges, random), edge, random))
.orElse(null))
.filter(Objects::nonNull);
}
private static <T> Optional<T> selectRandomElement(ImmutableSet<T> collection, Random random) {
return collection.isEmpty()
? Optional.empty()
: Optional.of(collection.asList().get(random.nextInt(collection.size())));
}
private static <T> ImmutableSet<T> shuffle(ImmutableCollection<T> values, Random random) {
List<T> allValues = new ArrayList<>(values);
Collections.shuffle(allValues, random);
return ImmutableSet.copyOf(allValues);
}
private static <T> ImmutableSet<T> insertValue(
ImmutableSet<T> values, T extraValue, Random random) {
List<T> allValues = new ArrayList<>(values);
allValues.add(random.nextInt(values.size() + 1), extraValue);
return ImmutableSet.copyOf(allValues);
}
private static <T> ImmutableSet<T> randomStrictSubset(ImmutableSet<T> values, Random random) {
checkArgument(!values.isEmpty(), "Cannot select strict subset of random collection");
List<T> allValues = new ArrayList<>(values);
Collections.shuffle(allValues, random);
return ImmutableSet.copyOf(allValues.subList(0, random.nextInt(allValues.size())));
}
private static <V> NodeTestCaseEntry<V> createTestCaseEntry(
ImmutableSetMultimap<V, ImmutableSet<String>> treeInput, ImmutableSet<String> edges) {
return new AutoValue_NodeTestCase_NodeTestCaseEntry<>(
edges,
treeInput.asMap().entrySet().stream()
.filter(e -> e.getValue().stream().anyMatch(edges::containsAll))
.map(Map.Entry::getKey)
.collect(toImmutableList()));
}
@AutoValue
abstract static class NodeTestCaseEntry<V> {
abstract ImmutableSet<String> candidateEdges();
abstract ImmutableList<V> reachableValues();
}
}

View File

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

View File

@@ -46,7 +46,12 @@ public abstract class AnnotatedCompositeCodeTransformer implements CodeTransform
abstract String packageName();
abstract ImmutableList<CodeTransformer> transformers();
/**
* Return The {@link CodeTransformer}s to which to delegate.
*
* @return The ordered {@link CodeTransformer}s to which to delegate.
*/
public abstract ImmutableList<CodeTransformer> transformers();
@Override
@SuppressWarnings("java:S3038" /* All AutoValue properties must be specified explicitly. */)
@@ -67,6 +72,18 @@ public abstract class AnnotatedCompositeCodeTransformer implements CodeTransform
return new AutoValue_AnnotatedCompositeCodeTransformer(packageName, transformers, annotations);
}
/**
* Returns a new {@link AnnotatedCompositeCodeTransformer} similar to this one, but with the
* specified transformers.
*
* @param transformers The replacement transformers.
* @return A derivative {@link AnnotatedCompositeCodeTransformer}.
*/
public AnnotatedCompositeCodeTransformer withTransformers(CodeTransformer... transformers) {
return new AutoValue_AnnotatedCompositeCodeTransformer(
packageName(), ImmutableList.copyOf(transformers), annotations());
}
@Override
public final void apply(TreePath path, Context context, DescriptionListener listener) {
for (CodeTransformer transformer : transformers()) {

View File

@@ -118,11 +118,12 @@ public final class IsEmpty implements Matcher<ExpressionTree> {
}
private boolean isEmptyCollectionConstructor(ExpressionTree tree, VisitorState state) {
if (!(tree instanceof NewClassTree) || !MUTABLE_COLLECTION_TYPE.matches(tree, state)) {
if (!(tree instanceof NewClassTree newClassTree)
|| !MUTABLE_COLLECTION_TYPE.matches(tree, state)) {
return false;
}
List<? extends ExpressionTree> arguments = ((NewClassTree) tree).getArguments();
List<? extends ExpressionTree> arguments = newClassTree.getArguments();
if (arguments.stream().allMatch(a -> EMPTY_COLLECTION_CONSTRUCTOR_ARGUMENT.matches(a, state))) {
/*
* This is a default constructor, or a constructor that creates an empty collection using

View File

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

View File

@@ -6,6 +6,7 @@ import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.collect.ImmutableSortedSet.toImmutableSortedSet;
import static com.google.errorprone.BugPattern.LinkType.NONE;
import static com.google.errorprone.BugPattern.SeverityLevel.ERROR;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Comparator.naturalOrder;
import static tech.picnic.errorprone.refaster.runner.Refaster.INCLUDED_RULES_PATTERN_FLAG;
@@ -17,6 +18,7 @@ import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Range;
import com.google.common.collect.Sets;
import com.google.common.io.Resources;
import com.google.errorprone.BugCheckerRefactoringTestHelper;
import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;
import com.google.errorprone.BugPattern;
@@ -38,6 +40,9 @@ import com.sun.source.util.TreeScanner;
import com.sun.tools.javac.tree.EndPosTable;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.util.Position;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -124,13 +129,15 @@ public final class RefasterRuleCollection extends BugChecker implements Compilat
*/
public static void validate(Class<?> clazz) {
String className = clazz.getSimpleName();
String inputResource = className + "TestInput.java";
String outputResource = className + "TestOutput.java";
BugCheckerRefactoringTestHelper.newInstance(RefasterRuleCollection.class, clazz)
.setArgs(
"--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
"-XepOpt:" + RULE_COLLECTION_FLAG + '=' + className)
.addInput(className + "TestInput.java")
.addOutput(className + "TestOutput.java")
.addInputLines(inputResource, loadResource(clazz, inputResource))
.addOutputLines(outputResource, loadResource(clazz, outputResource))
.doTest(TestMode.TEXT_MATCH);
}
@@ -247,6 +254,15 @@ public final class RefasterRuleCollection extends BugChecker implements Compilat
return value.substring(index + 1);
}
private static String loadResource(Class<?> contextClass, String resource) {
URL url = Resources.getResource(contextClass, resource);
try {
return Resources.toString(url, UTF_8);
} catch (IOException e) {
throw new UncheckedIOException("Cannot find resource: " + url, e);
}
}
private class UnexpectedMatchReporter extends TreeScanner<@Nullable Void, VisitorState> {
private final ImmutableRangeMap<Integer, String> indexedMatches;

View File

@@ -0,0 +1,31 @@
package tech.picnic.errorprone.refaster.test;
import static java.util.Collections.singletonMap;
import com.google.common.collect.ImmutableMap;
import com.google.errorprone.refaster.Refaster;
import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.Map;
/** Refaster rule collection to validate the reporting of missing test methods. */
final class NestedRefasterAnyOfRules {
private NestedRefasterAnyOfRules() {}
static final class NestedRefasterAnyOf<K, V> {
@BeforeTemplate
@SuppressWarnings({"ImmutableMapOf1", "MapEntry"} /* Similar rules for testing purposes. */)
Map<K, V> before(K k1, V v1) {
return Refaster.anyOf(
ImmutableMap.ofEntries(
Refaster.anyOf(Map.entry(k1, v1), new SimpleImmutableEntry<>(k1, v1))),
singletonMap(k1, v1));
}
@AfterTemplate
ImmutableMap<K, V> after(K k1, V v1) {
return ImmutableMap.of(k1, v1);
}
}
}

View File

@@ -21,8 +21,10 @@ final class RefasterRuleCollectionTest {
MethodWithoutPrefixRules.class,
MisnamedTestClassRules.class,
MissingTestAndWrongTestRules.class,
NestedRefasterAnyOfRules.class,
PartialTestMatchRules.class,
RuleWithoutTestRules.class,
SingleRefasterAnyOfRules.class,
ValidRules.class
})
void verifyRefasterRuleCollections(Class<?> clazz) {

View File

@@ -0,0 +1,27 @@
package tech.picnic.errorprone.refaster.test;
import static java.util.Collections.singletonMap;
import com.google.common.collect.ImmutableMap;
import com.google.errorprone.refaster.Refaster;
import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import java.util.Map;
/** Refaster rule collection to validate the reporting of missing test methods. */
final class SingleRefasterAnyOfRules {
private SingleRefasterAnyOfRules() {}
static final class SingleRefasterAnyOf<K, V> {
@BeforeTemplate
@SuppressWarnings("ImmutableMapOf1" /* Similar rule for testing purposes. */)
Map<K, V> before(K k1, V v1) {
return Refaster.anyOf(ImmutableMap.ofEntries(Map.entry(k1, v1)), singletonMap(k1, v1));
}
@AfterTemplate
ImmutableMap<K, V> after(K k1, V v1) {
return ImmutableMap.of(k1, v1);
}
}
}

View File

@@ -0,0 +1,12 @@
package tech.picnic.errorprone.refaster.test;
import com.google.common.collect.ImmutableMap;
import java.util.Map;
/** Code to test the Refaster rules from {@link NestedRefasterAnyOfRules}. */
final class NestedRefasterAnyOfRulesTest implements RefasterRuleCollectionTestCase {
Map<?, ?> testNestedRefasterAnyOf() {
Map<String, String> stringStringMap = Map.of("1", "2");
return ImmutableMap.ofEntries(Map.entry("k1", "v1"));
}
}

View File

@@ -0,0 +1,12 @@
package tech.picnic.errorprone.refaster.test;
import com.google.common.collect.ImmutableMap;
import java.util.Map;
/** Code to test the Refaster rules from {@link NestedRefasterAnyOfRules}. */
final class NestedRefasterAnyOfRulesTest implements RefasterRuleCollectionTestCase {
Map<?, ?> testNestedRefasterAnyOf() {
Map<String, String> stringStringMap = Map.of("1", "2");
return ImmutableMap.of("k1", "v1");
}
}

View File

@@ -0,0 +1,17 @@
package tech.picnic.errorprone.refaster.test;
import com.google.common.collect.ImmutableSet;
import java.util.Collections;
import java.util.Map;
/** Code to test the Refaster rules from {@link SingleRefasterAnyOfRules}. */
final class SingleRefasterAnyOfRulesTest implements RefasterRuleCollectionTestCase {
@Override
public ImmutableSet<Object> elidedTypesAndStaticImports() {
return ImmutableSet.of(Collections.class);
}
Map<?, ?> testSingleRefasterAnyOf() {
return Collections.singletonMap("k1", "v1");
}
}

View File

@@ -0,0 +1,18 @@
package tech.picnic.errorprone.refaster.test;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import java.util.Collections;
import java.util.Map;
/** Code to test the Refaster rules from {@link SingleRefasterAnyOfRules}. */
final class SingleRefasterAnyOfRulesTest implements RefasterRuleCollectionTestCase {
@Override
public ImmutableSet<Object> elidedTypesAndStaticImports() {
return ImmutableSet.of(Collections.class);
}
Map<?, ?> testSingleRefasterAnyOf() {
return ImmutableMap.of("k1", "v1");
}
}

View File

@@ -1,6 +1,9 @@
# 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.21.0
compatible:
- "2.37.0"
- version: 0.20.0
compatible:
- "2.36.0"