Compare commits

...

105 Commits

Author SHA1 Message Date
Benedek Halasi
92071c854c Merge fixes of inner type decls, enable sorting nested types in one-go 2025-03-26 06:47:22 +01:00
Rick Ossendrijver
06028a0729 Pair programming 2025-03-26 06:47:21 +01:00
Rick Ossendrijver
1112cef15c Cleanup 2025-03-26 06:47:21 +01:00
Benedek Halasi
7eb5479f98 Fix & enable TypeMemberOrderEnumTest 2025-03-26 06:47:21 +01:00
Benedek Halasi
8d3fd072d3 Move TypeMemberOrder BugChecker into experimental module 2025-03-26 06:47:21 +01:00
Rick Ossendrijver
0ccea3c3c2 Final suggestions, but three failing tests 2025-03-26 06:47:21 +01:00
Rick Ossendrijver
d9607bde04 Try to implement new thing 2025-03-26 06:47:21 +01:00
Rick Ossendrijver
6b766891d2 Suggestions part 1 2025-03-26 06:47:21 +01:00
Rick Ossendrijver
a2c92b54dd Suggestions 2025-03-26 06:47:20 +01:00
Benedek Halasi
8c4b8c27d2 Fix syntactically wrong replecement with annotations containing LBRACE 2025-03-26 06:47:20 +01:00
Benedek Halasi
bdb37a553d Reproduce syntactically wrong replacement with annotations containing LBRACE 2025-03-26 06:47:20 +01:00
Rick Ossendrijver
56f58a45b4 Improve more tests 2025-03-26 06:47:20 +01:00
Rick Ossendrijver
bf98ce2f28 Suggestions 2025-03-26 06:47:20 +01:00
Benedek Halasi
6bd1f577ce Tweaks 2025-03-26 06:47:20 +01:00
Benedek Halasi
cd0a54c486 Test abstract and default methods 2025-03-26 06:47:20 +01:00
Rick Ossendrijver
4f139830ef Pair programming session 2025-03-26 06:47:20 +01:00
Rick Ossendrijver
173b43b0ad Post rebase fix 2025-03-26 06:47:19 +01:00
Benedek Halasi
7ec43faf6a Support classes, interfaces and enums 2025-03-26 06:47:19 +01:00
Benedek Halasi
46490b83fc Rename TypeMemberWithComments to TypeMember 2025-03-26 06:47:19 +01:00
Benedek Halasi
01c04007d4 Stop sorting unsorted members annotated w/ SuppressWarnings - all or TypeMemberOrdering 2025-03-26 06:47:19 +01:00
Benedek Halasi
4b9de605e7 Test not-ordering unordered members annotated w/ SuppressWarnings 2025-03-26 06:47:19 +01:00
Benedek Halasi
4ba51ac275 Implement inner type ordering 2025-03-26 06:47:19 +01:00
Benedek Halasi
58d21a5ea5 Test inner type ordering 2025-03-26 06:47:19 +01:00
Benedek Halasi
92181f3320 Implement initializer block ordering 2025-03-26 06:47:18 +01:00
Benedek Halasi
9b7e5a2da7 Test initializer block ordering 2025-03-26 06:47:18 +01:00
Benedek Halasi
9476e78fec Suggestions 2025-03-26 06:47:18 +01:00
Benedek Halasi
0eb4c8d93b Verify that SupressWarnings("all" or "TypeMemberOrdering") are not ordered 2025-03-26 06:47:18 +01:00
Benedek Halasi
1652a24bd2 Add identification test for an empty class, sync identifaction test w/ new error message 2025-03-26 06:47:18 +01:00
Benedek Halasi
69fe9bea95 Rename *class* to *type* 2025-03-26 06:47:18 +01:00
Benedek Halasi
778e2439ae List all remarks as TODOs, or address them 2025-03-26 06:47:18 +01:00
Stephan Schroevers
38adfa0507 Suggestions 2025-03-26 06:47:17 +01:00
Benedek Halasi
5a7995a598 Reproduce error-prone token start - end position overlap 2025-03-26 06:47:17 +01:00
Benedek Halasi
9a9a86cb60 Suggestions on naming, minor organizational changes, rewordings 2025-03-26 06:47:17 +01:00
Benedek Halasi
d7fc940a99 Assume that only generated members' end position is unavailable. 2025-03-26 06:47:17 +01:00
Benedek Halasi
a4dd402172 "Fix" previous token detection 2025-03-26 06:47:17 +01:00
Benedek Halasi
32bd39a4c3 Simplifing logic, killing mutants 2025-03-26 06:47:17 +01:00
Gijs de Jong
4453d9f122 Remove stray unused import 2025-03-26 06:47:17 +01:00
Gijs de Jong
253a35fc93 suggestions 2025-03-26 06:47:16 +01:00
Benedek Halasi
b531cd3fc9 Checkstyle 2025-03-26 06:47:16 +01:00
Benedek Halasi
dec75a841e Suggestions 2025-03-26 06:47:16 +01:00
Rick Ossendrijver
91f11dea71 Revert "Drop replaceIncludingComments"
This reverts commit 133c85da4f86a3d3965384acf4cdc24b3f50677b.
2025-03-26 06:47:16 +01:00
Rick Ossendrijver
01a31c6585 Drop replaceIncludingComments 2025-03-26 06:47:16 +01:00
Rick Ossendrijver
bd08fd30e1 Suggestions 2025-03-26 06:47:16 +01:00
Benedek Halasi
c8b7c7cdbf Apply my suggestions
- phrasing: last , -> and
- Reasonably concise `COMPARATOR` and its docs
2025-03-26 06:47:16 +01:00
Benedek Halasi
305cedd02f Cannot verify whitespace related requirements as TestMode.TEXT_MATCH formats the sources 2025-03-26 06:47:16 +01:00
Benedek Halasi
1bb8b85421 Code clean-up, formatting, docs, TEMPORARY supress warnings 2025-03-26 06:47:15 +01:00
Benedek Halasi
78cf52beff Test if error message contains crucial information 2025-03-26 06:47:15 +01:00
Benedek Halasi
f61539d266 Prepare the code for others to see
- kinda cleanup `replaceIncludingComments` copy
 - mark unsure parts of the code
 - list remaining tasks
2025-03-26 06:47:15 +01:00
Benedek Halasi
1a6f6ec04c Consider comments 2025-03-26 06:47:15 +01:00
Benedek Halasi
f8d6ae147b Naive impl 2025-03-26 06:47:15 +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
40 changed files with 1707 additions and 505 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

@@ -55,7 +55,7 @@ jobs:
run: xvfb-run "./integration-tests/${{ matrix.integration-test }}.sh" "${{ runner.temp }}/artifacts"
- name: Upload artifacts on failure
if: ${{ failure() }}
uses: actions/upload-artifact@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>
@@ -45,6 +45,11 @@
<artifactId>error_prone_test_helpers</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.auto.value</groupId>
<artifactId>auto-value-annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
@@ -68,4 +73,16 @@
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,296 @@
package tech.picnic.errorprone.experimental.bugpatterns;
import static com.google.errorprone.BugPattern.LinkType.CUSTOM;
import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
import static com.google.errorprone.BugPattern.StandardTags.STYLE;
import static com.sun.tools.javac.code.Flags.ENUM;
import static java.util.Objects.requireNonNull;
import static tech.picnic.errorprone.utils.Documentation.BUG_PATTERNS_BASE_URL;
import com.google.auto.service.AutoService;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Streams;
import com.google.errorprone.BugPattern;
import com.google.errorprone.VisitorState;
import com.google.errorprone.annotations.Var;
import com.google.errorprone.bugpatterns.BugChecker;
import com.google.errorprone.bugpatterns.BugChecker.CompilationUnitTreeMatcher;
import com.google.errorprone.fixes.Replacement;
import com.google.errorprone.fixes.SuggestedFix;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.util.ASTHelpers;
import com.google.errorprone.util.ErrorProneToken;
import com.google.errorprone.util.ErrorProneTokens;
import com.sun.source.tree.BlockTree;
import com.sun.source.tree.ClassTree;
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.MethodTree;
import com.sun.source.tree.Tree;
import com.sun.source.tree.Tree.Kind;
import com.sun.source.tree.VariableTree;
import com.sun.tools.javac.parser.Tokens.TokenKind;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.util.Position;
import java.util.Optional;
import java.util.Set;
import javax.lang.model.element.Modifier;
/**
* A {@link BugChecker} that flags classes with a non-canonical member order.
*
* <p>Class members should be ordered as follows:
*
* <ol>
* <li>Static fields
* <li>Instance fields
* <li>Static initializer blocks
* <li>Instance initializer blocks
* <li>Constructors
* <li>Methods
* <li>Nested classes, interfaces and enums
* </ol>
*
* @see <a
* href="https://checkstyle.sourceforge.io/apidocs/com/puppycrawl/tools/checkstyle/checks/coding/DeclarationOrderCheck.html">Checkstyle's
* {@code DeclarationOrderCheck}</a>
*/
// XXX: Consider introducing support for ordering members in records or annotation definitions.
// XXX: Exclude checkstyle from running against (this checker's) test files.
@AutoService(BugChecker.class)
@BugPattern(
summary = "Type members should be defined in a canonical order",
link = BUG_PATTERNS_BASE_URL + "TypeMemberOrder",
linkType = CUSTOM,
severity = WARNING,
tags = STYLE)
public final class TypeMemberOrder extends BugChecker implements CompilationUnitTreeMatcher {
private static final long serialVersionUID = 1L;
/** Instantiates a new {@link TypeMemberOrder} instance. */
public TypeMemberOrder() {}
@Override
public Description matchCompilationUnit(
CompilationUnitTree compilationUnitTree, VisitorState state) {
SuggestedFix.Builder suggestedFixes = SuggestedFix.builder();
for (Tree tree : compilationUnitTree.getTypeDecls()) {
if (!isSuppressed(tree, state) && tree instanceof ClassTree classTree) {
suggestedFixes.merge(
matchClass(classTree, state, (JCTree.JCCompilationUnit) compilationUnitTree));
}
}
SuggestedFix suggestedFix = suggestedFixes.build();
if (suggestedFix.isEmpty()) {
return Description.NO_MATCH;
}
return describeMatch(compilationUnitTree, suggestedFix);
}
private SuggestedFix matchClass(
ClassTree tree, VisitorState state, JCTree.JCCompilationUnit compilationUnit) {
Kind treeKind = tree.getKind();
if (treeKind != Kind.CLASS && treeKind != Kind.INTERFACE && treeKind != Kind.ENUM) {
return SuggestedFix.emptyFix();
}
int bodyStartPos = getBodyStartPos(tree, state);
if (bodyStartPos == Position.NOPOS) {
/*
* We can't determine the type body's start position in the source code. This generally means
* that (part of) its code was generated. Even if the source code for a subset of its members
* is available, dealing with this edge case is not worth the trouble.
*/
return SuggestedFix.emptyFix();
}
ImmutableList<TypeMember> members = getAllTypeMembers(tree, bodyStartPos, state);
boolean topLevelSorted = members.equals(ImmutableList.sortedCopyOf(members));
if (topLevelSorted) {
SuggestedFix.Builder nestedSuggestedFixes = SuggestedFix.builder();
for (TypeMember member : members) {
if (member.tree() instanceof ClassTree memberClassTree) {
SuggestedFix other = matchClass(memberClassTree, state, compilationUnit);
nestedSuggestedFixes.merge(other);
}
}
return nestedSuggestedFixes.build();
}
CharSequence source = requireNonNull(state.getSourceCode(), "Source code");
ImmutableMap.Builder<TypeMember, String> typeMemberSource = ImmutableMap.builder();
for (TypeMember member : members) {
if (member.tree() instanceof ClassTree memberClassTree) {
SuggestedFix suggestedFix = matchClass(memberClassTree, state, compilationUnit);
@Var
String memberSource =
source.subSequence(member.startPosition(), member.endPosition()).toString();
// Diff between memberSource and replacement positions.
@Var int diff = -member.startPosition();
for (Replacement replacement : suggestedFix.getReplacements(compilationUnit.endPositions)) {
memberSource =
memberSource.subSequence(0, replacement.startPosition() + diff)
+ replacement.replaceWith()
+ memberSource.subSequence(
replacement.endPosition() + diff, memberSource.length());
diff +=
replacement.replaceWith().length()
- (replacement.endPosition() - replacement.startPosition());
}
typeMemberSource.put(member, memberSource);
} else {
typeMemberSource.put(
member, source.subSequence(member.startPosition(), member.endPosition()).toString());
}
}
return sortTypeMembers(members, typeMemberSource.build());
}
/** Returns all members that can be moved or may lay between movable ones. */
private ImmutableList<TypeMember> getAllTypeMembers(
ClassTree tree, int bodyStartPos, VisitorState state) {
ImmutableList.Builder<TypeMember> builder = ImmutableList.builder();
@Var int currentStartPos = bodyStartPos;
for (Tree member : tree.getMembers()) {
if (state.getEndPosition(member) == Position.NOPOS) {
continue;
}
int treeStartPos = currentStartPos;
getMemberTypeOrdinal(member, state)
.ifPresent(
e ->
builder.add(
new AutoValue_TypeMemberOrder_TypeMember(
member, treeStartPos, state.getEndPosition(member), e)));
/* XXX: Write explanation about this enum. */
currentStartPos = Math.max(currentStartPos, state.getEndPosition(member));
}
return builder.build();
}
/**
* Returns the preferred ordinal of the given member, or empty if it's unmovable for any reason,
* including it lacking a preferred ordinal.
*/
private Optional<Integer> getMemberTypeOrdinal(Tree tree, VisitorState state) {
if (isSuppressed(tree, state) || isEnumeratorDefinition(tree)) {
return Optional.empty();
}
return switch (tree.getKind()) {
case VARIABLE -> Optional.of(isStatic((VariableTree) tree) ? 1 : 2);
case BLOCK -> Optional.of(isStatic((BlockTree) tree) ? 3 : 4);
case METHOD -> Optional.of(isConstructor((MethodTree) tree) ? 5 : 6);
case CLASS, INTERFACE, ENUM -> Optional.of(7);
default -> Optional.empty();
};
}
/**
* Returns the start position of the body of the given type, in the case of enums, it returns the
* position that follows the enumerated type's enumerations.
*/
private static int getBodyStartPos(ClassTree tree, VisitorState state) {
CharSequence sourceCode = state.getSourceCode();
/*
* To avoid including the type's preceding annotations, use `getPreferredPosition()` rather than
* `ASTHelpers`.
*/
int typeStart = ((JCTree.JCClassDecl) tree).getPreferredPosition();
int typeEnd = state.getEndPosition(tree);
if (sourceCode == null || typeStart == Position.NOPOS || typeEnd == Position.NOPOS) {
return Position.NOPOS;
}
/*
* Returns the source code position of the first token that comes after the first curly left
* bracket.
*/
return ErrorProneTokens.getTokens(
sourceCode.subSequence(typeStart, typeEnd).toString(), typeStart, state.context)
.stream()
.dropWhile(token -> token.kind() != TokenKind.LBRACE)
/*
* To accommodate enums, skip processing their enumerators. This is needed as Error Prone
* has access to the enumerations individually, but not to the whole expression that
* declares them, leaving the semicolon trailing the declarations unaccounted for. The
* current logic would move this trailing semicolon with the first member after the
* enumerations instead of leaving it to close the enumerations' declaration, introducing a
* syntax error.
*/
.dropWhile(token -> tree.getKind() == Kind.ENUM && token.kind() != TokenKind.SEMI)
.findFirst()
.map(ErrorProneToken::endPos)
.orElse(Position.NOPOS);
}
/**
* Returns true if {@link Tree} is an enum or an enumerator definition, false otherwise.
*
* @see com.sun.tools.javac.code.Flags#ENUM
*/
private static boolean isEnumeratorDefinition(Tree tree) {
return tree instanceof JCVariableDecl variableDecl && (variableDecl.mods.flags & ENUM) != 0;
}
/**
* Suggests a different way of ordering the given type members.
*
* @implNote For each member, this method tracks the source code between the end of the definition
* of the member that precedes it (or the start of the type body if there is no such member)
* and the end of the definition of the member itself. This subsequently enables moving
* members around, including any preceding comments and Javadoc. This approach isn't perfect,
* and may at times move too much code or documentation around; users will have to manually
* resolve this.
*/
private static SuggestedFix sortTypeMembers(
ImmutableList<TypeMember> members, ImmutableMap<TypeMember, String> sourceCode) {
return Streams.zip(
members.stream(),
members.stream().sorted(),
(original, replacement) -> {
String replacementSource = requireNonNull(sourceCode.get(replacement), "replacement");
return original.equals(replacement)
? SuggestedFix.emptyFix()
: SuggestedFix.replace(
original.startPosition(), original.endPosition(), replacementSource);
})
.reduce(SuggestedFix.builder(), SuggestedFix.Builder::merge, SuggestedFix.Builder::merge)
.build();
}
private static boolean isStatic(VariableTree variableTree) {
Set<Modifier> modifiers = variableTree.getModifiers().getFlags();
return modifiers.contains(Modifier.STATIC);
}
private static boolean isStatic(BlockTree blockTree) {
return blockTree.isStatic();
}
private static boolean isConstructor(MethodTree methodTree) {
return ASTHelpers.getSymbol(methodTree).isConstructor();
}
@AutoValue
abstract static class TypeMember implements Comparable<TypeMember> {
abstract Tree tree();
abstract int startPosition();
abstract int endPosition();
abstract int preferredOrdinal();
@Override
public int compareTo(TypeMemberOrder.TypeMember o) {
return Integer.compare(preferredOrdinal(), o.preferredOrdinal());
}
}
}

View File

@@ -0,0 +1,428 @@
package tech.picnic.errorprone.experimental.bugpatterns;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.errorprone.BugCheckerRefactoringTestHelper;
import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;
import com.google.errorprone.CompilationTestHelper;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import org.junit.jupiter.api.Test;
final class TypeMemberOrderClassTest {
@Test
void identification() {
CompilationTestHelper.newInstance(TypeMemberOrder.class, getClass())
.addSourceLines(
"A.java",
"// BUG: Diagnostic contains:",
"class A {",
" class InnerClass {}",
"",
" interface InnerInterface {}",
"",
" enum InnerEnum {}",
"",
" int foo() {",
" return foo;",
" }",
"",
" A() {}",
"",
" {",
" System.out.println(\"bar\");",
" }",
"",
" static {",
" System.out.println(\"foo\");",
" }",
"",
" private final int bar = 2;",
" private static final int foo = 1;",
"}")
.addSourceLines(
"B.java",
"class B {",
" private static final int foo = 1;",
" private final int bar = 2;",
"",
" static {",
" System.out.println(\"foo\");",
" }",
"",
" {",
" System.out.println(\"bar\");",
" }",
"",
" B() {}",
"",
" int foo() {",
" return foo;",
" }",
"",
" class InnerClass {}",
"",
" interface InnerInterface {}",
"",
" enum InnerEnum {}",
"}")
.addSourceLines(
"C.java",
"class C {",
" @SuppressWarnings({\"foo\", \"all\", \"bar\"})",
" void unorderedMethod() {}",
"",
" C() {}",
"}")
.addSourceLines(
"D.java",
"class D {",
" @SuppressWarnings(\"TypeMemberOrder\")",
" void unorderedMethod() {}",
"",
" D() {}",
"}")
.addSourceLines(
"E.java",
"@SuppressWarnings(\"TypeMemberOrder\")",
"class E {",
" void unorderedMethod() {}",
"",
" E() {}",
"}")
.addSourceLines("F.java", "class F {}")
.doTest();
}
@Test
void replacement() {
BugCheckerRefactoringTestHelper.newInstance(TypeMemberOrder.class, getClass())
.addInputLines(
"A.java",
"class A {",
" class Inner {",
" int innerFoo() {",
" return 1;",
" }",
"",
" private final int innerBar = 2;",
" }",
"",
" int foo() {",
" return foo;",
" }",
"",
" A() {}",
"",
" {",
" System.out.println(\"bar\");",
" }",
"",
" static {",
" System.out.println(\"foo\");",
" }",
"",
" private final int bar = 2;",
" private static final int foo = 1;",
"}")
.addOutputLines(
"A.java",
"class A {",
" private static final int foo = 1;",
"",
" private final int bar = 2;",
"",
" static {",
" System.out.println(\"foo\");",
" }",
"",
" {",
" System.out.println(\"bar\");",
" }",
"",
" A() {}",
"",
" int foo() {",
" return foo;",
" }",
"",
" class Inner {",
"",
" private final int innerBar = 2;",
"",
" int innerFoo() {",
" return 1;",
" }",
" }",
"}")
.doTest(TestMode.TEXT_MATCH);
}
@Test
void replacementNestedClasses() {
BugCheckerRefactoringTestHelper.newInstance(TypeMemberOrder.class, getClass())
.addInputLines(
"A.java",
// XXX: Use dedicated helper method to read test files here and below.
new BufferedReader(
new InputStreamReader(
this.getClass()
.getClassLoader()
.getResourceAsStream(
"TypeMemberOrderNestedCompilationUnitTestInput.java"),
UTF_8))
.lines()
.toArray(String[]::new))
.addOutputLines(
"A.java",
new BufferedReader(
new InputStreamReader(
this.getClass()
.getClassLoader()
.getResourceAsStream(
"TypeMemberOrderNestedCompilationUnitTestOutput.java"),
UTF_8))
.lines()
.toArray(String[]::new))
.doTest(TestMode.TEXT_MATCH);
}
@Test
void replacementAbstractMethods() {
BugCheckerRefactoringTestHelper.newInstance(TypeMemberOrder.class, getClass())
.addInputLines(
"A.java",
"abstract class A {",
" static class InnerClass {}",
"",
" void foo() {}",
"",
" abstract void bar();",
"",
" void baz() {}",
"",
" A() {}",
"}")
.addOutputLines(
"A.java",
"abstract class A {",
"",
" A() {}",
"",
" void foo() {}",
"",
" abstract void bar();",
"",
" void baz() {}",
"",
" static class InnerClass {}",
"}")
.doTest(TestMode.TEXT_MATCH);
}
@Test
void replacementUnmovableMembers() {
BugCheckerRefactoringTestHelper.newInstance(TypeMemberOrder.class, getClass())
.addInputLines(
"A.java",
"class A {",
" @SuppressWarnings(\"TypeMemberOrder\")",
" int foo() {",
" return foo;",
" }",
"",
" {",
" System.out.println(\"bar\");",
" }",
"",
" static {",
" System.out.println(\"foo\");",
" }",
"",
" private final int bar = 2;",
"",
" @SuppressWarnings(\"TypeMemberOrder\")",
" private static final int foo = 1;",
"}")
.addOutputLines(
"A.java",
"class A {",
" @SuppressWarnings(\"TypeMemberOrder\")",
" int foo() {",
" return foo;",
" }",
"",
" private final int bar = 2;",
"",
" static {",
" System.out.println(\"foo\");",
" }",
"",
" {",
" System.out.println(\"bar\");",
" }",
"",
" @SuppressWarnings(\"TypeMemberOrder\")",
" private static final int foo = 1;",
"}")
.doTest(TestMode.TEXT_MATCH);
}
@Test
void replacementHandlesGeneratedDefaultConstructor() {
BugCheckerRefactoringTestHelper.newInstance(TypeMemberOrder.class, getClass())
.addInputLines(
"A.java",
"class A {",
" int foo() {",
" return foo;",
" }",
"",
" {",
" System.out.println(\"bar\");",
" }",
"",
" static {",
" System.out.println(\"foo\");",
" }",
"",
" private final int bar = 2;",
" private static final int foo = 1;",
"}")
.addOutputLines(
"A.java",
"class A {",
" private static final int foo = 1;",
"",
" private final int bar = 2;",
"",
" static {",
" System.out.println(\"foo\");",
" }",
"",
" {",
" System.out.println(\"bar\");",
" }",
"",
" int foo() {",
" return foo;",
" }",
"}")
.doTest(TestMode.TEXT_MATCH);
}
@Test
void replacementDanglingComments() {
BugCheckerRefactoringTestHelper.newInstance(TypeMemberOrder.class, getClass())
.addInputLines(
"A.java",
"class A {",
" /* empty statement's dangling comment */",
" ;",
" /**",
" * Multiline JavaDoc",
" *",
" * <p>`foo` method's comment",
" */",
" int foo() {",
" return foo;",
" }",
"",
" // initializer block's comment",
" {",
" System.out.println(\"bar\");",
" }",
"",
" // static initializer block's comment",
" static {",
" System.out.println(\"foo\");",
" }",
"",
" /* `bar` field's dangling comment */",
"",
" private final int bar = 2;",
" // `foo` field's comment",
" private static final int foo = 1;",
" // trailing comment",
"}")
.addOutputLines(
"A.java",
"class A {",
" // `foo` field's comment",
" private static final int foo = 1;",
"",
" /* `bar` field's dangling comment */",
"",
" private final int bar = 2;",
"",
" // static initializer block's comment",
" static {",
" System.out.println(\"foo\");",
" }",
"",
" // initializer block's comment",
" {",
" System.out.println(\"bar\");",
" }",
" /* empty statement's dangling comment */",
" ;",
"",
" /**",
" * Multiline JavaDoc",
" *",
" * <p>`foo` method's comment",
" */",
" int foo() {",
" return foo;",
" }",
" // trailing comment",
"}")
.doTest(TestMode.TEXT_MATCH);
}
@Test
void replacementComplexAnnotation() {
BugCheckerRefactoringTestHelper.newInstance(TypeMemberOrder.class, getClass())
.addInputLines(
"A.java",
"class A {",
"",
" @interface AnnotationWithClassReferences {",
" Class<?>[] value() default {};",
" }",
"",
" @AnnotationWithClassReferences({Object.class})",
" class InnerClassOneValue {",
" String bar;",
" private static final int foo = 1;",
" }",
"",
" @AnnotationWithClassReferences(value = {Integer.class, String.class})",
" class InnerClassTwoValues {",
" String bar;",
" private static final int foo = 1;",
" }",
"}")
.addOutputLines(
"A.java",
"class A {",
"",
" @interface AnnotationWithClassReferences {",
" Class<?>[] value() default {};",
" }",
"",
" @AnnotationWithClassReferences({Object.class})",
" class InnerClassOneValue {",
" private static final int foo = 1;",
" String bar;",
" }",
"",
" @AnnotationWithClassReferences(value = {Integer.class, String.class})",
" class InnerClassTwoValues {",
" private static final int foo = 1;",
" String bar;",
" }",
"}")
.doTest(TestMode.TEXT_MATCH);
}
}

