pub struct AnalysisSession { /* private fields */ }Expand description
Long-lived analysis context. Owns the salsa database and tracks which stubs have been loaded.
Cheap to clone the inner db for parallel reads; writes funnel through
Self::ingest_file, Self::invalidate_file, and the crate-internal
[Self::with_db_mut].
Implementations§
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.
pub fn with_cache(self, cache: Arc<AnalysisCache>) -> Self
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.
Avoids forcing callers to wrap [AnalysisCache] in Arc themselves.
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::lazy_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.
pub fn with_user_stubs(self, files: Vec<PathBuf>, dirs: Vec<PathBuf>) -> Self
pub fn php_version(&self) -> PhpVersion
pub fn cache(&self) -> Option<&AnalysisCache>
pub fn psr4(&self) -> Option<&Psr4Map>
Sourcepub fn ensure_essential_stubs_loaded(&self)
pub fn ensure_essential_stubs_loaded(&self)
Load only the curated set of essential stubs (Core, standard, SPL, date) plus any configured user stubs. About 25 of 120 stub files; covers types and functions used by virtually all PHP code.
Other extension stubs (Reflection, gd, openssl, …) can be brought in
on demand via [Self::ensure_stubs_for_symbol] when user code
references them. Idempotent — already-loaded stubs are skipped.
Sourcepub fn ensure_all_stubs_loaded(&self)
pub fn ensure_all_stubs_loaded(&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(&self, source: &str)
pub fn ensure_stubs_for_source(&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 crate::FileAnalyzer::analyze to keep essentials-only mode
correct without forcing callers to enumerate which stubs they need.
Idempotent — already-loaded stubs are skipped via [Self::loaded_stubs].
The discovery scan is a coarse identifier sweep (see
[crate::stubs::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_loaded), the source scan
is skipped entirely.
Sourcepub fn ensure_stubs_for_ast(&self, program: &Program<'_, '_>)
pub fn ensure_stubs_for_ast(&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 ingest_file(&self, file: Arc<str>, source: Arc<str>)
pub fn ingest_file(&self, file: Arc<str>, source: Arc<str>)
Pass 1 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 invalidate_file(&self, file: &str)
pub fn invalidate_file(&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.
Sourcepub fn definition_of(
&self,
symbol: &Symbol,
) -> Result<Location, SymbolLookupError>
pub fn definition_of( &self, symbol: &Symbol, ) -> Result<Location, SymbolLookupError>
Resolve a top-level symbol (class or function) to its declaration location. Powers go-to-definition.
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 hover(&self, symbol: &Symbol) -> Result<HoverInfo, SymbolLookupError>
pub fn hover(&self, symbol: &Symbol) -> Result<HoverInfo, SymbolLookupError>
Hover information for a symbol: type, docstring, and definition location.
Use crate::FileAnalysis::symbol_at to find the symbol at a cursor
position, then build a crate::Symbol from its kind. This method
assembles the displayable hover data.
Returns Err(NotFound) if the symbol doesn’t exist. May still return
Ok with docstring: None or definition: None if those specific
pieces aren’t available.
Sourcepub fn references_to(&self, symbol: &Symbol) -> Vec<(Arc<str>, Range)>
pub fn references_to(&self, symbol: &Symbol) -> Vec<(Arc<str>, Range)>
Every recorded reference to symbol with its source location as a Range.
Use crate::FileAnalysis::symbol_at to find the symbol at a cursor,
build a crate::Symbol from it, and pass it here.
Sourcepub fn class_issues_for(&self, files: &[Arc<str>]) -> Vec<Issue>
pub fn class_issues_for(&self, files: &[Arc<str>]) -> Vec<Issue>
Class-level issues (inheritance violations, abstract-method gaps, override incompatibilities) for the given set of files.
These checks are cross-file by nature and are not emitted by
crate::FileAnalyzer::analyze. Call this after ingesting or
re-analyzing a file and its dependents to get the full diagnostic picture.
Circular-inheritance checks always run against the full workspace graph
regardless of the files filter — a cycle is a workspace-wide problem.
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.
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 lazy_load_class_with_outcome(&self, fqcn: &str) -> LazyLoadOutcome
pub fn lazy_load_class_with_outcome(&self, fqcn: &str) -> LazyLoadOutcome
Try to resolve fqcn via PSR-4 and ingest the mapped file, returning
a detailed outcome distinguishing “already there” from “freshly loaded”.
Sourcepub fn lazy_load_class(&self, fqcn: &str) -> bool
pub fn lazy_load_class(&self, fqcn: &str) -> bool
Try to resolve fqcn via the configured crate::ClassResolver and
ingest the mapped file.
This is the LSP-friendly lazy-load 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 true if either the class is already known or a matching
file was found and successfully ingested. Returns false if:
- No resolver is configured (neither
with_psr4norwith_class_resolvercalled), - The resolver can’t map
fqcnto a file, - The file can’t be read, or
- The file parsed but did not define
fqcn.
Sourcepub fn lazy_load_class_transitive(&self, fqcn: &str, max_depth: usize) -> usize
pub fn lazy_load_class_transitive(&self, fqcn: &str, max_depth: usize) -> usize
Lazy-load every class transitively reachable from fqcn via parent /
interface / trait edges. Useful when the consumer needs not just the
requested class but enough of its inheritance chain to type-check
member access.
Walks at most max_depth levels (default in batch analysis is 10).
Returns the number of classes successfully loaded (not counting
fqcn itself if it was already present).
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 Pass 2 without
the caller having to track sources independently.
Sourcepub fn analyze_dependents_of(&self, file: &str) -> Vec<(Arc<str>, FileAnalysis)>
pub fn analyze_dependents_of(&self, file: &str) -> Vec<(Arc<str>, FileAnalysis)>
Re-analyze every transitive dependent of file in parallel.
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. This method computes them in parallel using rayon and 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).
Does not run inference sweeps. For full-fidelity cross-file inferred
return types, follow up with Self::run_inference_sweep over the
affected file set.
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
loaded in the session.
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(&self, file: &str) -> usize
pub fn prefetch_imports(&self, file: &str) -> usize
Convenience: synchronously lazy-load every import of file that
isn’t already in the codebase. Returns the number successfully loaded.
For non-blocking prefetch, call this from a worker thread:
let s = session.clone(); // AnalysisSession is wrapped in Arc by callers
std::thread::spawn(move || {
s.prefetch_imports(&file_path);
});Internally walks the inheritance chain of each loaded class to a shallow depth so member access on imported types type-checks without the user paying the cost on their first navigation.
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 run_inference_sweep(&self, files: &[(Arc<str>, Arc<str>)])
pub fn run_inference_sweep(&self, files: &[(Arc<str>, Arc<str>)])
Cross-file inference sweep. For each (file, source) pair, runs the
Pass 2 inference-only mode on a cloned db (parallel via rayon), then
commits the collected inferred return types to the canonical db.
Call this on idle / save / explicit user request, not on every
keystroke — crate::FileAnalyzer::analyze deliberately skips
inference sweep on the hot path. Files whose source contains parse
errors are silently skipped.
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.
Dependencies are computed from:
- Direct imports (use statements)
- Class inheritance (parent classes, interfaces, traits)
Auto Trait Implementations§
impl Freeze for AnalysisSession
impl !RefUnwindSafe for AnalysisSession
impl Send for AnalysisSession
impl Sync for AnalysisSession
impl Unpin for AnalysisSession
impl UnsafeUnpin for AnalysisSession
impl !UnwindSafe 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
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 moreSource§impl<D> OwoColorize for D
impl<D> OwoColorize for D
Source§fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where
C: Color,
fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where
C: Color,
Source§fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where
C: Color,
fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where
C: Color,
Source§fn black(&self) -> FgColorDisplay<'_, Black, Self>
fn black(&self) -> FgColorDisplay<'_, Black, Self>
Source§fn on_black(&self) -> BgColorDisplay<'_, Black, Self>
fn on_black(&self) -> BgColorDisplay<'_, Black, Self>
Source§fn red(&self) -> FgColorDisplay<'_, Red, Self>
fn red(&self) -> FgColorDisplay<'_, Red, Self>
Source§fn on_red(&self) -> BgColorDisplay<'_, Red, Self>
fn on_red(&self) -> BgColorDisplay<'_, Red, Self>
Source§fn green(&self) -> FgColorDisplay<'_, Green, Self>
fn green(&self) -> FgColorDisplay<'_, Green, Self>
Source§fn on_green(&self) -> BgColorDisplay<'_, Green, Self>
fn on_green(&self) -> BgColorDisplay<'_, Green, Self>
Source§fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>
fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>
Source§fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>
fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>
Source§fn blue(&self) -> FgColorDisplay<'_, Blue, Self>
fn blue(&self) -> FgColorDisplay<'_, Blue, Self>
Source§fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>
fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>
Source§fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>
fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>
Source§fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>
fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>
Source§fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>
fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>
Source§fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>
fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>
Source§fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>
fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>
Source§fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>
fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>
Source§fn white(&self) -> FgColorDisplay<'_, White, Self>
fn white(&self) -> FgColorDisplay<'_, White, Self>
Source§fn on_white(&self) -> BgColorDisplay<'_, White, Self>
fn on_white(&self) -> BgColorDisplay<'_, White, Self>
Source§fn default_color(&self) -> FgColorDisplay<'_, Default, Self>
fn default_color(&self) -> FgColorDisplay<'_, Default, Self>
Source§fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>
fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>
Source§fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>
fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>
Source§fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>
fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>
Source§fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>
fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>
Source§fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>
fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>
Source§fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>
fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>
Source§fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>
fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>
Source§fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>
fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>
Source§fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>
fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>
Source§fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>
fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>
Source§fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>
fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>
Source§fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
Source§fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
Source§fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
Source§fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
Source§fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>
fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>
Source§fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>
fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>
Source§fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>
fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>
Source§fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>
fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>
Source§fn bold(&self) -> BoldDisplay<'_, Self>
fn bold(&self) -> BoldDisplay<'_, Self>
Source§fn dimmed(&self) -> DimDisplay<'_, Self>
fn dimmed(&self) -> DimDisplay<'_, Self>
Source§fn italic(&self) -> ItalicDisplay<'_, Self>
fn italic(&self) -> ItalicDisplay<'_, Self>
Source§fn underline(&self) -> UnderlineDisplay<'_, Self>
fn underline(&self) -> UnderlineDisplay<'_, Self>
Source§fn blink(&self) -> BlinkDisplay<'_, Self>
fn blink(&self) -> BlinkDisplay<'_, Self>
Source§fn blink_fast(&self) -> BlinkFastDisplay<'_, Self>
fn blink_fast(&self) -> BlinkFastDisplay<'_, Self>
Source§fn reversed(&self) -> ReversedDisplay<'_, Self>
fn reversed(&self) -> ReversedDisplay<'_, Self>
Source§fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>
fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>
Source§fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
OwoColorize::fg or
a color-specific method, such as OwoColorize::green, Read moreSource§fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
OwoColorize::bg or
a color-specific method, such as OwoColorize::on_yellow, Read more