Skip to content

SONARJAVA-7162 Implement rule S9435 - Ternary operator conditions should not be negated - #6353

Merged
rombirli merged 10 commits into
masterfrom
rombirli/implement-ternary-negated-condition
Oct 21, 2026
Merged

rombirli merged 10 commits into
masterfrom
rombirli/implement-ternary-negated-condition

Conversation

@rombirli

@rombirli rombirli commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Implements rule S9435, which raises on a ternary expression whose condition is negated (!x or x != y), since the reader has to invert the condition mentally before pairing each result with the case it belongs to.

Null checks are exempt: value != null ? value.name() : "unknown" reads naturally as a positive guard, and so does its long form !(value == null). Only the top-level condition is considered, so value != null && count != 0 ? ... : ... does not raise. if statements are out of scope by design, as decided on the RSPEC.

RSPEC: https://github.com/SonarSource/rspec/pull/8337 (branch rule/add-RSPEC-S9435, not merged yet)
Jira: https://sonarsource.atlassian.net/browse/SONARJAVA-7162


Summary by Gitar

  • Quick fix:
    • Adds a quick fix that inverts the condition and swaps both ternary branches
    • Parenthesizes assignments moved into the false branch so the rewritten expression compiles
  • Negated comparisons:
    • Skips negated comparisons such as !(count > 0) because rule S1940 already reports them

This will update automatically on new commits.

@hashicorp-vault-sonar-prod

hashicorp-vault-sonar-prod Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

SONARJAVA-7162

@datadog-sonarsource

datadog-sonarsource Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Pipelines

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 95c89a2 | Docs | View more details | Give us feedback!

@github-actions

Copy link
Copy Markdown
Contributor

⚖️ Ruling update ready for review: #6355

@github-actions

Copy link
Copy Markdown
Contributor

Ruling Diff Summary

Detected changes in 1 rule files: 0 issues removed, 3 issues added.

S9435 (java) on sonarqube-6.5 - 0 issues removed, 3 issues added - new ruling file

Added src/main/java/org/sonar/server/debt/DebtRulesXMLImporter.java (line 254)

(source file not found at this revision: src/main/java/org/sonar/server/debt/DebtRulesXMLImporter.java)

Added src/test/java/org/sonar/server/issue/IssueDocTesting.java (line 69)

(source file not found at this revision: src/test/java/org/sonar/server/issue/IssueDocTesting.java)

Added src/test/java/org/sonar/server/issue/IssueDocTesting.java (line 74)

(source file not found at this revision: src/test/java/org/sonar/server/issue/IssueDocTesting.java)

@rombirli

Copy link
Copy Markdown
Contributor Author

/pvf

@hashicorp-vault-sonar-prod

Copy link
Copy Markdown
Contributor

📊 Performance Validation complete
🆕 557 new · 🗑️ 0 lost issues
View dashboard

@hashicorp-vault-sonar-prod

Copy link
Copy Markdown
Contributor

📊 Performance Validation complete
🆕 8 new · 🗑️ 0 lost issues
View dashboard

@hashicorp-vault-sonar-prod

Copy link
Copy Markdown
Contributor

📊 Performance Validation complete
🆕 557 new · 🗑️ 0 lost issues
View dashboard

@rombirli
rombirli requested a review from nathsou October 19, 2026 12:26
@rombirli

Copy link
Copy Markdown
Contributor Author

/pvf

@hashicorp-vault-sonar-prod

Copy link
Copy Markdown
Contributor

📊 Performance Validation complete
🆕 852 new · 🗑️ 262 lost issues
View dashboard

@nathsou nathsou left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good but I would consider reusing S7735

Comment thread java-checks/src/main/java/org/sonar/java/checks/NegatedTernaryConditionCheck.java Outdated
Comment thread java-checks/src/main/java/org/sonar/java/checks/NegatedTernaryConditionCheck.java Outdated
@rombirli
rombirli requested a review from nathsou October 20, 2026 07:17

@nathsou nathsou left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good, only a small issue to fix.

Comment thread java-checks/src/main/java/org/sonar/java/checks/NegatedTernaryConditionCheck.java Outdated
@rombirli

Copy link
Copy Markdown
Contributor Author

/pvf

@hashicorp-vault-sonar-prod

Copy link
Copy Markdown
Contributor

📊 Performance Validation complete
🆕 557 new · 🗑️ 8447 lost issues
View dashboard

Comment thread java-checks/src/main/java/org/sonar/java/checks/NegatedTernaryConditionCheck.java Outdated
@gitar-bot

gitar-bot Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Code Review ✅ Approved 2 closed / 2 findings

🟡 Medium risk · Adding S9435 changes ternary issue reporting and introduces an autofix that could rewrite expressions incorrectly if condition or branch handling misses an edge case.

Adds rule S9435 flagging ternary expressions with a negated top-level condition (!x or x != y), excluding null checks, with a quick fix that inverts the condition and swaps branches. Resolved the quick fix compilation issue with unparenthesized assignments in the true branch and restored the Javadoc placement on falseBranchText.

✅ 2 closed
✅ Edge Case: Quick fix breaks compilation when the true branch is an unparenthesized assignment

📄 java-checks/src/main/java/org/sonar/java/checks/NegatedTernaryConditionCheck.java:76-77
invertAndSwap copies the true branch's source text into the false slot unchanged. In Java the middle operand of ?: can be any Expression, but the third operand must be a ConditionalExpression or a lambda. So !done ? x = 1 : y is valid code that this rule flags, yet the fix rewrites it to done ? y : x = 1. That parses as (done ? y : x) = 1, which does not compile. The fix should wrap the moved true expression in parentheses when it is an ASSIGNMENT-kind tree (or anything with lower precedence than a conditional), or skip the quick fix in that case.

✅ Quality: Javadoc for falseBranchText now attached to withSeparator

📄 java-checks/src/main/java/org/sonar/java/checks/NegatedTernaryConditionCheck.java:84-88 📄 java-checks/src/main/java/org/sonar/java/checks/NegatedTernaryConditionCheck.java:103
The new withSeparator method was inserted between the Javadoc that describes falseBranchText and that method. As a result, the comment about parenthesizing assignments moved to the third operand of ?: now documents withSeparator, which only adds a leading space, and falseBranchText has no doc at all. Move withSeparator above the Javadoc block, or move the Javadoc back down to sit directly above falseBranchText.

Verification Rules 2/2 met Repos 4 inspected

Functional validation No results

Rules 2 passed 1 not applicable

✅ Internal artifact registries
✅ Repository license compliance

Broader impact Repos 4 inspected
Cross-repo 4 repositories inspected 0 open impacts

SonarSource/sonarlint-intellij Inspected
SonarSource/sonarlint-vscode Inspected
SonarSource/sonarlint-language-server Inspected
SonarSource/sonar-java-symbolic-execution Inspected

Auto-approval Not enabled

Set up

For more verification details, comment gitar display:verbose.

Options

Auto-apply is off → Gitar will not commit updates to this branch.
Display: compact → Showing compact verification results.

Comment with these commands to change the behavior for this request:

Auto-apply Compact
gitar auto-apply:on         
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

@sonarqube-next

Copy link
Copy Markdown
Contributor

@rombirli
rombirli merged commit 6dfe7d5 into master Oct 21, 2026
32 of 34 checks passed
@rombirli
rombirli deleted the rombirli/implement-ternary-negated-condition branch October 21, 2026 08:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants