Skip to content

Add UseLocaleWithCaseConversions recipe for STR02-J (#78)#944

Open
kush2439p wants to merge 7 commits into
openrewrite:mainfrom
kush2439p:main
Open

Add UseLocaleWithCaseConversions recipe for STR02-J (#78)#944
kush2439p wants to merge 7 commits into
openrewrite:mainfrom
kush2439p:main

Conversation

@kush2439p

@kush2439p kush2439p commented Jul 19, 2026

Copy link
Copy Markdown

What does this PR do?

Adds a new recipe, UseLocaleWithCaseConversions, implementing STR02-J: it rewrites
String#toLowerCase() / String#toUpperCase() calls that don't specify a Locale to
explicitly pass Locale.ROOT (or a user-configured locale). This avoids locale-dependent
case-conversion bugs — e.g. converting "I" to lowercase under a Turkish locale yields a
dotless ı instead of the expected i.

Changes

  • UseLocaleWithCaseConversions: new recipe with an optional @Option locale
    (defaults to ROOT if not provided, per the issue's request), using MethodMatcher +
    JavaTemplate to rewrite the method call and maybeAddImport for the Locale import.
  • Tests: covers toLowerCase()toLowerCase(Locale.ROOT), toUpperCase()
    toUpperCase(Locale.ROOT), no-op when a Locale is already specified, and a
    configured non-default locale.
  • common-static-analysis.yml: registered the recipe, but commented out / opt-in,
    since it changes case-conversion semantics (not just style) for one of the most
    commonly called String methods. Happy to discuss making it active-by-default if
    maintainers feel differently.

Example

// before
str.toLowerCase();

// after
str.toLowerCase(Locale.ROOT);

Backward compatibility

Since the recipe is registered as opt-in (commented out in common-static-analysis.yml),
existing users of CommonStaticAnalysis see no behavior change unless they explicitly
activate this recipe.

…has dependent type params (<T, S extends T>)

Adds hasDependentTypeParameters() check so that explicit type arguments are
preserved when the enclosing method has a type parameter whose bound references
another type parameter of the same method (e.g. <T, S extends T>).

Also adds a regression test covering the minimal reproduction from the issue.
This class specifies a Locale for case conversions to avoid locale-dependent issues.
@kush2439p

Copy link
Copy Markdown
Author

Opened a PR for this: adds UseLocaleWithCaseConversions, a recipe that rewrites
String#toLowerCase()/toUpperCase() calls without a Locale to use Locale.ROOT by
default, with an @Option to configure a different locale — per the original ask in this
issue. Registered it as opt-in in common-static-analysis.yml for now since it's a
semantic (not just stylistic) change; open to feedback on whether it should be enabled
by default. Tests included, happy to adjust based on review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

Specify an appropriate locale when comparing locale-dependent data.STR02-J

1 participant