diff --git a/crates/rome_js_analyze/src/analyzers/nursery/no_excessive_complexity.rs b/crates/rome_js_analyze/src/analyzers/nursery/no_excessive_complexity.rs index 0c55c639f23..7e9de147d06 100644 --- a/crates/rome_js_analyze/src/analyzers/nursery/no_excessive_complexity.rs +++ b/crates/rome_js_analyze/src/analyzers/nursery/no_excessive_complexity.rs @@ -11,9 +11,9 @@ use rome_deserialize::{ }; use rome_js_syntax::{ AnyJsFunctionBody, JsBreakStatement, JsCatchClause, JsConditionalExpression, - JsContinueStatement, JsDoWhileStatement, JsFinallyClause, JsForInStatement, JsForOfStatement, - JsForStatement, JsIfStatement, JsLanguage, JsLogicalExpression, JsLogicalOperator, - JsSwitchStatement, JsWhileStatement, JsWithStatement, + JsContinueStatement, JsDoWhileStatement, JsElseClause, JsFinallyClause, JsForInStatement, + JsForOfStatement, JsForStatement, JsIfStatement, JsLanguage, JsLogicalExpression, + JsLogicalOperator, JsSwitchStatement, JsWhileStatement, JsWithStatement, }; use rome_json_syntax::{JsonLanguage, JsonSyntaxNode}; use rome_rowan::{AstNode, Language, SyntaxNode, SyntaxResult, TextRange, WalkEvent}; @@ -184,6 +184,15 @@ impl Visitor for CognitiveComplexityVisitor { state.score += 1; state.last_seen_operator = Some(operator); } + } else if let Some(alternate) = + JsElseClause::cast_ref(node).and_then(|js_else| js_else.alternate().ok()) + { + if alternate.as_js_if_statement().is_some() { + // Prevent double nesting inside else-if. + state.nesting_level = state.nesting_level.saturating_sub(1); + } else { + state.score += 1; + } } else { // Reset the operator for every other type of node. state.last_seen_operator = None; @@ -204,6 +213,15 @@ impl Visitor for CognitiveComplexityVisitor { } else if let Some(state) = self.stack.last_mut() { if increases_nesting(node) { state.nesting_level = state.nesting_level.saturating_sub(1); + } else if let Some(alternate) = + JsElseClause::cast_ref(node).and_then(|js_else| js_else.alternate().ok()) + { + if alternate.as_js_if_statement().is_some() { + // Prevent double nesting inside else-if. + state.nesting_level += 1; + } else { + state.nesting_level = state.nesting_level.saturating_sub(1); + } } } } diff --git a/crates/rome_js_analyze/tests/specs/nursery/noExcessiveComplexity/simpleBranches2.js b/crates/rome_js_analyze/tests/specs/nursery/noExcessiveComplexity/simpleBranches2.js new file mode 100644 index 00000000000..3b5b95a39b4 --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/noExcessiveComplexity/simpleBranches2.js @@ -0,0 +1,7 @@ +function simpleBranches2() { + if (firstCondition) { // +1 + return 1; + } else if (secondCondition) { // +1 + return 2; + } +} diff --git a/crates/rome_js_analyze/tests/specs/nursery/noExcessiveComplexity/simpleBranches2.js.snap b/crates/rome_js_analyze/tests/specs/nursery/noExcessiveComplexity/simpleBranches2.js.snap new file mode 100644 index 00000000000..fd16231fdd8 --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/noExcessiveComplexity/simpleBranches2.js.snap @@ -0,0 +1,33 @@ +--- +source: crates/rome_js_analyze/tests/spec_tests.rs +expression: simpleBranches2.js +--- +# Input +```js +function simpleBranches2() { + if (firstCondition) { // +1 + return 1; + } else if (secondCondition) { // +1 + return 2; + } +} + +``` + +# Diagnostics +``` +simpleBranches2.js:1:10 lint/nursery/noExcessiveComplexity ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Excessive complexity detected. + + > 1 │ function simpleBranches2() { + │ ^^^^^^^^^^^^^^^ + 2 │ if (firstCondition) { // +1 + 3 │ return 1; + + i Please refactor this function to reduce its complexity score from 2 to 1. + + +``` + + diff --git a/crates/rome_js_analyze/tests/specs/nursery/noExcessiveComplexity/simpleBranches2.options.json b/crates/rome_js_analyze/tests/specs/nursery/noExcessiveComplexity/simpleBranches2.options.json new file mode 100644 index 00000000000..9c89f99b2f2 --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/noExcessiveComplexity/simpleBranches2.options.json @@ -0,0 +1,15 @@ +{ + "$schema": "../../../../../../npm/rome/configuration_schema.json", + "linter": { + "rules": { + "nursery": { + "noExcessiveComplexity": { + "level": "error", + "options": { + "maxAllowedComplexity": 1 + } + } + } + } + } +}