fix(rome_js_analyze): include the exception handlers in the complexity score of the CFG
MODIFY
crates/rome_js_analyze/src/analyzers/js/no_dead_code.rs
crates/rome_js_analyze/src/analyzers/js/no_dead_code.rs
-use std::{cmp::Ordering, collections::VecDeque, vec::IntoIter};
+use std::{cmp::Ordering, collections::VecDeque, num::NonZeroU32, vec::IntoIter};
use roaring::bitmap::RoaringBitmap;
use rome_analyze::{context::RuleContext, declare_rule, Rule, RuleCategory, RuleDiagnostic};
@@ -207,13 +207,33 @@ fn exceeds_complexity_threshold(cfg: &ControlFlowGraph) -> bool {
let mut conditionals: u32 = 0;
for block in &cfg.blocks {
+ let mut exception_handlers = NonZeroU32::new(block.exception_handlers.len() as u32);
+ let mut cleanup_handlers = NonZeroU32::new(block.cleanup_handlers.len() as u32);
+
for inst in &block.instructions {
- if let InstructionKind::Jump { conditional, .. } = inst.kind {
+ if has_side_effects(inst) {
+ if let Some(handlers) = exception_handlers.take() {
+ edges += handlers.get();
+ conditionals += 1;
+ }
+ }
+
+ match inst.kind {
+ InstructionKind::Statement => {}
+ InstructionKind::Jump { conditional, .. } => {
edges += 1;
if conditional {
conditionals += 1;
}
+ }
+ InstructionKind::Return => {
+ if let Some(handlers) = cleanup_handlers.take() {
+ edges += handlers.get();
+ conditionals += 1;
+ }
+ }
+ }
let complexity = edges.saturating_sub(nodes) + conditionals / 2;
if complexity > COMPLEXITY_THRESHOLD {
@@ -221,7 +241,6 @@ fn exceeds_complexity_threshold(cfg: &ControlFlowGraph) -> bool {
}
}
}
- }
false
}

MODIFY
crates/rome_js_analyze/tests/specs/js/noDeadCode/HighComplexity.js
crates/rome_js_analyze/tests/specs/js/noDeadCode/HighComplexity.js
@@ -28,3 +28,214 @@ function HighComplexity1() {
return;
afterReturn();
}
+
+function HighComplexity2() {
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+ try {
+ !a && !a;
+ } catch (err) {
+ err = 2;
+ }
+
+ return;
+ afterReturn();
+}

fix(rome_js_analyze): include the exception handlers in the complexity score of the CFG (#2930)