1use crate::ast_names::AstName;
2use crate::lexer::QuoteStyle as LexerQuoteStyle;
3use crate::location::Location;
4use luau_common::{BStr, ByteSlice};
5use std::fmt;
6
7pub struct Local<'ast> {
8 pub name: AstName<'ast>,
9 pub location: Location,
10 pub shadow: Option<&'ast Local<'ast>>,
11 pub function_depth: usize,
12 pub loop_depth: usize,
13 pub annotation: Option<Type<'ast>>,
14 pub is_const: bool,
15 pub is_exported: bool,
16}
17
18#[derive(Debug, Clone, Copy)]
19pub struct LocalInit<'ast> {
20 pub name: AstName<'ast>,
21 pub location: Location,
22 pub shadow: Option<&'ast Local<'ast>>,
23 pub function_depth: usize,
24 pub loop_depth: usize,
25 pub annotation: Option<Type<'ast>>,
26 pub is_const: bool,
27 pub is_exported: bool,
28}
29
30impl fmt::Debug for Local<'_> {
31 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
32 formatter
33 .debug_struct("Local")
34 .field("name", &self.name)
35 .field("location", &self.location)
36 .field("shadow", &self.shadow)
37 .field("function_depth", &self.function_depth)
38 .field("loop_depth", &self.loop_depth)
39 .field("annotation", &self.annotation)
40 .field("is_const", &self.is_const)
41 .field("is_exported", &self.is_exported)
42 .finish()
43 }
44}
45
46impl PartialEq for Local<'_> {
47 fn eq(&self, other: &Self) -> bool {
48 self.name == other.name
49 && self.location == other.location
50 && self.shadow == other.shadow
51 && self.function_depth == other.function_depth
52 && self.loop_depth == other.loop_depth
53 && self.annotation == other.annotation
54 && self.is_const == other.is_const
55 && self.is_exported == other.is_exported
56 }
57}
58
59#[derive(Debug, PartialEq)]
60pub struct GenericType<'ast> {
61 pub location: Location,
62 pub name: AstName<'ast>,
63 pub default_value: Option<Type<'ast>>,
64}
65
66#[derive(Debug, PartialEq)]
67pub struct GenericTypePack<'ast> {
68 pub location: Location,
69 pub name: AstName<'ast>,
70 pub default_value: Option<TypePack<'ast>>,
71}
72
73#[derive(Debug, Clone, Copy, PartialEq)]
74pub struct ArgumentName<'ast> {
75 pub name: AstName<'ast>,
76 pub location: Location,
77}
78
79impl<'ast> Local<'ast> {
80 pub(crate) fn new(init: LocalInit<'ast>) -> Self {
81 Local {
82 name: init.name,
83 location: init.location,
84 shadow: init.shadow,
85 function_depth: init.function_depth,
86 loop_depth: init.loop_depth,
87 annotation: init.annotation,
88 is_const: init.is_const,
89 is_exported: init.is_exported,
90 }
91 }
92
93 pub fn visit<V: AstVisitor>(&self, visitor: &mut V) {
94 if let Some(annotation) = &self.annotation {
95 annotation.visit(visitor);
96 }
97 }
98}
99
100impl GenericType<'_> {
101 pub fn visit<V: AstVisitor>(&self, visitor: &mut V) {
102 if !visitor.visit_generic_type(self) {
103 return;
104 }
105
106 if let Some(default_value) = &self.default_value {
107 default_value.visit(visitor);
108 }
109 }
110}
111
112impl GenericTypePack<'_> {
113 pub fn visit<V: AstVisitor>(&self, visitor: &mut V) {
114 if !visitor.visit_generic_type_pack(self) {
115 return;
116 }
117
118 if let Some(default_value) = &self.default_value {
119 default_value.visit(visitor);
120 }
121 }
122}
123
124#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
125pub struct AstString<'ast> {
126 bytes: &'ast BStr,
127}
128
129impl<'ast> AstString<'ast> {
130 pub(crate) fn from_arena_bytes(bytes: &'ast [u8]) -> Self {
131 Self {
132 bytes: BStr::new(bytes),
133 }
134 }
135
136 pub fn as_bytes(&self) -> &[u8] {
137 self.bytes.as_bytes()
138 }
139
140 pub fn as_bstr(self) -> &'ast BStr {
141 self.bytes
142 }
143
144 pub fn into_bytes(self) -> &'ast [u8] {
145 self.bytes.as_bytes()
146 }
147}
148
149impl PartialEq<str> for AstString<'_> {
150 fn eq(&self, other: &str) -> bool {
151 self.as_bytes() == other.as_bytes()
152 }
153}
154
155pub trait AstVisitor {
156 fn visit_node(&mut self, _node: AstNodeRef<'_, '_>) -> bool {
157 true
158 }
159
160 fn visit_attribute(&mut self, attribute: &Attribute<'_>) -> bool {
161 self.visit_node(AstNodeRef::Attribute(attribute))
162 }
163
164 fn visit_generic_type(&mut self, generic: &GenericType<'_>) -> bool {
165 self.visit_node(AstNodeRef::GenericType(generic))
166 }
167
168 fn visit_generic_type_pack(&mut self, generic: &GenericTypePack<'_>) -> bool {
169 self.visit_node(AstNodeRef::GenericTypePack(generic))
170 }
171
172 fn visit_block(&mut self, block: Block<'_>) -> bool {
173 self.visit_statement(block.as_statement())
174 }
175
176 fn visit_statement(&mut self, statement: Statement<'_>) -> bool {
177 self.visit_node(AstNodeRef::Statement(statement))
178 }
179
180 fn visit_assign_statement(&mut self, statement: Statement<'_>) -> bool {
181 self.visit_statement(statement)
182 }
183
184 fn visit_compound_assign_statement(&mut self, statement: Statement<'_>) -> bool {
185 self.visit_statement(statement)
186 }
187
188 fn visit_break_statement(&mut self, statement: Statement<'_>) -> bool {
189 self.visit_statement(statement)
190 }
191
192 fn visit_continue_statement(&mut self, statement: Statement<'_>) -> bool {
193 self.visit_statement(statement)
194 }
195
196 fn visit_class_statement(&mut self, statement: Statement<'_>) -> bool {
197 self.visit_statement(statement)
198 }
199
200 fn visit_expression_statement(&mut self, statement: Statement<'_>) -> bool {
201 self.visit_statement(statement)
202 }
203
204 fn visit_numeric_for_statement(&mut self, statement: Statement<'_>) -> bool {
205 self.visit_statement(statement)
206 }
207
208 fn visit_generic_for_statement(&mut self, statement: Statement<'_>) -> bool {
209 self.visit_statement(statement)
210 }
211
212 fn visit_function_declaration_statement(&mut self, statement: Statement<'_>) -> bool {
213 self.visit_statement(statement)
214 }
215
216 fn visit_if_statement(&mut self, statement: Statement<'_>) -> bool {
217 self.visit_statement(statement)
218 }
219
220 fn visit_local_function_statement(&mut self, statement: Statement<'_>) -> bool {
221 self.visit_statement(statement)
222 }
223
224 fn visit_local_statement(&mut self, statement: Statement<'_>) -> bool {
225 self.visit_statement(statement)
226 }
227
228 fn visit_type_alias_statement(&mut self, statement: Statement<'_>) -> bool {
229 self.visit_statement(statement)
230 }
231
232 fn visit_type_function_statement(&mut self, statement: Statement<'_>) -> bool {
233 self.visit_statement(statement)
234 }
235
236 fn visit_declare_global_statement(&mut self, statement: Statement<'_>) -> bool {
237 self.visit_statement(statement)
238 }
239
240 fn visit_declare_function_statement(&mut self, statement: Statement<'_>) -> bool {
241 self.visit_statement(statement)
242 }
243
244 fn visit_declare_extern_type_statement(&mut self, statement: Statement<'_>) -> bool {
245 self.visit_statement(statement)
246 }
247
248 fn visit_repeat_statement(&mut self, statement: Statement<'_>) -> bool {
249 self.visit_statement(statement)
250 }
251
252 fn visit_return_statement(&mut self, statement: Statement<'_>) -> bool {
253 self.visit_statement(statement)
254 }
255
256 fn visit_while_statement(&mut self, statement: Statement<'_>) -> bool {
257 self.visit_statement(statement)
258 }
259
260 fn visit_error_statement(&mut self, statement: Statement<'_>) -> bool {
261 self.visit_statement(statement)
262 }
263
264 fn visit_expression(&mut self, expression: Expression<'_>) -> bool {
265 self.visit_node(AstNodeRef::Expression(expression))
266 }
267
268 fn visit_boolean_expression(&mut self, expression: Expression<'_>) -> bool {
269 self.visit_expression(expression)
270 }
271
272 fn visit_call_expression(&mut self, expression: Expression<'_>) -> bool {
273 self.visit_expression(expression)
274 }
275
276 fn visit_function_literal_expression(&mut self, expression: Expression<'_>) -> bool {
277 self.visit_expression(expression)
278 }
279
280 fn visit_grouped_expression(&mut self, expression: Expression<'_>) -> bool {
281 self.visit_expression(expression)
282 }
283
284 fn visit_integer_expression(&mut self, expression: Expression<'_>) -> bool {
285 self.visit_expression(expression)
286 }
287
288 fn visit_nil_expression(&mut self, expression: Expression<'_>) -> bool {
289 self.visit_expression(expression)
290 }
291
292 fn visit_number_expression(&mut self, expression: Expression<'_>) -> bool {
293 self.visit_expression(expression)
294 }
295
296 fn visit_string_expression(&mut self, expression: Expression<'_>) -> bool {
297 self.visit_expression(expression)
298 }
299
300 fn visit_interp_string_expression(&mut self, expression: Expression<'_>) -> bool {
301 self.visit_expression(expression)
302 }
303
304 fn visit_table_expression(&mut self, expression: Expression<'_>) -> bool {
305 self.visit_expression(expression)
306 }
307
308 fn visit_if_expression(&mut self, expression: Expression<'_>) -> bool {
309 self.visit_expression(expression)
310 }
311
312 fn visit_varargs_expression(&mut self, expression: Expression<'_>) -> bool {
313 self.visit_expression(expression)
314 }
315
316 fn visit_index_expression(&mut self, expression: Expression<'_>) -> bool {
317 self.visit_expression(expression)
318 }
319
320 fn visit_index_name_expression(&mut self, expression: Expression<'_>) -> bool {
321 self.visit_expression(expression)
322 }
323
324 fn visit_type_assertion_expression(&mut self, expression: Expression<'_>) -> bool {
325 self.visit_expression(expression)
326 }
327
328 fn visit_instantiate_expression(&mut self, expression: Expression<'_>) -> bool {
329 self.visit_expression(expression)
330 }
331
332 fn visit_unary_expression(&mut self, expression: Expression<'_>) -> bool {
333 self.visit_expression(expression)
334 }
335
336 fn visit_local_expression(&mut self, expression: Expression<'_>) -> bool {
337 self.visit_expression(expression)
338 }
339
340 fn visit_global_expression(&mut self, expression: Expression<'_>) -> bool {
341 self.visit_expression(expression)
342 }
343
344 fn visit_binary_expression(&mut self, expression: Expression<'_>) -> bool {
345 self.visit_expression(expression)
346 }
347
348 fn visit_error_expression(&mut self, expression: Expression<'_>) -> bool {
349 self.visit_expression(expression)
350 }
351
352 fn visit_type(&mut self, _annotation: Type<'_>) -> bool {
353 false
354 }
355
356 fn visit_reference_type(&mut self, annotation: Type<'_>) -> bool {
357 self.visit_type(annotation)
358 }
359
360 fn visit_table_type(&mut self, annotation: Type<'_>) -> bool {
361 self.visit_type(annotation)
362 }
363
364 fn visit_function_type(&mut self, annotation: Type<'_>) -> bool {
365 self.visit_type(annotation)
366 }
367
368 fn visit_typeof_type(&mut self, annotation: Type<'_>) -> bool {
369 self.visit_type(annotation)
370 }
371
372 fn visit_singleton_bool_type(&mut self, annotation: Type<'_>) -> bool {
373 self.visit_type(annotation)
374 }
375
376 fn visit_singleton_string_type(&mut self, annotation: Type<'_>) -> bool {
377 self.visit_type(annotation)
378 }
379
380 fn visit_group_type(&mut self, annotation: Type<'_>) -> bool {
381 self.visit_type(annotation)
382 }
383
384 fn visit_optional_type(&mut self, annotation: Type<'_>) -> bool {
385 self.visit_type(annotation)
386 }
387
388 fn visit_union_type(&mut self, annotation: Type<'_>) -> bool {
389 self.visit_type(annotation)
390 }
391
392 fn visit_intersection_type(&mut self, annotation: Type<'_>) -> bool {
393 self.visit_type(annotation)
394 }
395
396 fn visit_error_type(&mut self, annotation: Type<'_>) -> bool {
397 self.visit_type(annotation)
398 }
399
400 fn visit_type_pack(&mut self, _annotation: TypePack<'_>) -> bool {
401 false
402 }
403
404 fn visit_explicit_type_pack(&mut self, annotation: TypePack<'_>) -> bool {
405 self.visit_type_pack(annotation)
406 }
407
408 fn visit_variadic_type_pack(&mut self, annotation: TypePack<'_>) -> bool {
409 self.visit_type_pack(annotation)
410 }
411
412 fn visit_generic_type_pack_type(&mut self, annotation: TypePack<'_>) -> bool {
413 self.visit_type_pack(annotation)
414 }
415}
416
417#[derive(Debug, Clone, Copy, PartialEq)]
418pub enum AstNodeRef<'a, 'ast> {
419 Attribute(&'a Attribute<'ast>),
420 GenericType(&'a GenericType<'ast>),
421 GenericTypePack(&'a GenericTypePack<'ast>),
422 Statement(Statement<'ast>),
423 Expression(Expression<'ast>),
424 Type(Type<'ast>),
425 TypePack(TypePack<'ast>),
426}
427
428mod expression;
429mod statement;
430mod types;
431
432pub(crate) use self::statement::{BlockNode, StatementUnit};
433
434pub use self::{
435 expression::{
436 BinaryOp, ConstantNumberParseResult, Expression, ExpressionInit, ExpressionKind, Function,
437 IndexNameOp, StringQuoteStyle, TableItem, UnaryOp,
438 },
439 statement::{
440 Block, ClassMember, Statement, StatementAssign, StatementClass, StatementCompoundAssign,
441 StatementDeclareExternType, StatementDeclareFunction, StatementDeclareGlobal,
442 StatementError, StatementExpression, StatementFunctionDeclaration, StatementGenericFor,
443 StatementIf, StatementLocal, StatementLocalFunction, StatementNumericFor, StatementRepeat,
444 StatementReturn, StatementTag, StatementTypeAlias, StatementTypeFunction, StatementWhile,
445 },
446 types::{
447 Attribute, AttributeKind, DeclaredExternTypeProperty, DeprecatedInfo, TableAccess,
448 TableTypeIndexer, TableTypeProp, Type, TypeKind, TypeList, TypeOrPack, TypePack,
449 TypePackKind,
450 },
451};
452
453pub(super) fn find_attribute<'ast>(
454 attributes: &[&'ast Attribute<'ast>],
455 kind: AttributeKind,
456) -> Option<&'ast Attribute<'ast>> {
457 attributes
458 .iter()
459 .copied()
460 .find(|attribute| attribute.kind == kind)
461}
462
463pub(super) fn visit_statements<V: AstVisitor>(statements: &[Statement<'_>], visitor: &mut V) {
464 for &statement in statements {
465 statement.visit(visitor);
466 }
467}
468
469pub(super) fn visit_expressions<V: AstVisitor>(expressions: &[Expression<'_>], visitor: &mut V) {
470 for &expression in expressions {
471 expression.visit(visitor);
472 }
473}