pub struct AnalysisSnapshot { /* private fields */ }Expand description
A read handle on one revision of an super::AnalysisSession:
Send + Clone, for running queries on threads other than the owner’s.
No query writes salsa inputs. Class-likes and built-in stubs the symbol
index lacks load on demand as pure reads; the owner adopts them at its
next super::AnalysisSession::prepare_for_query, which also settles
the index before a snapshot is handed out.
A snapshot blocks the owner’s next input write until it is dropped (salsa
waits for outstanding handles), so hand snapshots out per request and
never park one. When the owner starts a write, in-flight queries unwind
and return Err(Cancelled): drop the snapshot and request a fresh one.
Queries may still commit to the shared reference/subtype indexes (lazy freshness passes); those commits land in the owner’s state too.
Implementations§
Source§impl AnalysisSnapshot
impl AnalysisSnapshot
Sourcepub fn analyze(
&self,
file: Arc<str>,
source: &str,
program: &Program,
source_map: &SourceMap,
) -> Result<FileAnalysis, Cancelled>
pub fn analyze( &self, file: Arc<str>, source: &str, program: &Program, source_map: &SourceMap, ) -> Result<FileAnalysis, Cancelled>
Body-analyze file and commit its reference locations — the read half
of FileAnalyzer::analyze. The owner should have run
AnalysisSession::prepare_for_query for file (or ingested it via
AnalysisSession::ingest_file_prepared): classes load on demand
regardless, but Composer autoload.files functions are indexed only
by that warm-up. file must already be ingested with source as its
text; the warm-up reads its input, so a file never ingested is not
warmed.
Sourcepub fn analyze_diagnostics_only(
&self,
file: Arc<str>,
source: &str,
program: &Program,
source_map: &SourceMap,
) -> Result<FileAnalysis, Cancelled>
pub fn analyze_diagnostics_only( &self, file: Arc<str>, source: &str, program: &Program, source_map: &SourceMap, ) -> Result<FileAnalysis, Cancelled>
Self::analyze without the whole-file ResolvedSymbol list; see
FileAnalyzer::analyze_diagnostics_only.
Sourcepub fn symbol_at(
&self,
file: &Arc<str>,
byte_offset: u32,
) -> Result<Option<ResolvedSymbol>, Cancelled>
pub fn symbol_at( &self, file: &Arc<str>, byte_offset: u32, ) -> Result<Option<ResolvedSymbol>, Cancelled>
The symbol at byte_offset in file, found by analyzing only the
containing scope — the read half of AnalysisSession::symbol_at.
Expects the owner to have prepared file
(AnalysisSession::prepare_for_query).
Sourcepub fn name_at(
&self,
file: &Arc<str>,
byte_offset: u32,
) -> Result<Option<Name>, Cancelled>
pub fn name_at( &self, file: &Arc<str>, byte_offset: u32, ) -> Result<Option<Name>, Cancelled>
The codebase-level symbol name at byte_offset in file — the read
half of AnalysisSession::name_at. Same preparation contract as
Self::symbol_at.
Sourcepub fn outgoing_calls(
&self,
file: &Arc<str>,
byte_offset: u32,
) -> Result<Vec<(Name, Range)>, Cancelled>
pub fn outgoing_calls( &self, file: &Arc<str>, byte_offset: u32, ) -> Result<Vec<(Name, Range)>, Cancelled>
Calls made inside the function or method whose declaration contains
byte_offset — the read half of AnalysisSession::outgoing_calls.
Same preparation contract as Self::symbol_at.
Sourcepub fn variable_references(
&self,
file: &Arc<str>,
byte_offset: u32,
) -> Result<Vec<Range>, Cancelled>
pub fn variable_references( &self, file: &Arc<str>, byte_offset: u32, ) -> Result<Vec<Range>, Cancelled>
Occurrences of the variable under byte_offset — the read half of
AnalysisSession::variable_references. Same preparation contract
as Self::symbol_at.
Source§impl AnalysisSnapshot
impl AnalysisSnapshot
pub fn php_version(&self) -> PhpVersion
Sourcepub fn index_generation(&self) -> u64
pub fn index_generation(&self) -> u64
Sourcepub fn text_revision(&self) -> Revision
pub fn text_revision(&self) -> Revision
pub fn find_class_like( &self, fqcn: &str, ) -> Result<Option<ClassLike>, Cancelled>
Sourcepub fn is_builtin_class(&self, fqcn: &str) -> Result<bool, Cancelled>
pub fn is_builtin_class(&self, fqcn: &str) -> Result<bool, Cancelled>
Whether fqcn resolves to a class-like declared by an embedded
built-in stub. A workspace class sharing a stub’s name (a polyfill’s
Stringable) shadows it and answers false, where
crate::stub_path_for_class tests the name alone.
pub fn find_function( &self, fqn: &str, ) -> Result<Option<Arc<FunctionDef>>, Cancelled>
Sourcepub fn find_method_in_chain(
&self,
class: &str,
method: &str,
) -> Result<Option<(Arc<str>, Arc<MethodDef>)>, Cancelled>
pub fn find_method_in_chain( &self, class: &str, method: &str, ) -> Result<Option<(Arc<str>, Arc<MethodDef>)>, Cancelled>
method as resolved along class’s ancestor chain (then mixins), as
(declaring class, method).
Sourcepub fn implemented_method(
&self,
method: &Name,
) -> Result<Option<Name>, Cancelled>
pub fn implemented_method( &self, method: &Name, ) -> Result<Option<Name>, Cancelled>
The interface or abstract method that method implements: the first
ancestor of its class declaring the same-named method as abstract or
as an interface member. None for non-methods and for methods that
implement nothing.
Sourcepub fn definition_of_cached(
&self,
symbol: &Name,
) -> Result<Result<Location, SymbolLookupError>, Cancelled>
pub fn definition_of_cached( &self, symbol: &Name, ) -> Result<Result<Location, SymbolLookupError>, Cancelled>
Declaration location of symbol. Symbols the index lacks load on
demand; no input is written.
Sourcepub fn files_mentioning_class(
&self,
files: &[Arc<str>],
class_name: &str,
) -> Result<Vec<Arc<str>>, Cancelled>
pub fn files_mentioning_class( &self, files: &[Arc<str>], class_name: &str, ) -> Result<Vec<Arc<str>>, Cancelled>
Which of files currently mention class_name as a whole identifier
(case-insensitive) — the same persistent, incrementally-maintained
mechanism Self::indexed_references_to’s own gate uses (see
db::class_mention_index), exposed so a host needn’t re-implement a
from-scratch text scan for its own narrowing. A file already scanned
against a universe that included class_name answers via an O(log n)
lookup; only a never-scanned or since-edited file pays a scan, and
that scan is recorded for every other name in the universe too.
Sourcepub fn files_mentioning_any(
&self,
files: &[Arc<str>],
needles: &[&str],
) -> Result<Vec<Arc<str>>, Cancelled>
pub fn files_mentioning_any( &self, files: &[Arc<str>], needles: &[&str], ) -> Result<Vec<Arc<str>>, Cancelled>
Which of files currently mention ANY of needles as a whole
identifier (case-insensitive). Every needle is admitted into the
shared universe verbatim (no short-name stripping) before querying,
so the answer is never conservative on account of an unknown needle.
Sourcepub fn indexed_references_to(
&self,
symbol: &Name,
files: &[Arc<str>],
include_declaration: bool,
includes: ReferenceIncludes,
) -> Result<Vec<(Arc<str>, Range)>, Cancelled>
pub fn indexed_references_to( &self, symbol: &Name, files: &[Arc<str>], include_declaration: bool, includes: ReferenceIncludes, ) -> Result<Vec<(Arc<str>, Range)>, Cancelled>
Inverted-index find-references: posting-list lookup plus an on-demand
freshness/completeness pass over files (the host’s candidate scope
— passing the whole workspace is fine; see the gate in
stale_reference_candidates_unguarded).
A candidate whose postings were committed from its current text (Arc
identity) is answered from the index with no salsa work. Stale or
never-committed candidates are analyzed via the memoized
analyze_file query and committed, so each file pays that cost once
per text change — after a background warm sweep the steady state is a
pure lookup, O(results) instead of O(candidates). Hosts need no text
prefilter of their own, and must not use one: a host-side filter
cannot know the gate’s matching semantics.
Results are filtered to files. With include_declaration, the
symbol’s declaration name span is appended when it lies inside the
scope.
Returned ranges use mir’s native coordinates: 1-based lines and
0-based Unicode code-point columns (UTF-32/LSP positionEncoding
"utf-32").
Stale candidates are analyzed against whatever the owner has loaded.
Classes load on demand, but Composer autoload.files functions only
load in the owner’s warm-up: a candidate analyzed before it records
unresolved names and is re-verified after the owner’s next load bumps
the generation. Run super::AnalysisSession::prepare_references_query
before taking the snapshot to warm the stale candidates first.
Memoized per (symbol, files, include_declaration, includes, query generation) — see RefQueryCacheKey — so a repeat query
against unchanged state (a code-lens refresh) is one hashmap lookup
instead of an O(candidates) freshness scan.
Sourcepub fn indexed_use_import_locations(
&self,
symbol: &Name,
files: &[Arc<str>],
) -> Result<Vec<(Arc<str>, Range)>, Cancelled>
pub fn indexed_use_import_locations( &self, symbol: &Name, files: &[Arc<str>], ) -> Result<Vec<(Arc<str>, Range)>, Cancelled>
use import items (use Foo\Bar;, use function ...;,
use const ...;) for symbol — Self::indexed_references_to with
crate::ReferenceIncludes::UseImports.
Sourcepub fn stale_reference_candidates(
&self,
symbol: &Name,
files: &[Arc<str>],
) -> Result<Vec<Arc<str>>, Cancelled>
pub fn stale_reference_candidates( &self, symbol: &Name, files: &[Arc<str>], ) -> Result<Vec<Arc<str>>, Cancelled>
The candidates in files that Self::indexed_references_to would
analyze and commit: those whose postings are not exact for their
current text. Empty means the owner-side prelude
(super::AnalysisSession::prepare_references_query) has nothing to
warm, so a host can check this off its lock and skip taking it; when
not empty it passes this list to the prelude, so the O(candidates)
scan never runs under the lock.
Sourcepub fn warm_files(
&self,
files: &[Arc<str>],
cancel: &IndexCancel,
) -> Result<bool, Cancelled>
pub fn warm_files( &self, files: &[Arc<str>], cancel: &IndexCancel, ) -> Result<bool, Cancelled>
Analyze files and commit their reference postings, class edges and
mention scans to the index shared with the owner, so later queries
find them fresh. Ok(false) when cancel stopped the pass first.
A commit with unresolved names stays tied to this snapshot’s
Self::index_generation, so the next workspace change re-opens it.
Sourcepub fn reanalyze_files(
&self,
files: &[Arc<str>],
cancel: &IndexCancel,
) -> Result<Option<Vec<(Arc<str>, FileAnalysis)>>, Cancelled>
pub fn reanalyze_files( &self, files: &[Arc<str>], cancel: &IndexCancel, ) -> Result<Option<Vec<(Arc<str>, FileAnalysis)>>, Cancelled>
The read half of super::AnalysisSession::reanalyze_files_cancellable:
analyze files, commit their reference postings and class edges, and
return each file’s diagnostics (symbols are empty). Files without
registered text are absent. Ok(None) when cancel stopped the pass
first, with nothing committed.
Run the owner-side prelude first: prepare_for_query(None), then
prepare_file_for_analysis per file, a map lookup for files ingested
with ingest_file_prepared.
Sourcepub fn declaration_name_range_cached(
&self,
symbol: &Name,
) -> Result<Option<(Arc<str>, Range)>, Cancelled>
pub fn declaration_name_range_cached( &self, symbol: &Name, ) -> Result<Option<(Arc<str>, Range)>, Cancelled>
The symbol’s declaration site, narrowed to the declared name’s own
token — the lock-free read half of
[AnalysisSession::declaration_name_range]. Symbols the index lacks
load on demand; no input is written.
Sourcepub fn subtype_files(
&self,
class_fqn: &str,
include_trait_users: bool,
) -> Result<Vec<Arc<str>>, Cancelled>
pub fn subtype_files( &self, class_fqn: &str, include_trait_users: bool, ) -> Result<Vec<Arc<str>>, Cancelled>
Files declaring transitive subclasses of class_fqn anywhere in the
workspace, excluding class_fqn’s own declaring file — the caller
adds it. Subclasses are matched by resolved FQCN, so extends \Ns\Base
and aliased use forms are all found. include_trait_users also
counts files whose classes use the trait class_fqn.
Sourcepub fn indexed_subtype_classes(
&self,
class_fqn: &str,
files: &[Arc<str>],
include_trait_users: bool,
) -> Result<Vec<SubtypeClassSite>, Cancelled>
pub fn indexed_subtype_classes( &self, class_fqn: &str, files: &[Arc<str>], include_trait_users: bool, ) -> Result<Vec<SubtypeClassSite>, Cancelled>
Transitive subtypes of class_fqn (classes/interfaces/enums whose
resolved ancestor chain reaches it), answered from the maintained
subtype edge index.
files is the host’s candidate scope for the on-demand completeness
pass: per BFS round, not-yet-committed files whose text mentions a
frontier short name get their definitions committed, so results are
complete even before a background sweep has covered the workspace.
That short-name gate is only candidate discovery; subtype identity is
resolved from the edge index by exact canonical FQCN. Committed files
answer from the index with no parsing at all.
include_trait_users also counts use Trait; composition as a
subtype edge (visibility-scoping semantics); leave it off for
goto-implementation semantics (extends/implements only).
Memoized per (class_fqn, include_trait_users, files, query generation), same rationale as Self::indexed_references_to.
Sourcepub fn indexed_direct_subtype_classes(
&self,
class_fqn: &str,
files: &[Arc<str>],
include_trait_users: bool,
) -> Result<Vec<SubtypeClassSite>, Cancelled>
pub fn indexed_direct_subtype_classes( &self, class_fqn: &str, files: &[Arc<str>], include_trait_users: bool, ) -> Result<Vec<SubtypeClassSite>, Cancelled>
Like Self::indexed_subtype_classes, restricted to subtypes that
name class_fqn directly in extends/implements (or use when
include_trait_users), resolved by canonical FQCN.
Sourcepub fn indexed_method_implementations(
&self,
class_fqn: &str,
method: &str,
files: &[Arc<str>],
) -> Result<Vec<(Arc<str>, Arc<str>, Range)>, Cancelled>
pub fn indexed_method_implementations( &self, class_fqn: &str, method: &str, files: &[Arc<str>], ) -> Result<Vec<(Arc<str>, Arc<str>, Range)>, Cancelled>
Concrete implementations of class_fqn::method across its transitive
subtypes: the same-named non-abstract method available to each subtype
(its own declaration, or one inherited/composed from a parent, trait,
or mixin), as (subtype fqcn, file, name range). Subtypes resolving to
the same declaring location collapse to a single entry.
Sourcepub fn class_issues(&self, files: &[Arc<str>]) -> Result<Vec<Issue>, Cancelled>
pub fn class_issues(&self, files: &[Arc<str>]) -> Result<Vec<Issue>, Cancelled>
Class-level issues (inheritance violations, abstract-method gaps,
override incompatibilities) for files.
These checks are cross-file by nature and are not emitted by
Self::analyze. Circular-inheritance checks always run against the
full workspace graph regardless of the files filter — a cycle is a
workspace-wide problem.
Sourcepub fn collector_issues(
&self,
files: &[Arc<str>],
) -> Result<Vec<Issue>, Cancelled>
pub fn collector_issues( &self, files: &[Arc<str>], ) -> Result<Vec<Issue>, Cancelled>
Collector-phase issues (e.g. BackedEnumCaseTypeMismatch,
InvalidReadonlyPropertyDeclaration, InvalidDocblock, and raw parse
errors) for files.
These are found while building a file’s declaration slice, before body
analysis or cross-file class checks run — neither Self::analyze
nor Self::class_issues reports them, so a caller merging just those
two sources silently drops every collector-time diagnostic.
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for AnalysisSnapshot
impl !RefUnwindSafe for AnalysisSnapshot
impl !Sync for AnalysisSnapshot
impl !UnwindSafe for AnalysisSnapshot
impl Send for AnalysisSnapshot
impl Unpin for AnalysisSnapshot
impl UnsafeUnpin for AnalysisSnapshot
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> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
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