rustextract

package
v0.9.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 12, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package rustextract walks a Rust file's tree-sitter syntax tree into the shared codegraph vocabulary (goextract.FileResult/ExtractedNode/IntraEdge/ UnresolvedRef, goextract.Kind*/RefKind*), mirroring internal/indexer/goextract's shape (D-01) rather than redefining its own copy of that vocabulary.

This is a MAINSTREAM-tier extractor (LANG-06, D-04): full structural extraction, but only best-effort SAME-FILE/SAME-MODULE cross-reference resolution — not the priority-4 full-import-resolution bar. Every resolution gap named below is a deliberate, documented tier boundary, not a bug.

Node-kind mapping decisions:

  • struct_item -> goextract.KindStruct.
  • enum_item -> goextract.KindStruct (documented gap: this vocabulary has no distinct "enum" kind; an enum's own variants are never extracted as separate symbols, mirroring the project's existing "reuse an existing Kind rather than mint a new one" discipline).
  • trait_item -> goextract.KindInterface.
  • A top-level (root-direct-child) function_item -> goextract.KindFunction. A function_item nested inside an impl_item's own declaration_list body -> goextract.KindMethod (QualifiedName "ImplType.fnname"). Only ROOT-LEVEL declarations are walked (mirrors goextract's/pyextract's own top-level-only scope) — items nested inside a `mod foo { ... }` inline module block are NOT descended into; a documented, accepted gap for this tier.
  • Rust has no field_declaration-equivalent node this extractor visits at all — a struct's own fields are never walked, matching the ratified "no field node" skip every other extractor in this project already applies.
  • use_declaration -> goextract.RefKindImports, one ref per leaf path (handling the plain/aliased/grouped-brace/wildcard shapes). This extractor deliberately NEVER populates FileResult.Imports from a `use` statement: resolving `use crate::foo::Bar` into a moduleKey that actually matches the target file's own computed moduleKey (languages_rust.go's crate-name + module-path scheme) requires knowing the enclosing crate's name at Extract time, which this function's shared cross-language signature does not provide (the same architectural constraint tsextract's Config/SetConfig side-channel pattern solves for TS/JS's tsconfig paths — out of scope for this mainstream-tier plan). Consequently cross-file `use`-qualified call/ trait-impl resolution is NOT implemented; only same-file (and, incidentally, any other file sharing the exact same computed rustModulePath) resolution via an empty PkgAlias works.
  • impl_item: the "type" field's struct/enum gets each of the impl block's own function_item children extracted as KindMethod nodes, attached via a same-file contains IntraEdge when the impl'd type is declared in this same file, or a RefKindContains unresolved ref otherwise (mirrors goextract's cross-file receiver-type handling). When the impl_item ALSO carries a "trait" field (`impl Trait for Type`), one RefKindEmbeds unresolved ref (Type -> Trait) is emitted, undistinguished from a "some other embed" shape at parse time (Pattern 2) — resolve.go promotes it to "implements" once the target resolves to an interface node, exactly like Java/C#/TS/Python's own extends/ implements-shaped refs.
  • call_expression -> goextract.RefKindCalls. A bare identifier callee is an unqualified call (empty PkgAlias). A field_expression callee (`recv.method()`) checks whether the receiver identifier is likely a same-module type name by PascalCase naming convention (Rust's own near-universal convention distinguishing a type from a local binding/parameter) — an empty PkgAlias routes it through resolveUnqualified; any other identifier or non-identifier receiver routes through the WR-02 synthetic-non-matching-alias pattern so it deterministically ends up "unresolved" rather than risking a false same-module match. A scoped_identifier callee (`Type::method()` / `Self::method()` / `crate::method()`) applies the same PascalCase heuristic to its path segment.

Explicitly out of scope for this mainstream tier (named for the D-11 capability matrix, not silently missing):

  • Macro-generated items (derive macros, function-like macros expanding into new struct/fn/trait declarations) are never extracted — this extractor only sees the macro invocation site (macro_invocation), not its expansion, since expansion requires a real macro engine this project does not run.
  • generic_function callees (`foo::<T>()`, turbofish syntax) and macro_invocation callees (`println!()`) are not resolved into calls edges at all.
  • Trait default-method inheritance (a type implementing a trait that has a default-bodied method, calling that method without overriding it) is not resolved — no conformance-retry pass exists for this tier (Pitfall 3's two-pass retry is a priority-4-only mechanism).
  • Items declared inside an inline `mod foo { ... }` block are not extracted (top-level-only scope, see above).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Extract

func Extract(p parser.Parser, moduleKey, relPath string, src []byte) (goextract.FileResult, error)

Extract walks a single Rust file's parsed syntax tree and produces its Pass-1 intermediate, reproducing goextract.Extract's exact skip/error contract (05-PATTERNS.md's "Per-file skip/error contract"): a parse failure or unexpected tree shape sets FileResult.Err and Extract itself returns a nil error, so one bad file never aborts a caller's batch. This is the front-line mitigation (threat T-05-DoS) for tree-sitter-rust's external raw-string C scanner — parser.MaxSourceBytes is enforced by p.Parse BEFORE any backend-specific parsing runs.

moduleKey is computed entirely at discovery time by languages_rust.go's LanguageSpec.ModuleKey (crate name + Cargo-convention module path) — Extract never overrides FileResult.ImportPath.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL