JS-1487 Fix FP in S125: suppress commented code with TODO/FIXME task markers#6648
Conversation
Tests cover the scenario where commented-out code is accompanied by a task marker (TODO, FIXME, HACK, XXX, NOTE) on a non-code line within the same comment group. The tests verify that each marker keyword suppresses the issue, and that marker keywords used as JavaScript identifiers inside commented code (e.g. const NOTE = 'padding') do not suppress the issue. Relates to JS-1487
S125 incorrectly flagged commented-out code that was accompanied by task markers (TODO, FIXME, HACK, XXX, NOTE), which indicate the code is intentionally deferred rather than forgotten dead code. The fix adds a per-line task marker check using the existing containsCode() and injectMissingBraces() helpers. A comment group is suppressed only when at least one line matches TASK_MARKER_PATTERN and that line is not itself parsable as code — avoiding false suppression when keywords like NOTE or TODO appear as JavaScript identifiers inside commented-out code (e.g., `// const NOTE = 'padding';`). Implementation follows the approved proposal algorithm from proposed-approach-20260319-150304.md. Relates to JS-1487
Ruling analysis over 383 entries confirmed the implementation is correct: all 379 genuine commented-out code cases raise as expected, and the 4 cases with TODO/FIXME markers in the same comment group are correctly suppressed. Added 3 new test cases derived from ruling patterns: - @todo prefix (e.g. // @todo: ...) is recognized as a task marker and suppresses the issue, same as TODO - Doubly-nested TODO comment (// // TODO: ...) is still recognized as a task marker via the per-line check - Task marker in an adjacent but separate comment group (blank line separator) does NOT suppress the commented code in the other group, demonstrating the per-group scoping of task marker detection
Ruling ReportCode no longer flagged (4 issues)S125Ghost/core/test/functional/client/content_test.js:70 68 | casper.waitForSelector('#entry-title');
69 |
> 70 | // // TODO readd this test when #3811 is fixed
71 | // // Change post to static page
72 | // casper.thenClick('.post-settings');Ghost/core/test/unit/permissions_spec.js:323 321 | // .then(function (updatedUser) {
322 |
> 323 | // // TODO: Verify updatedUser.related('permissions') has the permission?
324 | // var canThisResult = permissions.canThis(updatedUser.id);
325 | eigen/src/app/Scenes/MyCollection/Screens/ArtworkForm/Form/useArtworkForm.tests.tsx:5 3 | })
4 |
> 5 | /*
6 | // TODO: Reenable once we figure out circular dep issue involving GlobalStore
7 | postgraphql/src/postgres/inventory/collection/tests/PgCollection-test.js:107 105 | }))
106 |
> 107 | // TODO: reimplement
108 | // test('paginator will have the same name and type', () => {
109 | // expect(collection1.paginator.name).toBe(collection1.name) |
Fix two external SonarQube issues (S1134, S1135) in the JSDoc comment for hasTaskMarker() in rule.ts. The comment listed "TODO, FIXME, HACK, XXX, NOTE" as examples, which caused SonarQube to flag the word "TODO" as an unresolved action item. The fix rewrites the comment to reference the TASK_MARKER_PATTERN constant instead of enumerating the keywords, removing the false positive without changing any runtime behavior.
SummaryS125 rule now suppresses false positives on commented-out code that includes task markers (TODO, FIXME, HACK, XXX, NOTE). The implementation adds a per-line check to detect task markers only on non-code lines, avoiding false suppressions when these keywords appear as JavaScript identifiers within commented code itself. Comment group boundaries (blank lines) are respected, ensuring markers in one group don't suppress issues in a separate group. Ruling analysis confirms 4 false positives fixed with no impact on legitimate detections. What reviewers should knowStart with the hasTaskMarker() function (rule.ts:125-133) — the core logic splits each comment group by lines and checks both that the line contains a task marker AND that the line itself doesn't contain code. This dual check is what prevents false suppressions. Key nuance: the condition at line 101 gates on Test coverage is thorough. The valid cases test all five marker types plus Ruling removals show the fix in action: 4 previous false positives (lines 70, 323, 107 across three projects) are gone. The rspec description update explains the exception to end-users.
|
|
Thanks for the summary — the description accurately captures the implementation. No action needed on my end. |
…ules/S125/rule.ts Comment: The `/i` flag is too broad for `NOTE` (and to a lesser extent `HACK`). Both are common English prose words. A comment block like: ``` // Note that we disabled this temporarily. // const x = processVector(name, type); ``` will match `\bNote\b` (case-insensitive), `containsCode` returns false for the first line, so `hasTaskMarker` returns `true` and the genuine commented-out code is silently suppressed. `TODO`, `FIXME`, and `XXX` are almost never used as natural English prose in comments, so `/i` is low-risk for those. `NOTE` is different — it appears constantly in developer prose (`// Note that...`, `// Note:`, `// NOTE:` are all equivalent under `/i`). Remove the `/i` flag and match uppercase only, which is the de-facto convention for all five task markers. The `@TODO` test case still passes because `\b` matches before the `T` in `@TODO`. If lowercase support is truly needed, enumerate the exact mixed-case forms you want rather than accepting all cases. - [ ] Mark as noise
|
Fixed in the latest commit. The |
|




S125 was incorrectly raising issues on commented-out code that was accompanied by task markers (TODO, FIXME, HACK, XXX, NOTE), which indicate the code is intentionally deferred rather than forgotten dead code.
Changes
NOTE,TODO) appear as JavaScript identifiers inside commented-out code (e.g.// const NOTE = 'padding')@TODOprefix and doubly-nested task markers (e.g.// // TODO: ...)Validation
Ruling analysis over 383 entries confirmed correctness: all 379 genuine commented-out code cases raise as expected, and the 4 cases with TODO/FIXME markers in the same comment group are correctly suppressed.
Relates to JS-1487
Proposed rspec changes