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

Function seed_closure_params

src/completion/variable/forward_walk.rs:809–982  ·  view source on GitHub ↗
(
    scope: &mut ScopeState,
    parameter_list: &FunctionLikeParameterList<'_>,
    fn_span_start: u32,
    inferred_types: &[PhpType],
    ctx: &ForwardWalkCtx<'_>,
)

Source from the content-addressed store, hash-verified

807}
808
809fn seed_closure_params(
810 scope: &mut ScopeState,
811 parameter_list: &FunctionLikeParameterList<'_>,
812 fn_span_start: u32,
813 inferred_types: &[PhpType],
814 ctx: &ForwardWalkCtx<'_>,
815) {
816 for (idx, param) in parameter_list.parameters.iter().enumerate() {
817 let pname = param.variable.name.to_string();
818 let is_variadic = param.ellipsis.is_some();
819
820 let native_type = param.hint.as_ref().map(|h| extract_hint_type(h));
821
822 // Check the `@param` docblock annotation.
823 //
824 // Only trust the result when the docblock is directly attached
825 // to this closure/arrow function (no intervening code). Without
826 // this guard, sibling arrow functions that share a parameter
827 // name (e.g. two `array_map(fn($row) => …)` calls) would leak
828 // `@param` annotations from one closure to the other, because
829 // arrow functions don't introduce `{`/`}` scope boundaries and
830 // `find_iterable_raw_type_in_source` scans backward freely.
831 let raw_docblock_type = crate::docblock::find_iterable_raw_type_in_source(
832 ctx.content,
833 fn_span_start as usize,
834 &pname,
835 )
836 .filter(|_| is_docblock_adjacent(ctx.content, fn_span_start as usize))
837 .map(|t| crate::util::resolve_php_type_names(&t, ctx.class_loader));
838
839 let effective_type = crate::docblock::resolve_effective_type_typed(
840 native_type.as_ref(),
841 raw_docblock_type.as_ref(),
842 );
843
844 // Substitute method-level template params with their bounds.
845 let effective_type = effective_type.map(|ty| {
846 let ty = super::resolution::substitute_template_param_bounds(
847 ty,
848 ctx.content,
849 fn_span_start as usize,
850 );
851 super::resolution::substitute_class_string_template_bounds(
852 ty,
853 ctx.content,
854 fn_span_start as usize,
855 )
856 });
857
858 let inferred_for_idx = inferred_types.get(idx);
859
860 // When the explicit hint is a bare class name and the inferred
861 // type is the same class WITH generic args, prefer the inferred
862 // type (preserves template substitution).
863 let use_inferred_over_explicit = if let Some(ref eff) = effective_type
864 && let Some(inferred) = inferred_for_idx
865 {
866 super::closure_resolution::inferred_type_is_more_specific_pub(eff, inferred)

Callers 2

walk_closures_in_exprFunction · 0.85
try_enter_closure_exprFunction · 0.85

Calls 15

extract_hint_typeFunction · 0.85
is_docblock_adjacentFunction · 0.85
resolve_php_type_namesFunction · 0.85
is_subtype_of_namesFunction · 0.85
iterMethod · 0.80
filterMethod · 0.80

Tested by

no test coverage detected