darklua_core/nodes/statements/
generic_for.rs

1use crate::nodes::{Block, Expression, Token, TypedIdentifier};
2
3/// Tokens associated with a generic for statement.
4#[derive(Clone, Debug, PartialEq, Eq)]
5pub struct GenericForTokens {
6    pub r#for: Token,
7    pub r#in: Token,
8    pub r#do: Token,
9    pub end: Token,
10    /// The tokens for the commas between identifiers.
11    pub identifier_commas: Vec<Token>,
12    /// The tokens for the commas between values.
13    pub value_commas: Vec<Token>,
14}
15
16impl GenericForTokens {
17    super::impl_token_fns!(
18        target = [r#for, r#in, r#do, end]
19        iter = [identifier_commas, value_commas]
20    );
21}
22
23/// Represents a generic for loop statement.
24#[derive(Clone, Debug, PartialEq, Eq)]
25pub struct GenericForStatement {
26    identifiers: Vec<TypedIdentifier>,
27    expressions: Vec<Expression>,
28    block: Block,
29    tokens: Option<GenericForTokens>,
30}
31
32impl GenericForStatement {
33    /// Creates a new generic for statement.
34    pub fn new<B: Into<Block>>(
35        identifiers: Vec<TypedIdentifier>,
36        expressions: Vec<Expression>,
37        block: B,
38    ) -> Self {
39        Self {
40            identifiers,
41            expressions,
42            block: block.into(),
43            tokens: None,
44        }
45    }
46
47    /// Sets the tokens for this generic for statement.
48    pub fn with_tokens(mut self, tokens: GenericForTokens) -> Self {
49        self.tokens = Some(tokens);
50        self
51    }
52
53    /// Sets the tokens for this generic for statement.
54    #[inline]
55    pub fn set_tokens(&mut self, tokens: GenericForTokens) {
56        self.tokens = Some(tokens);
57    }
58
59    /// Returns the tokens for this generic for statement, if any.
60    #[inline]
61    pub fn get_tokens(&self) -> Option<&GenericForTokens> {
62        self.tokens.as_ref()
63    }
64
65    /// Returns a mutable reference to the tokens, if any.
66    #[inline]
67    pub fn mutate_tokens(&mut self) -> Option<&mut GenericForTokens> {
68        self.tokens.as_mut()
69    }
70
71    /// Returns the loop's block.
72    #[inline]
73    pub fn get_block(&self) -> &Block {
74        &self.block
75    }
76
77    /// Returns the list of identifiers that receive iterator values.
78    #[inline]
79    pub fn get_identifiers(&self) -> &Vec<TypedIdentifier> {
80        &self.identifiers
81    }
82
83    /// Returns an iterator over the identifiers.
84    #[inline]
85    pub fn iter_identifiers(&self) -> impl Iterator<Item = &TypedIdentifier> {
86        self.identifiers.iter()
87    }
88
89    /// Returns the list of expressions that produce the iterator values.
90    #[inline]
91    pub fn get_expressions(&self) -> &Vec<Expression> {
92        &self.expressions
93    }
94
95    /// Returns an iterator over the expressions.
96    #[inline]
97    pub fn iter_expressions(&self) -> impl Iterator<Item = &Expression> {
98        self.expressions.iter()
99    }
100
101    /// Returns a mutable iterator over the identifiers.
102    #[inline]
103    pub fn iter_mut_identifiers(&mut self) -> impl Iterator<Item = &mut TypedIdentifier> {
104        self.identifiers.iter_mut()
105    }
106
107    /// Returns a mutable iterator over the expressions.
108    #[inline]
109    pub fn iter_mut_expressions(&mut self) -> impl Iterator<Item = &mut Expression> {
110        self.expressions.iter_mut()
111    }
112
113    /// Returns a mutable reference to the expressions vector.
114    #[inline]
115    pub fn mutate_expressions(&mut self) -> &mut Vec<Expression> {
116        &mut self.expressions
117    }
118
119    /// Returns a mutable reference to the block.
120    #[inline]
121    pub fn mutate_block(&mut self) -> &mut Block {
122        &mut self.block
123    }
124
125    /// Returns the number of identifiers.
126    #[inline]
127    pub fn identifiers_len(&self) -> usize {
128        self.identifiers.len()
129    }
130
131    /// Returns the number of expressions.
132    #[inline]
133    pub fn expressions_len(&self) -> usize {
134        self.expressions.len()
135    }
136
137    /// Removes type annotations from all identifiers.
138    pub fn clear_types(&mut self) {
139        for identifier in &mut self.identifiers {
140            identifier.remove_type();
141        }
142    }
143
144    super::impl_token_fns!(iter = [tokens, identifiers]);
145
146    /// Returns a mutable reference to the first token for this statement, creating it if missing.
147    pub fn mutate_first_token(&mut self) -> &mut Token {
148        self.set_default_tokens();
149        &mut self.tokens.as_mut().unwrap().r#for
150    }
151
152    /// Returns a mutable reference to the last token for this statement,
153    /// creating it if missing.
154    pub fn mutate_last_token(&mut self) -> &mut Token {
155        self.set_default_tokens();
156        &mut self.tokens.as_mut().unwrap().end
157    }
158
159    fn set_default_tokens(&mut self) {
160        if self.tokens.is_none() {
161            self.tokens = Some(GenericForTokens {
162                r#for: Token::from_content("for"),
163                r#in: Token::from_content("in"),
164                r#do: Token::from_content("do"),
165                end: Token::from_content("end"),
166                identifier_commas: Vec::new(),
167                value_commas: Vec::new(),
168            });
169        }
170    }
171}