Feat/hdl vhdl tcl extractors - #2476
Conversation
VHDL (.vhd, .vhdl) — tree-sitter-vhdl (alemuller/tree-sitter-vhdl, MIT):
- entity_declaration, architecture_definition, package_declaration/
definition as top-level design-unit nodes
- subprogram_declaration/definition (functions and procedures) as
contained nodes
- component_instantiation_statement → instantiates edges (INFERRED)
- use_clause → imports_from edges
- architecture → implements entity edge (INFERRED)
Tcl (.tcl) — regex-based (no tree-sitter-tcl on PyPI yet):
- proc definitions → defines edges
- namespace eval blocks → contains edges (INFERRED)
- package require → imports_from edges
Both extractors follow the established pattern in graphify/extractors/:
use _file_stem and _make_id from base, return {nodes, edges} dicts,
gracefully return an error key on missing optional dependency.
Registered in extract.py _DISPATCH and detect.py CODE_EXTENSIONS.
Auditing codegraph's Tcl extractor (colbymchenry/codegraph#1508) turned up a bug fixed by GitHub Copilot Autofix: 'source file.tcl' was never creating an import edge there because of an engine-specific dead-hook issue. That specific bug can't occur in graphify (no importTypes/ callTypes dispatch here), but auditing surfaced that our own Tcl extractor never handled 'source' either — same real-world gap, different cause. Closing it for parity with 'package require'.
There was a problem hiding this comment.
Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).
Graphify reviewed this change.
Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).
Graphify review — findings
This PR adds language support for VHDL and Tcl file extraction to graphify. It registers new file extensions (.vhd, .vhdl, .tcl) in the CODE_EXTENSIONS set in detect.py, and wires two new extractor functions into the _DISPATCH table in extract.py. It introduces graphify/extractors/tcl.py (regex-based extraction of procs, namespaces, package require, and source directives) and graphify/extractors/vhdl.py (tree-sitter-based extraction of entities, architectures, packages, subprograms, use-clauses, and component instantiations), each emitting nodes and edges. The large list of "changed symbols" appears to reflect broad file-level churn across detect.py and extract.py; the substantive additions are the two new extractor modules and their registration.
No blocking issues surfaced. 1 lower-confidence candidate did not survive cross-model review.
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 1656 functions depend on the 299 functions this change touches.
Health — grade A; 10 existing hotspot(s) in the area this change touches (pre-existing, not introduced here):
extract()— 365 callers, 39 callees (high)_rebuild_code()— 87 callers, 51 callees (high)detect()— 82 callers, 13 callees (high)extract_xaml()— 19 callers, 17 callees (high)extract_files_direct()— 15 callers, 20 callees (high)save_manifest()— 26 callers, 10 callees (high)dispatch_command()— 2 callers, 117 callees (high)extract_corpus_parallel()— 23 callers, 10 callees (high)- …and 2 more
Verification — 1656 functions in the blast radius were not formally verified this run (proofs are advisory here).
Gate & verification
graphify gate
PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.
Advisory (not blocking):
- verification_scope: 1470 function(s) in the blast radius were not formally verified this run
There was a problem hiding this comment.
Pull request overview
Adds first-pass HDL/Tcl support to Graphify’s structural extraction pipeline by introducing new extractors and wiring them into file-type detection and extension-based dispatch.
Changes:
- Added a tree-sitter-based VHDL extractor (
.vhd/.vhdl) for design units and relationships. - Added a regex-based Tcl extractor (
.tcl) for proc/namespace/package/source relationships. - Wired the new extensions into extraction dispatch (
graphify/extract.py) and code file detection (graphify/detect.py).
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| graphify/extractors/vhdl.py | New VHDL extractor using tree-sitter-vhdl to emit nodes/edges for common VHDL constructs. |
| graphify/extractors/tcl.py | New Tcl extractor using regex parsing to emit nodes/edges for procs, namespaces, and imports. |
| graphify/extract.py | Registers .vhd, .vhdl, and .tcl extensions in the extractor dispatch map and imports the new extractors. |
| graphify/detect.py | Adds .vhd, .vhdl, and .tcl to the code-extension allowlist. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
extract_vhdl() imports tree_sitter_vhdl, but nothing in pyproject.toml declared it — a plain 'uv tool install graphifyy' would leave the VHDL extractor silently degraded (its graceful "not installed" error path, never raising, so the gap wasn't obvious from a crash). Added the 'vhdl' extra following the same pattern as pascal/sql/dm/ terraform: kept optional rather than a hard dependency since VHDL projects are a minority of installs, same reasoning as those. Also folded into the 'all' extras group and documented in the README extras table and language-support list.
There was a problem hiding this comment.
Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).
Graphify reviewed this change.
Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).
Graphify review — findings
This PR adds source extraction support for two new languages, VHDL and Tcl. - New extractors: Introduces graphify/extractors/vhdl.py (tree-sitter-based, extracting entities, architectures, packages, subprograms, use-clause imports, and component instantiation edges) and graphify/extractors/tcl.py (regex-based, extracting procs, namespaces, package require, and source imports). - Wiring: Registers the new extensions (.vhd, .vhdl, .tcl) in detect.py's CODE_EXTENSIONS set and maps them to their extractors in the _DISPATCH table in extract.py. - Docs & packaging: Updates the README to document the new vhdl optional install extra and add the VHDL/Tcl language rows to the supported-formats tables. The surface area is mostly additive—two new files plus registration entries and documentation. Reviewers may want to confirm the tree-sitter-vhdl dependency is declared under the advertised [vhdl] extra.
No blocking issues surfaced. 2 lower-confidence candidates did not survive cross-model review.
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 1682 functions depend on the 325 functions this change touches.
Health — grade A; 10 existing hotspot(s) in the area this change touches (pre-existing, not introduced here):
extract()— 365 callers, 39 callees (high)_rebuild_code()— 87 callers, 51 callees (high)detect()— 82 callers, 13 callees (high)extract_xaml()— 19 callers, 17 callees (high)extract_files_direct()— 15 callers, 20 callees (high)save_manifest()— 26 callers, 10 callees (high)dispatch_command()— 2 callers, 117 callees (high)extract_corpus_parallel()— 23 callers, 10 callees (high)- …and 2 more
Verification — 1682 functions in the blast radius were not formally verified this run (proofs are advisory here).
Gate & verification
graphify gate
PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.
Advisory (not blocking):
- verification_scope: 1496 function(s) in the blast radius were not formally verified this run
vhdl.py — architecture_definition's 'implements' edge targeted _make_id(entity_name) (bare), while entity_declaration's own node uses _make_id(stem, name) (file-scoped). The two ids never matched, so the edge pointed at a disconnected placeholder node even when the entity and architecture live in the same file — the common VHDL case. Now uses the same stem-scoped id as entity_declaration. tcl.py — 'source <file>' edges targeted _make_id(filename) (bare filename text) and minted a new placeholder node for it, while real file nodes use _make_id(str(path)) (full resolved path). The two schemes never overlapped, so the edge could never connect to the sourced file's actual file-node. Fixed by mirroring bash.py's existing source-statement pattern: resolve (path.parent / filename).resolve(), require it to exist on disk (guards against path-traversal-crafted sources, same reasoning as bash.py), target the real file-node id, and attach target_file so extract()'s id-remap pass can still canonicalize the edge when the sourced file isn't in the current batch. Verified both: VHDL implements edge now resolves to the real entity node; Tcl imports_from edge now resolves to the real sourced file's node id, target_file hint attached.
There was a problem hiding this comment.
Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).
Graphify reviewed this change.
Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).
Graphify review — findings
This PR adds language support for VHDL and Tcl file extraction to graphify. It introduces two new extractor modules (graphify/extractors/vhdl.py using tree-sitter-vhdl for entities/architectures/packages/subprograms, and graphify/extractors/tcl.py using regex for procs/namespaces/package requires/source imports), registers their extensions in detect.py's CODE_EXTENSIONS, and wires them into the _DISPATCH map in extract.py. The README is also updated to document the new vhdl optional install extra and the supported extensions for both languages.
No blocking issues surfaced. 4 lower-confidence candidates did not survive cross-model review.
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 1682 functions depend on the 325 functions this change touches.
Health — grade A; 10 existing hotspot(s) in the area this change touches (pre-existing, not introduced here):
extract()— 365 callers, 39 callees (high)_rebuild_code()— 87 callers, 51 callees (high)detect()— 82 callers, 13 callees (high)extract_xaml()— 19 callers, 17 callees (high)extract_files_direct()— 15 callers, 20 callees (high)save_manifest()— 26 callers, 10 callees (high)dispatch_command()— 2 callers, 117 callees (high)extract_corpus_parallel()— 23 callers, 10 callees (high)- …and 2 more
Verification — 1682 functions in the blast radius were not formally verified this run (proofs are advisory here).
Gate & verification
graphify gate
PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.
Advisory (not blocking):
- verification_scope: 1496 function(s) in the blast radius were not formally verified this run
No description provided.