View File

@@ -0,0 +1,309 @@
package tech.picnic.errorprone.experimental.bugpatterns;
import com.google.errorprone.BugCheckerRefactoringTestHelper;
import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;
import com.google.errorprone.CompilationTestHelper;
import org.junit.jupiter.api.Test;
final class TypeMemberOrderEnumTest {
@Test
void identification() {
CompilationTestHelper.newInstance(TypeMemberOrder.class, getClass())
.addSourceLines(
"A.java",
"// BUG: Diagnostic contains:",
"enum A {",
" FOO;",
"",
" class InnerClass {}",
"",
" interface InnerInterface {}",
"",
" enum InnerEnum {}",
"",
" void qux() {}",
"",
" A() {}",
"",
" {",
" System.out.println(\"bar\");",
" }",
"",
" static {",
" System.out.println(\"foo\");",
" }",
"",
" final int baz = 2;",
" static final int BAR = 1;",
"}")
.addSourceLines(
"B.java",
"enum B {",
" FOO;",
" static final int BAR = 1;",
" final int baz = 2;",
"",
" static {",
" System.out.println(\"foo\");",
" }",
"",
" {",
" System.out.println(\"bar\");",
" }",
"",
" B() {}",
"",
" void qux() {}",
"",
" class InnerClass {}",
"",
" interface InnerInterface {}",
"",
" enum InnerEnum {}",
"}")
.addSourceLines(
"C.java",
"enum C {",
" FOO;",
"",
" @SuppressWarnings({\"foo\", \"all\", \"bar\"})",
" void bar() {}",
"",
" C() {}",
"}")
.addSourceLines(
"D.java",
"enum D {",
" FOO;",
"",
" @SuppressWarnings({\"TypeMemberOrder\"})",
" void bar() {}",
"",
" D() {}",
"}")
.addSourceLines("E.java", "enum E {}")
.doTest();
}
@Test
void replacement() {
BugCheckerRefactoringTestHelper.newInstance(TypeMemberOrder.class, getClass())
.addInputLines(
"A.java",
"enum A {",
" FOO,",
" BAR;",
"",
" class InnerClass {}",
"",
" interface InnerInterface {}",
"",
" enum InnerEnum {}",
"",
" void qux() {}",
"",
" A() {}",
"",
" {",
" System.out.println(\"bar\");",
" }",
"",
" static {",
" System.out.println(\"foo\");",
" }",
"",
" final int baz = 2;",
" static final int BAZ = 1;",
"}")
.addOutputLines(
"A.java",
"enum A {",
" FOO,",
" BAR;",
" static final int BAZ = 1;",
"",
" final int baz = 2;",
"",
" static {",
" System.out.println(\"foo\");",
" }",
"",
" {",
" System.out.println(\"bar\");",
" }",
"",
" A() {}",
"",
" void qux() {}",
"",
" class InnerClass {}",
"",
" interface InnerInterface {}",
"",
" enum InnerEnum {}",
"}")
.doTest(TestMode.TEXT_MATCH);
}
@Test
void replacementUnmovableMembers() {
BugCheckerRefactoringTestHelper.newInstance(TypeMemberOrder.class, getClass())
.addInputLines(
"A.java",
"enum A {",
" FOO;",
"",
" @SuppressWarnings(\"TypeMemberOrder\")",
" class InnerClass {}",
"",
" interface InnerInterface {}",
"",
" enum InnerEnum {}",
"",
" void qux() {}",
"",
" A() {}",
"",
" {",
" System.out.println(\"bar\");",
" }",
"",
" static {",
" System.out.println(\"foo\");",
" }",
"",
" @SuppressWarnings(\"TypeMemberOrder\")",
" final int baz = 2;",
"",
" static final int BAR = 1;",
"}")
.addOutputLines(
"A.java",
"enum A {",
" FOO;",
"",
" @SuppressWarnings(\"TypeMemberOrder\")",
" class InnerClass {}",
"",
" static final int BAR = 1;",
"",
" static {",
" System.out.println(\"foo\");",
" }",
"",
" {",
" System.out.println(\"bar\");",
" }",
"",
" A() {}",
"",
" void qux() {}",
"",
" interface InnerInterface {}",
"",
" @SuppressWarnings(\"TypeMemberOrder\")",
" final int baz = 2;",
"",
" enum InnerEnum {}",
"}")
.doTest(TestMode.TEXT_MATCH);
}
@Test
void replacementHandlesGeneratedDefaultConstructor() {
BugCheckerRefactoringTestHelper.newInstance(TypeMemberOrder.class, getClass())
.addInputLines(
"A.java",
"enum A {",
" FOO;",
"",
" class InnerClass {}",
"",
" interface InnerInterface {}",
"",
" enum InnerEnum {}",
"",
" void qux() {}",
"",
" {",
" System.out.println(\"bar\");",
" }",
"",
" static {",
" System.out.println(\"foo\");",
" }",
"",
" final int baz = 2;",
" static final int BAR = 1;",
"}")
.addOutputLines(
"A.java",
"enum A {",
" FOO;",
" static final int BAR = 1;",
"",
" final int baz = 2;",
"",
" static {",
" System.out.println(\"foo\");",
" }",
"",
" {",
" System.out.println(\"bar\");",
" }",
"",
" void qux() {}",
"",
" class InnerClass {}",
"",
" interface InnerInterface {}",
"",
" enum InnerEnum {}",
"}")
.doTest(TestMode.TEXT_MATCH);
}
@Test
void replacementDanglingComments() {
BugCheckerRefactoringTestHelper.newInstance(TypeMemberOrder.class, getClass())
.addInputLines(
"A.java",
"enum A {",
" /** FOO's JavaDoc */",
" FOO",
"/* Dangling comment trailing enumerations. */ ;",
"",
" /* `quz` method's dangling comment */",
" ;",
"",
" /* `quz` method's comment */",
" void qux() {}",
"",
" // `baz` method's comment",
" final int baz = 2;",
"",
" static final int BAR = 1;",
" // trailing comment",
"}")
.addOutputLines(
"A.java",
"enum A {",
" /** FOO's JavaDoc */",
" FOO",
"/* Dangling comment trailing enumerations. */ ;",
"",
" static final int BAR = 1;",
"",
" // `baz` method's comment",
" final int baz = 2;",
"",
" /* `quz` method's dangling comment */",
" ;",
"",
" /* `quz` method's comment */",
" void qux() {}",
" // trailing comment",
"}")
.doTest(TestMode.TEXT_MATCH);
}
}

