feat(graph): add Rust code graph extractor#101
Conversation
theDakshJaitly
left a comment
There was a problem hiding this comment.
Requesting changes because the implementation does not yet satisfy several explicit acceptance criteria from #96. The existing typecheck, full test suite, and build pass, but focused cases reproduce the inline issues below.
| if (!body) return; | ||
| this.scopeStack.push(id); | ||
| for (const member of body.namedChildren) { | ||
| if (member.type === "function_item") { |
There was a problem hiding this comment.
Trait methods without default bodies parse as function_signature_item, not function_item, so declarations such as fn greet(&self) -> String; are silently dropped. The current fixture contains exactly this case, but its test only asserts the Greeter interface node. Please handle signature-only trait methods too and assert that Greeter::greet is emitted with the expected containment/signature data.
| private walkBody(body: TSNode, ownerId: string): void { | ||
| const type = body.type; | ||
|
|
||
| if (CALL_TYPES.has(type)) { |
There was a problem hiding this comment.
This body walker never handles Rust struct_expression nodes, so even the fixture's explicit User { ... } construction emits no instantiates -> User reference. Issue #96 explicitly requires instantiation references where syntax is explicit. Please extract struct construction here (and cover it with a focused assertion).
| private extractFunction(node: TSNode, isMethod = false): void { | ||
| const name = nameOf(node, this.source); | ||
| if (!name) return; | ||
| const id = this.createNode(isMethod ? "method" : "function", name, node, { |
There was a problem hiding this comment.
Explicit generic parameters are not copied into GraphNode.typeParameters: for example, fn make<T> currently produces typeParameters: undefined. The same omission affects structs/enums/traits. Capturing explicit generics is an acceptance criterion in #96, so please parse the grammar's type-parameter field for each supported declaration and add coverage.
| // correct (e.g. `Foo::method`). | ||
|
|
||
| // Check if the struct/enum is already in the file. | ||
| let ownerId: string | null | undefined = this.nodes.find(n => n.name === typeName && (n.kind === "class" || n.kind === "enum" || n.kind === "interface"))?.id; |
There was a problem hiding this comment.
This lookup makes containment depend on declaration order. Valid Rust such as impl User { fn greet(&self) {} } struct User; creates a namespace owner for the impl, and the method never becomes contained by the later User class node. Please make same-file type ownership order-independent, for example by collecting declarations before visiting impls or deferring impl binding.
| if (calleeName) this.addRef(ownerId, calleeName, "calls", node); | ||
|
|
||
| const args = getChildByField(node, "arguments"); | ||
| if (args) for (const child of args.namedChildren) this.walkBody(child, ownerId); |
There was a problem hiding this comment.
Arguments are walked here and then walked a second time when walkBody continues through all of the call node's namedChildren. As a result, consume(make()) emits two identical calls -> make references, which are persisted as duplicate unresolved refs/edges. Please ensure call arguments are traversed exactly once and add a count-based regression assertion.
| tsx: "tree-sitter-tsx.wasm", | ||
| javascript: "tree-sitter-javascript.wasm", | ||
| jsx: "tree-sitter-javascript.wasm", | ||
| rust: "tree-sitter-rust.wasm", |
There was a problem hiding this comment.
The new vendored WASM binary is registered, but its upstream source, exact version/commit, and license are not documented anywhere in this PR. That provenance is explicitly required by issue #96 and docs/extractors.md; please add it alongside the vendored grammar documentation before merge.
|
Addressed all requested review feedback:
Re-ran validation:
|
What
LanguageExtractorinterface..rsfile detection and vendored the Tree-sitter Rust WASM grammar.Why
Closes #96
This adds initial Rust support to the code graph preview by extracting:
use)Cross-file references remain unresolved through
targetName, and macro invocations are handled conservatively as required.Type of change
How to test
Run:
Run:
npm testRun:
Verify that:
.rsfiles are recognized correctly.targetName.Checklist
npm test)Code-graph preview
code-graph-preview, notmainTarget branch: code-graph-previewLanguageExtractororFrameworkResolverinterface