feat: check sequence expressions in for-direction#20701
Conversation
✅ Deploy Preview for docs-eslint canceled.
|
c42027a to
6c766be
Compare
…b.com/Kuldeep2822k/eslint into fix/for-direction-sequence-expression
|
Thanks for the submission. Can you please update the description with the same fields we have in our bug report template? Thanks. |
Thanks for mentioning the template i have updated the pr description to include the templete please review it |
|
I believe this fix addresses #20410, but it’s assigned to someone else. And please double-check the PR template. It seems a malformed code block is still breaking the template. |
To clarify — PR #20701 addresses SequenceExpression support in the update clause, not the statically-false condition case described in the issue. |
This pr is not related to #20410 This PR addresses a completely different scenario where the update clause is a
Please create a separate issue to track this case - There can be multiple cases case 2: Three values separated by comma case 3: for(var i = 10; i < 20; i--, i++) {} - different directions Scenario 1: Condition: i < 20 → always true result in infinite loop. Scenario 2: Condition: i < 20 → runs from 10 to 19 and stops when i becomes 20 Normal loop (not infinite) Ideally if the counter appears more than once in the sequence, treat direction as unknown and we should skip i guess. |
| ? update.expressions.some( | ||
| expr => | ||
| getDirectionFromExpression( | ||
| expr, | ||
| counter, | ||
| ) === wrongDirection, | ||
| ) |
There was a problem hiding this comment.
@Kuldeep2822k The issue has been accepted, feel free to continue your work on this PR.
If the counter appears in more than one expression within the sequence, treat direction as unknown and skip. Only report when exactly one expression in the sequence modifies the counter in the wrong direction.
We need to make sure of this proposed behavior and add the corresponding test case.
When a SequenceExpression update has the counter modified in more than one sub-expression, treat direction as unknown and skip. Only report when exactly one expression in the sequence modifies the counter in the wrong direction. Refs eslint#20726
|
Did the changes as described in the issue |
|
Lines 164–182 in if (update.type === "SequenceExpression") {
const counterExpressions = update.expressions.filter(
expr => getDirectionFromExpression(expr, counter) !== 0,
);
if (
counterExpressions.length === 1 &&
getDirectionFromExpression(counterExpressions[0], counter) === wrongDirection
) {
report(node);
}
}This uses The corresponding test cases are already in place: Valid (counter modified multiple times → direction unknown, skip): "for(var i = 10; i < 20; (i--, i++)){}"
"for(var i = 10; i < 20; (i--, i += 2)){}"
"for(var i = 0; i < 10; (i++, i--)){}"
"for(var i = 0; i < 10; (i-=1, i+=2)){}"Invalid (exactly one expression moves counter in wrong direction): "for(var i = 0; i < 10; (i--, j++)){}"
"for(var i = 10; i > 0; (i++, j--)){}"
"for(var i = 0; i < 10; (i-=1, j++)){}"
// ...and moreLet me know if any additional test cases or changes are needed! |
There was a problem hiding this comment.
Pull request overview
Fixes for-direction false negatives when the for loop update clause is a SequenceExpression (comma operator), ensuring the rule evaluates counter-direction changes inside comma-separated updates.
Changes:
- Add
getDirectionFromExpression()helper to unify direction detection for update vs assignment expressions. - Extend
for-directionto handleSequenceExpressionupdates by analyzing its sub-expressions. - Add RuleTester coverage for
SequenceExpressionupdates in both valid and invalid cases.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
lib/rules/for-direction.js |
Adds SequenceExpression handling and a shared direction helper to detect wrong-direction counter updates inside comma operator updates. |
tests/lib/rules/for-direction.js |
Adds new valid/invalid cases covering comma operator updates in for loop update clauses. |
|
Before procceding with fixing all found issue i want a member confirmation to proceed |
|
I think this copilot review was trigger by me by mistake |
for-direction
…nt RHS in for-direction
Applied this change as requested by @mdjermanovic. I've updated the implementation to introduce a getMutatingExpressions helper that safely extracts all expressions modifying the counter. This successfully separates the check for "does it modify the counter?" from "what is its direction?". It now perfectly handles indeterminate assignments (like i += STEP_SIZE) as well as flattened nested SequenceExpressions. I also added tests to verify these edge cases are properly skipped without throwing false positive reports. |
mdjermanovic
left a comment
There was a problem hiding this comment.
LGTM, thanks! Leaving open for a second review.
Prerequisites checklist
AI acknowledgment
What is the purpose of this pull request? (put an "X" next to an item)
Tell us about your environment (
npx eslint --env-info):What parser are you using (place an "X" next to just one item)?
Default (Espree)@typescript-eslint/parser@babel/eslint-parservue-eslint-parser@angular-eslint/template-parserOtherPlease show your full configuration:
Configuration
What did you do? Please include the actual source code causing the issue.
The
for-directionrule was silently ignoring the update clause when it was aSequenceExpression(comma operator). It returned0(no direction detected) for the entire update, causing a false negative — no error was reported even though one of the comma-separated expressions moved the counter in the wrong direction.What did you expect to happen?
What actually happened? Please include the actual, raw output from ESLint.
No output. The rule passed silently without reporting an error.
What changes did you make? (Give an overview)
getDirectionFromExpressionhelper that dispatches togetUpdateDirectionorgetAssignmentDirectionbased on expression type.getModifyingExpressionshelper that recursively collects all sub-expressions in aSequenceExpressionthat modify the counter variable (i.e.,UpdateExpressionorAssignmentExpressiontargeting the counter).node.updateis aSequenceExpression, the rule collects all sub-expressions that modify the counter. If exactly one sub-expression modifies the counter and it moves in the wrong direction, the loop is reported. If multiple sub-expressions modify the counter, the rule skips reporting because the net direction is ambiguous.Is there anything you'd like reviewers to focus on?
The
counterExpressions.length === 1guard — the rule only reports when exactly one sub-expression in the sequence modifies the counter. When multiple sub-expressions modify the counter (e.g.,(i--, i += 2)), the net direction is ambiguous, so the rule intentionally skips those cases.