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

Method extract_call

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

Source from the content-addressed store, hash-verified

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

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