View File

@@ -0,0 +1,195 @@
package tech.picnic.errorprone.experimental.bugpatterns;
import com.google.errorprone.BugCheckerRefactoringTestHelper;
import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;
import com.google.errorprone.CompilationTestHelper;
import org.junit.jupiter.api.Test;
final class TypeMemberOrderInterfaceTest {
@Test
void identification() {
CompilationTestHelper.newInstance(TypeMemberOrder.class, getClass())
.addSourceLines(
"A.java",
"// BUG: Diagnostic contains:",
"interface A {",
" static class InnerClass {}",
"",
" static interface InnerInterface {}",
"",
" static enum InnerEnum {}",
"",
" void bar();",
"",
" static final int foo = 1;",
"}")
.addSourceLines(
"B.java",
"interface B {",
" static final int foo = 1;",
"",
" void bar();",
"",
" static class InnerClass {}",
"",
" static interface InnerInterface {}",
"",
" static enum InnerEnum {}",
"}")
.addSourceLines(
"C.java",
"interface C {",
" @SuppressWarnings({\"foo\", \"all\", \"bar\"})",
" void bar();",
"",
" static final int foo = 1;",
"}")
.addSourceLines(
"D.java",
"interface D {",
" @SuppressWarnings(\"TypeMemberOrder\")",
" void bar();",
"",
" static final int foo = 1;",
"}")
.addSourceLines("E.java", "interface E {}")
.doTest();
}
@Test
void replacement() {
BugCheckerRefactoringTestHelper.newInstance(TypeMemberOrder.class, getClass())
.addInputLines(
"A.java",
"interface A {",
" static class InnerClass {}",
"",
" static interface InnerInterface {}",
"",
" static enum InnerEnum {}",
"",
" void bar();",
"",
" static final int foo = 1;",
"}")
.addOutputLines(
"A.java",
"interface A {",
"",
" static final int foo = 1;",
"",
" void bar();",
"",
" static class InnerClass {}",
"",
" static interface InnerInterface {}",
"",
" static enum InnerEnum {}",
"}")
.doTest(TestMode.TEXT_MATCH);
}
@Test
void replacementDefaultMethods() {
BugCheckerRefactoringTestHelper.newInstance(TypeMemberOrder.class, getClass())
.addInputLines(
"A.java",
"interface A {",
" class InnerClass {}",
"",
" void foo();",
"",
" default void bar() {}",
"",
" void baz();",
"",
" static final int QUX = 1;",
"}")
.addOutputLines(
"A.java",
"interface A {",
"",
" static final int QUX = 1;",
"",
" void foo();",
"",
" default void bar() {}",
"",
" void baz();",
"",
" class InnerClass {}",
"}")
.doTest(TestMode.TEXT_MATCH);
}
@Test
void replacementUnmovableMembers() {
BugCheckerRefactoringTestHelper.newInstance(TypeMemberOrder.class, getClass())
.addInputLines(
"A.java",
"interface A {",
" @SuppressWarnings(\"TypeMemberOrder\")",
" static class InnerClass {}",
"",
" static interface InnerInterface {}",
"",
" static enum InnerEnum {}",
"",
" void bar();",
"",
" @SuppressWarnings(\"TypeMemberOrder\")",
" static final int baz = 1;",
"",
" static final int foo = 1;",
"}")
.addOutputLines(
"A.java",
"interface A {",
" @SuppressWarnings(\"TypeMemberOrder\")",
" static class InnerClass {}",
"",
" static final int foo = 1;",
"",
" void bar();",
"",
" static interface InnerInterface {}",
"",
" @SuppressWarnings(\"TypeMemberOrder\")",
" static final int baz = 1;",
"",
" static enum InnerEnum {}",
"}")
.doTest(TestMode.TEXT_MATCH);
}
@Test
void replacementDanglingComments() {
BugCheckerRefactoringTestHelper.newInstance(TypeMemberOrder.class, getClass())
.addInputLines(
"A.java",
"interface A {",
" // empty statement's dangling comment",
" ;",
" // `bar` method's comment",
" void bar();",
"",
" // `foo` field's comment",
" int foo = 1;",
" // trailing comment",
"}")
.addOutputLines(
"A.java",
"interface A {",
"",
" // `foo` field's comment",
" int foo = 1;",
" // empty statement's dangling comment",
" ;",
"",
" // `bar` method's comment",
" void bar();",
" // trailing comment",
"}")
.doTest(TestMode.TEXT_MATCH);
}
}

