use emmylua_parser::LuaSyntaxNode;
use crate::{DbIndex, LuaMemberId, LuaSemanticDeclId};
use super::{
LuaInferCache, SemanticDeclLevel, member::find_member_origin_owner,
semantic_info::infer_node_semantic_decl,
};
pub fn is_reference_to(
db: &DbIndex,
infer_config: &mut LuaInferCache,
node: LuaSyntaxNode,
semantic_decl: LuaSemanticDeclId,
level: SemanticDeclLevel,
) -> Option<bool> {
let node_semantic_decl_id = infer_node_semantic_decl(db, infer_config, node, level)?;
if node_semantic_decl_id == semantic_decl {
return Some(true);
}
match (node_semantic_decl_id, &semantic_decl) {
(LuaSemanticDeclId::Member(node_member_id), LuaSemanticDeclId::Member(member_id)) => {
if let Some(true) = is_member_reference_to(db, node_member_id, *member_id) {
return Some(true);
}
is_member_origin_reference_to(db, infer_config, node_member_id, semantic_decl)
}
_ => Some(false),
}
}
fn is_member_reference_to(
db: &DbIndex,
node_member_id: LuaMemberId,
member_id: LuaMemberId,
) -> Option<bool> {
let node_owner = db.get_member_index().get_current_owner(&node_member_id)?;
let owner = db.get_member_index().get_current_owner(&member_id)?;
Some(node_owner == owner)
}
fn is_member_origin_reference_to(
db: &DbIndex,
infer_config: &mut LuaInferCache,
node_member_id: LuaMemberId,
semantic_decl: LuaSemanticDeclId,
) -> Option<bool> {
let node_origin = find_member_origin_owner(db, infer_config, node_member_id)
.unwrap_or(LuaSemanticDeclId::Member(node_member_id));
match (node_origin, semantic_decl) {
(LuaSemanticDeclId::Member(node_owner), LuaSemanticDeclId::Member(member_owner)) => {
is_member_reference_to(db, node_owner, member_owner)
}
(node_origin, member_origin) => Some(node_origin == member_origin),
}
}