#![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],
_ancestors: Ancestors<'a, '_>,
stats: &mut Stats,
) {
use crate::metrics::cognitive::{elixir_call_keyword, elixir_do_block_call_children};
if !matches!(elixir_call_keyword(node, code), Some("defmodule")) {
return;
}
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()
}