`ChangeType` leaves the outer class import when replacing a doubly nested type
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 3/5
- Estimated time
- Half a day
- Newbie friendliness
- 62/100
Research direction
Start in ChangeType.visitFieldAccess, where maybeRemoveImport is called on oldType.getOwningClass() after the field access is replaced. The bug is that for a doubly nested type like a.Outer$Middle$Inner the import of the leftmost class a.Outer is never considered. Reproduce with the test in the issue, which expects the a.Outer import to be removed alongside the rewrite to b.Inner. Done when that test passes and the existing ChangeType tests still pass.
Written by the indexing model from the issue text.
Description
ChangeType leaves an unused import behind when the old type is nested two or more levels deep and the code reaches it through the top-level class, as in Outer.Middle.Inner. We ran into this migrating OpenAiAudioApi.SpeechRequest.Voice to OpenAiAudioSpeechOptions.Voice for Spring AI 2.0, which left import org.springframework.ai.openai.api.OpenAiAudioApi; behind. That class no longer exists in Spring AI 2.0, so the result doesn't compile.
What version of OpenRewrite are you using?
rewrite-java 8.96.0-SNAPSHOT; the same code is on main.
What is the smallest, simplest way to reproduce the problem?
@Test
void removeImportOfOutermostClass() {
rewriteRun(
spec -> spec.recipe(new ChangeType("a.Outer$Middle$Inner", "b.Inner", true)),
java("package a; public class Outer { public static class Middle { public enum Inner { ONE } } }"),
java("package b; public enum Inner { ONE }"),
java(
"""
import a.Outer;
class Test {
Object o = Outer.Middle.Inner.ONE;
}
""",
"""
import b.Inner;
class Test {
Object o = Inner.ONE;
}
"""
)
);
}
What did you see instead?
import a.Outer;
import b.Inner;
class Test {
Object o = Inner.ONE;
}
Cause
ChangeType.visitFieldAccess calls maybeRemoveImport(oldType.getOwningClass()) after replacing the field access. For a.Outer$Middle$Inner, that owning class is a.Outer$Middle, which nothing imports. The a.Outer import that the field access actually used is never considered. With a type nested only one level deep, the owning class is the top-level class and the import is removed as expected.
A fix could remove the import of the class that the leftmost identifier of the replaced field access refers to, or walk up all the owning classes.
- Dominant language
- Java
- Stars
- 3.9k
- Forks
- 599
- Avg merge
- 9h 38m
- Merged PRs (30d)
- 557
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from openrewrite/rewrite
-
Difficulty 2/5 1-3 hours Newbie friendliness 79/100
openrewrite/rewrite#9835 ·
Maintainers usually reply within 1 day
-
bug gradle
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
openrewrite/rewrite#7576 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 5/5 Over a week Newbie friendliness 25/100
openrewrite/rewrite#9834 ·
Maintainers usually reply within 1 day
-
Difficulty 5/5 Over a week Newbie friendliness 35/100
openrewrite/rewrite#9819 ·
Maintainers usually reply within 1 day
-
enhancement
Difficulty 4/5 3-5 days Newbie friendliness 55/100
openrewrite/rewrite#9817 ·
Maintainers usually reply within 1 day
All issues in openrewrite/rewrite
Similar issues
-
Four TestConstraintBasedAlgorithm tests pass when nothing is thrownPossibly taken @sharanggupta claimed this today. Open
Difficulty 1/5 1-3 hours Newbie friendliness 85/100
-
bug documentation good first issue help wanted priority low size XS
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
martin-francois/symphony-trello#1351 ·
Maintainers usually reply within 1 day
-
Add test coverage for ConvertUtil.parseDate() with NULL inputPossibly taken @mirajul-mollah7 claimed this today. Open
Difficulty 1/5 Under an hour Newbie friendliness 78/100
eclipse-sw360/sw360#4792 · 1 comment ·
Maintainers usually reply within 3 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
aws/aws-emulator#30 · 1 comment ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 4 days