mirror of
https://github.com/safishamsi/graphify.git
synced 2026-07-16 04:17:19 +00:00
b9871d7019
* Fix #563: prevent rationale-node leakage and preserve calls direction Two AST-extractor bugs were inflating god-node centrality: 1. Rationale leakage in cross-file resolvers _resolve_cross_file_imports indexed any node whose label didn't end in ')' or '.py' as an importable entity, so rationale nodes (whose labels are docstring text) ended up in both stem_to_entities and local_classes. Result: phantom '<file>_rationale_N --uses--> ImportedThing' edges for every imported entity in every file with docstrings. The same leak existed in cross-file call resolution via global_label_to_nid, where rationale labels could collide with callee names. Fix: skip nodes with file_type == 'rationale' in all three index loops. 2. Calls / rationale_for direction lost at export to_json() called nx.json_graph.node_link_data() on a NetworkX undirected Graph, which canonicalizes endpoint order. The build path already stashes _src and _tgt on every edge for exactly this case (with a comment to that effect at build.py:100), but the exporter never consulted them, so 'calls' and 'rationale_for' edges were emitted with arbitrary direction. Fix: in to_json(), restore link['source'] / link['target'] from _src / _tgt, then pop those internal fields before writing graph.json. Repro on a minimal 3-file project (queue.py + contact_form.py + a test file with multi-paragraph docstrings) showed: Before fix: 31 edges, 12 incident on SQLiteQueue, 7 phantom uses-edges from rationale nodes, 1 inverted calls edge. After fix: 24 edges, 5 incident on SQLiteQueue, 0 phantom edges, all calls edges go caller -> callee. Adds tests/test_issue_563.py with 5 regression tests covering both bugs plus a direction-pin on the existing sample_calls.py fixture. Full suite passes (446/446). * Address Copilot review on #576 - tests: identify rationale nodes by file_type metadata, not id substring (decouples regression from current `<stem>_rationale_<line>` naming) - tests: assert contact_form -> SQLiteQueue.enqueue calls edge directly (previously only inversions were guarded; a dropped enqueue edge would have passed silently) - extract.py: clarify cross-file import indexing comment — the filter intentionally indexes only class-level entities (function/method labels end in "()" and are excluded by design) * Fix #563 (HTML export): restore arrow direction in graph.html to_json was patched to consult _src/_tgt before serializing edge endpoints, but to_html still read endpoints directly from G.edges(), so calls and rationale_for arrows in the rendered graph.html still pointed in canonicalized (often inverted) order. Apply the same direction restore in to_html when building vis.js edges. Use data.get (not pop) since G.edges(data=True) yields the live attribute dict and other exporters may run after to_html. Adds test_to_html_preserves_calls_and_rationale_for_direction: parses RAW_EDGES out of the rendered HTML and pins both the caller->callee assertions from #563 and the rationale->parent direction. Without the fix, the test reports 11 flipped arrows on the 3-file repro.