Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix suggestions emitted by the StringCaseLocaleUsage check #400

Merged
merged 4 commits into from
Dec 9, 2022

Conversation

rickie
Copy link
Member

@rickie rickie commented Dec 8, 2022

Encountered this while testing the upcoming release on downstream code.

The following code:

return this.name().toLowerCase();

Got rewritten to:

return this.name(Locale.ROOT).toLowerCase();

But should've been:

return this.name().toLowerCase(Locale.ROOT);

After some testing, it turns out that searching for the first occurrence of ( is much more error-prone than searching for the last occurrence. Therefore I propose to change the implementation accordingly.

NB: To be (arguably) more correct, I changed the implementation to find the first closing bracket after the last opening bracket. There are cases where this can still cause problems. An example:

// This code:
"a".toLowerCase(/* Comment with parens: ((. */ );
// would currently result in:
"a".toLowerCase(/* Comment with parens: ((Locale.ROOT);  
// at the end we are missing: `*/...`

Yes we should tackle this, but I think it'd be better for now to leave this as is and create a ticket to properly fix this.

So this is indeed not the optimal solution and we should implement a more correct one. However, for now I'd argue this is a clear improvement.

@rickie rickie requested a review from Stephan202 December 8, 2022 10:45
@rickie rickie added the bug fix label Dec 8, 2022
@rickie rickie added this to the 0.6.0 milestone Dec 8, 2022
@github-actions
Copy link

github-actions bot commented Dec 8, 2022

Looks good. All 5 mutations in this change were killed.

class surviving killed
🎉tech.picnic.errorprone.bugpatterns.StringCaseLocaleUsage 0 5

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

1 similar comment
@github-actions
Copy link

github-actions bot commented Dec 8, 2022

Looks good. All 5 mutations in this change were killed.

class surviving killed
🎉tech.picnic.errorprone.bugpatterns.StringCaseLocaleUsage 0 5

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

Copy link
Member

@Stephan202 Stephan202 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a commit.

Suggested commit message:

Fix suggestions emitted by the `StringCaseLocaleUsage` check (#400)

The suggested `Locale` arguments are now always located in the correct place.

Comment on lines 66 to 71
" getString().toLowerCase();",
" getString().toUpperCase /* Comment with parens: (). */();",
" }",
"",
" private String getString() {",
" return \"\";",
" }",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can simply use toString() instead of a custom getString().

Comment on lines 61 to 74
// XXX: The logic that replaces the first parenthesis assumes that `tree` does not have a source
// code representation such as `str.toLowerCase/* Some comment with parens (). */()`. In such a
// XXX: The logic that replaces the last parenthesis assumes that `tree` does not have a source
// code representation such as `str.toLowerCase(/* Some comment with parens (). */)`. In such a
// case the comment, rather than the method invocation arguments, will be modified. Implement a
// generic solution for this.
String source = SourceCode.treeToString(tree, state);
int indexOfLastOpeningBracket = source.lastIndexOf('(');
String sourceAfterLastOpeningBracket = source.substring(indexOfLastOpeningBracket);
int indexOfClosingBracket = sourceAfterLastOpeningBracket.indexOf(')');
return SuggestedFix.builder()
.addImport("java.util.Locale")
.replace(tree, SourceCode.treeToString(tree, state).replaceFirst("\\(", '(' + locale))
.replace(
tree,
source.substring(0, indexOfLastOpeningBracket)
+ "("
+ locale
+ sourceAfterLastOpeningBracket.substring(indexOfClosingBracket))
.build();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a known-hacky solution bit us once, then we shouldn't replace it with another hacky solution. It seem better to look only at the final closing paren. Additionally, we can take inspiration from Error Prone's (Java)doc-related checks to see how we can robustly avoid matching comments. Will push a proposal.

@github-actions
Copy link

github-actions bot commented Dec 8, 2022

  • Surviving mutants in this change: 4
  • Killed mutants in this change: 10
class surviving killed
🧟tech.picnic.errorprone.bugpatterns.StringCaseLocaleUsage 4 10

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

@Stephan202
Copy link
Member

^ The four surviving mutants are in code that handles the absence of source code; not sure how we can test those cases without jumping through lots of hoops. Not worth the effort :)

@rickie rickie force-pushed the rossendrijver/bugs/stringlocalecaseusage branch from 16c65de to 7e01f11 Compare December 9, 2022 12:28
@rickie rickie requested a review from Badbond December 9, 2022 12:28
@github-actions
Copy link

github-actions bot commented Dec 9, 2022

  • Surviving mutants in this change: 4
  • Killed mutants in this change: 10
class surviving killed
🧟tech.picnic.errorprone.bugpatterns.StringCaseLocaleUsage 4 10

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

Copy link
Member

@Badbond Badbond left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice bug fix and general improvement 👍 Suggested commit message LGTM. Didn't have much input but for maybe one test case that can be added.

Comment on lines +70 to 71
" this.toString().toUpperCase();",
" }",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we match on last ), we could add a test to make sure it does not match when there is another chained method invocation afterwards:

Suggested change
" this.toString().toUpperCase();",
" }",
" this.toString().toUpperCase();",
"",
" "a".toUpperCase().toString();"
" }",

But this is rather testing that the Matcher defined is not matching too broadly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see why not. Will push something.

@rickie
Copy link
Member Author

rickie commented Dec 9, 2022

Added commit.

Will merge once 🟢 .

Added one word to the suggested commit message 👀.

@github-actions
Copy link

github-actions bot commented Dec 9, 2022

  • Surviving mutants in this change: 4
  • Killed mutants in this change: 10
class surviving killed
🧟tech.picnic.errorprone.bugpatterns.StringCaseLocaleUsage 4 10

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

@rickie rickie changed the title Improve SuggestedFix for StringCaseLocaleUsage check Fix suggestions emitted by the StringCaseLocaleUsage check Dec 9, 2022
@rickie rickie merged commit 8145028 into master Dec 9, 2022
@rickie rickie deleted the rossendrijver/bugs/stringlocalecaseusage branch December 9, 2022 13:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging this pull request may close these issues.

3 participants