Skip to content

Fix IfElseIfConstructToSwitch type attribution for non-JDK types#994

Open
timtebeek wants to merge 2 commits intomainfrom
timtebeek/fix-java21-recipe
Open

Fix IfElseIfConstructToSwitch type attribution for non-JDK types#994
timtebeek wants to merge 2 commits intomainfrom
timtebeek/fix-java21-recipe

Conversation

@timtebeek
Copy link
Member

@timtebeek timtebeek commented Feb 27, 2026

Summary

  • Fix type attribution loss when JavaTemplate applies raw string substitution (#{}) for non-JDK types in generated switch case labels
  • Add fixTypeAttribution post-processing method that restores original type information from instanceof checks onto generated case labels and pattern variables
  • Re-enable IfElseIfConstructToSwitch in java-version-21.yml (was disabled with a FIXME about casecase artifact near non-JDK types)

What was wrong

JavaTemplate.apply() uses raw string substitution which loses type information for non-JDK types. This caused corrupted casecase output in the generated switch statements when the recipe encountered user-defined types like Dog, Cat, etc.

How it's fixed

After the template generates the switch statement, fixTypeAttribution() iterates over the original instanceof checks (from patternMatchers) alongside the generated case statements. For each pattern-matching case label (J.VariableDeclarations), it replaces the typeExpression and variable type with the originals from the corresponding instanceof check, which carry proper type information.

Test plan

  • nullCheckWithNonJdkTypes — null check + two non-JDK instanceof types (Dog, Cat)
  • threeNonJdkTypes — three non-JDK instanceof types without null check (Dog, Cat, Bird)
  • Run full test suite to verify no regressions

JavaTemplate uses raw string substitution (#{}) for class names in
generated switch cases. The template parser can resolve JDK types
like Integer (in java.lang) but cannot resolve non-JDK types from
just a name string, producing missing type information on case labels.

Add fixTypeAttribution() post-processing that restores original type
information from the instanceof checks onto the generated switch case
variable declarations.

Re-enable the recipe in UpgradeToJava21.
@timtebeek timtebeek force-pushed the timtebeek/fix-java21-recipe branch from 1e6a960 to fa52f6b Compare February 27, 2026 10:06
@timtebeek timtebeek changed the title Fix IfElseIfConstructToSwitch for non-JDK types Fix IfElseIfConstructToSwitch for non-JDK types Feb 27, 2026
@timtebeek timtebeek changed the title Fix IfElseIfConstructToSwitch for non-JDK types Fix IfElseIfConstructToSwitch type attribution for non-JDK types Feb 27, 2026
@timtebeek timtebeek requested a review from Jenson3210 February 27, 2026 11:32
@timtebeek timtebeek added bug Something isn't working recipe Recipe requested java 21+ labels Feb 27, 2026
@timtebeek timtebeek moved this from In Progress to Ready to Review in OpenRewrite Feb 27, 2026
@timtebeek timtebeek marked this pull request as ready for review February 27, 2026 11:33
@timtebeek timtebeek changed the title Fix IfElseIfConstructToSwitch type attribution for non-JDK types Fix IfElseIfConstructToSwitch type attribution for non-JDK types Feb 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working java 21+ recipe Recipe requested

Projects

Status: Ready to Review

Development

Successfully merging this pull request may close these issues.

1 participant