MCPcopy Create free account
hub / github.com/PHPantom-dev/phpantom_lsp / process_do_while

Function process_do_while

src/completion/variable/forward_walk.rs:7152–7193  ·  view source on GitHub ↗

Process a `do-while` loop. Uses the same assignment-depth-bounded iteration as `process_foreach`: a cheap AST walk determines the dependency chain depth, then the body is re-walked up to that many times with fixed-point early exit. Unlike `for`/`while`, the body of a `do-while` always executes at least once, so we do NOT merge with a pre-loop scope at the end.

(dw: &'b DoWhile<'b>, scope: &mut ScopeState, ctx: &ForwardWalkCtx<'_>)

Source from the content-addressed store, hash-verified

7150/// Unlike `for`/`while`, the body of a `do-while` always executes at
7151/// least once, so we do NOT merge with a pre-loop scope at the end.
7152fn process_do_while<'b>(dw: &'b DoWhile<'b>, scope: &mut ScopeState, ctx: &ForwardWalkCtx<'_>) {
7153 let loop_depth = enter_loop();
7154
7155 // Hard limit: skip the body entirely at excessive nesting depth.
7156 if loop_depth > MAX_LOOP_DEPTH {
7157 leave_loop(loop_depth);
7158 return;
7159 }
7160
7161 let pre_loop_scope = scope.clone();
7162
7163 // ── Assignment-depth-bounded loop iteration ─────────────────
7164 let body_stmts: Vec<&Statement<'b>> = vec![dw.statement];
7165 let assignment_depth =
7166 clamp_iterations_for_depth(assignment_map_depth(&body_stmts), loop_depth);
7167
7168 // ── Initial walk (always performed) ─────────────────────────
7169 walk_body_forward(std::iter::once(dw.statement), scope, ctx);
7170
7171 // ── Re-walk iterations (only if types changed) ──────────────
7172 for _iteration in 0..assignment_depth.saturating_sub(1) {
7173 if !scope_has_changes(&pre_loop_scope, scope) {
7174 break;
7175 }
7176
7177 let mut next_scope = pre_loop_scope.clone();
7178 next_scope.merge_branch(scope);
7179 process_condition_assignment(dw.condition, &mut next_scope, ctx);
7180 seed_pass_by_ref_in_condition(dw.condition, &mut next_scope, ctx);
7181 *scope = next_scope;
7182
7183 walk_body_forward(std::iter::once(dw.statement), scope, ctx);
7184 }
7185
7186 // After the do-while loop, the condition evaluated to false (that's
7187 // why the loop exited). Apply the inverse of the condition to narrow
7188 // types. For example: `do { $a = getA(); } while ($a !== null);`
7189 // => after loop, $a is null.
7190 apply_condition_narrowing_inverse(dw.condition, scope, ctx);
7191
7192 leave_loop(loop_depth);
7193}
7194
7195/// Process a `try-catch-finally` statement.
7196fn process_try<'b>(try_stmt: &'b Try<'b>, scope: &mut ScopeState, ctx: &ForwardWalkCtx<'_>) {

Callers 1

process_statementFunction · 0.85

Calls 11

enter_loopFunction · 0.85
leave_loopFunction · 0.85
assignment_map_depthFunction · 0.85
walk_body_forwardFunction · 0.85
scope_has_changesFunction · 0.85
cloneMethod · 0.80
merge_branchMethod · 0.80

Tested by

no test coverage detected