MCPcopy Create free account
hub / github.com/DeusData/codebase-memory-mcp / process_commonjs_require

Function process_commonjs_require

internal/cbm/extract_imports.c:445–505  ·  view source on GitHub ↗

Handle CommonJS `require("path")` call_expression nodes. The local name * is derived from the enclosing variable_declarator / assignment when * possible (so `const foo = require('./foo')` emits local_name="foo"), * otherwise falls back to the last path component. */

Source from the content-addressed store, hash-verified

443 * possible (so `const foo = require('./foo')` emits local_name="foo"),
444 * otherwise falls back to the last path component. */
445static bool process_commonjs_require(CBMExtractCtx *ctx, TSNode call) {
446 CBMArena *a = ctx->arena;
447 if (ts_node_child_count(call) < MIN_WOLFRAM_CHILDREN) {
448 return false;
449 }
450 /* Callee must be the identifier "require". */
451 TSNode fn = ts_node_child_by_field_name(call, TS_FIELD("function"));
452 if (ts_node_is_null(fn)) {
453 fn = ts_node_child(call, 0);
454 }
455 if (ts_node_is_null(fn)) {
456 return false;
457 }
458 const char *fn_kind = ts_node_type(fn);
459 if (strcmp(fn_kind, "identifier") != 0) {
460 return false;
461 }
462 char *fn_name = cbm_node_text(a, fn, ctx->source);
463 if (!fn_name || strcmp(fn_name, "require") != 0) {
464 return false;
465 }
466
467 /* First string literal child of the argument list is the module path. */
468 TSNode args = ts_node_child_by_field_name(call, TS_FIELD("arguments"));
469 if (ts_node_is_null(args)) {
470 return false;
471 }
472 uint32_t argc = ts_node_named_child_count(args);
473 char *path = NULL;
474 for (uint32_t i = 0; i < argc; i++) {
475 TSNode arg = ts_node_named_child(args, i);
476 const char *ak = ts_node_type(arg);
477 if (strcmp(ak, "string") == 0 || strcmp(ak, "string_literal") == 0 ||
478 strcmp(ak, "template_string") == 0) {
479 path = strip_quotes(a, cbm_node_text(a, arg, ctx->source));
480 break;
481 }
482 }
483 if (!path || !path[0]) {
484 return false;
485 }
486
487 /* Infer local name from enclosing variable_declarator. Tree-sitter's JS
488 * grammar wraps `const foo = require(..)` as
489 * lexical_declaration → variable_declarator { name: identifier, value: call } */
490 const char *local_name = NULL;
491 TSNode parent = ts_node_parent(call);
492 if (!ts_node_is_null(parent) && strcmp(ts_node_type(parent), "variable_declarator") == 0) {
493 TSNode name_node = ts_node_child_by_field_name(parent, TS_FIELD("name"));
494 if (!ts_node_is_null(name_node) && strcmp(ts_node_type(name_node), "identifier") == 0) {
495 local_name = cbm_node_text(a, name_node, ctx->source);
496 }
497 }
498 if (!local_name) {
499 local_name = path_last(a, path);
500 }
501
502 CBMImport imp = {.local_name = local_name, .module_path = path};

Callers 1

walk_es_importsFunction · 0.85

Calls 4

cbm_node_textFunction · 0.85
path_lastFunction · 0.85
cbm_imports_pushFunction · 0.85
strip_quotesFunction · 0.70

Tested by

no test coverage detected