Remove old alias implementation (#8797)

This commit is contained in:
Jakub Žádník 2023-04-07 21:09:38 +03:00 committed by GitHub
parent d881481758
commit 1b677f167e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 387 additions and 1818 deletions

View File

@ -34,7 +34,7 @@ pub fn evaluate_commands(
let mut working_set = StateWorkingSet::new(engine_state); let mut working_set = StateWorkingSet::new(engine_state);
let output = parse(&mut working_set, None, commands.item.as_bytes(), false, &[]); let output = parse(&mut working_set, None, commands.item.as_bytes(), false);
if let Some(err) = working_set.parse_errors.first() { if let Some(err) = working_set.parse_errors.first() {
report_error(&working_set, err); report_error(&working_set, err);

View File

@ -88,7 +88,7 @@ impl CommandCompletion {
let filter_predicate = |command: &[u8]| match_algorithm.matches_u8(command, partial); let filter_predicate = |command: &[u8]| match_algorithm.matches_u8(command, partial);
let results = working_set let mut results = working_set
.find_commands_by_predicate(filter_predicate) .find_commands_by_predicate(filter_predicate)
.into_iter() .into_iter()
.map(move |x| Suggestion { .map(move |x| Suggestion {
@ -97,20 +97,8 @@ impl CommandCompletion {
extra: None, extra: None,
span: reedline::Span::new(span.start - offset, span.end - offset), span: reedline::Span::new(span.start - offset, span.end - offset),
append_whitespace: true, append_whitespace: true,
}); })
.collect::<Vec<_>>();
let results_aliases = working_set
.find_aliases_by_predicate(filter_predicate)
.into_iter()
.map(move |x| Suggestion {
value: String::from_utf8_lossy(&x).to_string(),
description: None,
extra: None,
span: reedline::Span::new(span.start - offset, span.end - offset),
append_whitespace: true,
});
let mut results = results.chain(results_aliases).collect::<Vec<_>>();
let partial = working_set.get_span_contents(span); let partial = working_set.get_span_contents(span);
let partial = String::from_utf8_lossy(partial).to_string(); let partial = String::from_utf8_lossy(partial).to_string();

View File

@ -113,14 +113,13 @@ impl NuCompleter {
fn completion_helper(&mut self, line: &str, pos: usize) -> Vec<Suggestion> { fn completion_helper(&mut self, line: &str, pos: usize) -> Vec<Suggestion> {
let mut working_set = StateWorkingSet::new(&self.engine_state); let mut working_set = StateWorkingSet::new(&self.engine_state);
let offset = working_set.next_span_start(); let offset = working_set.next_span_start();
let (mut new_line, alias_offset) = try_find_alias(line.as_bytes(), &working_set);
let initial_line = line.to_string(); let initial_line = line.to_string();
let alias_total_offset: usize = alias_offset.iter().sum(); let mut line = line.to_string();
new_line.insert(alias_total_offset + pos, b'a'); line.insert(pos, 'a');
let pos = offset + pos; let pos = offset + pos;
let config = self.engine_state.get_config(); let config = self.engine_state.get_config();
let output = parse(&mut working_set, Some("completer"), &new_line, false, &[]); let output = parse(&mut working_set, Some("completer"), line.as_bytes(), false);
for pipeline in output.pipelines.into_iter() { for pipeline in output.pipelines.into_iter() {
for pipeline_element in pipeline.elements { for pipeline_element in pipeline.elements {
@ -131,7 +130,6 @@ impl NuCompleter {
| PipelineElement::Or(_, expr) | PipelineElement::Or(_, expr)
| PipelineElement::SeparateRedirection { out: (_, expr), .. } => { | PipelineElement::SeparateRedirection { out: (_, expr), .. } => {
let flattened: Vec<_> = flatten_expression(&working_set, &expr); let flattened: Vec<_> = flatten_expression(&working_set, &expr);
let span_offset: usize = alias_offset.iter().sum();
let mut spans: Vec<String> = vec![]; let mut spans: Vec<String> = vec![];
for (flat_idx, flat) in flattened.iter().enumerate() { for (flat_idx, flat) in flattened.iter().enumerate() {
@ -154,24 +152,17 @@ impl NuCompleter {
} }
// Complete based on the last span // Complete based on the last span
if pos + span_offset >= flat.0.start && pos + span_offset < flat.0.end { if pos >= flat.0.start && pos < flat.0.end {
// Context variables // Context variables
let most_left_var = let most_left_var =
most_left_variable(flat_idx, &working_set, flattened.clone()); most_left_variable(flat_idx, &working_set, flattened.clone());
// Create a new span // Create a new span
let new_span = if flat_idx == 0 { let new_span = Span::new(flat.0.start, flat.0.end - 1);
Span::new(flat.0.start, flat.0.end - 1 - span_offset)
} else {
Span::new(
flat.0.start - span_offset,
flat.0.end - 1 - span_offset,
)
};
// Parses the prefix. Completion should look up to the cursor position, not after. // Parses the prefix. Completion should look up to the cursor position, not after.
let mut prefix = working_set.get_span_contents(flat.0).to_vec(); let mut prefix = working_set.get_span_contents(flat.0).to_vec();
let index = pos - (flat.0.start - span_offset); let index = pos - flat.0.start;
prefix.drain(index..); prefix.drain(index..);
// Variables completion // Variables completion
@ -391,85 +382,6 @@ impl ReedlineCompleter for NuCompleter {
} }
} }
type MatchedAlias = Vec<(Vec<u8>, Vec<u8>)>;
// Handler the completion when giving lines contains at least one alias. (e.g: `g checkout`)
// that `g` is an alias of `git`
fn try_find_alias(line: &[u8], working_set: &StateWorkingSet) -> (Vec<u8>, Vec<usize>) {
// An vector represents the offsets of alias
// e.g: the offset is 2 for the alias `g` of `git`
let mut alias_offset = vec![];
let mut output = vec![];
if let Some(matched_alias) = search_alias(line, working_set) {
let mut lens = matched_alias.len();
for (input_vec, line_vec) in matched_alias {
alias_offset.push(line_vec.len() - input_vec.len());
output.extend(line_vec);
if lens > 1 {
output.push(b' ');
lens -= 1;
}
}
if !line.is_empty() {
let last = line.last().expect("input is empty");
if last == &b' ' {
output.push(b' ');
}
}
} else {
output = line.to_vec();
}
(output, alias_offset)
}
fn search_alias(input: &[u8], working_set: &StateWorkingSet) -> Option<MatchedAlias> {
let mut vec_names = vec![];
let mut vec_alias = vec![];
let mut pos = 0;
let mut is_alias = false;
for (index, character) in input.iter().enumerate() {
if *character == b' ' {
let range = &input[pos..index];
vec_names.push(range.to_owned());
pos = index + 1;
}
}
// Push the rest to names vector.
if pos < input.len() {
vec_names.push(input[pos..].to_owned());
}
for name in &vec_names {
if let Some(alias_id) = working_set.find_alias(&name[..]) {
let alias_span = working_set.get_alias(alias_id);
let mut span_vec = vec![];
is_alias = true;
for alias in alias_span {
let name = working_set.get_span_contents(*alias);
if !name.is_empty() {
span_vec.push(name);
}
}
// Join span of vector together for complex alias, e.g: `f` is an alias for `git remote -v`
let full_aliases = span_vec.join(&[b' '][..]);
vec_alias.push(full_aliases);
} else {
vec_alias.push(name.to_owned());
}
}
if is_alias {
// Zip names and alias vectors, the original inputs and its aliases mapping.
// e.g:(['g'], ['g','i','t'])
let output = vec_names.into_iter().zip(vec_alias).collect();
Some(output)
} else {
None
}
}
// reads the most left variable returning it's name (e.g: $myvar) // reads the most left variable returning it's name (e.g: $myvar)
// and the depth (a.b.c) // and the depth (a.b.c)
fn most_left_variable( fn most_left_variable(

View File

@ -96,7 +96,7 @@ pub fn evaluate_file(
let mut working_set = StateWorkingSet::new(engine_state); let mut working_set = StateWorkingSet::new(engine_state);
trace!("parsing file: {}", file_path_str); trace!("parsing file: {}", file_path_str);
let _ = parse(&mut working_set, Some(file_path_str), &file, false, &[]); let _ = parse(&mut working_set, Some(file_path_str), &file, false);
if working_set.find_decl(b"main", &Type::Any).is_some() { if working_set.find_decl(b"main", &Type::Any).is_some() {
let args = format!("main {}", args.join(" ")); let args = format!("main {}", args.join(" "));

View File

@ -102,7 +102,6 @@ pub(crate) fn add_menus(
Some(name), // format!("entry #{}", entry_num) Some(name), // format!("entry #{}", entry_num)
definition.as_bytes(), definition.as_bytes(),
true, true,
&[],
); );
(output, working_set.render()) (output, working_set.render())

View File

@ -789,7 +789,7 @@ pub fn eval_string_with_input(
) -> Result<Value, ShellError> { ) -> Result<Value, ShellError> {
let (block, delta) = { let (block, delta) = {
let mut working_set = StateWorkingSet::new(engine_state); let mut working_set = StateWorkingSet::new(engine_state);
let output = parse(&mut working_set, None, source.as_bytes(), false, &[]); let output = parse(&mut working_set, None, source.as_bytes(), false);
(output, working_set.render()) (output, working_set.render())
}; };

View File

@ -18,7 +18,7 @@ impl Highlighter for NuHighlighter {
trace!("highlighting: {}", line); trace!("highlighting: {}", line);
let mut working_set = StateWorkingSet::new(&self.engine_state); let mut working_set = StateWorkingSet::new(&self.engine_state);
let block = parse(&mut working_set, None, line.as_bytes(), false, &[]); let block = parse(&mut working_set, None, line.as_bytes(), false);
let (shapes, global_span_offset) = { let (shapes, global_span_offset) = {
let shapes = flatten_block(&working_set, &block); let shapes = flatten_block(&working_set, &block);
(shapes, self.engine_state.next_span_start()) (shapes, self.engine_state.next_span_start())

View File

@ -222,7 +222,6 @@ pub fn eval_source(
Some(fname), // format!("entry #{}", entry_num) Some(fname), // format!("entry #{}", entry_num)
source, source,
false, false,
&[],
); );
if let Some(err) = working_set.parse_errors.first() { if let Some(err) = working_set.parse_errors.first() {
set_last_exit_code(stack, 1); set_last_exit_code(stack, 1);

View File

@ -13,7 +13,7 @@ pub struct NuValidator {
impl Validator for NuValidator { impl Validator for NuValidator {
fn validate(&self, line: &str) -> ValidationResult { fn validate(&self, line: &str) -> ValidationResult {
let mut working_set = StateWorkingSet::new(&self.engine_state); let mut working_set = StateWorkingSet::new(&self.engine_state);
parse(&mut working_set, None, line.as_bytes(), false, &[]); parse(&mut working_set, None, line.as_bytes(), false);
if matches!( if matches!(
working_set.parse_errors.first(), working_set.parse_errors.first(),

View File

@ -663,7 +663,7 @@ fn run_external_completion(block: &str, input: &str) -> Vec<Suggestion> {
let (dir, _, mut engine_state, mut stack) = new_engine(); let (dir, _, mut engine_state, mut stack) = new_engine();
let (_, delta) = { let (_, delta) = {
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let block = parse(&mut working_set, None, block.as_bytes(), false, &[]); let block = parse(&mut working_set, None, block.as_bytes(), false);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
(block, working_set.render()) (block, working_set.render())

View File

@ -146,7 +146,7 @@ pub fn merge_input(
let (block, delta) = { let (block, delta) = {
let mut working_set = StateWorkingSet::new(engine_state); let mut working_set = StateWorkingSet::new(engine_state);
let block = parse(&mut working_set, None, input, false, &[]); let block = parse(&mut working_set, None, input, false);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());

View File

@ -7,7 +7,6 @@ use nu_protocol::{
span, Category, Example, IntoInterruptiblePipelineData, IntoPipelineData, PipelineData, span, Category, Example, IntoInterruptiblePipelineData, IntoPipelineData, PipelineData,
ShellError, Signature, Span, Spanned, SyntaxShape, Type, Value, ShellError, Signature, Span, Spanned, SyntaxShape, Type, Value,
}; };
use std::borrow::Cow;
#[derive(Clone)] #[derive(Clone)]
pub struct HelpAliases; pub struct HelpAliases;
@ -112,22 +111,24 @@ pub fn help_aliases(
name.push_str(&r.item); name.push_str(&r.item);
} }
let alias_id = if let Some(id) = engine_state.find_alias(name.as_bytes(), &[]) { let alias = if let Some(id) = engine_state.find_decl(name.as_bytes(), &[]) {
id if let Some(alias) = engine_state.get_decl(id).as_alias() {
alias
} else {
return Err(ShellError::AliasNotFound(span(
&rest.iter().map(|r| r.span).collect::<Vec<Span>>(),
)));
}
} else { } else {
return Err(ShellError::AliasNotFound(span( return Err(ShellError::AliasNotFound(span(
&rest.iter().map(|r| r.span).collect::<Vec<Span>>(), &rest.iter().map(|r| r.span).collect::<Vec<Span>>(),
))); )));
}; };
let alias_expansion = engine_state let alias_expansion =
.get_alias(alias_id) String::from_utf8_lossy(engine_state.get_span_contents(&alias.wrapped_call.span));
.iter() let usage = alias.usage();
.map(|span| String::from_utf8_lossy(engine_state.get_span_contents(span))) let extra_usage = alias.extra_usage();
.collect::<Vec<Cow<str>>>()
.join(" ");
let alias_usage = engine_state.build_alias_usage(alias_id);
// TODO: merge this into documentation.rs at some point // TODO: merge this into documentation.rs at some point
const G: &str = "\x1b[32m"; // green const G: &str = "\x1b[32m"; // green
@ -136,14 +137,12 @@ pub fn help_aliases(
let mut long_desc = String::new(); let mut long_desc = String::new();
if let Some((usage, extra_usage)) = alias_usage { long_desc.push_str(usage);
long_desc.push_str(&usage); long_desc.push_str("\n\n");
long_desc.push_str("\n\n");
if !extra_usage.is_empty() { if !extra_usage.is_empty() {
long_desc.push_str(&extra_usage); long_desc.push_str(extra_usage);
long_desc.push_str("\n\n"); long_desc.push_str("\n\n");
}
} }
long_desc.push_str(&format!("{G}Alias{RESET}: {C}{name}{RESET}")); long_desc.push_str(&format!("{G}Alias{RESET}: {C}{name}{RESET}"));
@ -165,7 +164,7 @@ pub fn help_aliases(
fn build_help_aliases(engine_state: &EngineState, stack: &Stack, span: Span) -> Vec<Value> { fn build_help_aliases(engine_state: &EngineState, stack: &Stack, span: Span) -> Vec<Value> {
let mut scope_data = ScopeData::new(engine_state, stack); let mut scope_data = ScopeData::new(engine_state, stack);
scope_data.populate_aliases(); scope_data.populate_all();
scope_data.collect_aliases(span) scope_data.collect_aliases(span)
} }

View File

@ -4,8 +4,8 @@ use nu_engine::{scope::ScopeData, CallExt};
use nu_protocol::{ use nu_protocol::{
ast::Call, ast::Call,
engine::{Command, EngineState, Stack}, engine::{Command, EngineState, Stack},
span, AliasId, Category, DeclId, Example, IntoInterruptiblePipelineData, IntoPipelineData, span, Category, DeclId, Example, IntoInterruptiblePipelineData, IntoPipelineData, PipelineData,
PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Type, Value, ShellError, Signature, Span, Spanned, SyntaxShape, Type, Value,
}; };
#[derive(Clone)] #[derive(Clone)]
@ -152,9 +152,16 @@ pub fn help_modules(
long_desc.push_str("\n\n"); long_desc.push_str("\n\n");
if !module.decls.is_empty() || module.main.is_some() { if !module.decls.is_empty() || module.main.is_some() {
let commands: Vec<(Vec<u8>, DeclId)> = engine_state.get_decls_sorted(false).collect(); let commands: Vec<(Vec<u8>, DeclId)> = engine_state
.get_decls_sorted(false)
.filter(|(_, id)| !engine_state.get_decl(*id).is_alias())
.collect();
let mut module_commands = module.decls(); let mut module_commands: Vec<(Vec<u8>, DeclId)> = module
.decls()
.into_iter()
.filter(|(_, id)| !engine_state.get_decl(*id).is_alias())
.collect();
module_commands.sort_by(|a, b| a.0.cmp(&b.0)); module_commands.sort_by(|a, b| a.0.cmp(&b.0));
let commands_str = module_commands let commands_str = module_commands
@ -181,15 +188,18 @@ pub fn help_modules(
long_desc.push_str("\n\n"); long_desc.push_str("\n\n");
} }
if !module.aliases.is_empty() { if !module.decls.is_empty() {
let aliases: Vec<(Vec<u8>, AliasId)> = engine_state.get_aliases_sorted(false).collect(); let aliases: Vec<(Vec<u8>, DeclId)> = engine_state
.get_decls_sorted(false)
let mut module_aliases: Vec<(&[u8], AliasId)> = module .filter(|(_, id)| engine_state.get_decl(*id).is_alias())
.aliases
.iter()
.map(|(name, id)| (name.as_ref(), *id))
.collect(); .collect();
module_aliases.sort_by(|a, b| a.0.cmp(b.0));
let mut module_aliases: Vec<(Vec<u8>, DeclId)> = module
.decls()
.into_iter()
.filter(|(_, id)| engine_state.get_decl(*id).is_alias())
.collect();
module_aliases.sort_by(|a, b| a.0.cmp(&b.0));
let aliases_str = module_aliases let aliases_str = module_aliases
.iter() .iter()
@ -198,7 +208,7 @@ pub fn help_modules(
if let Some((used_name_bytes, _)) = if let Some((used_name_bytes, _)) =
aliases.iter().find(|(_, alias_id)| id == alias_id) aliases.iter().find(|(_, alias_id)| id == alias_id)
{ {
if engine_state.find_alias(name.as_bytes(), &[]).is_some() { if engine_state.find_decl(name.as_bytes(), &[]).is_some() {
format!("{CB}{name}{RESET}") format!("{CB}{name}{RESET}")
} else { } else {
let alias_name = String::from_utf8_lossy(used_name_bytes); let alias_name = String::from_utf8_lossy(used_name_bytes);

View File

@ -126,7 +126,7 @@ fn eval_pipeline_without_terminal_expression(
pub fn parse(contents: &str, engine_state: &EngineState) -> (Block, StateDelta) { pub fn parse(contents: &str, engine_state: &EngineState) -> (Block, StateDelta) {
let mut working_set = StateWorkingSet::new(engine_state); let mut working_set = StateWorkingSet::new(engine_state);
let output = nu_parser::parse(&mut working_set, None, contents.as_bytes(), false, &[]); let output = nu_parser::parse(&mut working_set, None, contents.as_bytes(), false);
if let Some(err) = working_set.parse_errors.first() { if let Some(err) = working_set.parse_errors.first() {
panic!("test parse error in `{contents}`: {err:?}") panic!("test parse error in `{contents}`: {err:?}")

View File

@ -50,13 +50,7 @@ pub fn test_dataframe(cmds: Vec<Box<dyn Command + 'static>>) {
let (block, delta) = { let (block, delta) = {
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let output = parse( let output = parse(&mut working_set, None, example.example.as_bytes(), false);
&mut working_set,
None,
example.example.as_bytes(),
false,
&[],
);
if let Some(err) = working_set.parse_errors.first() { if let Some(err) = working_set.parse_errors.first() {
panic!("test parse error in `{}`: {:?}", example.example, err) panic!("test parse error in `{}`: {:?}", example.example, err)

View File

@ -41,7 +41,7 @@ impl Command for Ast {
let pipeline: Spanned<String> = call.req(engine_state, stack, 0)?; let pipeline: Spanned<String> = call.req(engine_state, stack, 0)?;
let mut working_set = StateWorkingSet::new(engine_state); let mut working_set = StateWorkingSet::new(engine_state);
let block_output = parse(&mut working_set, None, pipeline.item.as_bytes(), false, &[]); let block_output = parse(&mut working_set, None, pipeline.item.as_bytes(), false);
let error_output = working_set.parse_errors.first(); let error_output = working_set.parse_errors.first();

View File

@ -1,4 +1,3 @@
use itertools::Itertools;
use nu_engine::CallExt; use nu_engine::CallExt;
use nu_protocol::ast::Call; use nu_protocol::ast::Call;
use nu_protocol::engine::{Command, EngineState, Stack}; use nu_protocol::engine::{Command, EngineState, Stack};
@ -133,15 +132,6 @@ impl Command for ViewSource {
Vec::new(), Vec::new(),
)) ))
} }
} else if let Some(alias_id) = engine_state.find_alias(val.as_bytes(), &[]) {
let contents = &mut engine_state.get_alias(alias_id).iter().map(|span| {
String::from_utf8_lossy(engine_state.get_span_contents(span)).to_string()
});
Ok(Value::String {
val: contents.join(" "),
span: call.head,
}
.into_pipeline_data())
} else { } else {
Err(ShellError::GenericError( Err(ShellError::GenericError(
"Cannot view value".to_string(), "Cannot view value".to_string(),

View File

@ -65,8 +65,7 @@ impl Command for FromNuon {
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let mut block = let mut block = nu_parser::parse(&mut working_set, None, string_input.as_bytes(), false);
nu_parser::parse(&mut working_set, None, string_input.as_bytes(), false, &[]);
if let Some(pipeline) = block.pipelines.get(1) { if let Some(pipeline) = block.pipelines.get(1) {
if let Some(element) = pipeline.elements.get(0) { if let Some(element) = pipeline.elements.get(0) {

View File

@ -167,7 +167,7 @@ pub fn eval_hook(
} }
let output = let output =
parse(&mut working_set, Some("hook"), val.as_bytes(), false, &[]); parse(&mut working_set, Some("hook"), val.as_bytes(), false);
if let Some(err) = working_set.parse_errors.first() { if let Some(err) = working_set.parse_errors.first() {
report_error(&working_set, err); report_error(&working_set, err);

View File

@ -290,7 +290,7 @@ fn format_record(
} }
} }
FormatOperation::ValueNeedEval(_col_name, span) => { FormatOperation::ValueNeedEval(_col_name, span) => {
let exp = parse_expression(working_set, &[*span], &[], false); let exp = parse_expression(working_set, &[*span], false);
match working_set.parse_errors.first() { match working_set.parse_errors.first() {
None => { None => {
let parsed_result = eval_expression(engine_state, stack, &exp); let parsed_result = eval_expression(engine_state, stack, &exp);

View File

@ -320,7 +320,7 @@ fn parse_module(
let new_span = Span::new(start, end); let new_span = Span::new(start, end);
let starting_error_count = working_set.parse_errors.len(); let starting_error_count = working_set.parse_errors.len();
parse_module_block(working_set, new_span, filename.as_bytes(), &[]); parse_module_block(working_set, new_span, filename.as_bytes());
if starting_error_count != working_set.parse_errors.len() { if starting_error_count != working_set.parse_errors.len() {
if is_debug { if is_debug {
@ -354,7 +354,7 @@ fn parse_script(
span: Span, span: Span,
) -> Result<PipelineData, ShellError> { ) -> Result<PipelineData, ShellError> {
let starting_error_count = working_set.parse_errors.len(); let starting_error_count = working_set.parse_errors.len();
parse(working_set, filename, contents, false, &[]); parse(working_set, filename, contents, false);
if starting_error_count != working_set.parse_errors.len() { if starting_error_count != working_set.parse_errors.len() {
let msg = format!( let msg = format!(
r#"Found : {}"#, r#"Found : {}"#,

View File

@ -1,4 +1,3 @@
use itertools::Itertools;
use log::trace; use log::trace;
use nu_engine::env; use nu_engine::env;
use nu_engine::CallExt; use nu_engine::CallExt;
@ -74,27 +73,6 @@ fn entry(arg: impl Into<String>, path: impl Into<String>, builtin: bool, span: S
Value::Record { cols, vals, span } Value::Record { cols, vals, span }
} }
fn get_entry_in_aliases(engine_state: &EngineState, name: &str, span: Span) -> Option<Value> {
if let Some(alias_id) = engine_state.find_alias(name.as_bytes(), &[]) {
let alias = engine_state.get_alias(alias_id);
let alias_str = alias
.iter()
.map(|alias_span| String::from_utf8_lossy(engine_state.get_span_contents(alias_span)))
.join(" ");
trace!("Found alias: {}", name);
Some(entry(
name,
format!("Nushell alias: {alias_str}"),
false,
span,
))
} else {
None
}
}
fn get_entry_in_commands(engine_state: &EngineState, name: &str, span: Span) -> Option<Value> { fn get_entry_in_commands(engine_state: &EngineState, name: &str, span: Span) -> Option<Value> {
if let Some(decl_id) = engine_state.find_decl(name.as_bytes(), &[]) { if let Some(decl_id) = engine_state.find_decl(name.as_bytes(), &[]) {
let (msg, is_builtin) = if engine_state.get_decl(decl_id).is_custom_command() { let (msg, is_builtin) = if engine_state.get_decl(decl_id).is_custom_command() {
@ -119,10 +97,6 @@ fn get_entries_in_nu(
) -> Vec<Value> { ) -> Vec<Value> {
let mut all_entries = vec![]; let mut all_entries = vec![];
if let Some(ent) = get_entry_in_aliases(engine_state, name, span) {
all_entries.push(ent);
}
if !all_entries.is_empty() && skip_after_first_found { if !all_entries.is_empty() && skip_after_first_found {
return all_entries; return all_entries;
} }

View File

@ -5,8 +5,6 @@ use quickcheck_macros::quickcheck;
mod commands; mod commands;
mod format_conversions; mod format_conversions;
// use nu_engine::EvaluationContext;
#[quickcheck] #[quickcheck]
fn quickcheck_parse(data: String) -> bool { fn quickcheck_parse(data: String) -> bool {
let (tokens, err) = nu_parser::lex(data.as_bytes(), 0, b"", b"", true); let (tokens, err) = nu_parser::lex(data.as_bytes(), 0, b"", b"", true);
@ -17,7 +15,7 @@ fn quickcheck_parse(data: String) -> bool {
let mut working_set = StateWorkingSet::new(&context); let mut working_set = StateWorkingSet::new(&context);
working_set.add_file("quickcheck".into(), data.as_bytes()); working_set.add_file("quickcheck".into(), data.as_bytes());
let _ = nu_parser::parse_block(&mut working_set, &tokens, false, &[], false); let _ = nu_parser::parse_block(&mut working_set, &tokens, false, false);
} }
} }
true true

View File

@ -52,8 +52,7 @@ pub struct ScopeData<'e, 's> {
engine_state: &'e EngineState, engine_state: &'e EngineState,
stack: &'s Stack, stack: &'s Stack,
vars_map: HashMap<&'e Vec<u8>, &'e usize>, vars_map: HashMap<&'e Vec<u8>, &'e usize>,
commands_map: HashMap<&'e (Vec<u8>, Type), &'e usize>, decls_map: HashMap<&'e (Vec<u8>, Type), &'e usize>,
aliases_map: HashMap<&'e Vec<u8>, &'e usize>,
modules_map: HashMap<&'e Vec<u8>, &'e usize>, modules_map: HashMap<&'e Vec<u8>, &'e usize>,
visibility: Visibility, visibility: Visibility,
} }
@ -64,8 +63,7 @@ impl<'e, 's> ScopeData<'e, 's> {
engine_state, engine_state,
stack, stack,
vars_map: HashMap::new(), vars_map: HashMap::new(),
commands_map: HashMap::new(), decls_map: HashMap::new(),
aliases_map: HashMap::new(),
modules_map: HashMap::new(), modules_map: HashMap::new(),
visibility: Visibility::new(), visibility: Visibility::new(),
} }
@ -74,19 +72,12 @@ impl<'e, 's> ScopeData<'e, 's> {
pub fn populate_all(&mut self) { pub fn populate_all(&mut self) {
for overlay_frame in self.engine_state.active_overlays(&[]) { for overlay_frame in self.engine_state.active_overlays(&[]) {
self.vars_map.extend(&overlay_frame.vars); self.vars_map.extend(&overlay_frame.vars);
self.commands_map.extend(&overlay_frame.decls); self.decls_map.extend(&overlay_frame.decls);
self.aliases_map.extend(&overlay_frame.aliases);
self.modules_map.extend(&overlay_frame.modules); self.modules_map.extend(&overlay_frame.modules);
self.visibility.merge_with(overlay_frame.visibility.clone()); self.visibility.merge_with(overlay_frame.visibility.clone());
} }
} }
pub fn populate_aliases(&mut self) {
for overlay_frame in self.engine_state.active_overlays(&[]) {
self.aliases_map.extend(&overlay_frame.aliases);
}
}
pub fn populate_modules(&mut self) { pub fn populate_modules(&mut self) {
for overlay_frame in self.engine_state.active_overlays(&[]) { for overlay_frame in self.engine_state.active_overlays(&[]) {
self.modules_map.extend(&overlay_frame.modules); self.modules_map.extend(&overlay_frame.modules);
@ -117,8 +108,10 @@ impl<'e, 's> ScopeData<'e, 's> {
pub fn collect_commands(&self, span: Span) -> Vec<Value> { pub fn collect_commands(&self, span: Span) -> Vec<Value> {
let mut commands = vec![]; let mut commands = vec![];
for ((command_name, _), decl_id) in &self.commands_map { for ((command_name, _), decl_id) in &self.decls_map {
if self.visibility.is_decl_id_visible(decl_id) { if self.visibility.is_decl_id_visible(decl_id)
&& !self.engine_state.get_decl(**decl_id).is_alias()
{
let mut cols = vec![]; let mut cols = vec![];
let mut vals = vec![]; let mut vals = vec![];
@ -465,7 +458,7 @@ impl<'e, 's> ScopeData<'e, 's> {
pub fn collect_externs(&self, span: Span) -> Vec<Value> { pub fn collect_externs(&self, span: Span) -> Vec<Value> {
let mut externals = vec![]; let mut externals = vec![];
for ((command_name, _), decl_id) in &self.commands_map { for ((command_name, _), decl_id) in &self.decls_map {
let decl = self.engine_state.get_decl(**decl_id); let decl = self.engine_state.get_decl(**decl_id);
if decl.is_known_external() { if decl.is_known_external() {
@ -511,36 +504,6 @@ impl<'e, 's> ScopeData<'e, 's> {
pub fn collect_aliases(&self, span: Span) -> Vec<Value> { pub fn collect_aliases(&self, span: Span) -> Vec<Value> {
let mut aliases = vec![]; let mut aliases = vec![];
for (alias_name, alias_id) in &self.aliases_map {
if self.visibility.is_alias_id_visible(alias_id) {
let alias = self.engine_state.get_alias(**alias_id);
let mut alias_text = String::new();
for span in alias {
let contents = self.engine_state.get_span_contents(span);
if !alias_text.is_empty() {
alias_text.push(' ');
}
alias_text.push_str(&String::from_utf8_lossy(contents));
}
let alias_usage = self
.engine_state
.build_alias_usage(**alias_id)
.map(|(usage, _)| usage)
.unwrap_or_default();
aliases.push(Value::Record {
cols: vec!["name".into(), "expansion".into(), "usage".into()],
vals: vec![
Value::string(String::from_utf8_lossy(alias_name), span),
Value::string(alias_text, span),
Value::string(alias_usage, span),
],
span,
});
}
}
for (name_bytes, decl_id) in self.engine_state.get_decls_sorted(false) { for (name_bytes, decl_id) in self.engine_state.get_decls_sorted(false) {
if self.visibility.is_decl_id_visible(&decl_id) { if self.visibility.is_decl_id_visible(&decl_id) {
let decl = self.engine_state.get_decl(decl_id); let decl = self.engine_state.get_decl(decl_id);
@ -585,13 +548,21 @@ impl<'e, 's> ScopeData<'e, 's> {
let export_commands: Vec<Value> = module let export_commands: Vec<Value> = module
.decls() .decls()
.iter() .iter()
.filter(|(_, id)| {
self.visibility.is_decl_id_visible(id)
&& !self.engine_state.get_decl(*id).is_alias()
})
.map(|(bytes, _)| Value::string(String::from_utf8_lossy(bytes), span)) .map(|(bytes, _)| Value::string(String::from_utf8_lossy(bytes), span))
.collect(); .collect();
let export_aliases: Vec<Value> = module let export_aliases: Vec<Value> = module
.aliases .decls()
.keys() .iter()
.map(|bytes| Value::string(String::from_utf8_lossy(bytes), span)) .filter(|(_, id)| {
self.visibility.is_decl_id_visible(id)
&& self.engine_state.get_decl(*id).is_alias()
})
.map(|(bytes, _)| Value::string(String::from_utf8_lossy(bytes), span))
.collect(); .collect();
let export_env_block = module.env_block.map_or_else( let export_env_block = module.env_block.map_or_else(
@ -640,8 +611,7 @@ impl<'e, 's> ScopeData<'e, 's> {
let engine_state_cols = vec![ let engine_state_cols = vec![
"source_bytes".to_string(), "source_bytes".to_string(),
"num_vars".to_string(), "num_vars".to_string(),
"num_commands".to_string(), "num_decls".to_string(),
"num_aliases".to_string(),
"num_blocks".to_string(), "num_blocks".to_string(),
"num_modules".to_string(), "num_modules".to_string(),
"num_env_vars".to_string(), "num_env_vars".to_string(),
@ -651,7 +621,6 @@ impl<'e, 's> ScopeData<'e, 's> {
Value::int(self.engine_state.next_span_start() as i64, span), Value::int(self.engine_state.next_span_start() as i64, span),
Value::int(self.engine_state.num_vars() as i64, span), Value::int(self.engine_state.num_vars() as i64, span),
Value::int(self.engine_state.num_decls() as i64, span), Value::int(self.engine_state.num_decls() as i64, span),
Value::int(self.engine_state.num_aliases() as i64, span),
Value::int(self.engine_state.num_blocks() as i64, span), Value::int(self.engine_state.num_blocks() as i64, span),
Value::int(self.engine_state.num_modules() as i64, span), Value::int(self.engine_state.num_modules() as i64, span),
Value::int( Value::int(

View File

@ -60,7 +60,6 @@ fn eval_source2(
Some(fname), // format!("entry #{}", entry_num) Some(fname), // format!("entry #{}", entry_num)
source, source,
false, false,
&[],
); );
if let Some(err) = working_set.parse_errors.first() { if let Some(err) = working_set.parse_errors.first() {

File diff suppressed because it is too large Load Diff

View File

@ -49,7 +49,7 @@ pub fn parse_pattern(working_set: &mut StateWorkingSet, span: Span) -> MatchPatt
} }
} else { } else {
// Literal value // Literal value
let value = parse_value(working_set, span, &SyntaxShape::Any, &[]); let value = parse_value(working_set, span, &SyntaxShape::Any);
MatchPattern { MatchPattern {
pattern: Pattern::Value(value), pattern: Pattern::Value(value),

File diff suppressed because it is too large Load Diff

View File

@ -53,7 +53,7 @@ fn test_int(
let engine_state = EngineState::new(); let engine_state = EngineState::new();
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let block = parse(&mut working_set, None, test, true, &[]); let block = parse(&mut working_set, None, test, true);
let err = working_set.parse_errors.first(); let err = working_set.parse_errors.first();
@ -267,7 +267,7 @@ fn test_parse_any() {
let engine_state = EngineState::new(); let engine_state = EngineState::new();
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let block = parse(&mut working_set, None, test, true, &[]); let block = parse(&mut working_set, None, test, true);
match (block, working_set.parse_errors.first()) { match (block, working_set.parse_errors.first()) {
(_, Some(e)) => { (_, Some(e)) => {
@ -283,7 +283,7 @@ pub fn parse_int() {
let engine_state = EngineState::new(); let engine_state = EngineState::new();
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let block = parse(&mut working_set, None, b"3", true, &[]); let block = parse(&mut working_set, None, b"3", true);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
assert_eq!(block.len(), 1); assert_eq!(block.len(), 1);
@ -306,7 +306,7 @@ pub fn parse_int_with_underscores() {
let engine_state = EngineState::new(); let engine_state = EngineState::new();
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let block = parse(&mut working_set, None, b"420_69_2023", true, &[]); let block = parse(&mut working_set, None, b"420_69_2023", true);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
assert_eq!(block.len(), 1); assert_eq!(block.len(), 1);
@ -336,7 +336,7 @@ pub fn parse_cell_path() {
false, false,
); );
let block = parse(&mut working_set, None, b"$foo.bar.baz", true, &[]); let block = parse(&mut working_set, None, b"$foo.bar.baz", true);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
assert_eq!(block.len(), 1); assert_eq!(block.len(), 1);
@ -390,7 +390,7 @@ pub fn parse_cell_path_optional() {
false, false,
); );
let block = parse(&mut working_set, None, b"$foo.bar?.baz", true, &[]); let block = parse(&mut working_set, None, b"$foo.bar?.baz", true);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
@ -438,7 +438,7 @@ pub fn parse_binary_with_hex_format() {
let engine_state = EngineState::new(); let engine_state = EngineState::new();
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let block = parse(&mut working_set, None, b"0x[13]", true, &[]); let block = parse(&mut working_set, None, b"0x[13]", true);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
assert_eq!(block.len(), 1); assert_eq!(block.len(), 1);
@ -456,7 +456,7 @@ pub fn parse_binary_with_incomplete_hex_format() {
let engine_state = EngineState::new(); let engine_state = EngineState::new();
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let block = parse(&mut working_set, None, b"0x[3]", true, &[]); let block = parse(&mut working_set, None, b"0x[3]", true);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
assert_eq!(block.len(), 1); assert_eq!(block.len(), 1);
@ -474,7 +474,7 @@ pub fn parse_binary_with_binary_format() {
let engine_state = EngineState::new(); let engine_state = EngineState::new();
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let block = parse(&mut working_set, None, b"0b[1010 1000]", true, &[]); let block = parse(&mut working_set, None, b"0b[1010 1000]", true);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
assert_eq!(block.len(), 1); assert_eq!(block.len(), 1);
@ -492,7 +492,7 @@ pub fn parse_binary_with_incomplete_binary_format() {
let engine_state = EngineState::new(); let engine_state = EngineState::new();
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let block = parse(&mut working_set, None, b"0b[10]", true, &[]); let block = parse(&mut working_set, None, b"0b[10]", true);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
assert_eq!(block.len(), 1); assert_eq!(block.len(), 1);
@ -510,7 +510,7 @@ pub fn parse_binary_with_octal_format() {
let engine_state = EngineState::new(); let engine_state = EngineState::new();
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let block = parse(&mut working_set, None, b"0o[250]", true, &[]); let block = parse(&mut working_set, None, b"0o[250]", true);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
assert_eq!(block.len(), 1); assert_eq!(block.len(), 1);
@ -528,7 +528,7 @@ pub fn parse_binary_with_incomplete_octal_format() {
let engine_state = EngineState::new(); let engine_state = EngineState::new();
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let block = parse(&mut working_set, None, b"0o[2]", true, &[]); let block = parse(&mut working_set, None, b"0o[2]", true);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
assert_eq!(block.len(), 1); assert_eq!(block.len(), 1);
@ -546,7 +546,7 @@ pub fn parse_binary_with_invalid_octal_format() {
let engine_state = EngineState::new(); let engine_state = EngineState::new();
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let block = parse(&mut working_set, None, b"0b[90]", true, &[]); let block = parse(&mut working_set, None, b"0b[90]", true);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
assert_eq!(block.len(), 1); assert_eq!(block.len(), 1);
@ -566,7 +566,7 @@ pub fn parse_binary_with_multi_byte_char() {
// found using fuzzing, Rust can panic if you slice into this string // found using fuzzing, Rust can panic if you slice into this string
let contents = b"0x[\xEF\xBF\xBD]"; let contents = b"0x[\xEF\xBF\xBD]";
let block = parse(&mut working_set, None, contents, true, &[]); let block = parse(&mut working_set, None, contents, true);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
assert_eq!(block.len(), 1); assert_eq!(block.len(), 1);
@ -587,7 +587,7 @@ pub fn parse_call() {
let sig = Signature::build("foo").named("--jazz", SyntaxShape::Int, "jazz!!", Some('j')); let sig = Signature::build("foo").named("--jazz", SyntaxShape::Int, "jazz!!", Some('j'));
working_set.add_decl(sig.predeclare()); working_set.add_decl(sig.predeclare());
let block = parse(&mut working_set, None, b"foo", true, &[]); let block = parse(&mut working_set, None, b"foo", true);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
assert_eq!(block.len(), 1); assert_eq!(block.len(), 1);
@ -615,7 +615,7 @@ pub fn parse_call_missing_flag_arg() {
let sig = Signature::build("foo").named("jazz", SyntaxShape::Int, "jazz!!", Some('j')); let sig = Signature::build("foo").named("jazz", SyntaxShape::Int, "jazz!!", Some('j'));
working_set.add_decl(sig.predeclare()); working_set.add_decl(sig.predeclare());
parse(&mut working_set, None, b"foo --jazz", true, &[]); parse(&mut working_set, None, b"foo --jazz", true);
assert!(matches!( assert!(matches!(
working_set.parse_errors.first(), working_set.parse_errors.first(),
Some(ParseError::MissingFlagParam(..)) Some(ParseError::MissingFlagParam(..))
@ -630,7 +630,7 @@ pub fn parse_call_missing_short_flag_arg() {
let sig = Signature::build("foo").named("--jazz", SyntaxShape::Int, "jazz!!", Some('j')); let sig = Signature::build("foo").named("--jazz", SyntaxShape::Int, "jazz!!", Some('j'));
working_set.add_decl(sig.predeclare()); working_set.add_decl(sig.predeclare());
parse(&mut working_set, None, b"foo -j", true, &[]); parse(&mut working_set, None, b"foo -j", true);
assert!(matches!( assert!(matches!(
working_set.parse_errors.first(), working_set.parse_errors.first(),
Some(ParseError::MissingFlagParam(..)) Some(ParseError::MissingFlagParam(..))
@ -646,7 +646,7 @@ pub fn parse_call_too_many_shortflag_args() {
.named("--jazz", SyntaxShape::Int, "jazz!!", Some('j')) .named("--jazz", SyntaxShape::Int, "jazz!!", Some('j'))
.named("--math", SyntaxShape::Int, "math!!", Some('m')); .named("--math", SyntaxShape::Int, "math!!", Some('m'));
working_set.add_decl(sig.predeclare()); working_set.add_decl(sig.predeclare());
parse(&mut working_set, None, b"foo -mj", true, &[]); parse(&mut working_set, None, b"foo -mj", true);
assert!(matches!( assert!(matches!(
working_set.parse_errors.first(), working_set.parse_errors.first(),
Some(ParseError::ShortFlagBatchCantTakeArg(..)) Some(ParseError::ShortFlagBatchCantTakeArg(..))
@ -660,7 +660,7 @@ pub fn parse_call_unknown_shorthand() {
let sig = Signature::build("foo").switch("--jazz", "jazz!!", Some('j')); let sig = Signature::build("foo").switch("--jazz", "jazz!!", Some('j'));
working_set.add_decl(sig.predeclare()); working_set.add_decl(sig.predeclare());
parse(&mut working_set, None, b"foo -mj", true, &[]); parse(&mut working_set, None, b"foo -mj", true);
assert!(matches!( assert!(matches!(
working_set.parse_errors.first(), working_set.parse_errors.first(),
Some(ParseError::UnknownFlag(..)) Some(ParseError::UnknownFlag(..))
@ -674,7 +674,7 @@ pub fn parse_call_extra_positional() {
let sig = Signature::build("foo").switch("--jazz", "jazz!!", Some('j')); let sig = Signature::build("foo").switch("--jazz", "jazz!!", Some('j'));
working_set.add_decl(sig.predeclare()); working_set.add_decl(sig.predeclare());
parse(&mut working_set, None, b"foo -j 100", true, &[]); parse(&mut working_set, None, b"foo -j 100", true);
assert!(matches!( assert!(matches!(
working_set.parse_errors.first(), working_set.parse_errors.first(),
Some(ParseError::ExtraPositional(..)) Some(ParseError::ExtraPositional(..))
@ -688,7 +688,7 @@ pub fn parse_call_missing_req_positional() {
let sig = Signature::build("foo").required("jazz", SyntaxShape::Int, "jazz!!"); let sig = Signature::build("foo").required("jazz", SyntaxShape::Int, "jazz!!");
working_set.add_decl(sig.predeclare()); working_set.add_decl(sig.predeclare());
parse(&mut working_set, None, b"foo", true, &[]); parse(&mut working_set, None, b"foo", true);
assert!(matches!( assert!(matches!(
working_set.parse_errors.first(), working_set.parse_errors.first(),
Some(ParseError::MissingPositional(..)) Some(ParseError::MissingPositional(..))
@ -702,7 +702,7 @@ pub fn parse_call_missing_req_flag() {
let sig = Signature::build("foo").required_named("--jazz", SyntaxShape::Int, "jazz!!", None); let sig = Signature::build("foo").required_named("--jazz", SyntaxShape::Int, "jazz!!", None);
working_set.add_decl(sig.predeclare()); working_set.add_decl(sig.predeclare());
parse(&mut working_set, None, b"foo", true, &[]); parse(&mut working_set, None, b"foo", true);
assert!(matches!( assert!(matches!(
working_set.parse_errors.first(), working_set.parse_errors.first(),
Some(ParseError::MissingRequiredFlag(..)) Some(ParseError::MissingRequiredFlag(..))
@ -713,7 +713,7 @@ pub fn parse_call_missing_req_flag() {
fn test_nothing_comparison_eq() { fn test_nothing_comparison_eq() {
let engine_state = EngineState::new(); let engine_state = EngineState::new();
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let block = parse(&mut working_set, None, b"2 == null", true, &[]); let block = parse(&mut working_set, None, b"2 == null", true);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
assert_eq!(block.len(), 1); assert_eq!(block.len(), 1);
@ -736,7 +736,7 @@ fn test_nothing_comparison_eq() {
fn test_nothing_comparison_neq() { fn test_nothing_comparison_neq() {
let engine_state = EngineState::new(); let engine_state = EngineState::new();
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let block = parse(&mut working_set, None, b"2 != null", true, &[]); let block = parse(&mut working_set, None, b"2 != null", true);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
assert_eq!(block.len(), 1); assert_eq!(block.len(), 1);
@ -763,7 +763,7 @@ mod string {
let engine_state = EngineState::new(); let engine_state = EngineState::new();
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let block = parse(&mut working_set, None, b"\"hello nushell\"", true, &[]); let block = parse(&mut working_set, None, b"\"hello nushell\"", true);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
assert_eq!(block.len(), 1); assert_eq!(block.len(), 1);
@ -786,7 +786,7 @@ mod string {
let engine_state = EngineState::new(); let engine_state = EngineState::new();
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let block = parse(&mut working_set, None, b"$\"hello (39 + 3)\"", true, &[]); let block = parse(&mut working_set, None, b"$\"hello (39 + 3)\"", true);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
assert_eq!(block.len(), 1); assert_eq!(block.len(), 1);
@ -818,7 +818,7 @@ mod string {
let engine_state = EngineState::new(); let engine_state = EngineState::new();
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let block = parse(&mut working_set, None, b"$\"hello \\(39 + 3)\"", true, &[]); let block = parse(&mut working_set, None, b"$\"hello \\(39 + 3)\"", true);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
@ -849,13 +849,7 @@ mod string {
let engine_state = EngineState::new(); let engine_state = EngineState::new();
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let block = parse( let block = parse(&mut working_set, None, b"$\"hello \\\\(39 + 3)\"", true);
&mut working_set,
None,
b"$\"hello \\\\(39 + 3)\"",
true,
&[],
);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
@ -888,13 +882,7 @@ mod string {
let engine_state = EngineState::new(); let engine_state = EngineState::new();
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let block = parse( let block = parse(&mut working_set, None, b"$\"\\(1 + 3)\\(7 - 5)\"", true);
&mut working_set,
None,
b"$\"\\(1 + 3)\\(7 - 5)\"",
true,
&[],
);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
@ -938,7 +926,6 @@ mod string {
$"(($foo))" $"(($foo))"
"#, "#,
true, true,
&[],
); );
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
@ -963,7 +950,6 @@ mod string {
$"Hello ($foo.bar)" $"Hello ($foo.bar)"
"#, "#,
true, true,
&[],
); );
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
@ -1008,7 +994,7 @@ mod range {
let engine_state = EngineState::new(); let engine_state = EngineState::new();
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let block = parse(&mut working_set, None, phrase, true, &[]); let block = parse(&mut working_set, None, phrase, true);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
assert_eq!(block.len(), 1, "{tag}: block length"); assert_eq!(block.len(), 1, "{tag}: block length");
@ -1067,7 +1053,7 @@ mod range {
working_set.add_decl(Box::new(Let)); working_set.add_decl(Box::new(Let));
let block = parse(&mut working_set, None, phrase, true, &[]); let block = parse(&mut working_set, None, phrase, true);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
assert_eq!(block.len(), 2, "{tag} block len 2"); assert_eq!(block.len(), 2, "{tag} block len 2");
@ -1113,7 +1099,7 @@ mod range {
let engine_state = EngineState::new(); let engine_state = EngineState::new();
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let block = parse(&mut working_set, None, phrase, true, &[]); let block = parse(&mut working_set, None, phrase, true);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
assert_eq!(block.len(), 1, "{tag}: block len 1"); assert_eq!(block.len(), 1, "{tag}: block len 1");
@ -1159,7 +1145,7 @@ mod range {
let engine_state = EngineState::new(); let engine_state = EngineState::new();
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let block = parse(&mut working_set, None, phrase, true, &[]); let block = parse(&mut working_set, None, phrase, true);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
assert_eq!(block.len(), 1, "{tag}: block len 1"); assert_eq!(block.len(), 1, "{tag}: block len 1");
@ -1205,7 +1191,7 @@ mod range {
let engine_state = EngineState::new(); let engine_state = EngineState::new();
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let block = parse(&mut working_set, None, phrase, true, &[]); let block = parse(&mut working_set, None, phrase, true);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
assert_eq!(block.len(), 1, "{tag}: block length 1"); assert_eq!(block.len(), 1, "{tag}: block length 1");
@ -1243,7 +1229,7 @@ mod range {
let engine_state = EngineState::new(); let engine_state = EngineState::new();
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let _ = parse(&mut working_set, None, b"(0)..\"a\"", true, &[]); let _ = parse(&mut working_set, None, b"(0)..\"a\"", true);
assert!(!working_set.parse_errors.is_empty()); assert!(!working_set.parse_errors.is_empty());
} }
@ -1566,7 +1552,7 @@ mod input_types {
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let input = r#"ls | to-custom | group-by name other"#; let input = r#"ls | to-custom | group-by name other"#;
let block = parse(&mut working_set, None, input.as_bytes(), true, &[]); let block = parse(&mut working_set, None, input.as_bytes(), true);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
assert_eq!(block.len(), 1); assert_eq!(block.len(), 1);
@ -1630,7 +1616,7 @@ mod input_types {
let input = let input =
r#"let a = (ls | to-custom | group-by name other); let b = (1+3); $a | agg sum"#; r#"let a = (ls | to-custom | group-by name other); let b = (1+3); $a | agg sum"#;
let block = parse(&mut working_set, None, input.as_bytes(), true, &[]); let block = parse(&mut working_set, None, input.as_bytes(), true);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
assert_eq!(block.len(), 3); assert_eq!(block.len(), 3);
@ -1661,7 +1647,7 @@ mod input_types {
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let input = r#"let a = (ls | to-custom | group-by name other); ($a + $a) | agg sum"#; let input = r#"let a = (ls | to-custom | group-by name other); ($a + $a) | agg sum"#;
let block = parse(&mut working_set, None, input.as_bytes(), true, &[]); let block = parse(&mut working_set, None, input.as_bytes(), true);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
assert_eq!(block.len(), 2); assert_eq!(block.len(), 2);
@ -1693,7 +1679,7 @@ mod input_types {
let input = r#" let input = r#"
let a = (ls | to-custom | group-by name other); [1 2 3] | to-custom; [1 2 3] | to-custom"#; let a = (ls | to-custom | group-by name other); [1 2 3] | to-custom; [1 2 3] | to-custom"#;
let block = parse(&mut working_set, None, input.as_bytes(), true, &[]); let block = parse(&mut working_set, None, input.as_bytes(), true);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
assert_eq!(block.len(), 3); assert_eq!(block.len(), 3);
@ -1737,7 +1723,7 @@ mod input_types {
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let input = r#"ls | group-by name"#; let input = r#"ls | group-by name"#;
let block = parse(&mut working_set, None, input.as_bytes(), true, &[]); let block = parse(&mut working_set, None, input.as_bytes(), true);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
assert_eq!(block.len(), 1); assert_eq!(block.len(), 1);
@ -1782,7 +1768,7 @@ mod input_types {
let (block, delta) = { let (block, delta) = {
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let input = r#"ls | to-custom | group-by name other | agg ("b" | min)"#; let input = r#"ls | to-custom | group-by name other | agg ("b" | min)"#;
let block = parse(&mut working_set, None, input.as_bytes(), true, &[]); let block = parse(&mut working_set, None, input.as_bytes(), true);
(block, working_set.render()) (block, working_set.render())
}; };
@ -1843,7 +1829,7 @@ mod input_types {
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let input = r#"[[a b]; [1 2] [3 4]] | to-custom | with-column [ ("a" | min) ("b" | min) ] | collect"#; let input = r#"[[a b]; [1 2] [3 4]] | to-custom | with-column [ ("a" | min) ("b" | min) ] | collect"#;
let block = parse(&mut working_set, None, input.as_bytes(), true, &[]); let block = parse(&mut working_set, None, input.as_bytes(), true);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
assert_eq!(block.len(), 1); assert_eq!(block.len(), 1);
@ -1897,7 +1883,7 @@ mod input_types {
]; ];
for input in inputs { for input in inputs {
let block = parse(&mut working_set, None, input.as_bytes(), true, &[]); let block = parse(&mut working_set, None, input.as_bytes(), true);
assert!(working_set.parse_errors.is_empty()); assert!(working_set.parse_errors.is_empty());
assert_eq!(block.len(), 2, "testing: {input}"); assert_eq!(block.len(), 2, "testing: {input}");
@ -1915,7 +1901,6 @@ mod input_types {
None, None,
b"if false { 'a' } else { $foo }", b"if false { 'a' } else { $foo }",
true, true,
&[],
); );
assert!(matches!( assert!(matches!(
@ -1935,7 +1920,6 @@ mod input_types {
None, None,
b"if false { 'a' } else $foo { 'b' }", b"if false { 'a' } else $foo { 'b' }",
true, true,
&[],
); );
assert!(matches!( assert!(matches!(

View File

@ -14,7 +14,7 @@ pub fn do_test(test: &[u8], expected: &str, error_contains: Option<&str>) {
let engine_state = EngineState::new(); let engine_state = EngineState::new();
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let block = parse(&mut working_set, None, test, true, &[]); let block = parse(&mut working_set, None, test, true);
match working_set.parse_errors.first() { match working_set.parse_errors.first() {
None => { None => {

View File

@ -3,7 +3,7 @@ use lru::LruCache;
use super::{Command, EnvVars, OverlayFrame, ScopeFrame, Stack, Visibility, DEFAULT_OVERLAY_NAME}; use super::{Command, EnvVars, OverlayFrame, ScopeFrame, Stack, Visibility, DEFAULT_OVERLAY_NAME};
use crate::{ use crate::{
ast::Block, AliasId, BlockId, Config, DeclId, Example, Module, ModuleId, OverlayId, ShellError, ast::Block, BlockId, Config, DeclId, Example, Module, ModuleId, OverlayId, ShellError,
Signature, Span, Type, VarId, Variable, Signature, Span, Type, VarId, Variable,
}; };
use crate::{ParseError, Value}; use crate::{ParseError, Value};
@ -26,37 +26,26 @@ static PWD_ENV: &str = "PWD";
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Usage { pub struct Usage {
// TODO: Move decl usages here // TODO: Move decl usages here
alias_comments: HashMap<AliasId, Vec<Span>>,
module_comments: HashMap<ModuleId, Vec<Span>>, module_comments: HashMap<ModuleId, Vec<Span>>,
} }
impl Usage { impl Usage {
pub fn new() -> Self { pub fn new() -> Self {
Usage { Usage {
alias_comments: HashMap::new(),
module_comments: HashMap::new(), module_comments: HashMap::new(),
} }
} }
pub fn add_alias_comments(&mut self, alias_id: AliasId, comments: Vec<Span>) {
self.alias_comments.insert(alias_id, comments);
}
pub fn add_module_comments(&mut self, module_id: ModuleId, comments: Vec<Span>) { pub fn add_module_comments(&mut self, module_id: ModuleId, comments: Vec<Span>) {
self.module_comments.insert(module_id, comments); self.module_comments.insert(module_id, comments);
} }
pub fn get_alias_comments(&self, alias_id: AliasId) -> Option<&[Span]> {
self.alias_comments.get(&alias_id).map(|v| v.as_ref())
}
pub fn get_module_comments(&self, module_id: ModuleId) -> Option<&[Span]> { pub fn get_module_comments(&self, module_id: ModuleId) -> Option<&[Span]> {
self.module_comments.get(&module_id).map(|v| v.as_ref()) self.module_comments.get(&module_id).map(|v| v.as_ref())
} }
/// Overwrite own values with the other /// Overwrite own values with the other
pub fn merge_with(&mut self, other: Usage) { pub fn merge_with(&mut self, other: Usage) {
self.alias_comments.extend(other.alias_comments);
self.module_comments.extend(other.module_comments); self.module_comments.extend(other.module_comments);
} }
} }
@ -115,7 +104,6 @@ pub struct EngineState {
file_contents: Vec<(Vec<u8>, usize, usize)>, file_contents: Vec<(Vec<u8>, usize, usize)>,
vars: Vec<Variable>, vars: Vec<Variable>,
decls: Vec<Box<dyn Command + 'static>>, decls: Vec<Box<dyn Command + 'static>>,
aliases: Vec<Vec<Span>>,
blocks: Vec<Block>, blocks: Vec<Block>,
modules: Vec<Module>, modules: Vec<Module>,
usage: Usage, usage: Usage,
@ -164,7 +152,6 @@ impl EngineState {
Variable::new(Span::new(0, 0), Type::Any, false), Variable::new(Span::new(0, 0), Type::Any, false),
], ],
decls: vec![], decls: vec![],
aliases: vec![],
blocks: vec![], blocks: vec![],
modules: vec![Module::new(DEFAULT_OVERLAY_NAME.as_bytes().to_vec())], modules: vec![Module::new(DEFAULT_OVERLAY_NAME.as_bytes().to_vec())],
usage: Usage::new(), usage: Usage::new(),
@ -210,7 +197,6 @@ impl EngineState {
self.files.extend(delta.files); self.files.extend(delta.files);
self.file_contents.extend(delta.file_contents); self.file_contents.extend(delta.file_contents);
self.decls.extend(delta.decls); self.decls.extend(delta.decls);
self.aliases.extend(delta.aliases);
self.vars.extend(delta.vars); self.vars.extend(delta.vars);
self.blocks.extend(delta.blocks); self.blocks.extend(delta.blocks);
self.modules.extend(delta.modules); self.modules.extend(delta.modules);
@ -235,9 +221,6 @@ impl EngineState {
for item in delta_overlay.constants.into_iter() { for item in delta_overlay.constants.into_iter() {
existing_overlay.constants.insert(item.0, item.1); existing_overlay.constants.insert(item.0, item.1);
} }
for item in delta_overlay.aliases.into_iter() {
existing_overlay.aliases.insert(item.0, item.1);
}
for item in delta_overlay.modules.into_iter() { for item in delta_overlay.modules.into_iter() {
existing_overlay.modules.insert(item.0, item.1); existing_overlay.modules.insert(item.0, item.1);
} }
@ -568,10 +551,6 @@ impl EngineState {
self.decls.len() self.decls.len()
} }
pub fn num_aliases(&self) -> usize {
self.aliases.len()
}
pub fn num_blocks(&self) -> usize { pub fn num_blocks(&self) -> usize {
self.blocks.len() self.blocks.len()
} }
@ -639,26 +618,6 @@ impl EngineState {
None None
} }
pub fn find_alias(&self, name: &[u8], removed_overlays: &[Vec<u8>]) -> Option<AliasId> {
let mut visibility: Visibility = Visibility::new();
for overlay_frame in self.active_overlays(removed_overlays).iter().rev() {
visibility.append(&overlay_frame.visibility);
if let Some(alias_id) = overlay_frame.aliases.get(name) {
if visibility.is_alias_id_visible(alias_id) {
return Some(*alias_id);
}
}
}
None
}
pub fn get_alias_comments(&self, alias_id: AliasId) -> Option<&[Span]> {
self.usage.get_alias_comments(alias_id)
}
pub fn get_module_comments(&self, module_id: ModuleId) -> Option<&[Span]> { pub fn get_module_comments(&self, module_id: ModuleId) -> Option<&[Span]> {
self.usage.get_module_comments(module_id) self.usage.get_module_comments(module_id)
} }
@ -733,20 +692,6 @@ impl EngineState {
output output
} }
pub fn find_aliases_by_predicate(&self, predicate: impl Fn(&[u8]) -> bool) -> Vec<Vec<u8>> {
let mut output = vec![];
for overlay_frame in self.active_overlays(&[]).iter().rev() {
for alias in &overlay_frame.aliases {
if overlay_frame.visibility.is_alias_id_visible(alias.1) && predicate(alias.0) {
output.push(alias.0.clone());
}
}
}
output
}
pub fn find_constant(&self, var_id: VarId, removed_overlays: &[Vec<u8>]) -> Option<&Value> { pub fn find_constant(&self, var_id: VarId, removed_overlays: &[Vec<u8>]) -> Option<&Value> {
for overlay_frame in self.active_overlays(removed_overlays).iter().rev() { for overlay_frame in self.active_overlays(removed_overlays).iter().rev() {
if let Some(val) = overlay_frame.constants.get(&var_id) { if let Some(val) = overlay_frame.constants.get(&var_id) {
@ -787,41 +732,6 @@ impl EngineState {
.expect("internal error: missing declaration") .expect("internal error: missing declaration")
} }
pub fn get_alias(&self, alias_id: AliasId) -> &[Span] {
self.aliases
.get(alias_id)
.expect("internal error: missing alias")
.as_ref()
}
/// Get all aliases within scope, sorted by the alias names
pub fn get_aliases_sorted(
&self,
include_hidden: bool,
) -> impl Iterator<Item = (Vec<u8>, DeclId)> {
let mut aliases_map = HashMap::new();
for overlay_frame in self.active_overlays(&[]) {
let new_aliases = if include_hidden {
overlay_frame.aliases.clone()
} else {
overlay_frame
.aliases
.clone()
.into_iter()
.filter(|(_, id)| overlay_frame.visibility.is_alias_id_visible(id))
.collect()
};
aliases_map.extend(new_aliases);
}
let mut aliases: Vec<(Vec<u8>, DeclId)> = aliases_map.into_iter().collect();
aliases.sort_by(|a, b| a.0.cmp(&b.0));
aliases.into_iter()
}
/// Get all commands within scope, sorted by the commands' names /// Get all commands within scope, sorted by the commands' names
pub fn get_decls_sorted( pub fn get_decls_sorted(
&self, &self,
@ -992,11 +902,6 @@ impl EngineState {
build_usage(&comment_lines) build_usage(&comment_lines)
} }
pub fn build_alias_usage(&self, alias_id: AliasId) -> Option<(String, String)> {
self.get_alias_comments(alias_id)
.map(|comment_spans| self.build_usage(comment_spans))
}
pub fn build_module_usage(&self, module_id: ModuleId) -> Option<(String, String)> { pub fn build_module_usage(&self, module_id: ModuleId) -> Option<(String, String)> {
self.get_module_comments(module_id) self.get_module_comments(module_id)
.map(|comment_spans| self.build_usage(comment_spans)) .map(|comment_spans| self.build_usage(comment_spans))
@ -1094,7 +999,6 @@ pub struct StateDelta {
pub(crate) file_contents: Vec<(Vec<u8>, usize, usize)>, pub(crate) file_contents: Vec<(Vec<u8>, usize, usize)>,
vars: Vec<Variable>, // indexed by VarId vars: Vec<Variable>, // indexed by VarId
decls: Vec<Box<dyn Command>>, // indexed by DeclId decls: Vec<Box<dyn Command>>, // indexed by DeclId
aliases: Vec<Vec<Span>>, // indexed by AliasId
pub blocks: Vec<Block>, // indexed by BlockId pub blocks: Vec<Block>, // indexed by BlockId
modules: Vec<Module>, // indexed by ModuleId modules: Vec<Module>, // indexed by ModuleId
usage: Usage, usage: Usage,
@ -1117,7 +1021,6 @@ impl StateDelta {
file_contents: vec![], file_contents: vec![],
vars: vec![], vars: vec![],
decls: vec![], decls: vec![],
aliases: vec![],
blocks: vec![], blocks: vec![],
modules: vec![], modules: vec![],
scope: vec![scope_frame], scope: vec![scope_frame],
@ -1135,10 +1038,6 @@ impl StateDelta {
self.decls.len() self.decls.len()
} }
pub fn num_aliases(&self) -> usize {
self.aliases.len()
}
pub fn num_blocks(&self) -> usize { pub fn num_blocks(&self) -> usize {
self.blocks.len() self.blocks.len()
} }
@ -1235,10 +1134,6 @@ impl<'a> StateWorkingSet<'a> {
self.delta.num_decls() + self.permanent_state.num_decls() self.delta.num_decls() + self.permanent_state.num_decls()
} }
pub fn num_aliases(&self) -> usize {
self.delta.num_aliases() + self.permanent_state.num_aliases()
}
pub fn num_blocks(&self) -> usize { pub fn num_blocks(&self) -> usize {
self.delta.num_blocks() + self.permanent_state.num_blocks() self.delta.num_blocks() + self.permanent_state.num_blocks()
} }
@ -1295,15 +1190,6 @@ impl<'a> StateWorkingSet<'a> {
} }
} }
pub fn use_aliases(&mut self, aliases: Vec<(Vec<u8>, AliasId)>) {
let overlay_frame = self.last_overlay_mut();
for (name, alias_id) in aliases {
overlay_frame.aliases.insert(name, alias_id);
overlay_frame.visibility.use_alias_id(&alias_id);
}
}
pub fn add_predecl(&mut self, decl: Box<dyn Command>) -> Option<DeclId> { pub fn add_predecl(&mut self, decl: Box<dyn Command>) -> Option<DeclId> {
let name = decl.name().as_bytes().to_vec(); let name = decl.name().as_bytes().to_vec();
@ -1389,109 +1275,12 @@ impl<'a> StateWorkingSet<'a> {
None None
} }
pub fn use_alias(&mut self, alias_id: &AliasId) {
let mut removed_overlays = vec![];
let mut visibility: Visibility = Visibility::new();
// Since we can mutate scope frames in delta, remove the id directly
for scope_frame in self.delta.scope.iter_mut().rev() {
for overlay_id in scope_frame
.active_overlay_ids(&mut removed_overlays)
.iter()
.rev()
{
let overlay_frame = scope_frame.get_overlay_mut(*overlay_id);
visibility.append(&overlay_frame.visibility);
if !visibility.is_alias_id_visible(alias_id) {
// Use alias only if it's already hidden
overlay_frame.visibility.use_alias_id(alias_id);
return;
}
}
}
// We cannot mutate the permanent state => store the information in the current scope frame
// for scope in self.permanent_state.scope.iter().rev() {
for overlay_frame in self
.permanent_state
.active_overlays(&removed_overlays)
.iter()
.rev()
{
visibility.append(&overlay_frame.visibility);
if !visibility.is_alias_id_visible(alias_id) {
// Hide alias only if it's not already hidden
self.last_overlay_mut().visibility.use_alias_id(alias_id);
return;
}
}
}
pub fn hide_alias(&mut self, name: &[u8]) -> Option<AliasId> {
let mut removed_overlays = vec![];
let mut visibility: Visibility = Visibility::new();
// Since we can mutate scope frames in delta, remove the id directly
for scope_frame in self.delta.scope.iter_mut().rev() {
for overlay_id in scope_frame
.active_overlay_ids(&mut removed_overlays)
.iter()
.rev()
{
let overlay_frame = scope_frame.get_overlay_mut(*overlay_id);
visibility.append(&overlay_frame.visibility);
if let Some(alias_id) = overlay_frame.aliases.get(name) {
if visibility.is_alias_id_visible(alias_id) {
// Hide alias only if it's not already hidden
overlay_frame.visibility.hide_alias_id(alias_id);
return Some(*alias_id);
}
}
}
}
// We cannot mutate the permanent state => store the information in the current scope frame
// for scope in self.permanent_state.scope.iter().rev() {
for overlay_frame in self
.permanent_state
.active_overlays(&removed_overlays)
.iter()
.rev()
{
visibility.append(&overlay_frame.visibility);
if let Some(alias_id) = overlay_frame.aliases.get(name) {
if visibility.is_alias_id_visible(alias_id) {
// Hide alias only if it's not already hidden
self.last_overlay_mut().visibility.hide_alias_id(alias_id);
return Some(*alias_id);
}
}
}
None
}
pub fn hide_decls(&mut self, decls: &[Vec<u8>]) { pub fn hide_decls(&mut self, decls: &[Vec<u8>]) {
for decl in decls.iter() { for decl in decls.iter() {
self.hide_decl(decl); // let's assume no errors self.hide_decl(decl); // let's assume no errors
} }
} }
pub fn hide_aliases(&mut self, aliases: &[Vec<u8>]) {
for alias in aliases.iter() {
self.hide_alias(alias); // let's assume no errors
}
}
pub fn add_block(&mut self, block: Block) -> BlockId { pub fn add_block(&mut self, block: Block) -> BlockId {
self.delta.blocks.push(block); self.delta.blocks.push(block);
@ -1675,44 +1464,6 @@ impl<'a> StateWorkingSet<'a> {
None None
} }
pub fn find_alias(&self, name: &[u8]) -> Option<AliasId> {
let mut removed_overlays = vec![];
let mut visibility: Visibility = Visibility::new();
for scope_frame in self.delta.scope.iter().rev() {
for overlay_frame in scope_frame
.active_overlays(&mut removed_overlays)
.iter()
.rev()
{
visibility.append(&overlay_frame.visibility);
if let Some(alias_id) = overlay_frame.aliases.get(name) {
if visibility.is_alias_id_visible(alias_id) {
return Some(*alias_id);
}
}
}
}
for overlay_frame in self
.permanent_state
.active_overlays(&removed_overlays)
.iter()
.rev()
{
visibility.append(&overlay_frame.visibility);
if let Some(alias_id) = overlay_frame.aliases.get(name) {
if visibility.is_alias_id_visible(alias_id) {
return Some(*alias_id);
}
}
}
None
}
pub fn find_module(&self, name: &[u8]) -> Option<ModuleId> { pub fn find_module(&self, name: &[u8]) -> Option<ModuleId> {
let mut removed_overlays = vec![]; let mut removed_overlays = vec![];
@ -1848,20 +1599,6 @@ impl<'a> StateWorkingSet<'a> {
next_id next_id
} }
pub fn add_alias(&mut self, name: Vec<u8>, replacement: Vec<Span>, comments: Vec<Span>) {
self.delta.aliases.push(replacement);
let alias_id = self.num_aliases() - 1;
if !comments.is_empty() {
self.delta.usage.add_alias_comments(alias_id, comments);
}
let last = self.last_overlay_mut();
last.aliases.insert(name, alias_id);
last.visibility.use_alias_id(&alias_id);
}
pub fn get_cwd(&self) -> String { pub fn get_cwd(&self) -> String {
let pwd = self let pwd = self
.permanent_state .permanent_state
@ -1966,19 +1703,6 @@ impl<'a> StateWorkingSet<'a> {
} }
} }
pub fn get_alias(&self, alias_id: AliasId) -> &[Span] {
let num_permanent_aliases = self.permanent_state.num_aliases();
if alias_id < num_permanent_aliases {
self.permanent_state.get_alias(alias_id)
} else {
self.delta
.aliases
.get(alias_id - num_permanent_aliases)
.expect("internal error: missing alias")
.as_ref()
}
}
pub fn find_commands_by_predicate( pub fn find_commands_by_predicate(
&self, &self,
predicate: impl Fn(&[u8]) -> bool, predicate: impl Fn(&[u8]) -> bool,
@ -2006,31 +1730,6 @@ impl<'a> StateWorkingSet<'a> {
output output
} }
pub fn find_aliases_by_predicate(
&self,
predicate: impl Fn(&[u8]) -> bool + Copy,
) -> Vec<Vec<u8>> {
let mut output = vec![];
for scope_frame in self.delta.scope.iter().rev() {
for overlay_id in scope_frame.active_overlays.iter().rev() {
let overlay_frame = scope_frame.get_overlay(*overlay_id);
for alias in &overlay_frame.aliases {
if overlay_frame.visibility.is_alias_id_visible(alias.1) && predicate(alias.0) {
output.push(alias.0.clone());
}
}
}
}
let mut permanent = self.permanent_state.find_aliases_by_predicate(predicate);
output.append(&mut permanent);
output
}
pub fn get_block(&self, block_id: BlockId) -> &Block { pub fn get_block(&self, block_id: BlockId) -> &Block {
let num_permanent_blocks = self.permanent_state.num_blocks(); let num_permanent_blocks = self.permanent_state.num_blocks();
if block_id < num_permanent_blocks { if block_id < num_permanent_blocks {
@ -2134,7 +1833,7 @@ impl<'a> StateWorkingSet<'a> {
let name = self.last_overlay_name().to_vec(); let name = self.last_overlay_name().to_vec();
let origin = overlay_frame.origin; let origin = overlay_frame.origin;
let prefixed = overlay_frame.prefixed; let prefixed = overlay_frame.prefixed;
self.add_overlay(name, origin, vec![], vec![], prefixed); self.add_overlay(name, origin, vec![], prefixed);
} }
self.delta self.delta
@ -2167,37 +1866,11 @@ impl<'a> StateWorkingSet<'a> {
result result
} }
/// Collect all aliases that belong to an overlay
pub fn aliases_of_overlay(&self, name: &[u8]) -> HashMap<Vec<u8>, DeclId> {
let mut result = HashMap::new();
if let Some(overlay_id) = self.permanent_state.find_overlay(name) {
let overlay_frame = self.permanent_state.get_overlay(overlay_id);
for (alias_name, alias_id) in &overlay_frame.aliases {
result.insert(alias_name.to_owned(), *alias_id);
}
}
for scope_frame in self.delta.scope.iter() {
if let Some(overlay_id) = scope_frame.find_overlay(name) {
let overlay_frame = scope_frame.get_overlay(overlay_id);
for (alias_name, alias_id) in &overlay_frame.aliases {
result.insert(alias_name.to_owned(), *alias_id);
}
}
}
result
}
pub fn add_overlay( pub fn add_overlay(
&mut self, &mut self,
name: Vec<u8>, name: Vec<u8>,
origin: ModuleId, origin: ModuleId,
decls: Vec<(Vec<u8>, DeclId)>, decls: Vec<(Vec<u8>, DeclId)>,
aliases: Vec<(Vec<u8>, AliasId)>,
prefixed: bool, prefixed: bool,
) { ) {
let last_scope_frame = self.delta.last_scope_frame_mut(); let last_scope_frame = self.delta.last_scope_frame_mut();
@ -2225,7 +1898,6 @@ impl<'a> StateWorkingSet<'a> {
self.move_predecls_to_overlay(); self.move_predecls_to_overlay();
self.use_decls(decls); self.use_decls(decls);
self.use_aliases(aliases);
} }
pub fn remove_overlay(&mut self, name: &[u8], keep_custom: bool) { pub fn remove_overlay(&mut self, name: &[u8], keep_custom: bool) {
@ -2255,14 +1927,7 @@ impl<'a> StateWorkingSet<'a> {
.filter(|(n, _)| !origin_module.has_decl(n)) .filter(|(n, _)| !origin_module.has_decl(n))
.collect(); .collect();
let aliases = self
.aliases_of_overlay(name)
.into_iter()
.filter(|(n, _)| !origin_module.has_alias(n))
.collect();
self.use_decls(decls); self.use_decls(decls);
self.use_aliases(aliases);
} }
} }
} }

View File

@ -1,22 +1,20 @@
use crate::{AliasId, DeclId, ModuleId, OverlayId, Type, Value, VarId}; use crate::{DeclId, ModuleId, OverlayId, Type, Value, VarId};
use std::borrow::Borrow; use std::borrow::Borrow;
use std::collections::HashMap; use std::collections::HashMap;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
pub static DEFAULT_OVERLAY_NAME: &str = "zero"; pub static DEFAULT_OVERLAY_NAME: &str = "zero";
/// Tells whether a decl or alias is visible or not /// Tells whether a decl is visible or not
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Visibility { pub struct Visibility {
decl_ids: HashMap<DeclId, bool>, decl_ids: HashMap<DeclId, bool>,
alias_ids: HashMap<AliasId, bool>,
} }
impl Visibility { impl Visibility {
pub fn new() -> Self { pub fn new() -> Self {
Visibility { Visibility {
decl_ids: HashMap::new(), decl_ids: HashMap::new(),
alias_ids: HashMap::new(),
} }
} }
@ -24,30 +22,17 @@ impl Visibility {
*self.decl_ids.get(decl_id).unwrap_or(&true) // by default it's visible *self.decl_ids.get(decl_id).unwrap_or(&true) // by default it's visible
} }
pub fn is_alias_id_visible(&self, alias_id: &AliasId) -> bool {
*self.alias_ids.get(alias_id).unwrap_or(&true) // by default it's visible
}
pub fn hide_decl_id(&mut self, decl_id: &DeclId) { pub fn hide_decl_id(&mut self, decl_id: &DeclId) {
self.decl_ids.insert(*decl_id, false); self.decl_ids.insert(*decl_id, false);
} }
pub fn hide_alias_id(&mut self, alias_id: &AliasId) {
self.alias_ids.insert(*alias_id, false);
}
pub fn use_decl_id(&mut self, decl_id: &DeclId) { pub fn use_decl_id(&mut self, decl_id: &DeclId) {
self.decl_ids.insert(*decl_id, true); self.decl_ids.insert(*decl_id, true);
} }
pub fn use_alias_id(&mut self, alias_id: &AliasId) {
self.alias_ids.insert(*alias_id, true);
}
/// Overwrite own values with the other /// Overwrite own values with the other
pub fn merge_with(&mut self, other: Visibility) { pub fn merge_with(&mut self, other: Visibility) {
self.decl_ids.extend(other.decl_ids); self.decl_ids.extend(other.decl_ids);
self.alias_ids.extend(other.alias_ids);
} }
/// Take new values from the other but keep own values /// Take new values from the other but keep own values
@ -57,12 +42,6 @@ impl Visibility {
self.decl_ids.insert(*decl_id, *visible); self.decl_ids.insert(*decl_id, *visible);
} }
} }
for (alias_id, visible) in other.alias_ids.iter() {
if !self.alias_ids.contains_key(alias_id) {
self.alias_ids.insert(*alias_id, *visible);
}
}
} }
} }
@ -198,7 +177,6 @@ pub struct OverlayFrame {
pub constants: HashMap<VarId, Value>, pub constants: HashMap<VarId, Value>,
pub predecls: HashMap<Vec<u8>, DeclId>, // temporary storage for predeclarations pub predecls: HashMap<Vec<u8>, DeclId>, // temporary storage for predeclarations
pub decls: HashMap<(Vec<u8>, Type), DeclId>, pub decls: HashMap<(Vec<u8>, Type), DeclId>,
pub aliases: HashMap<Vec<u8>, AliasId>,
pub modules: HashMap<Vec<u8>, ModuleId>, pub modules: HashMap<Vec<u8>, ModuleId>,
pub visibility: Visibility, pub visibility: Visibility,
pub origin: ModuleId, // The original module the overlay was created from pub origin: ModuleId, // The original module the overlay was created from
@ -212,7 +190,6 @@ impl OverlayFrame {
constants: HashMap::new(), constants: HashMap::new(),
predecls: HashMap::new(), predecls: HashMap::new(),
decls: HashMap::new(), decls: HashMap::new(),
aliases: HashMap::new(),
modules: HashMap::new(), modules: HashMap::new(),
visibility: Visibility::new(), visibility: Visibility::new(),
origin, origin,

View File

@ -1,6 +1,5 @@
use crate::{AliasId, DeclId}; use crate::DeclId;
pub enum Exportable { pub enum Exportable {
Decl { name: Vec<u8>, id: DeclId }, Decl { name: Vec<u8>, id: DeclId },
Alias { name: Vec<u8>, id: AliasId },
} }

View File

@ -1,6 +1,5 @@
pub type VarId = usize; pub type VarId = usize;
pub type DeclId = usize; pub type DeclId = usize;
pub type AliasId = usize;
pub type BlockId = usize; pub type BlockId = usize;
pub type ModuleId = usize; pub type ModuleId = usize;
pub type OverlayId = usize; pub type OverlayId = usize;

View File

@ -1,4 +1,4 @@
use crate::{AliasId, BlockId, DeclId, Span}; use crate::{BlockId, DeclId, Span};
use indexmap::IndexMap; use indexmap::IndexMap;
@ -7,7 +7,6 @@ use indexmap::IndexMap;
pub struct Module { pub struct Module {
pub name: Vec<u8>, pub name: Vec<u8>,
pub decls: IndexMap<Vec<u8>, DeclId>, pub decls: IndexMap<Vec<u8>, DeclId>,
pub aliases: IndexMap<Vec<u8>, AliasId>,
pub env_block: Option<BlockId>, // `export-env { ... }` block pub env_block: Option<BlockId>, // `export-env { ... }` block
pub main: Option<DeclId>, // `export def main` pub main: Option<DeclId>, // `export def main`
pub span: Option<Span>, pub span: Option<Span>,
@ -18,7 +17,6 @@ impl Module {
Module { Module {
name, name,
decls: IndexMap::new(), decls: IndexMap::new(),
aliases: IndexMap::new(),
env_block: None, env_block: None,
main: None, main: None,
span: None, span: None,
@ -29,7 +27,6 @@ impl Module {
Module { Module {
name, name,
decls: IndexMap::new(), decls: IndexMap::new(),
aliases: IndexMap::new(),
env_block: None, env_block: None,
main: None, main: None,
span: Some(span), span: Some(span),
@ -40,31 +37,22 @@ impl Module {
self.decls.insert(name, decl_id) self.decls.insert(name, decl_id)
} }
pub fn add_alias(&mut self, name: Vec<u8>, alias_id: AliasId) -> Option<AliasId> {
self.aliases.insert(name, alias_id)
}
pub fn add_env_block(&mut self, block_id: BlockId) { pub fn add_env_block(&mut self, block_id: BlockId) {
self.env_block = Some(block_id); self.env_block = Some(block_id);
} }
pub fn extend(&mut self, other: &Module) { pub fn extend(&mut self, other: &Module) {
self.decls.extend(other.decls.clone()); self.decls.extend(other.decls.clone());
self.aliases.extend(other.aliases.clone());
} }
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.decls.is_empty() && self.aliases.is_empty() self.decls.is_empty()
} }
pub fn get_decl_id(&self, name: &[u8]) -> Option<DeclId> { pub fn get_decl_id(&self, name: &[u8]) -> Option<DeclId> {
self.decls.get(name).copied() self.decls.get(name).copied()
} }
pub fn get_alias_id(&self, name: &[u8]) -> Option<AliasId> {
self.aliases.get(name).copied()
}
pub fn has_decl(&self, name: &[u8]) -> bool { pub fn has_decl(&self, name: &[u8]) -> bool {
if name == self.name && self.main.is_some() { if name == self.name && self.main.is_some() {
return true; return true;
@ -73,10 +61,6 @@ impl Module {
self.decls.contains_key(name) self.decls.contains_key(name)
} }
pub fn has_alias(&self, name: &[u8]) -> bool {
self.aliases.contains_key(name)
}
pub fn decl_name_with_head(&self, name: &[u8], head: &[u8]) -> Option<Vec<u8>> { pub fn decl_name_with_head(&self, name: &[u8], head: &[u8]) -> Option<Vec<u8>> {
if self.has_decl(name) { if self.has_decl(name) {
let mut new_name = head.to_vec(); let mut new_name = head.to_vec();
@ -88,17 +72,6 @@ impl Module {
} }
} }
pub fn alias_name_with_head(&self, name: &[u8], head: &[u8]) -> Option<Vec<u8>> {
if self.has_alias(name) {
let mut new_name = head.to_vec();
new_name.push(b' ');
new_name.extend(name);
Some(new_name)
} else {
None
}
}
pub fn decls_with_head(&self, head: &[u8]) -> Vec<(Vec<u8>, DeclId)> { pub fn decls_with_head(&self, head: &[u8]) -> Vec<(Vec<u8>, DeclId)> {
let mut result: Vec<(Vec<u8>, DeclId)> = self let mut result: Vec<(Vec<u8>, DeclId)> = self
.decls .decls
@ -137,30 +110,6 @@ impl Module {
result result
} }
pub fn aliases_with_head(&self, head: &[u8]) -> Vec<(Vec<u8>, AliasId)> {
self.aliases
.iter()
.map(|(name, id)| {
let mut new_name = head.to_vec();
new_name.push(b' ');
new_name.extend(name);
(new_name, *id)
})
.collect()
}
pub fn alias_names_with_head(&self, head: &[u8]) -> Vec<Vec<u8>> {
self.aliases
.keys()
.map(|name| {
let mut new_name = head.to_vec();
new_name.push(b' ');
new_name.extend(name);
new_name
})
.collect()
}
pub fn decls(&self) -> Vec<(Vec<u8>, DeclId)> { pub fn decls(&self) -> Vec<(Vec<u8>, DeclId)> {
let mut result: Vec<(Vec<u8>, DeclId)> = self let mut result: Vec<(Vec<u8>, DeclId)> = self
.decls .decls
@ -184,15 +133,4 @@ impl Module {
result result
} }
pub fn alias_names(&self) -> Vec<Vec<u8>> {
self.aliases.keys().cloned().collect()
}
pub fn aliases(&self) -> Vec<(Vec<u8>, AliasId)> {
self.aliases
.iter()
.map(|(name, id)| (name.clone(), *id))
.collect()
}
} }

View File

@ -64,13 +64,7 @@ pub(crate) fn parse_commandline_args(
let mut working_set = StateWorkingSet::new(engine_state); let mut working_set = StateWorkingSet::new(engine_state);
working_set.add_decl(Box::new(Nu)); working_set.add_decl(Box::new(Nu));
let output = parse( let output = parse(&mut working_set, None, commandline_args.as_bytes(), false);
&mut working_set,
None,
commandline_args.as_bytes(),
false,
&[],
);
if let Some(err) = working_set.parse_errors.first() { if let Some(err) = working_set.parse_errors.first() {
report_error(&working_set, err); report_error(&working_set, err);

View File

@ -22,7 +22,7 @@ fn find_id(
location: &Value, location: &Value,
) -> Option<(Id, usize, Span)> { ) -> Option<(Id, usize, Span)> {
let offset = working_set.next_span_start(); let offset = working_set.next_span_start();
let block = parse(working_set, Some(file_path), file, false, &[]); let block = parse(working_set, Some(file_path), file, false);
let flattened = flatten_block(working_set, &block); let flattened = flatten_block(working_set, &block);
@ -78,7 +78,7 @@ pub fn check(engine_state: &mut EngineState, file_path: &String) {
if let Ok(contents) = file { if let Ok(contents) = file {
let offset = working_set.next_span_start(); let offset = working_set.next_span_start();
let block = parse(&mut working_set, Some(file_path), &contents, false, &[]); let block = parse(&mut working_set, Some(file_path), &contents, false);
for err in &working_set.parse_errors { for err in &working_set.parse_errors {
let mut span = err.span(); let mut span = err.span();

View File

@ -62,18 +62,14 @@ fn load_standard_library(
working_set.add_file(name.clone(), content); working_set.add_file(name.clone(), content);
let end = working_set.next_span_start(); let end = working_set.next_span_start();
let (_, module, comments) = parse_module_block( let (_, module, comments) =
&mut working_set, parse_module_block(&mut working_set, Span::new(start, end), name.as_bytes());
Span::new(start, end),
name.as_bytes(),
&[],
);
if let Some(err) = working_set.parse_errors.first() { if let Some(err) = working_set.parse_errors.first() {
report_error(&working_set, err); report_error(&working_set, err);
} }
parse(&mut working_set, Some(&name), content, true, &[]); parse(&mut working_set, Some(&name), content, true);
if let Some(err) = working_set.parse_errors.first() { if let Some(err) = working_set.parse_errors.first() {
report_error(&working_set, err); report_error(&working_set, err);

View File

@ -229,7 +229,6 @@ pub fn nu_repl() {
Some(&format!("line{i}")), Some(&format!("line{i}")),
line.as_bytes(), line.as_bytes(),
false, false,
&[],
); );
if let Some(err) = working_set.parse_errors.first() { if let Some(err) = working_set.parse_errors.first() {