Skip to main content

luaur_ast/methods/
parser_parse_function_stat.rs

1use crate::enums::type_lexer::Type;
2use crate::functions::is_expr_l_value::is_expr_l_value;
3use crate::records::ast_array::AstArray;
4use crate::records::ast_attr::AstAttr;
5use crate::records::ast_expr::AstExpr;
6use crate::records::ast_expr_function::AstExprFunction;
7use crate::records::ast_name::AstName;
8use crate::records::ast_stat_function::AstStatFunction;
9use crate::records::cst_stat_function::CstStatFunction;
10use crate::records::lexeme::Lexeme;
11use crate::records::location::Location;
12use crate::records::parser::Parser;
13use crate::records::position::Position;
14
15impl Parser {
16    pub fn parse_function_stat(
17        &mut self,
18        attributes: &AstArray<*mut AstAttr>,
19    ) -> *mut AstStatFunction {
20        let start = if attributes.size > 0 {
21            unsafe { (**attributes.data).base.location }
22        } else {
23            self.lexer.current().location
24        };
25
26        let match_function = *self.lexer.current();
27        self.next_lexeme();
28
29        let mut hasself = false;
30        let mut debugname = AstName::new();
31        let expr = self.parse_function_name(&mut hasself, &mut debugname);
32
33        if luaur_common::FFlag::LuauConst2.get() && !is_expr_l_value(expr) {
34            let expr = if luaur_common::FFlag::LuauExportValueSyntax.get()
35                && luaur_common::FFlag::LuauConst2.get()
36            {
37                self.report_l_value_error(expr)
38            } else {
39                let expressions = self.copy_initializer_list_t(&[expr]);
40                self.report_expr_error(
41                    unsafe { (*expr).base.location },
42                    expressions,
43                    format_args!("Assigned expression must be a variable or a field"),
44                )
45            };
46            return expr as *mut AstStatFunction;
47        }
48
49        self.match_recovery_stop_on_token[Type::ReservedEnd.0 as usize] += 1;
50
51        let (body, _) = self.parse_function_body(
52            hasself,
53            &match_function,
54            &debugname,
55            None,
56            attributes,
57            false,
58        );
59
60        self.match_recovery_stop_on_token[Type::ReservedEnd.0 as usize] -= 1;
61
62        let node = unsafe {
63            (*self.allocator).alloc(AstStatFunction::new(
64                Location::new(start.begin, (*body).base.base.location.end),
65                expr,
66                body,
67            ))
68        };
69
70        if self.options.store_cst_data {
71            let cst_node = unsafe {
72                (*self.allocator).alloc(CstStatFunction::new(match_function.location.begin))
73            };
74            self.cst_node_map.try_insert(
75                node as *mut crate::records::ast_node::AstNode,
76                cst_node as *mut crate::records::cst_node::CstNode,
77            );
78        }
79
80        node as *mut AstStatFunction
81    }
82}