View File

@@ -0,0 +1,65 @@
class A {
class AInner2 {
private static final int foo = 1;
int bar = 2;
class AInner2Inner1 {
private static final int foo = 1;
int bar = 2;
}
class AInner2Inner2 {
int bar = 2;
private static final int foo = 1;
}
}
private static final int foo = 1;
class OnlyTopLevelSortedClass {
private static final int foo = 1;
int bar = 2;
class UnsortedNestedClass {
int bar = 2;
private static final int foo = 1;
}
}
class AInner1 {
class AInner1Inner1 {
int bar = 2;
private static final int foo = 1;
}
enum DeeplyNestedEnum {
/** FOO's JavaDoc */
FOO,
/* Dangling comment trailing enumerations. */ ;
/** `quz` method's dangling comment */
;
/** `quz` method's comment */
void qux() {}
// `baz` method's comment
final int baz = 2;
static final int BAR = 1;
// trailing comment
}
private static final int foo = 1;
class AInner1Inner2 {
int bar = 2;
private static final int foo = 1;
}
int bar = 2;
}
static int baz = 3;
private final int bar = 2;
}

View File

@@ -0,0 +1,67 @@
class A {
private static final int foo = 1;
static int baz = 3;
private final int bar = 2;
class AInner2 {
private static final int foo = 1;
int bar = 2;
class AInner2Inner1 {
private static final int foo = 1;
int bar = 2;
}
class AInner2Inner2 {
private static final int foo = 1;
int bar = 2;
}
}
class OnlyTopLevelSortedClass {
private static final int foo = 1;
int bar = 2;
class UnsortedNestedClass {
private static final int foo = 1;
int bar = 2;
}
}
class AInner1 {
private static final int foo = 1;
int bar = 2;
class AInner1Inner1 {
private static final int foo = 1;
int bar = 2;
}
enum DeeplyNestedEnum {
/** FOO's JavaDoc */
FOO,
/* Dangling comment trailing enumerations. */ ;
static final int BAR = 1;
// `baz` method's comment
final int baz = 2;
/** `quz` method's dangling comment */
;
/** `quz` method's comment */
void qux() {}
// trailing comment
}
class AInner1Inner2 {
private static final int foo = 1;
int bar = 2;
}
}
}

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

