Try to enter a closure or arrow function if the cursor is inside one. Returns `true` if the cursor was inside a closure and the scope was updated accordingly.
(
stmt: &'b Statement<'b>,
scope: &mut ScopeState,
ctx: &ForwardWalkCtx<'_>,
)
| 9075 | /// Returns `true` if the cursor was inside a closure and the scope was |
| 9076 | /// updated accordingly. |
| 9077 | fn try_enter_closure<'b>( |
| 9078 | stmt: &'b Statement<'b>, |
| 9079 | scope: &mut ScopeState, |
| 9080 | ctx: &ForwardWalkCtx<'_>, |
| 9081 | ) -> bool { |
| 9082 | // Walk the statement's expression tree looking for closures/arrow |
| 9083 | // functions that contain the cursor. |
| 9084 | if let Statement::Expression(expr_stmt) = stmt { |
| 9085 | return try_enter_closure_expr(expr_stmt.expression, scope, ctx, None); |
| 9086 | } |
| 9087 | if let Statement::Return(ret) = stmt |
| 9088 | && let Some(val) = ret.value |
| 9089 | { |
| 9090 | return try_enter_closure_expr(val, scope, ctx, None); |
| 9091 | } |
| 9092 | // Closures/arrow functions can appear inside if/while/for/switch |
| 9093 | // conditions (e.g. `if (array_any($items, fn($x) => $x->...))`). |
| 9094 | // Recurse into these condition expressions so the forward walker |
| 9095 | // can enter the closure scope. |
| 9096 | if let Statement::If(if_stmt) = stmt { |
| 9097 | if try_enter_closure_expr(if_stmt.condition, scope, ctx, None) { |
| 9098 | return true; |
| 9099 | } |
| 9100 | // Also check elseif conditions and bodies for closures. |
| 9101 | match &if_stmt.body { |
| 9102 | IfBody::Statement(body) => { |
| 9103 | for ei in body.else_if_clauses.iter() { |
| 9104 | if try_enter_closure_expr(ei.condition, scope, ctx, None) { |
| 9105 | return true; |
| 9106 | } |
| 9107 | } |
| 9108 | } |
| 9109 | IfBody::ColonDelimited(body) => { |
| 9110 | for ei in body.else_if_clauses.iter() { |
| 9111 | if try_enter_closure_expr(ei.condition, scope, ctx, None) { |
| 9112 | return true; |
| 9113 | } |
| 9114 | } |
| 9115 | } |
| 9116 | } |
| 9117 | } |
| 9118 | if let Statement::While(while_stmt) = stmt |
| 9119 | && try_enter_closure_expr(while_stmt.condition, scope, ctx, None) |
| 9120 | { |
| 9121 | return true; |
| 9122 | } |
| 9123 | if let Statement::For(for_stmt) = stmt { |
| 9124 | for cond in for_stmt.conditions.iter() { |
| 9125 | if try_enter_closure_expr(cond, scope, ctx, None) { |
| 9126 | return true; |
| 9127 | } |
| 9128 | } |
| 9129 | } |
| 9130 | if let Statement::Switch(switch) = stmt { |
| 9131 | if try_enter_closure_expr(switch.expression, scope, ctx, None) { |
| 9132 | return true; |
| 9133 | } |
| 9134 | for case in switch.body.cases().iter() { |
no test coverage detected