mirror of
https://github.com/safishamsi/graphify.git
synced 2026-09-20 20:46:15 +00:00
fix(commonlisp): derive node ids from the full path stem
The Common Lisp extractor minted its id prefix from the bare path.stem instead of the canonical _file_stem used by every other extractor, so two same-basename .lisp files in different directories collided (one file's nodes vanished on merge) and nested .lisp files tripped a spurious legacy-id nudge. Use _make_id(_file_stem(path)) to match the shared convention; cross-file rewire is unaffected (it matches on label, not id).
This commit is contained in:
@@ -4,7 +4,7 @@ from __future__ import annotations
|
||||
import warnings
|
||||
from pathlib import Path
|
||||
|
||||
from graphify.extractors.base import _make_id
|
||||
from graphify.extractors.base import _file_stem, _make_id
|
||||
|
||||
|
||||
# Standard CL definer forms that introduce data/type/variable bindings
|
||||
@@ -84,7 +84,11 @@ def extract_commonlisp(path: Path) -> dict:
|
||||
except Exception as e:
|
||||
return {"nodes": [], "edges": [], "error": str(e)}
|
||||
|
||||
stem = path.stem
|
||||
# Path-qualified, not the bare `path.stem`: same-named .lisp files in
|
||||
# different directories must not collide (#1504). Pre-collapsed through
|
||||
# `_make_id` because `_cl_id` would otherwise map the `/` separators to
|
||||
# `_slash` via _CL_CHAR_MAP.
|
||||
stem = _make_id(_file_stem(path))
|
||||
str_path = str(path)
|
||||
nodes: list[dict] = []
|
||||
edges: list[dict] = []
|
||||
|
||||
@@ -3974,3 +3974,25 @@ def test_zig_enum_and_union_methods_are_extracted(tmp_path):
|
||||
for e in r["edges"] if e["relation"] == "calls"
|
||||
}
|
||||
assert (".area()", "helper()") in calls, "call from union method body dropped"
|
||||
|
||||
|
||||
@_needs_commonlisp
|
||||
def test_cl_ids_are_path_qualified_across_directories(tmp_path):
|
||||
"""Two same-named .lisp files in DIFFERENT directories must mint distinct
|
||||
ids (#1504). The prefix was derived from the bare `path.stem`, so both
|
||||
`a/sample.lisp` and `b/sample.lisp` minted `sample` / `sample_init`; when
|
||||
they land in separate extract batches (what `graphify update` does) build()
|
||||
merges them and one file's nodes are dropped."""
|
||||
a = tmp_path / "a" / "sample.lisp"
|
||||
b = tmp_path / "b" / "sample.lisp"
|
||||
for p in (a, b):
|
||||
p.parent.mkdir(parents=True)
|
||||
p.write_text("(defun init (x) (+ x 1))\n")
|
||||
|
||||
ids_a = {n["id"] for n in extract_commonlisp(a)["nodes"]}
|
||||
ids_b = {n["id"] for n in extract_commonlisp(b)["nodes"]}
|
||||
|
||||
assert not (ids_a & ids_b), (
|
||||
f"same-named .lisp files in different dirs must not share ids, "
|
||||
f"got overlap {sorted(ids_a & ids_b)}"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user