Emit an IMPORTS edge for a module path string (strips a trailing [symbols] list and surrounding quotes; uses the last path segment as the local name).
| 820 | // Emit an IMPORTS edge for a module path string (strips a trailing [symbols] |
| 821 | // list and surrounding quotes; uses the last path segment as the local name). |
| 822 | static void r_push_import(CBMExtractCtx *ctx, const char *raw) { |
| 823 | CBMArena *a = ctx->arena; |
| 824 | if (!raw || !raw[0]) { |
| 825 | return; |
| 826 | } |
| 827 | char *mod = strip_quotes(a, raw); |
| 828 | // box::use specs look like "shiny[moduleServer, NS]" or |
| 829 | // "app/logic/validation[validate_input]" — the module path is the part |
| 830 | // before the '[' symbol list. |
| 831 | char *bracket = strchr(mod, '['); |
| 832 | if (bracket) { |
| 833 | *bracket = '\0'; |
| 834 | } |
| 835 | // Trim trailing whitespace left by truncation. |
| 836 | size_t len = strlen(mod); |
| 837 | while (len > 0 && (mod[len - SKIP_ONE] == ' ' || mod[len - SKIP_ONE] == '\t' || |
| 838 | mod[len - SKIP_ONE] == '\n')) { |
| 839 | mod[--len] = '\0'; |
| 840 | } |
| 841 | if (mod[0] == '\0') { |
| 842 | return; |
| 843 | } |
| 844 | CBMImport imp = {.local_name = path_last(a, mod), .module_path = mod}; |
| 845 | cbm_imports_push(&ctx->result->imports, a, imp); |
| 846 | } |
| 847 | |
| 848 | // Recursively scan R for import-producing calls. |
| 849 | static void r_collect_imports(CBMExtractCtx *ctx, TSNode node) { // NOLINT(misc-no-recursion) |
no test coverage detected