Add test for @SuppressWarnings and @AnnotatedFor interaction and refine SourceChecker logic#1699
Add test for @SuppressWarnings and @AnnotatedFor interaction and refine SourceChecker logic#1699aosen-xiong wants to merge 7 commits into
@SuppressWarnings and @AnnotatedFor interaction and refine SourceChecker logic#1699Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes warning suppression behavior in SourceChecker so an enclosing @SuppressWarnings still applies when an inner declaration is marked @AnnotatedFor. It also adds regression tests in both framework-level subtyping tests and nullness conservative-default tests.
Changes:
- Removed the redundant early return in
SourceChecker.shouldSuppressWarnings(Element, String)so suppression lookup continues through enclosing elements. - Added a subtyping regression test covering class-level
@SuppressWarningswith a method-level@AnnotatedFor. - Added a nullness regression test covering the same interaction for nullness checking.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
framework/tests/conservative-defaults/annotatedfor/AnnotatedForTest.java |
Adds a regression case proving outer @SuppressWarnings("subtyping") overrides inner @AnnotatedFor("subtyping"). |
framework/src/main/java/org/checkerframework/framework/source/SourceChecker.java |
Removes the early exit that prevented suppression lookup from reaching enclosing scopes. |
checker/tests/nulless-conservative-defaults/annotatedfornullness/AnnotatedForNullness.java |
Adds a nullness regression case for the same suppression/@AnnotatedFor interaction. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
thisisalexandercook
left a comment
There was a problem hiding this comment.
Great catch! It may be worth noting that #1331 also removes this check as part of its broader refactor, but this bug is independent and makes sense as its own PR.
Co-authored-by: Alex Cook <43047600+thisisalexandercook@users.noreply.github.com>
Thanks! Yes, that's the point of having this PR. |
wmdietl
left a comment
There was a problem hiding this comment.
Thanks for looking into this!
Also, please go through the javadoc and manual and see where this behavior is described.
| return true; | ||
| } | ||
| } | ||
| if (isAnnotatedForThisCheckerOrUpstreamChecker(elt)) { |
There was a problem hiding this comment.
The public boolean shouldSuppressWarnings(TreePath path, String errKey) overload still has this logic in it, twice.
Should that version continue to check for this condition?
I would expect that we need to find two things:
- what is the nearest SuppressWarnings?
- what is the nearest AnnotatedFor or UnannotatedFor?
Once we found an AnnotatedFor or UnannotatedFor, we can stop looking for the other as well, but we do need to continue looking for a SuppressWarnings, and the other way around.
Can you look through the other overload and write a test case that triggers that version?
There was a problem hiding this comment.
The
public boolean shouldSuppressWarnings(TreePath path, String errKey)overload still has this logic in it, twice.
Updated. The TreePath overload no longer returns immediately when it sees an applicable @AnnotatedFor.
I would expect that we need to find two things:
- what is the nearest SuppressWarnings?
- what is the nearest AnnotatedFor or UnannotatedFor?
The new logic does that by tracking whether an applicable @AnnotatedFor was found, while continuing to walk enclosing declarations for a matching @SuppressWarnings. If it finds a matching suppression, it returns true; if it found @AnnotatedFor but no suppression, it returns false.
Also, please go through the javadoc and manual and see where this behavior is described.
I updated the relevant manual sections to state that diagnostics in an @AnnotatedFor scope can still be suppressed by an in-scope @SuppressWarnings.
Fix
@SuppressWarningson an enclosing element being ignored when an inner element carries@AnnotatedFor.The early return was redundant: the loop's natural termination already produces false when no matching
@SuppressWarningsis found. Removing it lets the walk continue past @AnnotatedFor-annotated elements to enclosing scopes.