luaur_analysis/functions/
function_is_expected_at.rs1use crate::functions::find_expected_type_at::find_expected_type_at;
2use crate::functions::follow_type::follow_type_id;
3use crate::functions::get_type_alt_j::get_type_id;
4use crate::records::function_type::FunctionType;
5use crate::records::intersection_type::IntersectionType;
6use crate::records::module::Module;
7use crate::records::union_type::UnionType;
8use luaur_ast::records::ast_node::AstNode;
9use luaur_ast::records::position::Position;
10
11pub fn function_is_expected_at(
12 module: &Module,
13 node: *mut AstNode,
14 position: Position,
15) -> Option<bool> {
16 let type_at_position = find_expected_type_at(module, node, position)?;
17 let expected_type = unsafe { follow_type_id(type_at_position) };
18
19 unsafe {
20 if !get_type_id::<FunctionType>(expected_type).is_null() {
21 return Some(true);
22 }
23
24 if let Some(itv) = get_type_id::<IntersectionType>(expected_type).as_ref() {
25 for part in &itv.parts {
26 if get_type_id::<FunctionType>(follow_type_id(*part)).is_null() {
27 return Some(false);
28 }
29 }
30 return Some(true);
31 }
32
33 if let Some(utv) = get_type_id::<UnionType>(expected_type).as_ref() {
34 return Some(
35 crate::functions::return_first_nonnull_option_of_type::return_first_nonnull_option_of_type::<FunctionType>(utv)
36 .is_some()
37 );
38 }
39
40 Some(false)
41 }
42}