MCPcopy Create free account
hub / github.com/colbymchenry/codegraph / extract_call

Method extract_call

codegraph-kernel/src/php.rs:997–1063  ·  view source on GitHub ↗
(&mut self, node: Node<'t>)

Source from the content-addressed store, hash-verified

995 // --- calls ---------------------------------------------------------------------
996
997 fn extract_call(&mut self, node: Node<'t>) {
998 if self.stack.is_empty() {
999 return;
1000 }
1001 let caller = self.top_row();
1002 let mut callee_name = String::new();
1003
1004 let name_field = node.child_by_field_name("name");
1005 let object_field = node
1006 .child_by_field_name("object")
1007 .or_else(|| node.child_by_field_name("scope"));
1008
1009 if let (Some(name_field), Some(object_field)) = (name_field, object_field) {
1010 // member_call_expression / scoped_call_expression.
1011 let method_name = self.text(name_field);
1012
1013 // Fluent static-factory `Cls::factory($x)->method()` — encode
1014 // `Cls::factory().method` (inner args dropped) and return; the
1015 // inner scoped call is also visited by recursion (`Cls.factory`).
1016 if !method_name.is_empty() && object_field.kind() == "scoped_call_expression" {
1017 let inner_scope = object_field.child_by_field_name("scope");
1018 let inner_name = object_field.child_by_field_name("name");
1019 let callee = match (inner_scope, inner_name) {
1020 (Some(s), Some(n)) => {
1021 format!("{}::{}().{method_name}", self.text(s), self.text(n))
1022 }
1023 _ => method_name.to_string(),
1024 };
1025 if !callee.is_empty() {
1026 self.push_ref_at(caller, &callee, edge_kind_index("calls").unwrap(), node);
1027 }
1028 return;
1029 }
1030
1031 // receiverName = raw receiver text with ONE leading `$` stripped:
1032 // `$this->prop->m()` → `this->prop.m` (#1251 encoding — the whole
1033 // resolution machinery is TS-side); chains keep args
1034 // (`this->factory($cfg).m`); literals are NOT suppressed
1035 // (`"chain".upper`); scoped calls are DOT-joined (`UserModel.query`).
1036 let receiver_raw = self.text(object_field);
1037 let receiver = receiver_raw.strip_prefix('$').unwrap_or(receiver_raw);
1038 if !method_name.is_empty() {
1039 if matches!(receiver, "self" | "this" | "cls" | "super" | "parent" | "static") {
1040 callee_name = method_name.to_string();
1041 } else {
1042 callee_name = format!("{receiver}.{method_name}");
1043 }
1044 }
1045 } else {
1046 // function_call_expression: raw func text — bare `helper`,
1047 // qualified `\App\Helpers\format_id` verbatim, `$fn` for
1048 // variable callees, FCC `f(...)` → `f`.
1049 let func = node
1050 .child_by_field_name("function")
1051 .or_else(|| node.named_child(0));
1052 if let Some(func) = func {
1053 callee_name = self.text(func).to_string();
1054 }

Callers 2

visit_nodeMethod · 0.45

Calls 5

edge_kind_indexFunction · 0.85
textMethod · 0.65
unwrapMethod · 0.60
top_rowMethod · 0.45
push_ref_atMethod · 0.45

Tested by

no test coverage detected