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

Method parse_and_cache_content_versioned

src/resolution.rs:354–520  ·  view source on GitHub ↗

Version-aware variant of [`parse_and_cache_content`]. When `php_version` is `Some`, elements annotated with `#[PhpStormStubsElementAvailable]` whose version range excludes the target version are filtered out during extraction. Used when parsing phpstorm-stubs so that only the correct variant of each function, method, or parameter is presented. # Consistency model The five maps (`uri_classes_in

(
        &self,
        content: &str,
        uri: &str,
        php_version: Option<PhpVersion>,
    )

Source from the content-addressed store, hash-verified

352 /// for consistency within the same request, the writes here must
353 /// be batched under a single coordination mechanism.
354 pub(crate) fn parse_and_cache_content_versioned(
355 &self,
356 content: &str,
357 uri: &str,
358 php_version: Option<PhpVersion>,
359 ) -> Option<Vec<Arc<ClassInfo>>> {
360 let file_use_map = self.parse_use_statements(content);
361 let file_namespace = self.parse_namespace(content);
362
363 // Parse classes with per-class namespace tracking so that
364 // multi-namespace files (e.g. PDO.php with both `namespace { }`
365 // and `namespace Pdo { }`) resolve parent names correctly.
366 let classes_with_ns = Self::parse_php_versioned_with_namespaces(content, php_version);
367
368 // Group classes by their enclosing namespace and resolve parent
369 // names once per group, mirroring the logic in `update_ast_inner`.
370 let mut classes: Vec<ClassInfo> = Vec::with_capacity(classes_with_ns.len());
371 let mut ns_groups: HashMap<Option<String>, Vec<usize>> = HashMap::new();
372 for (i, (_cls, ns)) in classes_with_ns.iter().enumerate() {
373 ns_groups.entry(ns.clone()).or_default().push(i);
374 }
375
376 // Flatten into a single Vec, preserving original order.
377 for (cls, _) in &classes_with_ns {
378 classes.push(cls.clone());
379 }
380
381 if ns_groups.len() <= 1 {
382 // Single namespace (common case): resolve with file namespace.
383 Self::resolve_parent_class_names(&mut classes, &file_use_map, &file_namespace);
384 } else {
385 // Multi-namespace file: resolve each group with its own
386 // namespace context so that classes in `namespace { }` are
387 // not polluted by a sibling `namespace Pdo { }` block.
388 for (group_ns, indices) in &ns_groups {
389 let mut group: Vec<ClassInfo> =
390 indices.iter().map(|&i| classes[i].clone()).collect();
391 Self::resolve_parent_class_names(&mut group, &file_use_map, group_ns);
392 for (j, &idx) in indices.iter().enumerate() {
393 classes[idx] = group[j].clone();
394 }
395 }
396 }
397
398 // Set the per-class file_namespace so that classes loaded via
399 // PSR-4 / class index carry their namespace. This mirrors the
400 // same assignment done in `update_ast_inner` for files opened
401 // through `did_open` / `did_change`.
402 for (i, cls) in classes.iter_mut().enumerate() {
403 if cls.file_namespace.is_none() {
404 cls.file_namespace = classes_with_ns[i]
405 .1
406 .as_deref()
407 .or(file_namespace.as_deref())
408 .map(crate::atom::atom);
409 }
410 }
411

Callers 3

load_stub_classMethod · 0.80

Calls 15

apply_class_stub_patchesFunction · 0.85
evict_fqnFunction · 0.85
parse_use_statementsMethod · 0.80
parse_namespaceMethod · 0.80
iterMethod · 0.80
pushMethod · 0.80
cloneMethod · 0.80
into_iterMethod · 0.80
containsMethod · 0.80
writeMethod · 0.80
fqnMethod · 0.80
filterMethod · 0.80

Tested by

no test coverage detected