From 969b77b53d488a7bd4381beac55256bb8b2cceda Mon Sep 17 00:00:00 2001 From: RebeccaStevens Date: Thu, 11 Jul 2024 07:26:01 +0000 Subject: [PATCH] fix(no-conditional-statements): allow continue and break statements with labels to be considered "returning" (#846) Handle labeled break statements and continue statements in switch cases in the no-conditional-statements rule. --- src/rules/no-conditional-statements.ts | 31 ++++++++++++++++---------- src/utils/type-guards.ts | 6 +++++ 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/rules/no-conditional-statements.ts b/src/rules/no-conditional-statements.ts index 57c436b88..1bdfdb83a 100644 --- a/src/rules/no-conditional-statements.ts +++ b/src/rules/no-conditional-statements.ts @@ -17,6 +17,7 @@ import { isContinueStatement, isExpressionStatement, isIfStatement, + isLabeledStatement, isReturnStatement, isSwitchStatement, isThrowStatement, @@ -195,18 +196,6 @@ function getIfBranchViolations( return violations.flatMap(incompleteBranchViolation); } -/** - * Is the given statement, when inside a switch statement, a returning branch? - */ -function isSwitchReturningBranch(statement: TSESTree.Statement) { - return ( - // Another instance of this rule will check nested switch statements. - isSwitchStatement(statement) || - isReturnStatement(statement) || - isThrowStatement(statement) - ); -} - /** * Get all of the violations in the given switch statement assuming switch * statements are allowed. @@ -217,6 +206,8 @@ function getSwitchViolations( ): RuleResult["descriptors"] { const isNeverExpressions = getIsNeverExpressions(context); + const label = isLabeledStatement(node.parent) ? node.parent.label.name : null; + const violations = node.cases.filter((branch) => { if (branch.consequent.length === 0) { return false; @@ -241,6 +232,22 @@ function getSwitchViolations( }); return violations.flatMap(incompleteBranchViolation); + + /** + * Is the given statement, when inside a switch statement, a returning branch? + */ + function isSwitchReturningBranch(statement: TSESTree.Statement) { + return ( + // Another instance of this rule will check nested switch statements. + isSwitchStatement(statement) || + isReturnStatement(statement) || + isThrowStatement(statement) || + (isBreakStatement(statement) && + statement.label !== null && + statement.label.name !== label) || + isContinueStatement(statement) + ); + } } /** diff --git a/src/utils/type-guards.ts b/src/utils/type-guards.ts index 507dc55df..87af3b85e 100644 --- a/src/utils/type-guards.ts +++ b/src/utils/type-guards.ts @@ -157,6 +157,12 @@ export function isIfStatement( return node.type === AST_NODE_TYPES.IfStatement; } +export function isLabeledStatement( + node: TSESTree.Node, +): node is TSESTree.LabeledStatement { + return node.type === AST_NODE_TYPES.LabeledStatement; +} + export function isMemberExpression( node: TSESTree.Node, ): node is TSESTree.MemberExpression {