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

Function analyze_function_body

src/completion/variable/forward_walk.rs:1745–1801  ·  view source on GitHub ↗

Run the forward walker on a single function/method body and record scope snapshots for diagnostics. `is_static` indicates whether this is a static method. When `false` and `current_class` has a non-empty name, `$this` is seeded in the scope so that expressions like `$this->prop` and `foreach ($this->items as $item)` can resolve without remaining unresolved.

(
    parameters: impl Iterator<Item = &'b FunctionLikeParameter<'b>>,
    body_statements: impl Iterator<Item = &'b Statement<'b>>,
    fn_span_start: u32,
    current_class: &ClassInfo,
    method_n

Source from the content-addressed store, hash-verified

1743/// scope so that expressions like `$this->prop` and `foreach ($this->items as $item)`
1744/// can resolve without remaining unresolved.
1745fn analyze_function_body<'b>(
1746 parameters: impl Iterator<Item = &'b FunctionLikeParameter<'b>>,
1747 body_statements: impl Iterator<Item = &'b Statement<'b>>,
1748 fn_span_start: u32,
1749 current_class: &ClassInfo,
1750 method_name: Option<&str>,
1751 is_static: bool,
1752 diag_ctx: &DiagnosticWalkCtx<'_>,
1753) {
1754 let ctx = ForwardWalkCtx {
1755 current_class,
1756 all_classes: diag_ctx.local_classes,
1757 content: diag_ctx.content,
1758 cursor_offset: u32::MAX,
1759 class_loader: diag_ctx.class_loader,
1760 loaders: diag_ctx.loaders,
1761 resolved_class_cache: diag_ctx.resolved_class_cache,
1762 enclosing_return_type: None,
1763 top_level_scope: None,
1764 };
1765
1766 let mut scope = ScopeState::new();
1767
1768 // Seed `$this` for non-static class methods so that expressions
1769 // referencing `$this` (e.g. `$this->prop`, `foreach ($this->items …)`)
1770 // resolve from the scope instead of falling through to the backward
1771 // scanner.
1772 if !is_static {
1773 seed_this(&mut scope, current_class);
1774 }
1775
1776 // Seed scope with parameter types.
1777 // Detect whether this method has a #[Scope] attribute by scanning
1778 // the source text around the method span for `#[Scope]`.
1779 let has_scope_attr = method_name
1780 .map(|_| detect_scope_attribute_from_source(diag_ctx.content, fn_span_start as usize))
1781 .unwrap_or(false);
1782 seed_params(
1783 &mut scope,
1784 parameters,
1785 fn_span_start,
1786 method_name,
1787 has_scope_attr,
1788 &ctx,
1789 );
1790
1791 // Seed superglobals so that accesses like `$_SERVER['key']` don't
1792 // remain unresolved.
1793 seed_superglobals(&mut scope);
1794
1795 // Record the scope right at the function body start so that
1796 // member accesses on parameters before any assignment are covered.
1797 record_scope_snapshot(fn_span_start, &scope);
1798
1799 // Walk the entire body, recording snapshots at each statement.
1800 walk_body_for_diagnostics(body_statements, &mut scope, &ctx);
1801}
1802

Callers 3

walk_class_member_bodyFunction · 0.85

Calls 7

seed_thisFunction · 0.85
seed_paramsFunction · 0.85
seed_superglobalsFunction · 0.85
record_scope_snapshotFunction · 0.85
mapMethod · 0.45

Tested by

no test coverage detected