Skip to main content

FileIndex

Struct FileIndex 

Source
pub struct FileIndex { /* private fields */ }

Implementations§

Source§

impl FileIndex

Source

pub async fn open(db_path: &Path, root: &Path) -> Result<Self, Error>

Open or create an index at the specified database path. On corruption, automatically deletes and recreates the index.

§Arguments
  • db_path - Path to the SQLite database file
  • root - Project root directory (used for file walking during refresh)
Source

pub fn set_progress(&mut self, enabled: bool)

Enable progress bar output for long-running operations (refresh, call graph). Only shows bars when stderr is a terminal.

Source

pub fn connection(&self) -> &Connection

Get a reference to the underlying SQLite connection for direct queries

Source

pub async fn get_changed_files(&self) -> Result<ChangedFiles, Error>

Get files that have changed since last index

Source

pub async fn invalidate_last_indexed(&self) -> Result<(), Error>

Test/maintenance helper: clear the last_indexed meta value so the next needs_refresh() returns true regardless of the 60-second debounce.

Used by integration tests that need to force refresh after each file edit without waiting for the staleness window.

Source

pub async fn incremental_refresh(&mut self) -> Result<Vec<PathBuf>, Error>

Refresh only files that have changed (faster than full refresh). Returns the list of changed file paths (absolute) that were added, modified, or deleted. The count can be derived from .len().

Source

pub async fn incremental_refresh_force(&mut self) -> Result<Vec<PathBuf>, Error>

Refresh only files that have changed, bypassing the needs_refresh() staleness gate.

incremental_refresh() short-circuits if the index was refreshed within the last 60 seconds and no top-level mtime changes are visible — a cheap “probably nothing changed” heuristic for cold-CLI callers running many commands in quick succession. For an event-driven daemon, the watcher firing is the signal that something changed, so the gate is wrong. Daemons should call this variant.

Source

pub async fn execute(&self, sql: &str) -> Result<u64, Error>

Execute a raw SQL statement (for maintenance operations).

Source

pub async fn raw_query( &self, sql: &str, ) -> Result<Vec<Map<String, Value>>, Error>

Run an arbitrary read-only SQL query and return results as a list of row maps.

Each row is a serde_json::Map from column name to value. Useful for agent-driven exploration of the structural index.

Source

pub async fn refresh(&mut self) -> Result<usize, Error>

Refresh the index by walking the filesystem

Source

pub async fn all_files(&self) -> Result<Vec<IndexedFile>, Error>

Get all files from the index

Source

pub async fn find_by_name(&self, name: &str) -> Result<Vec<IndexedFile>, Error>

Search files by exact name match

Source

pub async fn find_by_stem(&self, stem: &str) -> Result<Vec<IndexedFile>, Error>

Search files by stem (filename without extension)

Source

pub async fn count(&self) -> Result<usize, Error>

Count indexed files

Source

pub async fn index_file_symbols( &self, path: &str, symbols: &[FlatSymbol], calls: &[(String, String, usize)], ) -> Result<(), Error>

Index symbols and call graph for a file

Source

pub async fn find_callers( &self, symbol_name: &str, def_file: &str, ) -> Result<Vec<(String, String, usize, Option<String>)>, Error>

Find callers of a specific symbol definition (from call graph).

def_file is the file that contains the definition being searched. Results are restricted to files that are def_file itself (self-recursive calls) or that explicitly import the symbol. This prevents false positives from unrelated functions with the same name in other modules.

Resolves through imports: if file A imports X as Y and calls Y(), it is found as a caller of X. Also handles qualified calls (foo.bar()) and self.method() resolved to the containing class.

Source

pub async fn find_callees( &self, file: &str, symbol_name: &str, ) -> Result<Vec<(String, usize, Option<String>)>, Error>

Find callees of a symbol (what it calls)

Source

pub async fn find_callees_resolved( &self, file: &str, symbol_name: &str, ) -> Result<Vec<(String, usize, Option<String>)>, Error>

Find callees with their resolved definition file.

Returns (callee_name, line, Option<def_file>) where def_file is the root-relative path of the file that defines the callee, resolved via the imports table’s resolved_file column. None means the callee is locally defined, external, or could not be resolved.

Source

pub async fn find_symbol( &self, name: &str, ) -> Result<Vec<(String, String, usize, usize)>, Error>

Find a symbol by name

Source

pub async fn all_symbol_names(&self) -> Result<HashSet<String>, Error>

Get all distinct symbol names as a HashSet.

Source

pub async fn find_symbols( &self, query: &str, kind: Option<&str>, fuzzy: bool, limit: usize, ) -> Result<Vec<SymbolMatch>, Error>

Find symbols by name with fuzzy matching, optional kind filter, and limit

Source

pub async fn call_graph_stats(&self) -> Result<CallGraphStats, Error>

Get call graph stats

Source

pub async fn all_call_edges( &self, ) -> Result<Vec<(String, String, String)>, Error>

Load all call edges from the calls table. Returns Vec<(caller_file, caller_symbol, callee_name)>. Used by test-gaps analysis for bulk caller lookup.

Source

pub async fn all_imports( &self, ) -> Result<Vec<(String, String, String, u32)>, Error>

Load all imports from the imports table. Returns Vec<(file, module, name, line)>. Used by rules for building relations.

Source

pub async fn all_resolved_import_edges( &self, ) -> Result<Vec<(String, String)>, Error>

Load all resolved import edges from the imports table. Returns Vec<(importer_file, imported_file)> for rows where resolved_file IS NOT NULL. The paths are root-relative strings as stored in the database. Used by the daemon to build the reverse-dep graph on startup.

Source

pub async fn all_resolved_imports_with_lines( &self, ) -> Result<Vec<(String, u32, String)>, Error>

Load all resolved import edges with line numbers. Returns Vec<(importer_file, line, resolved_file)> for rows where resolved_file IS NOT NULL. Used by the boundary-violations native rule to check cross-boundary imports with precise source locations.

Source

pub async fn import_fan_out_by_file( &self, ) -> Result<Vec<(String, usize)>, Error>

Count distinct resolved import targets per file (fan-out). Returns Vec<(file, count)> ordered by count descending. Only counts rows where resolved_file IS NOT NULL. Used by the high-fan-out native rule.

Source

pub async fn import_fan_in_by_file(&self) -> Result<Vec<(String, usize)>, Error>

Count distinct files that import each file (fan-in). Returns Vec<(file, count)> ordered by count descending. Only counts rows where resolved_file IS NOT NULL. Used by the high-fan-in native rule.

Source

pub async fn resolved_imports_for_file( &self, file: &str, ) -> Result<Vec<String>, Error>

Load resolved import edges for a specific importer file (root-relative path). Returns Vec<imported_file> where resolved_file IS NOT NULL. Used by the daemon to update outgoing edges for a changed file.

Source

pub async fn find_import_path( &self, from: &str, to: &str, all_paths: bool, path_limit: usize, max_depth: usize, ) -> Result<Vec<Vec<String>>, Error>

Find the shortest import path(s) from from to to via BFS over the resolved import graph.

from and to are root-relative path strings (as stored in the DB). Returns all shortest paths (there may be more than one of equal length). If all_paths is true, returns all simple paths up to path_limit paths and up to max_depth hops deep. Returns an empty vec if no path exists.

Source

pub async fn all_symbol_implements( &self, ) -> Result<Vec<(String, String, String)>, Error>

Load all symbol implements from the symbol_implements table. Returns Vec<(file, name, interface)>.

Source

pub async fn all_type_methods( &self, ) -> Result<Vec<(String, String, String)>, Error>

Load all type methods from the type_methods table. Returns Vec<(file, type_name, method_name)>.

Source

pub async fn all_calls_with_lines( &self, ) -> Result<Vec<(String, String, String, u32)>, Error>

Load all calls with line numbers. Returns Vec<(caller_file, caller_symbol, callee_name, line)>. Used by rules for building relations.

Source

pub async fn all_symbols_with_details( &self, ) -> Result<Vec<(String, String, String, usize, usize, Option<String>, String, bool)>, Error>

Load all symbols from the symbols table with full details. Returns Vec<(file, name, kind, start_line, end_line, parent, visibility, is_impl)>. Used by test-gaps analysis to classify test context.

Source

pub async fn all_symbol_attributes( &self, ) -> Result<Vec<(String, String, String)>, Error>

Load all symbol attributes from the symbol_attributes table. Returns Vec<(file, name, attribute)>.

Source

pub async fn all_calls_with_qualifiers( &self, ) -> Result<Vec<(String, String, String, Option<String>, u32)>, Error>

Load all calls with qualifiers. Returns Vec<(caller_file, caller_symbol, callee_name, callee_qualifier, line)>.

