pub struct Database { /* private fields */ }Expand description
Workspace-scoped incremental analysis database (spec §11).
The primary public API for all consumers (cyrs-lsp, cyrs-agent,
cyrs-cli, cyrs-tck). Wraps CypherDatabase with:
- A
FileId→SourceFileregistry so callers use stableu32handles instead of raw Salsa input structs. - A single
WorkspaceInputsfor the workspace-scoped schema. - Snapshot support via
Database::snapshot.
§Concurrency contract (spec §11.5)
Database is Send but not Sync. All mutating methods take &mut self.
For concurrent read access from multiple threads, call snapshot to
obtain a DatabaseSnapshot that implements Send and can be given to
a worker thread.
Implementations§
Source§impl Database
impl Database
Sourcepub fn with_options(opts: DatabaseOptions) -> Database
pub fn with_options(opts: DatabaseOptions) -> Database
Create a new, empty workspace database with the given DatabaseOptions.
LRU capacities in opts are applied via Salsa’s runtime
set_lru_capacity API immediately after construction. The options
are immutable after this point.
§Example
use cyrs_db::{Database, DatabaseOptions};
let db = Database::with_options(DatabaseOptions {
parse_lru: 512,
sema_lru: 128,
..DatabaseOptions::default()
});Sourcepub fn open_file(
&mut self,
path: &Path,
source: String,
dialect: DialectMode,
) -> FileId
pub fn open_file( &mut self, path: &Path, source: String, dialect: DialectMode, ) -> FileId
Open a file in the workspace.
Returns a stable FileId that uniquely identifies this file for the
lifetime of the database. The path is recorded for diagnostics /
display but is not used as a key; two calls with the same path but
different sources produce two independent files.
§Caching
Opening a file creates new Salsa input structs and does not yet run any derived query. All analysis is lazy and memoised.
Sourcepub fn update_file(
&mut self,
id: FileId,
new_source: String,
) -> Result<(), UnknownFileId>
pub fn update_file( &mut self, id: FileId, new_source: String, ) -> Result<(), UnknownFileId>
Update the source text of an already-open file.
Bumps the Salsa revision for this file’s SourceFile input, causing
all derived queries that depend on source to be re-evaluated on the
next access.
Returns Err(UnknownFileId) if id is not currently open.
Sourcepub fn edit_file(
&mut self,
id: FileId,
edit: &TextEdit,
) -> Result<(), UnknownFileId>
pub fn edit_file( &mut self, id: FileId, edit: &TextEdit, ) -> Result<(), UnknownFileId>
Apply a single-range text edit to an already-open file (cy-zv0, spec §11).
This is the incremental-edit entry point that textDocument/didChange
and agent edit flows should prefer over update_file when only a
byte range changed. The API is shaped so that a future sub-tree
reparse (see cyrs_syntax::edit::incremental_reparse) can plug in
underneath without breaking callers.
§Current implementation
Today the underlying incremental_reparse is a whole-file reparse
fallback, so the cache-invalidation behaviour is identical to
update_file. The observable difference is:
- Callers pass a
TextEditvalue (range + replacement) instead of re-materialising the full source, so they don’t pay an extraStringallocation for the unchanged prefix / suffix. - The edit is applied to the current source held by Salsa, not to a caller-managed copy, so there is no opportunity for the caller’s local mirror to drift out of sync.
Once the smart path lands (tracked as a follow-up bead to cy-zv0),
edit_file will become strictly sub-linear in file size for small
edits. Callers do not need to change.
Returns Err(UnknownFileId) if id is not currently open.
Sourcepub fn remove_file(&mut self, id: FileId) -> Result<(), UnknownFileId>
pub fn remove_file(&mut self, id: FileId) -> Result<(), UnknownFileId>
Remove a file from the workspace.
After removal, the FileId is considered stale. Any subsequent call
that takes this FileId will return Err(UnknownFileId) rather than
panic.
Returns Err(UnknownFileId) if id was not open.
Sourcepub fn set_schema(&mut self, schema: Option<Arc<dyn SchemaProvider>>)
pub fn set_schema(&mut self, schema: Option<Arc<dyn SchemaProvider>>)
Set the workspace-scoped schema.
Bumps the Salsa revision on WorkspaceInputs, which cascades to
every schema-aware derived query (sema_diagnostics, all_diagnostics)
across all files. The parse cache is unaffected.
Pass None to switch to schema-free analysis mode (§7.1).
Sourcepub fn schema(&self) -> Option<Arc<dyn SchemaProvider>>
pub fn schema(&self) -> Option<Arc<dyn SchemaProvider>>
Read the current workspace-scoped schema (may be None).
Sourcepub fn snapshot(&self) -> DatabaseSnapshot
pub fn snapshot(&self) -> DatabaseSnapshot
Create a DatabaseSnapshot suitable for cross-thread queries.
The snapshot is a frozen read-only view of the database at this
instant. It can be sent to another thread (Send) and used to run
any derived query without &mut. Mutations applied to self after
calling snapshot() are not visible to the snapshot.
§Pattern — one DB + snapshot per request
let snap = db.snapshot();
std::thread::spawn(move || {
let out = snap.parse_cst(file_id).unwrap();
// use out …
});Sourcepub fn parse_cst(&self, id: FileId) -> Result<ParseOutput, UnknownFileId>
pub fn parse_cst(&self, id: FileId) -> Result<ParseOutput, UnknownFileId>
Run parse_cst on the given file.
Sourcepub fn parse_ast(&self, id: FileId) -> Result<AstOutput, UnknownFileId>
pub fn parse_ast(&self, id: FileId) -> Result<AstOutput, UnknownFileId>
Run parse_ast on the given file.
Sourcepub fn plan_of(&self, id: FileId) -> Result<PlanOutput, UnknownFileId>
pub fn plan_of(&self, id: FileId) -> Result<PlanOutput, UnknownFileId>
Run plan_of on the given file.
Sourcepub fn sema_diagnostics(
&self,
id: FileId,
) -> Result<DiagnosticsOutput, UnknownFileId>
pub fn sema_diagnostics( &self, id: FileId, ) -> Result<DiagnosticsOutput, UnknownFileId>
Run sema_diagnostics on the given file.
Sourcepub fn resolved_names(
&self,
id: FileId,
) -> Result<ResolvedNamesOutput, UnknownFileId>
pub fn resolved_names( &self, id: FileId, ) -> Result<ResolvedNamesOutput, UnknownFileId>
Run resolved_names on the given file.
Sourcepub fn all_diagnostics(
&self,
id: FileId,
) -> Result<DiagnosticsOutput, UnknownFileId>
pub fn all_diagnostics( &self, id: FileId, ) -> Result<DiagnosticsOutput, UnknownFileId>
Run all_diagnostics on the given file.
Sourcepub fn analyse_file(&self, id: FileId) -> Result<Analysis, UnknownFileId>
pub fn analyse_file(&self, id: FileId) -> Result<Analysis, UnknownFileId>
Run the full analysis pipeline on the given file.
Sourcepub fn source_of(&self, id: FileId) -> Result<String, UnknownFileId>
pub fn source_of(&self, id: FileId) -> Result<String, UnknownFileId>
Return the source text of a file.
Returns Err(UnknownFileId) if id is not open.
Sourcepub fn path_of(&self, id: FileId) -> Result<&Path, UnknownFileId>
pub fn path_of(&self, id: FileId) -> Result<&Path, UnknownFileId>
Return the path associated with a file.
Returns Err(UnknownFileId) if id is not open.
Sourcepub fn file_ids(&self) -> impl Iterator<Item = FileId>
pub fn file_ids(&self) -> impl Iterator<Item = FileId>
Iterate every currently-open FileId in insertion order.
Needed by cross-file analyses (workspace symbols / references /
goto-definition, spec §14.2, bead cy-kkw) so the navigation
engine can walk every member file of the workspace without the
caller having to track its own file list alongside the
Database.
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for Database
impl RefUnwindSafe for Database
impl Send for Database
impl !Sync for Database
impl Unpin for Database
impl UnsafeUnpin for Database
impl !UnwindSafe for Database
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 more