use emmylua_parser::{LuaExpr, LuaIndexExpr, LuaIndexMemberExpr};
use crate::{
DbIndex, InferFailReason, LuaInferCache,
semantic::infer::{
VarRefId,
narrow::{
condition_flow::{
ConditionFlowAction, FieldConditionKind, InferConditionFlow, PendingConditionNarrow,
},
var_ref_id::get_var_expr_var_ref_id,
},
},
};
pub fn get_type_at_index_expr(
db: &DbIndex,
cache: &mut LuaInferCache,
var_ref_id: &VarRefId,
index_expr: LuaIndexExpr,
condition_flow: InferConditionFlow,
) -> Result<ConditionFlowAction, InferFailReason> {
let Some(name_var_ref_id) =
get_var_expr_var_ref_id(db, cache, LuaExpr::IndexExpr(index_expr.clone()))
else {
return Ok(ConditionFlowAction::Continue);
};
if name_var_ref_id == *var_ref_id {
return Ok(ConditionFlowAction::Pending(
PendingConditionNarrow::Truthiness(condition_flow),
));
}
let Some(prefix_expr) = index_expr.get_prefix_expr() else {
return Ok(ConditionFlowAction::Continue);
};
let Some(maybe_var_ref_id) = get_var_expr_var_ref_id(db, cache, prefix_expr.clone()) else {
return Ok(ConditionFlowAction::Continue);
};
if maybe_var_ref_id != *var_ref_id {
return Ok(ConditionFlowAction::Continue);
}
let idx = LuaIndexMemberExpr::IndexExpr(index_expr);
Ok(ConditionFlowAction::Pending(
PendingConditionNarrow::Field {
idx,
key_type: None,
condition_flow,
kind: FieldConditionKind::Truthy,
},
))
}