Source

pub async fn all_cfg_edges( &self, ) -> Result<Vec<(String, String, u32, u32, u32, String, String)>, Error>

Return all CFG effect rows: (file, function_qname, function_start_line, block_id, kind, line, label). Query all CFG edge facts from the index. Returns tuples of (file, function_qname, function_start_line, from_block, to_block, kind, exception_type).

Source

pub async fn all_cfg_effects( &self, ) -> Result<Vec<(String, String, u32, u32, String, u32, String)>, Error>

Source

pub async fn module_to_files( &self, module: &str, source_file: &str, ) -> Vec<String>

Convert a module name to possible file paths using the language’s trait method. Returns only paths that exist in the index.

Source

pub async fn resolve_all_imports(&self) -> Result<usize, Error>

Resolve all unresolved import rows by populating resolved_file.

For each import row where module IS NOT NULL and resolved_file IS NULL, calls module_to_files() to convert the module specifier to a project-relative file path and writes it back. Rows that cannot be resolved (external packages, stdlib, unknown modules) keep resolved_file = NULL.

Safe to call multiple times — only processes rows with resolved_file IS NULL.

Source

pub async fn resolve_imports_via_module_resolver(&self) -> Result<usize, Error>

Resolve import specifiers using per-language ModuleResolver implementations.

Runs after resolve_all_imports as a second pass: for any import row that still has resolved_file IS NULL, look up the language’s ModuleResolver and call resolve() directly. Updates resolved_file on successful resolutions.

Uses the workspace root to build ResolverConfig once per language, then resolves all pending imports for that language’s files.

Source

pub async fn trace_reexports(&self) -> Result<usize, Error>

Follow re-export chains to resolve imports to their ultimate source file.

When file A imports Foo from file B, but file B re-exports Foo from file C (via pub use c::Foo in Rust or export { Foo } from './c' in TypeScript), this updates A’s import row so resolved_file points to C instead of B.

Runs iteratively (up to max_depth passes) to handle chains longer than one hop, stopping early when no rows are updated. Wildcard re-exports (pub use mod::*) are handled by following any re-export from the intermediate file.

Source

pub async fn resolve_all_calls(&self) -> Result<usize, Error>

Resolve call targets: for each call, try to determine which file defines the callee.

Uses the import graph: if caller_file imports a name that matches callee_name (or its alias), and that import has a resolved_file, set callee_resolved_file on the call row. Same-file calls (caller_file has a symbol matching callee_name) also get resolved.

Source

pub async fn resolve_import( &self, file: &str, name: &str, ) -> Result<Option<(String, String)>, Error>

Resolve a name in a file’s context to its source module Returns: (source_module, original_name) if found

Source

pub async fn find_importers( &self, module: &str, ) -> Result<Vec<(String, String, usize)>, Error>

Find which files import a given module

Source

pub async fn has_import_named( &self, file: &str, name: &str, ) -> Result<bool, Error>

Check whether a file already has an import named name (as name or alias). Used for rename conflict detection.

Source

pub async fn find_symbol_importers( &self, symbol_name: &str, ) -> Result<Vec<(String, String, Option<String>, usize)>, Error>

Find files that import a specific symbol by name. Returns: (file, imported_name, alias, line) Useful for rename: find all files that need their import statement updated.

Source

pub async fn find_symbol_importers_with_module( &self, symbol_name: &str, ) -> Result<Vec<(String, String, Option<String>, usize, Option<String>)>, Error>

Find files that import a specific symbol by name, including the module path. Returns: (file, imported_name, alias, line, module) Useful for move: the recipe needs the original module string so it can rewrite it to the new path verbatim, rather than guessing where the path begins/ends.

Source

pub async fn get_type_methods( &self, file: &str, type_name: &str, ) -> Result<Vec<String>, Error>

Get method names for a type (interface/class) in a specific file. Used for cross-file interface implementation detection.

Source

pub async fn find_type_definitions( &self, type_name: &str, ) -> Result<Vec<String>, Error>

Find files that define a type by name. Returns all files that have a type (interface/class) with the given name.

Source

pub async fn refresh_call_graph(&mut self) -> Result<CallGraphStats, Error>

Refresh the call graph by parsing all supported source files This is more expensive than file refresh since it parses every file Uses parallel processing for parsing, sequential insertion for SQLite

Source

pub async fn incremental_call_graph_refresh( &mut self, ) -> Result<CallGraphStats, Error>

