use nu_protocol::ast::{Expr, Expression, Range};
use crate::{ast::call::CallExt, context::LintContext};
pub mod each_if_to_where;
pub mod for_filter_to_where;
pub mod omit_it_in_row_condition;
pub mod slice_to_drop;
pub mod slice_to_last;
pub mod slice_to_skip;
pub mod slice_to_take;
pub mod where_closure_drop_parameter;
pub fn extract_int_value(expr: &Expression, context: &LintContext) -> Option<i64> {
match &expr.expr {
Expr::Int(n) => Some(*n),
Expr::FullCellPath(cell_path) => match &cell_path.head.expr {
Expr::Subexpression(block_id) | Expr::Block(block_id) => {
let block = context.working_set.get_block(*block_id);
block
.pipelines
.first()
.and_then(|pipeline| pipeline.elements.first())
.and_then(|elem| extract_int_value(&elem.expr, context))
}
_ => None,
},
Expr::Subexpression(block_id) | Expr::Block(block_id) => {
let block = context.working_set.get_block(*block_id);
block
.pipelines
.first()
.and_then(|pipeline| pipeline.elements.first())
.and_then(|elem| extract_int_value(&elem.expr, context))
}
_ => None,
}
}
pub fn get_slice_range<'a>(expr: &'a Expression, context: &LintContext) -> Option<&'a Range> {
let Expr::Call(call) = &expr.expr else {
return None;
};
if call.get_call_name(context) != "slice" {
return None;
}
let range_arg = call.get_first_positional_arg()?;
match &range_arg.expr {
Expr::Range(range) => Some(range),
_ => None,
}
}
pub fn is_negative_expression(expr: &Expression, context: &LintContext) -> bool {
match &expr.expr {
Expr::Int(n) => *n < 0,
Expr::FullCellPath(cell_path) => match &cell_path.head.expr {
Expr::Subexpression(block_id) | Expr::Block(block_id) => {
let block = context.working_set.get_block(*block_id);
block
.pipelines
.first()
.and_then(|pipeline| pipeline.elements.first())
.is_some_and(|elem| is_negative_expression(&elem.expr, context))
}
_ => false,
},
Expr::Subexpression(block_id) | Expr::Block(block_id) => {
let block = context.working_set.get_block(*block_id);
block
.pipelines
.first()
.and_then(|pipeline| pipeline.elements.first())
.is_some_and(|elem| is_negative_expression(&elem.expr, context))
}
Expr::BinaryOp(left, op, _right) => {
use nu_protocol::ast::{Math, Operator};
matches!(op.expr, Expr::Operator(Operator::Math(Math::Subtract)))
&& extract_int_value(left, context) == Some(0)
}
_ => false,
}
}