darklua_core/nodes/
function_call.rs1use crate::nodes::{Arguments, Expression, Identifier, Prefix, Token};
2
3#[derive(Clone, Debug, PartialEq, Eq)]
5pub struct FunctionCallTokens {
6 pub colon: Option<Token>,
7}
8
9impl FunctionCallTokens {
10 super::impl_token_fns!(iter = [colon]);
11}
12
13#[derive(Clone, Debug, PartialEq, Eq)]
15pub struct FunctionCall {
16 prefix: Box<Prefix>,
17 arguments: Arguments,
18 method: Option<Identifier>,
19 tokens: Option<FunctionCallTokens>,
20}
21
22impl FunctionCall {
23 pub fn new(prefix: Prefix, arguments: Arguments, method: Option<Identifier>) -> Self {
25 Self {
26 prefix: Box::new(prefix),
27 arguments,
28 method,
29 tokens: None,
30 }
31 }
32
33 pub fn from_name<T: Into<Identifier>>(name: T) -> Self {
35 Self {
36 prefix: Box::new(name.into().into()),
37 arguments: Arguments::default(),
38 method: None,
39 tokens: None,
40 }
41 }
42
43 pub fn from_prefix<T: Into<Prefix>>(prefix: T) -> Self {
45 Self {
46 prefix: Box::new(prefix.into()),
47 arguments: Arguments::default(),
48 method: None,
49 tokens: None,
50 }
51 }
52
53 pub fn with_tokens(mut self, tokens: FunctionCallTokens) -> Self {
55 self.tokens = Some(tokens);
56 self
57 }
58
59 #[inline]
61 pub fn set_tokens(&mut self, tokens: FunctionCallTokens) {
62 self.tokens = Some(tokens);
63 }
64
65 #[inline]
67 pub fn get_tokens(&self) -> Option<&FunctionCallTokens> {
68 self.tokens.as_ref()
69 }
70
71 pub fn with_arguments<A: Into<Arguments>>(mut self, arguments: A) -> Self {
73 self.arguments = arguments.into();
74 self
75 }
76
77 pub fn with_argument<T: Into<Expression>>(mut self, argument: T) -> Self {
79 self.arguments = self.arguments.with_argument(argument);
80 self
81 }
82
83 pub fn with_method<IntoString: Into<Identifier>>(mut self, method: IntoString) -> Self {
85 self.method.replace(method.into());
86 self
87 }
88
89 #[inline]
91 pub fn get_arguments(&self) -> &Arguments {
92 &self.arguments
93 }
94
95 #[inline]
97 pub fn get_method(&self) -> Option<&Identifier> {
98 self.method.as_ref()
99 }
100
101 #[inline]
103 pub fn has_method(&self) -> bool {
104 self.method.is_some()
105 }
106
107 #[inline]
109 pub fn get_prefix(&self) -> &Prefix {
110 &self.prefix
111 }
112
113 #[inline]
115 pub fn take_method(&mut self) -> Option<Identifier> {
116 let method = self.method.take();
117 if let Some(tokens) = self.tokens.as_mut() {
118 tokens.colon = None;
119 }
120 method
121 }
122
123 #[inline]
125 pub fn set_arguments(&mut self, arguments: Arguments) {
126 self.arguments = arguments;
127 }
128
129 #[inline]
131 pub fn set_method(&mut self, method: Identifier) {
132 self.method.replace(method);
133 }
134
135 #[inline]
137 pub fn mutate_arguments(&mut self) -> &mut Arguments {
138 &mut self.arguments
139 }
140
141 #[inline]
143 pub fn mutate_prefix(&mut self) -> &mut Prefix {
144 &mut self.prefix
145 }
146
147 pub fn mutate_first_token(&mut self) -> &mut Token {
150 self.prefix.mutate_first_token()
151 }
152
153 pub fn mutate_last_token(&mut self) -> &mut Token {
156 self.arguments.mutate_last_token()
157 }
158
159 super::impl_token_fns!(iter = [tokens, method]);
160}
161
162#[cfg(test)]
163mod tests {
164 use super::*;
165 use crate::{nodes::Statement, Parser};
166
167 fn parse_call(code: &str) -> FunctionCall {
168 let parser = Parser::default().preserve_tokens();
169 let block = parser.parse(code).expect("code should parse");
170 if let Some(statement) = block.first_statement() {
171 if let Statement::Call(call) = statement {
172 return call.clone();
173 }
174 }
175 panic!("failed to parse call from: {}", code);
176 }
177
178 #[test]
179 fn test_take_method_removes_colon_token() {
180 let mut call = parse_call("obj:method()");
181
182 assert!(call.get_tokens().unwrap().colon.is_some());
183 call.take_method();
184 assert!(call.get_tokens().unwrap().colon.is_none());
185 }
186}