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

Method hook_call

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

Source from the content-addressed store, hash-verified

321 }
322
323 fn hook_call(&mut self, node: Node<'t>) -> bool {
324 let fname = match self.callee_name(node) {
325 Some(f) => f,
326 None => return false,
327 };
328
329 // library(dplyr) / require(stats) / requireNamespace("jsonlite") /
330 // source("helpers.R") (r.ts:189-208). A dynamic/missing/empty first
331 // arg is consumed SILENTLY — nothing recorded, subtree never visited.
332 if is_import_fn(fname) || fname == "source" {
333 let module = match self.literal_or_identifier(self.first_arg_value(node)) {
334 Some(m) if !m.is_empty() => m,
335 _ => return true,
336 };
337 // signature: whole call text .trim().slice(0, 100) — UTF-16 slice.
338 // (A call node's text starts at the callee and ends at `)`, so
339 // trim() never has anything to strip on reachable inputs.)
340 let (sig, _) = util::slice_utf16(self.text(node).trim(), 100);
341 let module = module.to_string();
342 let imp = self.create_node("import", &module, node, Some(&sig));
343 if imp.is_some() && !self.stack.is_empty() {
344 let parent_row = self.top_row();
345 self.push_ref_at(parent_row, &module, "imports", node);
346 }
347 return true;
348 }
349
350 // setClass("Patient", …) / setRefClass / R6Class / ggproto
351 // (r.ts:211-221). A falsy name FALLS THROUGH to the generic call —
352 // `ggproto(NULL, Geom, …)` emits `calls ggproto` + file-scope body
353 // leak (asymmetric with imports, preserved).
354 if is_class_fn(fname) {
355 let name = match self.literal_or_identifier(self.first_arg_value(node)) {
356 Some(n) if !n.is_empty() => n.to_string(),
357 _ => return false,
358 };
359 if let Some(cls_row) = self.create_node("class", &name, node, None) {
360 self.stack.push(Scope { row: cls_row, kind: "class", name });
361 self.extract_class_members(node, cls_row);
362 self.stack.pop();
363 }
364 return true;
365 }
366
367 // setGeneric("describe", …) / setMethod("describe", "Patient", fn)
368 // (r.ts:224-249): function node named by the first arg; signature and
369 // body from the FIRST argument (any position) whose value is a
370 // function_definition.
371 if is_generic_fn(fname) {
372 let name = match self.literal_or_identifier(self.first_arg_value(node)) {
373 Some(n) if !n.is_empty() => n.to_string(),
374 _ => return false,
375 };
376 let mut impl_node: Option<Node<'t>> = None;
377 if let Some(args) = node.child_by_field_name("arguments") {
378 let mut cursor = args.walk();
379 for a in args.named_children(&mut cursor) {
380 if a.kind() != "argument" {

Callers 1

hookMethod · 0.80

Calls 13

is_import_fnFunction · 0.85
slice_utf16Function · 0.85
is_class_fnFunction · 0.85
is_generic_fnFunction · 0.85
callee_nameMethod · 0.80
literal_or_identifierMethod · 0.80
first_arg_valueMethod · 0.80
extract_class_membersMethod · 0.80
textMethod · 0.45
create_nodeMethod · 0.45
top_rowMethod · 0.45
push_ref_atMethod · 0.45

Tested by

no test coverage detected