Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,17 @@

Full release notes with details on each version: [GitHub Releases](https://github.com/Graphify-Labs/graphify/releases)

## Unreleased

- Feature: the Salam extractor now resolves a bare function name passed as a call argument (`register("/", home)`, `pool.submit(worker)`) to its definition as an `indirect_call` edge - Salam decays a bare function reference to its address, so this is a real, common pattern (route handlers, thread entry points, callback registries), not a call. A package-qualified reference (`handlers.Home`) resolves across files; an unqualified one only within the same file, since nothing else can tell a same-named local/param/constant apart from a genuine reference without risking a wrong cross-file guess.
- Fix: a param/local that shadows an import alias (`func Escape(db: Database)` alongside a same-file `import db`, real code in `std/db/mysql/mysql.salam`) no longer has its own field read (`db.handle`) misread as a package-qualified function reference.
- Fix: a multi-word method name (`.is weekend()`) is no longer truncated to its last word when called - previously only multi-word top-level functions merged correctly; `this`/`این` is now a registered keyword (it was accidentally omitted from the keyword-table refresh), fixing the receiver chain for `this.field` when a preceding identifier could otherwise merge into it.

## 0.9.69 (2026-09-26)

- Feature: the Salam extractor now resolves a member call chained off another call's return value (`makeCircle(r).area()`), off a local variable bound from one (`c := makeCircle(r) ... c.area()`), off a struct literal (`Circle{r=1}.area()`), and off an `as Type` cast (`f() as Circle`) - reading the callee's declared return type across files where needed. A 2+-hop chain (`f().g().h()`) is left unresolved rather than guessed.
- Fix: the Salam extractor now tracks the current compiler keyword table (`switch`/`case`, the Persian guillemet `«»` string form, and the `repeat ... each N in i` step/binding spelling) and no longer misreads a keyword reused as a struct-literal field name (`Type { if = true }`) as the start of a control block.
- Feature: Salam (`.salam`) language extractor — current English and Persian keyword set (including the Persian comma `،`), packages and imports (including Persian package names via `@fa`), functions, structs with methods, enums, interfaces, `impl` blocks, type aliases, constants, `extern:` C functions, `link` libraries, layout blocks and components, plus `calls` and `references` edges; pure token scanner, no new dependency. A cross-file resolver binds `pkg.Func()`, string-import aliases, receiver-typed method calls, and type references.
- Feature: five language extractors gained structural depth — **OCaml** classes now emit their methods (via the `method` relation) and instance variables (#3838, thanks @rajatnagda45); **Elixir** `defprotocol`/`defimpl` are extracted as containers holding their functions, with a same-file `implements` link (#3839, thanks @rajatnagda45); **Fortran** derived-type `contains` blocks link type-bound procedures to the type, resolving the `=> impl` target (#3840, thanks @rajatnagda45); **Julia** macro definitions and `@enum` types are extracted, including valued (`red = 1`) and typed (`Color::UInt8`) enum forms, with members using the `case_of` relation (#3841, thanks @rajatnagda45); **Kotlin** annotations (class/function/property, use-site targets) and `val`/`var` primary-constructor properties now produce edges (#3848, #3842, thanks @nikhilsaxena04).
- Fix: a TypeScript "solution" `tsconfig.json` that only carries `references` (no `paths` of its own) now resolves path aliases declared in the referenced project configs, so alias imports in a `tsc -b` layout no longer dangle (#3753, #3745, thanks @abhay-codes07).
- Fix: extraction now skips the process pool up front when the `spawn` start method can't re-import `__main__` (stdin, `python -c`, REPL, embedded callers), falling back to a correct sequential run instead of a wall of `BrokenProcessPool` tracebacks (#3754, #3669, thanks @abhay-codes07).
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ To remove graphify from all platforms at once: `graphify uninstall` (add `--purg
|------|-----------|
| Code (37 tree-sitter grammars) | `.py .ts .mts .cts .js .jsx .tsx .mjs .go .rs .java .c .cpp .cc .cxx .h .hpp .cu .cuh .metal .rb .cs .kt .kts .scala .php .swift .lua .luau .toc .zig .ps1 .psm1 .psd1 .ex .exs .m .mm .ml .mli .jl .vue .svelte .astro .groovy .gradle .dart .v .sv .svh .sql .f .f90 .f95 .f03 .f08 .pas .pp .dpr .dpk .lpr .inc .dfm .lfm .lpk .sh .bash .json .dm .dme .dmi .dmm .dmf .sln .slnx .csproj .fsproj .vbproj .xaml .razor .cshtml` (`.dm`/`.dme` requires `uv tool install graphifyy[dm]`, `.ml`/`.mli` requires `uv tool install graphifyy[ocaml]`; `.mts`/`.cts` reuse the TypeScript grammar, `.cc`/`.cxx` and CUDA `.cu`/`.cuh` and Metal `.metal` reuse the C++ grammar) |
| Salesforce Apex | `.cls .trigger` (regex-based; classes, interfaces, enums, methods, triggers, SOQL/DML edges) |
| Salam | `.salam` (no extra dependency; English and Persian keywords, `switch`/`case`, Persian guillemet `«»` strings; packages, imports, functions, structs, methods, enums, interfaces, `impl`, extern C, layout/components, call and type-reference edges, `@en`/`@fa` name aliases) |
| Terraform / HCL | `.tf .tfvars .hcl` (requires `uv tool install graphifyy[terraform]`) |
| OCaml | `.ml .mli` (requires `uv tool install graphifyy[ocaml]`) |
| Common Lisp | `.lisp .cl .lsp .asd` (requires `uv tool install graphifyy[commonlisp]`) |
Expand Down
1 change: 1 addition & 0 deletions graphify/analyze.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
**{e: "php" for e in (".php",)},
**{e: "r" for e in (".r",)},
**{e: "cobol" for e in (".cbl", ".cob", ".cobol", ".cpy")},
**{e: "salam" for e in (".salam",)},
**{e: "solidity" for e in (".sol",)},
**{e: "erlang" for e in (".erl", ".hrl", ".escript")},
}
Expand Down
2 changes: 1 addition & 1 deletion graphify/detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class FileType(str, Enum):
_MTIME_COARSE_S = 2.0
_MTIME_SUBSECOND_S = 0.05

CODE_EXTENSIONS = {'.py', '.ts', '.tsx', '.mts', '.cts', '.js', '.jsx', '.mjs', '.cjs', '.ejs', '.ets', '.go', '.rs', '.vb', '.cbl', '.cob', '.cobol', '.cpy', '.java', '.groovy', '.gradle', '.cpp', '.cc', '.cxx', '.c', '.h', '.hpp', '.cu', '.cuh', '.metal', '.rb', '.rake', '.swift', '.kt', '.kts', '.cs', '.scala', '.php', '.lua', '.luau', '.toc', '.zig', '.ps1', '.psm1', '.psd1', '.ex', '.exs', '.m', '.mm', '.ml', '.mli', '.jl', '.vue', '.svelte', '.astro', '.dart', '.v', '.sv', '.svh', '.sql', '.r', '.f', '.F', '.f90', '.F90', '.f95', '.F95', '.f03', '.F03', '.f08', '.F08', '.pas', '.pp', '.dpr', '.dpk', '.lpr', '.inc', '.dfm', '.lfm', '.lpk', '.sh', '.bash', '.json', '.tf', '.tfvars', '.hcl', '.dm', '.dme', '.dmi', '.dmm', '.dmf', '.sln', '.slnx', '.csproj', '.fsproj', '.vbproj', '.xaml', '.razor', '.cshtml', '.cls', '.trigger', '.lisp', '.cl', '.lsp', '.asd', '.robot', '.resource', '.sol', '.erl', '.hrl', '.escript'}
CODE_EXTENSIONS = {'.py', '.ts', '.tsx', '.mts', '.cts', '.js', '.jsx', '.mjs', '.cjs', '.ejs', '.ets', '.go', '.rs', '.salam', '.vb', '.cbl', '.cob', '.cobol', '.cpy', '.java', '.groovy', '.gradle', '.cpp', '.cc', '.cxx', '.c', '.h', '.hpp', '.cu', '.cuh', '.metal', '.rb', '.rake', '.swift', '.kt', '.kts', '.cs', '.scala', '.php', '.lua', '.luau', '.toc', '.zig', '.ps1', '.psm1', '.psd1', '.ex', '.exs', '.m', '.mm', '.ml', '.mli', '.jl', '.vue', '.svelte', '.astro', '.dart', '.v', '.sv', '.svh', '.sql', '.r', '.f', '.F', '.f90', '.F90', '.f95', '.F95', '.f03', '.F03', '.f08', '.F08', '.pas', '.pp', '.dpr', '.dpk', '.lpr', '.inc', '.dfm', '.lfm', '.lpk', '.sh', '.bash', '.json', '.tf', '.tfvars', '.hcl', '.dm', '.dme', '.dmi', '.dmm', '.dmf', '.sln', '.slnx', '.csproj', '.fsproj', '.vbproj', '.xaml', '.razor', '.cshtml', '.cls', '.trigger', '.lisp', '.cl', '.lsp', '.asd', '.robot', '.resource', '.sol', '.erl', '.hrl', '.escript'}
DOC_EXTENSIONS = {'.md', '.mdx', '.qmd', '.skill', '.txt', '.rst', '.html', '.yaml', '.yml'}
PAPER_EXTENSIONS = {'.pdf'}
IMAGE_EXTENSIONS = {'.png', '.jpg', '.jpeg', '.gif', '.webp', '.svg'}
Expand Down
6 changes: 6 additions & 0 deletions graphify/extract.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
from graphify.extractors.razor import extract_razor # noqa: F401
from graphify.extractors.robot import extract_robot # noqa: F401
from graphify.extractors.rust import extract_rust # noqa: F401
from graphify.extractors.salam import extract_salam, resolve_salam_references # noqa: F401
from graphify.extractors.sln import extract_sln # noqa: F401
from graphify.extractors.solidity import ( # noqa: F401
extract_solidity,
Expand Down Expand Up @@ -3070,6 +3071,7 @@ def _lang_is_case_insensitive(source_file: object) -> bool:
".py": "python",
".go": "go",
".rs": "rust",
".salam": "salam",
".cbl": "cobol", ".cob": "cobol", ".cobol": "cobol", ".cpy": "cobol",
".r": "r",
".sol": "solidity",
Expand Down Expand Up @@ -5518,6 +5520,9 @@ def _resolve_kotlin_member_calls(
"solidity_type_references", frozenset({".sol"}), resolve_solidity_type_references
)
)
register_language_resolver(
LanguageResolver("salam_references", frozenset({".salam"}), resolve_salam_references)
)
register_language_resolver(
LanguageResolver(
"erlang_remote_calls",
Expand Down Expand Up @@ -6626,6 +6631,7 @@ def add_existing_edge(edge: dict) -> None:
".metal": extract_cpp,
".rb": extract_ruby, ".rake": extract_ruby,
".cs": extract_csharp,
".salam": extract_salam,
".cbl": extract_cobol,
".cob": extract_cobol,
".cobol": extract_cobol,
Expand Down
2 changes: 2 additions & 0 deletions graphify/extractors/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from graphify.extractors.r import extract_r
from graphify.extractors.razor import extract_razor
from graphify.extractors.rust import extract_rust
from graphify.extractors.salam import extract_salam
from graphify.extractors.sln import extract_sln
from graphify.extractors.solidity import extract_solidity
from graphify.extractors.sql import extract_sql
Expand Down Expand Up @@ -66,6 +67,7 @@
"r": extract_r,
"razor": extract_razor,
"rust": extract_rust,
"salam": extract_salam,
"sln": extract_sln,
"solidity": extract_solidity,
"sql": extract_sql,
Expand Down
Loading