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

Function extract_casts_definitions

src/parser/classes.rs:371–438  ·  view source on GitHub ↗

Extract Eloquent cast definitions from a class's members. Scans the class members for: 1. A `$casts` property with an array initializer (`protected $casts = [...]`) 2. A `casts()` method whose body contains a `return [...]` statement Returns a list of `(column_name, cast_type)` pairs extracted from the array literal text. Both sources are merged: entries from the `casts()` method take priority

(
    members: impl Iterator<Item = &'a ClassLikeMember<'a>>,
    content: &str,
)

Source from the content-addressed store, hash-verified

369/// the same column appears in both. This matches Laravel's runtime
370/// behaviour where `Model::casts()` overrides `$casts`.
371fn extract_casts_definitions<'a>(
372 members: impl Iterator<Item = &'a ClassLikeMember<'a>>,
373 content: &str,
374) -> Vec<(String, String)> {
375 let mut property_text: Option<String> = None;
376 let mut method_text: Option<String> = None;
377
378 for member in members {
379 match member {
380 ClassLikeMember::Property(Property::Plain(plain)) => {
381 for item in plain.items.iter() {
382 let var_name = item.variable().name.to_string();
383 let stripped = var_name.strip_prefix('$').unwrap_or(&var_name);
384 if stripped != "casts" {
385 continue;
386 }
387 if let PropertyItem::Concrete(concrete) = item {
388 let span = concrete.value.span();
389 let start = span.start.offset as usize;
390 let end = span.end.offset as usize;
391 if let Some(text) = content.get(start..end) {
392 property_text = Some(text.to_string());
393 }
394 }
395 }
396 }
397 ClassLikeMember::Method(method) if method.name.value == "casts" => {
398 if let MethodBody::Concrete(block) = &method.body {
399 let start = block.left_brace.start.offset as usize;
400 let end = block.right_brace.end.offset as usize;
401 if let Some(text) = content.get(start..end) {
402 method_text = Some(text.to_string());
403 }
404 }
405 }
406 _ => {}
407 }
408 }
409
410 // Start with $casts property entries as the base.
411 let mut merged: Vec<(String, String)> = Vec::new();
412
413 if let Some(ref text) = property_text {
414 merged = parse_casts_array(text);
415 }
416
417 // Merge casts() method entries on top — method entries override
418 // property entries for the same column, matching Laravel's runtime
419 // behaviour.
420 if let Some(ref text) = method_text
421 && let Some(arr_start) = text.find("return")
422 {
423 let after_return = &text[arr_start + 6..];
424 if let Some(bracket_pos) = after_return.find('[') {
425 let array_text = &after_return[bracket_pos..];
426 let method_defs = parse_casts_array(array_text);
427 for (key, value) in method_defs {
428 if let Some(existing) = merged.iter_mut().find(|(k, _)| *k == key) {

Callers 1

Calls 5

parse_casts_arrayFunction · 0.85
iterMethod · 0.80
pushMethod · 0.80
getMethod · 0.45
findMethod · 0.45

Tested by

no test coverage detected