Skip to content

feat(lint): add UncheckedFlagAccess, ExpiredFeatureFlag, and InvalidFlagReference detectors#176

Merged
kirich1409 merged 3 commits intomainfrom
feat/lint-invalid-flag-reference
Apr 29, 2026
Merged

feat(lint): add UncheckedFlagAccess, ExpiredFeatureFlag, and InvalidFlagReference detectors#176
kirich1409 merged 3 commits intomainfrom
feat/lint-invalid-flag-reference

Conversation

@kirich1409
Copy link
Copy Markdown
Contributor

@kirich1409 kirich1409 commented Apr 29, 2026

Adds three Android Lint detectors to featured-lint-rules.

Closes #157
Closes #158
Closes #159

Changes

UncheckedFlagAccessDetector

UAST scanner for UCallExpression. Resolves @BehindFlag via PSI (SOURCE retention workaround). Walks the UAST parent chain for guard contexts: if/when referencing the flag by name, or an enclosing @BehindFlag-annotated function. v1 scope: direct calls only — callable references, companion scope escape, and @AssumesFlag deferred.

ExpiredFeatureFlagDetector

Visits @ExpiresAt annotations on ConfigParam properties. Parses the ISO-8601 date and reports if it is in the past. Deduplicates via visitedSourceElements to avoid double-firing from @Target(PROPERTY, FIELD).

InvalidFlagReferenceDetector

File-level UAST scanner. Collects ConfigParam property names in the file, then validates @BehindFlag/@AssumesFlag flagName arguments against them. Skips files with no ConfigParam declarations to avoid false positives on generated code.

Tests

27/27 tests pass (positive + negative cases for each detector).

Detects @BehindFlag/@AssumesFlag annotations whose flagName does not
match any ConfigParam property in the same file. Skips files with no
ConfigParam declarations to avoid false positives from generated code.

Also fixes pre-existing compile errors in ExpiredFeatureFlagDetector
and UncheckedFlagAccessDetector (ambiguous overload, missing uastContents
API) and adds their test files that were present but never committed.
@qodo-code-review
Copy link
Copy Markdown

ⓘ You've reached your Qodo monthly free-tier limit. Reviews pause until next month — upgrade your plan to continue now, or link your paid account if you already have one.

Detects ConfigParam properties annotated with @ExpiresAt where the date
has passed. Rewrites the previous broken implementation to use
getApplicableUastTypes + visitAnnotation, which avoids the duplicate-fire
issue caused by Kotlin @target(PROPERTY, FIELD) generating two UAST
annotation nodes from the same KtAnnotationEntry. Deduplicates remaining
visits via sourcePsi identity tracking within the file handler.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@kirich1409 kirich1409 changed the title feat(lint): add InvalidFlagReference detector (#159) feat(lint): add InvalidFlagReference and ExpiredFeatureFlag detectors (#159, #158) Apr 29, 2026
@kirich1409 kirich1409 changed the title feat(lint): add InvalidFlagReference and ExpiredFeatureFlag detectors (#159, #158) feat(lint): add UncheckedFlagAccess, ExpiredFeatureFlag, and InvalidFlagReference detectors Apr 29, 2026
@kirich1409 kirich1409 merged commit 8979f24 into main Apr 29, 2026
7 of 8 checks passed
@kirich1409 kirich1409 deleted the feat/lint-invalid-flag-reference branch April 29, 2026 20:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant