mago_syntax/utils/
condition.rs

1use crate::ast::*;
2
3/// Determine if an expression is truthy.
4///
5/// This function will return true if the expression is truthy, and false otherwise.
6///
7/// When this function returns true, it does not necessarily mean that the expression will always evaluate to true.
8/// It simply means that the expression is truthy in the context of PHP.
9#[inline]
10pub fn is_truthy(expression: &Expression) -> bool {
11    match &expression {
12        Expression::Parenthesized(parenthesized) => is_truthy(&parenthesized.expression),
13        Expression::Literal(Literal::True(_)) => true,
14        Expression::AnonymousClass(_) => true,
15        Expression::Closure(_) => true,
16        Expression::ArrowFunction(_) => true,
17        Expression::Array(array) => !array.elements.is_empty(),
18        Expression::LegacyArray(array) => !array.elements.is_empty(),
19        Expression::ClosureCreation(_) => true,
20        Expression::Binary(operation) => match operation.operator {
21            BinaryOperator::Or(_) | BinaryOperator::LowOr(_) => is_truthy(&operation.lhs) || is_truthy(&operation.rhs),
22            BinaryOperator::And(_) | BinaryOperator::LowAnd(_) => {
23                is_truthy(&operation.lhs) && is_truthy(&operation.rhs)
24            }
25            BinaryOperator::NullCoalesce(_) => is_truthy(&operation.lhs),
26            BinaryOperator::LowXor(_) => is_truthy(&operation.lhs) ^ is_truthy(&operation.rhs),
27            _ => false,
28        },
29        Expression::UnaryPrefix(operation) => match operation.operator {
30            UnaryPrefixOperator::ErrorControl(_) => is_truthy(&operation.operand),
31            UnaryPrefixOperator::Reference(_) => is_truthy(&operation.operand),
32            UnaryPrefixOperator::Not(_) => is_falsy(&operation.operand),
33            _ => false,
34        },
35        Expression::Assignment(assignment) => is_truthy(&assignment.rhs),
36        _ => false,
37    }
38}
39
40/// Determine if an expression is falsy.
41///
42/// This function will return true if the expression is falsy, and false otherwise.
43///
44/// When this function returns false, it does not mean that the expression is truthy,
45/// it just means that we could not determine if the expression is falsy.
46#[inline]
47pub fn is_falsy(expression: &Expression) -> bool {
48    match &expression {
49        Expression::Parenthesized(parenthesized) => is_falsy(&parenthesized.expression),
50        Expression::Literal(Literal::False(_) | Literal::Null(_)) => true,
51        Expression::Array(array) => array.elements.is_empty(),
52        Expression::LegacyArray(array) => array.elements.is_empty(),
53        Expression::Assignment(assignment) => is_falsy(&assignment.rhs),
54        Expression::Binary(operation) => match operation.operator {
55            BinaryOperator::Or(_) | BinaryOperator::LowOr(_) => is_falsy(&operation.lhs) && is_falsy(&operation.rhs),
56            BinaryOperator::And(_) | BinaryOperator::LowAnd(_) => is_falsy(&operation.lhs) || is_falsy(&operation.rhs),
57            BinaryOperator::NullCoalesce(_) => is_falsy(&operation.lhs) && is_falsy(&operation.rhs),
58            BinaryOperator::LowXor(_) => is_falsy(&operation.lhs) ^ is_falsy(&operation.rhs),
59            _ => false,
60        },
61        Expression::UnaryPrefix(operation) => match operation.operator {
62            UnaryPrefixOperator::ErrorControl(_) => is_falsy(&operation.operand),
63            UnaryPrefixOperator::Reference(_) => is_falsy(&operation.operand),
64            UnaryPrefixOperator::Not(_) => is_truthy(&operation.operand),
65            _ => false,
66        },
67        _ => false,
68    }
69}