diff --git a/crates/oxc_linter/src/generated/rule_runner_impls.rs b/crates/oxc_linter/src/generated/rule_runner_impls.rs index bba17a7ccf685..46f22d0759336 100644 --- a/crates/oxc_linter/src/generated/rule_runner_impls.rs +++ b/crates/oxc_linter/src/generated/rule_runner_impls.rs @@ -3550,6 +3550,12 @@ impl RuleRunner for crate::rules::unicorn::switch_case_braces::SwitchCaseBraces const RUN_FUNCTIONS: RuleRunFunctionsImplemented = RuleRunFunctionsImplemented::Run; } +impl RuleRunner for crate::rules::unicorn::switch_case_break_position::SwitchCaseBreakPosition { + const NODE_TYPES: Option<&AstTypesBitset> = + Some(&AstTypesBitset::from_types(&[AstType::SwitchCase])); + const RUN_FUNCTIONS: RuleRunFunctionsImplemented = RuleRunFunctionsImplemented::Run; +} + impl RuleRunner for crate::rules::unicorn::text_encoding_identifier_case::TextEncodingIdentifierCase { diff --git a/crates/oxc_linter/src/generated/rules_enum.rs b/crates/oxc_linter/src/generated/rules_enum.rs index 302f0f2c209e3..4a55ad1ed5f67 100644 --- a/crates/oxc_linter/src/generated/rules_enum.rs +++ b/crates/oxc_linter/src/generated/rules_enum.rs @@ -676,6 +676,7 @@ pub use crate::rules::unicorn::require_module_specifiers::RequireModuleSpecifier pub use crate::rules::unicorn::require_number_to_fixed_digits_argument::RequireNumberToFixedDigitsArgument as UnicornRequireNumberToFixedDigitsArgument; pub use crate::rules::unicorn::require_post_message_target_origin::RequirePostMessageTargetOrigin as UnicornRequirePostMessageTargetOrigin; pub use crate::rules::unicorn::switch_case_braces::SwitchCaseBraces as UnicornSwitchCaseBraces; +pub use crate::rules::unicorn::switch_case_break_position::SwitchCaseBreakPosition as UnicornSwitchCaseBreakPosition; pub use crate::rules::unicorn::text_encoding_identifier_case::TextEncodingIdentifierCase as UnicornTextEncodingIdentifierCase; pub use crate::rules::unicorn::throw_new_error::ThrowNewError as UnicornThrowNewError; pub use crate::rules::vitest::consistent_each_for::ConsistentEachFor as VitestConsistentEachFor; @@ -1278,6 +1279,7 @@ pub enum RuleEnum { UnicornRequireNumberToFixedDigitsArgument(UnicornRequireNumberToFixedDigitsArgument), UnicornRequirePostMessageTargetOrigin(UnicornRequirePostMessageTargetOrigin), UnicornSwitchCaseBraces(UnicornSwitchCaseBraces), + UnicornSwitchCaseBreakPosition(UnicornSwitchCaseBreakPosition), UnicornTextEncodingIdentifierCase(UnicornTextEncodingIdentifierCase), UnicornThrowNewError(UnicornThrowNewError), JsxA11YAltText(JsxA11YAltText), @@ -2062,7 +2064,9 @@ const UNICORN_REQUIRE_NUMBER_TO_FIXED_DIGITS_ARGUMENT_ID: usize = const UNICORN_REQUIRE_POST_MESSAGE_TARGET_ORIGIN_ID: usize = UNICORN_REQUIRE_NUMBER_TO_FIXED_DIGITS_ARGUMENT_ID + 1usize; const UNICORN_SWITCH_CASE_BRACES_ID: usize = UNICORN_REQUIRE_POST_MESSAGE_TARGET_ORIGIN_ID + 1usize; -const UNICORN_TEXT_ENCODING_IDENTIFIER_CASE_ID: usize = UNICORN_SWITCH_CASE_BRACES_ID + 1usize; +const UNICORN_SWITCH_CASE_BREAK_POSITION_ID: usize = UNICORN_SWITCH_CASE_BRACES_ID + 1usize; +const UNICORN_TEXT_ENCODING_IDENTIFIER_CASE_ID: usize = + UNICORN_SWITCH_CASE_BREAK_POSITION_ID + 1usize; const UNICORN_THROW_NEW_ERROR_ID: usize = UNICORN_TEXT_ENCODING_IDENTIFIER_CASE_ID + 1usize; const JSX_A_11_Y_ALT_TEXT_ID: usize = UNICORN_THROW_NEW_ERROR_ID + 1usize; const JSX_A_11_Y_ANCHOR_AMBIGUOUS_TEXT_ID: usize = JSX_A_11_Y_ALT_TEXT_ID + 1usize; @@ -2886,6 +2890,7 @@ impl RuleEnum { UNICORN_REQUIRE_POST_MESSAGE_TARGET_ORIGIN_ID } Self::UnicornSwitchCaseBraces(_) => UNICORN_SWITCH_CASE_BRACES_ID, + Self::UnicornSwitchCaseBreakPosition(_) => UNICORN_SWITCH_CASE_BREAK_POSITION_ID, Self::UnicornTextEncodingIdentifierCase(_) => UNICORN_TEXT_ENCODING_IDENTIFIER_CASE_ID, Self::UnicornThrowNewError(_) => UNICORN_THROW_NEW_ERROR_ID, Self::JsxA11YAltText(_) => JSX_A_11_Y_ALT_TEXT_ID, @@ -3697,6 +3702,7 @@ impl RuleEnum { UnicornRequirePostMessageTargetOrigin::NAME } Self::UnicornSwitchCaseBraces(_) => UnicornSwitchCaseBraces::NAME, + Self::UnicornSwitchCaseBreakPosition(_) => UnicornSwitchCaseBreakPosition::NAME, Self::UnicornTextEncodingIdentifierCase(_) => UnicornTextEncodingIdentifierCase::NAME, Self::UnicornThrowNewError(_) => UnicornThrowNewError::NAME, Self::JsxA11YAltText(_) => JsxA11YAltText::NAME, @@ -4544,6 +4550,7 @@ impl RuleEnum { UnicornRequirePostMessageTargetOrigin::CATEGORY } Self::UnicornSwitchCaseBraces(_) => UnicornSwitchCaseBraces::CATEGORY, + Self::UnicornSwitchCaseBreakPosition(_) => UnicornSwitchCaseBreakPosition::CATEGORY, Self::UnicornTextEncodingIdentifierCase(_) => { UnicornTextEncodingIdentifierCase::CATEGORY } @@ -5366,6 +5373,7 @@ impl RuleEnum { UnicornRequirePostMessageTargetOrigin::FIX } Self::UnicornSwitchCaseBraces(_) => UnicornSwitchCaseBraces::FIX, + Self::UnicornSwitchCaseBreakPosition(_) => UnicornSwitchCaseBreakPosition::FIX, Self::UnicornTextEncodingIdentifierCase(_) => UnicornTextEncodingIdentifierCase::FIX, Self::UnicornThrowNewError(_) => UnicornThrowNewError::FIX, Self::JsxA11YAltText(_) => JsxA11YAltText::FIX, @@ -6340,6 +6348,9 @@ impl RuleEnum { UnicornRequirePostMessageTargetOrigin::documentation() } Self::UnicornSwitchCaseBraces(_) => UnicornSwitchCaseBraces::documentation(), + Self::UnicornSwitchCaseBreakPosition(_) => { + UnicornSwitchCaseBreakPosition::documentation() + } Self::UnicornTextEncodingIdentifierCase(_) => { UnicornTextEncodingIdentifierCase::documentation() } @@ -8137,6 +8148,10 @@ impl RuleEnum { } Self::UnicornSwitchCaseBraces(_) => UnicornSwitchCaseBraces::config_schema(generator) .or_else(|| UnicornSwitchCaseBraces::schema(generator)), + Self::UnicornSwitchCaseBreakPosition(_) => { + UnicornSwitchCaseBreakPosition::config_schema(generator) + .or_else(|| UnicornSwitchCaseBreakPosition::schema(generator)) + } Self::UnicornTextEncodingIdentifierCase(_) => { UnicornTextEncodingIdentifierCase::config_schema(generator) .or_else(|| UnicornTextEncodingIdentifierCase::schema(generator)) @@ -9122,6 +9137,7 @@ impl RuleEnum { Self::UnicornRequireNumberToFixedDigitsArgument(_) => "unicorn", Self::UnicornRequirePostMessageTargetOrigin(_) => "unicorn", Self::UnicornSwitchCaseBraces(_) => "unicorn", + Self::UnicornSwitchCaseBreakPosition(_) => "unicorn", Self::UnicornTextEncodingIdentifierCase(_) => "unicorn", Self::UnicornThrowNewError(_) => "unicorn", Self::JsxA11YAltText(_) => "jsx_a11y", @@ -11070,6 +11086,9 @@ impl RuleEnum { Self::UnicornSwitchCaseBraces(_) => Ok(Self::UnicornSwitchCaseBraces( UnicornSwitchCaseBraces::from_configuration(value)?, )), + Self::UnicornSwitchCaseBreakPosition(_) => Ok(Self::UnicornSwitchCaseBreakPosition( + UnicornSwitchCaseBreakPosition::from_configuration(value)?, + )), Self::UnicornTextEncodingIdentifierCase(_) => { Ok(Self::UnicornTextEncodingIdentifierCase( UnicornTextEncodingIdentifierCase::from_configuration(value)?, @@ -12119,6 +12138,7 @@ impl RuleEnum { Self::UnicornRequireNumberToFixedDigitsArgument(rule) => rule.to_configuration(), Self::UnicornRequirePostMessageTargetOrigin(rule) => rule.to_configuration(), Self::UnicornSwitchCaseBraces(rule) => rule.to_configuration(), + Self::UnicornSwitchCaseBreakPosition(rule) => rule.to_configuration(), Self::UnicornTextEncodingIdentifierCase(rule) => rule.to_configuration(), Self::UnicornThrowNewError(rule) => rule.to_configuration(), Self::JsxA11YAltText(rule) => rule.to_configuration(), @@ -12834,6 +12854,7 @@ impl RuleEnum { Self::UnicornRequireNumberToFixedDigitsArgument(rule) => rule.run(node, ctx), Self::UnicornRequirePostMessageTargetOrigin(rule) => rule.run(node, ctx), Self::UnicornSwitchCaseBraces(rule) => rule.run(node, ctx), + Self::UnicornSwitchCaseBreakPosition(rule) => rule.run(node, ctx), Self::UnicornTextEncodingIdentifierCase(rule) => rule.run(node, ctx), Self::UnicornThrowNewError(rule) => rule.run(node, ctx), Self::JsxA11YAltText(rule) => rule.run(node, ctx), @@ -13547,6 +13568,7 @@ impl RuleEnum { Self::UnicornRequireNumberToFixedDigitsArgument(rule) => rule.run_once(ctx), Self::UnicornRequirePostMessageTargetOrigin(rule) => rule.run_once(ctx), Self::UnicornSwitchCaseBraces(rule) => rule.run_once(ctx), + Self::UnicornSwitchCaseBreakPosition(rule) => rule.run_once(ctx), Self::UnicornTextEncodingIdentifierCase(rule) => rule.run_once(ctx), Self::UnicornThrowNewError(rule) => rule.run_once(ctx), Self::JsxA11YAltText(rule) => rule.run_once(ctx), @@ -14354,6 +14376,7 @@ impl RuleEnum { rule.run_on_jest_node(jest_node, ctx) } Self::UnicornSwitchCaseBraces(rule) => rule.run_on_jest_node(jest_node, ctx), + Self::UnicornSwitchCaseBreakPosition(rule) => rule.run_on_jest_node(jest_node, ctx), Self::UnicornTextEncodingIdentifierCase(rule) => rule.run_on_jest_node(jest_node, ctx), Self::UnicornThrowNewError(rule) => rule.run_on_jest_node(jest_node, ctx), Self::JsxA11YAltText(rule) => rule.run_on_jest_node(jest_node, ctx), @@ -15073,6 +15096,7 @@ impl RuleEnum { Self::UnicornRequireNumberToFixedDigitsArgument(rule) => rule.should_run(ctx), Self::UnicornRequirePostMessageTargetOrigin(rule) => rule.should_run(ctx), Self::UnicornSwitchCaseBraces(rule) => rule.should_run(ctx), + Self::UnicornSwitchCaseBreakPosition(rule) => rule.should_run(ctx), Self::UnicornTextEncodingIdentifierCase(rule) => rule.should_run(ctx), Self::UnicornThrowNewError(rule) => rule.should_run(ctx), Self::JsxA11YAltText(rule) => rule.should_run(ctx), @@ -16040,6 +16064,9 @@ impl RuleEnum { UnicornRequirePostMessageTargetOrigin::IS_TSGOLINT_RULE } Self::UnicornSwitchCaseBraces(_) => UnicornSwitchCaseBraces::IS_TSGOLINT_RULE, + Self::UnicornSwitchCaseBreakPosition(_) => { + UnicornSwitchCaseBreakPosition::IS_TSGOLINT_RULE + } Self::UnicornTextEncodingIdentifierCase(_) => { UnicornTextEncodingIdentifierCase::IS_TSGOLINT_RULE } @@ -16954,6 +16981,7 @@ impl RuleEnum { UnicornRequirePostMessageTargetOrigin::HAS_CONFIG } Self::UnicornSwitchCaseBraces(_) => UnicornSwitchCaseBraces::HAS_CONFIG, + Self::UnicornSwitchCaseBreakPosition(_) => UnicornSwitchCaseBreakPosition::HAS_CONFIG, Self::UnicornTextEncodingIdentifierCase(_) => { UnicornTextEncodingIdentifierCase::HAS_CONFIG } @@ -17687,6 +17715,7 @@ impl RuleEnum { Self::UnicornRequireNumberToFixedDigitsArgument(rule) => rule.types_info(), Self::UnicornRequirePostMessageTargetOrigin(rule) => rule.types_info(), Self::UnicornSwitchCaseBraces(rule) => rule.types_info(), + Self::UnicornSwitchCaseBreakPosition(rule) => rule.types_info(), Self::UnicornTextEncodingIdentifierCase(rule) => rule.types_info(), Self::UnicornThrowNewError(rule) => rule.types_info(), Self::JsxA11YAltText(rule) => rule.types_info(), @@ -18400,6 +18429,7 @@ impl RuleEnum { Self::UnicornRequireNumberToFixedDigitsArgument(rule) => rule.run_info(), Self::UnicornRequirePostMessageTargetOrigin(rule) => rule.run_info(), Self::UnicornSwitchCaseBraces(rule) => rule.run_info(), + Self::UnicornSwitchCaseBreakPosition(rule) => rule.run_info(), Self::UnicornTextEncodingIdentifierCase(rule) => rule.run_info(), Self::UnicornThrowNewError(rule) => rule.run_info(), Self::JsxA11YAltText(rule) => rule.run_info(), @@ -19225,6 +19255,7 @@ pub static RULES: std::sync::LazyLock> = std::sync::LazyLock::new( UnicornRequirePostMessageTargetOrigin::default(), ), RuleEnum::UnicornSwitchCaseBraces(UnicornSwitchCaseBraces::default()), + RuleEnum::UnicornSwitchCaseBreakPosition(UnicornSwitchCaseBreakPosition::default()), RuleEnum::UnicornTextEncodingIdentifierCase(UnicornTextEncodingIdentifierCase::default()), RuleEnum::UnicornThrowNewError(UnicornThrowNewError::default()), RuleEnum::JsxA11YAltText(JsxA11YAltText::default()), diff --git a/crates/oxc_linter/src/rules.rs b/crates/oxc_linter/src/rules.rs index 9c7f86740803f..76ecef3f23cd1 100644 --- a/crates/oxc_linter/src/rules.rs +++ b/crates/oxc_linter/src/rules.rs @@ -573,6 +573,7 @@ pub(crate) mod unicorn { pub mod require_number_to_fixed_digits_argument; pub mod require_post_message_target_origin; pub mod switch_case_braces; + pub mod switch_case_break_position; pub mod text_encoding_identifier_case; pub mod throw_new_error; } diff --git a/crates/oxc_linter/src/rules/unicorn/switch_case_break_position.rs b/crates/oxc_linter/src/rules/unicorn/switch_case_break_position.rs new file mode 100644 index 0000000000000..4ab601249b595 --- /dev/null +++ b/crates/oxc_linter/src/rules/unicorn/switch_case_break_position.rs @@ -0,0 +1,342 @@ +use oxc_ast::{AstKind, ast::Statement}; +use oxc_diagnostics::OxcDiagnostic; +use oxc_macros::declare_oxc_lint; +use oxc_span::{GetSpan, Span}; + +use crate::{AstNode, context::LintContext, rule::Rule}; + +fn switch_case_break_position_diagnostic(span: Span, keyword: &str) -> OxcDiagnostic { + OxcDiagnostic::warn(format!("Move `{keyword}` inside the block statement.")).with_label(span) +} + +#[derive(Debug, Default, Clone)] +pub struct SwitchCaseBreakPosition; + +declare_oxc_lint!( + /// ### What it does + /// + /// Enforce consistent `break`/`return`/`continue`/`throw` position in `case` clauses. + /// + /// ### Why is this bad? + /// + /// Enforce that terminating statements (`break`, `return`, `continue`, `throw`) appear inside the block statement of a `case` clause, not after it. + /// This can happen when refactoring — for example, removing an `if` wrapper but leaving the `break` outside the braces. + /// + /// ### Examples + /// + /// Examples of **incorrect** code for this rule: + /// ```js + /// switch(foo) { + /// case 1: { + /// doStuff(); + /// } + /// break; + /// } + /// ``` + /// + /// Examples of **correct** code for this rule: + /// ```js + /// switch(foo) { + /// case 1: { + /// doStuff(); + /// break; + /// } + /// } + /// ``` + SwitchCaseBreakPosition, + unicorn, + style, + pending, +); + +impl Rule for SwitchCaseBreakPosition { + fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) { + let AstKind::SwitchCase(switch_case) = node.kind() else { + return; + }; + + let consequent = &switch_case.consequent; + + let [Statement::BlockStatement(block_statement), last_statement] = consequent.as_slice() + else { + return; + }; + + let keyword = match last_statement { + Statement::BreakStatement(_) => "break", + Statement::ReturnStatement(_) => "return", + Statement::ContinueStatement(_) => "continue", + Statement::ThrowStatement(_) => "throw", + _ => return, + }; + + if block_statement.body.is_empty() { + return; + } + + ctx.diagnostic(switch_case_break_position_diagnostic(last_statement.span(), keyword)); + } +} + +#[test] +fn test() { + use crate::tester::Tester; + + let pass = vec![ + "switch(foo) { + case 1: { + doStuff(); + break; + } + }", + "function bar() { + switch(foo) { + case 1: { + doStuff(); + return; + } + } + }", + "switch(foo) { + case 1: + doStuff(); + break; + }", + "switch(foo) { + case 1: { + doStuff(); + } + case 2: { + doOtherStuff(); + break; + } + }", + "switch(foo) { + case 1: + case 2: { + doStuff(); + break; + } + }", + "switch(foo) { + case 1: { + break; + } + }", + "switch(foo) { + default: { + doStuff(); + break; + } + }", + "switch(foo) { + case 1: {} + break; + }", + ]; + + let fail = vec![ + "switch(foo) { + case 1: { + doStuff(); + } + break; + }", + "function bar() { + switch(foo) { + case 1: { + doStuff(); + } + return; + } + }", + "function bar() { + switch(foo) { + case 1: { + doStuff(); + } + return result; + } + }", + "switch(foo) { + case 1: { + doStuff(); + } + throw new Error('bad'); + }", + "switch(foo) { + default: { + doStuff(); + } + break; + }", + "switch(foo) { + case 1: + { + doStuff(); + } + break; + }", + "switch(foo) { + case 1: { + doStuff(); + break; + } + case 2: { + doOtherStuff(); + } + break; + }", + "for (const foo of items) { + switch(foo) { + case 1: { + doStuff(); + } + continue; + } + }", + "outer: for (let i = 0; i < 3; i++) { + switch(foo) { + case 1: { + doStuff(); + } + break outer; + } + }", + "switch(foo) { + case 1: { + doStuff(); + } + // This break is intentional + break; + }", + "function bar() { + switch(foo) { + case 1: { + const value = 1; + } + return value; + } + }", + "function bar() { + switch(foo) { + case 1: { + const error = new Error('inner'); + } + throw error; + } + }", + "switch(foo) { + case 1: { + doStuff(); // Keep this comment with the statement + } + break; + }", + "switch(foo) { + case 1: { + doStuff(); /* Keep this block comment with the statement */ + } + break; + }", + "switch(foo) { + case 1: { + doStuff(); + // Keep this comment before the inserted break + } + break; + }", + "switch(foo) { + case 1: { + console.log(foo); // eslint-disable-line no-console + } + break; + }", + "switch(foo) { case 1: { doStuff(); } break; }", + "switch(foo) { + case 1: { + doStuff(); + } + break; // keep with break + }", + "switch(foo) { + case 1: { + doStuff(); + } + break; /* keep with break */ + }", + "function foo() { + switch(bar) { + case 1: { + doStuff(); + } + return value; // keep with return + } + }", + ]; + + // TODO: add fixer + #[expect(clippy::useless_vec)] + let _fix = vec![ + ( + "switch(foo) { + case 1: { + doStuff(); // Keep this comment with the statement + } + break; + }", + "switch(foo) { + case 1: { + doStuff(); // Keep this comment with the statement + break; + } + }", + ), + ( + "switch(foo) { + case 1: { + doStuff(); /* Keep this block comment with the statement */ + } + break; + }", + "switch(foo) { + case 1: { + doStuff(); /* Keep this block comment with the statement */ + break; + } + }", + ), + ( + "switch(foo) { + case 1: { + doStuff(); + // Keep this comment before the inserted break + } + break; + }", + "switch(foo) { + case 1: { + doStuff(); + // Keep this comment before the inserted break + break; + } + }", + ), + ( + "switch(foo) { + case 1: { + console.log(foo); // eslint-disable-line no-console + } + break; + }", + "switch(foo) { + case 1: { + console.log(foo); // eslint-disable-line no-console + break; + } + }", + ), + ]; + + Tester::new(SwitchCaseBreakPosition::NAME, SwitchCaseBreakPosition::PLUGIN, pass, fail) + .test_and_snapshot(); +} diff --git a/crates/oxc_linter/src/snapshots/unicorn_switch_case_break_position.snap b/crates/oxc_linter/src/snapshots/unicorn_switch_case_break_position.snap new file mode 100644 index 0000000000000..c806b725ff717 --- /dev/null +++ b/crates/oxc_linter/src/snapshots/unicorn_switch_case_break_position.snap @@ -0,0 +1,161 @@ +--- +source: crates/oxc_linter/src/tester.rs +--- + + ⚠ eslint-plugin-unicorn(switch-case-break-position): Move `break` inside the block statement. + ╭─[switch_case_break_position.tsx:5:17] + 4 │ } + 5 │ break; + · ────── + 6 │ } + ╰──── + + ⚠ eslint-plugin-unicorn(switch-case-break-position): Move `return` inside the block statement. + ╭─[switch_case_break_position.tsx:6:21] + 5 │ } + 6 │ return; + · ─────── + 7 │ } + ╰──── + + ⚠ eslint-plugin-unicorn(switch-case-break-position): Move `return` inside the block statement. + ╭─[switch_case_break_position.tsx:6:21] + 5 │ } + 6 │ return result; + · ────────────── + 7 │ } + ╰──── + + ⚠ eslint-plugin-unicorn(switch-case-break-position): Move `throw` inside the block statement. + ╭─[switch_case_break_position.tsx:5:17] + 4 │ } + 5 │ throw new Error('bad'); + · ─────────────────────── + 6 │ } + ╰──── + + ⚠ eslint-plugin-unicorn(switch-case-break-position): Move `break` inside the block statement. + ╭─[switch_case_break_position.tsx:5:17] + 4 │ } + 5 │ break; + · ────── + 6 │ } + ╰──── + + ⚠ eslint-plugin-unicorn(switch-case-break-position): Move `break` inside the block statement. + ╭─[switch_case_break_position.tsx:6:21] + 5 │ } + 6 │ break; + · ────── + 7 │ } + ╰──── + + ⚠ eslint-plugin-unicorn(switch-case-break-position): Move `break` inside the block statement. + ╭─[switch_case_break_position.tsx:9:17] + 8 │ } + 9 │ break; + · ────── + 10 │ } + ╰──── + + ⚠ eslint-plugin-unicorn(switch-case-break-position): Move `continue` inside the block statement. + ╭─[switch_case_break_position.tsx:6:21] + 5 │ } + 6 │ continue; + · ───────── + 7 │ } + ╰──── + + ⚠ eslint-plugin-unicorn(switch-case-break-position): Move `break` inside the block statement. + ╭─[switch_case_break_position.tsx:6:21] + 5 │ } + 6 │ break outer; + · ──────────── + 7 │ } + ╰──── + + ⚠ eslint-plugin-unicorn(switch-case-break-position): Move `break` inside the block statement. + ╭─[switch_case_break_position.tsx:6:17] + 5 │ // This break is intentional + 6 │ break; + · ────── + 7 │ } + ╰──── + + ⚠ eslint-plugin-unicorn(switch-case-break-position): Move `return` inside the block statement. + ╭─[switch_case_break_position.tsx:6:21] + 5 │ } + 6 │ return value; + · ───────────── + 7 │ } + ╰──── + + ⚠ eslint-plugin-unicorn(switch-case-break-position): Move `throw` inside the block statement. + ╭─[switch_case_break_position.tsx:6:21] + 5 │ } + 6 │ throw error; + · ──────────── + 7 │ } + ╰──── + + ⚠ eslint-plugin-unicorn(switch-case-break-position): Move `break` inside the block statement. + ╭─[switch_case_break_position.tsx:5:17] + 4 │ } + 5 │ break; + · ────── + 6 │ } + ╰──── + + ⚠ eslint-plugin-unicorn(switch-case-break-position): Move `break` inside the block statement. + ╭─[switch_case_break_position.tsx:5:17] + 4 │ } + 5 │ break; + · ────── + 6 │ } + ╰──── + + ⚠ eslint-plugin-unicorn(switch-case-break-position): Move `break` inside the block statement. + ╭─[switch_case_break_position.tsx:6:17] + 5 │ } + 6 │ break; + · ────── + 7 │ } + ╰──── + + ⚠ eslint-plugin-unicorn(switch-case-break-position): Move `break` inside the block statement. + ╭─[switch_case_break_position.tsx:5:17] + 4 │ } + 5 │ break; + · ────── + 6 │ } + ╰──── + + ⚠ eslint-plugin-unicorn(switch-case-break-position): Move `break` inside the block statement. + ╭─[switch_case_break_position.tsx:1:38] + 1 │ switch(foo) { case 1: { doStuff(); } break; } + · ────── + ╰──── + + ⚠ eslint-plugin-unicorn(switch-case-break-position): Move `break` inside the block statement. + ╭─[switch_case_break_position.tsx:5:17] + 4 │ } + 5 │ break; // keep with break + · ────── + 6 │ } + ╰──── + + ⚠ eslint-plugin-unicorn(switch-case-break-position): Move `break` inside the block statement. + ╭─[switch_case_break_position.tsx:5:17] + 4 │ } + 5 │ break; /* keep with break */ + · ────── + 6 │ } + ╰──── + + ⚠ eslint-plugin-unicorn(switch-case-break-position): Move `return` inside the block statement. + ╭─[switch_case_break_position.tsx:6:21] + 5 │ } + 6 │ return value; // keep with return + · ───────────── + 7 │ } + ╰────