mago_syntax/utils/
assignment.rs1use crate::ast::Access;
2use crate::ast::Argument;
3use crate::ast::ArrayElement;
4use crate::ast::Assignment;
5use crate::ast::Call;
6use crate::ast::ClassLikeConstantSelector;
7use crate::ast::ClassLikeMemberSelector;
8use crate::ast::Construct;
9use crate::ast::Expression;
10use crate::ast::MatchArm;
11use crate::ast::PartialApplication;
12use crate::ast::Yield;
13
14#[inline]
21#[must_use]
22pub fn get_assignment_from_expression<'a, 'arena>(
23 expression: &'a Expression<'arena>,
24) -> Option<&'a Assignment<'arena>> {
25 match &expression {
26 Expression::Assignment(assignment_operation) => Some(assignment_operation),
27 Expression::Parenthesized(parenthesized) => get_assignment_from_expression(parenthesized.expression),
28 Expression::Binary(operation) => {
29 get_assignment_from_expression(operation.lhs).or_else(|| get_assignment_from_expression(operation.rhs))
30 }
31 Expression::UnaryPrefix(operation) => get_assignment_from_expression(operation.operand),
32 Expression::UnaryPostfix(operation) => get_assignment_from_expression(operation.operand),
33 Expression::Conditional(conditional) => get_assignment_from_expression(conditional.condition)
34 .or_else(|| conditional.then.as_ref().and_then(|then| get_assignment_from_expression(then)))
35 .or_else(|| get_assignment_from_expression(conditional.r#else)),
36 Expression::Array(array) => array.elements.iter().find_map(|element| match &element {
37 ArrayElement::KeyValue(key_value_array_element) => {
38 get_assignment_from_expression(key_value_array_element.key)
39 .or_else(|| get_assignment_from_expression(key_value_array_element.value))
40 }
41 ArrayElement::Value(value_array_element) => get_assignment_from_expression(value_array_element.value),
42 ArrayElement::Variadic(variadic_array_element) => {
43 get_assignment_from_expression(variadic_array_element.value)
44 }
45 ArrayElement::Missing(_) => None,
46 }),
47 Expression::LegacyArray(legacy_array) => legacy_array.elements.iter().find_map(|element| match &element {
48 ArrayElement::KeyValue(key_value_array_element) => {
49 get_assignment_from_expression(key_value_array_element.key)
50 .or_else(|| get_assignment_from_expression(key_value_array_element.value))
51 }
52 ArrayElement::Value(value_array_element) => get_assignment_from_expression(value_array_element.value),
53 ArrayElement::Variadic(variadic_array_element) => {
54 get_assignment_from_expression(variadic_array_element.value)
55 }
56 ArrayElement::Missing(_) => None,
57 }),
58 Expression::List(list) => list.elements.iter().find_map(|element| match &element {
59 ArrayElement::KeyValue(key_value_array_element) => {
60 get_assignment_from_expression(key_value_array_element.key)
61 .or_else(|| get_assignment_from_expression(key_value_array_element.value))
62 }
63 ArrayElement::Value(value_array_element) => get_assignment_from_expression(value_array_element.value),
64 ArrayElement::Variadic(variadic_array_element) => {
65 get_assignment_from_expression(variadic_array_element.value)
66 }
67 ArrayElement::Missing(_) => None,
68 }),
69 Expression::ArrayAccess(array_access) => get_assignment_from_expression(array_access.array)
70 .or_else(|| get_assignment_from_expression(array_access.index)),
71 Expression::ArrayAppend(array_append) => get_assignment_from_expression(array_append.array),
72 Expression::Match(r#match) => get_assignment_from_expression(r#match.expression).or_else(|| {
73 r#match.arms.iter().find_map(|arm| match arm {
74 MatchArm::Expression(match_expression_arm) => match_expression_arm
75 .conditions
76 .iter()
77 .find_map(|condition| get_assignment_from_expression(condition))
78 .or_else(|| get_assignment_from_expression(match_expression_arm.expression)),
79 MatchArm::Default(match_default_arm) => get_assignment_from_expression(match_default_arm.expression),
80 })
81 }),
82 Expression::Yield(r#yield) => match r#yield {
83 Yield::Value(yield_value) => {
84 yield_value.value.as_ref().and_then(|value| get_assignment_from_expression(value))
85 }
86 Yield::Pair(yield_pair) => get_assignment_from_expression(yield_pair.key)
87 .or_else(|| get_assignment_from_expression(yield_pair.value)),
88 Yield::From(yield_from) => get_assignment_from_expression(yield_from.iterator),
89 },
90 Expression::Construct(construct) => match construct {
91 Construct::Isset(isset_construct) => {
92 isset_construct.values.iter().find_map(|v| get_assignment_from_expression(v))
93 }
94 Construct::Empty(empty_construct) => get_assignment_from_expression(empty_construct.value),
95 Construct::Eval(eval_construct) => get_assignment_from_expression(eval_construct.value),
96 Construct::Include(include_construct) => get_assignment_from_expression(include_construct.value),
97 Construct::IncludeOnce(include_once_construct) => {
98 get_assignment_from_expression(include_once_construct.value)
99 }
100 Construct::Require(require_construct) => get_assignment_from_expression(require_construct.value),
101 Construct::RequireOnce(require_once_construct) => {
102 get_assignment_from_expression(require_once_construct.value)
103 }
104 Construct::Print(print_construct) => get_assignment_from_expression(print_construct.value),
105 Construct::Exit(exit_construct) => exit_construct.arguments.as_ref().and_then(|arguments| {
106 arguments.arguments.iter().find_map(|argument| {
107 get_assignment_from_expression(match &argument {
108 Argument::Positional(positional_argument) => &positional_argument.value,
109 Argument::Named(named_argument) => &named_argument.value,
110 })
111 })
112 }),
113 Construct::Die(die_construct) => die_construct.arguments.as_ref().and_then(|arguments| {
114 arguments.arguments.iter().find_map(|argument| {
115 get_assignment_from_expression(match &argument {
116 Argument::Positional(positional_argument) => &positional_argument.value,
117 Argument::Named(named_argument) => &named_argument.value,
118 })
119 })
120 }),
121 },
122 Expression::Throw(throw) => get_assignment_from_expression(throw.exception),
123 Expression::Clone(clone) => get_assignment_from_expression(clone.object),
124 Expression::Call(call) => match &call {
125 Call::Function(function_call) => get_assignment_from_expression(function_call.function).or_else(|| {
126 function_call.argument_list.arguments.iter().find_map(|argument| match &argument {
127 Argument::Positional(positional_argument) => {
128 get_assignment_from_expression(&positional_argument.value)
129 }
130 Argument::Named(named_argument) => get_assignment_from_expression(&named_argument.value),
131 })
132 }),
133 Call::Method(method_call) => get_assignment_from_expression(method_call.object)
134 .or_else(|| match &method_call.method {
135 ClassLikeMemberSelector::Expression(class_like_member_expression_selector) => {
136 get_assignment_from_expression(class_like_member_expression_selector.expression)
137 }
138 _ => None,
139 })
140 .or_else(|| {
141 method_call.argument_list.arguments.iter().find_map(|argument| match &argument {
142 Argument::Positional(positional_argument) => {
143 get_assignment_from_expression(&positional_argument.value)
144 }
145 Argument::Named(named_argument) => get_assignment_from_expression(&named_argument.value),
146 })
147 }),
148 Call::NullSafeMethod(null_safe_method_call) => get_assignment_from_expression(null_safe_method_call.object)
149 .or_else(|| match &null_safe_method_call.method {
150 ClassLikeMemberSelector::Expression(class_like_member_expression_selector) => {
151 get_assignment_from_expression(class_like_member_expression_selector.expression)
152 }
153 _ => None,
154 })
155 .or_else(|| {
156 null_safe_method_call.argument_list.arguments.iter().find_map(|argument| match &argument {
157 Argument::Positional(positional_argument) => {
158 get_assignment_from_expression(&positional_argument.value)
159 }
160 Argument::Named(named_argument) => get_assignment_from_expression(&named_argument.value),
161 })
162 }),
163 Call::StaticMethod(static_method_call) => get_assignment_from_expression(static_method_call.class)
164 .or_else(|| match &static_method_call.method {
165 ClassLikeMemberSelector::Expression(class_like_member_expression_selector) => {
166 get_assignment_from_expression(class_like_member_expression_selector.expression)
167 }
168 _ => None,
169 })
170 .or_else(|| {
171 static_method_call.argument_list.arguments.iter().find_map(|argument| match &argument {
172 Argument::Positional(positional_argument) => {
173 get_assignment_from_expression(&positional_argument.value)
174 }
175 Argument::Named(named_argument) => get_assignment_from_expression(&named_argument.value),
176 })
177 }),
178 },
179 Expression::Access(access) => match access {
180 Access::Property(property_access) => {
181 get_assignment_from_expression(property_access.object).or_else(|| match &property_access.property {
182 ClassLikeMemberSelector::Expression(class_like_member_expression_selector) => {
183 get_assignment_from_expression(class_like_member_expression_selector.expression)
184 }
185 _ => None,
186 })
187 }
188 Access::NullSafeProperty(null_safe_property_access) => {
189 get_assignment_from_expression(null_safe_property_access.object).or_else(|| {
190 match &null_safe_property_access.property {
191 ClassLikeMemberSelector::Expression(class_like_member_expression_selector) => {
192 get_assignment_from_expression(class_like_member_expression_selector.expression)
193 }
194 _ => None,
195 }
196 })
197 }
198 Access::StaticProperty(static_property_access) => {
199 get_assignment_from_expression(static_property_access.class)
200 }
201 Access::ClassConstant(class_constant_access) => get_assignment_from_expression(class_constant_access.class)
202 .or_else(|| match &class_constant_access.constant {
203 ClassLikeConstantSelector::Expression(class_like_member_expression_selector) => {
204 get_assignment_from_expression(class_like_member_expression_selector.expression)
205 }
206 _ => None,
207 }),
208 },
209 Expression::PartialApplication(partial_application) => match partial_application {
210 PartialApplication::Function(function_partial_application) => {
211 get_assignment_from_expression(function_partial_application.function)
212 }
213 PartialApplication::Method(method_partial_application) => {
214 get_assignment_from_expression(method_partial_application.object).or_else(|| {
215 match &method_partial_application.method {
216 ClassLikeMemberSelector::Expression(class_like_member_expression_selector) => {
217 get_assignment_from_expression(class_like_member_expression_selector.expression)
218 }
219 _ => None,
220 }
221 })
222 }
223 PartialApplication::StaticMethod(static_method_partial_application) => {
224 get_assignment_from_expression(static_method_partial_application.class).or_else(|| {
225 match &static_method_partial_application.method {
226 ClassLikeMemberSelector::Expression(class_like_member_expression_selector) => {
227 get_assignment_from_expression(class_like_member_expression_selector.expression)
228 }
229 _ => None,
230 }
231 })
232 }
233 },
234 Expression::Instantiation(instantiation) => get_assignment_from_expression(instantiation.class).or_else(|| {
235 instantiation.argument_list.as_ref().and_then(|arguments| {
236 arguments.arguments.iter().find_map(|argument| match &argument {
237 Argument::Positional(positional_argument) => {
238 get_assignment_from_expression(&positional_argument.value)
239 }
240 Argument::Named(named_argument) => get_assignment_from_expression(&named_argument.value),
241 })
242 })
243 }),
244 _ => None,
245 }
246}