Skip to main content

luaur_ast/methods/
parser_parse_return.rs

1use crate::functions::is_expr_l_value::is_expr_l_value;
2use crate::records::ast_expr::AstExpr;
3use crate::records::ast_stat::AstStat;
4use crate::records::ast_stat_return::AstStatReturn;
5use crate::records::cst_stat_return::CstStatReturn;
6use crate::records::lexeme::Type;
7use crate::records::location::Location;
8use crate::records::parser::Parser;
9use crate::records::position::Position;
10use crate::records::temp_vector::TempVector;
11
12impl Parser {
13    pub fn parse_return(&mut self) -> *mut AstStat {
14        let start = self.lexer.current().location;
15        self.next_lexeme();
16
17        let mut list = TempVector::new(&mut self.scratch_expr);
18        let mut comma_positions = TempVector::new(&mut self.scratch_position);
19
20        if !self.block_follow(self.lexer.current())
21            && self.lexer.current().r#type != Type::Semicolon
22        {
23            self.parse_expr_list(
24                &mut list,
25                if self.options.store_cst_data {
26                    Some(&mut comma_positions)
27                } else {
28                    None
29                },
30            );
31        }
32
33        let end = if list.empty() {
34            start
35        } else {
36            unsafe { (**list.back()).base.location }
37        };
38
39        let list_array = self.copy_temp_vector_t(&list);
40        let node = unsafe {
41            (*self.allocator).alloc(AstStatReturn::new(
42                Location::new(start.begin, end.end),
43                list_array,
44            ))
45        };
46
47        if self.options.store_cst_data {
48            let comma_positions_array = self.copy_temp_vector_t(&comma_positions);
49            let cst_node =
50                unsafe { (*self.allocator).alloc(CstStatReturn::new(comma_positions_array)) };
51            self.cst_node_map.try_insert(
52                node as *mut crate::records::ast_node::AstNode,
53                cst_node as *mut crate::records::cst_node::CstNode,
54            );
55        }
56
57        if luaur_common::FFlag::LuauExportValueSyntax.get()
58            && luaur_common::FFlag::LuauConst2.get()
59            && self.function_stack.len() == 1
60        {
61            if !self.declared_export_bindings.is_empty() {
62                let expressions = self.copy_initializer_list_t(&[node as *mut AstExpr]);
63                return self.report_stat_error(
64                    unsafe { (*node).base.base.location },
65                    expressions,
66                    crate::records::ast_array::AstArray { data: std::ptr::null_mut(), size: 0 },
67                    format_args!("Exporting values is not compatible with top-level return (export/return conflict)"),
68                ) as *mut AstStat;
69            }
70
71            self.has_module_return = true;
72        }
73
74        node as *mut AstStat
75    }
76}