#![allow(
clippy::enum_glob_use,
clippy::too_many_lines,
clippy::wildcard_imports
)]
#![allow(
clippy::cast_precision_loss,
clippy::cast_possible_truncation,
clippy::cast_sign_loss
)]
use super::{
Abc, Stats, count_boolean_slot, count_each_operand, count_field_operands,
count_negated_operand, wrapped_operand,
};
use crate::*;
fn lua_wrapper_operand<'a>(node: &Node<'a>) -> Option<(Node<'a>, bool)> {
match node.kind_id().into() {
Lua::ParenthesizedExpression => wrapped_operand(node).map(|o| (o, false)),
Lua::UnaryExpression
if node
.child(0)
.is_some_and(|c| c.kind_id() == Lua::Not as u16) =>
{
node.child_by_field_name("operand").map(|o| (o, true))
}
_ => None,
}
}
fn lua_condition_scores_itself(expr: &Node) -> bool {
expr.kind_id() == Lua::BinaryExpression
&& expr.child_by_field_name("operator").is_some_and(|op| {
matches!(
op.kind_id().into(),
Lua::EQEQ
| Lua::TILDEEQ
| Lua::LT
| Lua::GT
| Lua::LTEQ
| Lua::GTEQ
| Lua::And
| Lua::Or
)
})
}
fn lua_count_condition(condition: &Node, conditions: &mut f64) {
count_boolean_slot(
condition,
lua_wrapper_operand,
lua_condition_scores_itself,
conditions,
);
}
fn lua_count_negated(operand: &Node, conditions: &mut f64) {
count_negated_operand(
operand,
lua_wrapper_operand,
lua_condition_scores_itself,
conditions,
);
}
fn lua_count_slot(slot: Option<Node>, conditions: &mut f64) {
if let Some(condition) = slot {
lua_count_condition(&condition, conditions);
}
}
impl Abc for LuaCode {
fn compute<'a>(
node: &Node<'a>,
_code: &'a [u8],
ancestors: Ancestors<'a, '_>,
stats: &mut Stats,
) {
match node.kind_id().into() {
Lua::AssignmentStatement | Lua::AssignmentStatement2 => {
stats.assignments += 1.;
}
Lua::FunctionCall => {
stats.branches += 1.;
}
Lua::EQEQ | Lua::TILDEEQ | Lua::LTEQ | Lua::GTEQ | Lua::ElseStatement => {
stats.conditions += 1.;
}
Lua::LT | Lua::GT if ancestors.parent_has_kind(node, Lua::BinaryExpression as u16) => {
stats.conditions += 1.;
}
Lua::And | Lua::Or => {
if let Some(chain) = ancestors
.parent(node)
.filter(|p| p.kind_id() == Lua::BinaryExpression)
{
count_field_operands(&chain, lua_count_condition, &mut stats.conditions);
}
}
Lua::ElseifStatement => {
stats.conditions += 1.;
lua_count_slot(node.child_by_field_name("condition"), &mut stats.conditions);
}
Lua::IfStatement | Lua::WhileStatement | Lua::RepeatStatement => {
lua_count_slot(node.child_by_field_name("condition"), &mut stats.conditions);
}
Lua::ReturnStatement => {
if let Some(expr_list) = wrapped_operand(node) {
count_each_operand(&expr_list, lua_count_negated, &mut stats.conditions);
}
}
Lua::Arguments => {
count_each_operand(node, lua_count_negated, &mut stats.conditions);
}
_ => {}
}
}
}