Skip to main content

luaur_analysis/functions/
make_anonymous.rs

1use crate::functions::flatten_type_pack::flatten_type_pack_id;
2use crate::functions::follow_type_pack::follow_type_pack_id;
3use crate::functions::get_type_pack::get_type_pack_id;
4use crate::functions::is_variadic_type_pack::is_variadic;
5use crate::functions::try_get_type_name_in_scope_autocomplete_core::try_get_type_name_in_scope;
6use crate::functions::try_get_type_name_in_scope_autocomplete_core_alt_b::try_get_type_name_in_scope_scope_ptr_type_pack_id_bool;
7use crate::records::function_type::FunctionType;
8use crate::records::variadic_type_pack::VariadicTypePack;
9use crate::type_aliases::name_type::Name;
10use crate::type_aliases::scope_ptr_type::ScopePtr;
11use crate::type_aliases::type_id::TypeId;
12use crate::type_aliases::type_pack_id::TypePackId;
13use alloc::string::String;
14use alloc::vec::Vec;
15
16pub fn make_anonymous(scope: &ScopePtr, func_ty: &FunctionType) -> String {
17    let mut result = String::from("function(");
18
19    let (args, tail) = flatten_type_pack_id(func_ty.arg_types);
20
21    let mut first = true;
22    for arg_idx in 0..args.len() {
23        if !first {
24            result += ", ";
25        } else {
26            first = false;
27        }
28
29        let name: String;
30        if arg_idx < func_ty.arg_names.len() {
31            if let Some(ref arg_name) = func_ty.arg_names[arg_idx] {
32                name = arg_name.name.clone();
33            } else {
34                name = format!("a{}", arg_idx);
35            }
36        } else {
37            name = format!("a{}", arg_idx);
38        }
39
40        if let Some(ref r#type) = try_get_type_name_in_scope(scope.clone(), args[arg_idx], true) {
41            result += &format!("{}: {}", name, r#type);
42        } else {
43            result += &name;
44        }
45    }
46
47    if let Some(tail_tp) = tail {
48        let followed_tail = unsafe { follow_type_pack_id(tail_tp) };
49        if is_variadic(tail_tp) {
50            let pack_ptr = unsafe { get_type_pack_id::<VariadicTypePack>(followed_tail) };
51            if !pack_ptr.is_null() {
52                let pack = unsafe { &*pack_ptr };
53                if !first {
54                    result += ", ";
55                }
56                if let Some(ref var_arg_type) =
57                    try_get_type_name_in_scope(scope.clone(), pack.ty, true)
58                {
59                    result += &format!("...: {}", var_arg_type);
60                } else {
61                    result += "...";
62                }
63            }
64        }
65    }
66
67    result += ")";
68
69    let (rets, ret_tail) = flatten_type_pack_id(func_ty.ret_types);
70    let total_ret_size = rets.len() + if ret_tail.is_some() { 1 } else { 0 };
71    if total_ret_size > 0 {
72        if let Some(ref return_types) = try_get_type_name_in_scope_scope_ptr_type_pack_id_bool(
73            scope.clone(),
74            func_ty.ret_types,
75            true,
76        ) {
77            result += ": ";
78            let wrap = total_ret_size != 1;
79            if wrap {
80                result += "(";
81            }
82            result += return_types;
83            if wrap {
84                result += ")";
85            }
86        }
87    }
88
89    result += "  end";
90    result
91}