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}