SONARJAVA-6824: Implemented rule S9358 - Conditional expressions should not duplicate operations in both branches - #6001
Conversation
…ld not duplicate operations in both branches This rule detects when a ternary operator applies the same operation (method invocation, object creation, or array access) to different arguments in both branches. Such patterns can be refactored by moving the condition inside the operation for better readability.
|
🔗 Commit SHA: 4c652ad | Docs | View more details | Give us feedback! |
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move test cases into methods with properly typed local variables to fix compilation errors in TernaryOperatorSameOperationCheckSample - Use ExpressionUtils.skipParentheses() to handle parenthesized expressions in ternary branches - Fix argument comparison logic to flag cases where at least one argument differs (not only when all arguments differ) - Add test cases for multi-argument scenarios Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
🤖 Generated with GitHub Actions
|
❌ Ruling needs updating. A fix PR has been created: #6012 Please review and merge it into your branch. |
- Change type from String to Object for ternary with Foo/Bar constructors - Merge ruling expectation updates from PR #6012 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Ruling Diff SummaryDetected changes in 4 rule files: 0 issues removed, 16 issues added. S9358 (
|
|
❌ Ruling needs updating. A fix PR has been created: #6014 Please review and merge it into your branch. |
- Remove unused imports (ArrayDimensionTree, TypeTree) - Remove dead code: null checks that always evaluate to false - Reduce duplication by extracting hasExactlyOneArgumentDifference() and consolidating sameExpression/sameTree into a single method - Remove unused typeArguments handling in sameNewClass - Add more test cases for edge cases (no-arg methods, different receivers, mixed expression kinds, member select edge cases) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
🤖 Generated with GitHub Actions
|
❌ Ruling needs updating. A fix PR has been created: #6014 Please review and merge it into your branch. |
…ces and add ruling expectations The method was using a boolean flag that returned true when any arguments differed, causing false positives for cases with multiple differing arguments. Now uses an integer counter to ensure exactly one argument differs. Also adds eclipse-jetty ruling expectations and test cases for multiple argument differences. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
' of github.com:SonarSource/sonar-java into romain/new-rule-s9358-sonarjava-6824
🤖 Generated with GitHub Actions
|
❌ Ruling needs updating. A fix PR has been created: #6016 Please review and merge it into your branch. |
|
❌ Ruling needs updating. A fix PR has been created: #6018 Please review and merge it into your branch. |
…ar-to-main Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Code Review ✅ Approved 4 resolved / 4 findingsImplements rule S9358 to detect duplicate operations in conditional expression branches with comprehensive test cases, addressing missing metadata resource files, argument difference counting, and nested ternary handling. ✅ 4 resolved✅ Bug: Missing S9358 rule metadata (JSON/HTML) resource files
✅ Bug: Parentheses not unwrapped; nested-ternary test case won't be detected
✅ Edge Case: Only flags calls where every argument differs
✅ Bug: hasExactlyOneArgumentDifference flags any number of differing args
Implementation Status ✅ 1 / 1 issues implemented✅ SONARJAVA-6824 — 1 / 1 objectivesThe PR successfully implements rule S9358 with the corresponding check, tests, metadata, documentation, and ruling expectations. ✅ 1 complete
OptionsAuto-apply is off → Gitar will not commit updates to this branch. Comment with these commands to change the behavior for this request:
Was this helpful? React with 👍 / 👎 | Gitar |
|
| } | ||
|
|
||
| private static boolean sameMethodInvocation(MethodInvocationTree left, MethodInvocationTree right) { | ||
| return sameMethodSelect(left.methodSelect(), right.methodSelect()) |
There was a problem hiding this comment.
Method names do not identify the invoked operation. For example, condition ? overloaded(1) : overloaded("x") invokes distinct overloads but is reported, while condition ? foo(a) : this.foo(b) invokes the same method but is missed. The suggested refactoring for the overload case may not compile. Please compare resolved method symbols when semantic information is available, and avoid reporting ambiguous syntax-only matches.
| } | ||
|
|
||
| private static boolean sameNewClass(NewClassTree left, NewClassTree right) { | ||
| if (!sameTree(left.identifier(), right.identifier())) { |
There was a problem hiding this comment.
This comparison ignores constructor identity and the rest of the creation context. condition ? new Overloaded(1) : new Overloaded("x") is reported even when those arguments select different constructors; enclosing instances and anonymous class bodies are ignored as well. Please compare resolved constructor symbols and relevant NewClassTree context before treating these branches as the same operation.




This PR implements rule S9358 which detects when a ternary operator applies the same operation (method invocation, object creation, or array access) to different arguments in both branches.
Such patterns can be refactored by moving the condition inside the operation for better readability:
The rule handles:
Test cases cover both compliant and non-compliant scenarios including edge cases like nested ternaries, chained method calls, and generic type arguments.