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

Function rust_resolve_path_expr

internal/cbm/lsp/rust_lsp.c:617–731  ·  view source on GitHub ↗

Resolve a Rust *path expression* (e.g. `Foo::bar` or `crate::x::y`) * into a canonical QN. The resolver cascades through these rules, * matching what `rust-analyzer`'s name resolver does at the path level: * * 1. `Self::X` → ` .X` * 2. `crate::a::b` → ` .a.b` * 3. `super::a` → strip last segment of `module_qn` and prepend * 4. Single-segment + matches

Source from the content-addressed store, hash-verified

615 * The returned string is arena-owned; in case (6) we return the input
616 * with `::` already converted to `.`. */
617static const char *rust_resolve_path_expr(RustLSPContext *ctx, const char *path) {
618 if (!ctx || !path || !path[0]) {
619 return path;
620 }
621
622 /* Self:: handling — we treat the receiver type's QN as the head. */
623 if (strncmp(path, "Self::", 6) == 0 && ctx->self_type_qn) {
624 return cbm_arena_sprintf(ctx->arena, "%s.%s", ctx->self_type_qn,
625 convert_path_to_qn(ctx->arena, path + 6));
626 }
627 if (strcmp(path, "Self") == 0 && ctx->self_type_qn) {
628 return ctx->self_type_qn;
629 }
630
631 /* crate:: → <root>. We approximate the crate root as the first dotted
632 * segment of `module_qn` after the project prefix. The pipeline
633 * forms `module_qn` as `<project>.<crate>.<rel-path-segments>`, so
634 * the first two segments are project + crate root. */
635 if (strncmp(path, "crate::", 7) == 0 && ctx->module_qn) {
636 const char *p = ctx->module_qn;
637 int dots = 0;
638 const char *second_dot = NULL;
639 for (; *p; p++) {
640 if (*p == '.') {
641 if (++dots == 2) {
642 second_dot = p;
643 break;
644 }
645 }
646 }
647 size_t crate_len =
648 second_dot ? (size_t)(second_dot - ctx->module_qn) : strlen(ctx->module_qn);
649 char *crate_buf = cbm_arena_strndup(ctx->arena, ctx->module_qn, crate_len);
650 return cbm_arena_sprintf(ctx->arena, "%s.%s", crate_buf,
651 convert_path_to_qn(ctx->arena, path + 7));
652 }
653
654 /* super:: → drop last segment of module_qn. */
655 if (strncmp(path, "super::", 7) == 0 && ctx->module_qn) {
656 const char *dot = strrchr(ctx->module_qn, '.');
657 if (dot) {
658 char *parent =
659 cbm_arena_strndup(ctx->arena, ctx->module_qn, (size_t)(dot - ctx->module_qn));
660 return cbm_arena_sprintf(ctx->arena, "%s.%s", parent,
661 convert_path_to_qn(ctx->arena, path + 7));
662 }
663 }
664
665 /* Find first "::" — split into head + tail. */
666 const char *sep = strstr(path, "::");
667 if (!sep) {
668 const char *full = rust_resolve_use(ctx, path);
669 if (full) {
670 return convert_path_to_qn(ctx->arena, full);
671 }
672 /* Prelude name (e.g. `String`, `Vec`)? */
673 const char *prelude = rust_lookup_prelude(path);
674 if (prelude) {

Callers 8

resolve_path_to_type_qnFunction · 0.85
rust_parse_type_nodeFunction · 0.85
rust_eval_expr_typeFunction · 0.85
rust_process_statementFunction · 0.85
rust_process_implFunction · 0.85

Calls 7

convert_path_to_qnFunction · 0.85
rust_resolve_useFunction · 0.85
rust_lookup_preludeFunction · 0.85
cbm_cargo_find_memberFunction · 0.85
cbm_cargo_is_known_depFunction · 0.85
cbm_arena_sprintfFunction · 0.50
cbm_arena_strndupFunction · 0.50

Tested by

no test coverage detected