Repository: eslint/eslint
File: lib/linter/code-path-analysis/code-path.js (JavaScript)

Code before:
            if (index === 0) {

                // Skip if this segment has been visited already.
                if (visited.has(segment)) {
                    stack.pop();
                    continue;
                }

                // Skip if all previous segments have not been visited.
                if (segment !== startSegment &&
                    segment.prevSegments.length > 0 &&
                    !segment.prevSegments.every(isVisited)
                ) {
                    stack.pop();
                    continue;
                }

                visited.add(segment);


                // Skips the segment if itself or all previous segments have been skipped.
                const skip = skipped.has(segment) ||
                    (
                        skipped.size > 0 &&
                        segment.prevSegments.length > 0 &&
                        segment.prevSegments.every(prevSegment => skipped.has(prevSegment))
                    );

                /*
                 * If the most recent segment hasn't been skipped, then we call
                 * the callback, passing in the segment and the controller.
                 */
                if (!skip) {
                    resolvedCallback.call(this, segment, controller);

                    // exit if we're at the last segment
                    if (segment === lastSegment) {
                        controller.skip();
                    }

                    /*
                     * If the previous statement was executed, or if the callback
                     * called a method on the controller, we might need to exit the
                     * loop, so check for that and break accordingly.
                     */
                    if (broken) {
                        break;
                    }
                } else {

                    // If the most recent segment has been skipped, then mark it as skipped.

Review comment (suggestion):
I'm not sure if this logic works well when there are loops afterwards. For example:

```js
const codePath = parseCodePaths("a; while (b) { c; }")[0];
const order = getOrderOfTraversing(codePath, null, (segment, controller) => {
    if (segment.id === "s1_1") {
        controller.skip();
    }
});

assert.deepStrictEqual(order, ["s1_1"]); // actual result is ["s1_1", "s1_2", "s1_3", "s1_4"] but it should be just ["s1_1"]?
```

Code after:
                // Skip if this segment has been visited already.
                if (visited.has(segment)) {
                    stack.pop();
                    continue;
                }

                // Skip if all previous segments have not been visited.
                if (segment !== startSegment &&
                    segment.prevSegments.length > 0 &&
                    !segment.prevSegments.every(isVisited)
                ) {
                    stack.pop();
                    continue;
                }

                visited.add(segment);


                // Skips the segment if all previous segments have been skipped.
                const shouldSkip = (
                    skipped.size > 0 &&
                    segment.prevSegments.length > 0 &&
                    segment.prevSegments.every(isSkipped)
                );

                /*
                 * If the most recent segment hasn't been skipped, then we call
                 * the callback, passing in the segment and the controller.
                 */
                if (!shouldSkip) {
                    resolvedCallback.call(this, segment, controller);

                    // exit if we're at the last segment
                    if (segment === lastSegment) {
                        controller.skip();
                    }

                    /*
                     * If the previous statement was executed, or if the callback
                     * called a method on the controller, we might need to exit the
                     * loop, so check for that and break accordingly.
                     */
                    if (broken) {
                        break;
                    }
                } else {

                    // If the most recent segment has been skipped, then mark it as skipped.
                    skipped.add(segment);
                }
            }