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

Method extract_call

codegraph-kernel/src/tsjs/extractors.rs:1161–1245  ·  view source on GitHub ↗
(&mut self, node: Node<'t>)

Source from the content-addressed store, hash-verified

1159 }
1160
1161 pub(super) fn extract_call(&mut self, node: Node<'t>) {
1162 if self.stack.is_empty() {
1163 return;
1164 }
1165 let func = node
1166 .child_by_field_name("function")
1167 .or_else(|| node.named_child(0));
1168 let mut callee_name = String::new();
1169
1170 if let Some(func) = func {
1171 if func.kind() == "member_expression" {
1172 let property = func
1173 .child_by_field_name("property")
1174 .or_else(|| func.child_by_field_name("field"))
1175 .or_else(|| func.named_child(1));
1176 if let Some(property) = property {
1177 let method_name = self.text(property);
1178 let receiver = func
1179 .child_by_field_name("object")
1180 .or_else(|| func.child_by_field_name("operand"))
1181 .or_else(|| func.child_by_field_name("argument"))
1182 .or_else(|| func.named_child(0))
1183 // Look through `(x)`, `x!`, `(x as T)`, `(await f())`
1184 // (mirrors peelTsJsReceiver).
1185 .map(peel_receiver);
1186 // Literal receivers call builtins, never project symbols (#1230).
1187 if let Some(r) = receiver {
1188 if is_literal_receiver(r.kind()) {
1189 return;
1190 }
1191 }
1192 let recv_ident = receiver.filter(|r| {
1193 matches!(r.kind(), "identifier" | "simple_identifier" | "field_identifier")
1194 });
1195 if let Some(r) = recv_ident {
1196 let receiver_name = self.text(r);
1197 if !matches!(receiver_name, "self" | "this" | "cls" | "super") {
1198 callee_name = format!("{receiver_name}.{method_name}");
1199 } else {
1200 callee_name = method_name.to_string();
1201 }
1202 } else if receiver.is_some_and(|r| self.is_unresolved_member_chain(r)) {
1203 // Retain the call site for effects without guessing a
1204 // project method. Mirrors the TS extraction path.
1205 let chain = self.text(func).replace("?.", ".");
1206 let Some(chain) = Self::plain_member_name(&chain) else { return };
1207 callee_name = chain;
1208 } else if let Some(field) = receiver.and_then(|r| self.this_field_of(r)) {
1209 // `this.<field>.<method>()` — keep the field so the
1210 // resolver can read its declared type (#1496). Mirrors
1211 // TreeSitterExtractor.extractCall.
1212 callee_name = format!("this.{field}.{method_name}");
1213 } else if let Some(r) = receiver.filter(|r| r.kind() == "call_expression") {
1214 // Call receiver — `make().run()` (#1683): keep the inner
1215 // callee as `<inner>().<method>`, or emit nothing when it
1216 // is not a plain name / member chain. Mirrors
1217 // TreeSitterExtractor.extractCall.
1218 let Some(inner) = self.plain_inner_callee(r) else { return };

Callers 2

visit_nodeMethod · 0.45

Calls 8

keeps_bare_receiverFunction · 0.85
mapMethod · 0.80
this_field_ofMethod · 0.80
push_call_refMethod · 0.80
is_literal_receiverFunction · 0.70
textMethod · 0.65
plain_inner_calleeMethod · 0.45

Tested by

no test coverage detected