Commit Graph
19 Commits
Author SHA1 Message Date
Martin Vogel 91f622315b fix(test): free the fixture project name before reindexing
Three language fixtures assign cbm_project_name_from_path into lp->project each
time they open an indexed store. Teardown frees the last one, so a fixture that
indexes more than once dropped every earlier heap name — 68 allocations across the
run, which the macOS leak lane reports at process exit.

Pre-existing rather than introduced here: none of these files or fqn.c are in this
branch's diff, and the leak lane passed on the previous PR. Adding a suite shifted
what the leak job sees, which is how it surfaced. Fixing it here rather than
recording it, since a gate that only stays green by composition accident is not a
gate.

Freeing before reassigning also makes the ownership obvious at the point it
matters, instead of relying on the reader noticing the teardown three functions
away.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-08-06 18:15:48 +02:00
Martin Vogel 87a0e3f74f fix: preserve semantic graph relationships
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-18 15:52:50 +02:00
Martin Vogel 0ec24787fa Merge remote-tracking branch 'origin/main' into HEAD
# Conflicts:
#	tests/test_lang_contract.c
2026-07-16 17:37:46 +02:00
Martin Vogel 0563caeec2 Merge remote-tracking branch 'origin/main' into HEAD
# Conflicts:
#	tests/test_lang_contract.c
2026-07-16 02:35:43 +02:00
Martin Vogel 81e7b73647 Merge remote-tracking branch 'origin/main' into HEAD
# Conflicts:
#	tests/test_lang_contract.c
2026-07-16 02:31:18 +02:00
tmonestudioandClaude Opus 4.8 feb5cd8a6f fix(tests): isolate integration caches from user state
Run the test process under a private temporary HOME and clear inherited CBM_CACHE_DIR so production index paths and legacy fixtures resolve to the same isolated cache.

Make lang-contract fixtures honor an explicit cache override and remove the sentinel tree at process exit, including after early assertion returns.

Validated on Windows with the full runner: 5828 passed, 22 skipped; a 500-project user cache had zero files added or removed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: tmonestudio <tmonestudio@users.noreply.github.com>
2026-07-12 20:28:34 -03:00
Martin Vogel d3225485c2 fix(py-lsp): resolve calls through aliased imports
from m import f as g; g() produced no CALLS edge at all. Two stacked
defects: (1) py_lsp_bind_imports keyed from-style detection on the
local name matching the module-path tail - an alias never matches, so
g was bound MODULE(m.f) and the call missed; (2) even with the binding
fixed, the pass join compares the bare tail of the resolved QN (f)
against the textual callee (g) and dropped the resolution.

Fix: (1) a dotted module path whose tail differs from the local name
is an aliased binding - bind NAMED(qn) and let phase 6 upgrade it to
the registered function/class (from-import alias) or module (import
a.b as z); (2) when the identifier-callee NAMED branch resolves a name
whose textual form differs from the QN tail, emit strategy
lsp_import_alias with the textual name stashed in reason, and gate
that strategy in the join's reason list - the exact pattern already
used by lsp_dict_dispatch and lsp_func_ptr. The parallel path's hash
index misses the alias key and falls through to the same gated linear
scan.

The contract test pins all four import forms (aliased from-import,
plain from-import, single-segment module alias, dotted module alias)
so the flip from MODULE to NAMED binding cannot regress the module-
alias attribute chains.

Closes #988

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-12 14:51:02 +02:00
Martin Vogel f7b5a856f5 fix(pipeline): stop CI/tooling config URLs from minting infra Route nodes
URLs in .pre-commit-config.yaml, .github/workflows and similar CI
configs are repository/action/registry references for the development
toolchain, never endpoints the indexed service exposes. They matched
is_infra_file (.yaml) and passed the #521 value guards, so each minted
a __route__infra__<url> Route node; the route matcher's root-service
heuristic then attached every handler of an ambiguous '/' route to each
junk URL - 6-7 junk HANDLES targets per handler on plain pallets/flask,
with tie-break-dependent winners feeding HANDLES churn between builds.

Deny by file identity (well-known CI/tooling basenames plus .github/,
.gitlab/, .circleci/ trees) in cbm_pipeline_extract_infra_routes, not
by URL shape: deployment configs (Cloud Scheduler push endpoints,
compose) keep minting their genuine endpoints, guarded by an inverse
test.

Closes #999

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-12 14:12:26 +02:00
Martin Vogel 66f2413cd9 test(contract): free node fields in calls_edge_targets helper
cbm_store_find_node_by_id heap-allocates the node's string fields;
the #871 helper left them unfreed, tripping LSan on the Linux legs.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-12 13:40:33 +02:00
Martin Vogel 8a1b5f64b8 fix(extract): stop CommonJS require() bindings from shadowing call resolution
const foo = require('./foo') emitted a Variable definition for the
binding, so calls to foo() resolved to that same-module Variable (an
import alias, not a definition) instead of following the recorded
import to the exported function - which stayed at zero inbound CALLS
and surfaced as a disconnected Variable node. ESM import bindings never
materialize as Variables; the identifier-bound require form now behaves
identically: extract_js_vars skips the Variable def exactly when the
declarator value is a require() call with a string-literal path (the
form extract_imports records with local_name = the identifier), letting
resolution fall through to the import map. Destructured requires keep
their Variable defs since the import row only records the module.

