Skip to content

Feat/hdl vhdl tcl extractors - #2476

Open
3brahimi wants to merge 4 commits into
Graphify-Labs:v8from
3brahimi:feat/hdl-vhdl-tcl-extractors
Open

Feat/hdl vhdl tcl extractors#2476
3brahimi wants to merge 4 commits into
Graphify-Labs:v8from
3brahimi:feat/hdl-vhdl-tcl-extractors

Conversation

@3brahimi

@3brahimi 3brahimi commented Aug 5, 2026

Copy link
Copy Markdown

No description provided.

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'.
Copilot AI lite review requested due to automatic review settings August 5, 2026 13:08

@graphify-labs graphify-labs Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread graphify/extractors/vhdl.py
Comment thread graphify/extractors/tcl.py Outdated
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.

@graphify-labs graphify-labs Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@graphify-labs graphify-labs Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants