use oxc_ast::ast::Expression;
use crate::GlobalContext;
pub trait ToBoolean<'a> {
fn to_boolean(&self, ctx: &impl GlobalContext<'a>) -> Option<bool>;
}
impl<'a> ToBoolean<'a> for Expression<'a> {
fn to_boolean(&self, ctx: &impl GlobalContext<'a>) -> Option<bool> {
match self {
Expression::Identifier(ident) => match ident.name.as_str() {
"NaN" | "undefined" if ctx.is_global_reference(ident) => Some(false),
"Infinity" if ctx.is_global_reference(ident) => Some(true),
_ => None,
},
Expression::RegExpLiteral(_)
| Expression::ArrayExpression(_)
| Expression::ArrowFunctionExpression(_)
| Expression::ClassExpression(_)
| Expression::FunctionExpression(_)
| Expression::NewExpression(_)
| Expression::ObjectExpression(_) => Some(true),
Expression::NullLiteral(_) => Some(false),
Expression::BooleanLiteral(boolean_literal) => Some(boolean_literal.value),
Expression::NumericLiteral(lit) => {
Some(if lit.value.is_nan() { false } else { lit.value != 0.0 })
}
Expression::BigIntLiteral(big_int_literal) => Some(!big_int_literal.is_zero()),
Expression::StringLiteral(string_literal) => Some(!string_literal.value.is_empty()),
Expression::TemplateLiteral(template_literal) => {
template_literal
.quasis
.first()
.filter(|quasi| quasi.tail)
.and_then(|quasi| quasi.value.cooked.as_ref())
.map(|cooked| !cooked.is_empty())
}
Expression::SequenceExpression(e) => {
e.expressions.last().and_then(|expr| expr.to_boolean(ctx))
}
_ => None,
}
}
}