Closes #871

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-12 11:56:23 +02:00
Alexandros Pappas fe2b072d02 fix(pipeline): reject non-file-like IMPORTS targets in fallback strategies
A wildcard tsconfig path alias (e.g. "@lib/*" -> "./src/lib/*") matches
any import specifier sharing that prefix, including an unrelated scoped
npm package meant to resolve from node_modules. The direct match
already failed cleanly (no node exists at the substituted path), but
cbm_pipeline_resolve_import_node's Strategy 4 - a generic "strip a
trailing path segment and retry" fallback applied to every language,
not just its intended Rust crate::/self::/super:: case - re-resolves
the truncated import string and can land on the tsconfig's OTHER, bare
alias entry that maps straight to a directory. The resulting QN
collides with that directory's real Folder node (cbm_pipeline_fqn_module
and cbm_pipeline_fqn_folder both dot-join path segments with no type
tag), and Strategy 4 accepted whatever node it found there.

Strategy 3 (symbol-name fallback) already guards its matches with
import_targetable_label(), which excludes Folder/Project/etc. Strategy
1b (resolve_sibling_file, used only for markup/build-tool sibling
imports - SCSS/Just/BitBake/Meson/Pony, none of which are directory-
module languages) and Strategy 4 lacked the same guard; both now use
it too.

Strategy 1 (the primary, direct resolution path) intentionally keeps
no such filter: Go and Java are directory-module languages in this
pipeline (cbm_lang_module_is_dir), so a bare package import correctly
and deliberately resolves straight to a Folder node there - adding the
guard to Strategy 1 broke that (verified via the Go/Java integration
tests) before being scoped down to just the fallback strategies where
the collision actually originates.

Closes #767.

Signed-off-by: Alexandros Pappas <11921291+apappas1129@users.noreply.github.com>
2026-07-02 21:20:22 +08:00
Martin Vogel 3ee9d5d112 Drop the nim grammar and refresh language counts
Removes the heaviest vendored grammar (66 MB) along with its language
wiring and test fixtures; the supported-language count moves to 158
across README, site, and manifest. The grammar manifest additionally
records the canonical-source decisions for the five
registry-disagreement grammars and the per-directory license files
restored earlier this week.
2026-06-12 02:17:39 +02:00
Martin Vogel 7bce843285 Add reproduction for package.json workspaces cross-package IMPORTS (#408)
A Lerna/Yarn workspaces monorepo where packages/b imports a sibling by package name (@org/a) should resolve via package.json name->dir into a cross-package IMPORTS edge. Reproduction contract; verifies whether the generic workspaces case resolves (cbm_pipeline_resolve_module already looks up bare specifiers in the pkgmap) or exposes a gap.
2026-06-06 22:16:05 +02:00
Martin Vogel a419bc81d5 Assert git in the FILE_CHANGES_WITH contract instead of skipping
git is now installed on every CI platform (incl. the Windows msys2 env) and run_git uses portable git -C, so a failed init is a broken-env failure, not a platform skip.
2026-06-06 18:36:28 +02:00
Martin Vogel 6f45ac32b8 Write fixtures in binary mode; skip FILE_CHANGES_WITH without git on Windows
fopen text mode rewrites newlines to CRLF on Windows, making line-ending-sensitive grammars under-extract (below_min/calls_breadth). Open fixtures with wb. Also skip the git-history contract when git init fails (platform limitation) rather than failing.
2026-06-06 14:57:30 +02:00
Martin Vogel 2e044dc9ad Normalize temp-dir paths to forward slashes for the Windows test build
cbm_mkdtemp on msys2 yields a backslash Windows path; embedding it in the JSON repo_path produced invalid escapes so index_repository failed (count=-1) for every harness contract, plus mixed-separator git -C args. Normalize to forward slashes after mkdtemp — valid in JSON and accepted by Windows file APIs and git.
2026-06-06 13:33:15 +02:00
Martin Vogel 0baa92c43c Guard the fork-based crash check for the Windows build
extract_crashes uses fork/waitpid/<sys/wait.h>, which msys2-clang lacks, so the Windows test build failed with 'sys/wait.h not found'. Guard the include for _WIN32 and run extraction in-process there (fixtures are crash-free; the fork-isolated check still runs on the POSIX CI legs).
2026-06-06 12:34:59 +02:00
Martin Vogel 3d9731f861 Zero-initialize LangFile fixture arrays (GCC -Werror=maybe-uninitialized)
GCC at -O1 flags the partially-filled LangFile arrays in contract_all_grammars_in_graph and index_parallel_fixture as maybe-used-uninitialized when passed to lang_index_files (clang does not), failing the -Werror Linux test build. Zero-initialize both; only files[0..nfiles-1] are ever read, so behavior is unchanged.
2026-06-06 11:43:23 +02:00
Martin Vogel 7a43b38ef7 Add per-grammar regression suite across all 159 grammars
Index a fixture for every grammar through the full pipeline and assert graph-level invariants: golden node-label histograms, def/node breadth, CALLS and IMPORTS breadth, presence of all 26 pipeline edge types (structural, type-relationship, service/dataflow, and similarity), no-crash, and call resolution. Reproduced quality gaps (under-extraction, import-extraction, and CALLS-resolution) are kept as hard failures for the fix phase rather than skipped. Adds a real-repo scale tier (scale_contract.sh) and ignores local-only private/ scratch.
2026-06-05 21:53:25 +02:00