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

Function process_switch

src/completion/variable/forward_walk.rs:7303–7359  ·  view source on GitHub ↗

Process a `switch` statement. Each case arm is walked on a clone of the pre-switch scope so that assignments in one arm don't leak into another. After all arms are walked, the resulting scopes are merged (union of types), matching the runtime behaviour where only one arm executes. Fall-through cases (cases with no statements) share their scope with the next non-empty case, mirroring PHP semanti

(switch: &'b Switch<'b>, scope: &mut ScopeState, ctx: &ForwardWalkCtx<'_>)

Source from the content-addressed store, hash-verified

7301/// Fall-through cases (cases with no statements) share their scope
7302/// with the next non-empty case, mirroring PHP semantics.
7303fn process_switch<'b>(switch: &'b Switch<'b>, scope: &mut ScopeState, ctx: &ForwardWalkCtx<'_>) {
7304 let pre_switch_scope = scope.clone();
7305 let cases: Vec<_> = switch.body.cases().iter().collect();
7306
7307 if cases.is_empty() {
7308 return;
7309 }
7310
7311 let mut branch_scopes: Vec<ScopeState> = Vec::new();
7312 let mut has_default = false;
7313
7314 // Walk cases, accumulating fall-through groups.
7315 let mut accumulated_stmts: Vec<&Statement<'b>> = Vec::new();
7316 for case in &cases {
7317 if case.is_default() {
7318 has_default = true;
7319 }
7320
7321 let stmts: Vec<_> = case.statements().iter().collect();
7322 if stmts.is_empty() {
7323 // Fall-through: no statements, will share scope with next case.
7324 continue;
7325 }
7326
7327 accumulated_stmts.extend(stmts);
7328
7329 let mut case_scope = pre_switch_scope.clone();
7330 walk_body_forward(accumulated_stmts.iter().copied(), &mut case_scope, ctx);
7331 branch_scopes.push(case_scope);
7332 accumulated_stmts.clear();
7333 }
7334
7335 // Handle trailing fall-through cases (empty cases at the end).
7336 if !accumulated_stmts.is_empty() {
7337 let mut case_scope = pre_switch_scope.clone();
7338 walk_body_forward(accumulated_stmts.iter().copied(), &mut case_scope, ctx);
7339 branch_scopes.push(case_scope);
7340 }
7341
7342 if branch_scopes.is_empty() {
7343 return;
7344 }
7345
7346 // Merge all branch scopes.
7347 let mut merged = branch_scopes[0].clone();
7348 for s in &branch_scopes[1..] {
7349 merged.merge_branch(s);
7350 }
7351
7352 // If there is no default case, the switch might not execute any
7353 // arm at all, so merge with the pre-switch scope.
7354 if !has_default {
7355 merged.merge_branch(&pre_switch_scope);
7356 }
7357
7358 *scope = merged;
7359}
7360

Callers 1

process_statementFunction · 0.85

Calls 7

walk_body_forwardFunction · 0.85
cloneMethod · 0.80
iterMethod · 0.80
extendMethod · 0.80
pushMethod · 0.80
merge_branchMethod · 0.80
is_emptyMethod · 0.45

Tested by

no test coverage detected