@@ -79,6 +79,16 @@ public final class MoreASTHelpers {
return ASTHelpers.isSameType(ASTHelpers.getType(treeA), ASTHelpers.getType(treeB), state);
}
/**
* Tells whether a given tree is a generated constructor.
*
* @param tree The tree of interest.
* @return Whether the specified tree is a generated constructor.
*/
public static boolean isGeneratedConstructor(Tree tree) {
return tree instanceof MethodTree methodTree && ASTHelpers.isGeneratedConstructor(methodTree);
}
/**
* Tells whether the given tree is of type {@link String}.
*

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=''

107
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,17 @@
<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.maven>3.9.9</version.maven>
<version.mockito>5.15.2</version.mockito>
<version.mockito>5.16.1</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.nullaway>0.12.4</version.nullaway>
<version.pitest-git>2.2.0</version.pitest-git>
<version.rewrite-templating>1.24.1</version.rewrite-templating>
<version.surefire>3.2.3</version.surefire>
</properties>
@@ -269,7 +269,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>
@@ -363,14 +363,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 +387,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 +422,7 @@
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>1.17.1</version>
<version>1.17.4</version>
</dependency>
<!-- Specified so that Renovate will file Maven upgrade PRs, which
subsequently will cause `maven-enforcer-plugin` to require that
@@ -435,7 +435,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 +447,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 +472,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 +485,10 @@
</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.openrewrite</groupId>
@@ -496,33 +498,33 @@
<dependency>
<groupId>org.openrewrite.recipe</groupId>
<artifactId>rewrite-recipe-bom</artifactId>
<version>3.2.0</version>
<version>3.4.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 +550,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 +587,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>
@@ -923,7 +925,7 @@
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>10.21.2</version>
<version>10.21.4</version>
</dependency>
<dependency>
<groupId>io.spring.nohttp</groupId>
@@ -948,7 +950,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
@@ -1056,7 +1058,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>
@@ -1162,7 +1164,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>
@@ -1306,6 +1308,7 @@
<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>
@@ -1442,7 +1445,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>
@@ -1524,7 +1527,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 +1549,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>
@@ -1938,9 +1941,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}

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>

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

@@ -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

@@ -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"