Incrementally update call graph for changed files only. Much faster than full refresh when few files changed.

Source

pub async fn update_file( &mut self, rel_path: &str, ) -> Result<CallGraphStats, Error>

Update the index for a single file (used by LSP on save). Skips filesystem walk — directly reindexes the given path and resolves imports/calls.

Source

pub async fn needs_call_graph_refresh(&self) -> bool

Check if call graph needs refresh

Source

pub async fn find_like(&self, query: &str) -> Result<Vec<IndexedFile>, Error>

Find files matching a query using LIKE (fast pre-filter) Splits query by whitespace/separators and requires all parts to match Special case: queries starting with ‘.’ are treated as extension patterns

Source

pub async fn rebuild_co_change_edges( &self, since_commit: Option<&str>, ) -> Result<usize, Error>

Rebuild (or incrementally update) the co-change edges table from git history.

When since_commit is None, performs a full rebuild: clears the table and walks all commits. When since_commit is Some(sha), walks only commits after that SHA and merges counts into the existing table before re-applying the per-file fanout cap.

Algorithm:

  1. Walk commits via gix (pure-Rust, no git binary required).
  2. For each commit: skip if it touches >50 files (large mechanical commit, no signal).
  3. For each pair of source files in a commit: increment co-change count.
  4. Apply filters: drop pairs with count < 2, cap each file to top 20 partners.
  5. Upsert into co_change_edges.
  6. Record HEAD SHA in meta.co_change_last_commit for incremental use.
Source

pub async fn query_co_change_edges( &self, min_count: usize, ) -> Result<Option<Vec<(String, String, usize)>>, Error>

Query co-change edges from the index.

Returns pairs (file_a, file_b, count) where count >= min_count. Returns Ok(None) if the co_change_edges table is empty (not yet built), so callers can fall back to the git walk.

Source

pub async fn co_change_last_commit(&self) -> Option<String>

Return the stored HEAD SHA from the last co-change rebuild, if any.

Source

pub async fn save_diagnostics_blob( &self, engine: &str, blob: &[u8], config_hash: &str, ) -> Result<(), Error>

Persist rkyv-serialized diagnostics blob for one engine (“syntax”, “fact”, “native”, “all”). Replaces any previous value for that engine.

config_hash is stamped on the row so callers can detect blobs produced under a different config (cross-daemon-restart staleness). See load_diagnostics_blob for the matching read side.

Source

pub async fn load_diagnostics_blob( &self, engine: &str, expected_hash: &str, ) -> Result<Option<Vec<u8>>, Error>

Load rkyv-serialized diagnostics blob for one engine.

Returns None if no row exists or the row’s config_hash does not match expected_hash. The mismatch case is treated as a cache miss so the caller will reprime under the current config rather than serving a blob from a previous daemon session.

Source

pub async fn save_diagnostics_per_file( &self, upserts: &[(String, Vec<u8>)], deletes: &[String], config_hash: &str, ) -> Result<(), Error>

Replace per-file diagnostics blobs in a single transaction.

upserts: (relative_path, rkyv_blob) — files that have issues. deletes: relative paths that became clean (had a row, now don’t).

All upserts and deletes commit atomically so readers never see a partially-updated state.

Source

pub async fn load_diagnostics_for_file( &self, path: &str, expected_hash: &str, ) -> Result<Option<Vec<u8>>, Error>

Load the rkyv blob for one file. None = no row (file is clean) or the row’s config_hash doesn’t match expected_hash (stale across config change).

Source

pub async fn load_diagnostics_for_files( &self, paths: &[String], expected_hash: &str, ) -> Result<Vec<(String, Vec<u8>)>, Error>

Load blobs for many files. Skips files with no row or whose stored config_hash doesn’t match expected_hash. Returns (path, blob) pairs in arbitrary order.

Source

pub async fn clear_all_diagnostics(&self) -> Result<(), Error>

Drop every cached diagnostic row (both per-engine blobs and the per-file table). Used by the daemon when .normalize/config.toml or a rule-definition file changes — the cached blobs reflect the previous config, so they must be cleared before a full reprime to prevent stale RunRules results being served between the config change and the reprime completing.

Source

pub async fn list_diagnostic_paths(&self) -> Result<Vec<String>, Error>

Return all paths that currently have a per-file diagnostics row. Used by the daemon refresh diff to detect files that became clean.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more