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

Function check_catch_frame

src/diagnostics/unused_variables.rs:347–418  ·  view source on GitHub ↗

Check a catch frame for unused catch variables only. Catch frames inherit the parent scope, so we only flag variables that are in the catch frame's own `parameters` list (the catch variable itself, e.g. `$e` in `catch (Exception $e)`).

(
    frame: &crate::scope_collector::Frame,
    scope: &ScopeMap,
    ctx: &mut DiagnosticCtx<'_>,
    always_skip: &HashSet<&str>,
)

Source from the content-addressed store, hash-verified

345/// that are in the catch frame's own `parameters` list (the catch
346/// variable itself, e.g. `$e` in `catch (Exception $e)`).
347fn check_catch_frame(
348 frame: &crate::scope_collector::Frame,
349 scope: &ScopeMap,
350 ctx: &mut DiagnosticCtx<'_>,
351 always_skip: &HashSet<&str>,
352) {
353 for param in &frame.parameters {
354 let var_name = param.as_str();
355
356 if always_skip.contains(var_name) {
357 continue;
358 }
359 if var_name == "$_" || var_name.starts_with("$_") {
360 continue;
361 }
362
363 // Check for reads inside the catch block body.
364 let has_read = scope.accesses.iter().any(|a| {
365 a.name == var_name
366 && matches!(a.kind, AccessKind::Read | AccessKind::ReadWrite)
367 && a.offset >= frame.start
368 && a.offset <= frame.end
369 });
370
371 if has_read {
372 continue;
373 }
374
375 // Find the catch variable's write offset — the closest write
376 // *before* this frame's start. Using `.find()` would return the
377 // first write in the file, which for nested catches with the same
378 // variable name points at the wrong catch clause.
379 let diag_offset = scope
380 .accesses
381 .iter()
382 .filter(|a| {
383 a.name == var_name && matches!(a.kind, AccessKind::Write) && a.offset <= frame.start
384 })
385 .max_by_key(|a| a.offset)
386 .or_else(|| {
387 scope
388 .accesses
389 .iter()
390 .find(|a| a.name == var_name && matches!(a.kind, AccessKind::Write))
391 })
392 .map(|a| a.offset)
393 .unwrap_or(frame.start);
394
395 let var_len = var_name.len();
396 let range = match ctx.backend.offset_range_to_lsp_range(
397 ctx.uri,
398 ctx.content,
399 diag_offset as usize,
400 diag_offset as usize + var_len,
401 ) {
402 Some(r) => r,
403 None => continue,
404 };

Callers 1

check_scopeFunction · 0.85

Calls 8

as_strMethod · 0.80
containsMethod · 0.80
iterMethod · 0.80
filterMethod · 0.80
pushMethod · 0.80
mapMethod · 0.45
findMethod · 0.45

Tested by

no test coverage detected