luaur_ast/methods/
parser_parse_function_stat.rs1use 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}