mirror of
https://github.com/nushell/nushell.git
synced 2025-05-28 10:31:23 +00:00
# Description @sholderbach left a very helpful review and this just implements the suggestions he made. Didn't notice any difference in performance, but there could potentially be for a long running Nushell session or one that loads a lot of stuff. I also caught a bug where nu-protocol won't build without `plugin` because of the previous conditional import. Oops. Fixed. # User-Facing Changes `blocks` and `modules` type in `EngineState` changed again. Shouldn't affect plugins or anything else though really # Tests + Formatting - 🟢 `toolkit fmt` - 🟢 `toolkit clippy` - 🟢 `toolkit test` - 🟢 `toolkit test stdlib` # After Submitting --------- Co-authored-by: sholderbach <sholderbach@users.noreply.github.com>
136 lines
3.9 KiB
Rust
136 lines
3.9 KiB
Rust
use super::cached_file::CachedFile;
|
|
use super::{usage::Usage, Command, EngineState, OverlayFrame, ScopeFrame, Variable, VirtualPath};
|
|
use crate::ast::Block;
|
|
use crate::Module;
|
|
|
|
use std::sync::Arc;
|
|
|
|
#[cfg(feature = "plugin")]
|
|
use crate::RegisteredPlugin;
|
|
|
|
/// A delta (or change set) between the current global state and a possible future global state. Deltas
|
|
/// can be applied to the global state to update it to contain both previous state and the state held
|
|
/// within the delta.
|
|
pub struct StateDelta {
|
|
pub(super) files: Vec<CachedFile>,
|
|
pub(super) virtual_paths: Vec<(String, VirtualPath)>,
|
|
pub(super) vars: Vec<Variable>, // indexed by VarId
|
|
pub(super) decls: Vec<Box<dyn Command>>, // indexed by DeclId
|
|
pub blocks: Vec<Arc<Block>>, // indexed by BlockId
|
|
pub(super) modules: Vec<Arc<Module>>, // indexed by ModuleId
|
|
pub(super) usage: Usage,
|
|
pub scope: Vec<ScopeFrame>,
|
|
#[cfg(feature = "plugin")]
|
|
pub(super) plugins_changed: bool, // marks whether plugin file should be updated
|
|
#[cfg(feature = "plugin")]
|
|
pub(super) plugins: Vec<Arc<dyn RegisteredPlugin>>,
|
|
}
|
|
|
|
impl StateDelta {
|
|
pub fn new(engine_state: &EngineState) -> Self {
|
|
let last_overlay = engine_state.last_overlay(&[]);
|
|
let scope_frame = ScopeFrame::with_empty_overlay(
|
|
engine_state.last_overlay_name(&[]).to_owned(),
|
|
last_overlay.origin,
|
|
last_overlay.prefixed,
|
|
);
|
|
|
|
StateDelta {
|
|
files: vec![],
|
|
virtual_paths: vec![],
|
|
vars: vec![],
|
|
decls: vec![],
|
|
blocks: vec![],
|
|
modules: vec![],
|
|
scope: vec![scope_frame],
|
|
usage: Usage::new(),
|
|
#[cfg(feature = "plugin")]
|
|
plugins_changed: false,
|
|
#[cfg(feature = "plugin")]
|
|
plugins: vec![],
|
|
}
|
|
}
|
|
|
|
pub fn num_files(&self) -> usize {
|
|
self.files.len()
|
|
}
|
|
|
|
pub fn num_virtual_paths(&self) -> usize {
|
|
self.virtual_paths.len()
|
|
}
|
|
|
|
pub fn num_decls(&self) -> usize {
|
|
self.decls.len()
|
|
}
|
|
|
|
pub fn num_blocks(&self) -> usize {
|
|
self.blocks.len()
|
|
}
|
|
|
|
pub fn num_modules(&self) -> usize {
|
|
self.modules.len()
|
|
}
|
|
|
|
pub fn last_scope_frame_mut(&mut self) -> &mut ScopeFrame {
|
|
self.scope
|
|
.last_mut()
|
|
.expect("internal error: missing required scope frame")
|
|
}
|
|
|
|
pub fn last_scope_frame(&self) -> &ScopeFrame {
|
|
self.scope
|
|
.last()
|
|
.expect("internal error: missing required scope frame")
|
|
}
|
|
|
|
pub fn last_overlay_mut(&mut self) -> Option<&mut OverlayFrame> {
|
|
let last_scope = self
|
|
.scope
|
|
.last_mut()
|
|
.expect("internal error: missing required scope frame");
|
|
|
|
if let Some(last_overlay_id) = last_scope.active_overlays.last() {
|
|
Some(
|
|
&mut last_scope
|
|
.overlays
|
|
.get_mut(*last_overlay_id)
|
|
.expect("internal error: missing required overlay")
|
|
.1,
|
|
)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
pub fn last_overlay(&self) -> Option<&OverlayFrame> {
|
|
let last_scope = self
|
|
.scope
|
|
.last()
|
|
.expect("internal error: missing required scope frame");
|
|
|
|
if let Some(last_overlay_id) = last_scope.active_overlays.last() {
|
|
Some(
|
|
&last_scope
|
|
.overlays
|
|
.get(*last_overlay_id)
|
|
.expect("internal error: missing required overlay")
|
|
.1,
|
|
)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
pub fn enter_scope(&mut self) {
|
|
self.scope.push(ScopeFrame::new());
|
|
}
|
|
|
|
pub fn exit_scope(&mut self) {
|
|
self.scope.pop();
|
|
}
|
|
|
|
pub fn get_file_contents(&self) -> &[CachedFile] {
|
|
&self.files
|
|
}
|
|
}
|