--- Namespace / package declaration capture --- Java/Kotlin/C#/PHP put the file's symbols inside a namespace/package whose name is NOT reflected in the path-based QN scheme. Capturing it lets the pipeline resolve `using App.Utils` / `import com.example.Foo` to the File node(s) that declare that namespace, which the path-derived QN alone cannot.
| 1471 | // pipeline resolve `using App.Utils` / `import com.example.Foo` to the File |
| 1472 | // node(s) that declare that namespace, which the path-derived QN alone cannot. |
| 1473 | static void capture_namespace_decl(CBMExtractCtx *ctx) { |
| 1474 | CBMArena *a = ctx->arena; |
| 1475 | static const char *ns_kinds[] = {"namespace_declaration", // C# |
| 1476 | "file_scoped_namespace_declaration", // C# 10 |
| 1477 | "package_declaration", // Java / Kotlin |
| 1478 | "package_header", // Kotlin |
| 1479 | "namespace_definition", // PHP |
| 1480 | NULL}; |
| 1481 | TSTreeCursor cursor = ts_tree_cursor_new(ctx->root); |
| 1482 | if (!ts_tree_cursor_goto_first_child(&cursor)) { |
| 1483 | ts_tree_cursor_delete(&cursor); |
| 1484 | return; |
| 1485 | } |
| 1486 | do { |
| 1487 | TSNode node = ts_tree_cursor_current_node(&cursor); |
| 1488 | const char *kind = ts_node_type(node); |
| 1489 | if (!spec_type_matches(ns_kinds, kind)) { |
| 1490 | continue; |
| 1491 | } |
| 1492 | // The namespace name is the first qualified_name / scoped_identifier / |
| 1493 | // namespace_name / identifier descendant. |
| 1494 | static const char *name_kinds[] = {"qualified_name", |
| 1495 | "scoped_identifier", |
| 1496 | "namespace_name", |
| 1497 | "identifier", |
| 1498 | "dotted_name", |
| 1499 | "name", |
| 1500 | NULL}; |
| 1501 | for (const char **nk = name_kinds; *nk; nk++) { |
| 1502 | TSNode nn = node; |
| 1503 | if (find_first_descendant_of(node, *nk, &nn)) { |
| 1504 | char *ns = cbm_node_text(a, nn, ctx->source); |
| 1505 | if (ns && ns[0]) { |
| 1506 | ctx->result->namespace_name = ns; |
| 1507 | } |
| 1508 | break; |
| 1509 | } |
| 1510 | } |
| 1511 | if (ctx->result->namespace_name) { |
| 1512 | break; |
| 1513 | } |
| 1514 | } while (ts_tree_cursor_goto_next_sibling(&cursor)); |
| 1515 | ts_tree_cursor_delete(&cursor); |
| 1516 | } |
| 1517 | |
| 1518 | // --- Hare imports --- |
| 1519 | // tree-sitter-hare nests imports: module -> imports -> use_statement* -> |
no test coverage detected