luaur_ast/methods/
parser_parse_attribute_stat.rs1use crate::enums::type_lexer::Type;
2use crate::records::ast_attr::AstAttr;
3use crate::records::ast_expr::AstExpr;
4use crate::records::ast_name::AstName;
5use crate::records::ast_stat::AstStat;
6use crate::records::ast_stat_error::AstStatError;
7use crate::records::ast_stat_function::AstStatFunction;
8use crate::records::location::Location;
9use crate::records::parser::Parser;
10
11impl Parser {
12 pub fn parse_attribute_stat(&mut self) -> *mut AstStat {
13 let attributes = self.parse_attributes();
14 let current_type = self.lexer.current().r#type;
15
16 match current_type {
17 Type::ReservedFunction => self.parse_function_stat(&attributes) as *mut AstStat,
18 Type::ReservedLocal => {
19 if luaur_common::FFlag::LuauConst2.get() {
20 let attr_loc = if attributes.size > 0 {
21 unsafe { (**attributes.data.add(0)).base.location }
22 } else {
23 self.lexer.current().location
24 };
25
26 self.parse_local(
27 attr_loc,
28 self.lexer.current().location.begin,
29 &attributes,
30 false,
31 ) as *mut AstStat
32 } else {
33 self.parseLocal_DEPRECATED(&attributes) as *mut AstStat
34 }
35 }
36 Type::Name => {
37 let current = self.lexer.current();
38 let current_name = unsafe { current.data.name };
39
40 if luaur_common::FFlag::LuauExportValueSyntax.get()
41 && luaur_common::FFlag::LuauConst2.get()
42 && unsafe {
43 AstName::operator_eq_c_char(
44 &AstName {
45 value: current_name,
46 },
47 c"export".as_ptr(),
48 )
49 }
50 {
51 let keyword_loc = current.location;
52 self.next_lexeme();
53
54 let attr_loc = if attributes.size > 0 {
55 unsafe { (**attributes.data.add(0)).base.location }
56 } else {
57 keyword_loc
58 };
59
60 self.parse_export_value(&attr_loc, keyword_loc.begin, &attributes)
61 as *mut AstStat
62 } else if luaur_common::FFlag::LuauConst2.get()
63 && unsafe {
64 AstName::operator_eq_c_char(
65 &AstName {
66 value: current_name,
67 },
68 c"const".as_ptr(),
69 )
70 }
71 {
72 let keyword_loc = current.location;
73 self.next_lexeme();
74
75 let attr_loc = if attributes.size > 0 {
76 unsafe { (**attributes.data.add(0)).base.location }
77 } else {
78 keyword_loc
79 };
80
81 self.parse_local(attr_loc, keyword_loc.begin, &attributes, true) as *mut AstStat
82 } else if self.options.allow_declaration_syntax
83 && unsafe {
84 AstName::operator_eq_c_char(
85 &AstName {
86 value: current_name,
87 },
88 c"declare".as_ptr(),
89 )
90 }
91 {
92 let expr = self.parse_primary_expr(true);
93 self.parse_declaration(&unsafe { (*expr).base.location }, &attributes)
94 as *mut AstStat
95 } else {
96 self.parse_attribute_stat_fallthrough_to_error(&attributes) as *mut AstStat
97 }
98 }
99 _ => self.parse_attribute_stat_fallthrough_to_error(&attributes) as *mut AstStat,
100 }
101 }
102
103 fn parse_attribute_stat_fallthrough_to_error(
104 &mut self,
105 _attributes: &crate::records::ast_array::AstArray<*mut AstAttr>,
106 ) -> *mut AstStatError {
107 let current = self.lexer.current();
108 let loc = current.location;
109
110 if luaur_common::FFlag::LuauConst2.get() {
111 self.report_stat_error(
112 loc,
113 crate::records::ast_array::AstArray {
114 data: core::ptr::null_mut(),
115 size: 0,
116 },
117 crate::records::ast_array::AstArray {
118 data: core::ptr::null_mut(),
119 size: 0,
120 },
121 format_args!(
122 "Expected 'function', 'local function', 'const function', 'declare function' or a function type declaration after attribute, but got {} instead",
123 current.to_string()
124 ),
125 )
126 } else {
127 self.report_stat_error(
128 loc,
129 crate::records::ast_array::AstArray {
130 data: core::ptr::null_mut(),
131 size: 0,
132 },
133 crate::records::ast_array::AstArray {
134 data: core::ptr::null_mut(),
135 size: 0,
136 },
137 format_args!(
138 "Expected 'function', 'local function', 'declare function' or a function type declaration after attribute, but got {} instead",
139 current.to_string()
140 ),
141 )
142 }
143 }
144}