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

Method extract_call

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

Source from the content-addressed store, hash-verified

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

Callers 2

visit_nodeMethod · 0.45

Calls 5

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

Tested by

no test coverage detected