Skip to content

Fix method patterns for dead UnsignedInts/UnsignedLongs recipes#1176

Merged
timtebeek merged 3 commits into
mainfrom
tim/fix-remainder-unsigned-signature
Jul 26, 2026
Merged

Fix method patterns for dead UnsignedInts/UnsignedLongs recipes#1176
timtebeek merged 3 commits into
mainfrom
tim/fix-remainder-unsigned-signature

Conversation

@timtebeek

@timtebeek timtebeek commented Jul 26, 2026

Copy link
Copy Markdown
Member

Guava's UnsignedInts/UnsignedLongs have no remainderUnsigned, compareUnsigned or divideUnsigned methods — the real names are remainder, compare and divide — so six of the eight method patterns in this block never matched anything. I checked every release from 10.0 to 33.5.0 with javap: the *Unsigned names appear in none of them, and the real signatures have been byte-identical since the classes were introduced, so this was never a case of Guava dropping methods.

Both Prefer*RemainderUnsigned recipes now rename remainder first, mirroring the existing Compare/Divide chaining; PreferLongCompareUnsigned and PreferLongDivideUnsigned had (int, int) where UnsignedLongs takes (long, long); and PreferLongParseUnsignedLong pointed at UnsignedInts instead of UnsignedLongs (its display name and description also said parseUnsignedInt). Separately, PreferIntegerRemainderUnsigned was declared but never referenced from NoGuava, so it would not have run even once fixed — it is now wired in.

There were no tests for any of these recipes, so this adds NoGuavaUnsignedTest covering every conversion for both types plus the radix overloads, run through the aggregate NoGuava recipe so it guards the wiring too. Confirmed these are genuine regression tests by stashing only the YAML: unsignedLongs() reported "Recipe was expected to make a change but made no changes" and unsignedInts() failed on remainder.

Two follow-up commits: one drops descriptions advertising methods Guava does not have (#compareUnsigned, #divideUnsigned, IntMath#addExact/#subtractExact/#multiplyExact) and corrects com.google.common.primitives.IntMath to com.google.common.math.IntMath, a package that does not exist; the other matches on (..) rather than pinned parameter types, since pinning them is what let these mismatches hide, and the sibling PreferMath*Exact recipes already do this.

Guava's `UnsignedInts`/`UnsignedLongs` have no `remainderUnsigned`,
`compareUnsigned` or `divideUnsigned` methods; the real names are
`remainder`, `compare` and `divide`. Six of the eight method patterns in
this block therefore never matched:

- `PreferIntegerRemainderUnsigned` and `PreferLongRemainderUnsigned`
  targeted a nonexistent `remainderUnsigned`; they now rename `remainder`
  first, mirroring the existing Compare/Divide chaining.
- `PreferLongCompareUnsigned` and `PreferLongDivideUnsigned` declared
  `(int, int)` where `UnsignedLongs` takes `(long, long)`.
- `PreferLongParseUnsignedLong` pointed at `UnsignedInts` rather than
  `UnsignedLongs`, and its display name and description said
  `parseUnsignedInt`.

Also add `PreferIntegerRemainderUnsigned` to `NoGuava`, as it was
declared but never referenced, and add `NoGuavaUnsignedTest` to cover
all four conversions per type.
None of `UnsignedInts`/`UnsignedLongs#compareUnsigned`, `#divideUnsigned`
or `IntMath#addExact`/`#subtractExact`/`#multiplyExact` exist in Guava, so
naming them as the "instead of" source was misleading. The Subtract and
Multiply descriptions also referenced `com.google.common.primitives.IntMath`,
a package that does not exist; the class is `com.google.common.math.IntMath`.

Descriptions only; the underlying method patterns were already correct for
the Math recipes.
Pinning the exact parameter types is what allowed the earlier mismatches
to go unnoticed, so match on `(..)` instead, as the sibling
`PreferMath*Exact` recipes already do. `UnsignedInts` and `UnsignedLongs`
each declare a single overload of `compare`, `divide` and `remainder`, and
those signatures have been unchanged since the classes were introduced in
Guava 10.0/11.0, so this cannot over-match.

Also cover the two-argument radix overloads of `parseUnsignedInt` and
`parseUnsignedLong`, and add the missing blank line before
`PreferLongDivideUnsigned`.
@timtebeek
timtebeek merged commit e29c330 into main Jul 26, 2026
1 check passed
@timtebeek
timtebeek deleted the tim/fix-remainder-unsigned-signature branch July 26, 2026 22:06
@github-project-automation github-project-automation Bot moved this from In Progress to Done in OpenRewrite Jul 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant