Skip to content

v0.2.0

Choose a tag to compare

@JeelGajera JeelGajera released this 16 Aug 11:19
· 78 commits to master since this release
aeebd0f

Graphyn v0.2.0 — Five languages, one graph 🌐

Graphyn is no longer TypeScript-only.

v0.2.0 adds Python, Rust, Go, and C/C++ adapters behind a shared dispatch layer, so mixed-language repositories can now be indexed in a single pass — with property resolution grounded in declared types across every adapter.

graphyn analyze ./my-repo

This now indexes .ts, .py, .rs, .go, .c, and .cpp together.

🚀 Language support

Language Extensions Resolves
TypeScript / JavaScript .ts .tsx .js .jsx .mts .cts .mjs .cjs tsconfig paths, barrel re-exports, decorator DI
Framework files .vue .svelte .astro Script blocks within the component
Python .py .pyi Relative imports, __init__ re-export chains, star imports, TYPE_CHECKING guards, Pydantic / Django / dataclass fields
Rust .rs Module tree, use groups and aliases, glob imports, trait impls, #[derive], macro token trees
Go .go Package imports via go.mod, structural interface satisfaction
C .c .h #include resolution, typedef aliases
C++ .cpp .cc .cxx .hpp .hxx .hh using aliases, base classes, namespace-qualified names

Every adapter attributes member access to the type a value was declared as. So payload.user_id is recorded against UserPayload regardless of what the variable is actually named.

✨ Added

  • Added five new crates:
    • graphyn-adapter-python
    • graphyn-adapter-rust
    • graphyn-adapter-go
    • graphyn-adapter-c
    • graphyn-adapter-dispatch
  • The dispatch layer routes files to the correct language adapter and runs adapter groups in parallel.
  • Added shared symbol-ID and AST traversal helpers to graphyn-core, replacing five per-adapter copies.
  • Added parse, resolution, and skip diagnostics across adapters. Pruned directories are now reported instead of silently disappearing.
  • Added a cross-language regression suite and polyglot fixtures.
  • Test coverage grew from 39 to 185 tests, replacing 27 assert!(true) stubs with real coverage.

🐛 Fixed

Property resolution

  • Property access was previously matched against a hardcoded variable name.
  • The new adapters compared receivers against the literal string "data", which meant property tracking failed for any other variable name in Rust, Go, and C/C++.
  • Receivers are now bound to declared types from parameters, let/var bindings, annotations, and declarators.
  • Struct fields no longer leak from one struct into another.

Imports & symbols

  • #include previously produced a graph with zero edges because includes became local_header::<name>, which add_relationship drops. Includes now resolve to the header's module symbol.
  • C struct names were incorrectly reported as ambiguous. A struct Foo *p parameter is a struct_specifier, but not a new definition; we no longer mint a symbol for every reference.
  • Go imports previously pointed at an arbitrary package member instead of the package itself.
  • Rust use paths now resolve through the declaring module and follow pub use chains instead of matching leaf names repository-wide.
  • Python now indexes the relevant symbol kinds so importing a function no longer fabricates a dependency that does not exist.
  • An alias equal to the symbol's own name is no longer treated as a rename, reducing noise around genuine renames.

Publishing

  • The crates.io publish job now publishes all ten crates in dependency order.
  • Previously, publishing could fail partway through after graphyn-core had already been released.

🔧 Changed

  • Graph construction order is deterministic again. Dispatch groups files using a stable ordering key instead of relying on HashMap iteration order.
  • AST traversal is now iterative and depth-bounded, preventing deeply nested input from overflowing a rayon worker's stack.
  • Unresolved edges are removed with a warning instead of being silently dropped.
  • env, gen, and proto are indexable again.
  • An explicit --include now overrides the built-in excludes.

⚠️ Known limits

A few limitations are worth calling out explicitly:

  • Imports are language-local. A Python module importing a TypeScript file through a build step is not linked.
  • Chained access only tracks the first receiver. In a.b.c, c is not attributed to the type of a.b.
  • C++ templates are parsed, not instantiated. vector<Foo> records a reference to Foo.
  • Go structural matching is per-package. Matching every method set against every interface repository-wide creates more noise than signal.
  • Rust macro bodies are token trees. Field access inside format! and similar macros is recovered by scanning tokens; macro-generated code is not expanded.

📦 Install

macOS / Linux

curl -fsSL https://raw.githubusercontent.com/JeelGajera/graphyn/master/install.sh | bash

Windows

irm https://raw.githubusercontent.com/JeelGajera/graphyn/master/install.ps1 | iex

Cargo

cargo install graphyn-cli

🔗 Full changelog

v0.1.3...v0.2.0