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

Function build_completion_items

src/completion/builder.rs:290–517  ·  view source on GitHub ↗

Build completion items for a resolved class, filtered by access kind and visibility scope. - `Arrow` access: returns only non-static methods and properties. - `DoubleColon` access: returns only static methods, static properties, and constants. - `ParentDoubleColon` access: returns both static and non-static methods, static properties, and constants — but excludes private members. - `Other` access

(
    target_class: &ClassInfo,
    access_kind: AccessKind,
    current_class_name: Option<&str>,
    is_self_or_ancestor: bool,
    uri: &str,
)

Source from the content-addressed store, hash-verified

288/// `parent::__construct()`, `ClassName::__construct()` from within a
289/// subclass). When `false`, magic methods are suppressed entirely.
290pub(crate) fn build_completion_items(
291 target_class: &ClassInfo,
292 access_kind: AccessKind,
293 current_class_name: Option<&str>,
294 is_self_or_ancestor: bool,
295 uri: &str,
296) -> Vec<CompletionItem> {
297 // Determine whether we are inside the same class as the target.
298 let same_class = current_class_name.is_some_and(|name| name == target_class.name);
299 let mut items: Vec<CompletionItem> = Vec::new();
300
301 // Methods — filtered by static / instance, excluding magic methods
302 for method in &target_class.methods {
303 // `__construct` is meaningful to call explicitly via `::` when
304 // inside the same class or a subclass (e.g.
305 // `parent::__construct(...)`, `self::__construct()`).
306 // Outside of that relationship, magic methods are suppressed.
307 let is_constructor = method.name.eq_ignore_ascii_case("__construct");
308 if is_magic_method(&method.name) {
309 let allow = is_constructor
310 && is_self_or_ancestor
311 && matches!(
312 access_kind,
313 AccessKind::DoubleColon | AccessKind::ParentDoubleColon
314 );
315 if !allow {
316 continue;
317 }
318 }
319
320 // Visibility filtering:
321 // - private: only visible from within the same class
322 // - protected: visible from the same class or a subclass
323 // (we approximate by allowing when inside any class)
324 if method.visibility == Visibility::Private && !same_class {
325 continue;
326 }
327 if method.visibility == Visibility::Protected && !same_class && !is_self_or_ancestor {
328 continue;
329 }
330
331 let include = match access_kind {
332 AccessKind::Arrow => !method.is_static,
333 // External `ClassName::` shows only static methods, but
334 // `__construct` is an exception — it's an instance method
335 // that is routinely called via `ClassName::__construct()`
336 // from within a subclass.
337 AccessKind::DoubleColon => method.is_static || is_constructor,
338 // `self::`, `static::`, and `parent::` show both static and
339 // non-static methods (PHP allows calling instance methods
340 // via `::` from within the class hierarchy).
341 AccessKind::ParentDoubleColon => true,
342 AccessKind::Other => true,
343 };
344 if !include {
345 continue;
346 }
347

Callers 1

Calls 10

is_magic_methodFunction · 0.85
build_method_labelFunction · 0.85
build_callable_snippetFunction · 0.85
deprecation_tagFunction · 0.85
kind_sort_tierFunction · 0.85
pushMethod · 0.80
iterMethod · 0.80
cloneMethod · 0.80
display_class_nameFunction · 0.70
mapMethod · 0.45

Tested by

no test coverage detected