forked from extern/nushell
Split up nu-protocol/src/engine/engine_state.rs
(#10368)
Factor the big parts into separate files: - `state_delta.rs` - `state_working_set.rs` - smaller `usage.rs` This required adjusting the visibility of several parts. Makes `StateDelta` transparent for the module. Trying to reduce visibility in some other places
This commit is contained in:
parent
1c677c9577
commit
ef7ade59f3
File diff suppressed because it is too large
Load Diff
@ -5,6 +5,9 @@ mod engine_state;
|
||||
mod overlay;
|
||||
mod pattern_match;
|
||||
mod stack;
|
||||
mod state_delta;
|
||||
mod state_working_set;
|
||||
mod usage;
|
||||
|
||||
pub use call_info::*;
|
||||
pub use capture_block::*;
|
||||
@ -13,3 +16,5 @@ pub use engine_state::*;
|
||||
pub use overlay::*;
|
||||
pub use pattern_match::*;
|
||||
pub use stack::*;
|
||||
pub use state_delta::*;
|
||||
pub use state_working_set::*;
|
||||
|
127
crates/nu-protocol/src/engine/state_delta.rs
Normal file
127
crates/nu-protocol/src/engine/state_delta.rs
Normal file
@ -0,0 +1,127 @@
|
||||
use super::{usage::Usage, Command, EngineState, OverlayFrame, ScopeFrame, VirtualPath};
|
||||
use crate::ast::Block;
|
||||
use crate::{Module, Variable};
|
||||
|
||||
/// 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<(String, usize, usize)>,
|
||||
pub(crate) file_contents: Vec<(Vec<u8>, usize, usize)>,
|
||||
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<Block>, // indexed by BlockId
|
||||
pub(super) modules: Vec<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
|
||||
}
|
||||
|
||||
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![],
|
||||
file_contents: 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,
|
||||
}
|
||||
}
|
||||
|
||||
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) -> &[(Vec<u8>, usize, usize)] {
|
||||
&self.file_contents
|
||||
}
|
||||
}
|
1055
crates/nu-protocol/src/engine/state_working_set.rs
Normal file
1055
crates/nu-protocol/src/engine/state_working_set.rs
Normal file
File diff suppressed because it is too large
Load Diff
89
crates/nu-protocol/src/engine/usage.rs
Normal file
89
crates/nu-protocol/src/engine/usage.rs
Normal file
@ -0,0 +1,89 @@
|
||||
use crate::{ModuleId, Span};
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// Organizes usage messages for various primitives
|
||||
#[derive(Debug, Clone)]
|
||||
pub(super) struct Usage {
|
||||
// TODO: Move decl usages here
|
||||
module_comments: HashMap<ModuleId, Vec<Span>>,
|
||||
}
|
||||
|
||||
impl Usage {
|
||||
pub fn new() -> Self {
|
||||
Usage {
|
||||
module_comments: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_module_comments(&mut self, module_id: ModuleId, comments: Vec<Span>) {
|
||||
self.module_comments.insert(module_id, comments);
|
||||
}
|
||||
|
||||
pub fn get_module_comments(&self, module_id: ModuleId) -> Option<&[Span]> {
|
||||
self.module_comments.get(&module_id).map(|v| v.as_ref())
|
||||
}
|
||||
|
||||
/// Overwrite own values with the other
|
||||
pub fn merge_with(&mut self, other: Usage) {
|
||||
self.module_comments.extend(other.module_comments);
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Usage {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn build_usage(comment_lines: &[&[u8]]) -> (String, String) {
|
||||
let mut usage = String::new();
|
||||
|
||||
let mut num_spaces = 0;
|
||||
let mut first = true;
|
||||
|
||||
// Use the comments to build the usage
|
||||
for contents in comment_lines {
|
||||
let comment_line = if first {
|
||||
// Count the number of spaces still at the front, skipping the '#'
|
||||
let mut pos = 1;
|
||||
while pos < contents.len() {
|
||||
if let Some(b' ') = contents.get(pos) {
|
||||
// continue
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
pos += 1;
|
||||
}
|
||||
|
||||
num_spaces = pos;
|
||||
|
||||
first = false;
|
||||
|
||||
String::from_utf8_lossy(&contents[pos..]).to_string()
|
||||
} else {
|
||||
let mut pos = 1;
|
||||
|
||||
while pos < contents.len() && pos < num_spaces {
|
||||
if let Some(b' ') = contents.get(pos) {
|
||||
// continue
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
pos += 1;
|
||||
}
|
||||
|
||||
String::from_utf8_lossy(&contents[pos..]).to_string()
|
||||
};
|
||||
|
||||
if !usage.is_empty() {
|
||||
usage.push('\n');
|
||||
}
|
||||
usage.push_str(&comment_line);
|
||||
}
|
||||
|
||||
if let Some((brief_usage, extra_usage)) = usage.split_once("\n\n") {
|
||||
(brief_usage.to_string(), extra_usage.to_string())
|
||||
} else {
|
||||
(usage, String::default())
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user