Span ID Refactor - Step 1 (#12960)

# Description
First part of SpanID refactoring series. This PR adds a `SpanId` type
and a corresponding `span_id` field to `Expression`. Parser creating
expressions will now add them to an array in `StateWorkingSet`,
generates a corresponding ID and saves the ID to the Expression. The IDs
are not used anywhere yet.

For the rough overall plan, see
https://github.com/nushell/nushell/issues/12963.

# User-Facing Changes
Hopefully none. This is only a refactor of Nushell's internals that
shouldn't have visible side effects.

# Tests + Formatting

# After Submitting
This commit is contained in:
Jakub Žádník
2024-06-05 04:57:14 +03:00
committed by GitHub
parent b10325dff1
commit e4104d0792
14 changed files with 1029 additions and 1050 deletions

View File

@@ -8,7 +8,7 @@ use crate::{
},
eval_const::create_nu_constant,
BlockId, Category, Config, DeclId, FileId, HistoryConfig, Module, ModuleId, OverlayId,
ShellError, Signature, Span, Type, Value, VarId, VirtualPathId,
ShellError, Signature, Span, SpanId, Type, Value, VarId, VirtualPathId,
};
use fancy_regex::Regex;
use lru::LruCache;
@@ -81,6 +81,7 @@ pub struct EngineState {
// especially long, so it helps
pub(super) blocks: Arc<Vec<Arc<Block>>>,
pub(super) modules: Arc<Vec<Arc<Module>>>,
pub spans: Vec<Span>,
usage: Usage,
pub scope: ScopeFrame,
pub ctrlc: Option<Arc<AtomicBool>>,
@@ -115,6 +116,9 @@ pub const IN_VARIABLE_ID: usize = 1;
pub const ENV_VARIABLE_ID: usize = 2;
// NOTE: If you add more to this list, make sure to update the > checks based on the last in the list
// The first span is unknown span
pub const UNKNOWN_SPAN_ID: SpanId = SpanId(0);
impl EngineState {
pub fn new() -> Self {
Self {
@@ -132,6 +136,7 @@ impl EngineState {
modules: Arc::new(vec![Arc::new(Module::new(
DEFAULT_OVERLAY_NAME.as_bytes().to_vec(),
))]),
spans: vec![Span::unknown()],
usage: Usage::new(),
// make sure we have some default overlay:
scope: ScopeFrame::with_empty_overlay(
@@ -184,6 +189,7 @@ impl EngineState {
self.files.extend(delta.files);
self.virtual_paths.extend(delta.virtual_paths);
self.vars.extend(delta.vars);
self.spans.extend(delta.spans);
self.usage.merge_with(delta.usage);
// Avoid potentially cloning the Arcs if we aren't adding anything
@@ -565,6 +571,9 @@ impl EngineState {
self.modules.len()
}
pub fn num_spans(&self) -> usize {
self.spans.len()
}
pub fn print_vars(&self) {
for var in self.vars.iter().enumerate() {
println!("var{}: {:?}", var.0, var.1);
@@ -1019,6 +1028,25 @@ impl EngineState {
)));
}
}
/// Add new span and return its ID
pub fn add_span(&mut self, span: Span) -> SpanId {
self.spans.push(span);
SpanId(self.num_spans() - 1)
}
/// Get existing span
pub fn get_span(&self, span_id: SpanId) -> Span {
*self
.spans
.get(span_id.0)
.expect("internal error: missing span")
}
/// Find ID of a span (should be avoided if possible)
pub fn find_span_id(&self, span: Span) -> Option<SpanId> {
self.spans.iter().position(|sp| sp == &span).map(SpanId)
}
}
impl Default for EngineState {

View File

@@ -4,7 +4,7 @@ use crate::{
usage::Usage, CachedFile, Command, EngineState, OverlayFrame, ScopeFrame, Variable,
VirtualPath,
},
Module,
Module, Span,
};
use std::sync::Arc;
@@ -21,6 +21,7 @@ pub struct StateDelta {
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 spans: Vec<Span>, // indexed by SpanId
pub(super) usage: Usage,
pub scope: Vec<ScopeFrame>,
#[cfg(feature = "plugin")]
@@ -45,6 +46,7 @@ impl StateDelta {
decls: vec![],
blocks: vec![],
modules: vec![],
spans: vec![],
scope: vec![scope_frame],
usage: Usage::new(),
#[cfg(feature = "plugin")]

View File

@@ -5,7 +5,7 @@ use crate::{
StateDelta, Variable, VirtualPath, Visibility,
},
BlockId, Category, Config, DeclId, FileId, Module, ModuleId, ParseError, ParseWarning, Span,
Type, Value, VarId, VirtualPathId,
SpanId, Type, Value, VarId, VirtualPathId,
};
use core::panic;
use std::{
@@ -1013,6 +1013,25 @@ impl<'a> StateWorkingSet<'a> {
.expect("internal error: missing virtual path")
}
}
pub fn add_span(&mut self, span: Span) -> SpanId {
let num_permanent_spans = self.permanent_state.spans.len();
self.delta.spans.push(span);
SpanId(num_permanent_spans + self.delta.spans.len() - 1)
}
pub fn get_span(&self, span_id: SpanId) -> Span {
let num_permanent_spans = self.permanent_state.num_spans();
if span_id.0 < num_permanent_spans {
self.permanent_state.get_span(span_id)
} else {
*self
.delta
.spans
.get(span_id.0 - num_permanent_spans)
.expect("internal error: missing span")
}
}
}
impl<'a> miette::SourceCode for &StateWorkingSet<'a> {