Keep annotated and strictfp overrides that only call super - #988
Merged
timtebeek merged 2 commits intoAug 17, 2026
Merged
Conversation
4 tasks
martinfrancois
force-pushed
the
repro/remove-methods-only-call-super-annotations
branch
2 times, most recently
from
August 16, 2026 02:53
5a8030e to
134b35a
Compare
martinfrancois
force-pushed
the
repro/remove-methods-only-call-super-annotations
branch
from
August 16, 2026 12:23
134b35a to
b0a9d77
Compare
strictfp overrides that only call super
martinfrancois
marked this pull request as ready for review
August 17, 2026 08:08
timtebeek
approved these changes
Aug 17, 2026
timtebeek
left a comment
Member
There was a problem hiding this comment.
Thanks for the double fixes here!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Suggested review order: 8 of 52 (Score: 8)
Review first: openrewrite/rewrite-migrate-java#1205
What's changed?
Updates
RemoveMethodsOnlyCallSuperto preserve forwarding overrides when a parameter or any nested part of the method signature carries an annotation other than@Override.The change also preserves a
strictfpoverride when the invoked super method is notstrictfp. It still removes the override when both methods arestrictfp, matching the recipe's existing handling ofsynchronized.The three former failing reproductions are now passing regression tests, and a positive control verifies the safe
strictfpremoval. All 20 tests inRemoveMethodsOnlyCallSuperTestpass.What's your motivation?
Recipe:
org.openrewrite.staticanalysis.RemoveMethodsOnlyCallSuper.#971 taught this recipe to keep overrides that add declaration annotations or the
synchronizedmodifier. Its method-level annotation query does not include annotations on parameters or type-use annotations nested inside the return type, so the recipe still deletes overrides that carry those contracts.Case 1: parameter annotation
Before
Actual after the recipe
Expected after the recipe
(unchanged)Removing the method silently removes the parameter contract read by annotation processors and static-analysis tools. The same loss occurs for a nested type-use annotation such as
public String @Nullable [] foo().Case 2:
strictfpmodifierBefore
Actual after the recipe
The override is deleted, leaving the same empty
Childclass shown in Case 1.Expected after the recipe
(unchanged)when the super method is notstrictfp.The previous transformation drops a reflection-visible modifier. Before Java 17, it also changes floating-point semantics. When the super method is already
strictfp, removing this forwarding override remains safe and the recipe still removes it.Confirmed real-world execution
MethodOverridingTests.javaate1f271a7and its integration test.org.openrewrite.recipe:rewrite-static-analysis:2.41.0.The released recipe deletes a delegating override whose parameter annotations intentionally create the invalid constraint declaration tested by Hibernate Validator. The deletion removes the diagnostic condition and weakens the test.
Affected code in real projects
didi/DoKitCpuMainPageFragment.java: anonViewCreatedoverride that only forwards to super but carries@NonNulland@Nullableparameter annotations. The recipe from main deletes the whole override, silently dropping the parameter nullability contracts it declares.Justson/AgentWebAgentActionFragment.java: the same shape in a library fragment,super.onViewCreated(view, savedInstanceState)with@NonNull/@Nullableannotated parameters. The recipe from main removes the method together with those annotations.Anything in particular you'd like reviewers to focus on?
Please review the conservative signature traversal, which intentionally stops before the method body, and the decision to mirror the existing
synchronizedparent-method comparison forstrictfp.Have you considered any alternatives or workarounds?
One alternative is to enumerate specific signature locations. Traversing the complete signature is safer because an override carrying annotation metadata is not redundant, regardless of whether the annotation is attached to a parameter, type parameter, return type, or nested type use.
For
strictfp, preserving every marked override would also retain behavior. Comparing the super method retains the recipe's cleanup when the modifier is redundant.Any additional context
Pre-existing tests changed: None.
Related: #971 added the
synchronizedguard and the declaration-level annotation guard. This change extends the same behavior to the remaining signature locations and tostrictfp.This change was prepared with AI assistance. I reviewed the implementation, regression tests, focused test results, and contribution text.
Checklist
./gradlew buildlocally, and committed any resulting changes torecipes.csv