luau_parser/types/block/statement.rs
1//! # Shared types
2//!
3//! Module holding types that'll be used everywhere around the parser and most likely
4//! outside it too, like in a formatter or a lsp.
5
6use luau_lexer::prelude::Token;
7use luau_parser_derive::{Print, Range};
8
9use crate::types::{
10 CompoundSetExpression, DoBlock, EndOfFile, Expression, FunctionCall, GenericFor,
11 GlobalFunction, IfStatement, List, LocalAssignment, LocalFunction, NumericalFor, Pointer,
12 RepeatBlock, SetExpression, TypeDefinition, TypeFunction, WhileLoop,
13};
14
15/// Helper macro to generate the [`Statement`] enum.
16macro_rules! generate_statement {
17 ($(
18 $( #[$meta:meta] )*
19 $name:ident($ty:ty)
20 ),* $(,)?) => {
21 /// All possible statements in a [`CST`](crate::types::Cst), excluding
22 /// [ending ones](TerminationStatement).
23 #[derive(Clone, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord, Range, Print)]
24 #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
25 pub enum Statement {
26 /// This statement had an error and couldn't parse anything.
27 #[default]
28 ERROR,
29
30 $( $( #[$meta] )* $name(Pointer<$ty>) ,)*
31 }
32
33 impl Statement {
34 pub(crate) fn __parse(
35 token: luau_lexer::prelude::Token,
36 lexer: &mut luau_lexer::prelude::Lexer,
37 errors: &mut Vec<luau_lexer::prelude::Error>
38 ) -> Option<Self> {
39 use $crate::types::Parse as _;
40
41 $( if let Some(value) = <$ty>::parse(token.clone(), lexer, errors) {
42 Some(Self::$name(Pointer::new(value)))
43 } else )* {
44 None
45 }
46 }
47 }
48 };
49}
50
51generate_statement! {
52 /// A local function.
53 ///
54 /// ```lua
55 /// local function foo(bar: string): Qux
56 /// end
57 /// ```
58 LocalFunction(LocalFunction),
59
60 /// A variable declaration.
61 ///
62 /// ```lua
63 /// local foo = bar
64 /// local bar = function()
65 /// end
66 /// local qux = {}
67 /// ```
68 LocalAssignment(LocalAssignment),
69
70 /// A type definition.
71 ///
72 /// ```lua
73 /// type Foo = Bar<string, number>
74 /// export type Bar<P, R> = (param: P) -> R
75 /// type qux = {}
76 /// ```
77 TypeDefinition(TypeDefinition),
78
79 /// An if statement.
80 ///
81 /// ```lua
82 /// if a then
83 /// print("It's a")
84 /// elseif b then
85 /// print("It's b")
86 /// else
87 /// print("It's neither a or b :(")
88 /// end
89 /// ```
90 IfStatement(IfStatement),
91
92 /// A do block.
93 ///
94 /// ```lua
95 /// do
96 /// print("Hello, World!")
97 /// end
98 /// ```
99 ///
100 /// # Note
101 ///
102 /// This struct isn't used for while or for loops, they have their own tokens, and have
103 /// do blocks as part of their token.
104 DoBlock(DoBlock),
105
106 /// A generic for loop.
107 ///
108 /// ```lua
109 /// for i, v in ipairs(t) do
110 /// print(`{i}: {v}`)
111 /// end
112 /// ```
113 GenericFor(GenericFor),
114
115 /// A numerical for loop.
116 ///
117 /// ```lua
118 /// for i = 1, 100, 2 do
119 /// print(i)
120 /// end
121 /// ```
122 NumericalFor(NumericalFor),
123
124 /// A repeat block.
125 ///
126 /// ```lua
127 /// local i = 0
128 /// repeat
129 /// print(i)
130 /// i += 1
131 /// until i == 10
132 /// ```
133 RepeatBlock(RepeatBlock),
134
135 /// A while loop.
136 ///
137 /// ```lua
138 /// local i = 0
139 /// while i <= 10 do
140 /// print(i)
141 /// i += 1
142 /// end
143 /// ```
144 WhileLoop(WhileLoop),
145
146 /// A set expression.
147 ///
148 /// ```lua
149 /// a = "test"
150 /// b, c = true, false, 1
151 /// d, e, f = foo()
152 /// ```
153 SetExpression(SetExpression),
154
155 /// A compound set expression.
156 ///
157 /// ```lua
158 /// foo += 1
159 /// bar //= 2
160 /// ```
161 CompoundSetExpression(CompoundSetExpression),
162
163 /// A function call.
164 ///
165 /// ```lua
166 /// local _ = foo(1, 2, 3)
167 /// ```
168 FunctionCall(FunctionCall),
169
170 /// A global function.
171 ///
172 /// ```lua
173 /// function foo(bar: string): Qux
174 /// end
175 /// function foo:Qux(bar: string): Qux
176 /// end
177 /// ```
178 GlobalFunction(GlobalFunction),
179
180 /// A type function
181 ///
182 /// ```lua
183 /// type function Foo(ty)
184 /// return types.unionof(types.string, ty)
185 /// end
186 ///
187 /// export type function Bar(ty)
188 /// return types.unionof(types.number, ty)
189 /// end
190 ///
191 /// type qux = Bar<Foo<boolean>> -- number | string | boolean
192 /// ```
193 TypeFunction(TypeFunction),
194
195 /// The [`EndOfFile`] token. Read it's documentation for it's uses.
196 EndOfFile(EndOfFile),
197}
198
199/// An enum representing different types of statements that can end a block of code.
200/// These statements may or may not be present.
201#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Range)]
202#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
203pub enum TerminationStatement {
204 /// The `break` keyword.
205 ///
206 /// ```lua
207 /// break
208 /// ```
209 Break(Token),
210
211 /// The `continue` keyword.
212 ///
213 /// ```lua
214 /// continue
215 /// ```
216 Continue(Token),
217
218 /// A `return` statement. Can be in multiple forms:
219 ///
220 /// ```lua
221 /// return
222 /// -- or
223 /// return value
224 /// -- or
225 /// return value1, value2, ...
226 /// ```
227 Return {
228 /// The `return` keyword.
229 return_keyword: Token,
230
231 /// The list of expressions after it.
232 #[range_or = "return_keyword"]
233 expressions: Option<List<Pointer<Expression>>>,
234 },
235}