UNPKG

eslint-plugin-complete

Version:

An ESLint plugin that contains useful rules.

77 lines (76 loc) 2.73 kB
// This rule is mostly copied from the `no-fallthrough` ESLint core rule: // https://github.com/eslint/eslint/blob/main/lib/rules/no-fallthrough.js import { createRule } from "../utils.js"; export const requireBreak = createRule({ name: "require-break", meta: { type: "layout", docs: { description: "Requires that each case of a switch statement has a `break` statement", recommended: true, requiresTypeChecking: false, }, schema: [], messages: { noBreak: "Expected a 'break' statement.", }, }, defaultOptions: [], create(context) { const codePathSegments = []; let currentCodePathSegments = new Set(); return { onCodePathStart() { codePathSegments.push(currentCodePathSegments); currentCodePathSegments = new Set(); }, onCodePathEnd() { const codePathSegmentsSet = codePathSegments.pop(); if (codePathSegmentsSet !== undefined) { currentCodePathSegments = codePathSegmentsSet; } }, onUnreachableCodePathSegmentStart(segment) { currentCodePathSegments.add(segment); }, onUnreachableCodePathSegmentEnd(segment) { currentCodePathSegments.delete(segment); }, onCodePathSegmentStart(segment) { currentCodePathSegments.add(segment); }, onCodePathSegmentEnd(segment) { currentCodePathSegments.delete(segment); }, "SwitchCase:exit"(node) { /* * `reachable` means fallthrough because statements preceded by * `break`, `return`, or `throw` are unreachable. * And allows empty cases and the last case. */ const thisNodeIsReachable = isAnySegmentReachable(currentCodePathSegments); const thisNodeIsFinalCase = node === node.parent.cases.at(-1); if (thisNodeIsReachable && thisNodeIsFinalCase) { context.report({ messageId: "noBreak", node, }); } }, }; }, }); /** * Checks all segments in a set and returns true if any are reachable. * * @param segments The segments to check. * @returns True if any segment is reachable; false otherwise. */ function isAnySegmentReachable(segments) { for (const segment of segments) { if (segment.reachable) { return true; } } return false; }