fix(go): resolve cross-package field-chain calls via type dispatch - #1939
fix(go): resolve cross-package field-chain calls via type dispatch#1939xkchok wants to merge 4 commits into
Conversation
Go calls written through an aliased struct field (h.svc.Method(ctx, req)) previously fell through to fuzzy suffix matching because: - the per-file Go dispatch walk was bypassed, so field selectors were never descended; - struct fields extracted as flat "Field" defs were dropped by the LSP label map, so every Go struct registered with zero fields; - receiver types written through import aliases (svc.Svc) produced qualified names that exist nowhere in the project registry. Changes: - restore the Go walk in cbm_pxc_dispatch_file and descend field selectors through the shared prebuilt registry, emitting lsp_type_dispatch edges; - fold per-field defs into their owning struct inside cbm_pxc_collect_all_defs (one site covers both the prebuilt-registry path and the per-file fallback); - re-qualify the last alias segment through the calling file's import map when the direct receiver-type lookup misses (go_requalify_via_imports). Tests: - tests/test_parallel.c: cross-package field chain resolves end to end with an lsp_type_dispatch edge in the parallel resolver; - tests/test_go_lsp.c: alias-typed struct field re-qualifies through the import map and lands on the real receiver type. Signed-off-by: xkchok <143325001+xkchok@users.noreply.github.com>
The Go resolve worker's stderr is swallowed by the daemon supervisor, so dispatch diagnostics are unreachable. Add a file-sink trace gated by CBM_DISPATCH_TRACE (path via CBM_TRACE_FILE, default /tmp/cbm_dispatch_trace.txt, append): emits one line per NAMED-receiver dispatch attempt, successful emit, and failure reason. Aids upstream debugging of receiver-QN/lookup mismatches without changing behavior when unset. Signed-off-by: xkchok <143325001+xkchok@users.noreply.github.com>
d4416bc to
54cfae5
Compare
|
Thanks for opening this — it has been seen, and it is queued. This note is automated, but it is not a brush-off: it exists so you know where your PR stands instead of having to guess from silence. Current review status: working through a backlog. What that means for this PR, concretely:
Things that will genuinely speed it up whenever review does happen:
If this fixes a bug, a reproduction we can run is worth more than a description of the symptom. Thanks for contributing, and sorry in advance for the wait. |
The manual wrap disagreed with clang-format's packing heuristic: with two parameters still fitting under the 100-column limit, the formatter packs them onto the first line rather than breaking after the first argument. Fix the wrap so the PR cleanly passes the ci lint gate. Signed-off-by: xkchok <143325001+xkchok@users.noreply.github.com>
0f2ff82 to
8b4af11
Compare
run_go_field_chain_sequential tears down the results, registry and cross arenas but never calls harness_ctx_free_tables, so pass_calls' CBMReturnTypeTable (strdup'd method return types) leaked whenever the helper ran. ASan builds caught it: AddressSanitizer: 32911 byte(s) leaked in 6 allocation(s) from build_return_type_table, failing test-diag, test-lsan-macos and both gcc sanitizer shards. Verify locally: build/c/test-runner parallel -> 73 passed, no leaks. Signed-off-by: xkchok <143325001+xkchok@users.noreply.github.com>
|
Reviewed against current You and #1940 independently found the same extraction bugYour defect 2 — "every Go struct registered with zero fields" — was also diagnosed and fixed in #1940, which merged as Concretely, TSNode body = find_class_member_body(class_node, ctx->language);
if (ctx->language == CBM_LANG_GO) {
body = go_normalize_struct_body(body); /* struct_type -> field_declaration_list */
}So please drop your The rest of it is still needed — I checked rather than assumed
The Two smaller asks
Worth calling outThe measurement is the part that makes this reviewable: 49/49 handler→service field-chain calls at 0.95 via type dispatch against 0.33 fuzzy, on a named fixture. And you recorded the two known gaps — nested-module receiver-QN reconstruction, and generated client factories — instead of leaving them for someone to discover later. That is the right way to hand over a partial fix. Ping when it is rebased and I will re-review promptly. |
Summary
Go calls written through an aliased cross-package struct field (
h.svc.Method(ctx, req)) previously fell through to fuzzy suffix matching instead of type dispatch. Three defects caused it:cbm_pxc_dispatch_filewas bypassed, so field selectors were never descended.Fielddefs were discarded by the LSP label map, so every Go struct registered with zero fields in the cross-file registry.Changes
internal/cbm/lsp/go_lsp.c— restore the Go field-chain walk: descendreceiver.fieldselectors through the shared prebuilt registry and emitlsp_type_dispatch/lsp_embed_dispatchedges; addgo_requalify_via_importsto re-qualify alias segments through the calling file's import map when the direct receiver-type lookup misses.internal/cbm/extract_defs.c+src/pipeline/pass_lsp_cross.c— fold per-fieldFielddefs into their owning struct insidecbm_pxc_collect_all_defs(one site covers both the prebuilt-registry path and the per-file fallback).tests/test_parallel.c— regression: a cross-package field chain resolves end to end with anlsp_type_dispatchedge from the parallel resolver.tests/test_go_lsp.c— regression: an alias-typed struct field re-qualifies through the import map and lands on the real receiver type.Separate chore commit (drop it if unwanted): env-gated dispatch tracing (
CBM_DISPATCH_TRACE/CBM_TRACE_FILE, file sink) ingo_lsp.c, since resolve-worker stderr is swallowed by the daemon supervisor. No behavior change when unset.Test plan
make test-runnerclean build./build/test-runner parallel go_lsp— 125 passed, regression fixtures dispatch as expected./scripts/build.shclean production buildVerified scope