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