Skip to main content

luaur_analysis/functions/
function_is_expected_at.rs

1use 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}