ReplaceStringConcatenationWithStringValueOf: add failing tests for out-of-scope paren unwrap and untyped operand - #989
Closed
martinfrancois wants to merge 1 commit into
Conversation
…t-of-scope paren unwrap and untyped operand doNotChangeParenthesizedValueOfWithoutConcatenation pins that visitParentheses strips parens from a pre-existing (String.valueOf(o)) in a file where no concatenation was rewritten. doNotChangeWhenOperandTypeIsMissing pins that an operand without type attribution is still rewritten, which changes the rendered value when it is really a char[]. Both are marked @ExpectedToFail. Relates to openrewrite#975.
Contributor
Author
|
Closing after review: the remaining parentheses-only case does not meet the bug threshold. The missing-type safety case overlaps with #975 and will be handled there. |
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.
Review together with: #975
This companion PR is folded into the same review position rather than receiving a separate rank.
What's changed?
Adds 2 known-failing tests to the
NoChangenested class ofReplaceStringConcatenationWithStringValueOfTest. One reproduces the recipe stripping parentheses from a pre-existingString.valueOf(..)call in a file that has no string concatenation at all. The other reproduces the recipe rewriting"" + xeven when the type ofxis unknown.No recipe code changes. Both tests are marked
@ExpectedToFail, so the suite stays green; removing the annotation shows the failure. On current main the class has 14 tests (9 in the outer class, 5 inNoChange) with 0 failures; with these additions it has 16 tests (7 inNoChange), still 0 failures and the 2 new ones reported as skipped.What's your motivation?
First defect: the recipe edits files it should not touch. Before the recipe runs:
There is no concatenation here, so the recipe should make no change. Output from current main:
The hand-written parentheses are stripped.
visitParenthesesinReplaceStringConcatenationWithStringValueOfunwraps any parenthesizedString.valueOf(..)call it visits, not only the ones the recipe just introduced.Second defect:
doNotChangeWhenOperandTypeIsMissingparses this input withTypeValidation.none(), soholder.chars()carries no type attribution:Output from current main:
This rewrite is not safe when the operand type is unknown, because it is not value-preserving if the operand is really a
char[]. We verified that with a small Java program usingchar[] chars = {'h','i'}:"" + charsprinted[C@2b2fa4f7whileString.valueOf(chars)printedhi. The guard invisitBinaryonly checks!TypeUtils.isString(right.getType()), which is also true for a missing type, so the rewrite proceeds. The test asserts the recipe skips the expression when the type is unknown.Found while preparing #975, which fixes a related defect in this recipe and lists both of these limitations as out of scope. These tests do not depend on #975; both defects reproduce on today's main.
Anything in particular you'd like reviewers to focus on?
We think both are genuine bugs: the first changes files the recipe has no business editing, and the second can change runtime behavior when types are missing. Note the
char[]hazard also exists with full type attribution, since the recipe has nochar[]guard at all; #975 adds a typed guard for that, while the test here pins only the missing-type case. If you agree this should change, I would gladly prepare the fix. If this behavior is intended, feel free to close this and we know it is settled.Any additional context
Related open PR of ours touching the same recipe: #975. It discloses both limitations as out of scope and does not fix them.
This reproduction was prepared with AI assistance (Claude Code). I reviewed the tests and this description.
Checklist
This draft adds a reproduction test only, so the first box stays unticked on purpose; I will complete it together with the fix if you want one. The formatter run was calibrated per file; I declined reindentation of untouched lines.