pub struct AnalysisSession { /* private fields */ }Expand description
Long-lived analysis context. Owns the salsa database and tracks which stubs have been loaded.
Send but not Sync: share it across threads through
AnalysisSession::snapshot, never by reference.
Implementations§
Source§impl AnalysisSession
impl AnalysisSession
Sourcepub fn analyze_paths(
&mut self,
paths: &[PathBuf],
opts: &BatchOptions,
) -> AnalysisResult
pub fn analyze_paths( &mut self, paths: &[PathBuf], opts: &BatchOptions, ) -> AnalysisResult
Run the full batch analysis pipeline on a set of file paths.
Sourcepub fn re_analyze_file(
&mut self,
file_path: &str,
new_content: &str,
opts: &BatchOptions,
) -> AnalysisResult
pub fn re_analyze_file( &mut self, file_path: &str, new_content: &str, opts: &BatchOptions, ) -> AnalysisResult
Re-analyze a single file (definition collection + body analysis) within the batch context, consulting the disk cache.
Use Self::reanalyze_dependents for LSP-style per-file flows that
don’t need batch options.
Sourcepub fn collect_definitions(&mut self, paths: &[PathBuf])
pub fn collect_definitions(&mut self, paths: &[PathBuf])
Collect type definitions only from paths into the codebase
without analyzing method bodies or emitting issues. Used to load
vendor types.
When a disk-backed cache is attached, per-file StubSlice results
from previous runs are reused on a content-hash match, eliminating
the parse + definition-collection step. Cache misses run the normal
pipeline and write back so subsequent runs hit.
Source§impl AnalysisSession
impl AnalysisSession
Sourcepub fn source_of(&self, file: &str) -> Option<Arc<str>>
pub fn source_of(&self, file: &str) -> Option<Arc<str>>
Retrieve the source text the session has registered for file, if
any. Returns None when the file has never been ingested. Used by
the parallel re-analysis path to re-feed dependents to body analysis without
the caller having to track sources independently.
Sourcepub fn reanalyze_dependents(
&mut self,
file: &str,
) -> Vec<(Arc<str>, FileAnalysis)>
pub fn reanalyze_dependents( &mut self, file: &str, ) -> Vec<(Arc<str>, FileAnalysis)>
Re-analyze every transitive dependent of file.
When the user saves a file that other files depend on (e.g. editing a base class, an interface, or a trait), those dependents may have new diagnostics. Returns the per-file analysis results so the LSP server can publish updated diagnostics in one batch.
Source text for dependents is retrieved from the session’s salsa
inputs (set by previous ingest_file calls) — the caller doesn’t
need to track or re-read files. Files for which the session has no
source are silently skipped (returns the analyzable subset).
Cross-file inferred return types are resolved on demand via salsa.
Sourcepub fn reanalyze_dependents_cancellable(
&mut self,
file: &str,
cancel: &IndexCancel,
) -> Vec<(Arc<str>, FileAnalysis)>
pub fn reanalyze_dependents_cancellable( &mut self, file: &str, cancel: &IndexCancel, ) -> Vec<(Arc<str>, FileAnalysis)>
Cancellable variant of Self::reanalyze_dependents.
The consumer flips cancel (typically because a newer edit arrived) to
abandon the re-analysis; the flag is checked at each file boundary. Salsa
cannot unwind the plain-Rust body-analysis walk mid-flight, so a file
already in progress finishes, but no further files are started. Files
skipped due to cancellation are simply absent from the returned vec —
the consumer should drop a stale flag and start fresh work on each edit.
Sourcepub fn reanalyze_files_cancellable(
&mut self,
files: &[Arc<str>],
cancel: &IndexCancel,
) -> Vec<(Arc<str>, FileAnalysis)>
pub fn reanalyze_files_cancellable( &mut self, files: &[Arc<str>], cancel: &IndexCancel, ) -> Vec<(Arc<str>, FileAnalysis)>
Re-analyze an explicit file set — typically the editor’s currently open files — after an edit elsewhere in the workspace.
The caller passes the files it publishes diagnostics for instead of computing the edited file’s transitive dependents; salsa memoization makes unaffected files ~free. Per-edit cost is O(open files).
Files the session has no source for are silently skipped. Cancellation
semantics match Self::reanalyze_dependents_cancellable.
Sourcepub fn class_imports(&self, file: &str) -> Vec<(Arc<str>, Arc<str>)>
pub fn class_imports(&self, file: &str) -> Vec<(Arc<str>, Arc<str>)>
Return the use-import alias map for a file: a list of (alias, fqcn)
pairs where alias is the local name (e.g. "Str") and fqcn is the
fully-qualified name (e.g. "Illuminate\\Support\\Str").
Completion handlers can use this to expand a short class name written
before :: into its FQN before looking up static members, mirroring the
same alias expansion that go-to-definition already performs via
symbol_at + definition_of.
Returns an empty Vec if the file has not been ingested or has no use imports.
Sourcepub fn pending_lazy_loads(&self, file: &str) -> Vec<Arc<str>>
pub fn pending_lazy_loads(&self, file: &str) -> Vec<Arc<str>>
FQCNs that file imports via use statements but that aren’t yet
in the session’s symbol index.
Designed as the input to background prefetching: after the LSP server ingests an open buffer, it can call this and lazy-load the returned FQCNs on a worker thread so the user’s first Cmd+Click into vendor code doesn’t pay the file-read+parse cost.
Returns an empty Vec if the file hasn’t been ingested or has no unresolved imports.
Sourcepub fn prefetch_imports(&mut self, file: &str) -> usize
pub fn prefetch_imports(&mut self, file: &str) -> usize
Convenience: synchronously lazy-load every import of file that
isn’t already in the symbol index. Returns the number successfully loaded.
Loads only the imported files themselves; their ancestors and signature types resolve through the symbol index or on demand.
Sourcepub fn all_classes(&self) -> Vec<(Arc<str>, Option<Location>)>
pub fn all_classes(&self) -> Vec<(Arc<str>, Option<Location>)>
All class / interface / trait / enum FQCNs currently known to the session, each paired with the file that defines them when available.
Use this to build workspace-wide views (outline, fuzzy search, etc.). Consumers implement their own search/match logic on top — the analyzer only exposes the iterator.
Sourcepub fn all_functions(&self) -> Vec<(Arc<str>, Option<Location>)>
pub fn all_functions(&self) -> Vec<(Arc<str>, Option<Location>)>
All global function FQNs currently known to the session, each paired with their declaration location when available.
Sourcepub fn ancestors_of(&self, fqcn: &str) -> Vec<Arc<str>>
pub fn ancestors_of(&self, fqcn: &str) -> Vec<Arc<str>>
Every ancestor of fqcn — extended class, implemented interfaces,
used traits, transitively — most-derived first. Does not include
fqcn itself. Memoized per FQCN (shares class_ancestors_by_fqcn’s
tracked cache with member-resolution paths).
Sourcepub fn function_signature(&self, fqn: &str) -> Option<Arc<FunctionDef>>
pub fn function_signature(&self, fqn: &str) -> Option<Arc<FunctionDef>>
Full signature for a global function, resolved by FQN.
Sourcepub fn dependency_graph(&self) -> DependencyGraph
pub fn dependency_graph(&self) -> DependencyGraph
File dependency graph: which files depend on which other files. Used for incremental invalidation in LSP servers and build systems.
O(E) in the (file, symbol) edges from the reference index and
file_structural_symbols, each resolved to its defining
file by index lookup. Cached until the file set or an edge changes.
Source§impl AnalysisSession
impl AnalysisSession
Sourcepub fn ingest_file(&mut self, file: Arc<str>, source: Arc<str>)
pub fn ingest_file(&mut self, file: Arc<str>, source: Arc<str>)
definition-collection ingestion. Updates the file’s source text in the salsa db,
runs definition collection, and ingests the resulting stub slice.
Triggers stub loading on first call. Also updates the cache’s reverse-
dependency graph for file so cross-file invalidation stays correct
across incremental edits — without rebuilding the graph from scratch.
If file was previously ingested, its old definitions and reference
locations are removed first so renames / deletions don’t leave stale
state in the codebase. (Without this, long-running sessions would
accumulate dead reference-location entries indefinitely.)
Sourcepub fn ingest_file_prepared(&mut self, file: Arc<str>, source: Arc<str>)
pub fn ingest_file_prepared(&mut self, file: Arc<str>, source: Arc<str>)
Self::ingest_file followed by the file’s Phase-1 warm-up
(Self::prepare_file_for_analysis): its direct class references are
resolved and lazy-loaded now, at write time, instead of serially at
the front of the next references / re-analysis read.
The host edit-path entry point: mutation happens only when text
changes; requests are pure reads.
Lazy loads triggered by the warm-up go through plain
Self::ingest_file, so faulting in a dependency never cascades into
preparing its dependencies — the load frontier stays one file wide.
Sourcepub fn set_file_text(&mut self, file: Arc<str>, source: Arc<str>)
pub fn set_file_text(&mut self, file: Arc<str>, source: Arc<str>)
Register source as the text of file in the salsa input layer without
parsing or running definition collection.
This is the LSP-friendly bulk-population entry point: after a workspace
scan, callers can feed every discovered file’s text to the session
cheaply (an Arc clone plus a HashMap insert per file). Name resolution
then happens on demand via Self::load_class, which reads
the file from disk through the configured crate::ClassResolver and
runs definition collection lazily when a class FQCN actually needs to resolve.
Contrast with Self::ingest_file, which eagerly parses, runs definition collection,
and populates the symbol index. Use ingest_file for files the user is
actively editing (where in-memory text diverges from disk); use
set_file_text for files known only through the workspace scan.
Clears the negative cache: a previously-unresolvable FQCN may now resolve if its defining file is among the newly-registered set.
Sourcepub fn set_vendor_files<I>(&mut self, files: I)
pub fn set_vendor_files<I>(&mut self, files: I)
Bulk-register vendor / library files with HIGH salsa durability.
HIGH-durability files are not expected to change during the session.
When a LOW-durability project file is edited, salsa can skip O(N)
dependency verification for every HIGH-durability file, reducing
workspace_symbol_index re-verification cost to O(project files only).
Definition collection runs lazily on first symbol access; no parsing at call time.
Sourcepub fn rebuild_workspace_symbol_index(&mut self)
pub fn rebuild_workspace_symbol_index(&mut self)
Build or refresh the WorkspaceSymbolIndexSingleton from all currently
registered files.
After this call, find_class_like, find_function, and
find_global_constant read the singleton through per-name
projections instead of recomputing the full O(N_files) dep list via
workspace_symbol_index.
Call this once after all vendor + stub + project files have been
ingested (end of workspace warm-up). Also called automatically by
Self::ingest_file when a file’s declared names change.
Sourcepub fn set_workspace_files<I>(&mut self, files: I)
pub fn set_workspace_files<I>(&mut self, files: I)
Bulk variant of Self::set_file_text, with one revision bump for the
whole batch.
The intended LSP scan loop is:
let files: Vec<_> = walk_workspace()
.map(|path| (path, fs::read(&path).unwrap()))
.collect();
session.set_workspace_files(files);After this call, every file’s source text is known to salsa. No
parsing has happened yet — Definition collection runs per file on the first
load_class that needs to consult it.
Sourcepub fn index_generation(&self) -> u64
pub fn index_generation(&self) -> u64
The workspace generation epoch (“are we up to date” counter). Bumped whenever a file is added or removed. A consumer records this alongside the diagnostics it publishes for a file; when the value later advances (background indexing registered more files), those files become candidates for re-analysis + re-publish.
Sourcepub fn text_revision(&self) -> Revision
pub fn text_revision(&self) -> Revision
The text-write epoch — salsa’s own global revision, which bumps on
every source-file add, edit, or removal (any input write at all),
unlike Self::index_generation which only bumps on file
add/remove/declaration changes (a body-only edit deliberately leaves
it unchanged, to avoid over-invalidating workspace-enumeration
queries). A cache of a per-file or per-query result — as opposed to
declaration-shape state — must key on this instead: any text write
can move or add/remove a reference location within that file, even
when no declaration changed. See MirDbStorage::current_revision’s
doc comment for why this must be salsa’s own revision rather than a
hand-rolled counter.
Sourcepub fn index_batch(
&mut self,
files: &[(Arc<str>, Arc<str>)],
parallelism: IndexParallelism,
cancel: &IndexCancel,
) -> IndexBatchOutcome
pub fn index_batch( &mut self, files: &[(Arc<str>, Arc<str>)], parallelism: IndexParallelism, cancel: &IndexCancel, ) -> IndexBatchOutcome
Index one bounded chunk of (path, text) files — the chunked background
indexing primitive.
For each chunk this: (1) registers the files as Durability::HIGH salsa
inputs in one short write window, (2) parses them to prime the in-process
and on-disk declaration caches (in parallel for
crate::IndexParallelism::Rayon; sequentially for wasm /
single-thread consumers), and (3) merges their declarations into the
workspace symbol index singleton incrementally (no full rebuild) so
partially-indexed symbols resolve immediately.
The library spawns no thread: the consumer pumps chunks from its own
driver (LSP worker thread, or one chunk per wasm event-loop tick),
re-checking higher-priority work between calls. cancel is honoured at
chunk boundaries so an edit can abandon queued indexing cheaply.
Contract: index the workspace incrementally through this method;
don’t bulk-register the entire file set up front and then index — the
first call lazily seeds the singleton from the currently-registered set
(built-in stubs + this chunk), so keeping that initial set small keeps
the first call cheap. Call Self::finalize_index once after the last
chunk to reconcile authoritatively.
Responsiveness: parsing runs on a snapshot; only the cheap
symbol-map merge writes salsa. Queries running on other threads’
snapshots during that write may unwind with salsa::Cancelled and
should be retried.
Sourcepub fn finalize_index(&mut self)
pub fn finalize_index(&mut self)
Authoritative full rebuild of the workspace symbol index. Call once
after the consumer has pumped every Self::index_batch chunk (end of
warm-up) to reconcile the incrementally-merged index against the full
registered set. Cheap after indexing — every file’s declarations are
already cached.
Sourcepub fn warm_start_files(
&mut self,
files: &[(Arc<str>, Arc<str>)],
) -> Vec<Arc<str>>
pub fn warm_start_files( &mut self, files: &[(Arc<str>, Arc<str>)], ) -> Vec<Arc<str>>
Replay disk-cached reference-location postings and subtype-index class
edges for files, so a returning session’s find-references /
goto-implementation queries are answered from the index immediately
instead of paying the on-demand analysis sweep the first time each
file is queried (indexed_references_to/indexed_subtype_classes’s
freshness pass already handles a miss correctly — this only shortens
the common warm-start case).
A no-op (per file) unless the disk cache from a previous run has an
entry whose content hash matches files’ current text: Self::with_cache/
Self::with_cache_dir must be attached, and each file’s reference
locations ([AnalysisCache], populated by the CLI batch pipeline) or
definitions ([crate::stub_cache::StubSliceCache], populated by
Self::ingest_file/vendor ingestion) must already be on disk from
some earlier run/tool invocation against this exact content. A first-
ever run (nothing cached yet) is unaffected — every file simply falls
through to the existing lazy on-demand paths, same as without this call.
Registers files as Durability::HIGH salsa inputs (like
Self::index_batch) if not already registered. Safe to call
alongside index_batch in any order; both merge into the same
maintained indexes.
Returns every file whose replayed postings carry an unresolved name
(live_analyzed: false in RefCommit terms) — these are seeded, but
indexed_references_to’s freshness pass can never treat them as
immune to growth, so the first query that touches one of them pays
a full analyze_file synchronously on the request path (measured:
~1.3-1.5s on a distinctive static method in a 15K-file workspace).
The subset is known right here, at warm-start time — a caller with
idle time between warm-start and the first live query (e.g. an LSP
server between indexReady and the user’s first request) can close
most of that gap by handing this list to
Self::reanalyze_files_cancellable on a background thread, the
same pattern Self::prefetch_imports uses for lazy-loaded
vendor FQCNs:
let unresolved = session.warm_start_files(&files);
let s = session.clone();
std::thread::spawn(move || {
s.reanalyze_files_cancellable(&unresolved, &crate::IndexCancel::new());
});This only relocates cost that would otherwise land on a user-facing query — it cannot eliminate the freshness check itself, since an unresolved posting is workspace-generation-sensitive by design.
Sourcepub fn settle_workspace_index(&mut self)
pub fn settle_workspace_index(&mut self)
Reconcile the symbol-index singleton with mirror-only text writes.
Plain upsert_source_file_with_durability calls (an LSP host
mirroring watcher-driven external edits or new files) bypass
ingest_file’s incremental index maintenance; those files accumulate
in a pending set while a singleton exists. Query entry points call
this first so the singleton is never consulted stale. Declaration
memos are pre-warmed on a snapshot in parallel, so the per-file merge
is a memo hit.
Sourcepub fn prepare_for_query(&mut self, file: Option<&Arc<str>>)
pub fn prepare_for_query(&mut self, file: Option<&Arc<str>>)
The single write prelude every interactive query needs before it can
read a consistent snapshot: reconcile the workspace index, then (if a
specific file is the target of the query) warm up that file’s direct
dependencies via Self::prepare_file_for_analysis.
Run it before handing out an super::AnalysisSnapshot: snapshot
queries load missing classes on demand, but workspace-wide ones only
enumerate what this has settled. Pass the file a query is about, or
None for workspace-wide queries.
Sourcepub fn invalidate_file(&mut self, file: &str)
pub fn invalidate_file(&mut self, file: &str)
Drop a file’s contribution to the session: codebase definitions, reference locations, salsa input handle, cache entry, and outgoing reverse-dependency edges. Cache entries of dependent files are also evicted (cross-file invalidation).
Use this when a file is closed by the consumer, or before a re-ingest
of substantially changed content. (Plain re-ingest via
Self::ingest_file also drops old definitions, but does not
remove the salsa input handle — call this for full cleanup.)
Sourcepub fn tracked_file_count(&self) -> usize
pub fn tracked_file_count(&self) -> usize
Number of files currently tracked in this session’s salsa input set. Stable across reads; useful for diagnostics and memory bounds checks.
Source§impl AnalysisSession
impl AnalysisSession
Sourcepub fn contains_function(&self, fqn: &str) -> bool
pub fn contains_function(&self, fqn: &str) -> bool
Returns true if a function with fqn is registered and active in
the codebase. Case-insensitive lookup with optional leading backslash.
Sourcepub fn contains_class(&self, fqcn: &str) -> bool
pub fn contains_class(&self, fqcn: &str) -> bool
Returns true if a class / interface / trait / enum with fqcn is
registered and active in the codebase.
Sourcepub fn contains_method(&self, class: &str, name: &str) -> bool
pub fn contains_method(&self, class: &str, name: &str) -> bool
Returns true if class has a method named name registered. Method
names are matched case-insensitively (PHP method dispatch semantics).
Sourcepub fn load_class(&mut self, fqcn: &str) -> LoadOutcome
pub fn load_class(&mut self, fqcn: &str) -> LoadOutcome
Resolve fqcn via the configured crate::ClassResolver and ingest
the mapped file into the symbol index. Lookups already find such a
class on demand; ingesting also makes workspace enumeration see it.
The session keeps a negative cache so repeated calls for an
unresolvable name don’t re-hit the resolver; the cache is invalidated
on any Self::ingest_file / Self::invalidate_file.
This is the LSP-friendly entry point: the analyzer never touches
vendor/ on its own, but consumers can ask it to resolve individual
symbols on demand. Designed to be called when a diagnostic would
otherwise report UndefinedClass.
Returns a crate::LoadOutcome distinguishing
already-loaded / freshly-loaded / not-resolvable. Use
crate::LoadOutcome::is_loaded when only success matters.
Source§impl AnalysisSession
impl AnalysisSession
Sourcepub fn analyze_file_diagnostics(
&mut self,
file: &str,
source: &str,
) -> FileAnalysis
pub fn analyze_file_diagnostics( &mut self, file: &str, source: &str, ) -> FileAnalysis
Open-file diagnostics entrypoint for issue-only consumers.
Updates the session’s current text for file, reuses the tracked parse
and definition queries for syntax/collector diagnostics, then runs the
targeted open-file body-analysis path without retaining whole-file
ResolvedSymbol payloads.
Sourcepub fn name_at(&mut self, file: &str, byte_offset: u32) -> Option<Name>
pub fn name_at(&mut self, file: &str, byte_offset: u32) -> Option<Name>
Resolve the codebase-level symbol name at byte_offset in file.
The identity half of Self::symbol_at, for consumers that only need
a crate::Name to feed Self::definition_of or
Self::indexed_references_to.
Sourcepub fn outgoing_calls(
&mut self,
file: &str,
byte_offset: u32,
) -> Vec<(Name, Range)>
pub fn outgoing_calls( &mut self, file: &str, byte_offset: u32, ) -> Vec<(Name, Range)>
Calls inside the function or method whose declaration contains
byte_offset in file, as (callee, call-site name range) in source
order. Callees are resolved crate::Names — a trait alias reports
the original method, parent::/self:: the declaring class — so the
result feeds Self::definition_of and Self::indexed_references_to
directly. Calls in nested closures belong to the enclosing function.
new Foo is a class reference, not reported. Empty when the offset is
outside a function or method body.
Sourcepub fn variable_references(
&mut self,
file: &str,
byte_offset: u32,
) -> Vec<Range>
pub fn variable_references( &mut self, file: &str, byte_offset: u32, ) -> Vec<Range>
Every occurrence of the local variable or parameter under
byte_offset in file, in source order, as name ranges including the
$. An occurrence belongs to the variable when it binds to the same
declaration: nested functions and closures start a new scope, except
where a closure captures the variable with use; arrow functions share
the enclosing scope except for their own parameters. Empty when the
offset is not on a variable. Powers document highlight and local
rename.
Sourcepub fn symbol_at(
&mut self,
file: &str,
byte_offset: u32,
) -> Option<ResolvedSymbol>
pub fn symbol_at( &mut self, file: &str, byte_offset: u32, ) -> Option<ResolvedSymbol>
Resolve the symbol at byte_offset in file’s current ingested text.
Answers the same as crate::FileAnalysis::symbol_at without the
caller retaining a whole-file symbol list: the containing scope is
re-analyzed on demand and only its symbol payload is searched.
Side effects: may fault in direct dependencies of file by running
the open-file warm-up path (prepare_file_for_analysis).
Sourcepub fn definition_of(
&mut self,
symbol: &Name,
) -> Result<Location, SymbolLookupError>
pub fn definition_of( &mut self, symbol: &Name, ) -> Result<Location, SymbolLookupError>
Resolve a top-level symbol (class or function) to its declaration location. Powers go-to-definition.
Side effects: ingests the file defining the symbol’s class if the
symbol index lacks it. Self::definition_of_cached answers the same
without writing inputs.
Returns:
Ok(Location)— symbol found with a source locationErr(NotFound)— no such symbol in the codebaseErr(NoSourceLocation)— symbol exists but has no recorded span (e.g. some stub-only declarations)
Sourcepub fn definition_of_cached(
&self,
symbol: &Name,
) -> Result<Location, SymbolLookupError>
pub fn definition_of_cached( &self, symbol: &Name, ) -> Result<Location, SymbolLookupError>
Pure variant of Self::definition_of: never writes salsa inputs.
Symbols the index lacks load on demand through the resolver and
crate::SourceProvider as pure reads.
Sourcepub fn implemented_method(&self, method: &Name) -> Option<Name>
pub fn implemented_method(&self, method: &Name) -> Option<Name>
Sourcepub fn subtype_files(
&mut self,
class_fqn: &str,
include_trait_users: bool,
) -> Vec<Arc<str>>
pub fn subtype_files( &mut self, class_fqn: &str, include_trait_users: bool, ) -> Vec<Arc<str>>
Files declaring transitive subclasses of class_fqn, backed by the
maintained subtype index (see Self::indexed_subtype_classes).
Excludes class_fqn’s own declaring file — the caller adds it.
Lets a reference-search caller scope a protected member to its class
hierarchy without reconstructing that hierarchy from declaration text:
subclasses are matched by resolved FQCN, so extends \Ns\Base and
aliased use forms are all found. Read-only from the caller’s
perspective; may trigger an on-demand commit of stale/uncommitted
candidates’ class edges (same self-heal indexed_subtype_classes uses).
include_trait_users also counts classes that use the trait.
Sourcepub fn indexed_use_import_locations(
&mut self,
symbol: &Name,
files: &[Arc<str>],
) -> Vec<(Arc<str>, Range)>
pub fn indexed_use_import_locations( &mut self, symbol: &Name, files: &[Arc<str>], ) -> Vec<(Arc<str>, Range)>
Compatibility wrapper for callers that only want use import items.
Delegates to Self::indexed_references_to so import references share
the same freshness/self-heal path, scope filtering, and memoization
boundary as every other reference query.
Sourcepub fn indexed_references_to(
&mut self,
symbol: &Name,
files: &[Arc<str>],
include_declaration: bool,
includes: ReferenceIncludes,
should_cancel: &(dyn Fn() -> bool + Sync),
) -> Option<Vec<(Arc<str>, Range)>>
pub fn indexed_references_to( &mut self, symbol: &Name, files: &[Arc<str>], include_declaration: bool, includes: ReferenceIncludes, should_cancel: &(dyn Fn() -> bool + Sync), ) -> Option<Vec<(Arc<str>, Range)>>
See AnalysisSnapshot::indexed_references_to. Unlike the snapshot
form, this runs the owner-side warm-up for stale candidates first, so
every one of them is analyzed with its referenced classes loaded.
should_cancel is polled at phase boundaries and between stale
candidates; true aborts with None, as does an index settle that
snapshot readers keep feeding past its round cap.
Sourcepub fn prepare_references_query(
&mut self,
symbol: &Name,
stale: &[Arc<str>],
include_declaration: bool,
should_cancel: &(dyn Fn() -> bool + Sync),
) -> bool
pub fn prepare_references_query( &mut self, symbol: &Name, stale: &[Arc<str>], include_declaration: bool, should_cancel: &(dyn Fn() -> bool + Sync), ) -> bool
Owner-side prelude for AnalysisSnapshot::indexed_references_to:
the warm-up Self::indexed_references_to runs before reading, so a
snapshot taken afterwards analyzes every stale candidate with its
dependencies loaded.
stale is AnalysisSnapshot::stale_reference_candidates, computed
on a snapshot before the host takes its lock to call this: that scan
is O(candidates) and, on a cold workspace, scans file text, so it must
not run under the lock. Only the stale files are prepared (not every
candidate), the workspace index is settled when it has pending work,
and with include_declaration the file declaring symbol is loaded.
With nothing stale and nothing pending this is a no-op. A file that
went stale after stale was computed is analyzed without the warm-up,
as it would be without this call. false when should_cancel stopped
it first.
Sourcepub fn declaration_name_range(
&mut self,
symbol: &Name,
) -> Option<(Arc<str>, Range)>
pub fn declaration_name_range( &mut self, symbol: &Name, ) -> Option<(Arc<str>, Range)>
The symbol’s declaration site, narrowed from the collector’s whole-declaration span to the declared name’s own token (matching the span shape of recorded references).
Sourcepub fn indexed_subtype_classes(
&mut self,
class_fqn: &str,
files: &[Arc<str>],
include_trait_users: bool,
) -> Vec<SubtypeClassSite>
pub fn indexed_subtype_classes( &mut self, class_fqn: &str, files: &[Arc<str>], include_trait_users: bool, ) -> Vec<SubtypeClassSite>
Sourcepub fn indexed_direct_subtype_classes(
&mut self,
class_fqn: &str,
files: &[Arc<str>],
include_trait_users: bool,
) -> Vec<SubtypeClassSite>
pub fn indexed_direct_subtype_classes( &mut self, class_fqn: &str, files: &[Arc<str>], include_trait_users: bool, ) -> Vec<SubtypeClassSite>
Sourcepub fn indexed_method_implementations(
&mut self,
class_fqn: &str,
method: &str,
files: &[Arc<str>],
) -> Vec<(Arc<str>, Arc<str>, Range)>
pub fn indexed_method_implementations( &mut self, class_fqn: &str, method: &str, files: &[Arc<str>], ) -> Vec<(Arc<str>, Arc<str>, Range)>
Sourcepub fn class_issues(&mut self, files: &[Arc<str>]) -> Vec<Issue>
pub fn class_issues(&mut self, files: &[Arc<str>]) -> Vec<Issue>
See AnalysisSnapshot::class_issues. Call this after ingesting or
re-analyzing a file and its dependents to get the full diagnostic
picture.
Sourcepub fn collector_issues(&self, files: &[Arc<str>]) -> Vec<Issue>
pub fn collector_issues(&self, files: &[Arc<str>]) -> Vec<Issue>
See AnalysisSnapshot::collector_issues. Correct regardless of
which path put the file’s text into the db (ingest_file,
set_file_text, lazy vendor load) or how many times.
Sourcepub fn document_symbols(&self, file: &str) -> Vec<DocumentSymbol>
pub fn document_symbols(&self, file: &str) -> Vec<DocumentSymbol>
All declarations defined in file as a hierarchical tree.
Classes/interfaces/traits/enums are returned with their methods,
properties, and constants nested in children. Top-level functions
and constants are returned with empty children.
Source§impl AnalysisSession
impl AnalysisSession
Sourcepub fn ensure_all_stubs(&mut self)
pub fn ensure_all_stubs(&mut self)
Load every embedded PHP stub plus any configured user stubs. Use for batch tools (CLI, full project analysis) where comprehensive symbol coverage matters more than cold-start latency.
Sourcepub fn loaded_stub_count(&self) -> usize
pub fn loaded_stub_count(&self) -> usize
Number of distinct embedded stubs currently ingested into the session. Useful for diagnostics and bench reporting.
Sourcepub fn ensure_stubs_for_source(&mut self, source: &str)
pub fn ensure_stubs_for_source(&mut self, source: &str)
Auto-discover and ingest the embedded stubs needed to cover every
built-in PHP function / class / constant referenced by source.
Used by the open-file analysis paths
(crate::FileAnalyzer::analyze and
crate::FileAnalyzer::analyze_diagnostics_only) to keep
essentials-only mode correct without forcing callers to enumerate which
stubs they need.
Idempotent — already-loaded stubs are skipped.
The discovery scan is a coarse identifier sweep (see
collect_referenced_builtin_paths) — it may pull in
a slightly larger set than the file strictly needs, but never misses
a referenced built-in. Cost is sub-millisecond per file.
Fast path: if every embedded stub is already loaded (e.g. after a
batch tool called Self::ensure_all_stubs), the source scan
is skipped entirely.
Sourcepub fn ensure_stubs_for_ast(&mut self, program: &Program)
pub fn ensure_stubs_for_ast(&mut self, program: &Program)
Discover and ingest stubs by walking the parsed AST of a PHP file.
Similar to Self::ensure_stubs_for_source, but takes an already-parsed
AST instead of raw source text. Produces zero false positives since it
only extracts identifiers from actual AST nodes (not from strings or
comments). Preferred over ensure_stubs_for_source when the AST is
already available (e.g., in crate::FileAnalyzer).
Idempotent and skips the scan if all stubs are already loaded.
Sourcepub fn has_resolver(&self) -> bool
pub fn has_resolver(&self) -> bool
Returns true if this session has a configured class resolver
(typically a PSR-4 / classmap autoloader chained with the stub
resolver). Used by FileAnalyzer to skip the AST-scan preload
when no resolver is wired up.
Sourcepub fn prepare_ast_for_analysis(&mut self, program: &Program, file: &str)
pub fn prepare_ast_for_analysis(&mut self, program: &Program, file: &str)
Run all pre-passes (builtin-stub loading, vendor-eager-file loading, and PSR-4 class preloading) before body analysis of a single file.
Replaces the two separate ensure_stubs_for_ast /
preload_psr4_classes_for_ast calls at every open-file analysis site.
Sourcepub fn prepare_file_for_analysis(&mut self, path: &Arc<str>)
pub fn prepare_file_for_analysis(&mut self, path: &Arc<str>)
Run file’s Phase-1 warm-up — resolve its direct class references and
lazy-load any not yet indexed — and record it as prepared against its
current text. No-op when the file is unknown or already prepared.
This is the write-path home of the warm-up: hosts call it (via
Self::ingest_file_prepared) when text lands, so read paths
(indexed_references_to, reanalyze_files_cancellable) find every
candidate prepared and stay pure.
Sourcepub fn bump_prepare_generation(&mut self)
pub fn bump_prepare_generation(&mut self)
Invalidate every warm-up skip entry. Call when previously loaded
declarations may have been removed outside Self::ingest_file /
Self::invalidate_file — e.g. a host that writes file text straight
into the salsa layer and detects a declaration-level change. A prepared
file might then need its warm-up re-run to lazy-load a replacement
(a vendor class shadowed by a since-deleted project class).
Sourcepub fn priority_index_for_ast(&mut self, program: &Program, file: &str)
pub fn priority_index_for_ast(&mut self, program: &Program, file: &str)
Priority-index the classes directly referenced by file’s AST.
Lookups already find unindexed classes on demand; this moves the
buffer’s direct references to the front of the background indexer’s
(Self::index_batch) queue so workspace enumeration and reverse
lookups see them too. Bounded by one file’s direct references: their
ancestors and signature types are left to the background walk. Each
Self::load_class is a resolver lookup, a parse (or cache hit) and
one index merge; a no-op once indexing has passed the file.
Source§impl AnalysisSession
impl AnalysisSession
Sourcepub fn new(php_version: PhpVersion) -> Self
pub fn new(php_version: PhpVersion) -> Self
Create a session targeting the given PHP language version.
Sourcepub fn snapshot(&self) -> AnalysisSnapshot
pub fn snapshot(&self) -> AnalysisSnapshot
A Send + Clone read handle on the current revision. See
AnalysisSnapshot for the lifetime rules.
Sourcepub fn ref_query_cache_hits(&self) -> u64
pub fn ref_query_cache_hits(&self) -> u64
Hits served from Self::indexed_references_to’s memoization cache.
Diagnostic only — lets tests assert a warm repeat skipped the
freshness scan entirely.
Sourcepub fn ref_query_cache_locations(&self) -> usize
pub fn ref_query_cache_locations(&self) -> usize
Total cached reference-location count across the references memo. Diagnostic only — lets tests/hosts assert the cache stays under its byte-proportional cap rather than trusting entry count alone.
Sourcepub fn subtype_query_cache_hits(&self) -> u64
pub fn subtype_query_cache_hits(&self) -> u64
Hits served from Self::indexed_subtype_classes’s memoization
cache. Diagnostic only.
Sourcepub fn subtype_query_cache_sites(&self) -> usize
pub fn subtype_query_cache_sites(&self) -> usize
Total cached site count across the subtype memo. Diagnostic only.
Sourcepub fn ref_index_lock_count(&self) -> u64
pub fn ref_index_lock_count(&self) -> u64
Times the reference index has been locked on this session’s db.
Sourcepub fn class_mention_stats(&self) -> ClassMentionStats
pub fn class_mention_stats(&self) -> ClassMentionStats
Coverage/size counters for the class-mention gate index (host metrics and memory-bound checks).
Sourcepub fn files_mentioning_class(
&self,
files: &[Arc<str>],
class_name: &str,
) -> Vec<Arc<str>>
pub fn files_mentioning_class( &self, files: &[Arc<str>], class_name: &str, ) -> Vec<Arc<str>>
Sourcepub fn flush_analysis_cache(&self)
pub fn flush_analysis_cache(&self)
Persist the attached [AnalysisCache] to disk. No-op without an
attached cache or when nothing changed since the last flush.
Reference postings committed by session sweeps and on-demand query
freshness passes reach disk only here — a host should call this after
its warm sweep completes and on shutdown so the next launch’s
Self::warm_start_files finds them.
Sourcepub fn workspace_symbol_index_ready(&self) -> bool
pub fn workspace_symbol_index_ready(&self) -> bool
Whether the workspace symbol index singleton is populated (seeded by
Self::warm_start_files or built by index_batch) — symbol lookups
answer from the O(1) map instead of the tracked O(all-files) walk.
Sourcepub fn workspace_index_walks(&self) -> u64
pub fn workspace_index_walks(&self) -> u64
Executions of the tracked O(all-files) workspace_symbol_index walk
(diagnostic; a warm-started session should keep this at zero).
Sourcepub fn work_count(&self, work: Work) -> u64
pub fn work_count(&self, work: Work) -> u64
Units of work this session’s analysis has done (diagnostic).
Sourcepub fn with_source_provider(self, provider: Arc<dyn SourceProvider>) -> Self
pub fn with_source_provider(self, provider: Arc<dyn SourceProvider>) -> Self
Swap in a custom crate::SourceProvider. LSPs install a VFS-backed
provider here so the analyzer reads from unsaved editor buffers
instead of disk.
Sourcepub fn with_cache(self, cache: Arc<AnalysisCache>) -> Self
pub fn with_cache(self, cache: Arc<AnalysisCache>) -> Self
Attach a pre-built [AnalysisCache] (the body-analysis issue cache) and
open a sibling definition StubSlice cache under the same root, so
callers using this builder get the same speedup as with_cache_dir.
Call before any file is ingested. A debug assertion catches misuse.
Sourcepub fn with_cache_dir(self, cache_dir: &Path) -> Self
pub fn with_cache_dir(self, cache_dir: &Path) -> Self
Convenience: open a disk-backed cache at cache_dir and attach it.
Attaches both the body-analysis issue cache ([AnalysisCache]) and the
definition StubSlice cache to the shared database. Call before
any file is ingested. A debug assertion catches misuse.
Sourcepub fn with_psr4(self, map: Arc<Psr4Map>) -> Self
pub fn with_psr4(self, map: Arc<Psr4Map>) -> Self
Attach a Composer autoload map (PSR-4, PSR-0, classmap, files).
Sets the same map as the active crate::ClassResolver so
Self::load_class works out of the box.
Sourcepub fn with_class_resolver(self, resolver: Arc<dyn ClassResolver>) -> Self
pub fn with_class_resolver(self, resolver: Arc<dyn ClassResolver>) -> Self
Attach a generic class resolver for projects that don’t use Composer (WordPress, Drupal, custom autoloaders, workspace-walk indexes). Replaces any previously-set Composer-backed resolver. Automatically wrapped with stub awareness so PHP built-ins remain resolvable.
pub fn with_user_stubs(self, files: Vec<PathBuf>, dirs: Vec<PathBuf>) -> Self
Sourcepub fn with_memoize_method_call_results(self, enabled: bool) -> Self
pub fn with_memoize_method_call_results(self, enabled: bool) -> Self
Assume repeated zero-arg method calls on the same receiver return the
same value (Psalm’s memoizeMethodCallResults), so narrowing them
(if (!$a->b()) throw; return $a->b();) holds. Call before
Self::with_cache_dir.
pub fn php_version(&self) -> PhpVersion
pub fn cache(&self) -> Option<&AnalysisCache>
pub fn psr4(&self) -> Option<&Psr4Map>
Auto Trait Implementations§
impl !Freeze for AnalysisSession
impl !RefUnwindSafe for AnalysisSession
impl !Sync for AnalysisSession
impl !UnwindSafe for AnalysisSession
impl Send for AnalysisSession
impl Unpin for AnalysisSession
impl UnsafeUnpin for AnalysisSession
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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