SONARJAVA-6757: Fix FP in S9149 for intentional hiding with deprecation annotations - #5924
SONARJAVA-6757: Fix FP in S9149 for intentional hiding with deprecation annotations#5924romainbrenguier wants to merge 3 commits into
Conversation
…n annotations Skip reporting when the hiding method is annotated with @deprecated or @DonotCall, as these indicate deliberate API design patterns (preventing misuse, guiding migration, enforcing type constraints). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
| private static boolean isIntentionalHiding(Symbol.MethodSymbol methodSymbol) { | ||
| return methodSymbol.metadata().isAnnotatedWith("java.lang.Deprecated") | ||
| || methodSymbol.metadata().isAnnotatedWith("com.google.errorprone.annotations.DoNotCall"); | ||
| } |
There was a problem hiding this comment.
💡 Edge Case: @deprecated blanket-suppresses S9149, risking false negatives
isIntentionalHiding treats any @deprecated hiding method as intentional. @deprecated is applied for many reasons unrelated to method hiding (e.g. a method scheduled for removal that accidentally hides a parent static method), so this may suppress genuinely accidental hiding that developers still want flagged. This is a reasonable tradeoff to remove the Guava FPs, but consider whether @DonotCall alone (a much more specific signal) would suffice, or document this broadening in the rule metadata so users understand deprecated methods are now exempt.
Was this helpful? React with 👍 / 👎
|
❌ Ruling needs updating. A fix PR has been created: #5926 Please review and merge it into your branch. |
Ruling Diff SummaryDetected changes in 1 rule files: 23 issues removed, 0 issues added. S9149 (
|
| } | ||
|
|
||
| private static boolean isIntentionalHiding(Symbol.MethodSymbol methodSymbol) { | ||
| return methodSymbol.metadata().isAnnotatedWith("java.lang.Deprecated") |
There was a problem hiding this comment.
It could be worth considering additional common decorators with similar meaning:
com.google.errorprone.annotations.InlineMeorg.jetbrains.annotations.ApiStatus.Obsoleteorg.jetbrains.annotations.ApiStatus.ScheduledForRemovalkotlin.Deprecated
Also, have you considered updating the RSPEC to document these exceptions?
There was a problem hiding this comment.
Good suggestion! I've added all four annotations to isIntentionalHiding:
com.google.errorprone.annotations.InlineMeorg.jetbrains.annotations.ApiStatus.Obsoleteorg.jetbrains.annotations.ApiStatus.ScheduledForRemovalkotlin.Deprecated
Test cases have been added for InlineMe, ApiStatus.Obsolete, and ApiStatus.ScheduledForRemoval. The kotlin.Deprecated annotation can't be used from Java source code (it requires Kotlin-specific parameter types), but it's kept in the implementation to handle Kotlin-compiled bytecode from binary dependencies.
I also bumped the JetBrains annotations dependency from 13.0 to 24.0.1 in the test sources to get the ApiStatus annotations.
…tion Add InlineMe, ApiStatus.Obsolete, ApiStatus.ScheduledForRemoval, and kotlin.Deprecated as additional signals for intentional static method hiding, as suggested in code review. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Code Review 👍 Approved with suggestions 0 resolved / 1 findingsUpdates S9149 static method hiding detection to skip methods annotated with 💡 Edge Case:
|
| Auto-apply | Compact |
|
|
Was this helpful? React with 👍 / 👎 | Gitar
|




Summary
@Deprecatedor@DoNotCall, as these indicate deliberate API design patterns rather than accidental hidingImmutableBiMap,ImmutableSortedSet, and similar classesTest plan
@Deprecatedannotated hiding methods@DoNotCallannotated hiding methods@Deprecated+@DoNotCallStaticMethodHidingCheckTest)🤖 Generated with Claude Code