#![allow(clippy::wildcard_imports, clippy::enum_glob_use)]
#![allow(
clippy::cast_precision_loss,
clippy::cast_possible_truncation,
clippy::cast_sign_loss
)]
use super::*;
impl Npa for ElixirCode {
fn compute<'a>(node: &Node<'a>, code: &'a [u8], stats: &mut Stats) {
use crate::metrics::cognitive::{elixir_call_keyword, elixir_do_block_call_children};
if !stats.is_disabled() || !Self::is_func_space_with_code(node, code) {
return;
}
if !matches!(elixir_call_keyword(node, code), Some("defmodule")) {
return;
}
stats.is_class_space = true;
for stmt in elixir_do_block_call_children(node) {
if matches!(elixir_call_keyword(&stmt, code), Some("defstruct")) {
let fields = count_defstruct_fields(&stmt);
stats.class_na += fields;
stats.class_npa += fields;
}
}
}
}
fn count_defstruct_fields(call: &Node) -> usize {
use Elixir as E;
call.children()
.filter(|child| matches!(child.kind_id().into(), E::Arguments | E::List | E::Keywords))
.map(|child| count_field_entries(&child))
.sum()
}
fn count_field_entries(node: &Node) -> usize {
use Elixir as E;
node.children()
.map(|child| match child.kind_id().into() {
E::Atom | E::QuotedAtom | E::Atom2 | E::Pair => 1,
E::List | E::Keywords => count_field_entries(&child),
_ => 0,
})
.sum()
}