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

Method hook_binary_operator

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

Source from the content-addressed store, hash-verified

405 }
406
407 fn hook_binary_operator(&mut self, node: Node<'t>) -> bool {
408 let op = match node.child_by_field_name("operator") {
409 Some(o) => self.text(o),
410 None => return false,
411 };
412 let lhs = node.child_by_field_name("lhs");
413 let rhs = node.child_by_field_name("rhs");
414
415 // name <- function(…) — ANY scope (r.ts:267-279). Body walked through
416 // the hook-aware visit (visitFunctionBody never runs for R).
417 if is_assign_left(op) {
418 if let (Some(lhs), Some(rhs)) = (lhs, rhs) {
419 if lhs.kind() == "identifier" && rhs.kind() == "function_definition" {
420 let params_text = rhs.child_by_field_name("parameters").map(|p| self.text(p));
421 let name = self.text(lhs).to_string();
422 let fn_row = self.create_node("function", &name, node, params_text);
423 let body = rhs.child_by_field_name("body");
424 if let (Some(row), Some(body)) = (fn_row, body) {
425 self.stack.push(Scope { row, kind: "function", name });
426 self.visit(body);
427 self.stack.pop();
428 }
429 return true;
430 }
431 }
432 }
433
434 let top_level = node.parent().map(|p| p.kind() == "program").unwrap_or(false);
435
436 // Top-level value assignments → variable/constant (r.ts:284-296);
437 // the class-definition idiom suppresses the twin variable node but the
438 // rhs is ALWAYS visited.
439 if top_level && is_assign_left(op) {
440 if let (Some(lhs), Some(rhs)) = (lhs, rhs) {
441 if lhs.kind() == "identifier" {
442 let rhs_callee = if rhs.kind() == "call" { self.callee_name(rhs) } else { None };
443 let suppressed = rhs_callee
444 .map(|c| is_class_fn(c) || is_generic_fn(c))
445 .unwrap_or(false);
446 if !suppressed {
447 let name = self.text(lhs);
448 let kind = if constant_name_re().is_match(name) { "constant" } else { "variable" };
449 self.create_node(kind, name, node, None);
450 }
451 self.visit(rhs);
452 return true;
453 }
454 }
455 }
456
457 // value -> name / value ->> name (r.ts:298-303).
458 if top_level && is_assign_right(op) {
459 if let (Some(lhs), Some(rhs)) = (lhs, rhs) {
460 if rhs.kind() == "identifier" {
461 let name = self.text(rhs);
462 let kind = if constant_name_re().is_match(name) { "constant" } else { "variable" };
463 self.create_node(kind, name, node, None);
464 self.visit(lhs);

Callers 1

hookMethod · 0.80

Calls 9

is_assign_leftFunction · 0.85
is_class_fnFunction · 0.85
is_generic_fnFunction · 0.85
constant_name_reFunction · 0.85
is_assign_rightFunction · 0.85
callee_nameMethod · 0.80
textMethod · 0.45
create_nodeMethod · 0.45
visitMethod · 0.45

Tested by

no test coverage detected