feat: Rust language support (.rs) - #59
Draft
qoole wants to merge 21 commits into
Draft
Conversation
Newer grammar releases in the tree-sitter ecosystem require the 0.25 runtime, so bump tree-sitter ^0.21.1→^0.25.0 and the Python/Go grammars to ^0.25.0 to unlock languages whose grammars need it. tree-sitter-typescript stays pinned at ^0.23.2 (still the latest release) — it declares peerOptional tree-sitter@^0.21.0, so an npm `overrides` entry pins its nested tree-sitter to the root one so the repo-root install resolves cleanly; verified the grammar's native binding still loads and parses correctly under tree-sitter 0.25.1. Also updates the stale-parse-limit comment in extract.ts: the chunked callback parse predates 0.25 (which lifted the 32KB string-parse limit) and is kept because it's behavior-identical and exercised by existing tests. No behavior change; full suite green (493/493).
Use stable syntax-node IDs to avoid duplicate reference edges and align the supported Node version with native Windows prebuilds.
Adds the PowerShell language to extract.ts: describePowerShell recognizes function/class/enum/method statements, psCalleeName/psImportKind/ psImportSpecifier classify commands (dot-source, Import-Module, using module) versus real calls, and psExported covers PowerShell's lack of a file-local export marker. bindings.ts's FileBindings gains a case-insensitive mode and PowerShell-specific defName/resolveRecvType handling ($this, scope-qualified definition names).
…, builtin cmdlets resolve.ts bundles the name-lookup and owner-index maps (NameIndex/ OwnerIndex) and adds a PowerShell case-folded tier alongside the existing exact-match one: same-file exact wins first, then same-file case-folded, then whole-repo exact, then whole-repo case-folded. A PowerShell caller that isn't itself a test file demotes test-path candidates at the two global tiers before the uniqueness check, so Pester's habit of redeclaring a prod name across several *.Tests.ps1 files doesn't drop every cross-file call as ambiguous. PS_BUILTIN_CMDLETS denylists the core cmdlet/Pester-DSL surface so a call to a builtin never wires to an unrelated in-repo definition of the same name. $PSScriptRoot resolves as a literal for import paths, and PS_IMPORT_EXTS keeps PowerShell's module extensions from cross-matching TS/Python specifiers. isTestPath moves to its own src/util/testpath.ts (a hard graph-topology input for resolve.ts now, not just ask.ts's soft rank-penalty); ask.ts re-exports it for backward compatibility.
CODE_EXTENSIONS picks up .ps1/.psm1/.psd1; isTestPath recognizes .tests.ps1 (Pester's naming convention). New test/graph-powershell.test.ts, test/testpath.test.ts, and test/utf16-routing.test.ts cover PowerShell graph extraction/resolution end-to-end and the UTF-16LE decode path. Every existing test file touched by the case-folding, test-aware tie-break, builtin-cmdlet denylist, and ingest changes is extended with PowerShell-specific coverage alongside its existing cases.
Assaf750
added a commit
to Assaf750/Graft
that referenced
this pull request
Aug 12, 2026
…and Rust behaviour Records the verified starting point before any Rust work: PR NanoNets#40/NanoNets#58/NanoNets#59 heads double-checked via the GitHub API and git ls-remote, strict-containment proof of the stack, and the finding that the stack carries no upstream CI signal at all. Suite on the pinned head is 638/645 with 3 failures. All three are an upstream locale defect (bare toLocaleString() resolving to ar-SA digits), reproduced verbatim on main and untouched by any Rust commit, so they are attributed upstream rather than counted as a Rust regression. Fix is deliberately deferred to its own commit. Also records measured behaviour on a Cargo workspace fixture: what already resolves, and the six gaps that Batches B-J exist to close — chiefly that cross-crate symbol imports never resolve because module-path resolution maps paths to files only. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Tier-1 graph extraction for Rust via tree-sitter-rust 0.24.0 (the tree-sitter org's own grammar; prebuilds for all six platform/arch combos — #40's 0.25 runtime is the prerequisite, and the same npm
overridespattern handles its peer range).What
interface), type aliases, unions, methods with impl-block owners (generics-stripped:impl Cache<T>owns asCache), andmacro_rules!definitions. Inline modules contribute scope segments (file.rs#imp.open), so cfg-gated sibling mods stay distinct and resolvable.pub/pub(crate)/pub(super)→ exported;pub(self)and plain items → not; trait-impl methods inherit the trait contract (exported);#[macro_export]macros exported; everything inside#[cfg(test)]mods unexported (#[cfg(not(test))]is correctly NOT matched).let, constructor-letT::new(), typed params,self→ enclosing impl),Type::method/Self::methodstatic calls, turbofish unwrapped, tuple-index calls guarded. Scoped calls (crate::worker::run()) resolve through the module tree and are restricted to the resolved file's candidates — never stripped to a bare name.!(log_it!), so a macro can never wire to a same-named function (Rust's namespaces are distinct). Std/prelude macros are skipped at extraction; path-qualified forms (std::println!) are recognized too.usepaths (all forms: scoped, grouped per-leaf, renames, wildcards) andmoddeclarations resolve through the real module tree —crate::/super::/self::, bothx.rsandx/mod.rslayouts, the parser-file rule (src/parser.rs's children live insrc/parser/), inline-modsuperconsumption (ause super::*inside#[cfg(test)] mod testscorrectly refers to its own file), and integration-test crate roots (tests/*.rsanchorcrate::to themselves, not the library).Cargo.toml's[package]name (section-aware parse;[[bin]]names ignored) maps cross-crate imports (foo_bar::…↔crates/foo-bar/), including dependency{ package = "…" }aliases; duplicate package names are treated as ambiguous and dropped rather than guessed, and crate matching is deterministic regardless of enumeration order.From<A>/From<B>both givingFrame.from;Display/Debugboth givingfmt) drops the member call as ambiguous instead of guessing first-in-file. Drop-don't-guess throughout, matchingmapclusters one entry per file instead of per directory #35's resolution philosophy.Evidence
moddeclarations,#[path]attributes, the cross-language method-owner leak). The reviews' dropped-edge findings are disclosed below rather than patched around.Known limitations (deliberate; all fail toward dropped edges, never wrong ones)
assert_eq!(compute(), 3)contributes nocomputecall edge (no expansion).<T as Tr>::method()) drop.#[path = "…"]mod declarations drop (resolving conventionally would wire the wrong file).impl Trait for Typeheritage is dropped (trait-default-method resolution needs the type defined in the same file).implblocks inside function bodies mint unowned functions.tests/don't anchorcrate::(statically ambiguous — each test binary is its own crate).pub usere-export chains and proc-macro expansion are unsupported.&raw const/mut(~2–4% of files in modern codebases parse with errors; extraction degrades gracefully and still yields those files' other definitions). Happy to file that upstream.