Skip to main content

DocumentStore

Struct DocumentStore 

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

Implementations§

Source§

impl DocumentStore

Source

pub fn new() -> Self

Source

pub fn interactive_read_guard(&self) -> InteractiveReadGuard<'_>

Mark an interactive read (a request the user is waiting on) as in flight for the guard’s lifetime. Background bulk writers poll Self::yield_to_interactive_reads between files and pause while any guard is live, giving the read a write-free window to complete.

Source

pub fn settled_write_rev_guard(&self) -> (InteractiveReadGuard<'_>, u64)

Take an interactive-read guard, wait (bounded ~50 ms) for in-flight background writes to go quiet, and return the settled write revision.

For user-facing sweeps that abort when Self::write_rev advances: snapshotting the revision this way ensures only genuine user edits — not the background scan the guard just paused — void the sweep. Sleeps; call from a blocking thread only.

Source

pub fn yield_to_interactive_reads(&self)

Pause the calling (background-writer) thread while interactive reads are in flight, up to 500 ms per call. Bounded so a wedged reader can only slow the scan, never stop it; callers invoke this per file, so sustained interactive traffic keeps yielding at each boundary.

Source

pub fn begin_reanalyze(&self) -> IndexCancel

Install a fresh cancel token for a dependent-diagnostics sweep, cancelling whichever sweep was previously in flight. Pass the returned token to reanalyze_dependents_cancellable; when a newer edit calls this again the old token flips and that older sweep stops at its next file boundary instead of racing this one to publish stale diagnostics.

Source

pub fn begin_warm_sweep(&self) -> IndexCancel

Install a fresh cancel token for an analysis warm sweep, cancelling any sweep previously in flight. Mirrors Self::begin_reanalyze but on a separate slot: edit-triggered diagnostic sweeps and background warming must not cancel each other.

Source

pub fn cancel_background_work(&self)

Stop in-flight warm and dependent-diagnostics sweeps at their next file boundary and make every later begin_* token start cancelled. Called on shutdown: the runtime joins blocking tasks on exit, so a sweep still grinding through a large workspace would otherwise hold the process open.

Source

pub fn warm_analysis_sweep(&self, priority: &[Uri], cancel: &IndexCancel)

Drive every workspace file through mir’s memoized analyze_file query so later reference/rename requests are memo hits instead of cold analyses (~20 ms per file on real code — a few hundred candidate files makes an interactive request take seconds).

priority files (and the files declaring the classes they reference — the user’s working set) are warmed first, so requests against open files go warm within the sweep’s first seconds even on workspaces where the full sweep takes much longer.

Background-priority: processes files in small chunks, yielding to interactive reads at each boundary, and stops at the next boundary once cancel flips. Re-running after edits is cheap — unaffected files revalidate via salsa without re-analysis. Blocking; call from spawn_blocking.

Source

pub fn warm_references_phase( &self, untrusted: Vec<Arc<str>>, priority: &[Uri], ambient: bool, progress: Option<UnboundedSender<(u32, u32)>>, )

The reference-warm phase: one deduped reanalysis queue holding mir’s returned warm-start priority set first, then — when ambient — the project sweep set with priority files at its front, so a file in both is analyzed once rather than twice. Flushes the analysis cache and counts as a completed warm sweep on full completion.

Every caller runs this in the background after publishing indexReady: it reanalyzes the whole project set, which on a real workspace costs seconds, and no query needs it to have finished (a cold file is analyzed on demand). Background-priority: yields to interactive reads at chunk boundaries, stops at the next boundary once a newer sweep takes the slot. Blocking; call from spawn_blocking.

Source

pub fn flush_analysis_cache(&self)

Persist mir’s staged analysis-cache entries (reference postings) to disk. No-op when nothing changed since the last flush.

Source

pub fn warm_sweeps_completed(&self) -> u64

Warm sweeps that ran to completion. See $/php-lsp/debugStats.

Source

pub fn warm_start_replays_completed(&self) -> u64

Source

pub fn mark_index_ready(&self)

Mark the workspace reference index as fully built. Called by the scan when its final phase completes (alongside $/php-lsp/indexReady).

Source

pub fn is_index_ready(&self) -> bool

Whether the workspace reference index has finished building.

Source

pub fn write_rev(&self) -> u64

Snapshot of the write-revision counter. Long-running reads should capture this before starting and pass it to cancellable operations; if the counter advances, those operations abort and return empty rather than looping indefinitely against a newly-invalidated database.

Source

pub fn set_session_cache_dir(&self, dir: PathBuf) -> bool

Set the directory used to persist stub-parse and analysis results across server restarts. Subsequent calls are silently ignored (OnceLock semantics).

If a session was already built — an early request (e.g. the editor’s restored-buffer didOpen racing initialized) builds one on demand — it was pinned in-memory-only: nothing it computes is ever flushed, and the next launch replays nothing, silently re-paying the whole cold cost every session. Drop it so the next analysis_session() rebuilds with the cache attached.

Returns true when a session was dropped — the caller must then re-mirror every currently open buffer (see drop_session_scoped_state): the workspace scan won’t do it, since it explicitly skips files that are already open.

Source

pub fn set_user_stub_dirs(&self, dirs: Vec<PathBuf>) -> bool

Set the user-supplied stub directories (initializationOptions.stubDirs). Subsequent calls are silently ignored (OnceLock semantics).

Same early-session race as Self::set_session_cache_dir: if a session was already built without these directories, drop it so the next analysis_session() rebuilds with with_user_stubs attached.

Returns true when a session was dropped — same re-mirroring obligation as set_session_cache_dir.

Source

pub fn set_autoload_uris(&self, uris: Vec<Uri>)

Register URIs discovered from composer.json autoload.files entries. These PHP files define global helper functions (e.g. tap() in Laravel) that are not class-resolvable via PSR-4. Clears analysis_cache so the next per-file analysis pre-ingests them into the AnalysisSession before running mir’s FileAnalyzer.

Source

pub fn with_session<R>(&self, f: impl FnOnce(&mut AnalysisSession) -> R) -> R

Run f against the AnalysisSession for the workspace PHP version, building it first when none exists yet.

The version is read under the same lock as the session: a version read beforehand could be stale and rebuild the session behind drop_session_scoped_state’s back.

This mutex is the only synchronization for session access and it is not reentrant: never call back into the store from inside f.

Source

pub fn with_snapshot<R>( &self, prepare: impl Fn(&mut AnalysisSession), f: impl Fn(&AnalysisSnapshot) -> Result<R, Cancelled>, ) -> Result<R, ContentModified>

Run f on a read snapshot without holding the session lock: the lock is taken only for prepare and the snapshot grab. A write that cancels f retries it on a fresh snapshot, at most [SNAPSHOT_ATTEMPTS] times, then yields ContentModified.

f must not call back into the store: a live snapshot blocks the next input write, so taking the session lock inside it can deadlock.

Source

pub fn read_snapshot<R>( &self, f: impl Fn(&AnalysisSnapshot) -> R, ) -> Result<R, ContentModified>

Self::with_snapshot for reads that need no preparation and cannot return Cancelled themselves; a cancellation unwinds into the retry.

Source

pub fn reanalyze_files( &self, files: &[Arc<str>], cancel: &IndexCancel, ) -> Option<Vec<(Arc<str>, FileAnalysis)>>

Re-analyze files off the session lock, committing their reference postings. None when cancel stopped the pass or writes kept cancelling it.

Source

pub fn stub_class_members(&self, fqcn: &str) -> Option<ClassMembers>

Members of a built-in PHP class from the phpstorm stubs, or None when fqcn is not one (or a write kept cancelling the lookup).

Source

pub fn find_class_like(&self, fqcn: &str) -> Option<ClassLike>

mir’s class-like for fqcn; None when unknown or every snapshot attempt was cancelled.

Source

pub fn find_method_in_chain( &self, class: &str, method: &str, ) -> Option<Arc<MethodDef>>

method as mir resolves it along class’s ancestor chain, then its mixins.

Source

pub fn workspace_php_version(&self) -> PhpVersion

Current PHP version tracked by the workspace input.

Source

pub fn class_direct_supertypes( &self, class_fqn: &str, ) -> Result<Vec<Arc<str>>, ContentModified>

Direct parent, interfaces and used traits of class_fqn as resolved FQCNs, via mir’s class table. Empty when mir doesn’t know the class.

Source

pub fn psr4_arc(&self) -> Arc<ArcSwap<Psr4Map>> ⓘ

Return the Arc<ArcSwap<Psr4Map>> so callers can share it. Backend clones this arc at construction time so writes (e.g. loading composer.json on initialized) are immediately visible to PSR-4 resolution during analysis without extra plumbing.

Source

pub fn mirror_text(&self, uri: &Uri, text: &str)

Mirror a file’s current text into the salsa layer. Creates the SourceFile input on first sight, otherwise updates it through mir’s session write API so mir’s own invalidation state stays in sync.

Source

pub fn mirror_text_arc(&self, uri: &Uri, text_arc: Arc<str>)

Like [mirror_text] but takes an already-allocated Arc<str>.

Callers that already hold an Arc<str> (e.g. ingest_from_doc reusing ParsedDoc::source_arc()) use this to avoid a second allocation and to ensure text_cache and parsed_cache hold the same Arc pointer — enabling Arc::ptr_eq validation in get_parsed_cached.

Source

pub fn seed_cached_index(&self, uri: &Uri, index: Arc<FileIndex>) -> bool

Phase K2: pre-seed a FileIndex loaded from the on-disk cache onto the FileText input for uri. The next file_index call for that file returns the cached index directly, skipping parse + extract.

Must be called before any file_index(db, sf) call for this file — otherwise salsa has already memoized the fresh-parse result and setting cached_index now would only bump the revision without using the cache. In practice the workspace-scan path seeds immediately after mirror_text and before any query runs.

Returns false when uri was not mirrored (caller should mirror first); returns true on success.

Source

pub fn evict_token_cache(&self, uri: &Uri)

Evict the semantic-tokens cache for uri. Called by Backend when a file is closed; diff-based tokens computed against the old revision are no longer meaningful.

Source

pub fn ingest(&self, uri: Uri, text: &str)

Register a file in the salsa layer without marking it open.

Salsa’s parsed_doc query parses lazily on first read; diagnostics are populated by did_open when the editor actually opens the file.

Source

pub fn ingest_from_doc(&self, uri: Uri, doc: &ParsedDoc)

Index a file using an already-parsed ParsedDoc, avoiding a second parse.

Prefer this over [ingest] when the caller already has a ParsedDoc (e.g. after running DefinitionCollector during workspace scan). Reuses the Arc<str> already owned by doc so that text_cache and SourceFile::text share the same pointer — enabling the Arc::ptr_eq fast path in get_parsed_cached on the first subsequent salsa query, without an extra Arc::from(source) allocation.

Source

pub fn remove(&self, uri: &Uri)

Source

pub fn get_doc_salsa(&self, uri: &Uri) -> Option<Arc<ParsedDoc>>

Salsa-backed parsed document.

Salsa-backed parsed document for any mirrored file (open or background-indexed). Returns None only when the file is not known to the store. Callers that want “only if open” should gate on Backend::open_files at the call site (see Backend::get_doc).

Source

pub fn get_index_salsa(&self, uri: &Uri) -> Option<Arc<FileIndex>>

Salsa-backed compact symbol index.

Source

pub fn get_symbol_map_salsa(&self, uri: &Uri) -> Option<Arc<SymbolMap>>

Salsa-backed pre-computed symbol map (name → Vec). Memoized per revision: stable files serve from cache in O(1).

Source

pub fn other_symbol_maps( &self, uri: &Uri, open_urls: &[Uri], ) -> Vec<(Uri, Arc<SymbolMap>)>

Pre-computed symbol maps for every entry in open_urls except uri.

Source

pub fn get_doc_snapshot_or_stale(&self, uri: &Uri) -> Option<Arc<ParsedDoc>>

Parsed doc for a cosmetic, cursor-triggered read (e.g. documentHighlight) that must stay responsive while the user types. Unlike Self::get_doc_salsa it never spins on the Cancelled retry loop: it tries the lock-free parsed_cache, then a bounded snapshot parse, and if a concurrent write stream keeps cancelling it, returns the last-good cached ParsedDoc (possibly one edit stale — invisible for a highlight, unlike a hang). None only when the file has never been parsed.

Source

pub fn sync_workspace_files(&self)

Refresh workspace.files to mirror the current active file set.

Skips all work when workspace_files_dirty is false (the common case after the workspace scan completes — file-set changes are rare).

Source

pub fn mark_workspace_files_dirty(&self)

Mark the workspace file set as dirty so the next sync_workspace_files call re-runs the collect/sort/compare path, and invalidate the workspace_file_paths() cache. Exposed for benchmarks that need to measure the dirty-path cost in isolation.

Source

pub fn set_php_version(&self, version: PhpVersion) -> bool

Update the PHP version tracked by the workspace. Salsa will invalidate all semantic_issues queries so diagnostics are re-evaluated. Skips the setter when the version hasn’t changed to avoid spurious query invalidation. Returns true when the version actually changed — callers that scan the workspace at runtime (not just at init, before any file is mirrored) must re-scan every root when this is true, since drop_session_scoped_state below empties lsp_ws_files and nothing else repopulates it.

Source

pub fn indexed_references( &self, symbol: &Name, files: &[Arc<str>], include_declaration: bool, cancel_rev: Option<u64>, ) -> Result<Vec<RefLocation>, ContentModified>

Inverted-index reference lookup scoped to files (the text-pre-filtered candidate set): a posting-list read for committed-fresh files plus an on-demand analyze+commit for stale/uncommitted candidates, so warm requests are O(results) instead of O(candidates).

Returns LSP-style 0-based line/column.

cancel_rev: when Some(rev), the query aborts with ContentModified if a concurrent write advances the write_revision counter past rev.

Source

pub fn indexed_use_imports( &self, symbol: &Name, files: &[Arc<str>], ) -> Result<Vec<RefLocation>, ContentModified>

use-import lines referencing symbol, from mir’s use: postings. Read-only lookup with no freshness pass — run Self::indexed_references over the same files first so uncommitted candidates are analyzed. Returns (file_uri, line, col_start, col_end) tuples like Self::indexed_references; the range covers the whole import item.

Source

pub fn warm_start_indexes(&self) -> Vec<Arc<str>>

Replay disk-cached reference postings and subtype edges for the whole mirrored workspace (mir’s warm_start_files) — a no-op per file without a content-hash-matching cache entry from a previous run. Call once after the scan mirrors texts, before the reference-warm phase, so a returning session starts index-warm. Cheap enough to sit on the pre-indexReady path — it replays cache entries, it does not analyze.

Returns the subset of replayed files that mir considers worth prioritizing for follow-up warming. php-lsp treats this as a performance hint: callers feed the list to the front of Self::warm_references_phase’s queue so likely-cold files warm in the background before the broader ambient sweep, when any, reaches them.

Source

pub fn workspace_file_paths(&self) -> Arc<Vec<Arc<str>>> ⓘ

Every active workspace file as a mir path (Arc<str> of the URI). The candidate scope handed to mir’s queries — mir gates uncommitted candidates on symbol-name mention internally, so this is always safe.

Cached behind an Arc (invalidated by mark_workspace_files_dirty) so the ~15K-file walk + Arc<str> allocation per file only happens once per workspace-file-set change, not once per caller per request.

Source

pub fn indexed_subtype_classes( &self, class_fqn: &str, include_trait_users: bool, ) -> Result<Vec<SubtypeClassSite>, ContentModified>

Transitive subtypes of class_fqn from mir’s maintained subtype edge index, with declaration sites. include_trait_users also counts use Trait; composition as a subtype edge (trait-usage lenses); leave it off for goto-implementation semantics (extends/implements only).

Source

pub fn indexed_direct_subtype_classes( &self, class_fqn: &str, include_trait_users: bool, ) -> Result<Vec<SubtypeClassSite>, ContentModified>

Self::indexed_subtype_classes restricted to subtypes naming class_fqn directly in extends/implements (or use).

Source

pub fn indexed_method_implementations( &self, class_fqn: &str, method: &str, ) -> Result<Vec<MethodImplSite>, ContentModified>

Concrete implementations of class_fqn::method across its subtypes: (subtype fqcn, file, name range) from mir’s subtype edge index.

Source

pub fn method_reference_scope( &self, owner_fqn: &str, method: &str, ) -> Option<Vec<Uri>>

The complete set of files a private method’s references can occur in, or None when the search must stay workspace-wide.

owner_fqn is the enclosing class at the cursor; narrowing applies only when that class directly declares method (so its MethodDef visibility is authoritative — inherited/call-site lookups fall through to None). A reference to Class::method is recorded only where analyze_file resolves an expression to that key, and analyze_file is per-source-file, so a private member — resolvable only inside the declaring class body, which lives in one file — is fully scoped to the declaring file at any indexing stage.

A protected member is reachable from the declaring class and its transitive subclasses ($this->m(), parent::m(), self::/static::), all of which live in the declaring file or a subtype file — never outside the hierarchy in valid PHP. Its scope is therefore the declaring file plus the transitive subtype files. The complete subtype set is only known once the workspace reference index finishes, so this narrowing applies only when Self::is_index_ready; before then it falls back to None (full workspace scope) so references are never under-reported.

Classes that compose traits or mixins are excluded — those inline external resolution context, so a reference could surface in another file.

Source

pub fn fqn_reachable_files(&self, fqns: &[Arc<str>]) -> Option<Vec<Arc<str>>>

Files that could possibly reference any FQN in fqns, narrowed via PHP’s own name-resolution rules rather than bare-word text mention:

  1. Namespace rule — the file’s namespace equals the target’s, or is a \-segment prefix of it: namespace Foo; reaches Foo\Bar\Baz through the relative-qualified Bar\Baz.
  2. Import rule — a use of the target itself, an alias of it, or any namespace prefix of it (use Foo\Bar; Bar\Baz::x()), all matched on the import’s FQN so aliases come for free.
  3. Text rule — the qualified path appears literally in the file (\App\Widget::class config arrays with no use line, or a leading-slash-free App\Widget from a no-namespace file, where qualified names resolve from the root). Matched ASCII-case-insensitively — PHP class names are case-insensitive.

These are the only ways PHP resolves a class-like or namespaced name, so this is exact narrowing grounded in the language’s own resolution order, not a heuristic — unlike mir’s own gate, which only sees bare short names and can’t distinguish this owner class from an unrelated class sharing its short name elsewhere in the workspace.

Callers must NOT use this for global-namespace functions/constants (unqualified calls fall back to the global namespace from any namespace, so no file can be excluded) or for instance members (a typed receiver can hide the class entirely).

Returns None (full workspace) when the boot scan hasn’t finished — same conservative discipline as the Protected branch above — so references are never under-reported at cold start.

Source

pub fn get_workspace_index_salsa(&self) -> Arc<WorkspaceIndexData> ⓘ

Phase J: salsa-memoized aggregate workspace index.

Returns the shared Arc<WorkspaceIndexData> with the flat (Uri, Arc<FileIndex>) list plus classes_by_lowercase_name (for completion’s prefix search). Used by workspace_symbols, prepare_type_hierarchy, supertypes_of, subtypes_of, and find_implementations so they don’t each rebuild the aggregate per request. Invalidates automatically when any file’s file_index changes. Class/declaration name lookups no longer come from this aggregate — see Self::resolve_class_ref/class_candidates/ declaration_candidate_files, which query mir’s mention index instead.

Source

pub fn parse_count(&self) -> u64

Total number of real ParsedDoc parses served so far (cache misses). Surfaced via $/php-lsp/debugStats so tests can assert the references read path doesn’t parse the whole workspace.

Source

pub fn ref_index_lock_count(&self) -> u64

Times mir’s RefIndex was locked on the current session. Reads are per-key posting lookups and edits commit one file’s postings, so this grows by a small bounded amount per operation — never per candidate. Surfaced via $/php-lsp/debugStats for the stress-test guard.

Source

pub fn mir_ref_query_cache_hits(&self) -> u64

Diagnostic: mir’s indexed_references_to memoization hits, surfaced via $/php-lsp/debugStats so a host-side query can be attributed to the right layer when diagnosing latency.

Source

pub fn mir_subtype_query_cache_hits(&self) -> u64

Diagnostic: mir’s indexed_subtype_classes memoization hits.

Source

pub fn workspace_symbol_index_ready(&self) -> bool

Whether mir’s workspace symbol index singleton is populated (warm-start seed or first sweep). See DebugStats::workspace_symbol_index_ready.

Source

pub fn workspace_index_walks(&self) -> u64

Executions of mir’s tracked O(all-files) symbol-index walk.

Source

pub fn workspace_file_count(&self) -> u64

Number of files mirrored into the salsa workspace (open + background indexed). Surfaced via $/php-lsp/debugStats as a denominator for the per-file cache sizes below — e.g. text_cache_len tracking this 1:1 means it’s carrying the workspace’s working set, not leaking.

Source

pub fn token_cache_len(&self) -> u64

Entries in the semantic-tokens delta cache. Evicted per-file on did_close; a value that keeps climbing past the number of files ever opened in the editor means that eviction isn’t firing.

Source

pub fn text_cache_len(&self) -> u64

Entries in the mirrored-source-text cache. Expected to track Self::workspace_file_count — it shares its Arc<str> with salsa’s own SourceFile::text, so this is a pointer per file, not a second copy of the workspace’s source.

Source

pub fn parsed_cache_len(&self) -> u64

Entries in the read-through ParsedDoc cache. Bounded by PARSED_CACHE_CAP via LRU shedding.

Source

pub fn analysis_cache_len(&self) -> u64

Entries in the per-file FileAnalysis cache. Bounded by ANALYSIS_CACHE_CAP via LRU shedding.

Source

pub fn owned_program_cache_len(&self) -> u64

Entries in the owned-Program cache. Bounded by OWNED_PROGRAM_CACHE_CAP via LRU shedding.

Source

pub fn source_text(&self, uri: &Uri) -> Option<Arc<str>>

Return the raw source text for uri if it has been mirrored into the salsa workspace. Used by the references handler to pre-filter session results by checking whether a file mentions the owning class name.

Source

pub fn store_token_cache( &self, uri: &Uri, result_id: String, tokens: Arc<Vec<SemanticToken>>, )

Cache the semantic tokens computed for a delta response. result_id is an opaque string (a hash of the token data) returned to the client.

Source

pub fn get_token_cache( &self, uri: &Uri, result_id: &str, ) -> Option<Arc<Vec<SemanticToken>>>

Return the cached tokens if result_id matches the stored one.

Source

pub fn get_semantic_issues_salsa(&self, uri: &Uri) -> Option<Arc<[Issue]>>

Raw semantic issues for a file, computed via mir’s session-based FileAnalyzer. The session lazy-loads dependencies via PSR-4 so the LSP no longer needs to mirror vendor up-front. Callers apply their own DiagnosticsConfig filter via crate::semantic_diagnostics::issues_to_diagnostics.

Source

pub fn mir_name_at( &self, uri: &Uri, offset: u32, ) -> Result<Option<Name>, ContentModified>

Resolve only the codebase symbol identity at offset in uri.

This targeted navigation path lets reference queries avoid php-lsp’s retained whole-file mir_analyzer::FileAnalysis merely to call symbol_at(...).kind.to_name().

Source

pub fn cached_analysis_if_fresh(&self, uri: &Uri) -> Option<Arc<FileAnalysis>>

Run (or reuse) mir’s per-file body analysis, retaining the full mir_analyzer::FileAnalysis — issues and resolved symbols — across requests. Diagnostics read .issues; position features call .symbol_at(offset) for the resolved type at a cursor.

Cache hit when the entry’s captured source Arc is pointer-equal to the file’s current doc.source_arc(). A miss recomputes and overwrites, so the entry self-evicts on any content edit. Cache-hit-only variant of Self::cached_analysis: returns the cached analysis when the entry is current for the file’s text, never computes. Lets async handlers take the warm path synchronously and reserve spawn_blocking for the cold path (mir Pass 1 + Pass 2 can take hundreds of ms on large files).

Source

pub fn cached_analysis(&self, uri: &Uri) -> Option<Arc<FileAnalysis>>

Source

pub fn sync_analysis_cache_declarations(&self, uri: &Uri)

Sync declaration freshness for a file mirrored outside its own analysis pass. Mir owns resolver/cache invalidation; this protects only php-lsp’s retained mir_analyzer::FileAnalysis cache, whose entries are tagged by decl_version.

Source

pub fn cached_analysis_cancellable( &self, uri: &Uri, should_cancel: &(dyn Fn() -> bool + Sync), ) -> Option<Arc<FileAnalysis>>

Self::cached_analysis with an early exit: should_cancel is polled whenever a concurrent salsa write cancels the analysis attempt. A handler passes its write-revision staleness probe so a request made obsolete by newer typing stops burning a blocking-pool thread instead of retrying until the writer pauses — the editor re-requests anyway.

Source

pub fn docs_for(&self, open_urls: &[Uri]) -> Vec<(Uri, Arc<ParsedDoc>)>

Returns (uri, doc) for files currently open in the editor.

Resolve open_urls (from Backend::open_urls()) to parsed docs. Files not mirrored in the salsa layer are filtered out silently.

Source

pub fn other_docs( &self, uri: &Uri, open_urls: &[Uri], ) -> Vec<(Uri, Arc<ParsedDoc>)>

Parsed docs for every entry in open_urls except uri.

Source

pub fn with_all_indexes<R>( &self, f: impl FnOnce(&[(Uri, Arc<FileIndex>)]) -> R, ) -> R

Borrow-scoped access to the aggregate (Uri, Arc<FileIndex>) slice, avoiding per-call cloning of the workspace-wide vector.

Source

pub fn docs_for_scan_mentioning( &self, needles: &[String], ) -> Vec<(Uri, Arc<ParsedDoc>)>

Parses only the workspace files whose raw text mentions at least one of needles as a whole identifier (ASCII-case-insensitive — PHP class names are case-insensitive). Used by callers scanning for a class/interface declaration by name (e.g. “implement missing methods”), where the needle set is small and a miss guarantees the file declares none of them.

Answered from mir’s persistent per-file ClassMentionIndex — the same cache the reference/subtype gates and Self::resolve_reachability_queries populate — so a file scanned here answers later reference queries for free, and vice versa. Text comes from this store’s own mirror (source_text), same as before; class_mention_answer validates cache freshness against it, so a file whose mirror diverges from mir’s copy is simply rescanned.

Source

pub fn files_mentioning_short_name( &self, files: &[Arc<str>], short_name: &str, ) -> Vec<Arc<str>>

Subset of files (mir paths) mentioning short_name as a whole identifier, ASCII-case-insensitive, via mir’s shared per-file mention cache, scanned off the session lock. A file mir doesn’t know is omitted; if writes keep cancelling the scan, every file is returned.

Source

pub fn declaration_candidate_files( &self, wi: &WorkspaceIndexData, name: &str, ) -> Vec<Uri>

Candidate files that may declare something named name anywhere in the workspace (function/class/method/property/constant/enum-case), narrowed via mir’s persistent per-file mention cache instead of an eagerly-rebuilt name → [DeclRef] map. A miss means no file’s text contains name at all, so nothing declares it either — same necessary-not-sufficient contract as files_mentioning_short_name; callers must still verify the candidate actually declares name (via its own FileIndex/AST), same as they always have. Unlike an eagerly rebuilt map, an edit to file X only invalidates X’s own cached mention set, not the whole workspace’s.

Source

pub fn class_ref_by_fqn( &self, wi: &WorkspaceIndexData, fqn: &str, ) -> Option<ClassRef>

O(1) resolution of a known FQN to its declaring class, via mir’s own incrementally-maintained FQN→location index (definition_of_cached, backed by the same singleton all_classes()/workspace_classes read from — no rebuild-from-scratch, no per-call scan over every workspace file). No php-lsp-side duplicate structure involved. Use this whenever the caller already has a resolved FQN, not just a bare short name needing disambiguation; falls back to None (never wrong, just not fast) when mir hasn’t loaded/committed the class yet.

Source

pub fn resolve_class_ref_by_fqn( &self, wi: &WorkspaceIndexData, fqn: &str, ) -> Option<ClassRef>

Resolve a known FQN to its declaring class. This is the default lookup path for callers that already resolved imports/aliases or are following a semantic symbol carrying an FQN.

Source

pub fn function_ref_by_fqn( &self, wi: &WorkspaceIndexData, fqn: &str, ) -> Option<FunctionRef>

O(1) resolution of a known FQN to its declaring global function via mir’s incrementally-maintained definition index. As with Self::class_ref_by_fqn, validate the result against the current workspace snapshot before returning its compact index back-pointer.

Source

pub fn find_declaration( &self, wi: &WorkspaceIndexData, word: &str, exclude: Option<&Uri>, ) -> Option<Location>

O(candidates) replacement for the old decls_by_name-backed linear scan: find a declaration named word anywhere in the workspace, optionally excluding one file (the current document, which the caller has already searched with accurate AST ranges), via Self::declaration_candidate_files + the same per-file check goto_declaration_from_index uses.

Source

pub fn files_importing(&self, fqn: &str) -> Vec<Uri>

Files whose use imports include the class fqn (leading \ ignored — PHP names are case-insensitive), from mir’s use: postings. The candidate scope for use-line rewrites on file rename/delete: only importers can carry such a line.

Trait Implementations§

Source§

impl Default for DocumentStore

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

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> Lookup<T> for T

Source§

fn into_owned(self) -> T

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> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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<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