use super::CompiledNode;
use crate::arena::DataValue;
use crate::opcode::OpCode;
use datavalue::OwnedDataValue;
#[inline]
pub(super) fn precompute_lit(value: &OwnedDataValue) -> Option<Box<DataValue<'static>>> {
match value {
OwnedDataValue::Null => Some(Box::new(DataValue::Null)),
OwnedDataValue::Bool(b) => Some(Box::new(DataValue::Bool(*b))),
OwnedDataValue::Number(n) => Some(Box::new(DataValue::Number(*n))),
OwnedDataValue::String(s) if s.is_empty() => Some(Box::new(DataValue::String(""))),
OwnedDataValue::Array(a) if a.is_empty() => Some(Box::new(DataValue::Array(&[]))),
OwnedDataValue::Object(o) if o.is_empty() => Some(Box::new(DataValue::Object(&[]))),
_ => None,
}
}
#[inline]
fn iterates_args0(opcode: OpCode) -> bool {
let _opcode = opcode;
#[cfg(feature = "ext-array")]
if matches!(opcode, OpCode::Sort) {
return true;
}
matches!(
opcode,
OpCode::Filter
| OpCode::Map
| OpCode::All
| OpCode::Some
| OpCode::None
| OpCode::Reduce
| OpCode::Min
| OpCode::Max
)
}
pub(crate) fn populate_lits(node: &mut CompiledNode) {
node.visit_children_mut(&mut populate_lits);
if let CompiledNode::BuiltinOperator {
opcode,
args,
predicate_hint,
iter_arg_kind,
..
} = node
{
*predicate_hint =
crate::operators::array::FastPredicate::try_detect_owned(*opcode, args).map(Box::new);
*iter_arg_kind = if iterates_args0(*opcode) && !args.is_empty() {
crate::operators::array::IterArgKind::classify(&args[0])
} else {
crate::operators::array::IterArgKind::General
};
}
}