SONARJAVA-6976 Clear check state after file analysis - #6144
romainbrenguier wants to merge 16 commits into
Conversation
This comment has been minimized.
This comment has been minimized.
|
❌ Ruling needs updating. A fix PR has been created: #6145 Please review and merge it into your branch. |
|
❌ Ruling needs updating. A fix PR has been created: #6145 Please review and merge it into your branch. |
Ruling Diff SummaryDetected changes in 5 rule files: 0 issues removed, 75 issues added. S1166 (
|
✅ All code review findings resolved.
|
❌ Ruling needs updating. A fix PR has been created: #6149 Please review and merge it into your branch. |
aurelien-coet-sonarsource
left a comment
There was a problem hiding this comment.
Maybe we could also document somewhere (e.g. in .claude/commands/project-level-rules.md) that checks which use collections to store some state should override clearState to clear it between files ?
| public void leaveFile(JavaFileScannerContext context) { | ||
| // Explicitly declares the method to make it appears in the IssuableSubscriptionVisitor's members. | ||
| // Default behaviour is to do nothing | ||
| clearState(); | ||
| } |
There was a problem hiding this comment.
If a class overrides leaveFile and doesn't call super.leaveFile(context) or clearState(), then the state will not be cleared, even if clearState is overriden to do so.
Furthermore, leaveFile is called inside a try .. catch block in VisitorsBridge.scanFile, after calling other methods that could throw, so if they do, then leaveFile is never called and the state is never cleared.
It may make more sense to directly call clearState on every visitor in the finally block inside VisitorsBridge.scanFile. WDYT ?
This comment is outdated. The PR should not update ruling results. |
|
aurelien-coet-sonarsource
left a comment
There was a problem hiding this comment.
Two comments are still unaddressed.
|
This PR is stale because it has been open 7 days with no activity. If there is no activity in the next 7 days it will be closed automatically |
…lived processes Move cache clearing (ifStatementCache, firstNullCheckCache, safeSymbols) from the start of scanFile to a finally block, so the last scanned file's AST is not retained for the lifetime of the plugin classloader in IDE sessions (SonarLint). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove no-op pre-clear guards before reassignment in NestedIfStatementsCheck and TypeParametersShadowingCheck - Revert unnecessary mutable copy in DepthOfInheritanceTreeCheck (filteredPatterns is a property cache, not AST state) - Fix indentation in ClassImportCouplingCheck finally block - Fix MissingPackageInfoCheckTest: remove assertion on internal state that is now properly cleared in endOfAnalysis Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ghten test - RedundantTypeCastCheck: set warnings = null instead of calling .clear() on the unmodifiable list, which threw UnsupportedOperationException - ClassImportCouplingCheck: remove redundant guarded cleanup blocks that can never execute; simplify to try/finally with null assignments - CheckStateCleanupTest: fix isPropertyCache returning true on empty stream (allMatch vacuous truth) by requiring non-empty value types Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…6 ruling Add a protected clearState() hook to IssuableSubscriptionVisitor, called automatically from setContext() before each file analysis. Checks that need to clear per-file state now simply override clearState() instead of duplicating the setContext/leaveFile boilerplate in every file. This eliminates ~210 lines of duplicated code across 14 checks. Also reverts the S1166 ruling file updates that were based on the bug where exceptions/exceptionIdentifiers were incorrectly cleared. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…dant override - Add clearState() call in IssuableSubscriptionVisitor.leaveFile() so state is released after the last file analysis, not just before the next one - Remove redundant setContext() override in UnusedPrivateFieldCheck since the base class already calls clearState() in setContext() - Remove unused JavaFileScannerContext import in UnreachableCatchCheck (SQ QG) - Relax ArchUnit test to accept field cleared by any lifecycle method, since clearState() is called from both setContext() and leaveFile() Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ontext/leaveFile Address review feedback: override clearState() in StaticFieldInitializationCheck, CookieHttpOnlyCheck, SecureCookieCheck, DateEnumsCheck, HardcodedURICheck, and WaitInWhileLoopCheck instead of duplicating cleanup logic in setContext/leaveFile. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…inal Add a "Per-File State Cleanup" section to CLAUDE.md explaining how rules should clear mutable state between files: via clearState() for IssuableSubscriptionVisitor, or in scanFile()'s finally block for BaseTreeVisitor/JavaFileScanner. Also make CatchUsesExceptionWithContextCheck's excludedCatchTrees field final to reflect it is never reassigned. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
df392b1 to
4a2a223
Compare
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Code Review ✅ Approved 14 closed / 14 findings🟡 Medium risk · Visitor lifecycle now clears mutable check state before and after file analysis Refactors check state management to guarantee cleanup at file analysis boundaries, addressing state carryover issues (S1166 exclusion list wiped, S6539 imports not recomputed, S120 project accumulator retained across files). Introduces ✅ 14 closed✅ Bug: S1166: exclusion list wiped after first file (false positives)
✅ Bug: S6539: imports never recomputed after first file
✅ Bug: S120: project-level accumulator cleared at start of each file
✅ Quality: CheckStateCleanupTest does not enforce what it claims
✅ Performance: IndentationCheck copies all file lines just to clear them
...and 9 more closed from earlier reviews Review coverage🧪 Functional validation No results 📋 Rules No rules evaluated 🤖 Auto-approval Not enabled · Set up 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 |
|
| try { | ||
| forEach(subscriptionVisitors, visitor -> { | ||
| if (visitor instanceof IssuableSubscriptionVisitor issuableVisitor) { | ||
| issuableVisitor.clearStateAfterFile(); | ||
| } | ||
| }); |
There was a problem hiding this comment.
Here, if any of the visitors throws an exception while clearing its state, any other visitor that hasn't cleared it yet will be skipped and its state won't be cleaned up.
Maybe it would be better to catch exceptions inside the for loop and log them, but still iterate over the remaining checks without interruptions to guarantee cleanup. WDYT ?
| @Override | ||
| public void leaveFile(JavaFileScannerContext context) { | ||
| /** Releases per-file state after analysis, independently of the leaveFile lifecycle callback. */ | ||
| public final void clearStateAfterFile() { |
There was a problem hiding this comment.
Why is this method needed ? Couldn't we directly call visitor.clearState ?






Summary
Validation
Agent workflow
Addressed review comments in pr_report_6144.md using
uv run address_reviews.py pr_report_6144.mdPR updated using
uv run update_with_claude.py --prompt "Implement the action plan described in the document [MAJOR] Refactor the code of the lambda to have only one invocation possibly throwing a runtime exception. (component: java-frontend/src/test/java/org/sonar/java/model/VisitorsBridgeTest.java, line: 187)." -a "[MAJOR] Refactor the code of the lambda to have only one invocation possibly throwing a runtime exception. (component: java-frontend/src/test/java/org/sonar/java/model/VisitorsBridgeTest.java, line: 187)" -g "claude"