From cf2c19706e31e1f7149c0343927f832e153394e0 Mon Sep 17 00:00:00 2001 From: Maximilian Roos Date: Mon, 9 Sep 2019 06:03:01 -0400 Subject: [PATCH 1/4] fix build warnings & add CI --- .azure/azure-pipelines.yml | 2 ++ src/commands/config.rs | 2 +- src/plugins/binaryview.rs | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.azure/azure-pipelines.yml b/.azure/azure-pipelines.yml index 50ebcf1e2..2c36e9969 100644 --- a/.azure/azure-pipelines.yml +++ b/.azure/azure-pipelines.yml @@ -21,5 +21,7 @@ steps: rustc -Vv echo "##vso[task.prependpath]$HOME/.cargo/bin" displayName: Install Rust + - bash: RUSTFLAGS="-D warnings" cargo build --all-features + displayName: Build - bash: RUSTFLAGS="-D warnings" cargo test displayName: Run tests diff --git a/src/commands/config.rs b/src/commands/config.rs index c1f000d04..5dfb28bf3 100644 --- a/src/commands/config.rs +++ b/src/commands/config.rs @@ -114,7 +114,7 @@ pub fn config( let key = v.to_string(); if result.contains_key(&key) { - result.remove(&key); + result.swap_remove(&key); config::write_config(&result)?; } else { return Err(ShellError::string(&format!( diff --git a/src/plugins/binaryview.rs b/src/plugins/binaryview.rs index c321e8115..a6b8df899 100644 --- a/src/plugins/binaryview.rs +++ b/src/plugins/binaryview.rs @@ -435,7 +435,7 @@ pub fn view_contents_interactive( let cursor = cursor(); let _ = cursor.show(); - let screen = RawScreen::disable_raw_mode(); + let _screen = RawScreen::disable_raw_mode(); Ok(()) } From 45201cb28427241ea9428faa2cac8c8f8461dedf Mon Sep 17 00:00:00 2001 From: Maximilian Roos Date: Mon, 9 Sep 2019 17:04:14 -0400 Subject: [PATCH 2/4] combine build & test --- .azure/azure-pipelines.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.azure/azure-pipelines.yml b/.azure/azure-pipelines.yml index 2c36e9969..b384e8df3 100644 --- a/.azure/azure-pipelines.yml +++ b/.azure/azure-pipelines.yml @@ -21,7 +21,5 @@ steps: rustc -Vv echo "##vso[task.prependpath]$HOME/.cargo/bin" displayName: Install Rust - - bash: RUSTFLAGS="-D warnings" cargo build --all-features - displayName: Build - - bash: RUSTFLAGS="-D warnings" cargo test + - bash: RUSTFLAGS="-D warnings" cargo test --all-features displayName: Run tests From 58b7800172fe754818ac21a8a210ea4d7970c5f5 Mon Sep 17 00:00:00 2001 From: Yehuda Katz Date: Tue, 10 Sep 2019 20:23:22 -0700 Subject: [PATCH 3/4] Migrate most uses of the Span concept to Tag Also migrate mv, rm and commands like that to taking a SyntaxType::Pattern instead of a SyntaxType::Path for their first argument. --- Cargo.lock | 8 +- Cargo.toml | 2 +- src/cli.rs | 25 ++- src/commands/cd.rs | 3 +- src/commands/classified.rs | 31 ++-- src/commands/clip.rs | 2 +- src/commands/command.rs | 30 ++-- src/commands/config.rs | 44 ++--- src/commands/cp.rs | 8 +- src/commands/date.rs | 44 ++--- src/commands/echo.rs | 8 +- src/commands/enter.rs | 6 +- src/commands/fetch.rs | 76 +++----- src/commands/first.rs | 2 +- src/commands/from_bson.rs | 14 +- src/commands/from_csv.rs | 12 +- src/commands/from_ini.rs | 12 +- src/commands/from_json.rs | 18 +- src/commands/from_sqlite.rs | 12 +- src/commands/from_toml.rs | 12 +- src/commands/from_tsv.rs | 12 +- src/commands/from_xml.rs | 12 +- src/commands/from_yaml.rs | 12 +- src/commands/get.rs | 6 +- src/commands/help.rs | 8 +- src/commands/last.rs | 2 +- src/commands/lines.rs | 8 +- src/commands/ls.rs | 17 +- src/commands/mkdir.rs | 2 +- src/commands/mv.rs | 8 +- src/commands/nth.rs | 2 +- src/commands/open.rs | 55 ++---- src/commands/pick.rs | 2 +- src/commands/post.rs | 82 ++++----- src/commands/reject.rs | 2 +- src/commands/rm.rs | 4 +- src/commands/save.rs | 32 ++-- src/commands/shells.rs | 6 +- src/commands/size.rs | 10 +- src/commands/skip_while.rs | 2 +- src/commands/sort_by.rs | 2 +- src/commands/split_column.rs | 14 +- src/commands/split_row.rs | 7 +- src/commands/tags.rs | 4 +- src/commands/to_bson.rs | 32 ++-- src/commands/to_csv.rs | 10 +- src/commands/to_json.rs | 12 +- src/commands/to_sqlite.rs | 6 +- src/commands/to_toml.rs | 12 +- src/commands/to_tsv.rs | 10 +- src/commands/to_yaml.rs | 12 +- src/commands/trim.rs | 4 +- src/commands/version.rs | 8 +- src/commands/where_.rs | 11 +- src/commands/which_.rs | 13 +- src/context.rs | 12 +- src/data/base.rs | 18 +- src/data/config.rs | 12 +- src/data/into.rs | 4 +- src/data/meta.rs | 164 +++++++++++++----- src/errors.rs | 96 +++++----- src/evaluate/evaluator.rs | 53 +++--- src/format/table.rs | 2 +- src/lib.rs | 4 +- src/parser.rs | 4 +- src/parser/deserializer.rs | 6 +- src/parser/hir.rs | 65 +++---- src/parser/hir/baseline_parse.rs | 106 ++++++------ src/parser/hir/baseline_parse_tokens.rs | 161 ++++++++--------- src/parser/hir/external_command.rs | 2 +- src/parser/hir/named.rs | 5 +- src/parser/parse/files.rs | 35 ++-- src/parser/parse/flag.rs | 4 +- src/parser/parse/parser.rs | 157 ++++++++++------- src/parser/parse/pipeline.rs | 10 +- src/parser/parse/token_tree.rs | 44 ++--- src/parser/parse/token_tree_builder.rs | 221 ++++++++++-------------- src/parser/parse/tokens.rs | 32 ++-- src/parser/parse_command.rs | 27 ++- src/parser/registry.rs | 38 ++-- src/plugins/add.rs | 8 +- src/plugins/edit.rs | 6 +- src/plugins/embed.rs | 6 +- src/plugins/inc.rs | 42 +++-- src/plugins/ps.rs | 4 +- src/plugins/skip.rs | 8 +- src/plugins/str.rs | 14 +- src/plugins/sum.rs | 12 +- src/plugins/sys.rs | 2 +- src/prelude.rs | 5 +- src/shell/filesystem_shell.rs | 115 ++++++------ src/shell/help_shell.rs | 19 +- src/shell/helper.rs | 38 ++-- src/shell/shell.rs | 14 +- src/shell/shell_manager.rs | 8 +- src/shell/value_shell.rs | 32 ++-- src/traits.rs | 4 +- 97 files changed, 1174 insertions(+), 1255 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 08fcb94a0..22af92884 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1474,8 +1474,8 @@ dependencies = [ ] [[package]] -name = "nom5_locate" -version = "0.1.1" +name = "nom_locate" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytecount 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1531,7 +1531,7 @@ dependencies = [ "mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", "neso 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "nom 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "nom5_locate 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "nom_locate 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "onig_sys 69.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3129,7 +3129,7 @@ dependencies = [ "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" "checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" "checksum nom 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e9761d859320e381010a4f7f8ed425f2c924de33ad121ace447367c713ad561b" -"checksum nom5_locate 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3d4312467f8b28d909344b934207e502212fa5a3adf1bff7428b0b86a666223d" +"checksum nom_locate 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f932834fd8e391fc7710e2ba17e8f9f8645d846b55aa63207e17e110a1e1ce35" "checksum ntapi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f26e041cd983acbc087e30fcba770380cfa352d0e392e175b2344ebaf7ea0602" "checksum num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "57450397855d951f1a41305e54851b1a7b8f5d2e349543a02a2effe25459f718" "checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" diff --git a/Cargo.toml b/Cargo.toml index f9e13c934..c4369b94b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,7 +53,7 @@ ctrlc = "3.1.3" surf = "1.0.2" url = "2.1.0" roxmltree = "0.7.0" -nom5_locate = "0.1.1" +nom_locate = "1.0.0" enum-utils = "0.1.1" unicode-xid = "0.2.0" serde_ini = "0.2.0" diff --git a/src/cli.rs b/src/cli.rs index ec8c7085c..c29617ca9 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -266,7 +266,7 @@ pub async fn cli() -> Result<(), Box> { context.shell_manager.clone(), ))); - let edit_mode = crate::data::config::config(Span::unknown())? + let edit_mode = crate::data::config::config(Tag::unknown())? .get("edit_mode") .map(|s| match s.as_string().unwrap().as_ref() { "vi" => EditMode::Vi, @@ -344,7 +344,7 @@ async fn process_line(readline: Result, ctx: &mut Context Ok(line) if line.trim() == "" => LineResult::Success(line.clone()), Ok(line) => { - let result = match crate::parser::parse(&line) { + let result = match crate::parser::parse(&line, uuid::Uuid::nil()) { Err(err) => { return LineResult::Error(line.clone(), err); } @@ -366,7 +366,7 @@ async fn process_line(readline: Result, ctx: &mut Context .commands .push(ClassifiedCommand::Internal(InternalCommand { command: whole_stream_command(autoview::Autoview), - name_span: Span::unknown(), + name_tag: Tag::unknown(), args: hir::Call::new( Box::new(hir::Expression::synthetic_string("autoview")), None, @@ -486,10 +486,10 @@ fn classify_command( match call { // If the command starts with `^`, treat it as an external command no matter what call if call.head().is_external() => { - let name_span = call.head().expect_external(); - let name = name_span.slice(source); + let name_tag = call.head().expect_external(); + let name = name_tag.slice(source); - Ok(external_command(call, source, name.tagged(name_span))) + Ok(external_command(call, source, name.tagged(name_tag))) } // Otherwise, if the command is a bare word, we'll need to triage it @@ -511,19 +511,19 @@ fn classify_command( Ok(ClassifiedCommand::Internal(InternalCommand { command, - name_span: head.span().clone(), + name_tag: head.tag(), args, })) } // otherwise, it's an external command - false => Ok(external_command(call, source, name.tagged(head.span()))), + false => Ok(external_command(call, source, name.tagged(head.tag()))), } } // If the command is something else (like a number or a variable), that is currently unsupported. // We might support `$somevar` as a curried command in the future. - call => Err(ShellError::invalid_command(call.head().span())), + call => Err(ShellError::invalid_command(call.head().tag())), } } @@ -540,10 +540,7 @@ fn external_command( .iter() .filter_map(|i| match i { TokenNode::Whitespace(_) => None, - other => Some(Tagged::from_simple_spanned_item( - other.as_external_arg(source), - other.span(), - )), + other => Some(other.as_external_arg(source).tagged(other.tag())), }) .collect(), None => vec![], @@ -553,7 +550,7 @@ fn external_command( ClassifiedCommand::External(ExternalCommand { name: name.to_string(), - name_span: tag.span, + name_tag: tag, args: arg_list_strings, }) } diff --git a/src/commands/cd.rs b/src/commands/cd.rs index a84e66fce..a3f5a8d89 100644 --- a/src/commands/cd.rs +++ b/src/commands/cd.rs @@ -10,8 +10,7 @@ impl WholeStreamCommand for CD { } fn signature(&self) -> Signature { - Signature::build("cd") - .optional("directory", SyntaxType::Path) + Signature::build("cd").optional("directory", SyntaxShape::Path) } fn usage(&self) -> &str { diff --git a/src/commands/classified.rs b/src/commands/classified.rs index 277a92534..4d15bce12 100644 --- a/src/commands/classified.rs +++ b/src/commands/classified.rs @@ -86,7 +86,7 @@ pub(crate) enum ClassifiedCommand { pub(crate) struct InternalCommand { pub(crate) command: Arc, - pub(crate) name_span: Span, + pub(crate) name_tag: Tag, pub(crate) args: hir::Call, } @@ -108,7 +108,7 @@ impl InternalCommand { let result = context.run_command( self.command, - self.name_span.clone(), + self.name_tag.clone(), context.source_map.clone(), self.args, &source, @@ -133,21 +133,18 @@ impl InternalCommand { match value { Tagged { item: Value::Primitive(Primitive::String(cmd)), - .. + tag, } => { context.shell_manager.insert_at_current(Box::new( HelpShell::for_command( - Tagged::from_simple_spanned_item( - Value::string(cmd), - Span::unknown(), - ), - &context.registry().clone(), + Value::string(cmd).tagged(tag), + &context.registry(), )?, )); } _ => { context.shell_manager.insert_at_current(Box::new( - HelpShell::index(&context.registry().clone())?, + HelpShell::index(&context.registry())?, )); } } @@ -189,7 +186,7 @@ impl InternalCommand { pub(crate) struct ExternalCommand { pub(crate) name: String, - pub(crate) name_span: Span, + pub(crate) name_tag: Tag, pub(crate) args: Vec>, } @@ -208,7 +205,7 @@ impl ExternalCommand { ) -> Result { let stdin = input.stdin; let inputs: Vec> = input.objects.into_vec().await; - let name_span = self.name_span.clone(); + let name_tag = self.name_tag.clone(); trace!(target: "nu::run::external", "-> {}", self.name); trace!(target: "nu::run::external", "inputs = {:?}", inputs); @@ -227,17 +224,17 @@ impl ExternalCommand { for i in &inputs { if i.as_string().is_err() { - let mut span = None; + let mut tag = None; for arg in &self.args { if arg.item.contains("$it") { - span = Some(arg.span()); + tag = Some(arg.tag()); } } - if let Some(span) = span { + if let Some(tag) = tag { return Err(ShellError::labeled_error( "External $it needs string data", "given row instead of string data", - span, + tag, )); } else { return Err(ShellError::string("Error: $it needs string data")); @@ -314,9 +311,7 @@ impl ExternalCommand { let stdout = popen.stdout.take().unwrap(); let file = futures::io::AllowStdIo::new(stdout); let stream = Framed::new(file, LinesCodec {}); - let stream = stream.map(move |line| { - Tagged::from_simple_spanned_item(Value::string(line.unwrap()), name_span) - }); + let stream = stream.map(move |line| Value::string(line.unwrap()).tagged(name_tag)); Ok(ClassifiedInputStream::from_input_stream( stream.boxed() as BoxStream<'static, Tagged> )) diff --git a/src/commands/clip.rs b/src/commands/clip.rs index 9bf7fa9f3..2ef5bfac1 100644 --- a/src/commands/clip.rs +++ b/src/commands/clip.rs @@ -51,7 +51,7 @@ pub mod clipboard { Ok(OutputStream::from(stream)) } - async fn inner_clip(input: Vec>, name: Span) -> OutputStream { + async fn inner_clip(input: Vec>, name: Tag) -> OutputStream { let mut clip_context: ClipboardContext = ClipboardProvider::new().unwrap(); let mut new_copy_data = String::new(); diff --git a/src/commands/command.rs b/src/commands/command.rs index 6be179895..99352a7b1 100644 --- a/src/commands/command.rs +++ b/src/commands/command.rs @@ -18,7 +18,7 @@ pub struct UnevaluatedCallInfo { pub args: hir::Call, pub source: Text, pub source_map: SourceMap, - pub name_span: Span, + pub name_tag: Tag, } impl ToDebug for UnevaluatedCallInfo { @@ -38,7 +38,7 @@ impl UnevaluatedCallInfo { Ok(CallInfo { args, source_map: self.source_map, - name_span: self.name_span, + name_tag: self.name_tag, }) } @@ -74,7 +74,7 @@ impl UnevaluatedCallInfo { pub struct CallInfo { pub args: registry::EvaluatedArgs, pub source_map: SourceMap, - pub name_span: Span, + pub name_tag: Tag, } impl CallInfo { @@ -89,7 +89,7 @@ impl CallInfo { args: T::deserialize(&mut deserializer)?, context: RunnablePerItemContext { shell_manager: shell_manager.clone(), - name: self.name_span, + name: self.name_tag, }, callback, }) @@ -158,7 +158,7 @@ impl CommandArgs { let host = self.host.clone(); let args = self.evaluate_once(registry)?; let (input, args) = args.split(); - let name_span = args.call_info.name_span; + let name_tag = args.call_info.name_tag; let mut deserializer = ConfigDeserializer::from_call_info(args.call_info); Ok(RunnableArgs { @@ -167,7 +167,7 @@ impl CommandArgs { input, commands: registry.clone(), shell_manager, - name: name_span, + name: name_tag, source_map, host, }, @@ -191,7 +191,7 @@ impl CommandArgs { let host = self.host.clone(); let args = self.evaluate_once(registry)?; let (input, args) = args.split(); - let name_span = args.call_info.name_span; + let name_tag = args.call_info.name_tag; let mut deserializer = ConfigDeserializer::from_call_info(args.call_info); Ok(RunnableRawArgs { @@ -200,7 +200,7 @@ impl CommandArgs { input, commands: registry.clone(), shell_manager, - name: name_span, + name: name_tag, source_map, host, }, @@ -212,7 +212,7 @@ impl CommandArgs { pub struct RunnablePerItemContext { pub shell_manager: ShellManager, - pub name: Span, + pub name: Tag, } impl RunnablePerItemContext { @@ -227,7 +227,7 @@ pub struct RunnableContext { pub host: Arc>, pub commands: CommandRegistry, pub source_map: SourceMap, - pub name: Span, + pub name: Tag, } impl RunnableContext { @@ -311,8 +311,8 @@ impl EvaluatedWholeStreamCommandArgs { } } - pub fn name_span(&self) -> Span { - self.args.call_info.name_span + pub fn name_tag(&self) -> Tag { + self.args.call_info.name_tag } pub fn parts(self) -> (InputStream, registry::EvaluatedArgs) { @@ -471,12 +471,6 @@ impl ReturnSuccess { pub fn action(input: CommandAction) -> ReturnValue { Ok(ReturnSuccess::Action(input)) } - - pub fn spanned_value(input: Value, span: Span) -> ReturnValue { - Ok(ReturnSuccess::Value(Tagged::from_simple_spanned_item( - input, span, - ))) - } } pub trait WholeStreamCommand: Send + Sync { diff --git a/src/commands/config.rs b/src/commands/config.rs index 78f1ad399..c1eae9194 100644 --- a/src/commands/config.rs +++ b/src/commands/config.rs @@ -1,7 +1,7 @@ use crate::commands::WholeStreamCommand; use crate::data::{config, Value}; use crate::errors::ShellError; -use crate::parser::hir::SyntaxType; +use crate::parser::hir::SyntaxShape; use crate::parser::registry::{self}; use crate::prelude::*; use std::iter::FromIterator; @@ -26,10 +26,10 @@ impl WholeStreamCommand for Config { fn signature(&self) -> Signature { Signature::build("config") - .named("load", SyntaxType::Path) - .named("set", SyntaxType::Any) - .named("get", SyntaxType::Any) - .named("remove", SyntaxType::Any) + .named("load", SyntaxShape::Path) + .named("set", SyntaxShape::Any) + .named("get", SyntaxShape::Any) + .named("remove", SyntaxShape::Any) .switch("clear") .switch("path") } @@ -96,41 +96,21 @@ pub fn config( config::write(&result, &configuration)?; - return Ok(stream![Tagged::from_simple_spanned_item( - Value::Row(result.into()), - value.span() - )] - .from_input_stream()); + return Ok(stream![Value::Row(result.into()).tagged(value.tag())].from_input_stream()); } - if let Tagged { - item: true, - tag: Tag { span, .. }, - } = clear - { + if let Tagged { item: true, tag } = clear { result.clear(); config::write(&result, &configuration)?; - return Ok(stream![Tagged::from_simple_spanned_item( - Value::Row(result.into()), - span - )] - .from_input_stream()); + return Ok(stream![Value::Row(result.into()).tagged(tag)].from_input_stream()); } - if let Tagged { - item: true, - tag: Tag { span, .. }, - } = path - { + if let Tagged { item: true, tag } = path { let path = config::default_path_for(&configuration)?; - return Ok(stream![Tagged::from_simple_spanned_item( - Value::Primitive(Primitive::Path(path)), - span - )] - .from_input_stream()); + return Ok(stream![Value::Primitive(Primitive::Path(path)).tagged(tag)].from_input_stream()); } if let Some(v) = remove { @@ -146,9 +126,9 @@ pub fn config( ))); } - let obj = VecDeque::from_iter(vec![Value::Row(result.into()).simple_spanned(v.span())]); + let obj = VecDeque::from_iter(vec![Value::Row(result.into()).tagged(v.tag())]); return Ok(obj.from_input_stream()); } - return Ok(vec![Value::Row(result.into()).simple_spanned(name)].into()); + return Ok(vec![Value::Row(result.into()).tagged(name)].into()); } diff --git a/src/commands/cp.rs b/src/commands/cp.rs index 491e18b1a..bf20c74ce 100644 --- a/src/commands/cp.rs +++ b/src/commands/cp.rs @@ -1,6 +1,6 @@ use crate::commands::command::RunnablePerItemContext; use crate::errors::ShellError; -use crate::parser::hir::SyntaxType; +use crate::parser::hir::SyntaxShape; use crate::parser::registry::{CommandRegistry, Signature}; use crate::prelude::*; use std::path::PathBuf; @@ -21,9 +21,9 @@ impl PerItemCommand for Cpy { fn signature(&self) -> Signature { Signature::build("cp") - .required("src", SyntaxType::Pattern) - .required("dst", SyntaxType::Path) - .named("file", SyntaxType::Any) + .required("src", SyntaxShape::Pattern) + .required("dst", SyntaxShape::Path) + .named("file", SyntaxShape::Any) .switch("recursive") } diff --git a/src/commands/date.rs b/src/commands/date.rs index 7d3307fe5..6df9e2720 100644 --- a/src/commands/date.rs +++ b/src/commands/date.rs @@ -1,5 +1,5 @@ -use crate::errors::ShellError; use crate::data::{Dictionary, Value}; +use crate::errors::ShellError; use crate::prelude::*; use chrono::{DateTime, Local, Utc}; @@ -33,58 +33,40 @@ impl WholeStreamCommand for Date { } } -pub fn date_to_value(dt: DateTime, span: Span) -> Tagged +pub fn date_to_value(dt: DateTime, tag: Tag) -> Tagged where T::Offset: Display, { let mut indexmap = IndexMap::new(); - indexmap.insert( - "year".to_string(), - Tagged::from_simple_spanned_item(Value::int(dt.year()), span), - ); - indexmap.insert( - "month".to_string(), - Tagged::from_simple_spanned_item(Value::int(dt.month()), span), - ); - indexmap.insert( - "day".to_string(), - Tagged::from_simple_spanned_item(Value::int(dt.day()), span), - ); - indexmap.insert( - "hour".to_string(), - Tagged::from_simple_spanned_item(Value::int(dt.hour()), span), - ); - indexmap.insert( - "minute".to_string(), - Tagged::from_simple_spanned_item(Value::int(dt.minute()), span), - ); - indexmap.insert( - "second".to_string(), - Tagged::from_simple_spanned_item(Value::int(dt.second()), span), - ); + indexmap.insert("year".to_string(), Value::int(dt.year()).tagged(tag)); + indexmap.insert("month".to_string(), Value::int(dt.month()).tagged(tag)); + indexmap.insert("day".to_string(), Value::int(dt.day()).tagged(tag)); + indexmap.insert("hour".to_string(), Value::int(dt.hour()).tagged(tag)); + indexmap.insert("minute".to_string(), Value::int(dt.minute()).tagged(tag)); + indexmap.insert("second".to_string(), Value::int(dt.second()).tagged(tag)); let tz = dt.offset(); indexmap.insert( "timezone".to_string(), - Tagged::from_simple_spanned_item(Value::string(format!("{}", tz)), span), + Value::string(format!("{}", tz)).tagged(tag), ); - Tagged::from_simple_spanned_item(Value::Row(Dictionary::from(indexmap)), span) + Value::Row(Dictionary::from(indexmap)).tagged(tag) } pub fn date(args: CommandArgs, registry: &CommandRegistry) -> Result { let args = args.evaluate_once(registry)?; let mut date_out = VecDeque::new(); - let span = args.call_info.name_span; + let tag = args.call_info.name_tag; let value = if args.has("utc") { let utc: DateTime = Utc::now(); - date_to_value(utc, span) + date_to_value(utc, tag) } else { let local: DateTime = Local::now(); - date_to_value(local, span) + date_to_value(local, tag) }; date_out.push_back(value); diff --git a/src/commands/echo.rs b/src/commands/echo.rs index f464630de..453041bbc 100644 --- a/src/commands/echo.rs +++ b/src/commands/echo.rs @@ -12,7 +12,7 @@ impl PerItemCommand for Echo { } fn signature(&self) -> Signature { - Signature::build("echo").rest(SyntaxType::Any) + Signature::build("echo").rest(SyntaxShape::Any) } fn usage(&self) -> &str { @@ -35,7 +35,7 @@ fn run( _registry: &CommandRegistry, _raw_args: &RawCommandArgs, ) -> Result { - let name = call_info.name_span; + let name = call_info.name_tag; let mut output = String::new(); @@ -57,7 +57,7 @@ fn run( return Err(ShellError::labeled_error( "Expect a string from pipeline", "not a string-compatible value", - i.span(), + i.tag(), )); } } @@ -65,7 +65,7 @@ fn run( } let stream = VecDeque::from(vec![Ok(ReturnSuccess::Value( - Value::string(output).simple_spanned(name), + Value::string(output).tagged(name), ))]); Ok(stream.to_output_stream()) diff --git a/src/commands/enter.rs b/src/commands/enter.rs index 7b42793e1..4148d03c5 100644 --- a/src/commands/enter.rs +++ b/src/commands/enter.rs @@ -14,7 +14,7 @@ impl PerItemCommand for Enter { } fn signature(&self) -> registry::Signature { - Signature::build("enter").required("location", SyntaxType::Block) + Signature::build("enter").required("location", SyntaxShape::Block) } fn usage(&self) -> &str { @@ -70,7 +70,7 @@ impl PerItemCommand for Enter { crate::commands::open::fetch( &full_path, &location_clone, - Span::unknown(), + Tag::unknown(), ) .await.unwrap(); @@ -103,7 +103,7 @@ impl PerItemCommand for Enter { }, source: raw_args.call_info.source, source_map: raw_args.call_info.source_map, - name_span: raw_args.call_info.name_span, + name_tag: raw_args.call_info.name_tag, }, }; let mut result = converter.run( diff --git a/src/commands/fetch.rs b/src/commands/fetch.rs index e87ddf834..07ef0c3e0 100644 --- a/src/commands/fetch.rs +++ b/src/commands/fetch.rs @@ -2,14 +2,13 @@ use crate::commands::UnevaluatedCallInfo; use crate::context::SpanSource; use crate::data::Value; use crate::errors::ShellError; -use crate::parser::hir::SyntaxType; +use crate::parser::hir::SyntaxShape; use crate::parser::registry::Signature; use crate::prelude::*; use mime::Mime; use std::path::PathBuf; use std::str::FromStr; use surf::mime; -use uuid::Uuid; pub struct Fetch; impl PerItemCommand for Fetch { @@ -19,7 +18,7 @@ impl PerItemCommand for Fetch { fn signature(&self) -> Signature { Signature::build(self.name()) - .required("path", SyntaxType::Path) + .required("path", SyntaxShape::Path) .switch("raw") } @@ -52,14 +51,14 @@ fn run( }; let path_buf = path.as_path()?; let path_str = path_buf.display().to_string(); - let path_span = path.span(); + let path_tag = path.tag(); let has_raw = call_info.args.has("raw"); let registry = registry.clone(); let raw_args = raw_args.clone(); let stream = async_stream_block! { - let result = fetch(&path_str, path_span).await; + let result = fetch(&path_str, path_tag).await; if let Err(e) = result { yield Err(e); @@ -99,7 +98,7 @@ fn run( }, source: raw_args.call_info.source, source_map: raw_args.call_info.source_map, - name_span: raw_args.call_info.name_span, + name_tag: raw_args.call_info.name_tag, } }; let mut result = converter.run(new_args.with_input(vec![tagged_contents]), ®istry); @@ -130,13 +129,13 @@ fn run( pub async fn fetch( location: &str, - span: Span, + tag: Tag, ) -> Result<(Option, Value, Tag, SpanSource), ShellError> { if let Err(_) = url::Url::parse(location) { return Err(ShellError::labeled_error( "Incomplete or incorrect url", "expected a full url", - span, + tag, )); } @@ -152,13 +151,10 @@ pub async fn fetch( ShellError::labeled_error( "Could not load text from remote url", "could not load", - span, + tag, ) })?), - Tag { - span, - origin: Some(Uuid::new_v4()), - }, + tag, SpanSource::Url(location.to_string()), )), (mime::APPLICATION, mime::JSON) => Ok(( @@ -167,13 +163,10 @@ pub async fn fetch( ShellError::labeled_error( "Could not load text from remote url", "could not load", - span, + tag, ) })?), - Tag { - span, - origin: Some(Uuid::new_v4()), - }, + tag, SpanSource::Url(location.to_string()), )), (mime::APPLICATION, mime::OCTET_STREAM) => { @@ -181,16 +174,13 @@ pub async fn fetch( ShellError::labeled_error( "Could not load binary file", "could not load", - span, + tag, ) })?; Ok(( None, Value::Binary(buf), - Tag { - span, - origin: Some(Uuid::new_v4()), - }, + tag, SpanSource::Url(location.to_string()), )) } @@ -200,13 +190,10 @@ pub async fn fetch( ShellError::labeled_error( "Could not load svg from remote url", "could not load", - span, + tag, ) })?), - Tag { - span, - origin: Some(Uuid::new_v4()), - }, + tag, SpanSource::Url(location.to_string()), )), (mime::IMAGE, image_ty) => { @@ -214,16 +201,13 @@ pub async fn fetch( ShellError::labeled_error( "Could not load image file", "could not load", - span, + tag, ) })?; Ok(( Some(image_ty.to_string()), Value::Binary(buf), - Tag { - span, - origin: Some(Uuid::new_v4()), - }, + tag, SpanSource::Url(location.to_string()), )) } @@ -233,13 +217,10 @@ pub async fn fetch( ShellError::labeled_error( "Could not load text from remote url", "could not load", - span, + tag, ) })?), - Tag { - span, - origin: Some(Uuid::new_v4()), - }, + tag, SpanSource::Url(location.to_string()), )), (mime::TEXT, mime::PLAIN) => { @@ -260,23 +241,17 @@ pub async fn fetch( ShellError::labeled_error( "Could not load text from remote url", "could not load", - span, + tag, ) })?), - Tag { - span, - origin: Some(Uuid::new_v4()), - }, + tag, SpanSource::Url(location.to_string()), )) } (ty, sub_ty) => Ok(( None, Value::string(format!("Not yet supported MIME type: {} {}", ty, sub_ty)), - Tag { - span, - origin: Some(Uuid::new_v4()), - }, + tag, SpanSource::Url(location.to_string()), )), } @@ -284,10 +259,7 @@ pub async fn fetch( None => Ok(( None, Value::string(format!("No content type found")), - Tag { - span, - origin: Some(Uuid::new_v4()), - }, + tag, SpanSource::Url(location.to_string()), )), }, @@ -295,7 +267,7 @@ pub async fn fetch( return Err(ShellError::labeled_error( "URL could not be opened", "url not found", - span, + tag, )); } } diff --git a/src/commands/first.rs b/src/commands/first.rs index 6381d5def..77c9a4f69 100644 --- a/src/commands/first.rs +++ b/src/commands/first.rs @@ -17,7 +17,7 @@ impl WholeStreamCommand for First { fn signature(&self) -> Signature { Signature::build("first") - .required("amount", SyntaxType::Literal) + .required("amount", SyntaxShape::Literal) } fn usage(&self) -> &str { diff --git a/src/commands/from_bson.rs b/src/commands/from_bson.rs index e2f5421bd..b39754a19 100644 --- a/src/commands/from_bson.rs +++ b/src/commands/from_bson.rs @@ -1,6 +1,6 @@ use crate::commands::WholeStreamCommand; -use crate::errors::ExpectedRange; use crate::data::{Primitive, TaggedDictBuilder, Value}; +use crate::errors::ExpectedRange; use crate::prelude::*; use bson::{decode_document, spec::BinarySubtype, Bson}; use std::str::FromStr; @@ -198,7 +198,7 @@ pub fn from_bson_bytes_to_value( fn from_bson(args: CommandArgs, registry: &CommandRegistry) -> Result { let args = args.evaluate_once(registry)?; - let span = args.name_span(); + let tag = args.name_tag(); let input = args.input; let stream = async_stream_block! { @@ -208,24 +208,24 @@ fn from_bson(args: CommandArgs, registry: &CommandRegistry) -> Result - match from_bson_bytes_to_value(vb, span) { + match from_bson_bytes_to_value(vb, tag) { Ok(x) => yield ReturnSuccess::value(x), Err(_) => { yield Err(ShellError::labeled_error_with_secondary( "Could not parse as BSON", "input cannot be parsed as BSON", - span, + tag, "value originates from here", - value_tag.span, + value_tag, )) } } _ => yield Err(ShellError::labeled_error_with_secondary( "Expected a string from pipeline", "requires string input", - span, + tag, "value originates from here", - value_tag.span, + value_tag, )), } diff --git a/src/commands/from_csv.rs b/src/commands/from_csv.rs index c872e7736..68296eb11 100644 --- a/src/commands/from_csv.rs +++ b/src/commands/from_csv.rs @@ -86,7 +86,7 @@ fn from_csv( }: FromCSVArgs, RunnableContext { input, name, .. }: RunnableContext, ) -> Result { - let name_span = name; + let name_tag = name; let stream = async_stream_block! { let values: Vec> = input.values.collect().await; @@ -105,15 +105,15 @@ fn from_csv( _ => yield Err(ShellError::labeled_error_with_secondary( "Expected a string from pipeline", "requires string input", - name_span, + name_tag, "value originates from here", - value_tag.span, + value_tag, )), } } - match from_csv_string_to_value(concat_string, skip_headers, name_span) { + match from_csv_string_to_value(concat_string, skip_headers, name_tag) { Ok(x) => match x { Tagged { item: Value::Table(list), .. } => { for l in list { @@ -126,9 +126,9 @@ fn from_csv( yield Err(ShellError::labeled_error_with_secondary( "Could not parse as CSV", "input cannot be parsed as CSV", - name_span, + name_tag, "value originates from here", - last_tag.span, + last_tag, )) } , } diff --git a/src/commands/from_ini.rs b/src/commands/from_ini.rs index 0e128a22c..8409cf848 100644 --- a/src/commands/from_ini.rs +++ b/src/commands/from_ini.rs @@ -64,7 +64,7 @@ pub fn from_ini_string_to_value( fn from_ini(args: CommandArgs, registry: &CommandRegistry) -> Result { let args = args.evaluate_once(registry)?; - let span = args.name_span(); + let tag = args.name_tag(); let input = args.input; let stream = async_stream_block! { @@ -84,15 +84,15 @@ fn from_ini(args: CommandArgs, registry: &CommandRegistry) -> Result yield Err(ShellError::labeled_error_with_secondary( "Expected a string from pipeline", "requires string input", - span, + tag, "value originates from here", - value_tag.span, + value_tag, )), } } - match from_ini_string_to_value(concat_string, span) { + match from_ini_string_to_value(concat_string, tag) { Ok(x) => match x { Tagged { item: Value::Table(list), .. } => { for l in list { @@ -105,9 +105,9 @@ fn from_ini(args: CommandArgs, registry: &CommandRegistry) -> Result Result { - let name_span = name; + let name_tag = name; let stream = async_stream_block! { let values: Vec> = input.values.collect().await; @@ -91,9 +91,9 @@ fn from_json( _ => yield Err(ShellError::labeled_error_with_secondary( "Expected a string from pipeline", "requires string input", - name_span, + name_tag, "value originates from here", - value_tag.span, + value_tag, )), } @@ -106,7 +106,7 @@ fn from_json( continue; } - match from_json_string_to_value(json_str.to_string(), name_span) { + match from_json_string_to_value(json_str.to_string(), name_tag) { Ok(x) => yield ReturnSuccess::value(x), Err(_) => { @@ -114,15 +114,15 @@ fn from_json( yield Err(ShellError::labeled_error_with_secondary( "Could nnot parse as JSON", "input cannot be parsed as JSON", - name_span, + name_tag, "value originates from here", - last_tag.span)) + last_tag)) } } } } } else { - match from_json_string_to_value(concat_string, name_span) { + match from_json_string_to_value(concat_string, name_tag) { Ok(x) => match x { Tagged { item: Value::Table(list), .. } => { @@ -137,9 +137,9 @@ fn from_json( yield Err(ShellError::labeled_error_with_secondary( "Could not parse as JSON", "input cannot be parsed as JSON", - name_span, + name_tag, "value originates from here", - last_tag.span)) + last_tag)) } } } diff --git a/src/commands/from_sqlite.rs b/src/commands/from_sqlite.rs index c19c4fef1..1b04a59fd 100644 --- a/src/commands/from_sqlite.rs +++ b/src/commands/from_sqlite.rs @@ -128,7 +128,7 @@ pub fn from_sqlite_bytes_to_value( fn from_sqlite(args: CommandArgs, registry: &CommandRegistry) -> Result { let args = args.evaluate_once(registry)?; - let span = args.name_span(); + let tag = args.name_tag(); let input = args.input; let stream = async_stream_block! { @@ -138,7 +138,7 @@ fn from_sqlite(args: CommandArgs, registry: &CommandRegistry) -> Result - match from_sqlite_bytes_to_value(vb, span) { + match from_sqlite_bytes_to_value(vb, tag) { Ok(x) => match x { Tagged { item: Value::Table(list), .. } => { for l in list { @@ -151,18 +151,18 @@ fn from_sqlite(args: CommandArgs, registry: &CommandRegistry) -> Result yield Err(ShellError::labeled_error_with_secondary( "Expected a string from pipeline", "requires string input", - span, + tag, "value originates from here", - value_tag.span, + value_tag, )), } diff --git a/src/commands/from_toml.rs b/src/commands/from_toml.rs index c1338cb01..29db38a77 100644 --- a/src/commands/from_toml.rs +++ b/src/commands/from_toml.rs @@ -68,7 +68,7 @@ pub fn from_toml( registry: &CommandRegistry, ) -> Result { let args = args.evaluate_once(registry)?; - let span = args.name_span(); + let tag = args.name_tag(); let input = args.input; let stream = async_stream_block! { @@ -88,15 +88,15 @@ pub fn from_toml( _ => yield Err(ShellError::labeled_error_with_secondary( "Expected a string from pipeline", "requires string input", - span, + tag, "value originates from here", - value_tag.span, + value_tag, )), } } - match from_toml_string_to_value(concat_string, span) { + match from_toml_string_to_value(concat_string, tag) { Ok(x) => match x { Tagged { item: Value::Table(list), .. } => { for l in list { @@ -109,9 +109,9 @@ pub fn from_toml( yield Err(ShellError::labeled_error_with_secondary( "Could not parse as TOML", "input cannot be parsed as TOML", - span, + tag, "value originates from here", - last_tag.span, + last_tag, )) } , } diff --git a/src/commands/from_tsv.rs b/src/commands/from_tsv.rs index 92696c1aa..66f070a5d 100644 --- a/src/commands/from_tsv.rs +++ b/src/commands/from_tsv.rs @@ -87,7 +87,7 @@ fn from_tsv( }: FromTSVArgs, RunnableContext { input, name, .. }: RunnableContext, ) -> Result { - let name_span = name; + let name_tag = name; let stream = async_stream_block! { let values: Vec> = input.values.collect().await; @@ -106,15 +106,15 @@ fn from_tsv( _ => yield Err(ShellError::labeled_error_with_secondary( "Expected a string from pipeline", "requires string input", - name_span, + name_tag, "value originates from here", - value_tag.span, + value_tag, )), } } - match from_tsv_string_to_value(concat_string, skip_headers, name_span) { + match from_tsv_string_to_value(concat_string, skip_headers, name_tag) { Ok(x) => match x { Tagged { item: Value::Table(list), .. } => { for l in list { @@ -127,9 +127,9 @@ fn from_tsv( yield Err(ShellError::labeled_error_with_secondary( "Could not parse as TSV", "input cannot be parsed as TSV", - name_span, + name_tag, "value originates from here", - last_tag.span, + last_tag, )) } , } diff --git a/src/commands/from_xml.rs b/src/commands/from_xml.rs index 2c3f94cdd..f80d428f4 100644 --- a/src/commands/from_xml.rs +++ b/src/commands/from_xml.rs @@ -83,7 +83,7 @@ pub fn from_xml_string_to_value( fn from_xml(args: CommandArgs, registry: &CommandRegistry) -> Result { let args = args.evaluate_once(registry)?; - let span = args.name_span(); + let tag = args.name_tag(); let input = args.input; let stream = async_stream_block! { @@ -103,15 +103,15 @@ fn from_xml(args: CommandArgs, registry: &CommandRegistry) -> Result yield Err(ShellError::labeled_error_with_secondary( "Expected a string from pipeline", "requires string input", - span, + tag, "value originates from here", - value_tag.span, + value_tag, )), } } - match from_xml_string_to_value(concat_string, span) { + match from_xml_string_to_value(concat_string, tag) { Ok(x) => match x { Tagged { item: Value::Table(list), .. } => { for l in list { @@ -124,9 +124,9 @@ fn from_xml(args: CommandArgs, registry: &CommandRegistry) -> Result Result { let args = args.evaluate_once(registry)?; - let span = args.name_span(); + let tag = args.name_tag(); let input = args.input; let stream = async_stream_block! { @@ -117,15 +117,15 @@ fn from_yaml(args: CommandArgs, registry: &CommandRegistry) -> Result yield Err(ShellError::labeled_error_with_secondary( "Expected a string from pipeline", "requires string input", - span, + tag, "value originates from here", - value_tag.span, + value_tag, )), } } - match from_yaml_string_to_value(concat_string, span) { + match from_yaml_string_to_value(concat_string, tag) { Ok(x) => match x { Tagged { item: Value::Table(list), .. } => { for l in list { @@ -138,9 +138,9 @@ fn from_yaml(args: CommandArgs, registry: &CommandRegistry) -> Result Signature { - Signature::build("get").rest(SyntaxType::Member) + Signature::build("get").rest(SyntaxShape::Member) } fn usage(&self) -> &str { @@ -47,7 +47,7 @@ fn get_member(path: &Tagged, obj: &Tagged) -> Result registry::Signature { - Signature::build("help").rest(SyntaxType::Any) + Signature::build("help").rest(SyntaxShape::Any) } fn usage(&self) -> &str { @@ -27,11 +27,11 @@ impl PerItemCommand for Help { _raw_args: &RawCommandArgs, _input: Tagged, ) -> Result { - let span = call_info.name_span; + let tag = call_info.name_tag; if call_info.args.len() == 0 { return Ok(vec![Ok(ReturnSuccess::Action(CommandAction::EnterHelpShell( - Tagged::from_simple_spanned_item(Value::nothing(), span), + Value::nothing().tagged(tag), )))] .into()); } diff --git a/src/commands/last.rs b/src/commands/last.rs index 1f9cc62a7..fd7a3ecea 100644 --- a/src/commands/last.rs +++ b/src/commands/last.rs @@ -16,7 +16,7 @@ impl WholeStreamCommand for Last { } fn signature(&self) -> Signature { - Signature::build("last").required("amount", SyntaxType::Number) + Signature::build("last").required("amount", SyntaxShape::Number) } fn usage(&self) -> &str { diff --git a/src/commands/lines.rs b/src/commands/lines.rs index 15a467224..d2a9cdffd 100644 --- a/src/commands/lines.rs +++ b/src/commands/lines.rs @@ -1,6 +1,6 @@ use crate::commands::WholeStreamCommand; -use crate::errors::ShellError; use crate::data::{Primitive, Value}; +use crate::errors::ShellError; use crate::prelude::*; use log::trace; @@ -32,7 +32,7 @@ impl WholeStreamCommand for Lines { fn lines(args: CommandArgs, registry: &CommandRegistry) -> Result { let args = args.evaluate_once(registry)?; - let span = args.name_span(); + let tag = args.name_tag(); let input = args.input; let input: InputStream = trace_stream!(target: "nu::trace_stream::lines", "input" = input); @@ -58,9 +58,9 @@ fn lines(args: CommandArgs, registry: &CommandRegistry) -> Result>, +} + impl WholeStreamCommand for LS { fn name(&self) -> &str { "ls" } fn signature(&self) -> Signature { - Signature::build("ls").optional("path", SyntaxType::Pattern) + Signature::build("ls").optional("path", SyntaxShape::Pattern) } fn usage(&self) -> &str { @@ -22,12 +28,11 @@ impl WholeStreamCommand for LS { args: CommandArgs, registry: &CommandRegistry, ) -> Result { - ls(args, registry) + args.process(registry, ls)?.run() + // ls(args, registry) } } -fn ls(args: CommandArgs, registry: &CommandRegistry) -> Result { - let shell_manager = args.shell_manager.clone(); - let args = args.evaluate_once(registry)?; - shell_manager.ls(args) +fn ls(LsArgs { path }: LsArgs, context: RunnableContext) -> Result { + context.shell_manager.ls(path, context.name) } diff --git a/src/commands/mkdir.rs b/src/commands/mkdir.rs index 9dec9a314..8bf8a97d4 100644 --- a/src/commands/mkdir.rs +++ b/src/commands/mkdir.rs @@ -17,7 +17,7 @@ impl PerItemCommand for Mkdir { } fn signature(&self) -> Signature { - Signature::build("mkdir").rest(SyntaxType::Path) + Signature::build("mkdir").rest(SyntaxShape::Path) } fn usage(&self) -> &str { diff --git a/src/commands/mv.rs b/src/commands/mv.rs index 130e5996e..2ace1fa05 100644 --- a/src/commands/mv.rs +++ b/src/commands/mv.rs @@ -1,6 +1,6 @@ use crate::commands::command::RunnablePerItemContext; use crate::errors::ShellError; -use crate::parser::hir::SyntaxType; +use crate::parser::hir::SyntaxShape; use crate::parser::registry::{CommandRegistry, Signature}; use crate::prelude::*; use std::path::PathBuf; @@ -20,9 +20,9 @@ impl PerItemCommand for Move { fn signature(&self) -> Signature { Signature::build("mv") - .required("source", SyntaxType::Path) - .required("destination", SyntaxType::Path) - .named("file", SyntaxType::Any) + .required("source", SyntaxShape::Pattern) + .required("destination", SyntaxShape::Path) + .named("file", SyntaxShape::Any) } fn usage(&self) -> &str { diff --git a/src/commands/nth.rs b/src/commands/nth.rs index 98ab6a10a..bf397e1bc 100644 --- a/src/commands/nth.rs +++ b/src/commands/nth.rs @@ -16,7 +16,7 @@ impl WholeStreamCommand for Nth { } fn signature(&self) -> Signature { - Signature::build("nth").required("amount", SyntaxType::Any) + Signature::build("nth").required("amount", SyntaxShape::Any) } fn usage(&self) -> &str { diff --git a/src/commands/open.rs b/src/commands/open.rs index 32a99c6f1..57f035ac6 100644 --- a/src/commands/open.rs +++ b/src/commands/open.rs @@ -2,11 +2,10 @@ use crate::commands::UnevaluatedCallInfo; use crate::context::SpanSource; use crate::data::Value; use crate::errors::ShellError; -use crate::parser::hir::SyntaxType; +use crate::parser::hir::SyntaxShape; use crate::parser::registry::Signature; use crate::prelude::*; use std::path::{Path, PathBuf}; -use uuid::Uuid; pub struct Open; impl PerItemCommand for Open { @@ -16,7 +15,7 @@ impl PerItemCommand for Open { fn signature(&self) -> Signature { Signature::build(self.name()) - .required("path", SyntaxType::Path) + .required("path", SyntaxShape::Path) .switch("raw") } @@ -53,7 +52,7 @@ fn run( }; let path_buf = path.as_path()?; let path_str = path_buf.display().to_string(); - let path_span = path.span(); + let path_span = path.tag(); let has_raw = call_info.args.has("raw"); let registry = registry.clone(); let raw_args = raw_args.clone(); @@ -100,7 +99,7 @@ fn run( }, source: raw_args.call_info.source, source_map: raw_args.call_info.source_map, - name_span: raw_args.call_info.name_span, + name_tag: raw_args.call_info.name_tag, } }; let mut result = converter.run(new_args.with_input(vec![tagged_contents]), ®istry); @@ -132,7 +131,7 @@ fn run( pub async fn fetch( cwd: &PathBuf, location: &str, - span: Span, + tag: Tag, ) -> Result<(Option, Value, Tag, SpanSource), ShellError> { let mut cwd = cwd.clone(); @@ -144,10 +143,7 @@ pub async fn fetch( cwd.extension() .map(|name| name.to_string_lossy().to_string()), Value::string(s), - Tag { - span, - origin: Some(Uuid::new_v4()), - }, + tag, SpanSource::File(cwd.to_string_lossy().to_string()), )), Err(_) => { @@ -163,19 +159,13 @@ pub async fn fetch( cwd.extension() .map(|name| name.to_string_lossy().to_string()), Value::string(s), - Tag { - span, - origin: Some(Uuid::new_v4()), - }, + tag, SpanSource::File(cwd.to_string_lossy().to_string()), )), Err(_) => Ok(( None, Value::Binary(bytes), - Tag { - span, - origin: Some(Uuid::new_v4()), - }, + tag, SpanSource::File(cwd.to_string_lossy().to_string()), )), } @@ -183,10 +173,7 @@ pub async fn fetch( Ok(( None, Value::Binary(bytes), - Tag { - span, - origin: Some(Uuid::new_v4()), - }, + tag, SpanSource::File(cwd.to_string_lossy().to_string()), )) } @@ -201,19 +188,13 @@ pub async fn fetch( cwd.extension() .map(|name| name.to_string_lossy().to_string()), Value::string(s), - Tag { - span, - origin: Some(Uuid::new_v4()), - }, + tag, SpanSource::File(cwd.to_string_lossy().to_string()), )), Err(_) => Ok(( None, Value::Binary(bytes), - Tag { - span, - origin: Some(Uuid::new_v4()), - }, + tag, SpanSource::File(cwd.to_string_lossy().to_string()), )), } @@ -221,10 +202,7 @@ pub async fn fetch( Ok(( None, Value::Binary(bytes), - Tag { - span, - origin: Some(Uuid::new_v4()), - }, + tag, SpanSource::File(cwd.to_string_lossy().to_string()), )) } @@ -232,10 +210,7 @@ pub async fn fetch( _ => Ok(( None, Value::Binary(bytes), - Tag { - span, - origin: Some(Uuid::new_v4()), - }, + tag, SpanSource::File(cwd.to_string_lossy().to_string()), )), } @@ -245,7 +220,7 @@ pub async fn fetch( return Err(ShellError::labeled_error( "File could not be opened", "file not found", - span, + tag, )); } } @@ -253,7 +228,7 @@ pub async fn fetch( return Err(ShellError::labeled_error( "File could not be opened", "file not found", - span, + tag, )); } } diff --git a/src/commands/pick.rs b/src/commands/pick.rs index bc5f8df40..2fe21dbb4 100644 --- a/src/commands/pick.rs +++ b/src/commands/pick.rs @@ -17,7 +17,7 @@ impl WholeStreamCommand for Pick { } fn signature(&self) -> Signature { - Signature::build("pick").rest(SyntaxType::Any) + Signature::build("pick").rest(SyntaxShape::Any) } fn usage(&self) -> &str { diff --git a/src/commands/post.rs b/src/commands/post.rs index 8790c929a..88717a466 100644 --- a/src/commands/post.rs +++ b/src/commands/post.rs @@ -1,8 +1,8 @@ use crate::commands::UnevaluatedCallInfo; use crate::context::SpanSource; -use crate::errors::ShellError; use crate::data::Value; -use crate::parser::hir::SyntaxType; +use crate::errors::ShellError; +use crate::parser::hir::SyntaxShape; use crate::parser::registry::Signature; use crate::prelude::*; use base64::encode; @@ -10,7 +10,7 @@ use mime::Mime; use std::path::PathBuf; use std::str::FromStr; use surf::mime; -use uuid::Uuid; + pub struct Post; impl PerItemCommand for Post { @@ -20,10 +20,10 @@ impl PerItemCommand for Post { fn signature(&self) -> Signature { Signature::build(self.name()) - .required("path", SyntaxType::Any) - .required("body", SyntaxType::Any) - .named("user", SyntaxType::Any) - .named("password", SyntaxType::Any) + .required("path", SyntaxShape::Any) + .required("body", SyntaxShape::Any) + .named("user", SyntaxShape::Any) + .named("password", SyntaxShape::Any) .switch("raw") } @@ -63,7 +63,7 @@ fn run( file => file.clone(), }; let path_str = path.as_string()?; - let path_span = path.span(); + let path_span = path.tag(); let has_raw = call_info.args.has("raw"); let user = call_info.args.get("user").map(|x| x.as_string().unwrap()); let password = call_info @@ -109,7 +109,7 @@ fn run( }, source: raw_args.call_info.source, source_map: raw_args.call_info.source_map, - name_span: raw_args.call_info.name_span, + name_tag: raw_args.call_info.name_tag, } }; let mut result = converter.run(new_args.with_input(vec![tagged_contents]), ®istry); @@ -143,7 +143,7 @@ pub async fn post( body: &Tagged, user: Option, password: Option, - span: Span, + tag: Tag, registry: &CommandRegistry, raw_args: &RawCommandArgs, ) -> Result<(Option, Value, Tag, SpanSource), ShellError> { @@ -189,7 +189,7 @@ pub async fn post( }, source: raw_args.call_info.source, source_map: raw_args.call_info.source_map, - name_span: raw_args.call_info.name_span, + name_tag: raw_args.call_info.name_tag, }, }; let mut result = converter.run( @@ -211,7 +211,7 @@ pub async fn post( return Err(ShellError::labeled_error( "Save could not successfully save", "unexpected data during save", - span, + *tag, )); } } @@ -227,7 +227,7 @@ pub async fn post( return Err(ShellError::labeled_error( "Could not automatically convert table", "needs manual conversion", - tag.span, + *tag, )); } } @@ -243,13 +243,10 @@ pub async fn post( ShellError::labeled_error( "Could not load text from remote url", "could not load", - span, + tag, ) })?), - Tag { - span, - origin: Some(Uuid::new_v4()), - }, + tag, SpanSource::Url(location.to_string()), )), (mime::APPLICATION, mime::JSON) => Ok(( @@ -258,13 +255,10 @@ pub async fn post( ShellError::labeled_error( "Could not load text from remote url", "could not load", - span, + tag, ) })?), - Tag { - span, - origin: Some(Uuid::new_v4()), - }, + tag, SpanSource::Url(location.to_string()), )), (mime::APPLICATION, mime::OCTET_STREAM) => { @@ -272,16 +266,13 @@ pub async fn post( ShellError::labeled_error( "Could not load binary file", "could not load", - span, + tag, ) })?; Ok(( None, Value::Binary(buf), - Tag { - span, - origin: Some(Uuid::new_v4()), - }, + tag, SpanSource::Url(location.to_string()), )) } @@ -290,16 +281,13 @@ pub async fn post( ShellError::labeled_error( "Could not load image file", "could not load", - span, + tag, ) })?; Ok(( Some(image_ty.to_string()), Value::Binary(buf), - Tag { - span, - origin: Some(Uuid::new_v4()), - }, + tag, SpanSource::Url(location.to_string()), )) } @@ -309,13 +297,10 @@ pub async fn post( ShellError::labeled_error( "Could not load text from remote url", "could not load", - span, + tag, ) })?), - Tag { - span, - origin: Some(Uuid::new_v4()), - }, + tag, SpanSource::Url(location.to_string()), )), (mime::TEXT, mime::PLAIN) => { @@ -336,13 +321,10 @@ pub async fn post( ShellError::labeled_error( "Could not load text from remote url", "could not load", - span, + tag, ) })?), - Tag { - span, - origin: Some(Uuid::new_v4()), - }, + tag, SpanSource::Url(location.to_string()), )) } @@ -352,10 +334,7 @@ pub async fn post( "Not yet supported MIME type: {} {}", ty, sub_ty )), - Tag { - span, - origin: Some(Uuid::new_v4()), - }, + tag, SpanSource::Url(location.to_string()), )), } @@ -363,10 +342,7 @@ pub async fn post( None => Ok(( None, Value::string(format!("No content type found")), - Tag { - span, - origin: Some(Uuid::new_v4()), - }, + tag, SpanSource::Url(location.to_string()), )), }, @@ -374,7 +350,7 @@ pub async fn post( return Err(ShellError::labeled_error( "URL could not be opened", "url not found", - span, + tag, )); } } @@ -382,7 +358,7 @@ pub async fn post( Err(ShellError::labeled_error( "Expected a url", "needs a url", - span, + tag, )) } } diff --git a/src/commands/reject.rs b/src/commands/reject.rs index 49dbc4dd3..ea09bd749 100644 --- a/src/commands/reject.rs +++ b/src/commands/reject.rs @@ -16,7 +16,7 @@ impl WholeStreamCommand for Reject { } fn signature(&self) -> Signature { - Signature::build("reject").rest(SyntaxType::Member) + Signature::build("reject").rest(SyntaxShape::Member) } fn usage(&self) -> &str { diff --git a/src/commands/rm.rs b/src/commands/rm.rs index 60bb5c6e4..ac5aeaae7 100644 --- a/src/commands/rm.rs +++ b/src/commands/rm.rs @@ -1,6 +1,6 @@ use crate::commands::command::RunnablePerItemContext; use crate::errors::ShellError; -use crate::parser::hir::SyntaxType; +use crate::parser::hir::SyntaxShape; use crate::parser::registry::{CommandRegistry, Signature}; use crate::prelude::*; use std::path::PathBuf; @@ -20,7 +20,7 @@ impl PerItemCommand for Remove { fn signature(&self) -> Signature { Signature::build("rm") - .required("path", SyntaxType::Path) + .required("path", SyntaxShape::Pattern) .switch("recursive") } diff --git a/src/commands/save.rs b/src/commands/save.rs index 26bf8cb16..66d9732d6 100644 --- a/src/commands/save.rs +++ b/src/commands/save.rs @@ -7,7 +7,7 @@ use std::path::{Path, PathBuf}; pub struct Save; macro_rules! process_string { - ($input:ident, $name_span:ident) => {{ + ($input:ident, $name_tag:ident) => {{ let mut result_string = String::new(); for res in $input { match res { @@ -21,7 +21,7 @@ macro_rules! process_string { yield core::task::Poll::Ready(Err(ShellError::labeled_error( "Save could not successfully save", "unexpected data during save", - $name_span, + $name_tag, ))); } } @@ -31,7 +31,7 @@ macro_rules! process_string { } macro_rules! process_string_return_success { - ($result_vec:ident, $name_span:ident) => {{ + ($result_vec:ident, $name_tag:ident) => {{ let mut result_string = String::new(); for res in $result_vec { match res { @@ -45,7 +45,7 @@ macro_rules! process_string_return_success { yield core::task::Poll::Ready(Err(ShellError::labeled_error( "Save could not successfully save", "unexpected data during text save", - $name_span, + $name_tag, ))); } } @@ -55,7 +55,7 @@ macro_rules! process_string_return_success { } macro_rules! process_binary_return_success { - ($result_vec:ident, $name_span:ident) => {{ + ($result_vec:ident, $name_tag:ident) => {{ let mut result_binary: Vec = Vec::new(); for res in $result_vec { match res { @@ -71,7 +71,7 @@ macro_rules! process_binary_return_success { yield core::task::Poll::Ready(Err(ShellError::labeled_error( "Save could not successfully save", "unexpected data during binary save", - $name_span, + $name_tag, ))); } } @@ -93,7 +93,7 @@ impl WholeStreamCommand for Save { fn signature(&self) -> Signature { Signature::build("save") - .optional("path", SyntaxType::Path) + .optional("path", SyntaxShape::Path) .switch("raw") } @@ -127,7 +127,7 @@ fn save( raw_args: RawCommandArgs, ) -> Result { let mut full_path = PathBuf::from(shell_manager.path()); - let name_span = name; + let name_tag = name; let source_map = source_map.clone(); let stream = async_stream_block! { @@ -145,7 +145,7 @@ fn save( yield Err(ShellError::labeled_error( "Save requires a filepath", "needs path", - name_span, + name_tag, )); } }, @@ -153,7 +153,7 @@ fn save( yield Err(ShellError::labeled_error( "Save requires a filepath", "needs path", - name_span, + name_tag, )); } } @@ -161,7 +161,7 @@ fn save( yield Err(ShellError::labeled_error( "Save requires a filepath", "needs path", - name_span, + name_tag, )); } } else { @@ -185,21 +185,21 @@ fn save( }, source: raw_args.call_info.source, source_map: raw_args.call_info.source_map, - name_span: raw_args.call_info.name_span, + name_tag: raw_args.call_info.name_tag, } }; let mut result = converter.run(new_args.with_input(input), ®istry); let result_vec: Vec> = result.drain_vec().await; if converter.is_binary() { - process_binary_return_success!(result_vec, name_span) + process_binary_return_success!(result_vec, name_tag) } else { - process_string_return_success!(result_vec, name_span) + process_string_return_success!(result_vec, name_tag) } } else { - process_string!(input, name_span) + process_string!(input, name_tag) } } else { - process_string!(input, name_span) + process_string!(input, name_tag) } } else { Ok(string_from(&input).into_bytes()) diff --git a/src/commands/shells.rs b/src/commands/shells.rs index 856c23e7b..2aee2c856 100644 --- a/src/commands/shells.rs +++ b/src/commands/shells.rs @@ -1,6 +1,6 @@ use crate::commands::WholeStreamCommand; -use crate::errors::ShellError; use crate::data::TaggedDictBuilder; +use crate::errors::ShellError; use crate::prelude::*; pub struct Shells; @@ -29,10 +29,10 @@ impl WholeStreamCommand for Shells { fn shells(args: CommandArgs, _registry: &CommandRegistry) -> Result { let mut shells_out = VecDeque::new(); - let span = args.call_info.name_span; + let tag = args.call_info.name_tag; for (index, shell) in args.shell_manager.shells.lock().unwrap().iter().enumerate() { - let mut dict = TaggedDictBuilder::new(Tag::unknown_origin(span)); + let mut dict = TaggedDictBuilder::new(tag); if index == args.shell_manager.current_shell { dict.insert(" ", "X".to_string()); diff --git a/src/commands/size.rs b/src/commands/size.rs index d8383efcf..51f8d22c1 100644 --- a/src/commands/size.rs +++ b/src/commands/size.rs @@ -1,6 +1,6 @@ use crate::commands::WholeStreamCommand; -use crate::errors::ShellError; use crate::data::{TaggedDictBuilder, Value}; +use crate::errors::ShellError; use crate::prelude::*; pub struct Size; @@ -29,7 +29,7 @@ impl WholeStreamCommand for Size { fn size(args: CommandArgs, _registry: &CommandRegistry) -> Result { let input = args.input; - let span = args.call_info.name_span; + let tag = args.call_info.name_tag; Ok(input .values .map(move |v| match v.item { @@ -37,9 +37,9 @@ fn size(args: CommandArgs, _registry: &CommandRegistry) -> Result Err(ShellError::labeled_error_with_secondary( "Expected a string from pipeline", "requires string input", - span, + tag, "value originates from here", - v.span(), + v.tag(), )), }) .to_output_stream()) @@ -71,7 +71,7 @@ fn count(contents: &str, tag: impl Into) -> Tagged { } let mut dict = TaggedDictBuilder::new(tag); - //TODO: add back in name when we have it in the span + //TODO: add back in name when we have it in the tag //dict.insert("name", Value::string(name)); dict.insert("lines", Value::int(lines)); dict.insert("words", Value::int(words)); diff --git a/src/commands/skip_while.rs b/src/commands/skip_while.rs index 90ba24b99..041caf300 100644 --- a/src/commands/skip_while.rs +++ b/src/commands/skip_while.rs @@ -16,7 +16,7 @@ impl WholeStreamCommand for SkipWhile { fn signature(&self) -> Signature { Signature::build("skip-while") - .required("condition", SyntaxType::Block) + .required("condition", SyntaxShape::Block) .filter() } diff --git a/src/commands/sort_by.rs b/src/commands/sort_by.rs index edce33b96..8058b7889 100644 --- a/src/commands/sort_by.rs +++ b/src/commands/sort_by.rs @@ -15,7 +15,7 @@ impl WholeStreamCommand for SortBy { } fn signature(&self) -> Signature { - Signature::build("sort-by").rest(SyntaxType::String) + Signature::build("sort-by").rest(SyntaxShape::String) } fn usage(&self) -> &str { diff --git a/src/commands/split_column.rs b/src/commands/split_column.rs index 2df02cac1..00e2609f2 100644 --- a/src/commands/split_column.rs +++ b/src/commands/split_column.rs @@ -1,6 +1,6 @@ use crate::commands::WholeStreamCommand; -use crate::errors::ShellError; use crate::data::{Primitive, TaggedDictBuilder, Value}; +use crate::errors::ShellError; use crate::prelude::*; use log::trace; @@ -21,9 +21,9 @@ impl WholeStreamCommand for SplitColumn { fn signature(&self) -> Signature { Signature::build("split-column") - .required("separator", SyntaxType::Any) + .required("separator", SyntaxShape::Any) .switch("collapse-empty") - .rest(SyntaxType::Member) + .rest(SyntaxShape::Member) } fn usage(&self) -> &str { @@ -40,7 +40,11 @@ impl WholeStreamCommand for SplitColumn { } fn split_column( - SplitColumnArgs { separator, rest, collapse_empty}: SplitColumnArgs, + SplitColumnArgs { + separator, + rest, + collapse_empty, + }: SplitColumnArgs, RunnableContext { input, name, .. }: RunnableContext, ) -> Result { Ok(input @@ -92,7 +96,7 @@ fn split_column( "requires string input", name, "value originates from here", - v.span(), + v.tag(), )), }) .to_output_stream()) diff --git a/src/commands/split_row.rs b/src/commands/split_row.rs index d4f3824a8..e70e5cfa8 100644 --- a/src/commands/split_row.rs +++ b/src/commands/split_row.rs @@ -1,6 +1,6 @@ use crate::commands::WholeStreamCommand; -use crate::errors::ShellError; use crate::data::{Primitive, Value}; +use crate::errors::ShellError; use crate::prelude::*; use log::trace; @@ -17,8 +17,7 @@ impl WholeStreamCommand for SplitRow { } fn signature(&self) -> Signature { - Signature::build("split-row") - .required("separator", SyntaxType::Any) + Signature::build("split-row").required("separator", SyntaxShape::Any) } fn usage(&self) -> &str { @@ -63,7 +62,7 @@ fn split_row( "requires string input", name, "value originates from here", - v.span(), + v.tag(), ))); result } diff --git a/src/commands/tags.rs b/src/commands/tags.rs index 3f112482c..2b45105c2 100644 --- a/src/commands/tags.rs +++ b/src/commands/tags.rs @@ -1,6 +1,6 @@ use crate::commands::WholeStreamCommand; -use crate::errors::ShellError; use crate::data::{TaggedDictBuilder, Value}; +use crate::errors::ShellError; use crate::prelude::*; pub struct Tags; @@ -36,7 +36,7 @@ fn tags(args: CommandArgs, _registry: &CommandRegistry) -> Result Result { Ok(Bson::Document(doc)) } -fn shell_encode_document( - writer: &mut Vec, - doc: Document, - span: Span, -) -> Result<(), ShellError> { +fn shell_encode_document(writer: &mut Vec, doc: Document, tag: Tag) -> Result<(), ShellError> { match encode_document(writer, &doc) { Err(e) => Err(ShellError::labeled_error( format!("Failed to encode document due to: {:?}", e), "requires BSON-compatible document", - span, + tag, )), _ => Ok(()), } } -fn bson_value_to_bytes(bson: Bson, span: Span) -> Result, ShellError> { +fn bson_value_to_bytes(bson: Bson, tag: Tag) -> Result, ShellError> { let mut out = Vec::new(); match bson { Bson::Array(a) => { for v in a.into_iter() { match v { - Bson::Document(d) => shell_encode_document(&mut out, d, span)?, + Bson::Document(d) => shell_encode_document(&mut out, d, tag)?, _ => { return Err(ShellError::labeled_error( format!("All top level values must be Documents, got {:?}", v), "requires BSON-compatible document", - span, + tag, )) } } } } - Bson::Document(d) => shell_encode_document(&mut out, d, span)?, + Bson::Document(d) => shell_encode_document(&mut out, d, tag)?, _ => { return Err(ShellError::labeled_error( format!("All top level values must be Documents, got {:?}", bson), "requires BSON-compatible document", - span, + tag, )) } } @@ -236,7 +232,7 @@ fn bson_value_to_bytes(bson: Bson, span: Span) -> Result, ShellError> { fn to_bson(args: CommandArgs, registry: &CommandRegistry) -> Result { let args = args.evaluate_once(registry)?; - let name_span = args.name_span(); + let name_tag = args.name_tag(); let stream = async_stream_block! { let input: Vec> = args.input.values.collect().await; @@ -252,23 +248,23 @@ fn to_bson(args: CommandArgs, registry: &CommandRegistry) -> Result { - match bson_value_to_bytes(bson_value, name_span) { + match bson_value_to_bytes(bson_value, name_tag) { Ok(x) => yield ReturnSuccess::value( - Value::Binary(x).simple_spanned(name_span), + Value::Binary(x).tagged(name_tag), ), _ => yield Err(ShellError::labeled_error_with_secondary( - "Expected a table with BSON-compatible structure.span() from pipeline", + "Expected a table with BSON-compatible structure.tag() from pipeline", "requires BSON-compatible input", - name_span, + name_tag, "originates from here".to_string(), - value.span(), + value.tag(), )), } } _ => yield Err(ShellError::labeled_error( "Expected a table with BSON-compatible structure from pipeline", "requires BSON-compatible input", - name_span)) + name_tag)) } } }; diff --git a/src/commands/to_csv.rs b/src/commands/to_csv.rs index 615e49cbf..fd77fdcb6 100644 --- a/src/commands/to_csv.rs +++ b/src/commands/to_csv.rs @@ -134,7 +134,7 @@ fn to_csv( ToCSVArgs { headerless }: ToCSVArgs, RunnableContext { input, name, .. }: RunnableContext, ) -> Result { - let name_span = name; + let name_tag = name; let stream = async_stream_block! { let input: Vec> = input.values.collect().await; @@ -155,15 +155,15 @@ fn to_csv( } else { x }; - yield ReturnSuccess::value(Value::Primitive(Primitive::String(converted)).simple_spanned(name_span)) + yield ReturnSuccess::value(Value::Primitive(Primitive::String(converted)).tagged(name_tag)) } _ => { yield Err(ShellError::labeled_error_with_secondary( - "Expected a table with CSV-compatible structure.span() from pipeline", + "Expected a table with CSV-compatible structure.tag() from pipeline", "requires CSV-compatible input", - name_span, + name_tag, "originates from here".to_string(), - value.span(), + value.tag(), )) } } diff --git a/src/commands/to_json.rs b/src/commands/to_json.rs index 35c03af32..c6b5d9c01 100644 --- a/src/commands/to_json.rs +++ b/src/commands/to_json.rs @@ -80,7 +80,7 @@ fn json_list(input: &Vec>) -> Result, Shell fn to_json(args: CommandArgs, registry: &CommandRegistry) -> Result { let args = args.evaluate_once(registry)?; - let name_span = args.name_span(); + let name_tag = args.name_tag(); let stream = async_stream_block! { let input: Vec> = args.input.values.collect().await; @@ -98,21 +98,21 @@ fn to_json(args: CommandArgs, registry: &CommandRegistry) -> Result { match serde_json::to_string(&json_value) { Ok(x) => yield ReturnSuccess::value( - Value::Primitive(Primitive::String(x)).simple_spanned(name_span), + Value::Primitive(Primitive::String(x)).tagged(name_tag), ), _ => yield Err(ShellError::labeled_error_with_secondary( - "Expected a table with JSON-compatible structure.span() from pipeline", + "Expected a table with JSON-compatible structure.tag() from pipeline", "requires JSON-compatible input", - name_span, + name_tag, "originates from here".to_string(), - value.span(), + value.tag(), )), } } _ => yield Err(ShellError::labeled_error( "Expected a table with JSON-compatible structure from pipeline", "requires JSON-compatible input", - name_span)) + name_tag)) } } }; diff --git a/src/commands/to_sqlite.rs b/src/commands/to_sqlite.rs index 0fd392f34..580dba96b 100644 --- a/src/commands/to_sqlite.rs +++ b/src/commands/to_sqlite.rs @@ -200,7 +200,7 @@ fn sqlite_input_stream_to_bytes( fn to_sqlite(args: CommandArgs, registry: &CommandRegistry) -> Result { let args = args.evaluate_once(registry)?; - let name_span = args.name_span(); + let name_tag = args.name_tag(); let stream = async_stream_block! { let input: Vec> = args.input.values.collect().await; @@ -208,9 +208,9 @@ fn to_sqlite(args: CommandArgs, registry: &CommandRegistry) -> Result yield ReturnSuccess::value(out), _ => { yield Err(ShellError::labeled_error( - "Expected a table with SQLite-compatible structure.span() from pipeline", + "Expected a table with SQLite-compatible structure.tag() from pipeline", "requires SQLite-compatible input", - name_span, + name_tag, )) }, } diff --git a/src/commands/to_toml.rs b/src/commands/to_toml.rs index e18e15236..cf8f2b11f 100644 --- a/src/commands/to_toml.rs +++ b/src/commands/to_toml.rs @@ -75,7 +75,7 @@ fn collect_values(input: &Vec>) -> Result, ShellE fn to_toml(args: CommandArgs, registry: &CommandRegistry) -> Result { let args = args.evaluate_once(registry)?; - let name_span = args.name_span(); + let name_tag = args.name_tag(); let stream = async_stream_block! { let input: Vec> = args.input.values.collect().await; @@ -93,21 +93,21 @@ fn to_toml(args: CommandArgs, registry: &CommandRegistry) -> Result { match toml::to_string(&toml_value) { Ok(x) => yield ReturnSuccess::value( - Value::Primitive(Primitive::String(x)).simple_spanned(name_span), + Value::Primitive(Primitive::String(x)).tagged(name_tag), ), _ => yield Err(ShellError::labeled_error_with_secondary( - "Expected a table with TOML-compatible structure.span() from pipeline", + "Expected a table with TOML-compatible structure.tag() from pipeline", "requires TOML-compatible input", - name_span, + name_tag, "originates from here".to_string(), - value.span(), + value.tag(), )), } } _ => yield Err(ShellError::labeled_error( "Expected a table with TOML-compatible structure from pipeline", "requires TOML-compatible input", - name_span)) + name_tag)) } } }; diff --git a/src/commands/to_tsv.rs b/src/commands/to_tsv.rs index a0cbf1c1b..7bce174d0 100644 --- a/src/commands/to_tsv.rs +++ b/src/commands/to_tsv.rs @@ -133,7 +133,7 @@ fn to_tsv( ToTSVArgs { headerless }: ToTSVArgs, RunnableContext { input, name, .. }: RunnableContext, ) -> Result { - let name_span = name; + let name_tag = name; let stream = async_stream_block! { let input: Vec> = input.values.collect().await; @@ -154,15 +154,15 @@ fn to_tsv( } else { x }; - yield ReturnSuccess::value(Value::Primitive(Primitive::String(converted)).simple_spanned(name_span)) + yield ReturnSuccess::value(Value::Primitive(Primitive::String(converted)).tagged(name_tag)) } _ => { yield Err(ShellError::labeled_error_with_secondary( - "Expected a table with TSV-compatible structure.span() from pipeline", + "Expected a table with TSV-compatible structure.tag() from pipeline", "requires TSV-compatible input", - name_span, + name_tag, "originates from here".to_string(), - value.span(), + value.tag(), )) } } diff --git a/src/commands/to_yaml.rs b/src/commands/to_yaml.rs index 915827252..fc4412da0 100644 --- a/src/commands/to_yaml.rs +++ b/src/commands/to_yaml.rs @@ -76,7 +76,7 @@ pub fn value_to_yaml_value(v: &Tagged) -> Result Result { let args = args.evaluate_once(registry)?; - let name_span = args.name_span(); + let name_tag = args.name_tag(); let stream = async_stream_block! { let input: Vec> = args.input.values.collect().await; @@ -94,21 +94,21 @@ fn to_yaml(args: CommandArgs, registry: &CommandRegistry) -> Result { match serde_yaml::to_string(&yaml_value) { Ok(x) => yield ReturnSuccess::value( - Value::Primitive(Primitive::String(x)).simple_spanned(name_span), + Value::Primitive(Primitive::String(x)).tagged(name_tag), ), _ => yield Err(ShellError::labeled_error_with_secondary( - "Expected a table with YAML-compatible structure.span() from pipeline", + "Expected a table with YAML-compatible structure.tag() from pipeline", "requires YAML-compatible input", - name_span, + name_tag, "originates from here".to_string(), - value.span(), + value.tag(), )), } } _ => yield Err(ShellError::labeled_error( "Expected a table with YAML-compatible structure from pipeline", "requires YAML-compatible input", - name_span)) + name_tag)) } } }; diff --git a/src/commands/trim.rs b/src/commands/trim.rs index 865f6b50b..11ed02539 100644 --- a/src/commands/trim.rs +++ b/src/commands/trim.rs @@ -1,6 +1,6 @@ use crate::commands::WholeStreamCommand; -use crate::errors::ShellError; use crate::data::Value; +use crate::errors::ShellError; use crate::prelude::*; pub struct Trim; @@ -34,7 +34,7 @@ fn trim(args: CommandArgs, _registry: &CommandRegistry) -> Result Result { let args = args.evaluate_once(registry)?; - let span = args.call_info.name_span; + let tag = args.call_info.name_tag; let mut indexmap = IndexMap::new(); indexmap.insert( "version".to_string(), - Tagged::from_simple_spanned_item(Value::string(clap::crate_version!()), span), + Value::string(clap::crate_version!()).tagged(tag), ); - let value = Tagged::from_simple_spanned_item(Value::Row(Dictionary::from(indexmap)), span); + let value = Value::Row(Dictionary::from(indexmap)).tagged(tag); Ok(OutputStream::one(value)) } diff --git a/src/commands/where_.rs b/src/commands/where_.rs index b09c341b4..673c6dda8 100644 --- a/src/commands/where_.rs +++ b/src/commands/where_.rs @@ -1,6 +1,6 @@ use crate::commands::PerItemCommand; use crate::errors::ShellError; -use crate::parser::hir::SyntaxType; +use crate::parser::hir::SyntaxShape; use crate::parser::registry; use crate::prelude::*; @@ -12,8 +12,7 @@ impl PerItemCommand for Where { } fn signature(&self) -> registry::Signature { - Signature::build("where") - .required("condition", SyntaxType::Block) + Signature::build("where").required("condition", SyntaxShape::Block) } fn usage(&self) -> &str { @@ -43,16 +42,14 @@ impl PerItemCommand for Where { VecDeque::new() } } - Err(e) => { - return Err(e) - } + Err(e) => return Err(e), } } Tagged { tag, .. } => { return Err(ShellError::labeled_error( "Expected a condition", "where needs a condition", - tag.span, + *tag, )) } }; diff --git a/src/commands/which_.rs b/src/commands/which_.rs index 06c93f63f..905515848 100644 --- a/src/commands/which_.rs +++ b/src/commands/which_.rs @@ -1,5 +1,5 @@ -use crate::errors::ShellError; use crate::data::Value; +use crate::errors::ShellError; use crate::prelude::*; use crate::commands::WholeStreamCommand; @@ -13,8 +13,7 @@ impl WholeStreamCommand for Which { } fn signature(&self) -> Signature { - Signature::build("which") - .required("name", SyntaxType::Any) + Signature::build("which").required("name", SyntaxShape::Any) } fn usage(&self) -> &str { @@ -34,7 +33,7 @@ pub fn which(args: CommandArgs, registry: &CommandRegistry) -> Result 0 { @@ -53,7 +52,7 @@ pub fn which(args: CommandArgs, registry: &CommandRegistry) -> Result Result( &mut self, command: Arc, - name_span: Span, + name_tag: Tag, source_map: SourceMap, args: hir::Call, source: &Text, input: InputStream, ) -> OutputStream { - let command_args = self.command_args(args, input, source, source_map, name_span); + let command_args = self.command_args(args, input, source, source_map, name_tag); command.run(command_args, self.registry()) } @@ -135,13 +135,13 @@ impl Context { args: hir::Call, source: &Text, source_map: SourceMap, - name_span: Span, + name_tag: Tag, ) -> UnevaluatedCallInfo { UnevaluatedCallInfo { args, source: source.clone(), source_map, - name_span, + name_tag, } } @@ -151,12 +151,12 @@ impl Context { input: InputStream, source: &Text, source_map: SourceMap, - name_span: Span, + name_tag: Tag, ) -> CommandArgs { CommandArgs { host: self.host.clone(), shell_manager: self.shell_manager.clone(), - call_info: self.call_info(args, source, source_map, name_span), + call_info: self.call_info(args, source, source_map, name_tag), input, } } diff --git a/src/data/base.rs b/src/data/base.rs index aa491ebdc..fdd5542dc 100644 --- a/src/data/base.rs +++ b/src/data/base.rs @@ -145,7 +145,7 @@ pub struct Operation { pub struct Block { pub(crate) expressions: Vec, pub(crate) source: Text, - pub(crate) span: Span, + pub(crate) tag: Tag, } impl Block { @@ -153,7 +153,7 @@ impl Block { let scope = Scope::new(value.clone()); if self.expressions.len() == 0 { - return Ok(Value::nothing().simple_spanned(self.span)); + return Ok(Value::nothing().tagged(self.tag)); } let mut last = None; @@ -247,7 +247,7 @@ impl std::convert::TryFrom<&Tagged> for Block { Value::Block(block) => Ok(block.clone()), v => Err(ShellError::type_error( "Block", - value.copy_span(v.type_name()), + value.copy_tag(v.type_name()), )), } } @@ -263,7 +263,7 @@ impl std::convert::TryFrom<&Tagged> for i64 { } v => Err(ShellError::type_error( "Integer", - value.copy_span(v.type_name()), + value.copy_tag(v.type_name()), )), } } @@ -277,7 +277,7 @@ impl std::convert::TryFrom<&Tagged> for String { Value::Primitive(Primitive::String(s)) => Ok(s.clone()), v => Err(ShellError::type_error( "String", - value.copy_span(v.type_name()), + value.copy_tag(v.type_name()), )), } } @@ -291,7 +291,7 @@ impl std::convert::TryFrom<&Tagged> for Vec { Value::Binary(b) => Ok(b.clone()), v => Err(ShellError::type_error( "Binary", - value.copy_span(v.type_name()), + value.copy_tag(v.type_name()), )), } } @@ -305,7 +305,7 @@ impl<'a> std::convert::TryFrom<&'a Tagged> for &'a crate::data::Dictionar Value::Row(d) => Ok(d), v => Err(ShellError::type_error( "Dictionary", - value.copy_span(v.type_name()), + value.copy_tag(v.type_name()), )), } } @@ -327,7 +327,7 @@ impl std::convert::TryFrom>> for Switch { Value::Primitive(Primitive::Boolean(true)) => Ok(Switch::Present), v => Err(ShellError::type_error( "Boolean", - value.copy_span(v.type_name()), + value.copy_tag(v.type_name()), )), }, } @@ -639,7 +639,7 @@ impl Tagged { Value::Primitive(Primitive::Path(path)) => Ok(path.clone()), other => Err(ShellError::type_error( "Path", - other.type_name().tagged(self.span()), + other.type_name().tagged(self.tag()), )), } } diff --git a/src/data/config.rs b/src/data/config.rs index 08296c09a..6b4d1383f 100644 --- a/src/data/config.rs +++ b/src/data/config.rs @@ -50,7 +50,7 @@ pub fn default_path_for(file: &Option) -> Result { } pub fn read( - span: impl Into, + tag: impl Into, at: &Option, ) -> Result>, ShellError> { let filename = default_path()?; @@ -64,15 +64,15 @@ pub fn read( trace!("config file = {}", filename.display()); - let span = span.into(); + let tag = tag.into(); let contents = fs::read_to_string(filename) - .map(|v| v.simple_spanned(span)) + .map(|v| v.tagged(tag)) .map_err(|err| ShellError::string(&format!("Couldn't read config file:\n{}", err)))?; let parsed: toml::Value = toml::from_str(&contents) .map_err(|err| ShellError::string(&format!("Couldn't parse config file:\n{}", err)))?; - let value = convert_toml_value_to_nu_value(&parsed, Tag::unknown_origin(span)); + let value = convert_toml_value_to_nu_value(&parsed, tag); let tag = value.tag(); match value.item { Value::Row(Dictionary { entries }) => Ok(entries), @@ -83,8 +83,8 @@ pub fn read( } } -pub(crate) fn config(span: impl Into) -> Result>, ShellError> { - read(span, &None) +pub(crate) fn config(tag: impl Into) -> Result>, ShellError> { + read(tag, &None) } pub fn write( diff --git a/src/data/into.rs b/src/data/into.rs index 749ab0601..3d764fa0c 100644 --- a/src/data/into.rs +++ b/src/data/into.rs @@ -15,8 +15,8 @@ impl From for Value { impl> Tagged { pub fn into_tagged_value(self) -> Tagged { - let value_span = self.span(); + let value_tag = self.tag(); let value = self.item.into(); - value.simple_spanned(value_span) + value.tagged(value_tag) } } diff --git a/src/data/meta.rs b/src/data/meta.rs index f1d2b6713..d472a8add 100644 --- a/src/data/meta.rs +++ b/src/data/meta.rs @@ -5,6 +5,7 @@ use derive_new::new; use getset::Getters; use serde::Deserialize; use serde::Serialize; +use std::path::{Path, PathBuf}; use uuid::Uuid; #[derive(new, Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize, Hash)] @@ -13,9 +14,15 @@ pub struct Tagged { pub item: T, } -impl HasSpan for Tagged { - fn span(&self) -> Span { - self.tag.span +impl HasTag for Tagged { + fn tag(&self) -> Tag { + self.tag + } +} + +impl AsRef for Tagged { + fn as_ref(&self) -> &Path { + self.item.as_ref() } } @@ -24,10 +31,6 @@ pub trait TaggedItem: Sized { Tagged::from_item(self, tag.into()) } - fn simple_spanned(self, span: impl Into) -> Tagged { - Tagged::from_simple_spanned_item(self, span.into()) - } - // For now, this is a temporary facility. In many cases, there are other useful spans that we // could be using, such as the original source spans of JSON or Toml files, but we don't yet // have the infrastructure to make that work. @@ -53,14 +56,8 @@ impl std::ops::Deref for Tagged { } impl Tagged { - pub fn spanned(self, span: impl Into) -> Tagged { - Tagged::from_item( - self.item, - Tag { - span: span.into(), - origin: None, - }, - ) + pub fn with_tag(self, tag: impl Into) -> Tagged { + Tagged::from_item(self.item, tag) } pub fn from_item(item: T, tag: impl Into) -> Tagged { @@ -70,41 +67,26 @@ impl Tagged { } } - pub fn from_simple_spanned_item(item: T, span: impl Into) -> Tagged { - Tagged::from_item( - item, - Tag { - span: span.into(), - origin: None, - }, - ) - } - pub fn map(self, input: impl FnOnce(T) -> U) -> Tagged { let tag = self.tag(); let mapped = input(self.item); - Tagged::from_item(mapped, tag.clone()) + Tagged::from_item(mapped, tag) } - pub(crate) fn copy_span(&self, output: U) -> Tagged { - let span = self.span(); - - Tagged::from_simple_spanned_item(output, span) + pub(crate) fn copy_tag(&self, output: U) -> Tagged { + Tagged::from_item(output, self.tag()) } pub fn source(&self, source: &Text) -> Text { - Text::from(self.span().slice(source)) - } - - pub fn span(&self) -> Span { - self.tag.span + Text::from(self.tag().slice(source)) } pub fn tag(&self) -> Tag { self.tag } + // TODO: This should not be optional pub fn origin(&self) -> Option { self.tag.origin } @@ -126,20 +108,14 @@ impl Tagged { } } -impl From<&Tagged> for Span { - fn from(input: &Tagged) -> Span { - input.span() - } -} - -impl From<&Span> for Span { - fn from(input: &Span) -> Span { +impl From<&Tag> for Tag { + fn from(input: &Tag) -> Tag { *input } } -impl From> for Span { - fn from(input: nom5_locate::LocatedSpan<&str>) -> Span { +impl From> for Span { + fn from(input: nom_locate::LocatedSpanEx<&str, Uuid>) -> Span { Span { start: input.offset, end: input.offset + input.fragment.len(), @@ -147,8 +123,18 @@ impl From> for Span { } } -impl From<(nom5_locate::LocatedSpan, nom5_locate::LocatedSpan)> for Span { - fn from(input: (nom5_locate::LocatedSpan, nom5_locate::LocatedSpan)) -> Span { +impl + From<( + nom_locate::LocatedSpanEx, + nom_locate::LocatedSpanEx, + )> for Span +{ + fn from( + input: ( + nom_locate::LocatedSpanEx, + nom_locate::LocatedSpanEx, + ), + ) -> Span { Span { start: input.0.offset, end: input.1.offset, @@ -197,6 +183,36 @@ impl From<&Span> for Tag { } } +impl From<(usize, usize, Uuid)> for Tag { + fn from((start, end, origin): (usize, usize, Uuid)) -> Self { + Tag { + origin: Some(origin), + span: Span { start, end }, + } + } +} + +impl From<(usize, usize, Option)> for Tag { + fn from((start, end, origin): (usize, usize, Option)) -> Self { + Tag { + origin, + span: Span { start, end }, + } + } +} + +impl From> for Tag { + fn from(input: nom_locate::LocatedSpanEx<&str, Uuid>) -> Tag { + Tag { + origin: Some(input.extra), + span: Span { + start: input.offset, + end: input.offset + input.fragment.len(), + }, + } + } +} + impl From for Span { fn from(tag: Tag) -> Self { tag.span @@ -214,12 +230,36 @@ impl Tag { Tag { origin: None, span } } + pub fn unknown_span(origin: Uuid) -> Tag { + Tag { + origin: Some(origin), + span: Span::unknown(), + } + } + pub fn unknown() -> Tag { Tag { origin: None, span: Span::unknown(), } } + + pub fn until(&self, other: impl Into) -> Tag { + let other = other.into(); + debug_assert!(self.origin == other.origin, "Can only merge two tags with the same origin"); + + Tag { + span: Span { + start: self.span.start, + end: other.span.end + }, + origin: self.origin + } + } + + pub fn slice<'a>(&self, source: &'a str) -> &'a str { + self.span.slice(source) + } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Serialize, Deserialize, Hash)] @@ -284,3 +324,33 @@ impl language_reporting::ReportingSpan for Span { self.end } } + +impl language_reporting::ReportingSpan for Tag { + fn with_start(&self, start: usize) -> Self { + Tag { + span: Span { + start, + end: self.span.end, + }, + origin: self.origin, + } + } + + fn with_end(&self, end: usize) -> Self { + Tag { + span: Span { + start: self.span.start, + end, + }, + origin: self.origin, + } + } + + fn start(&self) -> usize { + self.span.start + } + + fn end(&self) -> usize { + self.span.end + } +} diff --git a/src/errors.rs b/src/errors.rs index d97435d22..3dfa644d4 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -14,20 +14,22 @@ pub enum Description { impl Description { pub fn from(value: Tagged>) -> Description { - let value_span = value.span(); let value_tag = value.tag(); - match value_span { - Span { start: 0, end: 0 } => Description::Synthetic(value.item.into()), + match value_tag { + Tag { + span: crate::data::meta::Span { start: 0, end: 0 }, + .. + } => Description::Synthetic(value.item.into()), _ => Description::Source(Tagged::from_item(value.item.into(), value_tag)), } } } impl Description { - fn into_label(self) -> Result, String> { + fn into_label(self) -> Result, String> { match self { - Description::Source(s) => Ok(Label::new_primary(s.span()).with_message(s.item)), + Description::Source(s) => Ok(Label::new_primary(s.tag()).with_message(s.item)), Description::Synthetic(s) => Err(s), } } @@ -81,7 +83,7 @@ impl ShellError { ) -> ShellError { ProximateShellError::RangeError { kind: expected.into(), - actual_kind: actual.copy_span(format!("{:?}", actual.item)), + actual_kind: actual.copy_tag(format!("{:?}", actual.item)), operation, } .start() @@ -116,9 +118,9 @@ impl ShellError { ProximateShellError::MissingProperty { subpath, expr }.start() } - pub(crate) fn missing_value(span: Option, reason: impl Into) -> ShellError { + pub(crate) fn missing_value(tag: Option, reason: impl Into) -> ShellError { ProximateShellError::MissingValue { - span, + tag, reason: reason.into(), } .start() @@ -127,28 +129,31 @@ impl ShellError { pub(crate) fn argument_error( command: impl Into, kind: ArgumentError, - span: Span, + tag: Tag, ) -> ShellError { ProximateShellError::ArgumentError { command: command.into(), error: kind, - span, + tag, } .start() } - pub(crate) fn invalid_external_word(span: Span) -> ShellError { + pub(crate) fn invalid_external_word(tag: Tag) -> ShellError { ProximateShellError::ArgumentError { command: "Invalid argument to Nu command (did you mean to call an external command?)" .into(), error: ArgumentError::InvalidExternalWord, - span, + tag, } .start() } pub(crate) fn parse_error( - error: nom::Err<(nom5_locate::LocatedSpan<&str>, nom::error::ErrorKind)>, + error: nom::Err<( + nom_locate::LocatedSpanEx<&str, uuid::Uuid>, + nom::error::ErrorKind, + )>, ) -> ShellError { use language_reporting::*; @@ -164,34 +169,34 @@ impl ShellError { } nom::Err::Failure(span) | nom::Err::Error(span) => { let diagnostic = Diagnostic::new(Severity::Error, format!("Parse Error")) - .with_label(Label::new_primary(Span::from(span.0))); + .with_label(Label::new_primary(Tag::from(span.0))); ShellError::diagnostic(diagnostic) } } } - pub(crate) fn diagnostic(diagnostic: Diagnostic) -> ShellError { + pub(crate) fn diagnostic(diagnostic: Diagnostic) -> ShellError { ProximateShellError::Diagnostic(ShellDiagnostic { diagnostic }).start() } - pub(crate) fn to_diagnostic(self) -> Diagnostic { + pub(crate) fn to_diagnostic(self) -> Diagnostic { match self.error { ProximateShellError::String(StringError { title, .. }) => { Diagnostic::new(Severity::Error, title) } ProximateShellError::InvalidCommand { command } => { Diagnostic::new(Severity::Error, "Invalid command") - .with_label(Label::new_primary(command.span)) + .with_label(Label::new_primary(command)) } - ProximateShellError::MissingValue { span, reason } => { + ProximateShellError::MissingValue { tag, reason } => { let mut d = Diagnostic::new( Severity::Bug, format!("Internal Error (missing value) :: {}", reason), ); - if let Some(span) = span { - d = d.with_label(Label::new_primary(span)); + if let Some(tag) = tag { + d = d.with_label(Label::new_primary(tag)); } d @@ -199,12 +204,12 @@ impl ShellError { ProximateShellError::ArgumentError { command, error, - span, + tag, } => match error { ArgumentError::InvalidExternalWord => Diagnostic::new( Severity::Error, format!("Invalid bare word for Nu command (did you intend to invoke an external command?)")) - .with_label(Label::new_primary(span)), + .with_label(Label::new_primary(tag)), ArgumentError::MissingMandatoryFlag(name) => Diagnostic::new( Severity::Error, format!( @@ -214,7 +219,7 @@ impl ShellError { Color::Black.bold().paint(name) ), ) - .with_label(Label::new_primary(span)), + .with_label(Label::new_primary(tag)), ArgumentError::MissingMandatoryPositional(name) => Diagnostic::new( Severity::Error, format!( @@ -224,7 +229,7 @@ impl ShellError { ), ) .with_label( - Label::new_primary(span).with_message(format!("requires {} parameter", name)), + Label::new_primary(tag).with_message(format!("requires {} parameter", name)), ), ArgumentError::MissingValueForName(name) => Diagnostic::new( Severity::Error, @@ -235,17 +240,17 @@ impl ShellError { Color::Black.bold().paint(name) ), ) - .with_label(Label::new_primary(span)), + .with_label(Label::new_primary(tag)), }, ProximateShellError::TypeError { expected, actual: Tagged { item: Some(actual), - tag: Tag { span, .. }, + tag, }, } => Diagnostic::new(Severity::Error, "Type Error").with_label( - Label::new_primary(span) + Label::new_primary(tag) .with_message(format!("Expected {}, found {}", expected, actual)), ), @@ -254,10 +259,10 @@ impl ShellError { actual: Tagged { item: None, - tag: Tag { span, .. }, + tag }, } => Diagnostic::new(Severity::Error, "Type Error") - .with_label(Label::new_primary(span).with_message(expected)), + .with_label(Label::new_primary(tag).with_message(expected)), ProximateShellError::RangeError { kind, @@ -265,10 +270,10 @@ impl ShellError { actual_kind: Tagged { item, - tag: Tag { span, .. }, + tag }, } => Diagnostic::new(Severity::Error, "Range Error").with_label( - Label::new_primary(span).with_message(format!( + Label::new_primary(tag).with_message(format!( "Expected to convert {} to {} while {}, but it was out of range", item, kind.desc(), @@ -279,11 +284,11 @@ impl ShellError { ProximateShellError::SyntaxError { problem: Tagged { - tag: Tag { span, .. }, + tag, .. }, } => Diagnostic::new(Severity::Error, "Syntax Error") - .with_label(Label::new_primary(span).with_message("Unexpected external command")), + .with_label(Label::new_primary(tag).with_message("Unexpected external command")), ProximateShellError::MissingProperty { subpath, expr } => { let subpath = subpath.into_label(); @@ -306,8 +311,8 @@ impl ShellError { ProximateShellError::Diagnostic(diag) => diag.diagnostic, ProximateShellError::CoerceError { left, right } => { Diagnostic::new(Severity::Error, "Coercion error") - .with_label(Label::new_primary(left.span()).with_message(left.item)) - .with_label(Label::new_secondary(right.span()).with_message(right.item)) + .with_label(Label::new_primary(left.tag()).with_message(left.item)) + .with_label(Label::new_secondary(right.tag()).with_message(right.item)) } } } @@ -315,26 +320,29 @@ impl ShellError { pub fn labeled_error( msg: impl Into, label: impl Into, - span: impl Into, + tag: impl Into, ) -> ShellError { ShellError::diagnostic( Diagnostic::new(Severity::Error, msg.into()) - .with_label(Label::new_primary(span.into()).with_message(label.into())), + .with_label(Label::new_primary(tag.into()).with_message(label.into())), ) } pub fn labeled_error_with_secondary( msg: impl Into, primary_label: impl Into, - primary_span: Span, + primary_span: impl Into, secondary_label: impl Into, - secondary_span: Span, + secondary_span: impl Into, ) -> ShellError { ShellError::diagnostic( Diagnostic::new_error(msg.into()) - .with_label(Label::new_primary(primary_span).with_message(primary_label.into())) .with_label( - Label::new_secondary(secondary_span).with_message(secondary_label.into()), + Label::new_primary(primary_span.into()).with_message(primary_label.into()), + ) + .with_label( + Label::new_secondary(secondary_span.into()) + .with_message(secondary_label.into()), ), ) } @@ -409,13 +417,13 @@ pub enum ProximateShellError { expr: Description, }, MissingValue { - span: Option, + tag: Option, reason: String, }, ArgumentError { command: String, error: ArgumentError, - span: Span, + tag: Tag, }, RangeError { kind: ExpectedRange, @@ -447,7 +455,7 @@ impl ToDebug for ProximateShellError { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ShellDiagnostic { - pub(crate) diagnostic: Diagnostic, + pub(crate) diagnostic: Diagnostic, } impl PartialEq for ShellDiagnostic { diff --git a/src/evaluate/evaluator.rs b/src/evaluate/evaluator.rs index 52edf6981..b9db82b54 100644 --- a/src/evaluate/evaluator.rs +++ b/src/evaluate/evaluator.rs @@ -38,13 +38,13 @@ pub(crate) fn evaluate_baseline_expr( source: &Text, ) -> Result, ShellError> { match &expr.item { - RawExpression::Literal(literal) => Ok(evaluate_literal(expr.copy_span(literal), source)), + RawExpression::Literal(literal) => Ok(evaluate_literal(expr.copy_tag(literal), source)), RawExpression::ExternalWord => Err(ShellError::argument_error( "Invalid external word", ArgumentError::InvalidExternalWord, - expr.span(), + expr.tag(), )), - RawExpression::FilePath(path) => Ok(Value::path(path.clone()).tagged(expr.span())), + RawExpression::FilePath(path) => Ok(Value::path(path.clone()).tagged(expr.tag())), RawExpression::Synthetic(hir::Synthetic::String(s)) => Ok(Value::string(s).tagged_unknown()), RawExpression::Variable(var) => evaluate_reference(var, scope, source), RawExpression::ExternalCommand(external) => evaluate_external(external, scope, source), @@ -53,13 +53,10 @@ pub(crate) fn evaluate_baseline_expr( let right = evaluate_baseline_expr(binary.right(), registry, scope, source)?; match left.compare(binary.op(), &*right) { - Ok(result) => Ok(Tagged::from_simple_spanned_item( - Value::boolean(result), - expr.span(), - )), + Ok(result) => Ok(Value::boolean(result).tagged(expr.tag())), Err((left_type, right_type)) => Err(ShellError::coerce_error( - binary.left().copy_span(left_type), - binary.right().copy_span(right_type), + binary.left().copy_tag(left_type), + binary.right().copy_tag(right_type), )), } } @@ -71,12 +68,14 @@ pub(crate) fn evaluate_baseline_expr( exprs.push(expr); } - Ok(Value::Table(exprs).tagged(Tag::unknown_origin(expr.span()))) + Ok(Value::Table(exprs).tagged(expr.tag())) + } + RawExpression::Block(block) => { + Ok( + Value::Block(Block::new(block.clone(), source.clone(), expr.tag())) + .tagged(expr.tag()), + ) } - RawExpression::Block(block) => Ok(Tagged::from_simple_spanned_item( - Value::Block(Block::new(block.clone(), source.clone(), expr.span())), - expr.span(), - )), RawExpression::Path(path) => { let value = evaluate_baseline_expr(path.head(), registry, scope, source)?; let mut item = value; @@ -92,18 +91,12 @@ pub(crate) fn evaluate_baseline_expr( )) } Some(next) => { - item = Tagged::from_simple_spanned_item( - next.clone().item, - (expr.span().start, name.span().end), - ) + item = next.clone().item.tagged(expr.tag()); } }; } - Ok(Tagged::from_simple_spanned_item( - item.item().clone(), - expr.span(), - )) + Ok(item.item().clone().tagged(expr.tag())) } RawExpression::Boolean(_boolean) => unimplemented!(), } @@ -113,9 +106,9 @@ fn evaluate_literal(literal: Tagged<&hir::Literal>, source: &Text) -> Tagged int.into(), hir::Literal::Size(int, unit) => unit.compute(int), - hir::Literal::String(span) => Value::string(span.slice(source)), - hir::Literal::GlobPattern => Value::pattern(literal.span().slice(source)), - hir::Literal::Bare => Value::string(literal.span().slice(source)), + hir::Literal::String(tag) => Value::string(tag.slice(source)), + hir::Literal::GlobPattern => Value::pattern(literal.tag().slice(source)), + hir::Literal::Bare => Value::string(literal.tag().slice(source)), }; literal.map(|_| result) @@ -127,12 +120,12 @@ fn evaluate_reference( source: &Text, ) -> Result, ShellError> { match name { - hir::Variable::It(span) => Ok(scope.it.item.clone().simple_spanned(span)), - hir::Variable::Other(span) => Ok(scope + hir::Variable::It(tag) => Ok(scope.it.item.clone().tagged(*tag)), + hir::Variable::Other(tag) => Ok(scope .vars - .get(span.slice(source)) + .get(tag.slice(source)) .map(|v| v.clone()) - .unwrap_or_else(|| Value::nothing().simple_spanned(span))), + .unwrap_or_else(|| Value::nothing().tagged(*tag))), } } @@ -142,6 +135,6 @@ fn evaluate_external( _source: &Text, ) -> Result, ShellError> { Err(ShellError::syntax_error( - "Unexpected external command".tagged(external.name()), + "Unexpected external command".tagged(*external.name()), )) } diff --git a/src/format/table.rs b/src/format/table.rs index 717e3c4a2..286be222c 100644 --- a/src/format/table.rs +++ b/src/format/table.rs @@ -204,7 +204,7 @@ impl RenderView for TableView { let mut table = Table::new(); - let table_mode = crate::data::config::config(Span::unknown())? + let table_mode = crate::data::config::config(Tag::unknown())? .get("table_mode") .map(|s| match s.as_string().unwrap().as_ref() { "light" => TableMode::Light, diff --git a/src/lib.rs b/src/lib.rs index a18343df9..60546e385 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,7 +23,7 @@ mod utils; pub use crate::commands::command::{CallInfo, ReturnSuccess, ReturnValue}; pub use crate::context::{SourceMap, SpanSource}; pub use crate::env::host::BasicHost; -pub use crate::parser::hir::SyntaxType; +pub use crate::parser::hir::SyntaxShape; pub use crate::parser::parse::token_tree_builder::TokenTreeBuilder; pub use crate::plugin::{serve_plugin, Plugin}; pub use crate::utils::{AbsoluteFile, AbsolutePath, RelativePath}; @@ -31,7 +31,7 @@ pub use cli::cli; pub use data::config::{APP_INFO, config_path}; pub use data::base::{Primitive, Value}; pub use data::dict::{Dictionary, TaggedDictBuilder}; -pub use data::meta::{Span, Tag, Tagged, TaggedItem}; +pub use data::meta::{Tag, Tagged, TaggedItem}; pub use errors::{CoerceInto, ShellError}; pub use num_traits::cast::ToPrimitive; pub use parser::parse::text::Text; diff --git a/src/parser.rs b/src/parser.rs index 2fd891efb..3b3ac1a13 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -21,10 +21,10 @@ pub(crate) use parse::unit::Unit; pub(crate) use parse_command::parse_command; pub(crate) use registry::CommandRegistry; -pub fn parse(input: &str) -> Result { +pub fn parse(input: &str, origin: uuid::Uuid) -> Result { let _ = pretty_env_logger::try_init(); - match pipeline(nom_input(input)) { + match pipeline(nom_input(input, origin)) { Ok((_rest, val)) => Ok(val), Err(err) => Err(ShellError::parse_error(err)), } diff --git a/src/parser/deserializer.rs b/src/parser/deserializer.rs index d5427766b..f9b9146e5 100644 --- a/src/parser/deserializer.rs +++ b/src/parser/deserializer.rs @@ -37,7 +37,7 @@ impl<'de> ConfigDeserializer<'de> { let value: Option> = if name == "rest" { let positional = self.call.args.slice_from(self.position); self.position += positional.len(); - Some(Value::Table(positional).tagged_unknown()) // TODO: correct span + Some(Value::Table(positional).tagged_unknown()) // TODO: correct tag } else { if self.call.args.has(name) { self.call.args.get(name).map(|x| x.clone()) @@ -52,9 +52,7 @@ impl<'de> ConfigDeserializer<'de> { self.stack.push(DeserializerItem { key_struct_field: Some((name.to_string(), name)), - val: value.unwrap_or_else(|| { - Value::nothing().tagged(Tag::unknown_origin(self.call.name_span)) - }), + val: value.unwrap_or_else(|| Value::nothing().tagged(self.call.name_tag)), }); Ok(()) diff --git a/src/parser/hir.rs b/src/parser/hir.rs index 90bb38796..96eb7272a 100644 --- a/src/parser/hir.rs +++ b/src/parser/hir.rs @@ -25,7 +25,7 @@ pub(crate) use self::external_command::ExternalCommand; pub(crate) use self::named::NamedArguments; pub(crate) use self::path::Path; -pub use self::baseline_parse_tokens::SyntaxType; +pub use self::baseline_parse_tokens::SyntaxShape; pub fn path(head: impl Into, tail: Vec>>) -> Path { Path::new( @@ -131,72 +131,57 @@ impl RawExpression { pub type Expression = Tagged; impl Expression { - pub(crate) fn number(i: impl Into, span: impl Into) -> Expression { - Tagged::from_simple_spanned_item(RawExpression::Literal(Literal::Number(i.into())), span) + pub(crate) fn number(i: impl Into, tag: impl Into) -> Expression { + RawExpression::Literal(Literal::Number(i.into())).tagged(tag.into()) } pub(crate) fn size( i: impl Into, unit: impl Into, - span: impl Into, + tag: impl Into, ) -> Expression { - Tagged::from_simple_spanned_item( - RawExpression::Literal(Literal::Size(i.into(), unit.into())), - span, - ) + RawExpression::Literal(Literal::Size(i.into(), unit.into())).tagged(tag.into()) } pub(crate) fn synthetic_string(s: impl Into) -> Expression { RawExpression::Synthetic(Synthetic::String(s.into())).tagged_unknown() } - pub(crate) fn string(inner: impl Into, outer: impl Into) -> Expression { - Tagged::from_simple_spanned_item( - RawExpression::Literal(Literal::String(inner.into())), - outer.into(), - ) + pub(crate) fn string(inner: impl Into, outer: impl Into) -> Expression { + RawExpression::Literal(Literal::String(inner.into())).tagged(outer.into()) } - pub(crate) fn file_path(path: impl Into, outer: impl Into) -> Expression { - Tagged::from_simple_spanned_item(RawExpression::FilePath(path.into()), outer.into()) + pub(crate) fn file_path(path: impl Into, outer: impl Into) -> Expression { + RawExpression::FilePath(path.into()).tagged(outer) } - pub(crate) fn bare(span: impl Into) -> Expression { - Tagged::from_simple_spanned_item(RawExpression::Literal(Literal::Bare), span.into()) + pub(crate) fn bare(tag: impl Into) -> Expression { + RawExpression::Literal(Literal::Bare).tagged(tag) } pub(crate) fn pattern(tag: impl Into) -> Expression { RawExpression::Literal(Literal::GlobPattern).tagged(tag.into()) } - pub(crate) fn variable(inner: impl Into, outer: impl Into) -> Expression { - Tagged::from_simple_spanned_item( - RawExpression::Variable(Variable::Other(inner.into())), - outer.into(), - ) + pub(crate) fn variable(inner: impl Into, outer: impl Into) -> Expression { + RawExpression::Variable(Variable::Other(inner.into())).tagged(outer) } - pub(crate) fn external_command(inner: impl Into, outer: impl Into) -> Expression { - Tagged::from_simple_spanned_item( - RawExpression::ExternalCommand(ExternalCommand::new(inner.into())), - outer.into(), - ) + pub(crate) fn external_command(inner: impl Into, outer: impl Into) -> Expression { + RawExpression::ExternalCommand(ExternalCommand::new(inner.into())).tagged(outer) } - pub(crate) fn it_variable(inner: impl Into, outer: impl Into) -> Expression { - Tagged::from_simple_spanned_item( - RawExpression::Variable(Variable::It(inner.into())), - outer.into(), - ) + pub(crate) fn it_variable(inner: impl Into, outer: impl Into) -> Expression { + RawExpression::Variable(Variable::It(inner.into())).tagged(outer) } } impl ToDebug for Expression { fn fmt_debug(&self, f: &mut fmt::Formatter, source: &str) -> fmt::Result { match self.item() { - RawExpression::Literal(l) => l.tagged(self.span()).fmt_debug(f, source), + RawExpression::Literal(l) => l.tagged(self.tag()).fmt_debug(f, source), RawExpression::FilePath(p) => write!(f, "{}", p.display()), - RawExpression::ExternalWord => write!(f, "{}", self.span().slice(source)), + RawExpression::ExternalWord => write!(f, "{}", self.tag().slice(source)), RawExpression::Synthetic(Synthetic::String(s)) => write!(f, "{:?}", s), RawExpression::Variable(Variable::It(_)) => write!(f, "$it"), RawExpression::Variable(Variable::Other(s)) => write!(f, "${}", s.slice(source)), @@ -242,7 +227,7 @@ impl From> for Expression { pub enum Literal { Number(Number), Size(Number, Unit), - String(Span), + String(Tag), GlobPattern, Bare, } @@ -252,9 +237,9 @@ impl ToDebug for Tagged<&Literal> { match self.item() { Literal::Number(number) => write!(f, "{:?}", *number), Literal::Size(number, unit) => write!(f, "{:?}{:?}", *number, unit), - Literal::String(span) => write!(f, "{}", span.slice(source)), - Literal::GlobPattern => write!(f, "{}", self.span().slice(source)), - Literal::Bare => write!(f, "{}", self.span().slice(source)), + Literal::String(tag) => write!(f, "{}", tag.slice(source)), + Literal::GlobPattern => write!(f, "{}", self.tag().slice(source)), + Literal::Bare => write!(f, "{}", self.tag().slice(source)), } } } @@ -273,6 +258,6 @@ impl Literal { #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] pub enum Variable { - It(Span), - Other(Span), + It(Tag), + Other(Tag), } diff --git a/src/parser/hir/baseline_parse.rs b/src/parser/hir/baseline_parse.rs index 5248bde5f..267494f27 100644 --- a/src/parser/hir/baseline_parse.rs +++ b/src/parser/hir/baseline_parse.rs @@ -10,19 +10,19 @@ pub fn baseline_parse_single_token( source: &Text, ) -> Result { Ok(match *token.item() { - RawToken::Number(number) => hir::Expression::number(number.to_number(source), token.span()), + RawToken::Number(number) => hir::Expression::number(number.to_number(source), token.tag()), RawToken::Size(int, unit) => { - hir::Expression::size(int.to_number(source), unit, token.span()) + hir::Expression::size(int.to_number(source), unit, token.tag()) } - RawToken::String(span) => hir::Expression::string(span, token.span()), - RawToken::Variable(span) if span.slice(source) == "it" => { - hir::Expression::it_variable(span, token.span()) + RawToken::String(tag) => hir::Expression::string(tag, token.tag()), + RawToken::Variable(tag) if tag.slice(source) == "it" => { + hir::Expression::it_variable(tag, token.tag()) } - RawToken::Variable(span) => hir::Expression::variable(span, token.span()), - RawToken::ExternalCommand(span) => hir::Expression::external_command(span, token.span()), - RawToken::ExternalWord => return Err(ShellError::invalid_external_word(token.span())), - RawToken::GlobPattern => hir::Expression::pattern(token.span()), - RawToken::Bare => hir::Expression::bare(token.span()), + RawToken::Variable(tag) => hir::Expression::variable(tag, token.tag()), + RawToken::ExternalCommand(tag) => hir::Expression::external_command(tag, token.tag()), + RawToken::ExternalWord => return Err(ShellError::invalid_external_word(token.tag())), + RawToken::GlobPattern => hir::Expression::pattern(token.tag()), + RawToken::Bare => hir::Expression::bare(token.tag()), }) } @@ -31,24 +31,24 @@ pub fn baseline_parse_token_as_number( source: &Text, ) -> Result { Ok(match *token.item() { - RawToken::Variable(span) if span.slice(source) == "it" => { - hir::Expression::it_variable(span, token.span()) + RawToken::Variable(tag) if tag.slice(source) == "it" => { + hir::Expression::it_variable(tag, token.tag()) } - RawToken::ExternalCommand(span) => hir::Expression::external_command(span, token.span()), - RawToken::ExternalWord => return Err(ShellError::invalid_external_word(token.span())), - RawToken::Variable(span) => hir::Expression::variable(span, token.span()), - RawToken::Number(number) => hir::Expression::number(number.to_number(source), token.span()), + RawToken::ExternalCommand(tag) => hir::Expression::external_command(tag, token.tag()), + RawToken::ExternalWord => return Err(ShellError::invalid_external_word(token.tag())), + RawToken::Variable(tag) => hir::Expression::variable(tag, token.tag()), + RawToken::Number(number) => hir::Expression::number(number.to_number(source), token.tag()), RawToken::Size(number, unit) => { - hir::Expression::size(number.to_number(source), unit, token.span()) + hir::Expression::size(number.to_number(source), unit, token.tag()) } - RawToken::Bare => hir::Expression::bare(token.span()), + RawToken::Bare => hir::Expression::bare(token.tag()), RawToken::GlobPattern => { return Err(ShellError::type_error( "Number", "glob pattern".to_string().tagged(token.tag()), )) } - RawToken::String(span) => hir::Expression::string(span, token.span()), + RawToken::String(tag) => hir::Expression::string(tag, token.tag()), }) } @@ -57,22 +57,22 @@ pub fn baseline_parse_token_as_string( source: &Text, ) -> Result { Ok(match *token.item() { - RawToken::Variable(span) if span.slice(source) == "it" => { - hir::Expression::it_variable(span, token.span()) + RawToken::Variable(tag) if tag.slice(source) == "it" => { + hir::Expression::it_variable(tag, token.tag()) } - RawToken::ExternalCommand(span) => hir::Expression::external_command(span, token.span()), - RawToken::ExternalWord => return Err(ShellError::invalid_external_word(token.span())), - RawToken::Variable(span) => hir::Expression::variable(span, token.span()), - RawToken::Number(_) => hir::Expression::bare(token.span()), - RawToken::Size(_, _) => hir::Expression::bare(token.span()), - RawToken::Bare => hir::Expression::bare(token.span()), + RawToken::ExternalCommand(tag) => hir::Expression::external_command(tag, token.tag()), + RawToken::ExternalWord => return Err(ShellError::invalid_external_word(token.tag())), + RawToken::Variable(tag) => hir::Expression::variable(tag, token.tag()), + RawToken::Number(_) => hir::Expression::bare(token.tag()), + RawToken::Size(_, _) => hir::Expression::bare(token.tag()), + RawToken::Bare => hir::Expression::bare(token.tag()), RawToken::GlobPattern => { return Err(ShellError::type_error( "String", "glob pattern".tagged(token.tag()), )) } - RawToken::String(span) => hir::Expression::string(span, token.span()), + RawToken::String(tag) => hir::Expression::string(tag, token.tag()), }) } @@ -82,26 +82,25 @@ pub fn baseline_parse_token_as_path( source: &Text, ) -> Result { Ok(match *token.item() { - RawToken::Variable(span) if span.slice(source) == "it" => { - hir::Expression::it_variable(span, token.span()) + RawToken::Variable(tag) if tag.slice(source) == "it" => { + hir::Expression::it_variable(tag, token.tag()) + } + RawToken::ExternalCommand(tag) => hir::Expression::external_command(tag, token.tag()), + RawToken::ExternalWord => return Err(ShellError::invalid_external_word(token.tag())), + RawToken::Variable(tag) => hir::Expression::variable(tag, token.tag()), + RawToken::Number(_) => hir::Expression::bare(token.tag()), + RawToken::Size(_, _) => hir::Expression::bare(token.tag()), + RawToken::Bare => { + hir::Expression::file_path(expand_path(token.tag().slice(source), context), token.tag()) } - RawToken::ExternalCommand(span) => hir::Expression::external_command(span, token.span()), - RawToken::ExternalWord => return Err(ShellError::invalid_external_word(token.span())), - RawToken::Variable(span) => hir::Expression::variable(span, token.span()), - RawToken::Number(_) => hir::Expression::bare(token.span()), - RawToken::Size(_, _) => hir::Expression::bare(token.span()), - RawToken::Bare => hir::Expression::file_path( - expand_path(token.span().slice(source), context), - token.span(), - ), RawToken::GlobPattern => { return Err(ShellError::type_error( "Path", "glob pattern".tagged(token.tag()), )) } - RawToken::String(span) => { - hir::Expression::file_path(expand_path(span.slice(source), context), token.span()) + RawToken::String(tag) => { + hir::Expression::file_path(expand_path(tag.slice(source), context), token.tag()) } }) } @@ -112,25 +111,24 @@ pub fn baseline_parse_token_as_pattern( source: &Text, ) -> Result { Ok(match *token.item() { - RawToken::Variable(span) if span.slice(source) == "it" => { - hir::Expression::it_variable(span, token.span()) + RawToken::Variable(tag) if tag.slice(source) == "it" => { + hir::Expression::it_variable(tag, token.tag()) } RawToken::ExternalCommand(_) => { return Err(ShellError::syntax_error( "Invalid external command".to_string().tagged(token.tag()), )) } - RawToken::ExternalWord => return Err(ShellError::invalid_external_word(token.span())), - RawToken::Variable(span) => hir::Expression::variable(span, token.span()), - RawToken::Number(_) => hir::Expression::bare(token.span()), - RawToken::Size(_, _) => hir::Expression::bare(token.span()), - RawToken::GlobPattern => hir::Expression::pattern(token.span()), - RawToken::Bare => hir::Expression::file_path( - expand_path(token.span().slice(source), context), - token.span(), - ), - RawToken::String(span) => { - hir::Expression::file_path(expand_path(span.slice(source), context), token.span()) + RawToken::ExternalWord => return Err(ShellError::invalid_external_word(token.tag())), + RawToken::Variable(tag) => hir::Expression::variable(tag, token.tag()), + RawToken::Number(_) => hir::Expression::bare(token.tag()), + RawToken::Size(_, _) => hir::Expression::bare(token.tag()), + RawToken::GlobPattern => hir::Expression::pattern(token.tag()), + RawToken::Bare => { + hir::Expression::file_path(expand_path(token.tag().slice(source), context), token.tag()) + } + RawToken::String(tag) => { + hir::Expression::file_path(expand_path(tag.slice(source), context), token.tag()) } }) } diff --git a/src/parser/hir/baseline_parse_tokens.rs b/src/parser/hir/baseline_parse_tokens.rs index ac2c703d3..8413bd07e 100644 --- a/src/parser/hir/baseline_parse_tokens.rs +++ b/src/parser/hir/baseline_parse_tokens.rs @@ -8,7 +8,7 @@ use crate::parser::{ }, DelimitedNode, Delimiter, PathNode, RawToken, TokenNode, }; -use crate::{Span, Tag, Tagged, TaggedItem, Text}; +use crate::{Tag, Tagged, TaggedItem, Text}; use derive_new::new; use log::trace; use serde::{Deserialize, Serialize}; @@ -17,7 +17,7 @@ pub fn baseline_parse_tokens( token_nodes: &mut TokensIterator<'_>, context: &Context, source: &Text, - syntax_type: SyntaxType, + syntax_type: SyntaxShape, ) -> Result, ShellError> { let mut exprs: Vec = vec![]; @@ -34,7 +34,7 @@ pub fn baseline_parse_tokens( } #[derive(Debug, Copy, Clone, Serialize, Deserialize)] -pub enum SyntaxType { +pub enum SyntaxShape { Any, List, Literal, @@ -49,21 +49,21 @@ pub enum SyntaxType { Boolean, } -impl std::fmt::Display for SyntaxType { +impl std::fmt::Display for SyntaxShape { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { - SyntaxType::Any => write!(f, "Any"), - SyntaxType::List => write!(f, "List"), - SyntaxType::Literal => write!(f, "Literal"), - SyntaxType::String => write!(f, "String"), - SyntaxType::Member => write!(f, "Member"), - SyntaxType::Variable => write!(f, "Variable"), - SyntaxType::Number => write!(f, "Number"), - SyntaxType::Path => write!(f, "Path"), - SyntaxType::Pattern => write!(f, "Pattern"), - SyntaxType::Binary => write!(f, "Binary"), - SyntaxType::Block => write!(f, "Block"), - SyntaxType::Boolean => write!(f, "Boolean"), + SyntaxShape::Any => write!(f, "Any"), + SyntaxShape::List => write!(f, "List"), + SyntaxShape::Literal => write!(f, "Literal"), + SyntaxShape::String => write!(f, "String"), + SyntaxShape::Member => write!(f, "Member"), + SyntaxShape::Variable => write!(f, "Variable"), + SyntaxShape::Number => write!(f, "Number"), + SyntaxShape::Path => write!(f, "Path"), + SyntaxShape::Pattern => write!(f, "Pattern"), + SyntaxShape::Binary => write!(f, "Binary"), + SyntaxShape::Block => write!(f, "Block"), + SyntaxShape::Boolean => write!(f, "Boolean"), } } } @@ -72,7 +72,7 @@ pub fn baseline_parse_next_expr( tokens: &mut TokensIterator, context: &Context, source: &Text, - syntax_type: SyntaxType, + syntax_type: SyntaxShape, ) -> Result { let next = tokens .next() @@ -81,69 +81,69 @@ pub fn baseline_parse_next_expr( trace!(target: "nu::parser::parse_one_expr", "syntax_type={:?}, token={:?}", syntax_type, next); match (syntax_type, next) { - (SyntaxType::Path, TokenNode::Token(token)) => { + (SyntaxShape::Path, TokenNode::Token(token)) => { return baseline_parse_token_as_path(token, context, source) } - (SyntaxType::Path, token) => { + (SyntaxShape::Path, token) => { return Err(ShellError::type_error( "Path", - token.type_name().simple_spanned(token.span()), + token.type_name().tagged(token.tag()), )) } - (SyntaxType::Pattern, TokenNode::Token(token)) => { + (SyntaxShape::Pattern, TokenNode::Token(token)) => { return baseline_parse_token_as_pattern(token, context, source) } - (SyntaxType::Pattern, token) => { + (SyntaxShape::Pattern, token) => { return Err(ShellError::type_error( "Path", - token.type_name().simple_spanned(token.span()), + token.type_name().tagged(token.tag()), )) } - (SyntaxType::String, TokenNode::Token(token)) => { + (SyntaxShape::String, TokenNode::Token(token)) => { return baseline_parse_token_as_string(token, source); } - (SyntaxType::String, token) => { + (SyntaxShape::String, token) => { return Err(ShellError::type_error( "String", - token.type_name().simple_spanned(token.span()), + token.type_name().tagged(token.tag()), )) } - (SyntaxType::Number, TokenNode::Token(token)) => { + (SyntaxShape::Number, TokenNode::Token(token)) => { return Ok(baseline_parse_token_as_number(token, source)?); } - (SyntaxType::Number, token) => { + (SyntaxShape::Number, token) => { return Err(ShellError::type_error( "Numeric", - token.type_name().simple_spanned(token.span()), + token.type_name().tagged(token.tag()), )) } // TODO: More legit member processing - (SyntaxType::Member, TokenNode::Token(token)) => { + (SyntaxShape::Member, TokenNode::Token(token)) => { return baseline_parse_token_as_string(token, source); } - (SyntaxType::Member, token) => { + (SyntaxShape::Member, token) => { return Err(ShellError::type_error( "member", - token.type_name().simple_spanned(token.span()), + token.type_name().tagged(token.tag()), )) } - (SyntaxType::Any, _) => {} - (SyntaxType::List, _) => {} - (SyntaxType::Literal, _) => {} - (SyntaxType::Variable, _) => {} - (SyntaxType::Binary, _) => {} - (SyntaxType::Block, _) => {} - (SyntaxType::Boolean, _) => {} + (SyntaxShape::Any, _) => {} + (SyntaxShape::List, _) => {} + (SyntaxShape::Literal, _) => {} + (SyntaxShape::Variable, _) => {} + (SyntaxShape::Binary, _) => {} + (SyntaxShape::Block, _) => {} + (SyntaxShape::Boolean, _) => {} }; let first = baseline_parse_semantic_token(next, context, source)?; @@ -162,7 +162,7 @@ pub fn baseline_parse_next_expr( return Err(ShellError::labeled_error( "Expected something after an operator", "operator", - op.span(), + op.tag(), )) } Some(token) => baseline_parse_semantic_token(token, context, source)?, @@ -171,75 +171,66 @@ pub fn baseline_parse_next_expr( // We definitely have a binary expression here -- let's see if we should coerce it into a block match syntax_type { - SyntaxType::Any => { - let span = (first.span().start, second.span().end); + SyntaxShape::Any => { + let tag = first.tag().until(second.tag()); let binary = hir::Binary::new(first, op, second); let binary = hir::RawExpression::Binary(Box::new(binary)); - let binary = Tagged::from_simple_spanned_item(binary, span); + let binary = binary.tagged(tag); Ok(binary) } - SyntaxType::Block => { - let span = (first.span().start, second.span().end); + SyntaxShape::Block => { + let tag = first.tag().until(second.tag()); let path: Tagged = match first { Tagged { item: hir::RawExpression::Literal(hir::Literal::Bare), - tag: Tag { span, .. }, + tag, } => { - let string = - Tagged::from_simple_spanned_item(span.slice(source).to_string(), span); + let string = tag.slice(source).to_string().tagged(tag); let path = hir::Path::new( - Tagged::from_simple_spanned_item( - // TODO: Deal with synthetic nodes that have no representation at all in source - hir::RawExpression::Variable(hir::Variable::It(Span::from((0, 0)))), - (0, 0), - ), + // TODO: Deal with synthetic nodes that have no representation at all in source + hir::RawExpression::Variable(hir::Variable::It(Tag::unknown())) + .tagged(Tag::unknown()), vec![string], ); let path = hir::RawExpression::Path(Box::new(path)); - Tagged::from_simple_spanned_item(path, first.span()) + path.tagged(first.tag()) } Tagged { item: hir::RawExpression::Literal(hir::Literal::String(inner)), - tag: Tag { span, .. }, + tag, } => { - let string = - Tagged::from_simple_spanned_item(inner.slice(source).to_string(), span); + let string = inner.slice(source).to_string().tagged(tag); let path = hir::Path::new( - Tagged::from_simple_spanned_item( - // TODO: Deal with synthetic nodes that have no representation at all in source - hir::RawExpression::Variable(hir::Variable::It(Span::from((0, 0)))), - (0, 0), - ), + // TODO: Deal with synthetic nodes that have no representation at all in source + hir::RawExpression::Variable(hir::Variable::It(Tag::unknown())) + .tagged_unknown(), vec![string], ); let path = hir::RawExpression::Path(Box::new(path)); - Tagged::from_simple_spanned_item(path, first.span()) + path.tagged(first.tag()) } Tagged { item: hir::RawExpression::Variable(..), .. } => first, - Tagged { - tag: Tag { span, .. }, - item, - } => { + Tagged { tag, item } => { return Err(ShellError::labeled_error( "The first part of an un-braced block must be a column name", item.type_name(), - span, + tag, )) } }; let binary = hir::Binary::new(path, op, second); let binary = hir::RawExpression::Binary(Box::new(binary)); - let binary = Tagged::from_simple_spanned_item(binary, span); + let binary = binary.tagged(tag); let block = hir::RawExpression::Block(vec![binary]); - let block = Tagged::from_simple_spanned_item(block, span); + let block = block.tagged(tag); Ok(block) } @@ -265,11 +256,11 @@ pub fn baseline_parse_semantic_token( "Unexpected operator".tagged(op.tag), )), TokenNode::Flag(flag) => Err(ShellError::syntax_error("Unexpected flag".tagged(flag.tag))), - TokenNode::Member(span) => Err(ShellError::syntax_error( - "BUG: Top-level member".tagged(span), + TokenNode::Member(tag) => Err(ShellError::syntax_error( + "BUG: Top-level member".tagged(*tag), )), - TokenNode::Whitespace(span) => Err(ShellError::syntax_error( - "BUG: Whitespace found during parse".tagged(span), + TokenNode::Whitespace(tag) => Err(ShellError::syntax_error( + "BUG: Whitespace found during parse".tagged(*tag), )), TokenNode::Error(error) => Err(*error.item.clone()), TokenNode::Path(path) => baseline_parse_path(path, context, source), @@ -288,11 +279,11 @@ pub fn baseline_parse_delimited( &mut TokensIterator::new(children), context, source, - SyntaxType::Any, + SyntaxShape::Any, )?; let expr = hir::RawExpression::Block(exprs); - Ok(Tagged::from_simple_spanned_item(expr, token.span())) + Ok(expr.tagged(token.tag())) } Delimiter::Paren => unimplemented!(), Delimiter::Square => { @@ -301,11 +292,11 @@ pub fn baseline_parse_delimited( &mut TokensIterator::new(children), context, source, - SyntaxType::Any, + SyntaxShape::Any, )?; let expr = hir::RawExpression::List(exprs); - Ok(expr.tagged(Tag::unknown_origin(token.span()))) + Ok(expr.tagged(token.tag())) } } } @@ -322,8 +313,8 @@ pub fn baseline_parse_path( for part in token.tail() { let string = match part { TokenNode::Token(token) => match token.item() { - RawToken::Bare => token.span().slice(source), - RawToken::String(span) => span.slice(source), + RawToken::Bare => token.tag().slice(source), + RawToken::String(tag) => tag.slice(source), RawToken::Number(_) | RawToken::Size(..) | RawToken::Variable(_) @@ -332,26 +323,26 @@ pub fn baseline_parse_path( | RawToken::ExternalWord => { return Err(ShellError::type_error( "String", - token.type_name().simple_spanned(part), + token.type_name().tagged(part.tag()), )) } }, - TokenNode::Member(span) => span.slice(source), + TokenNode::Member(tag) => tag.slice(source), // TODO: Make this impossible other => { return Err(ShellError::syntax_error( - format!("{} in path", other.type_name()).tagged(other.span()), + format!("{} in path", other.type_name()).tagged(other.tag()), )) } } .to_string(); - tail.push(string.simple_spanned(part)); + tail.push(string.tagged(part.tag())); } - Ok(hir::path(head, tail).simple_spanned(token).into()) + Ok(hir::path(head, tail).tagged(token.tag()).into()) } #[derive(Debug, new)] diff --git a/src/parser/hir/external_command.rs b/src/parser/hir/external_command.rs index 8511cce1e..28865330d 100644 --- a/src/parser/hir/external_command.rs +++ b/src/parser/hir/external_command.rs @@ -9,7 +9,7 @@ use std::fmt; )] #[get = "pub(crate)"] pub struct ExternalCommand { - name: Span, + name: Tag, } impl ToDebug for ExternalCommand { diff --git a/src/parser/hir/named.rs b/src/parser/hir/named.rs index 96d5132fb..838f643be 100644 --- a/src/parser/hir/named.rs +++ b/src/parser/hir/named.rs @@ -1,7 +1,6 @@ use crate::parser::hir::Expression; use crate::parser::Flag; use crate::prelude::*; -use crate::Span; use derive_new::new; use indexmap::IndexMap; use log::trace; @@ -11,7 +10,7 @@ use std::fmt; #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] pub enum NamedValue { AbsentSwitch, - PresentSwitch(Span), + PresentSwitch(Tag), AbsentValue, Value(Expression), } @@ -27,7 +26,7 @@ impl ToDebug for NamedArguments { for (name, value) in &self.named { match value { NamedValue::AbsentSwitch => continue, - NamedValue::PresentSwitch(span) => write!(f, " --{}", span.slice(source))?, + NamedValue::PresentSwitch(tag) => write!(f, " --{}", tag.slice(source))?, NamedValue::AbsentValue => continue, NamedValue::Value(expr) => write!(f, " --{} {}", name, expr.debug(source))?, } diff --git a/src/parser/parse/files.rs b/src/parser/parse/files.rs index 173da54a8..6cedb1e99 100644 --- a/src/parser/parse/files.rs +++ b/src/parser/parse/files.rs @@ -1,6 +1,7 @@ -use crate::Span; +use crate::Tag; use derive_new::new; use language_reporting::{FileName, Location}; +use uuid::Uuid; #[derive(new, Debug, Clone)] pub struct Files { @@ -8,26 +9,30 @@ pub struct Files { } impl language_reporting::ReportingFiles for Files { - type Span = Span; - type FileId = usize; + type Span = Tag; + type FileId = Uuid; fn byte_span( &self, - _file: Self::FileId, + file: Self::FileId, from_index: usize, to_index: usize, ) -> Option { - Some(Span::from((from_index, to_index))) + Some(Tag::from((from_index, to_index, file))) } - fn file_id(&self, _span: Self::Span) -> Self::FileId { - 0 + + fn file_id(&self, tag: Self::Span) -> Self::FileId { + tag.origin.unwrap() } + fn file_name(&self, _file: Self::FileId) -> FileName { FileName::Verbatim(format!("shell")) } + fn byte_index(&self, _file: Self::FileId, _line: usize, _column: usize) -> Option { unimplemented!("byte_index") } + fn location(&self, _file: Self::FileId, byte_index: usize) -> Option { let source = &self.snippet; let mut seen_lines = 0; @@ -51,14 +56,15 @@ impl language_reporting::ReportingFiles for Files { None } } - fn line_span(&self, _file: Self::FileId, lineno: usize) -> Option { + + fn line_span(&self, file: Self::FileId, lineno: usize) -> Option { let source = &self.snippet; let mut seen_lines = 0; let mut seen_bytes = 0; for (pos, _) in source.match_indices('\n') { if seen_lines == lineno { - return Some(Span::from((seen_bytes, pos))); + return Some(Tag::from((seen_bytes, pos, file))); } else { seen_lines += 1; seen_bytes = pos + 1; @@ -66,17 +72,18 @@ impl language_reporting::ReportingFiles for Files { } if seen_lines == 0 { - Some(Span::from((0, self.snippet.len() - 1))) + Some(Tag::from((0, self.snippet.len() - 1, file))) } else { None } } - fn source(&self, span: Self::Span) -> Option { - if span.start > span.end { + + fn source(&self, tag: Self::Span) -> Option { + if tag.span.start > tag.span.end { return None; - } else if span.end >= self.snippet.len() { + } else if tag.span.end >= self.snippet.len() { return None; } - Some(self.snippet[span.start..span.end].to_string()) + Some(tag.slice(&self.snippet).to_string()) } } diff --git a/src/parser/parse/flag.rs b/src/parser/parse/flag.rs index 096d69879..09d1e8633 100644 --- a/src/parser/parse/flag.rs +++ b/src/parser/parse/flag.rs @@ -1,4 +1,4 @@ -use crate::Span; +use crate::Tag; use derive_new::new; use getset::Getters; use serde::{Deserialize, Serialize}; @@ -13,5 +13,5 @@ pub enum FlagKind { #[get = "pub(crate)"] pub struct Flag { kind: FlagKind, - name: Span, + name: Tag, } diff --git a/src/parser/parse/parser.rs b/src/parser/parse/parser.rs index 0be05af06..f30eb2c11 100644 --- a/src/parser/parse/parser.rs +++ b/src/parser/parse/parser.rs @@ -5,7 +5,7 @@ use crate::parser::parse::{ tokens::*, unit::*, }; use crate::prelude::*; -use crate::{Span, Tagged}; +use crate::{Tag, Tagged}; use nom; use nom::branch::*; use nom::bytes::complete::*; @@ -18,15 +18,16 @@ use log::trace; use nom::dbg; use nom::*; use nom::{AsBytes, FindSubstring, IResult, InputLength, InputTake, Slice}; -use nom5_locate::{position, LocatedSpan}; +use nom_locate::{position, LocatedSpanEx}; use serde::{Deserialize, Serialize}; use std::fmt::Debug; use std::str::FromStr; +use uuid::Uuid; -pub type NomSpan<'a> = LocatedSpan<&'a str>; +pub type NomSpan<'a> = LocatedSpanEx<&'a str, Uuid>; -pub fn nom_input(s: &str) -> NomSpan<'_> { - LocatedSpan::new(s) +pub fn nom_input(s: &str, origin: Uuid) -> NomSpan<'_> { + LocatedSpanEx::new_extra(s, origin) } macro_rules! operator { @@ -38,7 +39,7 @@ macro_rules! operator { Ok(( input, - TokenTreeBuilder::spanned_op(tag.fragment, (start, end)), + TokenTreeBuilder::tagged_op(tag.fragment, (start, end, input.extra)), )) } }; @@ -159,14 +160,14 @@ pub fn raw_number(input: NomSpan) -> IResult> { Ok((input, dot)) => input, // it's just an integer - Err(_) => return Ok((input, RawNumber::int((start, input.offset)))), + Err(_) => return Ok((input, RawNumber::int((start, input.offset, input.extra)))), }; let (input, tail) = digit1(input)?; let end = input.offset; - Ok((input, RawNumber::decimal((start, end)))) + Ok((input, RawNumber::decimal((start, end, input.extra)))) }) } @@ -189,7 +190,7 @@ pub fn dq_string(input: NomSpan) -> IResult { let end = input.offset; Ok(( input, - TokenTreeBuilder::spanned_string((start1, end1), (start, end)), + TokenTreeBuilder::tagged_string((start1, end1, input.extra), (start, end, input.extra)), )) }) } @@ -206,7 +207,7 @@ pub fn sq_string(input: NomSpan) -> IResult { Ok(( input, - TokenTreeBuilder::spanned_string((start1, end1), (start, end)), + TokenTreeBuilder::tagged_string((start1, end1, input.extra), (start, end, input.extra)), )) }) } @@ -226,7 +227,7 @@ pub fn external(input: NomSpan) -> IResult { Ok(( input, - TokenTreeBuilder::spanned_external(bare, (start, end)), + TokenTreeBuilder::tagged_external(bare, (start, end, input.extra)), )) }) } @@ -250,7 +251,10 @@ pub fn pattern(input: NomSpan) -> IResult { let end = input.offset; - Ok((input, TokenTreeBuilder::spanned_pattern((start, end)))) + Ok(( + input, + TokenTreeBuilder::tagged_pattern((start, end, input.extra)), + )) }) } @@ -263,7 +267,7 @@ pub fn bare(input: NomSpan) -> IResult { let next_char = &input.fragment.chars().nth(0); if let Some(next_char) = next_char { - if is_external_word_char(*next_char) || *next_char == '*' { + if is_external_word_char(*next_char) || is_glob_specific_char(*next_char) { return Err(nom::Err::Error(nom::error::make_error( input, nom::error::ErrorKind::TakeWhile1, @@ -273,7 +277,10 @@ pub fn bare(input: NomSpan) -> IResult { let end = input.offset; - Ok((input, TokenTreeBuilder::spanned_bare((start, end)))) + Ok(( + input, + TokenTreeBuilder::tagged_bare((start, end, input.extra)), + )) }) } @@ -283,7 +290,10 @@ pub fn external_word(input: NomSpan) -> IResult { let (input, _) = take_while1(is_external_word_char)(input)?; let end = input.offset; - Ok((input, TokenTreeBuilder::spanned_external_word((start, end)))) + Ok(( + input, + TokenTreeBuilder::tagged_external_word((start, end, input.extra)), + )) }) } @@ -296,7 +306,7 @@ pub fn var(input: NomSpan) -> IResult { Ok(( input, - TokenTreeBuilder::spanned_var(bare.span(), (start, end)), + TokenTreeBuilder::tagged_var(bare.tag(), (start, end, input.extra)), )) }) } @@ -309,7 +319,10 @@ pub fn member(input: NomSpan) -> IResult { let end = input.offset; - Ok((input, TokenTreeBuilder::spanned_member((start, end)))) + Ok(( + input, + TokenTreeBuilder::tagged_member((start, end, input.extra)), + )) }) } @@ -322,7 +335,7 @@ pub fn flag(input: NomSpan) -> IResult { Ok(( input, - TokenTreeBuilder::spanned_flag(bare.span(), (start, end)), + TokenTreeBuilder::tagged_flag(bare.tag(), (start, end, input.extra)), )) }) } @@ -336,7 +349,7 @@ pub fn shorthand(input: NomSpan) -> IResult { Ok(( input, - TokenTreeBuilder::spanned_shorthand(bare.span(), (start, end)), + TokenTreeBuilder::tagged_shorthand(bare.tag(), (start, end, input.extra)), )) }) } @@ -369,7 +382,7 @@ pub fn raw_unit(input: NomSpan) -> IResult> { Ok(( input, - Tagged::from_simple_spanned_item(Unit::from(unit.fragment), (start, end)), + Unit::from(unit.fragment).tagged((start, end, input.extra)), )) }) } @@ -389,7 +402,7 @@ pub fn size(input: NomSpan) -> IResult { Ok(( input, - TokenTreeBuilder::spanned_size((number.item, *size), (start, end)), + TokenTreeBuilder::tagged_size((number.item, *size), (start, end, input.extra)), )) } else { let end = input.offset; @@ -401,7 +414,7 @@ pub fn size(input: NomSpan) -> IResult { Ok(( input, - TokenTreeBuilder::spanned_number(number.item, number.tag), + TokenTreeBuilder::tagged_number(number.item, number.tag), )) } }) @@ -455,18 +468,18 @@ fn make_token_list( let mut nodes = vec![]; if let Some(sp_left) = sp_left { - nodes.push(TokenNode::Whitespace(Span::from(sp_left))); + nodes.push(TokenNode::Whitespace(Tag::from(sp_left))); } nodes.push(first); for (ws, token) in list { - nodes.push(TokenNode::Whitespace(Span::from(ws))); + nodes.push(TokenNode::Whitespace(Tag::from(ws))); nodes.push(token); } if let Some(sp_right) = sp_right { - nodes.push(TokenNode::Whitespace(Span::from(sp_right))); + nodes.push(TokenNode::Whitespace(Tag::from(sp_right))); } nodes @@ -478,7 +491,10 @@ pub fn whitespace(input: NomSpan) -> IResult { let (input, ws1) = space1(input)?; let right = input.offset; - Ok((input, TokenTreeBuilder::spanned_ws((left, right)))) + Ok(( + input, + TokenTreeBuilder::tagged_ws((left, right, input.extra)), + )) }) } @@ -508,7 +524,7 @@ pub fn delimited_paren(input: NomSpan) -> IResult { Ok(( input, - TokenTreeBuilder::spanned_parens(items, (left, right)), + TokenTreeBuilder::tagged_parens(items, (left, right, input.extra)), )) }) } @@ -539,7 +555,7 @@ pub fn delimited_square(input: NomSpan) -> IResult { Ok(( input, - TokenTreeBuilder::spanned_square(items, (left, right)), + TokenTreeBuilder::tagged_square(items, (left, right, input.extra)), )) }) } @@ -556,7 +572,10 @@ pub fn delimited_brace(input: NomSpan) -> IResult { Ok(( input, - TokenTreeBuilder::spanned_brace(items.unwrap_or_else(|| vec![]), (left, right)), + TokenTreeBuilder::tagged_brace( + items.unwrap_or_else(|| vec![]), + (left, right, input.extra), + ), )) }) } @@ -567,7 +586,10 @@ pub fn raw_call(input: NomSpan) -> IResult> { let (input, items) = token_list(input)?; let right = input.offset; - Ok((input, TokenTreeBuilder::spanned_call(items, (left, right)))) + Ok(( + input, + TokenTreeBuilder::tagged_call(items, (left, right, input.extra)), + )) }) } @@ -581,7 +603,7 @@ pub fn path(input: NomSpan) -> IResult { Ok(( input, - TokenTreeBuilder::spanned_path((head, tail), (left, right)), + TokenTreeBuilder::tagged_path((head, tail), (left, right, input.extra)), )) }) } @@ -628,9 +650,9 @@ pub fn pipeline(input: NomSpan) -> IResult { Ok(( input, - TokenTreeBuilder::spanned_pipeline( - (make_call_list(head, items), tail.map(Span::from)), - (start, end), + TokenTreeBuilder::tagged_pipeline( + (make_call_list(head, items), tail.map(Tag::from)), + (start, end, input.extra), ), )) }) @@ -643,17 +665,17 @@ fn make_call_list( let mut out = vec![]; if let Some(head) = head { - let el = PipelineElement::new(None, head.0.map(Span::from), head.1, head.2.map(Span::from)); + let el = PipelineElement::new(None, head.0.map(Tag::from), head.1, head.2.map(Tag::from)); out.push(el); } for (pipe, ws1, call, ws2) in items { let el = PipelineElement::new( - Some(pipe).map(Span::from), - ws1.map(Span::from), + Some(pipe).map(Tag::from), + ws1.map(Tag::from), call, - ws2.map(Span::from), + ws2.map(Tag::from), ); out.push(el); @@ -679,12 +701,17 @@ fn is_external_word_char(c: char) -> bool { } } +/// These characters appear in globs and not bare words +fn is_glob_specific_char(c: char) -> bool { + c == '*' || c == '?' +} + fn is_start_glob_char(c: char) -> bool { - is_start_bare_char(c) || c == '*' + is_start_bare_char(c) || is_glob_specific_char(c) } fn is_glob_char(c: char) -> bool { - is_bare_char(c) || c == '*' + is_bare_char(c) || is_glob_specific_char(c) } fn is_start_bare_char(c: char) -> bool { @@ -779,7 +806,7 @@ mod tests { macro_rules! equal_tokens { ($source:tt -> $tokens:expr) => { let result = apply(pipeline, "pipeline", $source); - let (expected_tree, expected_source) = TokenTreeBuilder::build($tokens); + let (expected_tree, expected_source) = TokenTreeBuilder::build(uuid::Uuid::nil(), $tokens); if result != expected_tree { let debug_result = format!("{}", result.debug($source)); @@ -818,12 +845,12 @@ mod tests { fn test_integer() { assert_leaf! { parsers [ size ] - "123" -> 0..3 { Number(RawNumber::int((0, 3)).item) } + "123" -> 0..3 { Number(RawNumber::int((0, 3, test_uuid())).item) } } assert_leaf! { parsers [ size ] - "-123" -> 0..4 { Number(RawNumber::int((0, 4)).item) } + "-123" -> 0..4 { Number(RawNumber::int((0, 4, test_uuid())).item) } } } @@ -831,12 +858,12 @@ mod tests { fn test_size() { assert_leaf! { parsers [ size ] - "123MB" -> 0..5 { Size(RawNumber::int((0, 3)).item, Unit::MB) } + "123MB" -> 0..5 { Size(RawNumber::int((0, 3, test_uuid())).item, Unit::MB) } } assert_leaf! { parsers [ size ] - "10GB" -> 0..4 { Size(RawNumber::int((0, 2)).item, Unit::GB) } + "10GB" -> 0..4 { Size(RawNumber::int((0, 2, test_uuid())).item, Unit::GB) } } } @@ -874,12 +901,12 @@ mod tests { fn test_string() { assert_leaf! { parsers [ string dq_string ] - r#""hello world""# -> 0..13 { String(span(1, 12)) } + r#""hello world""# -> 0..13 { String(tag(1, 12)) } } assert_leaf! { parsers [ string sq_string ] - r"'hello world'" -> 0..13 { String(span(1, 12)) } + r"'hello world'" -> 0..13 { String(tag(1, 12)) } } } @@ -931,12 +958,12 @@ mod tests { fn test_variable() { assert_leaf! { parsers [ var ] - "$it" -> 0..3 { Variable(span(1, 3)) } + "$it" -> 0..3 { Variable(tag(1, 3)) } } assert_leaf! { parsers [ var ] - "$name" -> 0..5 { Variable(span(1, 5)) } + "$name" -> 0..5 { Variable(tag(1, 5)) } } } @@ -944,7 +971,7 @@ mod tests { fn test_external() { assert_leaf! { parsers [ external ] - "^ls" -> 0..3 { ExternalCommand(span(1, 3)) } + "^ls" -> 0..3 { ExternalCommand(tag(1, 3)) } } } @@ -1260,7 +1287,7 @@ mod tests { desc: &str, string: &str, ) -> T { - match f(NomSpan::new(string)) { + match f(NomSpan::new_extra(string, uuid::Uuid::nil())) { Ok(v) => v.1, Err(other) => { println!("{:?}", other); @@ -1270,44 +1297,46 @@ mod tests { } } - fn span(left: usize, right: usize) -> Span { - Span::from((left, right)) + fn tag(left: usize, right: usize) -> Tag { + Tag::from((left, right, uuid::Uuid::nil())) } fn delimited( - delimiter: Delimiter, + delimiter: Tagged, children: Vec, left: usize, right: usize, ) -> TokenNode { - let node = DelimitedNode::new(delimiter, children); - let spanned = Tagged::from_simple_spanned_item(node, (left, right)); + let node = DelimitedNode::new(*delimiter, children); + let spanned = node.tagged((left, right, delimiter.tag.origin)); TokenNode::Delimited(spanned) } fn path(head: TokenNode, tail: Vec, left: usize, right: usize) -> TokenNode { + let tag = head.tag(); + let node = PathNode::new( Box::new(head), tail.into_iter().map(TokenNode::Token).collect(), ); - let spanned = Tagged::from_simple_spanned_item(node, (left, right)); + let spanned = node.tagged((left, right, tag.origin)); TokenNode::Path(spanned) } - fn leaf_token(token: RawToken, left: usize, right: usize) -> TokenNode { - TokenNode::Token(Tagged::from_simple_spanned_item(token, (left, right))) - } - fn token(token: RawToken, left: usize, right: usize) -> TokenNode { - TokenNode::Token(Tagged::from_simple_spanned_item(token, (left, right))) + TokenNode::Token(token.tagged((left, right, uuid::Uuid::nil()))) } fn build(block: CurriedNode) -> T { - let mut builder = TokenTreeBuilder::new(); + let mut builder = TokenTreeBuilder::new(uuid::Uuid::nil()); block(&mut builder) } fn build_token(block: CurriedToken) -> TokenNode { - TokenTreeBuilder::build(block).0 + TokenTreeBuilder::build(uuid::Uuid::nil(), block).0 + } + + fn test_uuid() -> uuid::Uuid { + uuid::Uuid::nil() } } diff --git a/src/parser/parse/pipeline.rs b/src/parser/parse/pipeline.rs index 64a899c17..42bbe23a1 100644 --- a/src/parser/parse/pipeline.rs +++ b/src/parser/parse/pipeline.rs @@ -1,6 +1,6 @@ use crate::parser::CallNode; use crate::traits::ToDebug; -use crate::{Span, Tagged}; +use crate::{Tag, Tagged}; use derive_new::new; use getset::Getters; use std::fmt; @@ -8,7 +8,7 @@ use std::fmt; #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, new)] pub struct Pipeline { pub(crate) parts: Vec, - pub(crate) post_ws: Option, + pub(crate) post_ws: Option, } impl ToDebug for Pipeline { @@ -27,11 +27,11 @@ impl ToDebug for Pipeline { #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Getters, new)] pub struct PipelineElement { - pub pipe: Option, - pub pre_ws: Option, + pub pipe: Option, + pub pre_ws: Option, #[get = "pub(crate)"] call: Tagged, - pub post_ws: Option, + pub post_ws: Option, } impl ToDebug for PipelineElement { diff --git a/src/parser/parse/token_tree.rs b/src/parser/parse/token_tree.rs index f69c176e9..e0072360e 100644 --- a/src/parser/parse/token_tree.rs +++ b/src/parser/parse/token_tree.rs @@ -1,7 +1,7 @@ use crate::errors::ShellError; use crate::parser::parse::{call_node::*, flag::*, operator::*, pipeline::*, tokens::*}; use crate::traits::ToDebug; -use crate::{Span, Tagged, Text}; +use crate::{Tag, Tagged, Text}; use derive_new::new; use enum_utils::FromStr; use getset::Getters; @@ -16,8 +16,8 @@ pub enum TokenNode { Pipeline(Tagged), Operator(Tagged), Flag(Tagged), - Member(Span), - Whitespace(Span), + Member(Tag), + Whitespace(Tag), Error(Tagged>), Path(Tagged), @@ -78,31 +78,31 @@ impl fmt::Debug for DebugTokenNode<'_> { ) } TokenNode::Pipeline(pipeline) => write!(f, "{}", pipeline.debug(self.source)), - TokenNode::Error(s) => write!(f, " for {:?}", s.span().slice(self.source)), - rest => write!(f, "{}", rest.span().slice(self.source)), + TokenNode::Error(s) => write!(f, " for {:?}", s.tag().slice(self.source)), + rest => write!(f, "{}", rest.tag().slice(self.source)), } } } -impl From<&TokenNode> for Span { - fn from(token: &TokenNode) -> Span { - token.span() +impl From<&TokenNode> for Tag { + fn from(token: &TokenNode) -> Tag { + token.tag() } } impl TokenNode { - pub fn span(&self) -> Span { + pub fn tag(&self) -> Tag { match self { - TokenNode::Token(t) => t.span(), - TokenNode::Call(s) => s.span(), - TokenNode::Delimited(s) => s.span(), - TokenNode::Pipeline(s) => s.span(), - TokenNode::Operator(s) => s.span(), - TokenNode::Flag(s) => s.span(), + TokenNode::Token(t) => t.tag(), + TokenNode::Call(s) => s.tag(), + TokenNode::Delimited(s) => s.tag(), + TokenNode::Pipeline(s) => s.tag(), + TokenNode::Operator(s) => s.tag(), + TokenNode::Flag(s) => s.tag(), TokenNode::Member(s) => *s, TokenNode::Whitespace(s) => *s, - TokenNode::Error(s) => s.span(), - TokenNode::Path(s) => s.span(), + TokenNode::Error(s) => s.tag(), + TokenNode::Path(s) => s.tag(), } } @@ -127,11 +127,11 @@ impl TokenNode { } pub fn as_external_arg(&self, source: &Text) -> String { - self.span().slice(source).to_string() + self.tag().slice(source).to_string() } pub fn source<'a>(&self, source: &'a Text) -> &'a str { - self.span().slice(source) + self.tag().slice(source) } pub fn is_bare(&self) -> bool { @@ -154,12 +154,12 @@ impl TokenNode { } } - pub fn expect_external(&self) -> Span { + pub fn expect_external(&self) -> Tag { match self { TokenNode::Token(Tagged { - item: RawToken::ExternalCommand(span), + item: RawToken::ExternalCommand(tag), .. - }) => *span, + }) => *tag, _ => panic!("Only call expect_external if you checked is_external first"), } } diff --git a/src/parser/parse/token_tree_builder.rs b/src/parser/parse/token_tree_builder.rs index ae1b344c4..1ed8383f4 100644 --- a/src/parser/parse/token_tree_builder.rs +++ b/src/parser/parse/token_tree_builder.rs @@ -7,8 +7,8 @@ use crate::parser::parse::token_tree::{DelimitedNode, Delimiter, PathNode, Token use crate::parser::parse::tokens::{RawNumber, RawToken}; use crate::parser::parse::unit::Unit; use crate::parser::CallNode; -use crate::Span; use derive_new::new; +use uuid::Uuid; #[derive(new)] pub struct TokenTreeBuilder { @@ -17,14 +17,16 @@ pub struct TokenTreeBuilder { #[new(default)] output: String, + + origin: Uuid, } pub type CurriedToken = Box TokenNode + 'static>; pub type CurriedCall = Box Tagged + 'static>; impl TokenTreeBuilder { - pub fn build(block: impl FnOnce(&mut Self) -> TokenNode) -> (TokenNode, String) { - let mut builder = TokenTreeBuilder::new(); + pub fn build(origin: Uuid, block: impl FnOnce(&mut Self) -> TokenNode) -> (TokenNode, String) { + let mut builder = TokenTreeBuilder::new(origin); let node = block(&mut builder); (node, builder.output) } @@ -52,50 +54,37 @@ impl TokenTreeBuilder { .expect("A pipeline must contain at least one element"); let pipe = None; - let pre_span = pre.map(|pre| b.consume(&pre)); + let pre_tag = pre.map(|pre| b.consume_tag(&pre)); let call = call(b); - let post_span = post.map(|post| b.consume(&post)); + let post_tag = post.map(|post| b.consume_tag(&post)); - out.push(PipelineElement::new( - pipe, - pre_span.map(Span::from), - call, - post_span.map(Span::from), - )); + out.push(PipelineElement::new(pipe, pre_tag, call, post_tag)); loop { match input.next() { None => break, Some((pre, call, post)) => { - let pipe = Some(Span::from(b.consume("|"))); - let pre_span = pre.map(|pre| b.consume(&pre)); + let pipe = Some(b.consume_tag("|")); + let pre_span = pre.map(|pre| b.consume_tag(&pre)); let call = call(b); - let post_span = post.map(|post| b.consume(&post)); + let post_span = post.map(|post| b.consume_tag(&post)); - out.push(PipelineElement::new( - pipe, - pre_span.map(Span::from), - call, - post_span.map(Span::from), - )); + out.push(PipelineElement::new(pipe, pre_span, call, post_span)); } } } let end = b.pos; - TokenTreeBuilder::spanned_pipeline((out, None), (start, end)) + TokenTreeBuilder::tagged_pipeline((out, None), (start, end, b.origin)) }) } - pub fn spanned_pipeline( - input: (Vec, Option), - span: impl Into, + pub fn tagged_pipeline( + input: (Vec, Option), + tag: impl Into, ) -> TokenNode { - TokenNode::Pipeline(Tagged::from_simple_spanned_item( - Pipeline::new(input.0, input.1.into()), - span, - )) + TokenNode::Pipeline(Pipeline::new(input.0, input.1.into()).tagged(tag.into())) } pub fn op(input: impl Into) -> CurriedToken { @@ -106,12 +95,12 @@ impl TokenTreeBuilder { b.pos = end; - TokenTreeBuilder::spanned_op(input, (start, end)) + TokenTreeBuilder::tagged_op(input, (start, end, b.origin)) }) } - pub fn spanned_op(input: impl Into, span: impl Into) -> TokenNode { - TokenNode::Operator(Tagged::from_simple_spanned_item(input.into(), span.into())) + pub fn tagged_op(input: impl Into, tag: impl Into) -> TokenNode { + TokenNode::Operator(input.into().tagged(tag.into())) } pub fn string(input: impl Into) -> CurriedToken { @@ -123,15 +112,15 @@ impl TokenTreeBuilder { let (_, end) = b.consume("\""); b.pos = end; - TokenTreeBuilder::spanned_string((inner_start, inner_end), (start, end)) + TokenTreeBuilder::tagged_string( + (inner_start, inner_end, b.origin), + (start, end, b.origin), + ) }) } - pub fn spanned_string(input: impl Into, span: impl Into) -> TokenNode { - TokenNode::Token(Tagged::from_simple_spanned_item( - RawToken::String(input.into()), - span.into(), - )) + pub fn tagged_string(input: impl Into, tag: impl Into) -> TokenNode { + TokenNode::Token(RawToken::String(input.into()).tagged(tag.into())) } pub fn bare(input: impl Into) -> CurriedToken { @@ -141,15 +130,12 @@ impl TokenTreeBuilder { let (start, end) = b.consume(&input); b.pos = end; - TokenTreeBuilder::spanned_bare((start, end)) + TokenTreeBuilder::tagged_bare((start, end, b.origin)) }) } - pub fn spanned_bare(input: impl Into) -> TokenNode { - TokenNode::Token(Tagged::from_simple_spanned_item( - RawToken::Bare, - input.into(), - )) + pub fn tagged_bare(tag: impl Into) -> TokenNode { + TokenNode::Token(RawToken::Bare.tagged(tag.into())) } pub fn pattern(input: impl Into) -> CurriedToken { @@ -159,15 +145,12 @@ impl TokenTreeBuilder { let (start, end) = b.consume(&input); b.pos = end; - TokenTreeBuilder::spanned_pattern((start, end)) + TokenTreeBuilder::tagged_pattern((start, end, b.origin)) }) } - pub fn spanned_pattern(input: impl Into) -> TokenNode { - TokenNode::Token(Tagged::from_simple_spanned_item( - RawToken::Bare, - input.into(), - )) + pub fn tagged_pattern(input: impl Into) -> TokenNode { + TokenNode::Token(RawToken::GlobPattern.tagged(input.into())) } pub fn external_word(input: impl Into) -> CurriedToken { @@ -177,22 +160,16 @@ impl TokenTreeBuilder { let (start, end) = b.consume(&input); b.pos = end; - TokenTreeBuilder::spanned_external_word((start, end)) + TokenTreeBuilder::tagged_external_word((start, end, b.origin)) }) } - pub fn spanned_external_word(input: impl Into) -> TokenNode { - TokenNode::Token(Tagged::from_simple_spanned_item( - RawToken::ExternalWord, - input.into(), - )) + pub fn tagged_external_word(input: impl Into) -> TokenNode { + TokenNode::Token(RawToken::ExternalWord.tagged(input.into())) } - pub fn spanned_external(input: impl Into, span: impl Into) -> TokenNode { - TokenNode::Token(Tagged::from_simple_spanned_item( - RawToken::ExternalCommand(input.into()), - span.into(), - )) + pub fn tagged_external(input: impl Into, tag: impl Into) -> TokenNode { + TokenNode::Token(RawToken::ExternalCommand(input.into()).tagged(tag.into())) } pub fn int(input: impl Into) -> CurriedToken { @@ -202,7 +179,10 @@ impl TokenTreeBuilder { let (start, end) = b.consume(&int.to_string()); b.pos = end; - TokenTreeBuilder::spanned_number(RawNumber::Int((start, end).into()), (start, end)) + TokenTreeBuilder::tagged_number( + RawNumber::Int((start, end, b.origin).into()), + (start, end, b.origin), + ) }) } @@ -213,15 +193,15 @@ impl TokenTreeBuilder { let (start, end) = b.consume(&decimal.to_string()); b.pos = end; - TokenTreeBuilder::spanned_number(RawNumber::Decimal((start, end).into()), (start, end)) + TokenTreeBuilder::tagged_number( + RawNumber::Decimal((start, end, b.origin).into()), + (start, end, b.origin), + ) }) } - pub fn spanned_number(input: impl Into, span: impl Into) -> TokenNode { - TokenNode::Token(Tagged::from_simple_spanned_item( - RawToken::Number(input.into()), - span.into(), - )) + pub fn tagged_number(input: impl Into, tag: impl Into) -> TokenNode { + TokenNode::Token(RawToken::Number(input.into()).tagged(tag.into())) } pub fn size(int: impl Into, unit: impl Into) -> CurriedToken { @@ -233,23 +213,20 @@ impl TokenTreeBuilder { let (_, end_unit) = b.consume(unit.as_str()); b.pos = end_unit; - TokenTreeBuilder::spanned_size( - (RawNumber::Int((start_int, end_int).into()), unit), - (start_int, end_unit), + TokenTreeBuilder::tagged_size( + (RawNumber::Int((start_int, end_int, b.origin).into()), unit), + (start_int, end_unit, b.origin), ) }) } - pub fn spanned_size( + pub fn tagged_size( input: (impl Into, impl Into), - span: impl Into, + tag: impl Into, ) -> TokenNode { let (int, unit) = (input.0.into(), input.1.into()); - TokenNode::Token(Tagged::from_simple_spanned_item( - RawToken::Size(int, unit), - span, - )) + TokenNode::Token(RawToken::Size(int, unit).tagged(tag.into())) } pub fn path(head: CurriedToken, tail: Vec) -> CurriedToken { @@ -267,15 +244,12 @@ impl TokenTreeBuilder { let end = b.pos; - TokenTreeBuilder::spanned_path((head, output), (start, end)) + TokenTreeBuilder::tagged_path((head, output), (start, end, b.origin)) }) } - pub fn spanned_path(input: (TokenNode, Vec), span: impl Into) -> TokenNode { - TokenNode::Path(Tagged::from_simple_spanned_item( - PathNode::new(Box::new(input.0), input.1), - span, - )) + pub fn tagged_path(input: (TokenNode, Vec), tag: impl Into) -> TokenNode { + TokenNode::Path(PathNode::new(Box::new(input.0), input.1).tagged(tag.into())) } pub fn var(input: impl Into) -> CurriedToken { @@ -285,15 +259,12 @@ impl TokenTreeBuilder { let (start, _) = b.consume("$"); let (inner_start, end) = b.consume(&input); - TokenTreeBuilder::spanned_var((inner_start, end), (start, end)) + TokenTreeBuilder::tagged_var((inner_start, end, b.origin), (start, end, b.origin)) }) } - pub fn spanned_var(input: impl Into, span: impl Into) -> TokenNode { - TokenNode::Token(Tagged::from_simple_spanned_item( - RawToken::Variable(input.into()), - span.into(), - )) + pub fn tagged_var(input: impl Into, tag: impl Into) -> TokenNode { + TokenNode::Token(RawToken::Variable(input.into()).tagged(tag.into())) } pub fn flag(input: impl Into) -> CurriedToken { @@ -303,15 +274,12 @@ impl TokenTreeBuilder { let (start, _) = b.consume("--"); let (inner_start, end) = b.consume(&input); - TokenTreeBuilder::spanned_flag((inner_start, end), (start, end)) + TokenTreeBuilder::tagged_flag((inner_start, end, b.origin), (start, end, b.origin)) }) } - pub fn spanned_flag(input: impl Into, span: impl Into) -> TokenNode { - TokenNode::Flag(Tagged::from_simple_spanned_item( - Flag::new(FlagKind::Longhand, input.into()), - span.into(), - )) + pub fn tagged_flag(input: impl Into, tag: impl Into) -> TokenNode { + TokenNode::Flag(Flag::new(FlagKind::Longhand, input.into()).tagged(tag.into())) } pub fn shorthand(input: impl Into) -> CurriedToken { @@ -321,15 +289,12 @@ impl TokenTreeBuilder { let (start, _) = b.consume("-"); let (inner_start, end) = b.consume(&input); - TokenTreeBuilder::spanned_shorthand((inner_start, end), (start, end)) + TokenTreeBuilder::tagged_shorthand((inner_start, end, b.origin), (start, end, b.origin)) }) } - pub fn spanned_shorthand(input: impl Into, span: impl Into) -> TokenNode { - TokenNode::Flag(Tagged::from_simple_spanned_item( - Flag::new(FlagKind::Shorthand, input.into()), - span.into(), - )) + pub fn tagged_shorthand(input: impl Into, tag: impl Into) -> TokenNode { + TokenNode::Flag(Flag::new(FlagKind::Shorthand, input.into()).tagged(tag.into())) } pub fn member(input: impl Into) -> CurriedToken { @@ -337,12 +302,12 @@ impl TokenTreeBuilder { Box::new(move |b| { let (start, end) = b.consume(&input); - TokenTreeBuilder::spanned_member((start, end)) + TokenTreeBuilder::tagged_member((start, end, b.origin)) }) } - pub fn spanned_member(span: impl Into) -> TokenNode { - TokenNode::Member(span.into()) + pub fn tagged_member(tag: impl Into) -> TokenNode { + TokenNode::Member(tag.into()) } pub fn call(head: CurriedToken, input: Vec) -> CurriedCall { @@ -358,11 +323,11 @@ impl TokenTreeBuilder { let end = b.pos; - TokenTreeBuilder::spanned_call(nodes, (start, end)) + TokenTreeBuilder::tagged_call(nodes, (start, end, b.origin)) }) } - pub fn spanned_call(input: Vec, span: impl Into) -> Tagged { + pub fn tagged_call(input: Vec, tag: impl Into) -> Tagged { if input.len() == 0 { panic!("BUG: spanned call (TODO)") } @@ -372,7 +337,7 @@ impl TokenTreeBuilder { let head = input.next().unwrap(); let tail = input.collect(); - Tagged::from_simple_spanned_item(CallNode::new(Box::new(head), tail), span) + CallNode::new(Box::new(head), tail).tagged(tag.into()) } pub fn parens(input: Vec) -> CurriedToken { @@ -385,15 +350,12 @@ impl TokenTreeBuilder { let (_, end) = b.consume(")"); - TokenTreeBuilder::spanned_parens(output, (start, end)) + TokenTreeBuilder::tagged_parens(output, (start, end, b.origin)) }) } - pub fn spanned_parens(input: impl Into>, span: impl Into) -> TokenNode { - TokenNode::Delimited(Tagged::from_simple_spanned_item( - DelimitedNode::new(Delimiter::Paren, input.into()), - span, - )) + pub fn tagged_parens(input: impl Into>, tag: impl Into) -> TokenNode { + TokenNode::Delimited(DelimitedNode::new(Delimiter::Paren, input.into()).tagged(tag.into())) } pub fn square(input: Vec) -> CurriedToken { @@ -406,15 +368,12 @@ impl TokenTreeBuilder { let (_, end) = b.consume("]"); - TokenTreeBuilder::spanned_square(output, (start, end)) + TokenTreeBuilder::tagged_square(output, (start, end, b.origin)) }) } - pub fn spanned_square(input: impl Into>, span: impl Into) -> TokenNode { - TokenNode::Delimited(Tagged::from_simple_spanned_item( - DelimitedNode::new(Delimiter::Square, input.into()), - span, - )) + pub fn tagged_square(input: impl Into>, tag: impl Into) -> TokenNode { + TokenNode::Delimited(DelimitedNode::new(Delimiter::Square, input.into()).tagged(tag.into())) } pub fn braced(input: Vec) -> CurriedToken { @@ -427,21 +386,18 @@ impl TokenTreeBuilder { let (_, end) = b.consume(" }"); - TokenTreeBuilder::spanned_brace(output, (start, end)) + TokenTreeBuilder::tagged_brace(output, (start, end, b.origin)) }) } - pub fn spanned_brace(input: impl Into>, span: impl Into) -> TokenNode { - TokenNode::Delimited(Tagged::from_simple_spanned_item( - DelimitedNode::new(Delimiter::Brace, input.into()), - span, - )) + pub fn tagged_brace(input: impl Into>, tag: impl Into) -> TokenNode { + TokenNode::Delimited(DelimitedNode::new(Delimiter::Brace, input.into()).tagged(tag.into())) } pub fn sp() -> CurriedToken { Box::new(|b| { let (start, end) = b.consume(" "); - TokenNode::Whitespace(Span::from((start, end))) + TokenNode::Whitespace(Tag::from((start, end, b.origin))) }) } @@ -450,14 +406,12 @@ impl TokenTreeBuilder { Box::new(move |b| { let (start, end) = b.consume(&input); - TokenTreeBuilder::spanned_ws((start, end)) + TokenTreeBuilder::tagged_ws((start, end, b.origin)) }) } - pub fn spanned_ws(span: impl Into) -> TokenNode { - let span = span.into(); - - TokenNode::Whitespace(span.into()) + pub fn tagged_ws(tag: impl Into) -> TokenNode { + TokenNode::Whitespace(tag.into()) } fn consume(&mut self, input: &str) -> (usize, usize) { @@ -466,4 +420,11 @@ impl TokenTreeBuilder { self.output.push_str(input); (start, self.pos) } + + fn consume_tag(&mut self, input: &str) -> Tag { + let start = self.pos; + self.pos += input.len(); + self.output.push_str(input); + (start, self.pos, self.origin).into() + } } diff --git a/src/parser/parse/tokens.rs b/src/parser/parse/tokens.rs index b59985249..d796a8fcb 100644 --- a/src/parser/parse/tokens.rs +++ b/src/parser/parse/tokens.rs @@ -1,6 +1,6 @@ use crate::parser::parse::unit::*; use crate::prelude::*; -use crate::{Span, Tagged, Text}; +use crate::{Tagged, Text}; use std::fmt; use std::str::FromStr; @@ -8,9 +8,9 @@ use std::str::FromStr; pub enum RawToken { Number(RawNumber), Size(RawNumber, Unit), - String(Span), - Variable(Span), - ExternalCommand(Span), + String(Tag), + Variable(Tag), + ExternalCommand(Tag), ExternalWord, GlobPattern, Bare, @@ -18,28 +18,28 @@ pub enum RawToken { #[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)] pub enum RawNumber { - Int(Span), - Decimal(Span), + Int(Tag), + Decimal(Tag), } impl RawNumber { - pub fn int(span: impl Into) -> Tagged { - let span = span.into(); + pub fn int(tag: impl Into) -> Tagged { + let tag = tag.into(); - RawNumber::Int(span).tagged(span) + RawNumber::Int(tag).tagged(tag) } - pub fn decimal(span: impl Into) -> Tagged { - let span = span.into(); + pub fn decimal(tag: impl Into) -> Tagged { + let tag = tag.into(); - RawNumber::Decimal(span).tagged(span) + RawNumber::Decimal(tag).tagged(tag) } pub(crate) fn to_number(self, source: &Text) -> Number { match self { - RawNumber::Int(span) => Number::Int(BigInt::from_str(span.slice(source)).unwrap()), - RawNumber::Decimal(span) => { - Number::Decimal(BigDecimal::from_str(span.slice(source)).unwrap()) + RawNumber::Int(tag) => Number::Int(BigInt::from_str(tag.slice(source)).unwrap()), + RawNumber::Decimal(tag) => { + Number::Decimal(BigDecimal::from_str(tag.slice(source)).unwrap()) } } } @@ -78,6 +78,6 @@ pub struct DebugToken<'a> { impl fmt::Debug for DebugToken<'_> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.node.span().slice(self.source)) + write!(f, "{}", self.node.tag().slice(self.source)) } } diff --git a/src/parser/parse_command.rs b/src/parser/parse_command.rs index e0fc9d86f..36ba82f8e 100644 --- a/src/parser/parse_command.rs +++ b/src/parser/parse_command.rs @@ -7,7 +7,7 @@ use crate::parser::{ Flag, RawToken, TokenNode, }; use crate::traits::ToDebug; -use crate::{Span, Tag, Tagged, Text}; +use crate::{Tag, Tagged, TaggedItem, Text}; use log::trace; pub fn parse_command( @@ -33,7 +33,7 @@ pub fn parse_command( .collect() }); - match parse_command_tail(&config, context, children, source, call.span())? { + match parse_command_tail(&config, context, children, source, call.tag())? { None => Ok(hir::Call::new(Box::new(head), None, None)), Some((positional, named)) => Ok(hir::Call::new(Box::new(head), positional, named)), } @@ -49,12 +49,9 @@ fn parse_command_head(head: &TokenNode) -> Result { ) => Ok(spanned.map(|_| hir::RawExpression::Literal(hir::Literal::Bare))), TokenNode::Token(Tagged { - item: RawToken::String(inner_span), - tag: Tag { span, origin: None }, - }) => Ok(Tagged::from_simple_spanned_item( - hir::RawExpression::Literal(hir::Literal::String(*inner_span)), - *span, - )), + item: RawToken::String(inner_tag), + tag, + }) => Ok(hir::RawExpression::Literal(hir::Literal::String(*inner_tag)).tagged(*tag)), other => Err(ShellError::unexpected(&format!( "command head -> {:?}", @@ -68,7 +65,7 @@ fn parse_command_tail( context: &Context, tail: Option>, source: &Text, - command_span: Span, + command_tag: Tag, ) -> Result>, Option)>, ShellError> { let tail = &mut match &tail { None => hir::TokensIterator::new(&[]), @@ -89,7 +86,7 @@ fn parse_command_tail( named.insert_switch(name, flag); } NamedType::Mandatory(syntax_type) => { - match extract_mandatory(config, name, tail, source, command_span) { + match extract_mandatory(config, name, tail, source, command_tag) { Err(err) => return Err(err), // produce a correct diagnostic Ok((pos, flag)) => { tail.move_to(pos); @@ -98,7 +95,7 @@ fn parse_command_tail( return Err(ShellError::argument_error( config.name.clone(), ArgumentError::MissingValueForName(name.to_string()), - flag.span(), + flag.tag(), )); } @@ -119,7 +116,7 @@ fn parse_command_tail( return Err(ShellError::argument_error( config.name.clone(), ArgumentError::MissingValueForName(name.to_string()), - flag.span(), + flag.tag(), )); } @@ -150,7 +147,7 @@ fn parse_command_tail( return Err(ShellError::argument_error( config.name.clone(), ArgumentError::MissingMandatoryPositional(arg.name().to_string()), - command_span, + command_tag, )); } } @@ -208,7 +205,7 @@ fn extract_mandatory( name: &str, tokens: &mut hir::TokensIterator<'_>, source: &Text, - span: Span, + tag: Tag, ) -> Result<(usize, Tagged), ShellError> { let flag = tokens.extract(|t| t.as_flag(name, source)); @@ -216,7 +213,7 @@ fn extract_mandatory( None => Err(ShellError::argument_error( config.name.clone(), ArgumentError::MissingMandatoryFlag(name.to_string()), - span, + tag, )), Some((pos, flag)) => { diff --git a/src/parser/registry.rs b/src/parser/registry.rs index 7112d9111..e199be192 100644 --- a/src/parser/registry.rs +++ b/src/parser/registry.rs @@ -1,7 +1,7 @@ // TODO: Temporary redirect pub(crate) use crate::context::CommandRegistry; use crate::evaluate::{evaluate_baseline_expr, Scope}; -use crate::parser::{hir, hir::SyntaxType, parse_command, CallNode}; +use crate::parser::{hir, hir::SyntaxShape, parse_command, CallNode}; use crate::prelude::*; use derive_new::new; use indexmap::IndexMap; @@ -12,35 +12,35 @@ use std::fmt; #[derive(Debug, Serialize, Deserialize, Clone)] pub enum NamedType { Switch, - Mandatory(SyntaxType), - Optional(SyntaxType), + Mandatory(SyntaxShape), + Optional(SyntaxShape), } #[derive(Debug, Clone, Serialize, Deserialize)] pub enum PositionalType { - Mandatory(String, SyntaxType), - Optional(String, SyntaxType), + Mandatory(String, SyntaxShape), + Optional(String, SyntaxShape), } impl PositionalType { - pub fn mandatory(name: &str, ty: SyntaxType) -> PositionalType { + pub fn mandatory(name: &str, ty: SyntaxShape) -> PositionalType { PositionalType::Mandatory(name.to_string(), ty) } pub fn mandatory_any(name: &str) -> PositionalType { - PositionalType::Mandatory(name.to_string(), SyntaxType::Any) + PositionalType::Mandatory(name.to_string(), SyntaxShape::Any) } pub fn mandatory_block(name: &str) -> PositionalType { - PositionalType::Mandatory(name.to_string(), SyntaxType::Block) + PositionalType::Mandatory(name.to_string(), SyntaxShape::Block) } - pub fn optional(name: &str, ty: SyntaxType) -> PositionalType { + pub fn optional(name: &str, ty: SyntaxShape) -> PositionalType { PositionalType::Optional(name.to_string(), ty) } pub fn optional_any(name: &str) -> PositionalType { - PositionalType::Optional(name.to_string(), SyntaxType::Any) + PositionalType::Optional(name.to_string(), SyntaxShape::Any) } pub(crate) fn name(&self) -> &str { @@ -50,7 +50,7 @@ impl PositionalType { } } - pub(crate) fn syntax_type(&self) -> SyntaxType { + pub(crate) fn syntax_type(&self) -> SyntaxShape { match *self { PositionalType::Mandatory(_, t) => t, PositionalType::Optional(_, t) => t, @@ -66,7 +66,7 @@ pub struct Signature { #[new(default)] pub positional: Vec, #[new(value = "None")] - pub rest_positional: Option, + pub rest_positional: Option, #[new(default)] pub named: IndexMap, #[new(value = "false")] @@ -83,21 +83,21 @@ impl Signature { self } - pub fn required(mut self, name: impl Into, ty: impl Into) -> Signature { + pub fn required(mut self, name: impl Into, ty: impl Into) -> Signature { self.positional .push(PositionalType::Mandatory(name.into(), ty.into())); self } - pub fn optional(mut self, name: impl Into, ty: impl Into) -> Signature { + pub fn optional(mut self, name: impl Into, ty: impl Into) -> Signature { self.positional .push(PositionalType::Optional(name.into(), ty.into())); self } - pub fn named(mut self, name: impl Into, ty: impl Into) -> Signature { + pub fn named(mut self, name: impl Into, ty: impl Into) -> Signature { self.named .insert(name.into(), NamedType::Optional(ty.into())); @@ -107,7 +107,7 @@ impl Signature { pub fn required_named( mut self, name: impl Into, - ty: impl Into, + ty: impl Into, ) -> Signature { self.named .insert(name.into(), NamedType::Mandatory(ty.into())); @@ -126,7 +126,7 @@ impl Signature { self } - pub fn rest(mut self, ty: SyntaxType) -> Signature { + pub fn rest(mut self, ty: SyntaxShape) -> Signature { self.rest_positional = Some(ty); self } @@ -312,10 +312,10 @@ pub(crate) fn evaluate_args( for (name, value) in n.named.iter() { match value { - hir::named::NamedValue::PresentSwitch(span) => { + hir::named::NamedValue::PresentSwitch(tag) => { results.insert( name.clone(), - Tagged::from_simple_spanned_item(Value::boolean(true), *span), + Value::boolean(true).tagged(*tag), ); } hir::named::NamedValue::Value(expr) => { diff --git a/src/plugins/add.rs b/src/plugins/add.rs index 744003cd7..03e1d4282 100644 --- a/src/plugins/add.rs +++ b/src/plugins/add.rs @@ -1,6 +1,6 @@ use nu::{ serve_plugin, CallInfo, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError, Signature, - SyntaxType, Tagged, Value, + SyntaxShape, Tagged, Value, }; struct Add { @@ -44,9 +44,9 @@ impl Plugin for Add { fn config(&mut self) -> Result { Ok(Signature::build("add") .desc("Add a new field to the table.") - .required("Field", SyntaxType::String) - .required("Value", SyntaxType::String) - .rest(SyntaxType::String) + .required("Field", SyntaxShape::String) + .required("Value", SyntaxShape::String) + .rest(SyntaxShape::String) .filter()) } diff --git a/src/plugins/edit.rs b/src/plugins/edit.rs index aeda4ba09..db116fedf 100644 --- a/src/plugins/edit.rs +++ b/src/plugins/edit.rs @@ -1,6 +1,6 @@ use nu::{ serve_plugin, CallInfo, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError, Signature, - SyntaxType, Tagged, Value, + SyntaxShape, Tagged, Value, }; struct Edit { @@ -43,8 +43,8 @@ impl Plugin for Edit { fn config(&mut self) -> Result { Ok(Signature::build("edit") .desc("Edit an existing column to have a new value.") - .required("Field", SyntaxType::String) - .required("Value", SyntaxType::String) + .required("Field", SyntaxShape::String) + .required("Value", SyntaxShape::String) .filter()) } diff --git a/src/plugins/embed.rs b/src/plugins/embed.rs index 95140aa60..646db8091 100644 --- a/src/plugins/embed.rs +++ b/src/plugins/embed.rs @@ -1,6 +1,6 @@ use nu::{ serve_plugin, CallInfo, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError, Signature, - SyntaxType, Tag, Tagged, TaggedDictBuilder, Value, + SyntaxShape, Tag, Tagged, TaggedDictBuilder, Value, }; struct Embed { @@ -37,8 +37,8 @@ impl Plugin for Embed { fn config(&mut self) -> Result { Ok(Signature::build("embed") .desc("Embeds a new field to the table.") - .required("Field", SyntaxType::String) - .rest(SyntaxType::String) + .required("Field", SyntaxShape::String) + .rest(SyntaxShape::String) .filter()) } diff --git a/src/plugins/inc.rs b/src/plugins/inc.rs index d75da4142..4422195be 100644 --- a/src/plugins/inc.rs +++ b/src/plugins/inc.rs @@ -1,6 +1,6 @@ use nu::{ serve_plugin, CallInfo, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError, Signature, - SyntaxType, Tagged, TaggedItem, Value, + SyntaxShape, Tagged, TaggedItem, Value, }; enum Action { @@ -120,7 +120,7 @@ impl Plugin for Inc { .switch("major") .switch("minor") .switch("patch") - .rest(SyntaxType::String) + .rest(SyntaxShape::String) .filter()) } @@ -181,18 +181,20 @@ mod tests { use super::{Inc, SemVerAction}; use indexmap::IndexMap; use nu::{ - CallInfo, EvaluatedArgs, Plugin, ReturnSuccess, SourceMap, Span, Tag, Tagged, - TaggedDictBuilder, TaggedItem, Value, + CallInfo, EvaluatedArgs, Plugin, ReturnSuccess, SourceMap, Tag, Tagged, TaggedDictBuilder, + TaggedItem, Value, }; struct CallStub { + origin: uuid::Uuid, positionals: Vec>, flags: IndexMap>, } impl CallStub { - fn new() -> CallStub { + fn new(origin: uuid::Uuid) -> CallStub { CallStub { + origin, positionals: vec![], flags: indexmap::IndexMap::new(), } @@ -201,14 +203,14 @@ mod tests { fn with_long_flag(&mut self, name: &str) -> &mut Self { self.flags.insert( name.to_string(), - Value::boolean(true).simple_spanned(Span::unknown()), + Value::boolean(true).tagged(Tag::unknown()), ); self } fn with_parameter(&mut self, name: &str) -> &mut Self { self.positionals - .push(Value::string(name.to_string()).simple_spanned(Span::unknown())); + .push(Value::string(name.to_string()).tagged(Tag::unknown_span(self.origin))); self } @@ -216,7 +218,7 @@ mod tests { CallInfo { args: EvaluatedArgs::new(Some(self.positionals.clone()), Some(self.flags.clone())), source_map: SourceMap::new(), - name_span: Span::unknown(), + name_tag: Tag::unknown_span(self.origin), } } } @@ -243,7 +245,7 @@ mod tests { let mut plugin = Inc::new(); assert!(plugin - .begin_filter(CallStub::new().with_long_flag("major").create()) + .begin_filter(CallStub::new(test_uuid()).with_long_flag("major").create()) .is_ok()); assert!(plugin.action.is_some()); } @@ -253,7 +255,7 @@ mod tests { let mut plugin = Inc::new(); assert!(plugin - .begin_filter(CallStub::new().with_long_flag("minor").create()) + .begin_filter(CallStub::new(test_uuid()).with_long_flag("minor").create()) .is_ok()); assert!(plugin.action.is_some()); } @@ -263,7 +265,7 @@ mod tests { let mut plugin = Inc::new(); assert!(plugin - .begin_filter(CallStub::new().with_long_flag("patch").create()) + .begin_filter(CallStub::new(test_uuid()).with_long_flag("patch").create()) .is_ok()); assert!(plugin.action.is_some()); } @@ -274,7 +276,7 @@ mod tests { assert!(plugin .begin_filter( - CallStub::new() + CallStub::new(test_uuid()) .with_long_flag("major") .with_long_flag("minor") .create(), @@ -288,7 +290,11 @@ mod tests { let mut plugin = Inc::new(); assert!(plugin - .begin_filter(CallStub::new().with_parameter("package.version").create()) + .begin_filter( + CallStub::new(test_uuid()) + .with_parameter("package.version") + .create() + ) .is_ok()); assert_eq!(plugin.field, Some("package.version".to_string())); @@ -321,7 +327,7 @@ mod tests { assert!(plugin .begin_filter( - CallStub::new() + CallStub::new(test_uuid()) .with_long_flag("major") .with_parameter("version") .create() @@ -349,7 +355,7 @@ mod tests { assert!(plugin .begin_filter( - CallStub::new() + CallStub::new(test_uuid()) .with_long_flag("minor") .with_parameter("version") .create() @@ -378,7 +384,7 @@ mod tests { assert!(plugin .begin_filter( - CallStub::new() + CallStub::new(test_uuid()) .with_long_flag("patch") .with_parameter(&field) .create() @@ -399,4 +405,8 @@ mod tests { _ => {} } } + + fn test_uuid() -> uuid::Uuid { + uuid::Uuid::nil() + } } diff --git a/src/plugins/ps.rs b/src/plugins/ps.rs index 0f06167bd..342bd5eb3 100644 --- a/src/plugins/ps.rs +++ b/src/plugins/ps.rs @@ -40,7 +40,7 @@ async fn ps(tag: Tag) -> Vec> { let mut output = vec![]; while let Some(res) = processes.next().await { if let Ok((process, usage)) = res { - let mut dict = TaggedDictBuilder::new(Tag::unknown_origin(tag.span)); + let mut dict = TaggedDictBuilder::new(tag); dict.insert("pid", Value::int(process.pid())); if let Ok(name) = process.name().await { dict.insert("name", Value::string(name)); @@ -64,7 +64,7 @@ impl Plugin for Ps { } fn begin_filter(&mut self, callinfo: CallInfo) -> Result, ShellError> { - Ok(block_on(ps(Tag::unknown_origin(callinfo.name_span))) + Ok(block_on(ps(Tag::unknown_origin(callinfo.name_tag))) .into_iter() .map(ReturnSuccess::value) .collect()) diff --git a/src/plugins/skip.rs b/src/plugins/skip.rs index cb259e99b..efd323152 100644 --- a/src/plugins/skip.rs +++ b/src/plugins/skip.rs @@ -1,6 +1,6 @@ use nu::{ serve_plugin, CallInfo, CoerceInto, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError, - Signature, SyntaxType, Tagged, TaggedItem, Value, + Signature, SyntaxShape, Tagged, TaggedItem, Value, }; struct Skip { @@ -15,9 +15,9 @@ impl Skip { impl Plugin for Skip { fn config(&mut self) -> Result { - Ok(Signature::build("skip") + Ok(Signature::build("skip") .desc("Skip a number of rows") - .rest(SyntaxType::Number) + .rest(SyntaxShape::Number) .filter()) } fn begin_filter(&mut self, call_info: CallInfo) -> Result, ShellError> { @@ -34,7 +34,7 @@ impl Plugin for Skip { return Err(ShellError::labeled_error( "Unrecognized type in params", "expected an integer", - arg.span(), + arg.tag(), )) } } diff --git a/src/plugins/str.rs b/src/plugins/str.rs index 99700449b..c9e82ab15 100644 --- a/src/plugins/str.rs +++ b/src/plugins/str.rs @@ -1,6 +1,6 @@ use nu::{ serve_plugin, CallInfo, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError, Signature, - SyntaxType, Tagged, Value, + SyntaxShape, Tagged, Value, }; use regex::Regex; @@ -174,7 +174,7 @@ impl Plugin for Str { .switch("to-int") .switch("replace") .switch("find-replace") - .rest(SyntaxType::Member) + .rest(SyntaxShape::Member) .filter()) } @@ -261,7 +261,7 @@ mod tests { use super::{Action, ReplaceAction, Str}; use indexmap::IndexMap; use nu::{ - CallInfo, EvaluatedArgs, Plugin, Primitive, ReturnSuccess, SourceMap, Span, Tag, Tagged, + CallInfo, EvaluatedArgs, Plugin, Primitive, ReturnSuccess, SourceMap, Tag, Tagged, TaggedDictBuilder, TaggedItem, Value, }; use num_bigint::BigInt; @@ -277,6 +277,7 @@ mod tests { } struct CallStub { + origin: uuid::Uuid, positionals: Vec>, flags: IndexMap>, } @@ -284,6 +285,7 @@ mod tests { impl CallStub { fn new() -> CallStub { CallStub { + origin: uuid::Uuid::nil(), positionals: vec![], flags: indexmap::IndexMap::new(), } @@ -292,14 +294,14 @@ mod tests { fn with_long_flag(&mut self, name: &str) -> &mut Self { self.flags.insert( name.to_string(), - Value::boolean(true).simple_spanned(Span::unknown()), + Value::boolean(true).tagged(Tag::unknown()), ); self } fn with_parameter(&mut self, name: &str) -> &mut Self { self.positionals - .push(Value::string(name.to_string()).simple_spanned(Span::unknown())); + .push(Value::string(name.to_string()).tagged(Tag::unknown())); self } @@ -307,7 +309,7 @@ mod tests { CallInfo { args: EvaluatedArgs::new(Some(self.positionals.clone()), Some(self.flags.clone())), source_map: SourceMap::new(), - name_span: Span::unknown(), + name_tag: Tag::unknown_span(self.origin), } } } diff --git a/src/plugins/sum.rs b/src/plugins/sum.rs index 32ecd7a9c..ffb39cb90 100644 --- a/src/plugins/sum.rs +++ b/src/plugins/sum.rs @@ -1,6 +1,6 @@ use nu::{ serve_plugin, CallInfo, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError, Signature, - Tag, Tagged, Value, + Tagged, TaggedItem, Value, }; struct Sum { @@ -18,11 +18,10 @@ impl Sum { match &self.total { Some(Tagged { item: Value::Primitive(Primitive::Int(j)), - tag: Tag { span, .. }, + tag, }) => { //TODO: handle overflow - self.total = - Some(Tagged::from_simple_spanned_item(Value::int(i + j), span)); + self.total = Some(Value::int(i + j).tagged(*tag)); Ok(()) } None => { @@ -38,11 +37,10 @@ impl Sum { match self.total { Some(Tagged { item: Value::Primitive(Primitive::Bytes(j)), - tag: Tag { span, .. }, + tag, }) => { //TODO: handle overflow - self.total = - Some(Tagged::from_simple_spanned_item(Value::bytes(b + j), span)); + self.total = Some(Value::bytes(b + j).tagged(tag)); Ok(()) } None => { diff --git a/src/plugins/sys.rs b/src/plugins/sys.rs index db7de6e62..8030a86b8 100644 --- a/src/plugins/sys.rs +++ b/src/plugins/sys.rs @@ -315,7 +315,7 @@ impl Plugin for Sys { } fn begin_filter(&mut self, callinfo: CallInfo) -> Result, ShellError> { - Ok(block_on(sysinfo(Tag::unknown_origin(callinfo.name_span))) + Ok(block_on(sysinfo(Tag::unknown_origin(callinfo.name_tag))) .into_iter() .map(ReturnSuccess::value) .collect()) diff --git a/src/prelude.rs b/src/prelude.rs index a491aff5d..d58e7989a 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -62,7 +62,7 @@ pub(crate) use crate::data::{Primitive, Value}; pub(crate) use crate::env::host::handle_unexpected; pub(crate) use crate::env::Host; pub(crate) use crate::errors::{CoerceInto, ShellError}; -pub(crate) use crate::parser::hir::SyntaxType; +pub(crate) use crate::parser::hir::SyntaxShape; pub(crate) use crate::parser::parse::parser::Number; pub(crate) use crate::parser::registry::Signature; pub(crate) use crate::shell::filesystem_shell::FilesystemShell; @@ -70,8 +70,7 @@ pub(crate) use crate::shell::help_shell::HelpShell; pub(crate) use crate::shell::shell_manager::ShellManager; pub(crate) use crate::shell::value_shell::ValueShell; pub(crate) use crate::stream::{InputStream, OutputStream}; -pub(crate) use crate::traits::{HasSpan, ToDebug}; -pub(crate) use crate::Span; +pub(crate) use crate::traits::{HasTag, ToDebug}; pub(crate) use crate::Text; pub(crate) use bigdecimal::BigDecimal; pub(crate) use futures::stream::BoxStream; diff --git a/src/shell/filesystem_shell.rs b/src/shell/filesystem_shell.rs index 16cbf513f..1d26fa163 100644 --- a/src/shell/filesystem_shell.rs +++ b/src/shell/filesystem_shell.rs @@ -81,23 +81,27 @@ impl Shell for FilesystemShell { dirs::home_dir() } - fn ls(&self, args: EvaluatedWholeStreamCommandArgs) -> Result { + fn ls( + &self, + pattern: Option>, + command_tag: Tag, + ) -> Result { let cwd = self.path(); let mut full_path = PathBuf::from(self.path()); - match &args.nth(0) { - Some(value) => full_path.push(Path::new(&value.as_path()?)), + match &pattern { + Some(value) => full_path.push((*value).as_ref()), _ => {} } let entries: Vec<_> = match glob::glob(&full_path.to_string_lossy()) { Ok(files) => files.collect(), Err(_) => { - if let Some(source) = args.nth(0) { + if let Some(source) = pattern { return Err(ShellError::labeled_error( "Invalid pattern", "Invalid pattern", - source.span(), + source.tag(), )); } else { return Err(ShellError::string("Invalid pattern.")); @@ -114,17 +118,17 @@ impl Shell for FilesystemShell { let entries = std::fs::read_dir(&entry); let entries = match entries { Err(e) => { - if let Some(s) = args.nth(0) { + if let Some(s) = pattern { return Err(ShellError::labeled_error( e.to_string(), e.to_string(), - s.span(), + s.tag(), )); } else { return Err(ShellError::labeled_error( e.to_string(), e.to_string(), - args.name_span(), + command_tag, )); } } @@ -138,11 +142,7 @@ impl Shell for FilesystemShell { } else { Path::new(&filepath) }; - let value = dir_entry_dict( - filename, - &entry.metadata()?, - Tag::unknown_origin(args.call_info.name_span), - )?; + let value = dir_entry_dict(filename, &entry.metadata()?, command_tag)?; shell_entries.push_back(ReturnSuccess::value(value)) } return Ok(shell_entries.to_output_stream()); @@ -159,11 +159,7 @@ impl Shell for FilesystemShell { Path::new(&entry) }; let metadata = std::fs::metadata(&entry)?; - let value = dir_entry_dict( - filename, - &metadata, - Tag::unknown_origin(args.call_info.name_span), - )?; + let value = dir_entry_dict(filename, &metadata, command_tag)?; shell_entries.push_back(ReturnSuccess::value(value)) } } @@ -179,7 +175,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( "Can not change to home directory", "can not go to home", - args.call_info.name_span, + args.call_info.name_tag, )) } }, @@ -197,7 +193,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( "Can not change to directory", "directory not found", - v.span().clone(), + v.tag().clone(), )) } } @@ -207,8 +203,7 @@ impl Shell for FilesystemShell { let mut stream = VecDeque::new(); - stream.push_back( - ReturnSuccess::change_cwd( + stream.push_back(ReturnSuccess::change_cwd( path.to_string_lossy().to_string(), )); @@ -222,10 +217,10 @@ impl Shell for FilesystemShell { dst, recursive, }: CopyArgs, - name: Span, + name: Tag, path: &str, ) -> Result { - let name_span = name; + let name_tag = name; let mut source = PathBuf::from(path); let mut destination = PathBuf::from(path); @@ -280,7 +275,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( e.to_string(), e.to_string(), - name_span, + name_tag, )); } Ok(o) => o, @@ -296,7 +291,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( e.to_string(), e.to_string(), - name_span, + name_tag, )); } Ok(o) => o, @@ -332,7 +327,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( e.to_string(), e.to_string(), - name_span, + name_tag, )); } Ok(o) => o, @@ -346,7 +341,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( e.to_string(), e.to_string(), - name_span, + name_tag, )); } Ok(o) => o, @@ -360,7 +355,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( "Copy aborted. Not a valid path", "Copy aborted. Not a valid path", - name_span, + name_tag, )) } } @@ -370,7 +365,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( e.to_string(), e.to_string(), - name_span, + name_tag, )); } Ok(o) => o, @@ -406,7 +401,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( e.to_string(), e.to_string(), - name_span, + name_tag, )); } Ok(o) => o, @@ -420,7 +415,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( e.to_string(), e.to_string(), - name_span, + name_tag, )); } Ok(o) => o, @@ -453,7 +448,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( "Copy aborted. Not a valid path", "Copy aborted. Not a valid path", - name_span, + name_tag, )) } } @@ -480,7 +475,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( "Copy aborted. Not a valid destination", "Copy aborted. Not a valid destination", - name_span, + name_tag, )) } } @@ -489,7 +484,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( format!("Copy aborted. (Does {:?} exist?)", destination_file_name), format!("Copy aborted. (Does {:?} exist?)", destination_file_name), - &dst.span(), + dst.tag(), )); } } @@ -500,7 +495,7 @@ impl Shell for FilesystemShell { fn mkdir( &self, MkdirArgs { rest: directories }: MkdirArgs, - name: Span, + name: Tag, path: &str, ) -> Result { let full_path = PathBuf::from(path); @@ -525,7 +520,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( reason.to_string(), reason.to_string(), - dir.span(), + dir.tag(), )) } Ok(_) => {} @@ -538,10 +533,10 @@ impl Shell for FilesystemShell { fn mv( &self, MoveArgs { src, dst }: MoveArgs, - name: Span, + name: Tag, path: &str, ) -> Result { - let name_span = name; + let name_tag = name; let mut source = PathBuf::from(path); let mut destination = PathBuf::from(path); @@ -567,7 +562,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( "Rename aborted. Not a valid destination", "Rename aborted. Not a valid destination", - dst.span(), + dst.tag(), )) } } @@ -581,7 +576,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( "Rename aborted. Not a valid entry name", "Rename aborted. Not a valid entry name", - name_span, + name_tag, )) } }; @@ -593,7 +588,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( format!("Rename aborted. {:}", e.to_string()), format!("Rename aborted. {:}", e.to_string()), - name_span, + name_tag, )) } }; @@ -617,7 +612,7 @@ impl Shell for FilesystemShell { destination_file_name, e.to_string(), ), - name_span, + name_tag, )); } Ok(o) => o, @@ -640,7 +635,7 @@ impl Shell for FilesystemShell { destination_file_name, e.to_string(), ), - name_span, + name_tag, )); } Ok(o) => o, @@ -662,7 +657,7 @@ impl Shell for FilesystemShell { destination_file_name, e.to_string(), ), - name_span, + name_tag, )); } Ok(o) => o, @@ -715,7 +710,7 @@ impl Shell for FilesystemShell { destination_file_name, e.to_string(), ), - name_span, + name_tag, )); } Ok(o) => o, @@ -739,7 +734,7 @@ impl Shell for FilesystemShell { destination_file_name, e.to_string(), ), - name_span, + name_tag, )); } Ok(o) => o, @@ -762,7 +757,7 @@ impl Shell for FilesystemShell { destination_file_name, e.to_string(), ), - name_span, + name_tag, )); } Ok(o) => o, @@ -794,7 +789,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( "Rename aborted. Not a valid entry name", "Rename aborted. Not a valid entry name", - name_span, + name_tag, )) } }; @@ -818,7 +813,7 @@ impl Shell for FilesystemShell { destination_file_name, e.to_string(), ), - name_span, + name_tag, )); } Ok(o) => o, @@ -830,7 +825,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( format!("Rename aborted. (Does {:?} exist?)", destination_file_name), format!("Rename aborted. (Does {:?} exist?)", destination_file_name), - dst.span(), + dst.tag(), )); } } @@ -841,16 +836,16 @@ impl Shell for FilesystemShell { fn rm( &self, RemoveArgs { target, recursive }: RemoveArgs, - name: Span, + name: Tag, path: &str, ) -> Result { - let name_span = name; + let name_tag = name; if target.item.to_str() == Some(".") || target.item.to_str() == Some("..") { return Err(ShellError::labeled_error( "Remove aborted. \".\" or \"..\" may not be removed.", "Remove aborted. \".\" or \"..\" may not be removed.", - target.span(), + target.tag(), )); } @@ -882,7 +877,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( format!("{:?} is a directory. Try using \"--recursive\".", file), format!("{:?} is a directory. Try using \"--recursive\".", file), - target.span(), + target.tag(), )); } } @@ -899,7 +894,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( "Remove aborted. Not a valid path", "Remove aborted. Not a valid path", - name_span, + name_tag, )) } } @@ -919,7 +914,7 @@ impl Shell for FilesystemShell { "Directory {:?} found somewhere inside. Try using \"--recursive\".", path_file_name ), - target.span(), + target.tag(), )); } @@ -933,7 +928,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( format!("Remove aborted. {:}", e.to_string()), format!("Remove aborted. {:}", e.to_string()), - name_span, + name_tag, )) } } @@ -954,7 +949,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( "unable to show current directory", "pwd command failed", - args.call_info.name_span, + args.call_info.name_tag, )); } }; @@ -962,7 +957,7 @@ impl Shell for FilesystemShell { let mut stream = VecDeque::new(); stream.push_back(ReturnSuccess::value( Value::Primitive(Primitive::String(p.to_string_lossy().to_string())) - .simple_spanned(args.call_info.name_span), + .tagged(args.call_info.name_tag), )); Ok(stream.into()) diff --git a/src/shell/help_shell.rs b/src/shell/help_shell.rs index 35c939d7d..25f1b9c42 100644 --- a/src/shell/help_shell.rs +++ b/src/shell/help_shell.rs @@ -126,7 +126,11 @@ impl Shell for HelpShell { self.path = path.clone(); } - fn ls(&self, _args: EvaluatedWholeStreamCommandArgs) -> Result { + fn ls( + &self, + _pattern: Option>, + _command_tag: Tag, + ) -> Result { Ok(self .commands() .map(|x| ReturnSuccess::value(x)) @@ -161,24 +165,19 @@ impl Shell for HelpShell { Ok(stream.into()) } - fn cp(&self, _args: CopyArgs, _name: Span, _path: &str) -> Result { + fn cp(&self, _args: CopyArgs, _name: Tag, _path: &str) -> Result { Ok(OutputStream::empty()) } - fn mv(&self, _args: MoveArgs, _name: Span, _path: &str) -> Result { + fn mv(&self, _args: MoveArgs, _name: Tag, _path: &str) -> Result { Ok(OutputStream::empty()) } - fn mkdir( - &self, - _args: MkdirArgs, - _name: Span, - _path: &str, - ) -> Result { + fn mkdir(&self, _args: MkdirArgs, _name: Tag, _path: &str) -> Result { Ok(OutputStream::empty()) } - fn rm(&self, _args: RemoveArgs, _name: Span, _path: &str) -> Result { + fn rm(&self, _args: RemoveArgs, _name: Tag, _path: &str) -> Result { Ok(OutputStream::empty()) } diff --git a/src/shell/helper.rs b/src/shell/helper.rs index 16802657d..6fb454435 100644 --- a/src/shell/helper.rs +++ b/src/shell/helper.rs @@ -66,7 +66,7 @@ impl Highlighter for Helper { } fn highlight<'l>(&self, line: &'l str, _pos: usize) -> Cow<'l, str> { - let tokens = crate::parser::pipeline(nom_input(line)); + let tokens = crate::parser::pipeline(nom_input(line, uuid::Uuid::nil())); match tokens { Err(_) => Cow::Borrowed(line), @@ -106,47 +106,47 @@ impl Highlighter for Helper { fn paint_token_node(token_node: &TokenNode, line: &str) -> String { let styled = match token_node { - TokenNode::Call(..) => Color::Cyan.bold().paint(token_node.span().slice(line)), - TokenNode::Whitespace(..) => Color::White.normal().paint(token_node.span().slice(line)), - TokenNode::Flag(..) => Color::Black.bold().paint(token_node.span().slice(line)), - TokenNode::Member(..) => Color::Yellow.bold().paint(token_node.span().slice(line)), - TokenNode::Path(..) => Color::Green.bold().paint(token_node.span().slice(line)), - TokenNode::Error(..) => Color::Red.bold().paint(token_node.span().slice(line)), - TokenNode::Delimited(..) => Color::White.paint(token_node.span().slice(line)), - TokenNode::Operator(..) => Color::White.normal().paint(token_node.span().slice(line)), - TokenNode::Pipeline(..) => Color::Blue.normal().paint(token_node.span().slice(line)), + TokenNode::Call(..) => Color::Cyan.bold().paint(token_node.tag().slice(line)), + TokenNode::Whitespace(..) => Color::White.normal().paint(token_node.tag().slice(line)), + TokenNode::Flag(..) => Color::Black.bold().paint(token_node.tag().slice(line)), + TokenNode::Member(..) => Color::Yellow.bold().paint(token_node.tag().slice(line)), + TokenNode::Path(..) => Color::Green.bold().paint(token_node.tag().slice(line)), + TokenNode::Error(..) => Color::Red.bold().paint(token_node.tag().slice(line)), + TokenNode::Delimited(..) => Color::White.paint(token_node.tag().slice(line)), + TokenNode::Operator(..) => Color::White.normal().paint(token_node.tag().slice(line)), + TokenNode::Pipeline(..) => Color::Blue.normal().paint(token_node.tag().slice(line)), TokenNode::Token(Tagged { item: RawToken::Number(..), .. - }) => Color::Purple.bold().paint(token_node.span().slice(line)), + }) => Color::Purple.bold().paint(token_node.tag().slice(line)), TokenNode::Token(Tagged { item: RawToken::Size(..), .. - }) => Color::Purple.bold().paint(token_node.span().slice(line)), + }) => Color::Purple.bold().paint(token_node.tag().slice(line)), TokenNode::Token(Tagged { item: RawToken::GlobPattern, .. - }) => Color::Cyan.normal().paint(token_node.span().slice(line)), + }) => Color::Cyan.normal().paint(token_node.tag().slice(line)), TokenNode::Token(Tagged { item: RawToken::String(..), .. - }) => Color::Green.normal().paint(token_node.span().slice(line)), + }) => Color::Green.normal().paint(token_node.tag().slice(line)), TokenNode::Token(Tagged { item: RawToken::Variable(..), .. - }) => Color::Yellow.bold().paint(token_node.span().slice(line)), + }) => Color::Yellow.bold().paint(token_node.tag().slice(line)), TokenNode::Token(Tagged { item: RawToken::Bare, .. - }) => Color::Green.normal().paint(token_node.span().slice(line)), + }) => Color::Green.normal().paint(token_node.tag().slice(line)), TokenNode::Token(Tagged { item: RawToken::ExternalCommand(..), .. - }) => Color::Cyan.bold().paint(token_node.span().slice(line)), + }) => Color::Cyan.bold().paint(token_node.tag().slice(line)), TokenNode::Token(Tagged { item: RawToken::ExternalWord, .. - }) => Color::Black.bold().paint(token_node.span().slice(line)), + }) => Color::Black.bold().paint(token_node.tag().slice(line)), }; styled.to_string() @@ -166,7 +166,7 @@ fn paint_pipeline_element(pipeline_element: &PipelineElement, line: &str) -> Str styled.push_str( &Color::Cyan .bold() - .paint(pipeline_element.call().head().span().slice(line)) + .paint(pipeline_element.call().head().tag().slice(line)) .to_string(), ); diff --git a/src/shell/shell.rs b/src/shell/shell.rs index 549aa79d2..c567e474a 100644 --- a/src/shell/shell.rs +++ b/src/shell/shell.rs @@ -13,12 +13,16 @@ pub trait Shell: std::fmt::Debug { fn name(&self, source_map: &SourceMap) -> String; fn homedir(&self) -> Option; - fn ls(&self, args: EvaluatedWholeStreamCommandArgs) -> Result; + fn ls( + &self, + pattern: Option>, + command_tag: Tag, + ) -> Result; fn cd(&self, args: EvaluatedWholeStreamCommandArgs) -> Result; - fn cp(&self, args: CopyArgs, name: Span, path: &str) -> Result; - fn mkdir(&self, args: MkdirArgs, name: Span, path: &str) -> Result; - fn mv(&self, args: MoveArgs, name: Span, path: &str) -> Result; - fn rm(&self, args: RemoveArgs, name: Span, path: &str) -> Result; + fn cp(&self, args: CopyArgs, name: Tag, path: &str) -> Result; + fn mkdir(&self, args: MkdirArgs, name: Tag, path: &str) -> Result; + fn mv(&self, args: MoveArgs, name: Tag, path: &str) -> Result; + fn rm(&self, args: RemoveArgs, name: Tag, path: &str) -> Result; fn path(&self) -> String; fn pwd(&self, args: EvaluatedWholeStreamCommandArgs) -> Result; fn set_path(&mut self, path: String); diff --git a/src/shell/shell_manager.rs b/src/shell/shell_manager.rs index 53984c950..c4c42367e 100644 --- a/src/shell/shell_manager.rs +++ b/src/shell/shell_manager.rs @@ -115,10 +115,14 @@ impl ShellManager { env[self.current_shell].homedir() } - pub fn ls(&self, args: EvaluatedWholeStreamCommandArgs) -> Result { + pub fn ls( + &self, + path: Option>, + command_tag: Tag, + ) -> Result { let env = self.shells.lock().unwrap(); - env[self.current_shell].ls(args) + env[self.current_shell].ls(path, command_tag) } pub fn cd(&self, args: EvaluatedWholeStreamCommandArgs) -> Result { diff --git a/src/shell/value_shell.rs b/src/shell/value_shell.rs index 010c7ae08..175e232e7 100644 --- a/src/shell/value_shell.rs +++ b/src/shell/value_shell.rs @@ -87,13 +87,15 @@ impl Shell for ValueShell { Some(PathBuf::from("/")) } - fn ls(&self, args: EvaluatedWholeStreamCommandArgs) -> Result { + fn ls( + &self, + target: Option>, + command_name: Tag, + ) -> Result { let mut full_path = PathBuf::from(self.path()); - let target = args.nth(0); - - match target { - Some(value) => full_path.push(Path::new(&value.as_path()?)), + match &target { + Some(value) => full_path.push(value.as_ref()), _ => {} } @@ -101,18 +103,18 @@ impl Shell for ValueShell { value_system.walk_decorate(&self.value)?; if !value_system.exists(&full_path) { - if let Some(target) = target { + if let Some(target) = &target { return Err(ShellError::labeled_error( "Can not list entries inside", "No such path exists", - target.span(), + target.tag(), )); } return Err(ShellError::labeled_error( "Can not list entries inside", "No such path exists", - args.call_info.name_span, + command_name, )); } @@ -157,14 +159,14 @@ impl Shell for ValueShell { return Err(ShellError::labeled_error( "Can not change to path inside", "No such path exists", - destination.span(), + destination.tag(), )); } return Err(ShellError::labeled_error( "Can not change to path inside", "No such path exists", - args.call_info.name_span, + args.call_info.name_tag, )); } @@ -173,7 +175,7 @@ impl Shell for ValueShell { Ok(stream.into()) } - fn cp(&self, _args: CopyArgs, name: Span, _path: &str) -> Result { + fn cp(&self, _args: CopyArgs, name: Tag, _path: &str) -> Result { Err(ShellError::labeled_error( "cp not currently supported on values", "not currently supported", @@ -181,7 +183,7 @@ impl Shell for ValueShell { )) } - fn mv(&self, _args: MoveArgs, name: Span, _path: &str) -> Result { + fn mv(&self, _args: MoveArgs, name: Tag, _path: &str) -> Result { Err(ShellError::labeled_error( "mv not currently supported on values", "not currently supported", @@ -189,7 +191,7 @@ impl Shell for ValueShell { )) } - fn mkdir(&self, _args: MkdirArgs, name: Span, _path: &str) -> Result { + fn mkdir(&self, _args: MkdirArgs, name: Tag, _path: &str) -> Result { Err(ShellError::labeled_error( "mkdir not currently supported on values", "not currently supported", @@ -197,7 +199,7 @@ impl Shell for ValueShell { )) } - fn rm(&self, _args: RemoveArgs, name: Span, _path: &str) -> Result { + fn rm(&self, _args: RemoveArgs, name: Tag, _path: &str) -> Result { Err(ShellError::labeled_error( "rm not currently supported on values", "not currently supported", @@ -213,7 +215,7 @@ impl Shell for ValueShell { let mut stream = VecDeque::new(); stream.push_back(ReturnSuccess::value(Tagged::from_item( Value::string(self.path()), - args.call_info.name_span, + args.call_info.name_tag, ))); Ok(stream.into()) } diff --git a/src/traits.rs b/src/traits.rs index 5b022c444..677d019ad 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -12,8 +12,8 @@ impl fmt::Display for Debuggable<'_, T> { } } -pub trait HasSpan { - fn span(&self) -> Span; +pub trait HasTag { + fn tag(&self) -> Tag; } pub trait ToDebug: Sized { From bee7c5639cc78d65e6656518627a86009a522500 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Wed, 11 Sep 2019 19:53:05 +1200 Subject: [PATCH 4/4] Revert "Migrate most uses of the Span concept to Tag" --- Cargo.lock | 8 +- Cargo.toml | 2 +- src/cli.rs | 25 +-- src/commands/cd.rs | 3 +- src/commands/classified.rs | 31 ++-- src/commands/clip.rs | 2 +- src/commands/command.rs | 30 ++-- src/commands/config.rs | 44 +++-- src/commands/cp.rs | 8 +- src/commands/date.rs | 44 +++-- src/commands/echo.rs | 8 +- src/commands/enter.rs | 6 +- src/commands/fetch.rs | 76 +++++--- src/commands/first.rs | 2 +- src/commands/from_bson.rs | 14 +- src/commands/from_csv.rs | 12 +- src/commands/from_ini.rs | 12 +- src/commands/from_json.rs | 18 +- src/commands/from_sqlite.rs | 12 +- src/commands/from_toml.rs | 12 +- src/commands/from_tsv.rs | 12 +- src/commands/from_xml.rs | 12 +- src/commands/from_yaml.rs | 12 +- src/commands/get.rs | 6 +- src/commands/help.rs | 8 +- src/commands/last.rs | 2 +- src/commands/lines.rs | 8 +- src/commands/ls.rs | 17 +- src/commands/mkdir.rs | 2 +- src/commands/mv.rs | 8 +- src/commands/nth.rs | 2 +- src/commands/open.rs | 55 ++++-- src/commands/pick.rs | 2 +- src/commands/post.rs | 82 +++++---- src/commands/reject.rs | 2 +- src/commands/rm.rs | 4 +- src/commands/save.rs | 32 ++-- src/commands/shells.rs | 6 +- src/commands/size.rs | 10 +- src/commands/skip_while.rs | 2 +- src/commands/sort_by.rs | 2 +- src/commands/split_column.rs | 14 +- src/commands/split_row.rs | 7 +- src/commands/tags.rs | 4 +- src/commands/to_bson.rs | 32 ++-- src/commands/to_csv.rs | 10 +- src/commands/to_json.rs | 12 +- src/commands/to_sqlite.rs | 6 +- src/commands/to_toml.rs | 12 +- src/commands/to_tsv.rs | 10 +- src/commands/to_yaml.rs | 12 +- src/commands/trim.rs | 4 +- src/commands/version.rs | 8 +- src/commands/where_.rs | 11 +- src/commands/which_.rs | 13 +- src/context.rs | 12 +- src/data/base.rs | 18 +- src/data/config.rs | 12 +- src/data/into.rs | 4 +- src/data/meta.rs | 164 +++++------------- src/errors.rs | 96 +++++----- src/evaluate/evaluator.rs | 53 +++--- src/format/table.rs | 2 +- src/lib.rs | 4 +- src/parser.rs | 4 +- src/parser/deserializer.rs | 6 +- src/parser/hir.rs | 65 ++++--- src/parser/hir/baseline_parse.rs | 106 ++++++------ src/parser/hir/baseline_parse_tokens.rs | 161 +++++++++-------- src/parser/hir/external_command.rs | 2 +- src/parser/hir/named.rs | 5 +- src/parser/parse/files.rs | 35 ++-- src/parser/parse/flag.rs | 4 +- src/parser/parse/parser.rs | 157 +++++++---------- src/parser/parse/pipeline.rs | 10 +- src/parser/parse/token_tree.rs | 44 ++--- src/parser/parse/token_tree_builder.rs | 221 ++++++++++++++---------- src/parser/parse/tokens.rs | 32 ++-- src/parser/parse_command.rs | 27 +-- src/parser/registry.rs | 38 ++-- src/plugins/add.rs | 8 +- src/plugins/edit.rs | 6 +- src/plugins/embed.rs | 6 +- src/plugins/inc.rs | 42 ++--- src/plugins/ps.rs | 4 +- src/plugins/skip.rs | 8 +- src/plugins/str.rs | 14 +- src/plugins/sum.rs | 12 +- src/plugins/sys.rs | 2 +- src/prelude.rs | 5 +- src/shell/filesystem_shell.rs | 115 ++++++------ src/shell/help_shell.rs | 19 +- src/shell/helper.rs | 38 ++-- src/shell/shell.rs | 14 +- src/shell/shell_manager.rs | 8 +- src/shell/value_shell.rs | 32 ++-- src/traits.rs | 4 +- 97 files changed, 1255 insertions(+), 1174 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 22af92884..08fcb94a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1474,8 +1474,8 @@ dependencies = [ ] [[package]] -name = "nom_locate" -version = "1.0.0" +name = "nom5_locate" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytecount 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1531,7 +1531,7 @@ dependencies = [ "mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", "neso 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "nom 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "nom_locate 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "nom5_locate 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "onig_sys 69.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3129,7 +3129,7 @@ dependencies = [ "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" "checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" "checksum nom 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e9761d859320e381010a4f7f8ed425f2c924de33ad121ace447367c713ad561b" -"checksum nom_locate 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f932834fd8e391fc7710e2ba17e8f9f8645d846b55aa63207e17e110a1e1ce35" +"checksum nom5_locate 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3d4312467f8b28d909344b934207e502212fa5a3adf1bff7428b0b86a666223d" "checksum ntapi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f26e041cd983acbc087e30fcba770380cfa352d0e392e175b2344ebaf7ea0602" "checksum num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "57450397855d951f1a41305e54851b1a7b8f5d2e349543a02a2effe25459f718" "checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" diff --git a/Cargo.toml b/Cargo.toml index c4369b94b..f9e13c934 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,7 +53,7 @@ ctrlc = "3.1.3" surf = "1.0.2" url = "2.1.0" roxmltree = "0.7.0" -nom_locate = "1.0.0" +nom5_locate = "0.1.1" enum-utils = "0.1.1" unicode-xid = "0.2.0" serde_ini = "0.2.0" diff --git a/src/cli.rs b/src/cli.rs index c29617ca9..ec8c7085c 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -266,7 +266,7 @@ pub async fn cli() -> Result<(), Box> { context.shell_manager.clone(), ))); - let edit_mode = crate::data::config::config(Tag::unknown())? + let edit_mode = crate::data::config::config(Span::unknown())? .get("edit_mode") .map(|s| match s.as_string().unwrap().as_ref() { "vi" => EditMode::Vi, @@ -344,7 +344,7 @@ async fn process_line(readline: Result, ctx: &mut Context Ok(line) if line.trim() == "" => LineResult::Success(line.clone()), Ok(line) => { - let result = match crate::parser::parse(&line, uuid::Uuid::nil()) { + let result = match crate::parser::parse(&line) { Err(err) => { return LineResult::Error(line.clone(), err); } @@ -366,7 +366,7 @@ async fn process_line(readline: Result, ctx: &mut Context .commands .push(ClassifiedCommand::Internal(InternalCommand { command: whole_stream_command(autoview::Autoview), - name_tag: Tag::unknown(), + name_span: Span::unknown(), args: hir::Call::new( Box::new(hir::Expression::synthetic_string("autoview")), None, @@ -486,10 +486,10 @@ fn classify_command( match call { // If the command starts with `^`, treat it as an external command no matter what call if call.head().is_external() => { - let name_tag = call.head().expect_external(); - let name = name_tag.slice(source); + let name_span = call.head().expect_external(); + let name = name_span.slice(source); - Ok(external_command(call, source, name.tagged(name_tag))) + Ok(external_command(call, source, name.tagged(name_span))) } // Otherwise, if the command is a bare word, we'll need to triage it @@ -511,19 +511,19 @@ fn classify_command( Ok(ClassifiedCommand::Internal(InternalCommand { command, - name_tag: head.tag(), + name_span: head.span().clone(), args, })) } // otherwise, it's an external command - false => Ok(external_command(call, source, name.tagged(head.tag()))), + false => Ok(external_command(call, source, name.tagged(head.span()))), } } // If the command is something else (like a number or a variable), that is currently unsupported. // We might support `$somevar` as a curried command in the future. - call => Err(ShellError::invalid_command(call.head().tag())), + call => Err(ShellError::invalid_command(call.head().span())), } } @@ -540,7 +540,10 @@ fn external_command( .iter() .filter_map(|i| match i { TokenNode::Whitespace(_) => None, - other => Some(other.as_external_arg(source).tagged(other.tag())), + other => Some(Tagged::from_simple_spanned_item( + other.as_external_arg(source), + other.span(), + )), }) .collect(), None => vec![], @@ -550,7 +553,7 @@ fn external_command( ClassifiedCommand::External(ExternalCommand { name: name.to_string(), - name_tag: tag, + name_span: tag.span, args: arg_list_strings, }) } diff --git a/src/commands/cd.rs b/src/commands/cd.rs index a3f5a8d89..a84e66fce 100644 --- a/src/commands/cd.rs +++ b/src/commands/cd.rs @@ -10,7 +10,8 @@ impl WholeStreamCommand for CD { } fn signature(&self) -> Signature { - Signature::build("cd").optional("directory", SyntaxShape::Path) + Signature::build("cd") + .optional("directory", SyntaxType::Path) } fn usage(&self) -> &str { diff --git a/src/commands/classified.rs b/src/commands/classified.rs index 4d15bce12..277a92534 100644 --- a/src/commands/classified.rs +++ b/src/commands/classified.rs @@ -86,7 +86,7 @@ pub(crate) enum ClassifiedCommand { pub(crate) struct InternalCommand { pub(crate) command: Arc, - pub(crate) name_tag: Tag, + pub(crate) name_span: Span, pub(crate) args: hir::Call, } @@ -108,7 +108,7 @@ impl InternalCommand { let result = context.run_command( self.command, - self.name_tag.clone(), + self.name_span.clone(), context.source_map.clone(), self.args, &source, @@ -133,18 +133,21 @@ impl InternalCommand { match value { Tagged { item: Value::Primitive(Primitive::String(cmd)), - tag, + .. } => { context.shell_manager.insert_at_current(Box::new( HelpShell::for_command( - Value::string(cmd).tagged(tag), - &context.registry(), + Tagged::from_simple_spanned_item( + Value::string(cmd), + Span::unknown(), + ), + &context.registry().clone(), )?, )); } _ => { context.shell_manager.insert_at_current(Box::new( - HelpShell::index(&context.registry())?, + HelpShell::index(&context.registry().clone())?, )); } } @@ -186,7 +189,7 @@ impl InternalCommand { pub(crate) struct ExternalCommand { pub(crate) name: String, - pub(crate) name_tag: Tag, + pub(crate) name_span: Span, pub(crate) args: Vec>, } @@ -205,7 +208,7 @@ impl ExternalCommand { ) -> Result { let stdin = input.stdin; let inputs: Vec> = input.objects.into_vec().await; - let name_tag = self.name_tag.clone(); + let name_span = self.name_span.clone(); trace!(target: "nu::run::external", "-> {}", self.name); trace!(target: "nu::run::external", "inputs = {:?}", inputs); @@ -224,17 +227,17 @@ impl ExternalCommand { for i in &inputs { if i.as_string().is_err() { - let mut tag = None; + let mut span = None; for arg in &self.args { if arg.item.contains("$it") { - tag = Some(arg.tag()); + span = Some(arg.span()); } } - if let Some(tag) = tag { + if let Some(span) = span { return Err(ShellError::labeled_error( "External $it needs string data", "given row instead of string data", - tag, + span, )); } else { return Err(ShellError::string("Error: $it needs string data")); @@ -311,7 +314,9 @@ impl ExternalCommand { let stdout = popen.stdout.take().unwrap(); let file = futures::io::AllowStdIo::new(stdout); let stream = Framed::new(file, LinesCodec {}); - let stream = stream.map(move |line| Value::string(line.unwrap()).tagged(name_tag)); + let stream = stream.map(move |line| { + Tagged::from_simple_spanned_item(Value::string(line.unwrap()), name_span) + }); Ok(ClassifiedInputStream::from_input_stream( stream.boxed() as BoxStream<'static, Tagged> )) diff --git a/src/commands/clip.rs b/src/commands/clip.rs index 2ef5bfac1..9bf7fa9f3 100644 --- a/src/commands/clip.rs +++ b/src/commands/clip.rs @@ -51,7 +51,7 @@ pub mod clipboard { Ok(OutputStream::from(stream)) } - async fn inner_clip(input: Vec>, name: Tag) -> OutputStream { + async fn inner_clip(input: Vec>, name: Span) -> OutputStream { let mut clip_context: ClipboardContext = ClipboardProvider::new().unwrap(); let mut new_copy_data = String::new(); diff --git a/src/commands/command.rs b/src/commands/command.rs index 99352a7b1..6be179895 100644 --- a/src/commands/command.rs +++ b/src/commands/command.rs @@ -18,7 +18,7 @@ pub struct UnevaluatedCallInfo { pub args: hir::Call, pub source: Text, pub source_map: SourceMap, - pub name_tag: Tag, + pub name_span: Span, } impl ToDebug for UnevaluatedCallInfo { @@ -38,7 +38,7 @@ impl UnevaluatedCallInfo { Ok(CallInfo { args, source_map: self.source_map, - name_tag: self.name_tag, + name_span: self.name_span, }) } @@ -74,7 +74,7 @@ impl UnevaluatedCallInfo { pub struct CallInfo { pub args: registry::EvaluatedArgs, pub source_map: SourceMap, - pub name_tag: Tag, + pub name_span: Span, } impl CallInfo { @@ -89,7 +89,7 @@ impl CallInfo { args: T::deserialize(&mut deserializer)?, context: RunnablePerItemContext { shell_manager: shell_manager.clone(), - name: self.name_tag, + name: self.name_span, }, callback, }) @@ -158,7 +158,7 @@ impl CommandArgs { let host = self.host.clone(); let args = self.evaluate_once(registry)?; let (input, args) = args.split(); - let name_tag = args.call_info.name_tag; + let name_span = args.call_info.name_span; let mut deserializer = ConfigDeserializer::from_call_info(args.call_info); Ok(RunnableArgs { @@ -167,7 +167,7 @@ impl CommandArgs { input, commands: registry.clone(), shell_manager, - name: name_tag, + name: name_span, source_map, host, }, @@ -191,7 +191,7 @@ impl CommandArgs { let host = self.host.clone(); let args = self.evaluate_once(registry)?; let (input, args) = args.split(); - let name_tag = args.call_info.name_tag; + let name_span = args.call_info.name_span; let mut deserializer = ConfigDeserializer::from_call_info(args.call_info); Ok(RunnableRawArgs { @@ -200,7 +200,7 @@ impl CommandArgs { input, commands: registry.clone(), shell_manager, - name: name_tag, + name: name_span, source_map, host, }, @@ -212,7 +212,7 @@ impl CommandArgs { pub struct RunnablePerItemContext { pub shell_manager: ShellManager, - pub name: Tag, + pub name: Span, } impl RunnablePerItemContext { @@ -227,7 +227,7 @@ pub struct RunnableContext { pub host: Arc>, pub commands: CommandRegistry, pub source_map: SourceMap, - pub name: Tag, + pub name: Span, } impl RunnableContext { @@ -311,8 +311,8 @@ impl EvaluatedWholeStreamCommandArgs { } } - pub fn name_tag(&self) -> Tag { - self.args.call_info.name_tag + pub fn name_span(&self) -> Span { + self.args.call_info.name_span } pub fn parts(self) -> (InputStream, registry::EvaluatedArgs) { @@ -471,6 +471,12 @@ impl ReturnSuccess { pub fn action(input: CommandAction) -> ReturnValue { Ok(ReturnSuccess::Action(input)) } + + pub fn spanned_value(input: Value, span: Span) -> ReturnValue { + Ok(ReturnSuccess::Value(Tagged::from_simple_spanned_item( + input, span, + ))) + } } pub trait WholeStreamCommand: Send + Sync { diff --git a/src/commands/config.rs b/src/commands/config.rs index 3b36c88fa..97b2a948e 100644 --- a/src/commands/config.rs +++ b/src/commands/config.rs @@ -1,7 +1,7 @@ use crate::commands::WholeStreamCommand; use crate::data::{config, Value}; use crate::errors::ShellError; -use crate::parser::hir::SyntaxShape; +use crate::parser::hir::SyntaxType; use crate::parser::registry::{self}; use crate::prelude::*; use std::iter::FromIterator; @@ -26,10 +26,10 @@ impl WholeStreamCommand for Config { fn signature(&self) -> Signature { Signature::build("config") - .named("load", SyntaxShape::Path) - .named("set", SyntaxShape::Any) - .named("get", SyntaxShape::Any) - .named("remove", SyntaxShape::Any) + .named("load", SyntaxType::Path) + .named("set", SyntaxType::Any) + .named("get", SyntaxType::Any) + .named("remove", SyntaxType::Any) .switch("clear") .switch("path") } @@ -96,21 +96,41 @@ pub fn config( config::write(&result, &configuration)?; - return Ok(stream![Value::Row(result.into()).tagged(value.tag())].from_input_stream()); + return Ok(stream![Tagged::from_simple_spanned_item( + Value::Row(result.into()), + value.span() + )] + .from_input_stream()); } - if let Tagged { item: true, tag } = clear { + if let Tagged { + item: true, + tag: Tag { span, .. }, + } = clear + { result.clear(); config::write(&result, &configuration)?; - return Ok(stream![Value::Row(result.into()).tagged(tag)].from_input_stream()); + return Ok(stream![Tagged::from_simple_spanned_item( + Value::Row(result.into()), + span + )] + .from_input_stream()); } - if let Tagged { item: true, tag } = path { + if let Tagged { + item: true, + tag: Tag { span, .. }, + } = path + { let path = config::default_path_for(&configuration)?; - return Ok(stream![Value::Primitive(Primitive::Path(path)).tagged(tag)].from_input_stream()); + return Ok(stream![Tagged::from_simple_spanned_item( + Value::Primitive(Primitive::Path(path)), + span + )] + .from_input_stream()); } if let Some(v) = remove { @@ -126,9 +146,9 @@ pub fn config( ))); } - let obj = VecDeque::from_iter(vec![Value::Row(result.into()).tagged(v.tag())]); + let obj = VecDeque::from_iter(vec![Value::Row(result.into()).simple_spanned(v.span())]); return Ok(obj.from_input_stream()); } - return Ok(vec![Value::Row(result.into()).tagged(name)].into()); + return Ok(vec![Value::Row(result.into()).simple_spanned(name)].into()); } diff --git a/src/commands/cp.rs b/src/commands/cp.rs index bf20c74ce..491e18b1a 100644 --- a/src/commands/cp.rs +++ b/src/commands/cp.rs @@ -1,6 +1,6 @@ use crate::commands::command::RunnablePerItemContext; use crate::errors::ShellError; -use crate::parser::hir::SyntaxShape; +use crate::parser::hir::SyntaxType; use crate::parser::registry::{CommandRegistry, Signature}; use crate::prelude::*; use std::path::PathBuf; @@ -21,9 +21,9 @@ impl PerItemCommand for Cpy { fn signature(&self) -> Signature { Signature::build("cp") - .required("src", SyntaxShape::Pattern) - .required("dst", SyntaxShape::Path) - .named("file", SyntaxShape::Any) + .required("src", SyntaxType::Pattern) + .required("dst", SyntaxType::Path) + .named("file", SyntaxType::Any) .switch("recursive") } diff --git a/src/commands/date.rs b/src/commands/date.rs index 6df9e2720..7d3307fe5 100644 --- a/src/commands/date.rs +++ b/src/commands/date.rs @@ -1,5 +1,5 @@ -use crate::data::{Dictionary, Value}; use crate::errors::ShellError; +use crate::data::{Dictionary, Value}; use crate::prelude::*; use chrono::{DateTime, Local, Utc}; @@ -33,40 +33,58 @@ impl WholeStreamCommand for Date { } } -pub fn date_to_value(dt: DateTime, tag: Tag) -> Tagged +pub fn date_to_value(dt: DateTime, span: Span) -> Tagged where T::Offset: Display, { let mut indexmap = IndexMap::new(); - indexmap.insert("year".to_string(), Value::int(dt.year()).tagged(tag)); - indexmap.insert("month".to_string(), Value::int(dt.month()).tagged(tag)); - indexmap.insert("day".to_string(), Value::int(dt.day()).tagged(tag)); - indexmap.insert("hour".to_string(), Value::int(dt.hour()).tagged(tag)); - indexmap.insert("minute".to_string(), Value::int(dt.minute()).tagged(tag)); - indexmap.insert("second".to_string(), Value::int(dt.second()).tagged(tag)); + indexmap.insert( + "year".to_string(), + Tagged::from_simple_spanned_item(Value::int(dt.year()), span), + ); + indexmap.insert( + "month".to_string(), + Tagged::from_simple_spanned_item(Value::int(dt.month()), span), + ); + indexmap.insert( + "day".to_string(), + Tagged::from_simple_spanned_item(Value::int(dt.day()), span), + ); + indexmap.insert( + "hour".to_string(), + Tagged::from_simple_spanned_item(Value::int(dt.hour()), span), + ); + indexmap.insert( + "minute".to_string(), + Tagged::from_simple_spanned_item(Value::int(dt.minute()), span), + ); + indexmap.insert( + "second".to_string(), + Tagged::from_simple_spanned_item(Value::int(dt.second()), span), + ); let tz = dt.offset(); indexmap.insert( "timezone".to_string(), - Value::string(format!("{}", tz)).tagged(tag), + Tagged::from_simple_spanned_item(Value::string(format!("{}", tz)), span), ); - Value::Row(Dictionary::from(indexmap)).tagged(tag) + Tagged::from_simple_spanned_item(Value::Row(Dictionary::from(indexmap)), span) } pub fn date(args: CommandArgs, registry: &CommandRegistry) -> Result { let args = args.evaluate_once(registry)?; let mut date_out = VecDeque::new(); - let tag = args.call_info.name_tag; + let span = args.call_info.name_span; let value = if args.has("utc") { let utc: DateTime = Utc::now(); - date_to_value(utc, tag) + date_to_value(utc, span) } else { let local: DateTime = Local::now(); - date_to_value(local, tag) + date_to_value(local, span) }; date_out.push_back(value); diff --git a/src/commands/echo.rs b/src/commands/echo.rs index 453041bbc..f464630de 100644 --- a/src/commands/echo.rs +++ b/src/commands/echo.rs @@ -12,7 +12,7 @@ impl PerItemCommand for Echo { } fn signature(&self) -> Signature { - Signature::build("echo").rest(SyntaxShape::Any) + Signature::build("echo").rest(SyntaxType::Any) } fn usage(&self) -> &str { @@ -35,7 +35,7 @@ fn run( _registry: &CommandRegistry, _raw_args: &RawCommandArgs, ) -> Result { - let name = call_info.name_tag; + let name = call_info.name_span; let mut output = String::new(); @@ -57,7 +57,7 @@ fn run( return Err(ShellError::labeled_error( "Expect a string from pipeline", "not a string-compatible value", - i.tag(), + i.span(), )); } } @@ -65,7 +65,7 @@ fn run( } let stream = VecDeque::from(vec![Ok(ReturnSuccess::Value( - Value::string(output).tagged(name), + Value::string(output).simple_spanned(name), ))]); Ok(stream.to_output_stream()) diff --git a/src/commands/enter.rs b/src/commands/enter.rs index 4148d03c5..7b42793e1 100644 --- a/src/commands/enter.rs +++ b/src/commands/enter.rs @@ -14,7 +14,7 @@ impl PerItemCommand for Enter { } fn signature(&self) -> registry::Signature { - Signature::build("enter").required("location", SyntaxShape::Block) + Signature::build("enter").required("location", SyntaxType::Block) } fn usage(&self) -> &str { @@ -70,7 +70,7 @@ impl PerItemCommand for Enter { crate::commands::open::fetch( &full_path, &location_clone, - Tag::unknown(), + Span::unknown(), ) .await.unwrap(); @@ -103,7 +103,7 @@ impl PerItemCommand for Enter { }, source: raw_args.call_info.source, source_map: raw_args.call_info.source_map, - name_tag: raw_args.call_info.name_tag, + name_span: raw_args.call_info.name_span, }, }; let mut result = converter.run( diff --git a/src/commands/fetch.rs b/src/commands/fetch.rs index 07ef0c3e0..e87ddf834 100644 --- a/src/commands/fetch.rs +++ b/src/commands/fetch.rs @@ -2,13 +2,14 @@ use crate::commands::UnevaluatedCallInfo; use crate::context::SpanSource; use crate::data::Value; use crate::errors::ShellError; -use crate::parser::hir::SyntaxShape; +use crate::parser::hir::SyntaxType; use crate::parser::registry::Signature; use crate::prelude::*; use mime::Mime; use std::path::PathBuf; use std::str::FromStr; use surf::mime; +use uuid::Uuid; pub struct Fetch; impl PerItemCommand for Fetch { @@ -18,7 +19,7 @@ impl PerItemCommand for Fetch { fn signature(&self) -> Signature { Signature::build(self.name()) - .required("path", SyntaxShape::Path) + .required("path", SyntaxType::Path) .switch("raw") } @@ -51,14 +52,14 @@ fn run( }; let path_buf = path.as_path()?; let path_str = path_buf.display().to_string(); - let path_tag = path.tag(); + let path_span = path.span(); let has_raw = call_info.args.has("raw"); let registry = registry.clone(); let raw_args = raw_args.clone(); let stream = async_stream_block! { - let result = fetch(&path_str, path_tag).await; + let result = fetch(&path_str, path_span).await; if let Err(e) = result { yield Err(e); @@ -98,7 +99,7 @@ fn run( }, source: raw_args.call_info.source, source_map: raw_args.call_info.source_map, - name_tag: raw_args.call_info.name_tag, + name_span: raw_args.call_info.name_span, } }; let mut result = converter.run(new_args.with_input(vec![tagged_contents]), ®istry); @@ -129,13 +130,13 @@ fn run( pub async fn fetch( location: &str, - tag: Tag, + span: Span, ) -> Result<(Option, Value, Tag, SpanSource), ShellError> { if let Err(_) = url::Url::parse(location) { return Err(ShellError::labeled_error( "Incomplete or incorrect url", "expected a full url", - tag, + span, )); } @@ -151,10 +152,13 @@ pub async fn fetch( ShellError::labeled_error( "Could not load text from remote url", "could not load", - tag, + span, ) })?), - tag, + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::Url(location.to_string()), )), (mime::APPLICATION, mime::JSON) => Ok(( @@ -163,10 +167,13 @@ pub async fn fetch( ShellError::labeled_error( "Could not load text from remote url", "could not load", - tag, + span, ) })?), - tag, + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::Url(location.to_string()), )), (mime::APPLICATION, mime::OCTET_STREAM) => { @@ -174,13 +181,16 @@ pub async fn fetch( ShellError::labeled_error( "Could not load binary file", "could not load", - tag, + span, ) })?; Ok(( None, Value::Binary(buf), - tag, + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::Url(location.to_string()), )) } @@ -190,10 +200,13 @@ pub async fn fetch( ShellError::labeled_error( "Could not load svg from remote url", "could not load", - tag, + span, ) })?), - tag, + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::Url(location.to_string()), )), (mime::IMAGE, image_ty) => { @@ -201,13 +214,16 @@ pub async fn fetch( ShellError::labeled_error( "Could not load image file", "could not load", - tag, + span, ) })?; Ok(( Some(image_ty.to_string()), Value::Binary(buf), - tag, + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::Url(location.to_string()), )) } @@ -217,10 +233,13 @@ pub async fn fetch( ShellError::labeled_error( "Could not load text from remote url", "could not load", - tag, + span, ) })?), - tag, + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::Url(location.to_string()), )), (mime::TEXT, mime::PLAIN) => { @@ -241,17 +260,23 @@ pub async fn fetch( ShellError::labeled_error( "Could not load text from remote url", "could not load", - tag, + span, ) })?), - tag, + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::Url(location.to_string()), )) } (ty, sub_ty) => Ok(( None, Value::string(format!("Not yet supported MIME type: {} {}", ty, sub_ty)), - tag, + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::Url(location.to_string()), )), } @@ -259,7 +284,10 @@ pub async fn fetch( None => Ok(( None, Value::string(format!("No content type found")), - tag, + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::Url(location.to_string()), )), }, @@ -267,7 +295,7 @@ pub async fn fetch( return Err(ShellError::labeled_error( "URL could not be opened", "url not found", - tag, + span, )); } } diff --git a/src/commands/first.rs b/src/commands/first.rs index 77c9a4f69..6381d5def 100644 --- a/src/commands/first.rs +++ b/src/commands/first.rs @@ -17,7 +17,7 @@ impl WholeStreamCommand for First { fn signature(&self) -> Signature { Signature::build("first") - .required("amount", SyntaxShape::Literal) + .required("amount", SyntaxType::Literal) } fn usage(&self) -> &str { diff --git a/src/commands/from_bson.rs b/src/commands/from_bson.rs index b39754a19..e2f5421bd 100644 --- a/src/commands/from_bson.rs +++ b/src/commands/from_bson.rs @@ -1,6 +1,6 @@ use crate::commands::WholeStreamCommand; -use crate::data::{Primitive, TaggedDictBuilder, Value}; use crate::errors::ExpectedRange; +use crate::data::{Primitive, TaggedDictBuilder, Value}; use crate::prelude::*; use bson::{decode_document, spec::BinarySubtype, Bson}; use std::str::FromStr; @@ -198,7 +198,7 @@ pub fn from_bson_bytes_to_value( fn from_bson(args: CommandArgs, registry: &CommandRegistry) -> Result { let args = args.evaluate_once(registry)?; - let tag = args.name_tag(); + let span = args.name_span(); let input = args.input; let stream = async_stream_block! { @@ -208,24 +208,24 @@ fn from_bson(args: CommandArgs, registry: &CommandRegistry) -> Result - match from_bson_bytes_to_value(vb, tag) { + match from_bson_bytes_to_value(vb, span) { Ok(x) => yield ReturnSuccess::value(x), Err(_) => { yield Err(ShellError::labeled_error_with_secondary( "Could not parse as BSON", "input cannot be parsed as BSON", - tag, + span, "value originates from here", - value_tag, + value_tag.span, )) } } _ => yield Err(ShellError::labeled_error_with_secondary( "Expected a string from pipeline", "requires string input", - tag, + span, "value originates from here", - value_tag, + value_tag.span, )), } diff --git a/src/commands/from_csv.rs b/src/commands/from_csv.rs index 68296eb11..c872e7736 100644 --- a/src/commands/from_csv.rs +++ b/src/commands/from_csv.rs @@ -86,7 +86,7 @@ fn from_csv( }: FromCSVArgs, RunnableContext { input, name, .. }: RunnableContext, ) -> Result { - let name_tag = name; + let name_span = name; let stream = async_stream_block! { let values: Vec> = input.values.collect().await; @@ -105,15 +105,15 @@ fn from_csv( _ => yield Err(ShellError::labeled_error_with_secondary( "Expected a string from pipeline", "requires string input", - name_tag, + name_span, "value originates from here", - value_tag, + value_tag.span, )), } } - match from_csv_string_to_value(concat_string, skip_headers, name_tag) { + match from_csv_string_to_value(concat_string, skip_headers, name_span) { Ok(x) => match x { Tagged { item: Value::Table(list), .. } => { for l in list { @@ -126,9 +126,9 @@ fn from_csv( yield Err(ShellError::labeled_error_with_secondary( "Could not parse as CSV", "input cannot be parsed as CSV", - name_tag, + name_span, "value originates from here", - last_tag, + last_tag.span, )) } , } diff --git a/src/commands/from_ini.rs b/src/commands/from_ini.rs index 8409cf848..0e128a22c 100644 --- a/src/commands/from_ini.rs +++ b/src/commands/from_ini.rs @@ -64,7 +64,7 @@ pub fn from_ini_string_to_value( fn from_ini(args: CommandArgs, registry: &CommandRegistry) -> Result { let args = args.evaluate_once(registry)?; - let tag = args.name_tag(); + let span = args.name_span(); let input = args.input; let stream = async_stream_block! { @@ -84,15 +84,15 @@ fn from_ini(args: CommandArgs, registry: &CommandRegistry) -> Result yield Err(ShellError::labeled_error_with_secondary( "Expected a string from pipeline", "requires string input", - tag, + span, "value originates from here", - value_tag, + value_tag.span, )), } } - match from_ini_string_to_value(concat_string, tag) { + match from_ini_string_to_value(concat_string, span) { Ok(x) => match x { Tagged { item: Value::Table(list), .. } => { for l in list { @@ -105,9 +105,9 @@ fn from_ini(args: CommandArgs, registry: &CommandRegistry) -> Result Result { - let name_tag = name; + let name_span = name; let stream = async_stream_block! { let values: Vec> = input.values.collect().await; @@ -91,9 +91,9 @@ fn from_json( _ => yield Err(ShellError::labeled_error_with_secondary( "Expected a string from pipeline", "requires string input", - name_tag, + name_span, "value originates from here", - value_tag, + value_tag.span, )), } @@ -106,7 +106,7 @@ fn from_json( continue; } - match from_json_string_to_value(json_str.to_string(), name_tag) { + match from_json_string_to_value(json_str.to_string(), name_span) { Ok(x) => yield ReturnSuccess::value(x), Err(_) => { @@ -114,15 +114,15 @@ fn from_json( yield Err(ShellError::labeled_error_with_secondary( "Could nnot parse as JSON", "input cannot be parsed as JSON", - name_tag, + name_span, "value originates from here", - last_tag)) + last_tag.span)) } } } } } else { - match from_json_string_to_value(concat_string, name_tag) { + match from_json_string_to_value(concat_string, name_span) { Ok(x) => match x { Tagged { item: Value::Table(list), .. } => { @@ -137,9 +137,9 @@ fn from_json( yield Err(ShellError::labeled_error_with_secondary( "Could not parse as JSON", "input cannot be parsed as JSON", - name_tag, + name_span, "value originates from here", - last_tag)) + last_tag.span)) } } } diff --git a/src/commands/from_sqlite.rs b/src/commands/from_sqlite.rs index 1b04a59fd..c19c4fef1 100644 --- a/src/commands/from_sqlite.rs +++ b/src/commands/from_sqlite.rs @@ -128,7 +128,7 @@ pub fn from_sqlite_bytes_to_value( fn from_sqlite(args: CommandArgs, registry: &CommandRegistry) -> Result { let args = args.evaluate_once(registry)?; - let tag = args.name_tag(); + let span = args.name_span(); let input = args.input; let stream = async_stream_block! { @@ -138,7 +138,7 @@ fn from_sqlite(args: CommandArgs, registry: &CommandRegistry) -> Result - match from_sqlite_bytes_to_value(vb, tag) { + match from_sqlite_bytes_to_value(vb, span) { Ok(x) => match x { Tagged { item: Value::Table(list), .. } => { for l in list { @@ -151,18 +151,18 @@ fn from_sqlite(args: CommandArgs, registry: &CommandRegistry) -> Result yield Err(ShellError::labeled_error_with_secondary( "Expected a string from pipeline", "requires string input", - tag, + span, "value originates from here", - value_tag, + value_tag.span, )), } diff --git a/src/commands/from_toml.rs b/src/commands/from_toml.rs index 29db38a77..c1338cb01 100644 --- a/src/commands/from_toml.rs +++ b/src/commands/from_toml.rs @@ -68,7 +68,7 @@ pub fn from_toml( registry: &CommandRegistry, ) -> Result { let args = args.evaluate_once(registry)?; - let tag = args.name_tag(); + let span = args.name_span(); let input = args.input; let stream = async_stream_block! { @@ -88,15 +88,15 @@ pub fn from_toml( _ => yield Err(ShellError::labeled_error_with_secondary( "Expected a string from pipeline", "requires string input", - tag, + span, "value originates from here", - value_tag, + value_tag.span, )), } } - match from_toml_string_to_value(concat_string, tag) { + match from_toml_string_to_value(concat_string, span) { Ok(x) => match x { Tagged { item: Value::Table(list), .. } => { for l in list { @@ -109,9 +109,9 @@ pub fn from_toml( yield Err(ShellError::labeled_error_with_secondary( "Could not parse as TOML", "input cannot be parsed as TOML", - tag, + span, "value originates from here", - last_tag, + last_tag.span, )) } , } diff --git a/src/commands/from_tsv.rs b/src/commands/from_tsv.rs index 66f070a5d..92696c1aa 100644 --- a/src/commands/from_tsv.rs +++ b/src/commands/from_tsv.rs @@ -87,7 +87,7 @@ fn from_tsv( }: FromTSVArgs, RunnableContext { input, name, .. }: RunnableContext, ) -> Result { - let name_tag = name; + let name_span = name; let stream = async_stream_block! { let values: Vec> = input.values.collect().await; @@ -106,15 +106,15 @@ fn from_tsv( _ => yield Err(ShellError::labeled_error_with_secondary( "Expected a string from pipeline", "requires string input", - name_tag, + name_span, "value originates from here", - value_tag, + value_tag.span, )), } } - match from_tsv_string_to_value(concat_string, skip_headers, name_tag) { + match from_tsv_string_to_value(concat_string, skip_headers, name_span) { Ok(x) => match x { Tagged { item: Value::Table(list), .. } => { for l in list { @@ -127,9 +127,9 @@ fn from_tsv( yield Err(ShellError::labeled_error_with_secondary( "Could not parse as TSV", "input cannot be parsed as TSV", - name_tag, + name_span, "value originates from here", - last_tag, + last_tag.span, )) } , } diff --git a/src/commands/from_xml.rs b/src/commands/from_xml.rs index f80d428f4..2c3f94cdd 100644 --- a/src/commands/from_xml.rs +++ b/src/commands/from_xml.rs @@ -83,7 +83,7 @@ pub fn from_xml_string_to_value( fn from_xml(args: CommandArgs, registry: &CommandRegistry) -> Result { let args = args.evaluate_once(registry)?; - let tag = args.name_tag(); + let span = args.name_span(); let input = args.input; let stream = async_stream_block! { @@ -103,15 +103,15 @@ fn from_xml(args: CommandArgs, registry: &CommandRegistry) -> Result yield Err(ShellError::labeled_error_with_secondary( "Expected a string from pipeline", "requires string input", - tag, + span, "value originates from here", - value_tag, + value_tag.span, )), } } - match from_xml_string_to_value(concat_string, tag) { + match from_xml_string_to_value(concat_string, span) { Ok(x) => match x { Tagged { item: Value::Table(list), .. } => { for l in list { @@ -124,9 +124,9 @@ fn from_xml(args: CommandArgs, registry: &CommandRegistry) -> Result Result { let args = args.evaluate_once(registry)?; - let tag = args.name_tag(); + let span = args.name_span(); let input = args.input; let stream = async_stream_block! { @@ -117,15 +117,15 @@ fn from_yaml(args: CommandArgs, registry: &CommandRegistry) -> Result yield Err(ShellError::labeled_error_with_secondary( "Expected a string from pipeline", "requires string input", - tag, + span, "value originates from here", - value_tag, + value_tag.span, )), } } - match from_yaml_string_to_value(concat_string, tag) { + match from_yaml_string_to_value(concat_string, span) { Ok(x) => match x { Tagged { item: Value::Table(list), .. } => { for l in list { @@ -138,9 +138,9 @@ fn from_yaml(args: CommandArgs, registry: &CommandRegistry) -> Result Signature { - Signature::build("get").rest(SyntaxShape::Member) + Signature::build("get").rest(SyntaxType::Member) } fn usage(&self) -> &str { @@ -47,7 +47,7 @@ fn get_member(path: &Tagged, obj: &Tagged) -> Result registry::Signature { - Signature::build("help").rest(SyntaxShape::Any) + Signature::build("help").rest(SyntaxType::Any) } fn usage(&self) -> &str { @@ -27,11 +27,11 @@ impl PerItemCommand for Help { _raw_args: &RawCommandArgs, _input: Tagged, ) -> Result { - let tag = call_info.name_tag; + let span = call_info.name_span; if call_info.args.len() == 0 { return Ok(vec![Ok(ReturnSuccess::Action(CommandAction::EnterHelpShell( - Value::nothing().tagged(tag), + Tagged::from_simple_spanned_item(Value::nothing(), span), )))] .into()); } diff --git a/src/commands/last.rs b/src/commands/last.rs index fd7a3ecea..1f9cc62a7 100644 --- a/src/commands/last.rs +++ b/src/commands/last.rs @@ -16,7 +16,7 @@ impl WholeStreamCommand for Last { } fn signature(&self) -> Signature { - Signature::build("last").required("amount", SyntaxShape::Number) + Signature::build("last").required("amount", SyntaxType::Number) } fn usage(&self) -> &str { diff --git a/src/commands/lines.rs b/src/commands/lines.rs index d2a9cdffd..15a467224 100644 --- a/src/commands/lines.rs +++ b/src/commands/lines.rs @@ -1,6 +1,6 @@ use crate::commands::WholeStreamCommand; -use crate::data::{Primitive, Value}; use crate::errors::ShellError; +use crate::data::{Primitive, Value}; use crate::prelude::*; use log::trace; @@ -32,7 +32,7 @@ impl WholeStreamCommand for Lines { fn lines(args: CommandArgs, registry: &CommandRegistry) -> Result { let args = args.evaluate_once(registry)?; - let tag = args.name_tag(); + let span = args.name_span(); let input = args.input; let input: InputStream = trace_stream!(target: "nu::trace_stream::lines", "input" = input); @@ -58,9 +58,9 @@ fn lines(args: CommandArgs, registry: &CommandRegistry) -> Result>, -} - impl WholeStreamCommand for LS { fn name(&self) -> &str { "ls" } fn signature(&self) -> Signature { - Signature::build("ls").optional("path", SyntaxShape::Pattern) + Signature::build("ls").optional("path", SyntaxType::Pattern) } fn usage(&self) -> &str { @@ -28,11 +22,12 @@ impl WholeStreamCommand for LS { args: CommandArgs, registry: &CommandRegistry, ) -> Result { - args.process(registry, ls)?.run() - // ls(args, registry) + ls(args, registry) } } -fn ls(LsArgs { path }: LsArgs, context: RunnableContext) -> Result { - context.shell_manager.ls(path, context.name) +fn ls(args: CommandArgs, registry: &CommandRegistry) -> Result { + let shell_manager = args.shell_manager.clone(); + let args = args.evaluate_once(registry)?; + shell_manager.ls(args) } diff --git a/src/commands/mkdir.rs b/src/commands/mkdir.rs index 8bf8a97d4..9dec9a314 100644 --- a/src/commands/mkdir.rs +++ b/src/commands/mkdir.rs @@ -17,7 +17,7 @@ impl PerItemCommand for Mkdir { } fn signature(&self) -> Signature { - Signature::build("mkdir").rest(SyntaxShape::Path) + Signature::build("mkdir").rest(SyntaxType::Path) } fn usage(&self) -> &str { diff --git a/src/commands/mv.rs b/src/commands/mv.rs index 2ace1fa05..130e5996e 100644 --- a/src/commands/mv.rs +++ b/src/commands/mv.rs @@ -1,6 +1,6 @@ use crate::commands::command::RunnablePerItemContext; use crate::errors::ShellError; -use crate::parser::hir::SyntaxShape; +use crate::parser::hir::SyntaxType; use crate::parser::registry::{CommandRegistry, Signature}; use crate::prelude::*; use std::path::PathBuf; @@ -20,9 +20,9 @@ impl PerItemCommand for Move { fn signature(&self) -> Signature { Signature::build("mv") - .required("source", SyntaxShape::Pattern) - .required("destination", SyntaxShape::Path) - .named("file", SyntaxShape::Any) + .required("source", SyntaxType::Path) + .required("destination", SyntaxType::Path) + .named("file", SyntaxType::Any) } fn usage(&self) -> &str { diff --git a/src/commands/nth.rs b/src/commands/nth.rs index bf397e1bc..98ab6a10a 100644 --- a/src/commands/nth.rs +++ b/src/commands/nth.rs @@ -16,7 +16,7 @@ impl WholeStreamCommand for Nth { } fn signature(&self) -> Signature { - Signature::build("nth").required("amount", SyntaxShape::Any) + Signature::build("nth").required("amount", SyntaxType::Any) } fn usage(&self) -> &str { diff --git a/src/commands/open.rs b/src/commands/open.rs index 57f035ac6..32a99c6f1 100644 --- a/src/commands/open.rs +++ b/src/commands/open.rs @@ -2,10 +2,11 @@ use crate::commands::UnevaluatedCallInfo; use crate::context::SpanSource; use crate::data::Value; use crate::errors::ShellError; -use crate::parser::hir::SyntaxShape; +use crate::parser::hir::SyntaxType; use crate::parser::registry::Signature; use crate::prelude::*; use std::path::{Path, PathBuf}; +use uuid::Uuid; pub struct Open; impl PerItemCommand for Open { @@ -15,7 +16,7 @@ impl PerItemCommand for Open { fn signature(&self) -> Signature { Signature::build(self.name()) - .required("path", SyntaxShape::Path) + .required("path", SyntaxType::Path) .switch("raw") } @@ -52,7 +53,7 @@ fn run( }; let path_buf = path.as_path()?; let path_str = path_buf.display().to_string(); - let path_span = path.tag(); + let path_span = path.span(); let has_raw = call_info.args.has("raw"); let registry = registry.clone(); let raw_args = raw_args.clone(); @@ -99,7 +100,7 @@ fn run( }, source: raw_args.call_info.source, source_map: raw_args.call_info.source_map, - name_tag: raw_args.call_info.name_tag, + name_span: raw_args.call_info.name_span, } }; let mut result = converter.run(new_args.with_input(vec![tagged_contents]), ®istry); @@ -131,7 +132,7 @@ fn run( pub async fn fetch( cwd: &PathBuf, location: &str, - tag: Tag, + span: Span, ) -> Result<(Option, Value, Tag, SpanSource), ShellError> { let mut cwd = cwd.clone(); @@ -143,7 +144,10 @@ pub async fn fetch( cwd.extension() .map(|name| name.to_string_lossy().to_string()), Value::string(s), - tag, + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::File(cwd.to_string_lossy().to_string()), )), Err(_) => { @@ -159,13 +163,19 @@ pub async fn fetch( cwd.extension() .map(|name| name.to_string_lossy().to_string()), Value::string(s), - tag, + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::File(cwd.to_string_lossy().to_string()), )), Err(_) => Ok(( None, Value::Binary(bytes), - tag, + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::File(cwd.to_string_lossy().to_string()), )), } @@ -173,7 +183,10 @@ pub async fn fetch( Ok(( None, Value::Binary(bytes), - tag, + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::File(cwd.to_string_lossy().to_string()), )) } @@ -188,13 +201,19 @@ pub async fn fetch( cwd.extension() .map(|name| name.to_string_lossy().to_string()), Value::string(s), - tag, + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::File(cwd.to_string_lossy().to_string()), )), Err(_) => Ok(( None, Value::Binary(bytes), - tag, + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::File(cwd.to_string_lossy().to_string()), )), } @@ -202,7 +221,10 @@ pub async fn fetch( Ok(( None, Value::Binary(bytes), - tag, + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::File(cwd.to_string_lossy().to_string()), )) } @@ -210,7 +232,10 @@ pub async fn fetch( _ => Ok(( None, Value::Binary(bytes), - tag, + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::File(cwd.to_string_lossy().to_string()), )), } @@ -220,7 +245,7 @@ pub async fn fetch( return Err(ShellError::labeled_error( "File could not be opened", "file not found", - tag, + span, )); } } @@ -228,7 +253,7 @@ pub async fn fetch( return Err(ShellError::labeled_error( "File could not be opened", "file not found", - tag, + span, )); } } diff --git a/src/commands/pick.rs b/src/commands/pick.rs index 2fe21dbb4..bc5f8df40 100644 --- a/src/commands/pick.rs +++ b/src/commands/pick.rs @@ -17,7 +17,7 @@ impl WholeStreamCommand for Pick { } fn signature(&self) -> Signature { - Signature::build("pick").rest(SyntaxShape::Any) + Signature::build("pick").rest(SyntaxType::Any) } fn usage(&self) -> &str { diff --git a/src/commands/post.rs b/src/commands/post.rs index 88717a466..8790c929a 100644 --- a/src/commands/post.rs +++ b/src/commands/post.rs @@ -1,8 +1,8 @@ use crate::commands::UnevaluatedCallInfo; use crate::context::SpanSource; -use crate::data::Value; use crate::errors::ShellError; -use crate::parser::hir::SyntaxShape; +use crate::data::Value; +use crate::parser::hir::SyntaxType; use crate::parser::registry::Signature; use crate::prelude::*; use base64::encode; @@ -10,7 +10,7 @@ use mime::Mime; use std::path::PathBuf; use std::str::FromStr; use surf::mime; - +use uuid::Uuid; pub struct Post; impl PerItemCommand for Post { @@ -20,10 +20,10 @@ impl PerItemCommand for Post { fn signature(&self) -> Signature { Signature::build(self.name()) - .required("path", SyntaxShape::Any) - .required("body", SyntaxShape::Any) - .named("user", SyntaxShape::Any) - .named("password", SyntaxShape::Any) + .required("path", SyntaxType::Any) + .required("body", SyntaxType::Any) + .named("user", SyntaxType::Any) + .named("password", SyntaxType::Any) .switch("raw") } @@ -63,7 +63,7 @@ fn run( file => file.clone(), }; let path_str = path.as_string()?; - let path_span = path.tag(); + let path_span = path.span(); let has_raw = call_info.args.has("raw"); let user = call_info.args.get("user").map(|x| x.as_string().unwrap()); let password = call_info @@ -109,7 +109,7 @@ fn run( }, source: raw_args.call_info.source, source_map: raw_args.call_info.source_map, - name_tag: raw_args.call_info.name_tag, + name_span: raw_args.call_info.name_span, } }; let mut result = converter.run(new_args.with_input(vec![tagged_contents]), ®istry); @@ -143,7 +143,7 @@ pub async fn post( body: &Tagged, user: Option, password: Option, - tag: Tag, + span: Span, registry: &CommandRegistry, raw_args: &RawCommandArgs, ) -> Result<(Option, Value, Tag, SpanSource), ShellError> { @@ -189,7 +189,7 @@ pub async fn post( }, source: raw_args.call_info.source, source_map: raw_args.call_info.source_map, - name_tag: raw_args.call_info.name_tag, + name_span: raw_args.call_info.name_span, }, }; let mut result = converter.run( @@ -211,7 +211,7 @@ pub async fn post( return Err(ShellError::labeled_error( "Save could not successfully save", "unexpected data during save", - *tag, + span, )); } } @@ -227,7 +227,7 @@ pub async fn post( return Err(ShellError::labeled_error( "Could not automatically convert table", "needs manual conversion", - *tag, + tag.span, )); } } @@ -243,10 +243,13 @@ pub async fn post( ShellError::labeled_error( "Could not load text from remote url", "could not load", - tag, + span, ) })?), - tag, + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::Url(location.to_string()), )), (mime::APPLICATION, mime::JSON) => Ok(( @@ -255,10 +258,13 @@ pub async fn post( ShellError::labeled_error( "Could not load text from remote url", "could not load", - tag, + span, ) })?), - tag, + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::Url(location.to_string()), )), (mime::APPLICATION, mime::OCTET_STREAM) => { @@ -266,13 +272,16 @@ pub async fn post( ShellError::labeled_error( "Could not load binary file", "could not load", - tag, + span, ) })?; Ok(( None, Value::Binary(buf), - tag, + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::Url(location.to_string()), )) } @@ -281,13 +290,16 @@ pub async fn post( ShellError::labeled_error( "Could not load image file", "could not load", - tag, + span, ) })?; Ok(( Some(image_ty.to_string()), Value::Binary(buf), - tag, + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::Url(location.to_string()), )) } @@ -297,10 +309,13 @@ pub async fn post( ShellError::labeled_error( "Could not load text from remote url", "could not load", - tag, + span, ) })?), - tag, + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::Url(location.to_string()), )), (mime::TEXT, mime::PLAIN) => { @@ -321,10 +336,13 @@ pub async fn post( ShellError::labeled_error( "Could not load text from remote url", "could not load", - tag, + span, ) })?), - tag, + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::Url(location.to_string()), )) } @@ -334,7 +352,10 @@ pub async fn post( "Not yet supported MIME type: {} {}", ty, sub_ty )), - tag, + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::Url(location.to_string()), )), } @@ -342,7 +363,10 @@ pub async fn post( None => Ok(( None, Value::string(format!("No content type found")), - tag, + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::Url(location.to_string()), )), }, @@ -350,7 +374,7 @@ pub async fn post( return Err(ShellError::labeled_error( "URL could not be opened", "url not found", - tag, + span, )); } } @@ -358,7 +382,7 @@ pub async fn post( Err(ShellError::labeled_error( "Expected a url", "needs a url", - tag, + span, )) } } diff --git a/src/commands/reject.rs b/src/commands/reject.rs index ea09bd749..49dbc4dd3 100644 --- a/src/commands/reject.rs +++ b/src/commands/reject.rs @@ -16,7 +16,7 @@ impl WholeStreamCommand for Reject { } fn signature(&self) -> Signature { - Signature::build("reject").rest(SyntaxShape::Member) + Signature::build("reject").rest(SyntaxType::Member) } fn usage(&self) -> &str { diff --git a/src/commands/rm.rs b/src/commands/rm.rs index ac5aeaae7..60bb5c6e4 100644 --- a/src/commands/rm.rs +++ b/src/commands/rm.rs @@ -1,6 +1,6 @@ use crate::commands::command::RunnablePerItemContext; use crate::errors::ShellError; -use crate::parser::hir::SyntaxShape; +use crate::parser::hir::SyntaxType; use crate::parser::registry::{CommandRegistry, Signature}; use crate::prelude::*; use std::path::PathBuf; @@ -20,7 +20,7 @@ impl PerItemCommand for Remove { fn signature(&self) -> Signature { Signature::build("rm") - .required("path", SyntaxShape::Pattern) + .required("path", SyntaxType::Path) .switch("recursive") } diff --git a/src/commands/save.rs b/src/commands/save.rs index 66d9732d6..26bf8cb16 100644 --- a/src/commands/save.rs +++ b/src/commands/save.rs @@ -7,7 +7,7 @@ use std::path::{Path, PathBuf}; pub struct Save; macro_rules! process_string { - ($input:ident, $name_tag:ident) => {{ + ($input:ident, $name_span:ident) => {{ let mut result_string = String::new(); for res in $input { match res { @@ -21,7 +21,7 @@ macro_rules! process_string { yield core::task::Poll::Ready(Err(ShellError::labeled_error( "Save could not successfully save", "unexpected data during save", - $name_tag, + $name_span, ))); } } @@ -31,7 +31,7 @@ macro_rules! process_string { } macro_rules! process_string_return_success { - ($result_vec:ident, $name_tag:ident) => {{ + ($result_vec:ident, $name_span:ident) => {{ let mut result_string = String::new(); for res in $result_vec { match res { @@ -45,7 +45,7 @@ macro_rules! process_string_return_success { yield core::task::Poll::Ready(Err(ShellError::labeled_error( "Save could not successfully save", "unexpected data during text save", - $name_tag, + $name_span, ))); } } @@ -55,7 +55,7 @@ macro_rules! process_string_return_success { } macro_rules! process_binary_return_success { - ($result_vec:ident, $name_tag:ident) => {{ + ($result_vec:ident, $name_span:ident) => {{ let mut result_binary: Vec = Vec::new(); for res in $result_vec { match res { @@ -71,7 +71,7 @@ macro_rules! process_binary_return_success { yield core::task::Poll::Ready(Err(ShellError::labeled_error( "Save could not successfully save", "unexpected data during binary save", - $name_tag, + $name_span, ))); } } @@ -93,7 +93,7 @@ impl WholeStreamCommand for Save { fn signature(&self) -> Signature { Signature::build("save") - .optional("path", SyntaxShape::Path) + .optional("path", SyntaxType::Path) .switch("raw") } @@ -127,7 +127,7 @@ fn save( raw_args: RawCommandArgs, ) -> Result { let mut full_path = PathBuf::from(shell_manager.path()); - let name_tag = name; + let name_span = name; let source_map = source_map.clone(); let stream = async_stream_block! { @@ -145,7 +145,7 @@ fn save( yield Err(ShellError::labeled_error( "Save requires a filepath", "needs path", - name_tag, + name_span, )); } }, @@ -153,7 +153,7 @@ fn save( yield Err(ShellError::labeled_error( "Save requires a filepath", "needs path", - name_tag, + name_span, )); } } @@ -161,7 +161,7 @@ fn save( yield Err(ShellError::labeled_error( "Save requires a filepath", "needs path", - name_tag, + name_span, )); } } else { @@ -185,21 +185,21 @@ fn save( }, source: raw_args.call_info.source, source_map: raw_args.call_info.source_map, - name_tag: raw_args.call_info.name_tag, + name_span: raw_args.call_info.name_span, } }; let mut result = converter.run(new_args.with_input(input), ®istry); let result_vec: Vec> = result.drain_vec().await; if converter.is_binary() { - process_binary_return_success!(result_vec, name_tag) + process_binary_return_success!(result_vec, name_span) } else { - process_string_return_success!(result_vec, name_tag) + process_string_return_success!(result_vec, name_span) } } else { - process_string!(input, name_tag) + process_string!(input, name_span) } } else { - process_string!(input, name_tag) + process_string!(input, name_span) } } else { Ok(string_from(&input).into_bytes()) diff --git a/src/commands/shells.rs b/src/commands/shells.rs index 2aee2c856..856c23e7b 100644 --- a/src/commands/shells.rs +++ b/src/commands/shells.rs @@ -1,6 +1,6 @@ use crate::commands::WholeStreamCommand; -use crate::data::TaggedDictBuilder; use crate::errors::ShellError; +use crate::data::TaggedDictBuilder; use crate::prelude::*; pub struct Shells; @@ -29,10 +29,10 @@ impl WholeStreamCommand for Shells { fn shells(args: CommandArgs, _registry: &CommandRegistry) -> Result { let mut shells_out = VecDeque::new(); - let tag = args.call_info.name_tag; + let span = args.call_info.name_span; for (index, shell) in args.shell_manager.shells.lock().unwrap().iter().enumerate() { - let mut dict = TaggedDictBuilder::new(tag); + let mut dict = TaggedDictBuilder::new(Tag::unknown_origin(span)); if index == args.shell_manager.current_shell { dict.insert(" ", "X".to_string()); diff --git a/src/commands/size.rs b/src/commands/size.rs index 51f8d22c1..d8383efcf 100644 --- a/src/commands/size.rs +++ b/src/commands/size.rs @@ -1,6 +1,6 @@ use crate::commands::WholeStreamCommand; -use crate::data::{TaggedDictBuilder, Value}; use crate::errors::ShellError; +use crate::data::{TaggedDictBuilder, Value}; use crate::prelude::*; pub struct Size; @@ -29,7 +29,7 @@ impl WholeStreamCommand for Size { fn size(args: CommandArgs, _registry: &CommandRegistry) -> Result { let input = args.input; - let tag = args.call_info.name_tag; + let span = args.call_info.name_span; Ok(input .values .map(move |v| match v.item { @@ -37,9 +37,9 @@ fn size(args: CommandArgs, _registry: &CommandRegistry) -> Result Err(ShellError::labeled_error_with_secondary( "Expected a string from pipeline", "requires string input", - tag, + span, "value originates from here", - v.tag(), + v.span(), )), }) .to_output_stream()) @@ -71,7 +71,7 @@ fn count(contents: &str, tag: impl Into) -> Tagged { } let mut dict = TaggedDictBuilder::new(tag); - //TODO: add back in name when we have it in the tag + //TODO: add back in name when we have it in the span //dict.insert("name", Value::string(name)); dict.insert("lines", Value::int(lines)); dict.insert("words", Value::int(words)); diff --git a/src/commands/skip_while.rs b/src/commands/skip_while.rs index 041caf300..90ba24b99 100644 --- a/src/commands/skip_while.rs +++ b/src/commands/skip_while.rs @@ -16,7 +16,7 @@ impl WholeStreamCommand for SkipWhile { fn signature(&self) -> Signature { Signature::build("skip-while") - .required("condition", SyntaxShape::Block) + .required("condition", SyntaxType::Block) .filter() } diff --git a/src/commands/sort_by.rs b/src/commands/sort_by.rs index 8058b7889..edce33b96 100644 --- a/src/commands/sort_by.rs +++ b/src/commands/sort_by.rs @@ -15,7 +15,7 @@ impl WholeStreamCommand for SortBy { } fn signature(&self) -> Signature { - Signature::build("sort-by").rest(SyntaxShape::String) + Signature::build("sort-by").rest(SyntaxType::String) } fn usage(&self) -> &str { diff --git a/src/commands/split_column.rs b/src/commands/split_column.rs index 00e2609f2..2df02cac1 100644 --- a/src/commands/split_column.rs +++ b/src/commands/split_column.rs @@ -1,6 +1,6 @@ use crate::commands::WholeStreamCommand; -use crate::data::{Primitive, TaggedDictBuilder, Value}; use crate::errors::ShellError; +use crate::data::{Primitive, TaggedDictBuilder, Value}; use crate::prelude::*; use log::trace; @@ -21,9 +21,9 @@ impl WholeStreamCommand for SplitColumn { fn signature(&self) -> Signature { Signature::build("split-column") - .required("separator", SyntaxShape::Any) + .required("separator", SyntaxType::Any) .switch("collapse-empty") - .rest(SyntaxShape::Member) + .rest(SyntaxType::Member) } fn usage(&self) -> &str { @@ -40,11 +40,7 @@ impl WholeStreamCommand for SplitColumn { } fn split_column( - SplitColumnArgs { - separator, - rest, - collapse_empty, - }: SplitColumnArgs, + SplitColumnArgs { separator, rest, collapse_empty}: SplitColumnArgs, RunnableContext { input, name, .. }: RunnableContext, ) -> Result { Ok(input @@ -96,7 +92,7 @@ fn split_column( "requires string input", name, "value originates from here", - v.tag(), + v.span(), )), }) .to_output_stream()) diff --git a/src/commands/split_row.rs b/src/commands/split_row.rs index e70e5cfa8..d4f3824a8 100644 --- a/src/commands/split_row.rs +++ b/src/commands/split_row.rs @@ -1,6 +1,6 @@ use crate::commands::WholeStreamCommand; -use crate::data::{Primitive, Value}; use crate::errors::ShellError; +use crate::data::{Primitive, Value}; use crate::prelude::*; use log::trace; @@ -17,7 +17,8 @@ impl WholeStreamCommand for SplitRow { } fn signature(&self) -> Signature { - Signature::build("split-row").required("separator", SyntaxShape::Any) + Signature::build("split-row") + .required("separator", SyntaxType::Any) } fn usage(&self) -> &str { @@ -62,7 +63,7 @@ fn split_row( "requires string input", name, "value originates from here", - v.tag(), + v.span(), ))); result } diff --git a/src/commands/tags.rs b/src/commands/tags.rs index 2b45105c2..3f112482c 100644 --- a/src/commands/tags.rs +++ b/src/commands/tags.rs @@ -1,6 +1,6 @@ use crate::commands::WholeStreamCommand; -use crate::data::{TaggedDictBuilder, Value}; use crate::errors::ShellError; +use crate::data::{TaggedDictBuilder, Value}; use crate::prelude::*; pub struct Tags; @@ -36,7 +36,7 @@ fn tags(args: CommandArgs, _registry: &CommandRegistry) -> Result Result { Ok(Bson::Document(doc)) } -fn shell_encode_document(writer: &mut Vec, doc: Document, tag: Tag) -> Result<(), ShellError> { +fn shell_encode_document( + writer: &mut Vec, + doc: Document, + span: Span, +) -> Result<(), ShellError> { match encode_document(writer, &doc) { Err(e) => Err(ShellError::labeled_error( format!("Failed to encode document due to: {:?}", e), "requires BSON-compatible document", - tag, + span, )), _ => Ok(()), } } -fn bson_value_to_bytes(bson: Bson, tag: Tag) -> Result, ShellError> { +fn bson_value_to_bytes(bson: Bson, span: Span) -> Result, ShellError> { let mut out = Vec::new(); match bson { Bson::Array(a) => { for v in a.into_iter() { match v { - Bson::Document(d) => shell_encode_document(&mut out, d, tag)?, + Bson::Document(d) => shell_encode_document(&mut out, d, span)?, _ => { return Err(ShellError::labeled_error( format!("All top level values must be Documents, got {:?}", v), "requires BSON-compatible document", - tag, + span, )) } } } } - Bson::Document(d) => shell_encode_document(&mut out, d, tag)?, + Bson::Document(d) => shell_encode_document(&mut out, d, span)?, _ => { return Err(ShellError::labeled_error( format!("All top level values must be Documents, got {:?}", bson), "requires BSON-compatible document", - tag, + span, )) } } @@ -232,7 +236,7 @@ fn bson_value_to_bytes(bson: Bson, tag: Tag) -> Result, ShellError> { fn to_bson(args: CommandArgs, registry: &CommandRegistry) -> Result { let args = args.evaluate_once(registry)?; - let name_tag = args.name_tag(); + let name_span = args.name_span(); let stream = async_stream_block! { let input: Vec> = args.input.values.collect().await; @@ -248,23 +252,23 @@ fn to_bson(args: CommandArgs, registry: &CommandRegistry) -> Result { - match bson_value_to_bytes(bson_value, name_tag) { + match bson_value_to_bytes(bson_value, name_span) { Ok(x) => yield ReturnSuccess::value( - Value::Binary(x).tagged(name_tag), + Value::Binary(x).simple_spanned(name_span), ), _ => yield Err(ShellError::labeled_error_with_secondary( - "Expected a table with BSON-compatible structure.tag() from pipeline", + "Expected a table with BSON-compatible structure.span() from pipeline", "requires BSON-compatible input", - name_tag, + name_span, "originates from here".to_string(), - value.tag(), + value.span(), )), } } _ => yield Err(ShellError::labeled_error( "Expected a table with BSON-compatible structure from pipeline", "requires BSON-compatible input", - name_tag)) + name_span)) } } }; diff --git a/src/commands/to_csv.rs b/src/commands/to_csv.rs index fd77fdcb6..615e49cbf 100644 --- a/src/commands/to_csv.rs +++ b/src/commands/to_csv.rs @@ -134,7 +134,7 @@ fn to_csv( ToCSVArgs { headerless }: ToCSVArgs, RunnableContext { input, name, .. }: RunnableContext, ) -> Result { - let name_tag = name; + let name_span = name; let stream = async_stream_block! { let input: Vec> = input.values.collect().await; @@ -155,15 +155,15 @@ fn to_csv( } else { x }; - yield ReturnSuccess::value(Value::Primitive(Primitive::String(converted)).tagged(name_tag)) + yield ReturnSuccess::value(Value::Primitive(Primitive::String(converted)).simple_spanned(name_span)) } _ => { yield Err(ShellError::labeled_error_with_secondary( - "Expected a table with CSV-compatible structure.tag() from pipeline", + "Expected a table with CSV-compatible structure.span() from pipeline", "requires CSV-compatible input", - name_tag, + name_span, "originates from here".to_string(), - value.tag(), + value.span(), )) } } diff --git a/src/commands/to_json.rs b/src/commands/to_json.rs index c6b5d9c01..35c03af32 100644 --- a/src/commands/to_json.rs +++ b/src/commands/to_json.rs @@ -80,7 +80,7 @@ fn json_list(input: &Vec>) -> Result, Shell fn to_json(args: CommandArgs, registry: &CommandRegistry) -> Result { let args = args.evaluate_once(registry)?; - let name_tag = args.name_tag(); + let name_span = args.name_span(); let stream = async_stream_block! { let input: Vec> = args.input.values.collect().await; @@ -98,21 +98,21 @@ fn to_json(args: CommandArgs, registry: &CommandRegistry) -> Result { match serde_json::to_string(&json_value) { Ok(x) => yield ReturnSuccess::value( - Value::Primitive(Primitive::String(x)).tagged(name_tag), + Value::Primitive(Primitive::String(x)).simple_spanned(name_span), ), _ => yield Err(ShellError::labeled_error_with_secondary( - "Expected a table with JSON-compatible structure.tag() from pipeline", + "Expected a table with JSON-compatible structure.span() from pipeline", "requires JSON-compatible input", - name_tag, + name_span, "originates from here".to_string(), - value.tag(), + value.span(), )), } } _ => yield Err(ShellError::labeled_error( "Expected a table with JSON-compatible structure from pipeline", "requires JSON-compatible input", - name_tag)) + name_span)) } } }; diff --git a/src/commands/to_sqlite.rs b/src/commands/to_sqlite.rs index 580dba96b..0fd392f34 100644 --- a/src/commands/to_sqlite.rs +++ b/src/commands/to_sqlite.rs @@ -200,7 +200,7 @@ fn sqlite_input_stream_to_bytes( fn to_sqlite(args: CommandArgs, registry: &CommandRegistry) -> Result { let args = args.evaluate_once(registry)?; - let name_tag = args.name_tag(); + let name_span = args.name_span(); let stream = async_stream_block! { let input: Vec> = args.input.values.collect().await; @@ -208,9 +208,9 @@ fn to_sqlite(args: CommandArgs, registry: &CommandRegistry) -> Result yield ReturnSuccess::value(out), _ => { yield Err(ShellError::labeled_error( - "Expected a table with SQLite-compatible structure.tag() from pipeline", + "Expected a table with SQLite-compatible structure.span() from pipeline", "requires SQLite-compatible input", - name_tag, + name_span, )) }, } diff --git a/src/commands/to_toml.rs b/src/commands/to_toml.rs index cf8f2b11f..e18e15236 100644 --- a/src/commands/to_toml.rs +++ b/src/commands/to_toml.rs @@ -75,7 +75,7 @@ fn collect_values(input: &Vec>) -> Result, ShellE fn to_toml(args: CommandArgs, registry: &CommandRegistry) -> Result { let args = args.evaluate_once(registry)?; - let name_tag = args.name_tag(); + let name_span = args.name_span(); let stream = async_stream_block! { let input: Vec> = args.input.values.collect().await; @@ -93,21 +93,21 @@ fn to_toml(args: CommandArgs, registry: &CommandRegistry) -> Result { match toml::to_string(&toml_value) { Ok(x) => yield ReturnSuccess::value( - Value::Primitive(Primitive::String(x)).tagged(name_tag), + Value::Primitive(Primitive::String(x)).simple_spanned(name_span), ), _ => yield Err(ShellError::labeled_error_with_secondary( - "Expected a table with TOML-compatible structure.tag() from pipeline", + "Expected a table with TOML-compatible structure.span() from pipeline", "requires TOML-compatible input", - name_tag, + name_span, "originates from here".to_string(), - value.tag(), + value.span(), )), } } _ => yield Err(ShellError::labeled_error( "Expected a table with TOML-compatible structure from pipeline", "requires TOML-compatible input", - name_tag)) + name_span)) } } }; diff --git a/src/commands/to_tsv.rs b/src/commands/to_tsv.rs index 7bce174d0..a0cbf1c1b 100644 --- a/src/commands/to_tsv.rs +++ b/src/commands/to_tsv.rs @@ -133,7 +133,7 @@ fn to_tsv( ToTSVArgs { headerless }: ToTSVArgs, RunnableContext { input, name, .. }: RunnableContext, ) -> Result { - let name_tag = name; + let name_span = name; let stream = async_stream_block! { let input: Vec> = input.values.collect().await; @@ -154,15 +154,15 @@ fn to_tsv( } else { x }; - yield ReturnSuccess::value(Value::Primitive(Primitive::String(converted)).tagged(name_tag)) + yield ReturnSuccess::value(Value::Primitive(Primitive::String(converted)).simple_spanned(name_span)) } _ => { yield Err(ShellError::labeled_error_with_secondary( - "Expected a table with TSV-compatible structure.tag() from pipeline", + "Expected a table with TSV-compatible structure.span() from pipeline", "requires TSV-compatible input", - name_tag, + name_span, "originates from here".to_string(), - value.tag(), + value.span(), )) } } diff --git a/src/commands/to_yaml.rs b/src/commands/to_yaml.rs index fc4412da0..915827252 100644 --- a/src/commands/to_yaml.rs +++ b/src/commands/to_yaml.rs @@ -76,7 +76,7 @@ pub fn value_to_yaml_value(v: &Tagged) -> Result Result { let args = args.evaluate_once(registry)?; - let name_tag = args.name_tag(); + let name_span = args.name_span(); let stream = async_stream_block! { let input: Vec> = args.input.values.collect().await; @@ -94,21 +94,21 @@ fn to_yaml(args: CommandArgs, registry: &CommandRegistry) -> Result { match serde_yaml::to_string(&yaml_value) { Ok(x) => yield ReturnSuccess::value( - Value::Primitive(Primitive::String(x)).tagged(name_tag), + Value::Primitive(Primitive::String(x)).simple_spanned(name_span), ), _ => yield Err(ShellError::labeled_error_with_secondary( - "Expected a table with YAML-compatible structure.tag() from pipeline", + "Expected a table with YAML-compatible structure.span() from pipeline", "requires YAML-compatible input", - name_tag, + name_span, "originates from here".to_string(), - value.tag(), + value.span(), )), } } _ => yield Err(ShellError::labeled_error( "Expected a table with YAML-compatible structure from pipeline", "requires YAML-compatible input", - name_tag)) + name_span)) } } }; diff --git a/src/commands/trim.rs b/src/commands/trim.rs index 11ed02539..865f6b50b 100644 --- a/src/commands/trim.rs +++ b/src/commands/trim.rs @@ -1,6 +1,6 @@ use crate::commands::WholeStreamCommand; -use crate::data::Value; use crate::errors::ShellError; +use crate::data::Value; use crate::prelude::*; pub struct Trim; @@ -34,7 +34,7 @@ fn trim(args: CommandArgs, _registry: &CommandRegistry) -> Result Result { let args = args.evaluate_once(registry)?; - let tag = args.call_info.name_tag; + let span = args.call_info.name_span; let mut indexmap = IndexMap::new(); indexmap.insert( "version".to_string(), - Value::string(clap::crate_version!()).tagged(tag), + Tagged::from_simple_spanned_item(Value::string(clap::crate_version!()), span), ); - let value = Value::Row(Dictionary::from(indexmap)).tagged(tag); + let value = Tagged::from_simple_spanned_item(Value::Row(Dictionary::from(indexmap)), span); Ok(OutputStream::one(value)) } diff --git a/src/commands/where_.rs b/src/commands/where_.rs index 673c6dda8..b09c341b4 100644 --- a/src/commands/where_.rs +++ b/src/commands/where_.rs @@ -1,6 +1,6 @@ use crate::commands::PerItemCommand; use crate::errors::ShellError; -use crate::parser::hir::SyntaxShape; +use crate::parser::hir::SyntaxType; use crate::parser::registry; use crate::prelude::*; @@ -12,7 +12,8 @@ impl PerItemCommand for Where { } fn signature(&self) -> registry::Signature { - Signature::build("where").required("condition", SyntaxShape::Block) + Signature::build("where") + .required("condition", SyntaxType::Block) } fn usage(&self) -> &str { @@ -42,14 +43,16 @@ impl PerItemCommand for Where { VecDeque::new() } } - Err(e) => return Err(e), + Err(e) => { + return Err(e) + } } } Tagged { tag, .. } => { return Err(ShellError::labeled_error( "Expected a condition", "where needs a condition", - *tag, + tag.span, )) } }; diff --git a/src/commands/which_.rs b/src/commands/which_.rs index 905515848..06c93f63f 100644 --- a/src/commands/which_.rs +++ b/src/commands/which_.rs @@ -1,5 +1,5 @@ -use crate::data::Value; use crate::errors::ShellError; +use crate::data::Value; use crate::prelude::*; use crate::commands::WholeStreamCommand; @@ -13,7 +13,8 @@ impl WholeStreamCommand for Which { } fn signature(&self) -> Signature { - Signature::build("which").required("name", SyntaxShape::Any) + Signature::build("which") + .required("name", SyntaxType::Any) } fn usage(&self) -> &str { @@ -33,7 +34,7 @@ pub fn which(args: CommandArgs, registry: &CommandRegistry) -> Result 0 { @@ -52,7 +53,7 @@ pub fn which(args: CommandArgs, registry: &CommandRegistry) -> Result Result( &mut self, command: Arc, - name_tag: Tag, + name_span: Span, source_map: SourceMap, args: hir::Call, source: &Text, input: InputStream, ) -> OutputStream { - let command_args = self.command_args(args, input, source, source_map, name_tag); + let command_args = self.command_args(args, input, source, source_map, name_span); command.run(command_args, self.registry()) } @@ -135,13 +135,13 @@ impl Context { args: hir::Call, source: &Text, source_map: SourceMap, - name_tag: Tag, + name_span: Span, ) -> UnevaluatedCallInfo { UnevaluatedCallInfo { args, source: source.clone(), source_map, - name_tag, + name_span, } } @@ -151,12 +151,12 @@ impl Context { input: InputStream, source: &Text, source_map: SourceMap, - name_tag: Tag, + name_span: Span, ) -> CommandArgs { CommandArgs { host: self.host.clone(), shell_manager: self.shell_manager.clone(), - call_info: self.call_info(args, source, source_map, name_tag), + call_info: self.call_info(args, source, source_map, name_span), input, } } diff --git a/src/data/base.rs b/src/data/base.rs index fdd5542dc..aa491ebdc 100644 --- a/src/data/base.rs +++ b/src/data/base.rs @@ -145,7 +145,7 @@ pub struct Operation { pub struct Block { pub(crate) expressions: Vec, pub(crate) source: Text, - pub(crate) tag: Tag, + pub(crate) span: Span, } impl Block { @@ -153,7 +153,7 @@ impl Block { let scope = Scope::new(value.clone()); if self.expressions.len() == 0 { - return Ok(Value::nothing().tagged(self.tag)); + return Ok(Value::nothing().simple_spanned(self.span)); } let mut last = None; @@ -247,7 +247,7 @@ impl std::convert::TryFrom<&Tagged> for Block { Value::Block(block) => Ok(block.clone()), v => Err(ShellError::type_error( "Block", - value.copy_tag(v.type_name()), + value.copy_span(v.type_name()), )), } } @@ -263,7 +263,7 @@ impl std::convert::TryFrom<&Tagged> for i64 { } v => Err(ShellError::type_error( "Integer", - value.copy_tag(v.type_name()), + value.copy_span(v.type_name()), )), } } @@ -277,7 +277,7 @@ impl std::convert::TryFrom<&Tagged> for String { Value::Primitive(Primitive::String(s)) => Ok(s.clone()), v => Err(ShellError::type_error( "String", - value.copy_tag(v.type_name()), + value.copy_span(v.type_name()), )), } } @@ -291,7 +291,7 @@ impl std::convert::TryFrom<&Tagged> for Vec { Value::Binary(b) => Ok(b.clone()), v => Err(ShellError::type_error( "Binary", - value.copy_tag(v.type_name()), + value.copy_span(v.type_name()), )), } } @@ -305,7 +305,7 @@ impl<'a> std::convert::TryFrom<&'a Tagged> for &'a crate::data::Dictionar Value::Row(d) => Ok(d), v => Err(ShellError::type_error( "Dictionary", - value.copy_tag(v.type_name()), + value.copy_span(v.type_name()), )), } } @@ -327,7 +327,7 @@ impl std::convert::TryFrom>> for Switch { Value::Primitive(Primitive::Boolean(true)) => Ok(Switch::Present), v => Err(ShellError::type_error( "Boolean", - value.copy_tag(v.type_name()), + value.copy_span(v.type_name()), )), }, } @@ -639,7 +639,7 @@ impl Tagged { Value::Primitive(Primitive::Path(path)) => Ok(path.clone()), other => Err(ShellError::type_error( "Path", - other.type_name().tagged(self.tag()), + other.type_name().tagged(self.span()), )), } } diff --git a/src/data/config.rs b/src/data/config.rs index 6b4d1383f..08296c09a 100644 --- a/src/data/config.rs +++ b/src/data/config.rs @@ -50,7 +50,7 @@ pub fn default_path_for(file: &Option) -> Result { } pub fn read( - tag: impl Into, + span: impl Into, at: &Option, ) -> Result>, ShellError> { let filename = default_path()?; @@ -64,15 +64,15 @@ pub fn read( trace!("config file = {}", filename.display()); - let tag = tag.into(); + let span = span.into(); let contents = fs::read_to_string(filename) - .map(|v| v.tagged(tag)) + .map(|v| v.simple_spanned(span)) .map_err(|err| ShellError::string(&format!("Couldn't read config file:\n{}", err)))?; let parsed: toml::Value = toml::from_str(&contents) .map_err(|err| ShellError::string(&format!("Couldn't parse config file:\n{}", err)))?; - let value = convert_toml_value_to_nu_value(&parsed, tag); + let value = convert_toml_value_to_nu_value(&parsed, Tag::unknown_origin(span)); let tag = value.tag(); match value.item { Value::Row(Dictionary { entries }) => Ok(entries), @@ -83,8 +83,8 @@ pub fn read( } } -pub(crate) fn config(tag: impl Into) -> Result>, ShellError> { - read(tag, &None) +pub(crate) fn config(span: impl Into) -> Result>, ShellError> { + read(span, &None) } pub fn write( diff --git a/src/data/into.rs b/src/data/into.rs index 3d764fa0c..749ab0601 100644 --- a/src/data/into.rs +++ b/src/data/into.rs @@ -15,8 +15,8 @@ impl From for Value { impl> Tagged { pub fn into_tagged_value(self) -> Tagged { - let value_tag = self.tag(); + let value_span = self.span(); let value = self.item.into(); - value.tagged(value_tag) + value.simple_spanned(value_span) } } diff --git a/src/data/meta.rs b/src/data/meta.rs index d472a8add..f1d2b6713 100644 --- a/src/data/meta.rs +++ b/src/data/meta.rs @@ -5,7 +5,6 @@ use derive_new::new; use getset::Getters; use serde::Deserialize; use serde::Serialize; -use std::path::{Path, PathBuf}; use uuid::Uuid; #[derive(new, Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize, Hash)] @@ -14,15 +13,9 @@ pub struct Tagged { pub item: T, } -impl HasTag for Tagged { - fn tag(&self) -> Tag { - self.tag - } -} - -impl AsRef for Tagged { - fn as_ref(&self) -> &Path { - self.item.as_ref() +impl HasSpan for Tagged { + fn span(&self) -> Span { + self.tag.span } } @@ -31,6 +24,10 @@ pub trait TaggedItem: Sized { Tagged::from_item(self, tag.into()) } + fn simple_spanned(self, span: impl Into) -> Tagged { + Tagged::from_simple_spanned_item(self, span.into()) + } + // For now, this is a temporary facility. In many cases, there are other useful spans that we // could be using, such as the original source spans of JSON or Toml files, but we don't yet // have the infrastructure to make that work. @@ -56,8 +53,14 @@ impl std::ops::Deref for Tagged { } impl Tagged { - pub fn with_tag(self, tag: impl Into) -> Tagged { - Tagged::from_item(self.item, tag) + pub fn spanned(self, span: impl Into) -> Tagged { + Tagged::from_item( + self.item, + Tag { + span: span.into(), + origin: None, + }, + ) } pub fn from_item(item: T, tag: impl Into) -> Tagged { @@ -67,26 +70,41 @@ impl Tagged { } } + pub fn from_simple_spanned_item(item: T, span: impl Into) -> Tagged { + Tagged::from_item( + item, + Tag { + span: span.into(), + origin: None, + }, + ) + } + pub fn map(self, input: impl FnOnce(T) -> U) -> Tagged { let tag = self.tag(); let mapped = input(self.item); - Tagged::from_item(mapped, tag) + Tagged::from_item(mapped, tag.clone()) } - pub(crate) fn copy_tag(&self, output: U) -> Tagged { - Tagged::from_item(output, self.tag()) + pub(crate) fn copy_span(&self, output: U) -> Tagged { + let span = self.span(); + + Tagged::from_simple_spanned_item(output, span) } pub fn source(&self, source: &Text) -> Text { - Text::from(self.tag().slice(source)) + Text::from(self.span().slice(source)) + } + + pub fn span(&self) -> Span { + self.tag.span } pub fn tag(&self) -> Tag { self.tag } - // TODO: This should not be optional pub fn origin(&self) -> Option { self.tag.origin } @@ -108,14 +126,20 @@ impl Tagged { } } -impl From<&Tag> for Tag { - fn from(input: &Tag) -> Tag { +impl From<&Tagged> for Span { + fn from(input: &Tagged) -> Span { + input.span() + } +} + +impl From<&Span> for Span { + fn from(input: &Span) -> Span { *input } } -impl From> for Span { - fn from(input: nom_locate::LocatedSpanEx<&str, Uuid>) -> Span { +impl From> for Span { + fn from(input: nom5_locate::LocatedSpan<&str>) -> Span { Span { start: input.offset, end: input.offset + input.fragment.len(), @@ -123,18 +147,8 @@ impl From> for Span { } } -impl - From<( - nom_locate::LocatedSpanEx, - nom_locate::LocatedSpanEx, - )> for Span -{ - fn from( - input: ( - nom_locate::LocatedSpanEx, - nom_locate::LocatedSpanEx, - ), - ) -> Span { +impl From<(nom5_locate::LocatedSpan, nom5_locate::LocatedSpan)> for Span { + fn from(input: (nom5_locate::LocatedSpan, nom5_locate::LocatedSpan)) -> Span { Span { start: input.0.offset, end: input.1.offset, @@ -183,36 +197,6 @@ impl From<&Span> for Tag { } } -impl From<(usize, usize, Uuid)> for Tag { - fn from((start, end, origin): (usize, usize, Uuid)) -> Self { - Tag { - origin: Some(origin), - span: Span { start, end }, - } - } -} - -impl From<(usize, usize, Option)> for Tag { - fn from((start, end, origin): (usize, usize, Option)) -> Self { - Tag { - origin, - span: Span { start, end }, - } - } -} - -impl From> for Tag { - fn from(input: nom_locate::LocatedSpanEx<&str, Uuid>) -> Tag { - Tag { - origin: Some(input.extra), - span: Span { - start: input.offset, - end: input.offset + input.fragment.len(), - }, - } - } -} - impl From for Span { fn from(tag: Tag) -> Self { tag.span @@ -230,36 +214,12 @@ impl Tag { Tag { origin: None, span } } - pub fn unknown_span(origin: Uuid) -> Tag { - Tag { - origin: Some(origin), - span: Span::unknown(), - } - } - pub fn unknown() -> Tag { Tag { origin: None, span: Span::unknown(), } } - - pub fn until(&self, other: impl Into) -> Tag { - let other = other.into(); - debug_assert!(self.origin == other.origin, "Can only merge two tags with the same origin"); - - Tag { - span: Span { - start: self.span.start, - end: other.span.end - }, - origin: self.origin - } - } - - pub fn slice<'a>(&self, source: &'a str) -> &'a str { - self.span.slice(source) - } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Serialize, Deserialize, Hash)] @@ -324,33 +284,3 @@ impl language_reporting::ReportingSpan for Span { self.end } } - -impl language_reporting::ReportingSpan for Tag { - fn with_start(&self, start: usize) -> Self { - Tag { - span: Span { - start, - end: self.span.end, - }, - origin: self.origin, - } - } - - fn with_end(&self, end: usize) -> Self { - Tag { - span: Span { - start: self.span.start, - end, - }, - origin: self.origin, - } - } - - fn start(&self) -> usize { - self.span.start - } - - fn end(&self) -> usize { - self.span.end - } -} diff --git a/src/errors.rs b/src/errors.rs index 3dfa644d4..d97435d22 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -14,22 +14,20 @@ pub enum Description { impl Description { pub fn from(value: Tagged>) -> Description { + let value_span = value.span(); let value_tag = value.tag(); - match value_tag { - Tag { - span: crate::data::meta::Span { start: 0, end: 0 }, - .. - } => Description::Synthetic(value.item.into()), + match value_span { + Span { start: 0, end: 0 } => Description::Synthetic(value.item.into()), _ => Description::Source(Tagged::from_item(value.item.into(), value_tag)), } } } impl Description { - fn into_label(self) -> Result, String> { + fn into_label(self) -> Result, String> { match self { - Description::Source(s) => Ok(Label::new_primary(s.tag()).with_message(s.item)), + Description::Source(s) => Ok(Label::new_primary(s.span()).with_message(s.item)), Description::Synthetic(s) => Err(s), } } @@ -83,7 +81,7 @@ impl ShellError { ) -> ShellError { ProximateShellError::RangeError { kind: expected.into(), - actual_kind: actual.copy_tag(format!("{:?}", actual.item)), + actual_kind: actual.copy_span(format!("{:?}", actual.item)), operation, } .start() @@ -118,9 +116,9 @@ impl ShellError { ProximateShellError::MissingProperty { subpath, expr }.start() } - pub(crate) fn missing_value(tag: Option, reason: impl Into) -> ShellError { + pub(crate) fn missing_value(span: Option, reason: impl Into) -> ShellError { ProximateShellError::MissingValue { - tag, + span, reason: reason.into(), } .start() @@ -129,31 +127,28 @@ impl ShellError { pub(crate) fn argument_error( command: impl Into, kind: ArgumentError, - tag: Tag, + span: Span, ) -> ShellError { ProximateShellError::ArgumentError { command: command.into(), error: kind, - tag, + span, } .start() } - pub(crate) fn invalid_external_word(tag: Tag) -> ShellError { + pub(crate) fn invalid_external_word(span: Span) -> ShellError { ProximateShellError::ArgumentError { command: "Invalid argument to Nu command (did you mean to call an external command?)" .into(), error: ArgumentError::InvalidExternalWord, - tag, + span, } .start() } pub(crate) fn parse_error( - error: nom::Err<( - nom_locate::LocatedSpanEx<&str, uuid::Uuid>, - nom::error::ErrorKind, - )>, + error: nom::Err<(nom5_locate::LocatedSpan<&str>, nom::error::ErrorKind)>, ) -> ShellError { use language_reporting::*; @@ -169,34 +164,34 @@ impl ShellError { } nom::Err::Failure(span) | nom::Err::Error(span) => { let diagnostic = Diagnostic::new(Severity::Error, format!("Parse Error")) - .with_label(Label::new_primary(Tag::from(span.0))); + .with_label(Label::new_primary(Span::from(span.0))); ShellError::diagnostic(diagnostic) } } } - pub(crate) fn diagnostic(diagnostic: Diagnostic) -> ShellError { + pub(crate) fn diagnostic(diagnostic: Diagnostic) -> ShellError { ProximateShellError::Diagnostic(ShellDiagnostic { diagnostic }).start() } - pub(crate) fn to_diagnostic(self) -> Diagnostic { + pub(crate) fn to_diagnostic(self) -> Diagnostic { match self.error { ProximateShellError::String(StringError { title, .. }) => { Diagnostic::new(Severity::Error, title) } ProximateShellError::InvalidCommand { command } => { Diagnostic::new(Severity::Error, "Invalid command") - .with_label(Label::new_primary(command)) + .with_label(Label::new_primary(command.span)) } - ProximateShellError::MissingValue { tag, reason } => { + ProximateShellError::MissingValue { span, reason } => { let mut d = Diagnostic::new( Severity::Bug, format!("Internal Error (missing value) :: {}", reason), ); - if let Some(tag) = tag { - d = d.with_label(Label::new_primary(tag)); + if let Some(span) = span { + d = d.with_label(Label::new_primary(span)); } d @@ -204,12 +199,12 @@ impl ShellError { ProximateShellError::ArgumentError { command, error, - tag, + span, } => match error { ArgumentError::InvalidExternalWord => Diagnostic::new( Severity::Error, format!("Invalid bare word for Nu command (did you intend to invoke an external command?)")) - .with_label(Label::new_primary(tag)), + .with_label(Label::new_primary(span)), ArgumentError::MissingMandatoryFlag(name) => Diagnostic::new( Severity::Error, format!( @@ -219,7 +214,7 @@ impl ShellError { Color::Black.bold().paint(name) ), ) - .with_label(Label::new_primary(tag)), + .with_label(Label::new_primary(span)), ArgumentError::MissingMandatoryPositional(name) => Diagnostic::new( Severity::Error, format!( @@ -229,7 +224,7 @@ impl ShellError { ), ) .with_label( - Label::new_primary(tag).with_message(format!("requires {} parameter", name)), + Label::new_primary(span).with_message(format!("requires {} parameter", name)), ), ArgumentError::MissingValueForName(name) => Diagnostic::new( Severity::Error, @@ -240,17 +235,17 @@ impl ShellError { Color::Black.bold().paint(name) ), ) - .with_label(Label::new_primary(tag)), + .with_label(Label::new_primary(span)), }, ProximateShellError::TypeError { expected, actual: Tagged { item: Some(actual), - tag, + tag: Tag { span, .. }, }, } => Diagnostic::new(Severity::Error, "Type Error").with_label( - Label::new_primary(tag) + Label::new_primary(span) .with_message(format!("Expected {}, found {}", expected, actual)), ), @@ -259,10 +254,10 @@ impl ShellError { actual: Tagged { item: None, - tag + tag: Tag { span, .. }, }, } => Diagnostic::new(Severity::Error, "Type Error") - .with_label(Label::new_primary(tag).with_message(expected)), + .with_label(Label::new_primary(span).with_message(expected)), ProximateShellError::RangeError { kind, @@ -270,10 +265,10 @@ impl ShellError { actual_kind: Tagged { item, - tag + tag: Tag { span, .. }, }, } => Diagnostic::new(Severity::Error, "Range Error").with_label( - Label::new_primary(tag).with_message(format!( + Label::new_primary(span).with_message(format!( "Expected to convert {} to {} while {}, but it was out of range", item, kind.desc(), @@ -284,11 +279,11 @@ impl ShellError { ProximateShellError::SyntaxError { problem: Tagged { - tag, + tag: Tag { span, .. }, .. }, } => Diagnostic::new(Severity::Error, "Syntax Error") - .with_label(Label::new_primary(tag).with_message("Unexpected external command")), + .with_label(Label::new_primary(span).with_message("Unexpected external command")), ProximateShellError::MissingProperty { subpath, expr } => { let subpath = subpath.into_label(); @@ -311,8 +306,8 @@ impl ShellError { ProximateShellError::Diagnostic(diag) => diag.diagnostic, ProximateShellError::CoerceError { left, right } => { Diagnostic::new(Severity::Error, "Coercion error") - .with_label(Label::new_primary(left.tag()).with_message(left.item)) - .with_label(Label::new_secondary(right.tag()).with_message(right.item)) + .with_label(Label::new_primary(left.span()).with_message(left.item)) + .with_label(Label::new_secondary(right.span()).with_message(right.item)) } } } @@ -320,29 +315,26 @@ impl ShellError { pub fn labeled_error( msg: impl Into, label: impl Into, - tag: impl Into, + span: impl Into, ) -> ShellError { ShellError::diagnostic( Diagnostic::new(Severity::Error, msg.into()) - .with_label(Label::new_primary(tag.into()).with_message(label.into())), + .with_label(Label::new_primary(span.into()).with_message(label.into())), ) } pub fn labeled_error_with_secondary( msg: impl Into, primary_label: impl Into, - primary_span: impl Into, + primary_span: Span, secondary_label: impl Into, - secondary_span: impl Into, + secondary_span: Span, ) -> ShellError { ShellError::diagnostic( Diagnostic::new_error(msg.into()) + .with_label(Label::new_primary(primary_span).with_message(primary_label.into())) .with_label( - Label::new_primary(primary_span.into()).with_message(primary_label.into()), - ) - .with_label( - Label::new_secondary(secondary_span.into()) - .with_message(secondary_label.into()), + Label::new_secondary(secondary_span).with_message(secondary_label.into()), ), ) } @@ -417,13 +409,13 @@ pub enum ProximateShellError { expr: Description, }, MissingValue { - tag: Option, + span: Option, reason: String, }, ArgumentError { command: String, error: ArgumentError, - tag: Tag, + span: Span, }, RangeError { kind: ExpectedRange, @@ -455,7 +447,7 @@ impl ToDebug for ProximateShellError { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ShellDiagnostic { - pub(crate) diagnostic: Diagnostic, + pub(crate) diagnostic: Diagnostic, } impl PartialEq for ShellDiagnostic { diff --git a/src/evaluate/evaluator.rs b/src/evaluate/evaluator.rs index b9db82b54..52edf6981 100644 --- a/src/evaluate/evaluator.rs +++ b/src/evaluate/evaluator.rs @@ -38,13 +38,13 @@ pub(crate) fn evaluate_baseline_expr( source: &Text, ) -> Result, ShellError> { match &expr.item { - RawExpression::Literal(literal) => Ok(evaluate_literal(expr.copy_tag(literal), source)), + RawExpression::Literal(literal) => Ok(evaluate_literal(expr.copy_span(literal), source)), RawExpression::ExternalWord => Err(ShellError::argument_error( "Invalid external word", ArgumentError::InvalidExternalWord, - expr.tag(), + expr.span(), )), - RawExpression::FilePath(path) => Ok(Value::path(path.clone()).tagged(expr.tag())), + RawExpression::FilePath(path) => Ok(Value::path(path.clone()).tagged(expr.span())), RawExpression::Synthetic(hir::Synthetic::String(s)) => Ok(Value::string(s).tagged_unknown()), RawExpression::Variable(var) => evaluate_reference(var, scope, source), RawExpression::ExternalCommand(external) => evaluate_external(external, scope, source), @@ -53,10 +53,13 @@ pub(crate) fn evaluate_baseline_expr( let right = evaluate_baseline_expr(binary.right(), registry, scope, source)?; match left.compare(binary.op(), &*right) { - Ok(result) => Ok(Value::boolean(result).tagged(expr.tag())), + Ok(result) => Ok(Tagged::from_simple_spanned_item( + Value::boolean(result), + expr.span(), + )), Err((left_type, right_type)) => Err(ShellError::coerce_error( - binary.left().copy_tag(left_type), - binary.right().copy_tag(right_type), + binary.left().copy_span(left_type), + binary.right().copy_span(right_type), )), } } @@ -68,14 +71,12 @@ pub(crate) fn evaluate_baseline_expr( exprs.push(expr); } - Ok(Value::Table(exprs).tagged(expr.tag())) - } - RawExpression::Block(block) => { - Ok( - Value::Block(Block::new(block.clone(), source.clone(), expr.tag())) - .tagged(expr.tag()), - ) + Ok(Value::Table(exprs).tagged(Tag::unknown_origin(expr.span()))) } + RawExpression::Block(block) => Ok(Tagged::from_simple_spanned_item( + Value::Block(Block::new(block.clone(), source.clone(), expr.span())), + expr.span(), + )), RawExpression::Path(path) => { let value = evaluate_baseline_expr(path.head(), registry, scope, source)?; let mut item = value; @@ -91,12 +92,18 @@ pub(crate) fn evaluate_baseline_expr( )) } Some(next) => { - item = next.clone().item.tagged(expr.tag()); + item = Tagged::from_simple_spanned_item( + next.clone().item, + (expr.span().start, name.span().end), + ) } }; } - Ok(item.item().clone().tagged(expr.tag())) + Ok(Tagged::from_simple_spanned_item( + item.item().clone(), + expr.span(), + )) } RawExpression::Boolean(_boolean) => unimplemented!(), } @@ -106,9 +113,9 @@ fn evaluate_literal(literal: Tagged<&hir::Literal>, source: &Text) -> Tagged int.into(), hir::Literal::Size(int, unit) => unit.compute(int), - hir::Literal::String(tag) => Value::string(tag.slice(source)), - hir::Literal::GlobPattern => Value::pattern(literal.tag().slice(source)), - hir::Literal::Bare => Value::string(literal.tag().slice(source)), + hir::Literal::String(span) => Value::string(span.slice(source)), + hir::Literal::GlobPattern => Value::pattern(literal.span().slice(source)), + hir::Literal::Bare => Value::string(literal.span().slice(source)), }; literal.map(|_| result) @@ -120,12 +127,12 @@ fn evaluate_reference( source: &Text, ) -> Result, ShellError> { match name { - hir::Variable::It(tag) => Ok(scope.it.item.clone().tagged(*tag)), - hir::Variable::Other(tag) => Ok(scope + hir::Variable::It(span) => Ok(scope.it.item.clone().simple_spanned(span)), + hir::Variable::Other(span) => Ok(scope .vars - .get(tag.slice(source)) + .get(span.slice(source)) .map(|v| v.clone()) - .unwrap_or_else(|| Value::nothing().tagged(*tag))), + .unwrap_or_else(|| Value::nothing().simple_spanned(span))), } } @@ -135,6 +142,6 @@ fn evaluate_external( _source: &Text, ) -> Result, ShellError> { Err(ShellError::syntax_error( - "Unexpected external command".tagged(*external.name()), + "Unexpected external command".tagged(external.name()), )) } diff --git a/src/format/table.rs b/src/format/table.rs index 286be222c..717e3c4a2 100644 --- a/src/format/table.rs +++ b/src/format/table.rs @@ -204,7 +204,7 @@ impl RenderView for TableView { let mut table = Table::new(); - let table_mode = crate::data::config::config(Tag::unknown())? + let table_mode = crate::data::config::config(Span::unknown())? .get("table_mode") .map(|s| match s.as_string().unwrap().as_ref() { "light" => TableMode::Light, diff --git a/src/lib.rs b/src/lib.rs index 60546e385..a18343df9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,7 +23,7 @@ mod utils; pub use crate::commands::command::{CallInfo, ReturnSuccess, ReturnValue}; pub use crate::context::{SourceMap, SpanSource}; pub use crate::env::host::BasicHost; -pub use crate::parser::hir::SyntaxShape; +pub use crate::parser::hir::SyntaxType; pub use crate::parser::parse::token_tree_builder::TokenTreeBuilder; pub use crate::plugin::{serve_plugin, Plugin}; pub use crate::utils::{AbsoluteFile, AbsolutePath, RelativePath}; @@ -31,7 +31,7 @@ pub use cli::cli; pub use data::config::{APP_INFO, config_path}; pub use data::base::{Primitive, Value}; pub use data::dict::{Dictionary, TaggedDictBuilder}; -pub use data::meta::{Tag, Tagged, TaggedItem}; +pub use data::meta::{Span, Tag, Tagged, TaggedItem}; pub use errors::{CoerceInto, ShellError}; pub use num_traits::cast::ToPrimitive; pub use parser::parse::text::Text; diff --git a/src/parser.rs b/src/parser.rs index 3b3ac1a13..2fd891efb 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -21,10 +21,10 @@ pub(crate) use parse::unit::Unit; pub(crate) use parse_command::parse_command; pub(crate) use registry::CommandRegistry; -pub fn parse(input: &str, origin: uuid::Uuid) -> Result { +pub fn parse(input: &str) -> Result { let _ = pretty_env_logger::try_init(); - match pipeline(nom_input(input, origin)) { + match pipeline(nom_input(input)) { Ok((_rest, val)) => Ok(val), Err(err) => Err(ShellError::parse_error(err)), } diff --git a/src/parser/deserializer.rs b/src/parser/deserializer.rs index f9b9146e5..d5427766b 100644 --- a/src/parser/deserializer.rs +++ b/src/parser/deserializer.rs @@ -37,7 +37,7 @@ impl<'de> ConfigDeserializer<'de> { let value: Option> = if name == "rest" { let positional = self.call.args.slice_from(self.position); self.position += positional.len(); - Some(Value::Table(positional).tagged_unknown()) // TODO: correct tag + Some(Value::Table(positional).tagged_unknown()) // TODO: correct span } else { if self.call.args.has(name) { self.call.args.get(name).map(|x| x.clone()) @@ -52,7 +52,9 @@ impl<'de> ConfigDeserializer<'de> { self.stack.push(DeserializerItem { key_struct_field: Some((name.to_string(), name)), - val: value.unwrap_or_else(|| Value::nothing().tagged(self.call.name_tag)), + val: value.unwrap_or_else(|| { + Value::nothing().tagged(Tag::unknown_origin(self.call.name_span)) + }), }); Ok(()) diff --git a/src/parser/hir.rs b/src/parser/hir.rs index 96eb7272a..90bb38796 100644 --- a/src/parser/hir.rs +++ b/src/parser/hir.rs @@ -25,7 +25,7 @@ pub(crate) use self::external_command::ExternalCommand; pub(crate) use self::named::NamedArguments; pub(crate) use self::path::Path; -pub use self::baseline_parse_tokens::SyntaxShape; +pub use self::baseline_parse_tokens::SyntaxType; pub fn path(head: impl Into, tail: Vec>>) -> Path { Path::new( @@ -131,57 +131,72 @@ impl RawExpression { pub type Expression = Tagged; impl Expression { - pub(crate) fn number(i: impl Into, tag: impl Into) -> Expression { - RawExpression::Literal(Literal::Number(i.into())).tagged(tag.into()) + pub(crate) fn number(i: impl Into, span: impl Into) -> Expression { + Tagged::from_simple_spanned_item(RawExpression::Literal(Literal::Number(i.into())), span) } pub(crate) fn size( i: impl Into, unit: impl Into, - tag: impl Into, + span: impl Into, ) -> Expression { - RawExpression::Literal(Literal::Size(i.into(), unit.into())).tagged(tag.into()) + Tagged::from_simple_spanned_item( + RawExpression::Literal(Literal::Size(i.into(), unit.into())), + span, + ) } pub(crate) fn synthetic_string(s: impl Into) -> Expression { RawExpression::Synthetic(Synthetic::String(s.into())).tagged_unknown() } - pub(crate) fn string(inner: impl Into, outer: impl Into) -> Expression { - RawExpression::Literal(Literal::String(inner.into())).tagged(outer.into()) + pub(crate) fn string(inner: impl Into, outer: impl Into) -> Expression { + Tagged::from_simple_spanned_item( + RawExpression::Literal(Literal::String(inner.into())), + outer.into(), + ) } - pub(crate) fn file_path(path: impl Into, outer: impl Into) -> Expression { - RawExpression::FilePath(path.into()).tagged(outer) + pub(crate) fn file_path(path: impl Into, outer: impl Into) -> Expression { + Tagged::from_simple_spanned_item(RawExpression::FilePath(path.into()), outer.into()) } - pub(crate) fn bare(tag: impl Into) -> Expression { - RawExpression::Literal(Literal::Bare).tagged(tag) + pub(crate) fn bare(span: impl Into) -> Expression { + Tagged::from_simple_spanned_item(RawExpression::Literal(Literal::Bare), span.into()) } pub(crate) fn pattern(tag: impl Into) -> Expression { RawExpression::Literal(Literal::GlobPattern).tagged(tag.into()) } - pub(crate) fn variable(inner: impl Into, outer: impl Into) -> Expression { - RawExpression::Variable(Variable::Other(inner.into())).tagged(outer) + pub(crate) fn variable(inner: impl Into, outer: impl Into) -> Expression { + Tagged::from_simple_spanned_item( + RawExpression::Variable(Variable::Other(inner.into())), + outer.into(), + ) } - pub(crate) fn external_command(inner: impl Into, outer: impl Into) -> Expression { - RawExpression::ExternalCommand(ExternalCommand::new(inner.into())).tagged(outer) + pub(crate) fn external_command(inner: impl Into, outer: impl Into) -> Expression { + Tagged::from_simple_spanned_item( + RawExpression::ExternalCommand(ExternalCommand::new(inner.into())), + outer.into(), + ) } - pub(crate) fn it_variable(inner: impl Into, outer: impl Into) -> Expression { - RawExpression::Variable(Variable::It(inner.into())).tagged(outer) + pub(crate) fn it_variable(inner: impl Into, outer: impl Into) -> Expression { + Tagged::from_simple_spanned_item( + RawExpression::Variable(Variable::It(inner.into())), + outer.into(), + ) } } impl ToDebug for Expression { fn fmt_debug(&self, f: &mut fmt::Formatter, source: &str) -> fmt::Result { match self.item() { - RawExpression::Literal(l) => l.tagged(self.tag()).fmt_debug(f, source), + RawExpression::Literal(l) => l.tagged(self.span()).fmt_debug(f, source), RawExpression::FilePath(p) => write!(f, "{}", p.display()), - RawExpression::ExternalWord => write!(f, "{}", self.tag().slice(source)), + RawExpression::ExternalWord => write!(f, "{}", self.span().slice(source)), RawExpression::Synthetic(Synthetic::String(s)) => write!(f, "{:?}", s), RawExpression::Variable(Variable::It(_)) => write!(f, "$it"), RawExpression::Variable(Variable::Other(s)) => write!(f, "${}", s.slice(source)), @@ -227,7 +242,7 @@ impl From> for Expression { pub enum Literal { Number(Number), Size(Number, Unit), - String(Tag), + String(Span), GlobPattern, Bare, } @@ -237,9 +252,9 @@ impl ToDebug for Tagged<&Literal> { match self.item() { Literal::Number(number) => write!(f, "{:?}", *number), Literal::Size(number, unit) => write!(f, "{:?}{:?}", *number, unit), - Literal::String(tag) => write!(f, "{}", tag.slice(source)), - Literal::GlobPattern => write!(f, "{}", self.tag().slice(source)), - Literal::Bare => write!(f, "{}", self.tag().slice(source)), + Literal::String(span) => write!(f, "{}", span.slice(source)), + Literal::GlobPattern => write!(f, "{}", self.span().slice(source)), + Literal::Bare => write!(f, "{}", self.span().slice(source)), } } } @@ -258,6 +273,6 @@ impl Literal { #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] pub enum Variable { - It(Tag), - Other(Tag), + It(Span), + Other(Span), } diff --git a/src/parser/hir/baseline_parse.rs b/src/parser/hir/baseline_parse.rs index 267494f27..5248bde5f 100644 --- a/src/parser/hir/baseline_parse.rs +++ b/src/parser/hir/baseline_parse.rs @@ -10,19 +10,19 @@ pub fn baseline_parse_single_token( source: &Text, ) -> Result { Ok(match *token.item() { - RawToken::Number(number) => hir::Expression::number(number.to_number(source), token.tag()), + RawToken::Number(number) => hir::Expression::number(number.to_number(source), token.span()), RawToken::Size(int, unit) => { - hir::Expression::size(int.to_number(source), unit, token.tag()) + hir::Expression::size(int.to_number(source), unit, token.span()) } - RawToken::String(tag) => hir::Expression::string(tag, token.tag()), - RawToken::Variable(tag) if tag.slice(source) == "it" => { - hir::Expression::it_variable(tag, token.tag()) + RawToken::String(span) => hir::Expression::string(span, token.span()), + RawToken::Variable(span) if span.slice(source) == "it" => { + hir::Expression::it_variable(span, token.span()) } - RawToken::Variable(tag) => hir::Expression::variable(tag, token.tag()), - RawToken::ExternalCommand(tag) => hir::Expression::external_command(tag, token.tag()), - RawToken::ExternalWord => return Err(ShellError::invalid_external_word(token.tag())), - RawToken::GlobPattern => hir::Expression::pattern(token.tag()), - RawToken::Bare => hir::Expression::bare(token.tag()), + RawToken::Variable(span) => hir::Expression::variable(span, token.span()), + RawToken::ExternalCommand(span) => hir::Expression::external_command(span, token.span()), + RawToken::ExternalWord => return Err(ShellError::invalid_external_word(token.span())), + RawToken::GlobPattern => hir::Expression::pattern(token.span()), + RawToken::Bare => hir::Expression::bare(token.span()), }) } @@ -31,24 +31,24 @@ pub fn baseline_parse_token_as_number( source: &Text, ) -> Result { Ok(match *token.item() { - RawToken::Variable(tag) if tag.slice(source) == "it" => { - hir::Expression::it_variable(tag, token.tag()) + RawToken::Variable(span) if span.slice(source) == "it" => { + hir::Expression::it_variable(span, token.span()) } - RawToken::ExternalCommand(tag) => hir::Expression::external_command(tag, token.tag()), - RawToken::ExternalWord => return Err(ShellError::invalid_external_word(token.tag())), - RawToken::Variable(tag) => hir::Expression::variable(tag, token.tag()), - RawToken::Number(number) => hir::Expression::number(number.to_number(source), token.tag()), + RawToken::ExternalCommand(span) => hir::Expression::external_command(span, token.span()), + RawToken::ExternalWord => return Err(ShellError::invalid_external_word(token.span())), + RawToken::Variable(span) => hir::Expression::variable(span, token.span()), + RawToken::Number(number) => hir::Expression::number(number.to_number(source), token.span()), RawToken::Size(number, unit) => { - hir::Expression::size(number.to_number(source), unit, token.tag()) + hir::Expression::size(number.to_number(source), unit, token.span()) } - RawToken::Bare => hir::Expression::bare(token.tag()), + RawToken::Bare => hir::Expression::bare(token.span()), RawToken::GlobPattern => { return Err(ShellError::type_error( "Number", "glob pattern".to_string().tagged(token.tag()), )) } - RawToken::String(tag) => hir::Expression::string(tag, token.tag()), + RawToken::String(span) => hir::Expression::string(span, token.span()), }) } @@ -57,22 +57,22 @@ pub fn baseline_parse_token_as_string( source: &Text, ) -> Result { Ok(match *token.item() { - RawToken::Variable(tag) if tag.slice(source) == "it" => { - hir::Expression::it_variable(tag, token.tag()) + RawToken::Variable(span) if span.slice(source) == "it" => { + hir::Expression::it_variable(span, token.span()) } - RawToken::ExternalCommand(tag) => hir::Expression::external_command(tag, token.tag()), - RawToken::ExternalWord => return Err(ShellError::invalid_external_word(token.tag())), - RawToken::Variable(tag) => hir::Expression::variable(tag, token.tag()), - RawToken::Number(_) => hir::Expression::bare(token.tag()), - RawToken::Size(_, _) => hir::Expression::bare(token.tag()), - RawToken::Bare => hir::Expression::bare(token.tag()), + RawToken::ExternalCommand(span) => hir::Expression::external_command(span, token.span()), + RawToken::ExternalWord => return Err(ShellError::invalid_external_word(token.span())), + RawToken::Variable(span) => hir::Expression::variable(span, token.span()), + RawToken::Number(_) => hir::Expression::bare(token.span()), + RawToken::Size(_, _) => hir::Expression::bare(token.span()), + RawToken::Bare => hir::Expression::bare(token.span()), RawToken::GlobPattern => { return Err(ShellError::type_error( "String", "glob pattern".tagged(token.tag()), )) } - RawToken::String(tag) => hir::Expression::string(tag, token.tag()), + RawToken::String(span) => hir::Expression::string(span, token.span()), }) } @@ -82,25 +82,26 @@ pub fn baseline_parse_token_as_path( source: &Text, ) -> Result { Ok(match *token.item() { - RawToken::Variable(tag) if tag.slice(source) == "it" => { - hir::Expression::it_variable(tag, token.tag()) - } - RawToken::ExternalCommand(tag) => hir::Expression::external_command(tag, token.tag()), - RawToken::ExternalWord => return Err(ShellError::invalid_external_word(token.tag())), - RawToken::Variable(tag) => hir::Expression::variable(tag, token.tag()), - RawToken::Number(_) => hir::Expression::bare(token.tag()), - RawToken::Size(_, _) => hir::Expression::bare(token.tag()), - RawToken::Bare => { - hir::Expression::file_path(expand_path(token.tag().slice(source), context), token.tag()) + RawToken::Variable(span) if span.slice(source) == "it" => { + hir::Expression::it_variable(span, token.span()) } + RawToken::ExternalCommand(span) => hir::Expression::external_command(span, token.span()), + RawToken::ExternalWord => return Err(ShellError::invalid_external_word(token.span())), + RawToken::Variable(span) => hir::Expression::variable(span, token.span()), + RawToken::Number(_) => hir::Expression::bare(token.span()), + RawToken::Size(_, _) => hir::Expression::bare(token.span()), + RawToken::Bare => hir::Expression::file_path( + expand_path(token.span().slice(source), context), + token.span(), + ), RawToken::GlobPattern => { return Err(ShellError::type_error( "Path", "glob pattern".tagged(token.tag()), )) } - RawToken::String(tag) => { - hir::Expression::file_path(expand_path(tag.slice(source), context), token.tag()) + RawToken::String(span) => { + hir::Expression::file_path(expand_path(span.slice(source), context), token.span()) } }) } @@ -111,24 +112,25 @@ pub fn baseline_parse_token_as_pattern( source: &Text, ) -> Result { Ok(match *token.item() { - RawToken::Variable(tag) if tag.slice(source) == "it" => { - hir::Expression::it_variable(tag, token.tag()) + RawToken::Variable(span) if span.slice(source) == "it" => { + hir::Expression::it_variable(span, token.span()) } RawToken::ExternalCommand(_) => { return Err(ShellError::syntax_error( "Invalid external command".to_string().tagged(token.tag()), )) } - RawToken::ExternalWord => return Err(ShellError::invalid_external_word(token.tag())), - RawToken::Variable(tag) => hir::Expression::variable(tag, token.tag()), - RawToken::Number(_) => hir::Expression::bare(token.tag()), - RawToken::Size(_, _) => hir::Expression::bare(token.tag()), - RawToken::GlobPattern => hir::Expression::pattern(token.tag()), - RawToken::Bare => { - hir::Expression::file_path(expand_path(token.tag().slice(source), context), token.tag()) - } - RawToken::String(tag) => { - hir::Expression::file_path(expand_path(tag.slice(source), context), token.tag()) + RawToken::ExternalWord => return Err(ShellError::invalid_external_word(token.span())), + RawToken::Variable(span) => hir::Expression::variable(span, token.span()), + RawToken::Number(_) => hir::Expression::bare(token.span()), + RawToken::Size(_, _) => hir::Expression::bare(token.span()), + RawToken::GlobPattern => hir::Expression::pattern(token.span()), + RawToken::Bare => hir::Expression::file_path( + expand_path(token.span().slice(source), context), + token.span(), + ), + RawToken::String(span) => { + hir::Expression::file_path(expand_path(span.slice(source), context), token.span()) } }) } diff --git a/src/parser/hir/baseline_parse_tokens.rs b/src/parser/hir/baseline_parse_tokens.rs index 8413bd07e..ac2c703d3 100644 --- a/src/parser/hir/baseline_parse_tokens.rs +++ b/src/parser/hir/baseline_parse_tokens.rs @@ -8,7 +8,7 @@ use crate::parser::{ }, DelimitedNode, Delimiter, PathNode, RawToken, TokenNode, }; -use crate::{Tag, Tagged, TaggedItem, Text}; +use crate::{Span, Tag, Tagged, TaggedItem, Text}; use derive_new::new; use log::trace; use serde::{Deserialize, Serialize}; @@ -17,7 +17,7 @@ pub fn baseline_parse_tokens( token_nodes: &mut TokensIterator<'_>, context: &Context, source: &Text, - syntax_type: SyntaxShape, + syntax_type: SyntaxType, ) -> Result, ShellError> { let mut exprs: Vec = vec![]; @@ -34,7 +34,7 @@ pub fn baseline_parse_tokens( } #[derive(Debug, Copy, Clone, Serialize, Deserialize)] -pub enum SyntaxShape { +pub enum SyntaxType { Any, List, Literal, @@ -49,21 +49,21 @@ pub enum SyntaxShape { Boolean, } -impl std::fmt::Display for SyntaxShape { +impl std::fmt::Display for SyntaxType { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { - SyntaxShape::Any => write!(f, "Any"), - SyntaxShape::List => write!(f, "List"), - SyntaxShape::Literal => write!(f, "Literal"), - SyntaxShape::String => write!(f, "String"), - SyntaxShape::Member => write!(f, "Member"), - SyntaxShape::Variable => write!(f, "Variable"), - SyntaxShape::Number => write!(f, "Number"), - SyntaxShape::Path => write!(f, "Path"), - SyntaxShape::Pattern => write!(f, "Pattern"), - SyntaxShape::Binary => write!(f, "Binary"), - SyntaxShape::Block => write!(f, "Block"), - SyntaxShape::Boolean => write!(f, "Boolean"), + SyntaxType::Any => write!(f, "Any"), + SyntaxType::List => write!(f, "List"), + SyntaxType::Literal => write!(f, "Literal"), + SyntaxType::String => write!(f, "String"), + SyntaxType::Member => write!(f, "Member"), + SyntaxType::Variable => write!(f, "Variable"), + SyntaxType::Number => write!(f, "Number"), + SyntaxType::Path => write!(f, "Path"), + SyntaxType::Pattern => write!(f, "Pattern"), + SyntaxType::Binary => write!(f, "Binary"), + SyntaxType::Block => write!(f, "Block"), + SyntaxType::Boolean => write!(f, "Boolean"), } } } @@ -72,7 +72,7 @@ pub fn baseline_parse_next_expr( tokens: &mut TokensIterator, context: &Context, source: &Text, - syntax_type: SyntaxShape, + syntax_type: SyntaxType, ) -> Result { let next = tokens .next() @@ -81,69 +81,69 @@ pub fn baseline_parse_next_expr( trace!(target: "nu::parser::parse_one_expr", "syntax_type={:?}, token={:?}", syntax_type, next); match (syntax_type, next) { - (SyntaxShape::Path, TokenNode::Token(token)) => { + (SyntaxType::Path, TokenNode::Token(token)) => { return baseline_parse_token_as_path(token, context, source) } - (SyntaxShape::Path, token) => { + (SyntaxType::Path, token) => { return Err(ShellError::type_error( "Path", - token.type_name().tagged(token.tag()), + token.type_name().simple_spanned(token.span()), )) } - (SyntaxShape::Pattern, TokenNode::Token(token)) => { + (SyntaxType::Pattern, TokenNode::Token(token)) => { return baseline_parse_token_as_pattern(token, context, source) } - (SyntaxShape::Pattern, token) => { + (SyntaxType::Pattern, token) => { return Err(ShellError::type_error( "Path", - token.type_name().tagged(token.tag()), + token.type_name().simple_spanned(token.span()), )) } - (SyntaxShape::String, TokenNode::Token(token)) => { + (SyntaxType::String, TokenNode::Token(token)) => { return baseline_parse_token_as_string(token, source); } - (SyntaxShape::String, token) => { + (SyntaxType::String, token) => { return Err(ShellError::type_error( "String", - token.type_name().tagged(token.tag()), + token.type_name().simple_spanned(token.span()), )) } - (SyntaxShape::Number, TokenNode::Token(token)) => { + (SyntaxType::Number, TokenNode::Token(token)) => { return Ok(baseline_parse_token_as_number(token, source)?); } - (SyntaxShape::Number, token) => { + (SyntaxType::Number, token) => { return Err(ShellError::type_error( "Numeric", - token.type_name().tagged(token.tag()), + token.type_name().simple_spanned(token.span()), )) } // TODO: More legit member processing - (SyntaxShape::Member, TokenNode::Token(token)) => { + (SyntaxType::Member, TokenNode::Token(token)) => { return baseline_parse_token_as_string(token, source); } - (SyntaxShape::Member, token) => { + (SyntaxType::Member, token) => { return Err(ShellError::type_error( "member", - token.type_name().tagged(token.tag()), + token.type_name().simple_spanned(token.span()), )) } - (SyntaxShape::Any, _) => {} - (SyntaxShape::List, _) => {} - (SyntaxShape::Literal, _) => {} - (SyntaxShape::Variable, _) => {} - (SyntaxShape::Binary, _) => {} - (SyntaxShape::Block, _) => {} - (SyntaxShape::Boolean, _) => {} + (SyntaxType::Any, _) => {} + (SyntaxType::List, _) => {} + (SyntaxType::Literal, _) => {} + (SyntaxType::Variable, _) => {} + (SyntaxType::Binary, _) => {} + (SyntaxType::Block, _) => {} + (SyntaxType::Boolean, _) => {} }; let first = baseline_parse_semantic_token(next, context, source)?; @@ -162,7 +162,7 @@ pub fn baseline_parse_next_expr( return Err(ShellError::labeled_error( "Expected something after an operator", "operator", - op.tag(), + op.span(), )) } Some(token) => baseline_parse_semantic_token(token, context, source)?, @@ -171,66 +171,75 @@ pub fn baseline_parse_next_expr( // We definitely have a binary expression here -- let's see if we should coerce it into a block match syntax_type { - SyntaxShape::Any => { - let tag = first.tag().until(second.tag()); + SyntaxType::Any => { + let span = (first.span().start, second.span().end); let binary = hir::Binary::new(first, op, second); let binary = hir::RawExpression::Binary(Box::new(binary)); - let binary = binary.tagged(tag); + let binary = Tagged::from_simple_spanned_item(binary, span); Ok(binary) } - SyntaxShape::Block => { - let tag = first.tag().until(second.tag()); + SyntaxType::Block => { + let span = (first.span().start, second.span().end); let path: Tagged = match first { Tagged { item: hir::RawExpression::Literal(hir::Literal::Bare), - tag, + tag: Tag { span, .. }, } => { - let string = tag.slice(source).to_string().tagged(tag); + let string = + Tagged::from_simple_spanned_item(span.slice(source).to_string(), span); let path = hir::Path::new( - // TODO: Deal with synthetic nodes that have no representation at all in source - hir::RawExpression::Variable(hir::Variable::It(Tag::unknown())) - .tagged(Tag::unknown()), + Tagged::from_simple_spanned_item( + // TODO: Deal with synthetic nodes that have no representation at all in source + hir::RawExpression::Variable(hir::Variable::It(Span::from((0, 0)))), + (0, 0), + ), vec![string], ); let path = hir::RawExpression::Path(Box::new(path)); - path.tagged(first.tag()) + Tagged::from_simple_spanned_item(path, first.span()) } Tagged { item: hir::RawExpression::Literal(hir::Literal::String(inner)), - tag, + tag: Tag { span, .. }, } => { - let string = inner.slice(source).to_string().tagged(tag); + let string = + Tagged::from_simple_spanned_item(inner.slice(source).to_string(), span); let path = hir::Path::new( - // TODO: Deal with synthetic nodes that have no representation at all in source - hir::RawExpression::Variable(hir::Variable::It(Tag::unknown())) - .tagged_unknown(), + Tagged::from_simple_spanned_item( + // TODO: Deal with synthetic nodes that have no representation at all in source + hir::RawExpression::Variable(hir::Variable::It(Span::from((0, 0)))), + (0, 0), + ), vec![string], ); let path = hir::RawExpression::Path(Box::new(path)); - path.tagged(first.tag()) + Tagged::from_simple_spanned_item(path, first.span()) } Tagged { item: hir::RawExpression::Variable(..), .. } => first, - Tagged { tag, item } => { + Tagged { + tag: Tag { span, .. }, + item, + } => { return Err(ShellError::labeled_error( "The first part of an un-braced block must be a column name", item.type_name(), - tag, + span, )) } }; let binary = hir::Binary::new(path, op, second); let binary = hir::RawExpression::Binary(Box::new(binary)); - let binary = binary.tagged(tag); + let binary = Tagged::from_simple_spanned_item(binary, span); let block = hir::RawExpression::Block(vec![binary]); - let block = block.tagged(tag); + let block = Tagged::from_simple_spanned_item(block, span); Ok(block) } @@ -256,11 +265,11 @@ pub fn baseline_parse_semantic_token( "Unexpected operator".tagged(op.tag), )), TokenNode::Flag(flag) => Err(ShellError::syntax_error("Unexpected flag".tagged(flag.tag))), - TokenNode::Member(tag) => Err(ShellError::syntax_error( - "BUG: Top-level member".tagged(*tag), + TokenNode::Member(span) => Err(ShellError::syntax_error( + "BUG: Top-level member".tagged(span), )), - TokenNode::Whitespace(tag) => Err(ShellError::syntax_error( - "BUG: Whitespace found during parse".tagged(*tag), + TokenNode::Whitespace(span) => Err(ShellError::syntax_error( + "BUG: Whitespace found during parse".tagged(span), )), TokenNode::Error(error) => Err(*error.item.clone()), TokenNode::Path(path) => baseline_parse_path(path, context, source), @@ -279,11 +288,11 @@ pub fn baseline_parse_delimited( &mut TokensIterator::new(children), context, source, - SyntaxShape::Any, + SyntaxType::Any, )?; let expr = hir::RawExpression::Block(exprs); - Ok(expr.tagged(token.tag())) + Ok(Tagged::from_simple_spanned_item(expr, token.span())) } Delimiter::Paren => unimplemented!(), Delimiter::Square => { @@ -292,11 +301,11 @@ pub fn baseline_parse_delimited( &mut TokensIterator::new(children), context, source, - SyntaxShape::Any, + SyntaxType::Any, )?; let expr = hir::RawExpression::List(exprs); - Ok(expr.tagged(token.tag())) + Ok(expr.tagged(Tag::unknown_origin(token.span()))) } } } @@ -313,8 +322,8 @@ pub fn baseline_parse_path( for part in token.tail() { let string = match part { TokenNode::Token(token) => match token.item() { - RawToken::Bare => token.tag().slice(source), - RawToken::String(tag) => tag.slice(source), + RawToken::Bare => token.span().slice(source), + RawToken::String(span) => span.slice(source), RawToken::Number(_) | RawToken::Size(..) | RawToken::Variable(_) @@ -323,26 +332,26 @@ pub fn baseline_parse_path( | RawToken::ExternalWord => { return Err(ShellError::type_error( "String", - token.type_name().tagged(part.tag()), + token.type_name().simple_spanned(part), )) } }, - TokenNode::Member(tag) => tag.slice(source), + TokenNode::Member(span) => span.slice(source), // TODO: Make this impossible other => { return Err(ShellError::syntax_error( - format!("{} in path", other.type_name()).tagged(other.tag()), + format!("{} in path", other.type_name()).tagged(other.span()), )) } } .to_string(); - tail.push(string.tagged(part.tag())); + tail.push(string.simple_spanned(part)); } - Ok(hir::path(head, tail).tagged(token.tag()).into()) + Ok(hir::path(head, tail).simple_spanned(token).into()) } #[derive(Debug, new)] diff --git a/src/parser/hir/external_command.rs b/src/parser/hir/external_command.rs index 28865330d..8511cce1e 100644 --- a/src/parser/hir/external_command.rs +++ b/src/parser/hir/external_command.rs @@ -9,7 +9,7 @@ use std::fmt; )] #[get = "pub(crate)"] pub struct ExternalCommand { - name: Tag, + name: Span, } impl ToDebug for ExternalCommand { diff --git a/src/parser/hir/named.rs b/src/parser/hir/named.rs index 838f643be..96d5132fb 100644 --- a/src/parser/hir/named.rs +++ b/src/parser/hir/named.rs @@ -1,6 +1,7 @@ use crate::parser::hir::Expression; use crate::parser::Flag; use crate::prelude::*; +use crate::Span; use derive_new::new; use indexmap::IndexMap; use log::trace; @@ -10,7 +11,7 @@ use std::fmt; #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] pub enum NamedValue { AbsentSwitch, - PresentSwitch(Tag), + PresentSwitch(Span), AbsentValue, Value(Expression), } @@ -26,7 +27,7 @@ impl ToDebug for NamedArguments { for (name, value) in &self.named { match value { NamedValue::AbsentSwitch => continue, - NamedValue::PresentSwitch(tag) => write!(f, " --{}", tag.slice(source))?, + NamedValue::PresentSwitch(span) => write!(f, " --{}", span.slice(source))?, NamedValue::AbsentValue => continue, NamedValue::Value(expr) => write!(f, " --{} {}", name, expr.debug(source))?, } diff --git a/src/parser/parse/files.rs b/src/parser/parse/files.rs index 6cedb1e99..173da54a8 100644 --- a/src/parser/parse/files.rs +++ b/src/parser/parse/files.rs @@ -1,7 +1,6 @@ -use crate::Tag; +use crate::Span; use derive_new::new; use language_reporting::{FileName, Location}; -use uuid::Uuid; #[derive(new, Debug, Clone)] pub struct Files { @@ -9,30 +8,26 @@ pub struct Files { } impl language_reporting::ReportingFiles for Files { - type Span = Tag; - type FileId = Uuid; + type Span = Span; + type FileId = usize; fn byte_span( &self, - file: Self::FileId, + _file: Self::FileId, from_index: usize, to_index: usize, ) -> Option { - Some(Tag::from((from_index, to_index, file))) + Some(Span::from((from_index, to_index))) } - - fn file_id(&self, tag: Self::Span) -> Self::FileId { - tag.origin.unwrap() + fn file_id(&self, _span: Self::Span) -> Self::FileId { + 0 } - fn file_name(&self, _file: Self::FileId) -> FileName { FileName::Verbatim(format!("shell")) } - fn byte_index(&self, _file: Self::FileId, _line: usize, _column: usize) -> Option { unimplemented!("byte_index") } - fn location(&self, _file: Self::FileId, byte_index: usize) -> Option { let source = &self.snippet; let mut seen_lines = 0; @@ -56,15 +51,14 @@ impl language_reporting::ReportingFiles for Files { None } } - - fn line_span(&self, file: Self::FileId, lineno: usize) -> Option { + fn line_span(&self, _file: Self::FileId, lineno: usize) -> Option { let source = &self.snippet; let mut seen_lines = 0; let mut seen_bytes = 0; for (pos, _) in source.match_indices('\n') { if seen_lines == lineno { - return Some(Tag::from((seen_bytes, pos, file))); + return Some(Span::from((seen_bytes, pos))); } else { seen_lines += 1; seen_bytes = pos + 1; @@ -72,18 +66,17 @@ impl language_reporting::ReportingFiles for Files { } if seen_lines == 0 { - Some(Tag::from((0, self.snippet.len() - 1, file))) + Some(Span::from((0, self.snippet.len() - 1))) } else { None } } - - fn source(&self, tag: Self::Span) -> Option { - if tag.span.start > tag.span.end { + fn source(&self, span: Self::Span) -> Option { + if span.start > span.end { return None; - } else if tag.span.end >= self.snippet.len() { + } else if span.end >= self.snippet.len() { return None; } - Some(tag.slice(&self.snippet).to_string()) + Some(self.snippet[span.start..span.end].to_string()) } } diff --git a/src/parser/parse/flag.rs b/src/parser/parse/flag.rs index 09d1e8633..096d69879 100644 --- a/src/parser/parse/flag.rs +++ b/src/parser/parse/flag.rs @@ -1,4 +1,4 @@ -use crate::Tag; +use crate::Span; use derive_new::new; use getset::Getters; use serde::{Deserialize, Serialize}; @@ -13,5 +13,5 @@ pub enum FlagKind { #[get = "pub(crate)"] pub struct Flag { kind: FlagKind, - name: Tag, + name: Span, } diff --git a/src/parser/parse/parser.rs b/src/parser/parse/parser.rs index f30eb2c11..0be05af06 100644 --- a/src/parser/parse/parser.rs +++ b/src/parser/parse/parser.rs @@ -5,7 +5,7 @@ use crate::parser::parse::{ tokens::*, unit::*, }; use crate::prelude::*; -use crate::{Tag, Tagged}; +use crate::{Span, Tagged}; use nom; use nom::branch::*; use nom::bytes::complete::*; @@ -18,16 +18,15 @@ use log::trace; use nom::dbg; use nom::*; use nom::{AsBytes, FindSubstring, IResult, InputLength, InputTake, Slice}; -use nom_locate::{position, LocatedSpanEx}; +use nom5_locate::{position, LocatedSpan}; use serde::{Deserialize, Serialize}; use std::fmt::Debug; use std::str::FromStr; -use uuid::Uuid; -pub type NomSpan<'a> = LocatedSpanEx<&'a str, Uuid>; +pub type NomSpan<'a> = LocatedSpan<&'a str>; -pub fn nom_input(s: &str, origin: Uuid) -> NomSpan<'_> { - LocatedSpanEx::new_extra(s, origin) +pub fn nom_input(s: &str) -> NomSpan<'_> { + LocatedSpan::new(s) } macro_rules! operator { @@ -39,7 +38,7 @@ macro_rules! operator { Ok(( input, - TokenTreeBuilder::tagged_op(tag.fragment, (start, end, input.extra)), + TokenTreeBuilder::spanned_op(tag.fragment, (start, end)), )) } }; @@ -160,14 +159,14 @@ pub fn raw_number(input: NomSpan) -> IResult> { Ok((input, dot)) => input, // it's just an integer - Err(_) => return Ok((input, RawNumber::int((start, input.offset, input.extra)))), + Err(_) => return Ok((input, RawNumber::int((start, input.offset)))), }; let (input, tail) = digit1(input)?; let end = input.offset; - Ok((input, RawNumber::decimal((start, end, input.extra)))) + Ok((input, RawNumber::decimal((start, end)))) }) } @@ -190,7 +189,7 @@ pub fn dq_string(input: NomSpan) -> IResult { let end = input.offset; Ok(( input, - TokenTreeBuilder::tagged_string((start1, end1, input.extra), (start, end, input.extra)), + TokenTreeBuilder::spanned_string((start1, end1), (start, end)), )) }) } @@ -207,7 +206,7 @@ pub fn sq_string(input: NomSpan) -> IResult { Ok(( input, - TokenTreeBuilder::tagged_string((start1, end1, input.extra), (start, end, input.extra)), + TokenTreeBuilder::spanned_string((start1, end1), (start, end)), )) }) } @@ -227,7 +226,7 @@ pub fn external(input: NomSpan) -> IResult { Ok(( input, - TokenTreeBuilder::tagged_external(bare, (start, end, input.extra)), + TokenTreeBuilder::spanned_external(bare, (start, end)), )) }) } @@ -251,10 +250,7 @@ pub fn pattern(input: NomSpan) -> IResult { let end = input.offset; - Ok(( - input, - TokenTreeBuilder::tagged_pattern((start, end, input.extra)), - )) + Ok((input, TokenTreeBuilder::spanned_pattern((start, end)))) }) } @@ -267,7 +263,7 @@ pub fn bare(input: NomSpan) -> IResult { let next_char = &input.fragment.chars().nth(0); if let Some(next_char) = next_char { - if is_external_word_char(*next_char) || is_glob_specific_char(*next_char) { + if is_external_word_char(*next_char) || *next_char == '*' { return Err(nom::Err::Error(nom::error::make_error( input, nom::error::ErrorKind::TakeWhile1, @@ -277,10 +273,7 @@ pub fn bare(input: NomSpan) -> IResult { let end = input.offset; - Ok(( - input, - TokenTreeBuilder::tagged_bare((start, end, input.extra)), - )) + Ok((input, TokenTreeBuilder::spanned_bare((start, end)))) }) } @@ -290,10 +283,7 @@ pub fn external_word(input: NomSpan) -> IResult { let (input, _) = take_while1(is_external_word_char)(input)?; let end = input.offset; - Ok(( - input, - TokenTreeBuilder::tagged_external_word((start, end, input.extra)), - )) + Ok((input, TokenTreeBuilder::spanned_external_word((start, end)))) }) } @@ -306,7 +296,7 @@ pub fn var(input: NomSpan) -> IResult { Ok(( input, - TokenTreeBuilder::tagged_var(bare.tag(), (start, end, input.extra)), + TokenTreeBuilder::spanned_var(bare.span(), (start, end)), )) }) } @@ -319,10 +309,7 @@ pub fn member(input: NomSpan) -> IResult { let end = input.offset; - Ok(( - input, - TokenTreeBuilder::tagged_member((start, end, input.extra)), - )) + Ok((input, TokenTreeBuilder::spanned_member((start, end)))) }) } @@ -335,7 +322,7 @@ pub fn flag(input: NomSpan) -> IResult { Ok(( input, - TokenTreeBuilder::tagged_flag(bare.tag(), (start, end, input.extra)), + TokenTreeBuilder::spanned_flag(bare.span(), (start, end)), )) }) } @@ -349,7 +336,7 @@ pub fn shorthand(input: NomSpan) -> IResult { Ok(( input, - TokenTreeBuilder::tagged_shorthand(bare.tag(), (start, end, input.extra)), + TokenTreeBuilder::spanned_shorthand(bare.span(), (start, end)), )) }) } @@ -382,7 +369,7 @@ pub fn raw_unit(input: NomSpan) -> IResult> { Ok(( input, - Unit::from(unit.fragment).tagged((start, end, input.extra)), + Tagged::from_simple_spanned_item(Unit::from(unit.fragment), (start, end)), )) }) } @@ -402,7 +389,7 @@ pub fn size(input: NomSpan) -> IResult { Ok(( input, - TokenTreeBuilder::tagged_size((number.item, *size), (start, end, input.extra)), + TokenTreeBuilder::spanned_size((number.item, *size), (start, end)), )) } else { let end = input.offset; @@ -414,7 +401,7 @@ pub fn size(input: NomSpan) -> IResult { Ok(( input, - TokenTreeBuilder::tagged_number(number.item, number.tag), + TokenTreeBuilder::spanned_number(number.item, number.tag), )) } }) @@ -468,18 +455,18 @@ fn make_token_list( let mut nodes = vec![]; if let Some(sp_left) = sp_left { - nodes.push(TokenNode::Whitespace(Tag::from(sp_left))); + nodes.push(TokenNode::Whitespace(Span::from(sp_left))); } nodes.push(first); for (ws, token) in list { - nodes.push(TokenNode::Whitespace(Tag::from(ws))); + nodes.push(TokenNode::Whitespace(Span::from(ws))); nodes.push(token); } if let Some(sp_right) = sp_right { - nodes.push(TokenNode::Whitespace(Tag::from(sp_right))); + nodes.push(TokenNode::Whitespace(Span::from(sp_right))); } nodes @@ -491,10 +478,7 @@ pub fn whitespace(input: NomSpan) -> IResult { let (input, ws1) = space1(input)?; let right = input.offset; - Ok(( - input, - TokenTreeBuilder::tagged_ws((left, right, input.extra)), - )) + Ok((input, TokenTreeBuilder::spanned_ws((left, right)))) }) } @@ -524,7 +508,7 @@ pub fn delimited_paren(input: NomSpan) -> IResult { Ok(( input, - TokenTreeBuilder::tagged_parens(items, (left, right, input.extra)), + TokenTreeBuilder::spanned_parens(items, (left, right)), )) }) } @@ -555,7 +539,7 @@ pub fn delimited_square(input: NomSpan) -> IResult { Ok(( input, - TokenTreeBuilder::tagged_square(items, (left, right, input.extra)), + TokenTreeBuilder::spanned_square(items, (left, right)), )) }) } @@ -572,10 +556,7 @@ pub fn delimited_brace(input: NomSpan) -> IResult { Ok(( input, - TokenTreeBuilder::tagged_brace( - items.unwrap_or_else(|| vec![]), - (left, right, input.extra), - ), + TokenTreeBuilder::spanned_brace(items.unwrap_or_else(|| vec![]), (left, right)), )) }) } @@ -586,10 +567,7 @@ pub fn raw_call(input: NomSpan) -> IResult> { let (input, items) = token_list(input)?; let right = input.offset; - Ok(( - input, - TokenTreeBuilder::tagged_call(items, (left, right, input.extra)), - )) + Ok((input, TokenTreeBuilder::spanned_call(items, (left, right)))) }) } @@ -603,7 +581,7 @@ pub fn path(input: NomSpan) -> IResult { Ok(( input, - TokenTreeBuilder::tagged_path((head, tail), (left, right, input.extra)), + TokenTreeBuilder::spanned_path((head, tail), (left, right)), )) }) } @@ -650,9 +628,9 @@ pub fn pipeline(input: NomSpan) -> IResult { Ok(( input, - TokenTreeBuilder::tagged_pipeline( - (make_call_list(head, items), tail.map(Tag::from)), - (start, end, input.extra), + TokenTreeBuilder::spanned_pipeline( + (make_call_list(head, items), tail.map(Span::from)), + (start, end), ), )) }) @@ -665,17 +643,17 @@ fn make_call_list( let mut out = vec![]; if let Some(head) = head { - let el = PipelineElement::new(None, head.0.map(Tag::from), head.1, head.2.map(Tag::from)); + let el = PipelineElement::new(None, head.0.map(Span::from), head.1, head.2.map(Span::from)); out.push(el); } for (pipe, ws1, call, ws2) in items { let el = PipelineElement::new( - Some(pipe).map(Tag::from), - ws1.map(Tag::from), + Some(pipe).map(Span::from), + ws1.map(Span::from), call, - ws2.map(Tag::from), + ws2.map(Span::from), ); out.push(el); @@ -701,17 +679,12 @@ fn is_external_word_char(c: char) -> bool { } } -/// These characters appear in globs and not bare words -fn is_glob_specific_char(c: char) -> bool { - c == '*' || c == '?' -} - fn is_start_glob_char(c: char) -> bool { - is_start_bare_char(c) || is_glob_specific_char(c) + is_start_bare_char(c) || c == '*' } fn is_glob_char(c: char) -> bool { - is_bare_char(c) || is_glob_specific_char(c) + is_bare_char(c) || c == '*' } fn is_start_bare_char(c: char) -> bool { @@ -806,7 +779,7 @@ mod tests { macro_rules! equal_tokens { ($source:tt -> $tokens:expr) => { let result = apply(pipeline, "pipeline", $source); - let (expected_tree, expected_source) = TokenTreeBuilder::build(uuid::Uuid::nil(), $tokens); + let (expected_tree, expected_source) = TokenTreeBuilder::build($tokens); if result != expected_tree { let debug_result = format!("{}", result.debug($source)); @@ -845,12 +818,12 @@ mod tests { fn test_integer() { assert_leaf! { parsers [ size ] - "123" -> 0..3 { Number(RawNumber::int((0, 3, test_uuid())).item) } + "123" -> 0..3 { Number(RawNumber::int((0, 3)).item) } } assert_leaf! { parsers [ size ] - "-123" -> 0..4 { Number(RawNumber::int((0, 4, test_uuid())).item) } + "-123" -> 0..4 { Number(RawNumber::int((0, 4)).item) } } } @@ -858,12 +831,12 @@ mod tests { fn test_size() { assert_leaf! { parsers [ size ] - "123MB" -> 0..5 { Size(RawNumber::int((0, 3, test_uuid())).item, Unit::MB) } + "123MB" -> 0..5 { Size(RawNumber::int((0, 3)).item, Unit::MB) } } assert_leaf! { parsers [ size ] - "10GB" -> 0..4 { Size(RawNumber::int((0, 2, test_uuid())).item, Unit::GB) } + "10GB" -> 0..4 { Size(RawNumber::int((0, 2)).item, Unit::GB) } } } @@ -901,12 +874,12 @@ mod tests { fn test_string() { assert_leaf! { parsers [ string dq_string ] - r#""hello world""# -> 0..13 { String(tag(1, 12)) } + r#""hello world""# -> 0..13 { String(span(1, 12)) } } assert_leaf! { parsers [ string sq_string ] - r"'hello world'" -> 0..13 { String(tag(1, 12)) } + r"'hello world'" -> 0..13 { String(span(1, 12)) } } } @@ -958,12 +931,12 @@ mod tests { fn test_variable() { assert_leaf! { parsers [ var ] - "$it" -> 0..3 { Variable(tag(1, 3)) } + "$it" -> 0..3 { Variable(span(1, 3)) } } assert_leaf! { parsers [ var ] - "$name" -> 0..5 { Variable(tag(1, 5)) } + "$name" -> 0..5 { Variable(span(1, 5)) } } } @@ -971,7 +944,7 @@ mod tests { fn test_external() { assert_leaf! { parsers [ external ] - "^ls" -> 0..3 { ExternalCommand(tag(1, 3)) } + "^ls" -> 0..3 { ExternalCommand(span(1, 3)) } } } @@ -1287,7 +1260,7 @@ mod tests { desc: &str, string: &str, ) -> T { - match f(NomSpan::new_extra(string, uuid::Uuid::nil())) { + match f(NomSpan::new(string)) { Ok(v) => v.1, Err(other) => { println!("{:?}", other); @@ -1297,46 +1270,44 @@ mod tests { } } - fn tag(left: usize, right: usize) -> Tag { - Tag::from((left, right, uuid::Uuid::nil())) + fn span(left: usize, right: usize) -> Span { + Span::from((left, right)) } fn delimited( - delimiter: Tagged, + delimiter: Delimiter, children: Vec, left: usize, right: usize, ) -> TokenNode { - let node = DelimitedNode::new(*delimiter, children); - let spanned = node.tagged((left, right, delimiter.tag.origin)); + let node = DelimitedNode::new(delimiter, children); + let spanned = Tagged::from_simple_spanned_item(node, (left, right)); TokenNode::Delimited(spanned) } fn path(head: TokenNode, tail: Vec, left: usize, right: usize) -> TokenNode { - let tag = head.tag(); - let node = PathNode::new( Box::new(head), tail.into_iter().map(TokenNode::Token).collect(), ); - let spanned = node.tagged((left, right, tag.origin)); + let spanned = Tagged::from_simple_spanned_item(node, (left, right)); TokenNode::Path(spanned) } + fn leaf_token(token: RawToken, left: usize, right: usize) -> TokenNode { + TokenNode::Token(Tagged::from_simple_spanned_item(token, (left, right))) + } + fn token(token: RawToken, left: usize, right: usize) -> TokenNode { - TokenNode::Token(token.tagged((left, right, uuid::Uuid::nil()))) + TokenNode::Token(Tagged::from_simple_spanned_item(token, (left, right))) } fn build(block: CurriedNode) -> T { - let mut builder = TokenTreeBuilder::new(uuid::Uuid::nil()); + let mut builder = TokenTreeBuilder::new(); block(&mut builder) } fn build_token(block: CurriedToken) -> TokenNode { - TokenTreeBuilder::build(uuid::Uuid::nil(), block).0 - } - - fn test_uuid() -> uuid::Uuid { - uuid::Uuid::nil() + TokenTreeBuilder::build(block).0 } } diff --git a/src/parser/parse/pipeline.rs b/src/parser/parse/pipeline.rs index 42bbe23a1..64a899c17 100644 --- a/src/parser/parse/pipeline.rs +++ b/src/parser/parse/pipeline.rs @@ -1,6 +1,6 @@ use crate::parser::CallNode; use crate::traits::ToDebug; -use crate::{Tag, Tagged}; +use crate::{Span, Tagged}; use derive_new::new; use getset::Getters; use std::fmt; @@ -8,7 +8,7 @@ use std::fmt; #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, new)] pub struct Pipeline { pub(crate) parts: Vec, - pub(crate) post_ws: Option, + pub(crate) post_ws: Option, } impl ToDebug for Pipeline { @@ -27,11 +27,11 @@ impl ToDebug for Pipeline { #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Getters, new)] pub struct PipelineElement { - pub pipe: Option, - pub pre_ws: Option, + pub pipe: Option, + pub pre_ws: Option, #[get = "pub(crate)"] call: Tagged, - pub post_ws: Option, + pub post_ws: Option, } impl ToDebug for PipelineElement { diff --git a/src/parser/parse/token_tree.rs b/src/parser/parse/token_tree.rs index e0072360e..f69c176e9 100644 --- a/src/parser/parse/token_tree.rs +++ b/src/parser/parse/token_tree.rs @@ -1,7 +1,7 @@ use crate::errors::ShellError; use crate::parser::parse::{call_node::*, flag::*, operator::*, pipeline::*, tokens::*}; use crate::traits::ToDebug; -use crate::{Tag, Tagged, Text}; +use crate::{Span, Tagged, Text}; use derive_new::new; use enum_utils::FromStr; use getset::Getters; @@ -16,8 +16,8 @@ pub enum TokenNode { Pipeline(Tagged), Operator(Tagged), Flag(Tagged), - Member(Tag), - Whitespace(Tag), + Member(Span), + Whitespace(Span), Error(Tagged>), Path(Tagged), @@ -78,31 +78,31 @@ impl fmt::Debug for DebugTokenNode<'_> { ) } TokenNode::Pipeline(pipeline) => write!(f, "{}", pipeline.debug(self.source)), - TokenNode::Error(s) => write!(f, " for {:?}", s.tag().slice(self.source)), - rest => write!(f, "{}", rest.tag().slice(self.source)), + TokenNode::Error(s) => write!(f, " for {:?}", s.span().slice(self.source)), + rest => write!(f, "{}", rest.span().slice(self.source)), } } } -impl From<&TokenNode> for Tag { - fn from(token: &TokenNode) -> Tag { - token.tag() +impl From<&TokenNode> for Span { + fn from(token: &TokenNode) -> Span { + token.span() } } impl TokenNode { - pub fn tag(&self) -> Tag { + pub fn span(&self) -> Span { match self { - TokenNode::Token(t) => t.tag(), - TokenNode::Call(s) => s.tag(), - TokenNode::Delimited(s) => s.tag(), - TokenNode::Pipeline(s) => s.tag(), - TokenNode::Operator(s) => s.tag(), - TokenNode::Flag(s) => s.tag(), + TokenNode::Token(t) => t.span(), + TokenNode::Call(s) => s.span(), + TokenNode::Delimited(s) => s.span(), + TokenNode::Pipeline(s) => s.span(), + TokenNode::Operator(s) => s.span(), + TokenNode::Flag(s) => s.span(), TokenNode::Member(s) => *s, TokenNode::Whitespace(s) => *s, - TokenNode::Error(s) => s.tag(), - TokenNode::Path(s) => s.tag(), + TokenNode::Error(s) => s.span(), + TokenNode::Path(s) => s.span(), } } @@ -127,11 +127,11 @@ impl TokenNode { } pub fn as_external_arg(&self, source: &Text) -> String { - self.tag().slice(source).to_string() + self.span().slice(source).to_string() } pub fn source<'a>(&self, source: &'a Text) -> &'a str { - self.tag().slice(source) + self.span().slice(source) } pub fn is_bare(&self) -> bool { @@ -154,12 +154,12 @@ impl TokenNode { } } - pub fn expect_external(&self) -> Tag { + pub fn expect_external(&self) -> Span { match self { TokenNode::Token(Tagged { - item: RawToken::ExternalCommand(tag), + item: RawToken::ExternalCommand(span), .. - }) => *tag, + }) => *span, _ => panic!("Only call expect_external if you checked is_external first"), } } diff --git a/src/parser/parse/token_tree_builder.rs b/src/parser/parse/token_tree_builder.rs index 1ed8383f4..ae1b344c4 100644 --- a/src/parser/parse/token_tree_builder.rs +++ b/src/parser/parse/token_tree_builder.rs @@ -7,8 +7,8 @@ use crate::parser::parse::token_tree::{DelimitedNode, Delimiter, PathNode, Token use crate::parser::parse::tokens::{RawNumber, RawToken}; use crate::parser::parse::unit::Unit; use crate::parser::CallNode; +use crate::Span; use derive_new::new; -use uuid::Uuid; #[derive(new)] pub struct TokenTreeBuilder { @@ -17,16 +17,14 @@ pub struct TokenTreeBuilder { #[new(default)] output: String, - - origin: Uuid, } pub type CurriedToken = Box TokenNode + 'static>; pub type CurriedCall = Box Tagged + 'static>; impl TokenTreeBuilder { - pub fn build(origin: Uuid, block: impl FnOnce(&mut Self) -> TokenNode) -> (TokenNode, String) { - let mut builder = TokenTreeBuilder::new(origin); + pub fn build(block: impl FnOnce(&mut Self) -> TokenNode) -> (TokenNode, String) { + let mut builder = TokenTreeBuilder::new(); let node = block(&mut builder); (node, builder.output) } @@ -54,37 +52,50 @@ impl TokenTreeBuilder { .expect("A pipeline must contain at least one element"); let pipe = None; - let pre_tag = pre.map(|pre| b.consume_tag(&pre)); + let pre_span = pre.map(|pre| b.consume(&pre)); let call = call(b); - let post_tag = post.map(|post| b.consume_tag(&post)); + let post_span = post.map(|post| b.consume(&post)); - out.push(PipelineElement::new(pipe, pre_tag, call, post_tag)); + out.push(PipelineElement::new( + pipe, + pre_span.map(Span::from), + call, + post_span.map(Span::from), + )); loop { match input.next() { None => break, Some((pre, call, post)) => { - let pipe = Some(b.consume_tag("|")); - let pre_span = pre.map(|pre| b.consume_tag(&pre)); + let pipe = Some(Span::from(b.consume("|"))); + let pre_span = pre.map(|pre| b.consume(&pre)); let call = call(b); - let post_span = post.map(|post| b.consume_tag(&post)); + let post_span = post.map(|post| b.consume(&post)); - out.push(PipelineElement::new(pipe, pre_span, call, post_span)); + out.push(PipelineElement::new( + pipe, + pre_span.map(Span::from), + call, + post_span.map(Span::from), + )); } } } let end = b.pos; - TokenTreeBuilder::tagged_pipeline((out, None), (start, end, b.origin)) + TokenTreeBuilder::spanned_pipeline((out, None), (start, end)) }) } - pub fn tagged_pipeline( - input: (Vec, Option), - tag: impl Into, + pub fn spanned_pipeline( + input: (Vec, Option), + span: impl Into, ) -> TokenNode { - TokenNode::Pipeline(Pipeline::new(input.0, input.1.into()).tagged(tag.into())) + TokenNode::Pipeline(Tagged::from_simple_spanned_item( + Pipeline::new(input.0, input.1.into()), + span, + )) } pub fn op(input: impl Into) -> CurriedToken { @@ -95,12 +106,12 @@ impl TokenTreeBuilder { b.pos = end; - TokenTreeBuilder::tagged_op(input, (start, end, b.origin)) + TokenTreeBuilder::spanned_op(input, (start, end)) }) } - pub fn tagged_op(input: impl Into, tag: impl Into) -> TokenNode { - TokenNode::Operator(input.into().tagged(tag.into())) + pub fn spanned_op(input: impl Into, span: impl Into) -> TokenNode { + TokenNode::Operator(Tagged::from_simple_spanned_item(input.into(), span.into())) } pub fn string(input: impl Into) -> CurriedToken { @@ -112,15 +123,15 @@ impl TokenTreeBuilder { let (_, end) = b.consume("\""); b.pos = end; - TokenTreeBuilder::tagged_string( - (inner_start, inner_end, b.origin), - (start, end, b.origin), - ) + TokenTreeBuilder::spanned_string((inner_start, inner_end), (start, end)) }) } - pub fn tagged_string(input: impl Into, tag: impl Into) -> TokenNode { - TokenNode::Token(RawToken::String(input.into()).tagged(tag.into())) + pub fn spanned_string(input: impl Into, span: impl Into) -> TokenNode { + TokenNode::Token(Tagged::from_simple_spanned_item( + RawToken::String(input.into()), + span.into(), + )) } pub fn bare(input: impl Into) -> CurriedToken { @@ -130,12 +141,15 @@ impl TokenTreeBuilder { let (start, end) = b.consume(&input); b.pos = end; - TokenTreeBuilder::tagged_bare((start, end, b.origin)) + TokenTreeBuilder::spanned_bare((start, end)) }) } - pub fn tagged_bare(tag: impl Into) -> TokenNode { - TokenNode::Token(RawToken::Bare.tagged(tag.into())) + pub fn spanned_bare(input: impl Into) -> TokenNode { + TokenNode::Token(Tagged::from_simple_spanned_item( + RawToken::Bare, + input.into(), + )) } pub fn pattern(input: impl Into) -> CurriedToken { @@ -145,12 +159,15 @@ impl TokenTreeBuilder { let (start, end) = b.consume(&input); b.pos = end; - TokenTreeBuilder::tagged_pattern((start, end, b.origin)) + TokenTreeBuilder::spanned_pattern((start, end)) }) } - pub fn tagged_pattern(input: impl Into) -> TokenNode { - TokenNode::Token(RawToken::GlobPattern.tagged(input.into())) + pub fn spanned_pattern(input: impl Into) -> TokenNode { + TokenNode::Token(Tagged::from_simple_spanned_item( + RawToken::Bare, + input.into(), + )) } pub fn external_word(input: impl Into) -> CurriedToken { @@ -160,16 +177,22 @@ impl TokenTreeBuilder { let (start, end) = b.consume(&input); b.pos = end; - TokenTreeBuilder::tagged_external_word((start, end, b.origin)) + TokenTreeBuilder::spanned_external_word((start, end)) }) } - pub fn tagged_external_word(input: impl Into) -> TokenNode { - TokenNode::Token(RawToken::ExternalWord.tagged(input.into())) + pub fn spanned_external_word(input: impl Into) -> TokenNode { + TokenNode::Token(Tagged::from_simple_spanned_item( + RawToken::ExternalWord, + input.into(), + )) } - pub fn tagged_external(input: impl Into, tag: impl Into) -> TokenNode { - TokenNode::Token(RawToken::ExternalCommand(input.into()).tagged(tag.into())) + pub fn spanned_external(input: impl Into, span: impl Into) -> TokenNode { + TokenNode::Token(Tagged::from_simple_spanned_item( + RawToken::ExternalCommand(input.into()), + span.into(), + )) } pub fn int(input: impl Into) -> CurriedToken { @@ -179,10 +202,7 @@ impl TokenTreeBuilder { let (start, end) = b.consume(&int.to_string()); b.pos = end; - TokenTreeBuilder::tagged_number( - RawNumber::Int((start, end, b.origin).into()), - (start, end, b.origin), - ) + TokenTreeBuilder::spanned_number(RawNumber::Int((start, end).into()), (start, end)) }) } @@ -193,15 +213,15 @@ impl TokenTreeBuilder { let (start, end) = b.consume(&decimal.to_string()); b.pos = end; - TokenTreeBuilder::tagged_number( - RawNumber::Decimal((start, end, b.origin).into()), - (start, end, b.origin), - ) + TokenTreeBuilder::spanned_number(RawNumber::Decimal((start, end).into()), (start, end)) }) } - pub fn tagged_number(input: impl Into, tag: impl Into) -> TokenNode { - TokenNode::Token(RawToken::Number(input.into()).tagged(tag.into())) + pub fn spanned_number(input: impl Into, span: impl Into) -> TokenNode { + TokenNode::Token(Tagged::from_simple_spanned_item( + RawToken::Number(input.into()), + span.into(), + )) } pub fn size(int: impl Into, unit: impl Into) -> CurriedToken { @@ -213,20 +233,23 @@ impl TokenTreeBuilder { let (_, end_unit) = b.consume(unit.as_str()); b.pos = end_unit; - TokenTreeBuilder::tagged_size( - (RawNumber::Int((start_int, end_int, b.origin).into()), unit), - (start_int, end_unit, b.origin), + TokenTreeBuilder::spanned_size( + (RawNumber::Int((start_int, end_int).into()), unit), + (start_int, end_unit), ) }) } - pub fn tagged_size( + pub fn spanned_size( input: (impl Into, impl Into), - tag: impl Into, + span: impl Into, ) -> TokenNode { let (int, unit) = (input.0.into(), input.1.into()); - TokenNode::Token(RawToken::Size(int, unit).tagged(tag.into())) + TokenNode::Token(Tagged::from_simple_spanned_item( + RawToken::Size(int, unit), + span, + )) } pub fn path(head: CurriedToken, tail: Vec) -> CurriedToken { @@ -244,12 +267,15 @@ impl TokenTreeBuilder { let end = b.pos; - TokenTreeBuilder::tagged_path((head, output), (start, end, b.origin)) + TokenTreeBuilder::spanned_path((head, output), (start, end)) }) } - pub fn tagged_path(input: (TokenNode, Vec), tag: impl Into) -> TokenNode { - TokenNode::Path(PathNode::new(Box::new(input.0), input.1).tagged(tag.into())) + pub fn spanned_path(input: (TokenNode, Vec), span: impl Into) -> TokenNode { + TokenNode::Path(Tagged::from_simple_spanned_item( + PathNode::new(Box::new(input.0), input.1), + span, + )) } pub fn var(input: impl Into) -> CurriedToken { @@ -259,12 +285,15 @@ impl TokenTreeBuilder { let (start, _) = b.consume("$"); let (inner_start, end) = b.consume(&input); - TokenTreeBuilder::tagged_var((inner_start, end, b.origin), (start, end, b.origin)) + TokenTreeBuilder::spanned_var((inner_start, end), (start, end)) }) } - pub fn tagged_var(input: impl Into, tag: impl Into) -> TokenNode { - TokenNode::Token(RawToken::Variable(input.into()).tagged(tag.into())) + pub fn spanned_var(input: impl Into, span: impl Into) -> TokenNode { + TokenNode::Token(Tagged::from_simple_spanned_item( + RawToken::Variable(input.into()), + span.into(), + )) } pub fn flag(input: impl Into) -> CurriedToken { @@ -274,12 +303,15 @@ impl TokenTreeBuilder { let (start, _) = b.consume("--"); let (inner_start, end) = b.consume(&input); - TokenTreeBuilder::tagged_flag((inner_start, end, b.origin), (start, end, b.origin)) + TokenTreeBuilder::spanned_flag((inner_start, end), (start, end)) }) } - pub fn tagged_flag(input: impl Into, tag: impl Into) -> TokenNode { - TokenNode::Flag(Flag::new(FlagKind::Longhand, input.into()).tagged(tag.into())) + pub fn spanned_flag(input: impl Into, span: impl Into) -> TokenNode { + TokenNode::Flag(Tagged::from_simple_spanned_item( + Flag::new(FlagKind::Longhand, input.into()), + span.into(), + )) } pub fn shorthand(input: impl Into) -> CurriedToken { @@ -289,12 +321,15 @@ impl TokenTreeBuilder { let (start, _) = b.consume("-"); let (inner_start, end) = b.consume(&input); - TokenTreeBuilder::tagged_shorthand((inner_start, end, b.origin), (start, end, b.origin)) + TokenTreeBuilder::spanned_shorthand((inner_start, end), (start, end)) }) } - pub fn tagged_shorthand(input: impl Into, tag: impl Into) -> TokenNode { - TokenNode::Flag(Flag::new(FlagKind::Shorthand, input.into()).tagged(tag.into())) + pub fn spanned_shorthand(input: impl Into, span: impl Into) -> TokenNode { + TokenNode::Flag(Tagged::from_simple_spanned_item( + Flag::new(FlagKind::Shorthand, input.into()), + span.into(), + )) } pub fn member(input: impl Into) -> CurriedToken { @@ -302,12 +337,12 @@ impl TokenTreeBuilder { Box::new(move |b| { let (start, end) = b.consume(&input); - TokenTreeBuilder::tagged_member((start, end, b.origin)) + TokenTreeBuilder::spanned_member((start, end)) }) } - pub fn tagged_member(tag: impl Into) -> TokenNode { - TokenNode::Member(tag.into()) + pub fn spanned_member(span: impl Into) -> TokenNode { + TokenNode::Member(span.into()) } pub fn call(head: CurriedToken, input: Vec) -> CurriedCall { @@ -323,11 +358,11 @@ impl TokenTreeBuilder { let end = b.pos; - TokenTreeBuilder::tagged_call(nodes, (start, end, b.origin)) + TokenTreeBuilder::spanned_call(nodes, (start, end)) }) } - pub fn tagged_call(input: Vec, tag: impl Into) -> Tagged { + pub fn spanned_call(input: Vec, span: impl Into) -> Tagged { if input.len() == 0 { panic!("BUG: spanned call (TODO)") } @@ -337,7 +372,7 @@ impl TokenTreeBuilder { let head = input.next().unwrap(); let tail = input.collect(); - CallNode::new(Box::new(head), tail).tagged(tag.into()) + Tagged::from_simple_spanned_item(CallNode::new(Box::new(head), tail), span) } pub fn parens(input: Vec) -> CurriedToken { @@ -350,12 +385,15 @@ impl TokenTreeBuilder { let (_, end) = b.consume(")"); - TokenTreeBuilder::tagged_parens(output, (start, end, b.origin)) + TokenTreeBuilder::spanned_parens(output, (start, end)) }) } - pub fn tagged_parens(input: impl Into>, tag: impl Into) -> TokenNode { - TokenNode::Delimited(DelimitedNode::new(Delimiter::Paren, input.into()).tagged(tag.into())) + pub fn spanned_parens(input: impl Into>, span: impl Into) -> TokenNode { + TokenNode::Delimited(Tagged::from_simple_spanned_item( + DelimitedNode::new(Delimiter::Paren, input.into()), + span, + )) } pub fn square(input: Vec) -> CurriedToken { @@ -368,12 +406,15 @@ impl TokenTreeBuilder { let (_, end) = b.consume("]"); - TokenTreeBuilder::tagged_square(output, (start, end, b.origin)) + TokenTreeBuilder::spanned_square(output, (start, end)) }) } - pub fn tagged_square(input: impl Into>, tag: impl Into) -> TokenNode { - TokenNode::Delimited(DelimitedNode::new(Delimiter::Square, input.into()).tagged(tag.into())) + pub fn spanned_square(input: impl Into>, span: impl Into) -> TokenNode { + TokenNode::Delimited(Tagged::from_simple_spanned_item( + DelimitedNode::new(Delimiter::Square, input.into()), + span, + )) } pub fn braced(input: Vec) -> CurriedToken { @@ -386,18 +427,21 @@ impl TokenTreeBuilder { let (_, end) = b.consume(" }"); - TokenTreeBuilder::tagged_brace(output, (start, end, b.origin)) + TokenTreeBuilder::spanned_brace(output, (start, end)) }) } - pub fn tagged_brace(input: impl Into>, tag: impl Into) -> TokenNode { - TokenNode::Delimited(DelimitedNode::new(Delimiter::Brace, input.into()).tagged(tag.into())) + pub fn spanned_brace(input: impl Into>, span: impl Into) -> TokenNode { + TokenNode::Delimited(Tagged::from_simple_spanned_item( + DelimitedNode::new(Delimiter::Brace, input.into()), + span, + )) } pub fn sp() -> CurriedToken { Box::new(|b| { let (start, end) = b.consume(" "); - TokenNode::Whitespace(Tag::from((start, end, b.origin))) + TokenNode::Whitespace(Span::from((start, end))) }) } @@ -406,12 +450,14 @@ impl TokenTreeBuilder { Box::new(move |b| { let (start, end) = b.consume(&input); - TokenTreeBuilder::tagged_ws((start, end, b.origin)) + TokenTreeBuilder::spanned_ws((start, end)) }) } - pub fn tagged_ws(tag: impl Into) -> TokenNode { - TokenNode::Whitespace(tag.into()) + pub fn spanned_ws(span: impl Into) -> TokenNode { + let span = span.into(); + + TokenNode::Whitespace(span.into()) } fn consume(&mut self, input: &str) -> (usize, usize) { @@ -420,11 +466,4 @@ impl TokenTreeBuilder { self.output.push_str(input); (start, self.pos) } - - fn consume_tag(&mut self, input: &str) -> Tag { - let start = self.pos; - self.pos += input.len(); - self.output.push_str(input); - (start, self.pos, self.origin).into() - } } diff --git a/src/parser/parse/tokens.rs b/src/parser/parse/tokens.rs index d796a8fcb..b59985249 100644 --- a/src/parser/parse/tokens.rs +++ b/src/parser/parse/tokens.rs @@ -1,6 +1,6 @@ use crate::parser::parse::unit::*; use crate::prelude::*; -use crate::{Tagged, Text}; +use crate::{Span, Tagged, Text}; use std::fmt; use std::str::FromStr; @@ -8,9 +8,9 @@ use std::str::FromStr; pub enum RawToken { Number(RawNumber), Size(RawNumber, Unit), - String(Tag), - Variable(Tag), - ExternalCommand(Tag), + String(Span), + Variable(Span), + ExternalCommand(Span), ExternalWord, GlobPattern, Bare, @@ -18,28 +18,28 @@ pub enum RawToken { #[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)] pub enum RawNumber { - Int(Tag), - Decimal(Tag), + Int(Span), + Decimal(Span), } impl RawNumber { - pub fn int(tag: impl Into) -> Tagged { - let tag = tag.into(); + pub fn int(span: impl Into) -> Tagged { + let span = span.into(); - RawNumber::Int(tag).tagged(tag) + RawNumber::Int(span).tagged(span) } - pub fn decimal(tag: impl Into) -> Tagged { - let tag = tag.into(); + pub fn decimal(span: impl Into) -> Tagged { + let span = span.into(); - RawNumber::Decimal(tag).tagged(tag) + RawNumber::Decimal(span).tagged(span) } pub(crate) fn to_number(self, source: &Text) -> Number { match self { - RawNumber::Int(tag) => Number::Int(BigInt::from_str(tag.slice(source)).unwrap()), - RawNumber::Decimal(tag) => { - Number::Decimal(BigDecimal::from_str(tag.slice(source)).unwrap()) + RawNumber::Int(span) => Number::Int(BigInt::from_str(span.slice(source)).unwrap()), + RawNumber::Decimal(span) => { + Number::Decimal(BigDecimal::from_str(span.slice(source)).unwrap()) } } } @@ -78,6 +78,6 @@ pub struct DebugToken<'a> { impl fmt::Debug for DebugToken<'_> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.node.tag().slice(self.source)) + write!(f, "{}", self.node.span().slice(self.source)) } } diff --git a/src/parser/parse_command.rs b/src/parser/parse_command.rs index 36ba82f8e..e0fc9d86f 100644 --- a/src/parser/parse_command.rs +++ b/src/parser/parse_command.rs @@ -7,7 +7,7 @@ use crate::parser::{ Flag, RawToken, TokenNode, }; use crate::traits::ToDebug; -use crate::{Tag, Tagged, TaggedItem, Text}; +use crate::{Span, Tag, Tagged, Text}; use log::trace; pub fn parse_command( @@ -33,7 +33,7 @@ pub fn parse_command( .collect() }); - match parse_command_tail(&config, context, children, source, call.tag())? { + match parse_command_tail(&config, context, children, source, call.span())? { None => Ok(hir::Call::new(Box::new(head), None, None)), Some((positional, named)) => Ok(hir::Call::new(Box::new(head), positional, named)), } @@ -49,9 +49,12 @@ fn parse_command_head(head: &TokenNode) -> Result { ) => Ok(spanned.map(|_| hir::RawExpression::Literal(hir::Literal::Bare))), TokenNode::Token(Tagged { - item: RawToken::String(inner_tag), - tag, - }) => Ok(hir::RawExpression::Literal(hir::Literal::String(*inner_tag)).tagged(*tag)), + item: RawToken::String(inner_span), + tag: Tag { span, origin: None }, + }) => Ok(Tagged::from_simple_spanned_item( + hir::RawExpression::Literal(hir::Literal::String(*inner_span)), + *span, + )), other => Err(ShellError::unexpected(&format!( "command head -> {:?}", @@ -65,7 +68,7 @@ fn parse_command_tail( context: &Context, tail: Option>, source: &Text, - command_tag: Tag, + command_span: Span, ) -> Result>, Option)>, ShellError> { let tail = &mut match &tail { None => hir::TokensIterator::new(&[]), @@ -86,7 +89,7 @@ fn parse_command_tail( named.insert_switch(name, flag); } NamedType::Mandatory(syntax_type) => { - match extract_mandatory(config, name, tail, source, command_tag) { + match extract_mandatory(config, name, tail, source, command_span) { Err(err) => return Err(err), // produce a correct diagnostic Ok((pos, flag)) => { tail.move_to(pos); @@ -95,7 +98,7 @@ fn parse_command_tail( return Err(ShellError::argument_error( config.name.clone(), ArgumentError::MissingValueForName(name.to_string()), - flag.tag(), + flag.span(), )); } @@ -116,7 +119,7 @@ fn parse_command_tail( return Err(ShellError::argument_error( config.name.clone(), ArgumentError::MissingValueForName(name.to_string()), - flag.tag(), + flag.span(), )); } @@ -147,7 +150,7 @@ fn parse_command_tail( return Err(ShellError::argument_error( config.name.clone(), ArgumentError::MissingMandatoryPositional(arg.name().to_string()), - command_tag, + command_span, )); } } @@ -205,7 +208,7 @@ fn extract_mandatory( name: &str, tokens: &mut hir::TokensIterator<'_>, source: &Text, - tag: Tag, + span: Span, ) -> Result<(usize, Tagged), ShellError> { let flag = tokens.extract(|t| t.as_flag(name, source)); @@ -213,7 +216,7 @@ fn extract_mandatory( None => Err(ShellError::argument_error( config.name.clone(), ArgumentError::MissingMandatoryFlag(name.to_string()), - tag, + span, )), Some((pos, flag)) => { diff --git a/src/parser/registry.rs b/src/parser/registry.rs index e199be192..7112d9111 100644 --- a/src/parser/registry.rs +++ b/src/parser/registry.rs @@ -1,7 +1,7 @@ // TODO: Temporary redirect pub(crate) use crate::context::CommandRegistry; use crate::evaluate::{evaluate_baseline_expr, Scope}; -use crate::parser::{hir, hir::SyntaxShape, parse_command, CallNode}; +use crate::parser::{hir, hir::SyntaxType, parse_command, CallNode}; use crate::prelude::*; use derive_new::new; use indexmap::IndexMap; @@ -12,35 +12,35 @@ use std::fmt; #[derive(Debug, Serialize, Deserialize, Clone)] pub enum NamedType { Switch, - Mandatory(SyntaxShape), - Optional(SyntaxShape), + Mandatory(SyntaxType), + Optional(SyntaxType), } #[derive(Debug, Clone, Serialize, Deserialize)] pub enum PositionalType { - Mandatory(String, SyntaxShape), - Optional(String, SyntaxShape), + Mandatory(String, SyntaxType), + Optional(String, SyntaxType), } impl PositionalType { - pub fn mandatory(name: &str, ty: SyntaxShape) -> PositionalType { + pub fn mandatory(name: &str, ty: SyntaxType) -> PositionalType { PositionalType::Mandatory(name.to_string(), ty) } pub fn mandatory_any(name: &str) -> PositionalType { - PositionalType::Mandatory(name.to_string(), SyntaxShape::Any) + PositionalType::Mandatory(name.to_string(), SyntaxType::Any) } pub fn mandatory_block(name: &str) -> PositionalType { - PositionalType::Mandatory(name.to_string(), SyntaxShape::Block) + PositionalType::Mandatory(name.to_string(), SyntaxType::Block) } - pub fn optional(name: &str, ty: SyntaxShape) -> PositionalType { + pub fn optional(name: &str, ty: SyntaxType) -> PositionalType { PositionalType::Optional(name.to_string(), ty) } pub fn optional_any(name: &str) -> PositionalType { - PositionalType::Optional(name.to_string(), SyntaxShape::Any) + PositionalType::Optional(name.to_string(), SyntaxType::Any) } pub(crate) fn name(&self) -> &str { @@ -50,7 +50,7 @@ impl PositionalType { } } - pub(crate) fn syntax_type(&self) -> SyntaxShape { + pub(crate) fn syntax_type(&self) -> SyntaxType { match *self { PositionalType::Mandatory(_, t) => t, PositionalType::Optional(_, t) => t, @@ -66,7 +66,7 @@ pub struct Signature { #[new(default)] pub positional: Vec, #[new(value = "None")] - pub rest_positional: Option, + pub rest_positional: Option, #[new(default)] pub named: IndexMap, #[new(value = "false")] @@ -83,21 +83,21 @@ impl Signature { self } - pub fn required(mut self, name: impl Into, ty: impl Into) -> Signature { + pub fn required(mut self, name: impl Into, ty: impl Into) -> Signature { self.positional .push(PositionalType::Mandatory(name.into(), ty.into())); self } - pub fn optional(mut self, name: impl Into, ty: impl Into) -> Signature { + pub fn optional(mut self, name: impl Into, ty: impl Into) -> Signature { self.positional .push(PositionalType::Optional(name.into(), ty.into())); self } - pub fn named(mut self, name: impl Into, ty: impl Into) -> Signature { + pub fn named(mut self, name: impl Into, ty: impl Into) -> Signature { self.named .insert(name.into(), NamedType::Optional(ty.into())); @@ -107,7 +107,7 @@ impl Signature { pub fn required_named( mut self, name: impl Into, - ty: impl Into, + ty: impl Into, ) -> Signature { self.named .insert(name.into(), NamedType::Mandatory(ty.into())); @@ -126,7 +126,7 @@ impl Signature { self } - pub fn rest(mut self, ty: SyntaxShape) -> Signature { + pub fn rest(mut self, ty: SyntaxType) -> Signature { self.rest_positional = Some(ty); self } @@ -312,10 +312,10 @@ pub(crate) fn evaluate_args( for (name, value) in n.named.iter() { match value { - hir::named::NamedValue::PresentSwitch(tag) => { + hir::named::NamedValue::PresentSwitch(span) => { results.insert( name.clone(), - Value::boolean(true).tagged(*tag), + Tagged::from_simple_spanned_item(Value::boolean(true), *span), ); } hir::named::NamedValue::Value(expr) => { diff --git a/src/plugins/add.rs b/src/plugins/add.rs index 03e1d4282..744003cd7 100644 --- a/src/plugins/add.rs +++ b/src/plugins/add.rs @@ -1,6 +1,6 @@ use nu::{ serve_plugin, CallInfo, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError, Signature, - SyntaxShape, Tagged, Value, + SyntaxType, Tagged, Value, }; struct Add { @@ -44,9 +44,9 @@ impl Plugin for Add { fn config(&mut self) -> Result { Ok(Signature::build("add") .desc("Add a new field to the table.") - .required("Field", SyntaxShape::String) - .required("Value", SyntaxShape::String) - .rest(SyntaxShape::String) + .required("Field", SyntaxType::String) + .required("Value", SyntaxType::String) + .rest(SyntaxType::String) .filter()) } diff --git a/src/plugins/edit.rs b/src/plugins/edit.rs index db116fedf..aeda4ba09 100644 --- a/src/plugins/edit.rs +++ b/src/plugins/edit.rs @@ -1,6 +1,6 @@ use nu::{ serve_plugin, CallInfo, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError, Signature, - SyntaxShape, Tagged, Value, + SyntaxType, Tagged, Value, }; struct Edit { @@ -43,8 +43,8 @@ impl Plugin for Edit { fn config(&mut self) -> Result { Ok(Signature::build("edit") .desc("Edit an existing column to have a new value.") - .required("Field", SyntaxShape::String) - .required("Value", SyntaxShape::String) + .required("Field", SyntaxType::String) + .required("Value", SyntaxType::String) .filter()) } diff --git a/src/plugins/embed.rs b/src/plugins/embed.rs index 646db8091..95140aa60 100644 --- a/src/plugins/embed.rs +++ b/src/plugins/embed.rs @@ -1,6 +1,6 @@ use nu::{ serve_plugin, CallInfo, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError, Signature, - SyntaxShape, Tag, Tagged, TaggedDictBuilder, Value, + SyntaxType, Tag, Tagged, TaggedDictBuilder, Value, }; struct Embed { @@ -37,8 +37,8 @@ impl Plugin for Embed { fn config(&mut self) -> Result { Ok(Signature::build("embed") .desc("Embeds a new field to the table.") - .required("Field", SyntaxShape::String) - .rest(SyntaxShape::String) + .required("Field", SyntaxType::String) + .rest(SyntaxType::String) .filter()) } diff --git a/src/plugins/inc.rs b/src/plugins/inc.rs index 4422195be..d75da4142 100644 --- a/src/plugins/inc.rs +++ b/src/plugins/inc.rs @@ -1,6 +1,6 @@ use nu::{ serve_plugin, CallInfo, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError, Signature, - SyntaxShape, Tagged, TaggedItem, Value, + SyntaxType, Tagged, TaggedItem, Value, }; enum Action { @@ -120,7 +120,7 @@ impl Plugin for Inc { .switch("major") .switch("minor") .switch("patch") - .rest(SyntaxShape::String) + .rest(SyntaxType::String) .filter()) } @@ -181,20 +181,18 @@ mod tests { use super::{Inc, SemVerAction}; use indexmap::IndexMap; use nu::{ - CallInfo, EvaluatedArgs, Plugin, ReturnSuccess, SourceMap, Tag, Tagged, TaggedDictBuilder, - TaggedItem, Value, + CallInfo, EvaluatedArgs, Plugin, ReturnSuccess, SourceMap, Span, Tag, Tagged, + TaggedDictBuilder, TaggedItem, Value, }; struct CallStub { - origin: uuid::Uuid, positionals: Vec>, flags: IndexMap>, } impl CallStub { - fn new(origin: uuid::Uuid) -> CallStub { + fn new() -> CallStub { CallStub { - origin, positionals: vec![], flags: indexmap::IndexMap::new(), } @@ -203,14 +201,14 @@ mod tests { fn with_long_flag(&mut self, name: &str) -> &mut Self { self.flags.insert( name.to_string(), - Value::boolean(true).tagged(Tag::unknown()), + Value::boolean(true).simple_spanned(Span::unknown()), ); self } fn with_parameter(&mut self, name: &str) -> &mut Self { self.positionals - .push(Value::string(name.to_string()).tagged(Tag::unknown_span(self.origin))); + .push(Value::string(name.to_string()).simple_spanned(Span::unknown())); self } @@ -218,7 +216,7 @@ mod tests { CallInfo { args: EvaluatedArgs::new(Some(self.positionals.clone()), Some(self.flags.clone())), source_map: SourceMap::new(), - name_tag: Tag::unknown_span(self.origin), + name_span: Span::unknown(), } } } @@ -245,7 +243,7 @@ mod tests { let mut plugin = Inc::new(); assert!(plugin - .begin_filter(CallStub::new(test_uuid()).with_long_flag("major").create()) + .begin_filter(CallStub::new().with_long_flag("major").create()) .is_ok()); assert!(plugin.action.is_some()); } @@ -255,7 +253,7 @@ mod tests { let mut plugin = Inc::new(); assert!(plugin - .begin_filter(CallStub::new(test_uuid()).with_long_flag("minor").create()) + .begin_filter(CallStub::new().with_long_flag("minor").create()) .is_ok()); assert!(plugin.action.is_some()); } @@ -265,7 +263,7 @@ mod tests { let mut plugin = Inc::new(); assert!(plugin - .begin_filter(CallStub::new(test_uuid()).with_long_flag("patch").create()) + .begin_filter(CallStub::new().with_long_flag("patch").create()) .is_ok()); assert!(plugin.action.is_some()); } @@ -276,7 +274,7 @@ mod tests { assert!(plugin .begin_filter( - CallStub::new(test_uuid()) + CallStub::new() .with_long_flag("major") .with_long_flag("minor") .create(), @@ -290,11 +288,7 @@ mod tests { let mut plugin = Inc::new(); assert!(plugin - .begin_filter( - CallStub::new(test_uuid()) - .with_parameter("package.version") - .create() - ) + .begin_filter(CallStub::new().with_parameter("package.version").create()) .is_ok()); assert_eq!(plugin.field, Some("package.version".to_string())); @@ -327,7 +321,7 @@ mod tests { assert!(plugin .begin_filter( - CallStub::new(test_uuid()) + CallStub::new() .with_long_flag("major") .with_parameter("version") .create() @@ -355,7 +349,7 @@ mod tests { assert!(plugin .begin_filter( - CallStub::new(test_uuid()) + CallStub::new() .with_long_flag("minor") .with_parameter("version") .create() @@ -384,7 +378,7 @@ mod tests { assert!(plugin .begin_filter( - CallStub::new(test_uuid()) + CallStub::new() .with_long_flag("patch") .with_parameter(&field) .create() @@ -405,8 +399,4 @@ mod tests { _ => {} } } - - fn test_uuid() -> uuid::Uuid { - uuid::Uuid::nil() - } } diff --git a/src/plugins/ps.rs b/src/plugins/ps.rs index 342bd5eb3..0f06167bd 100644 --- a/src/plugins/ps.rs +++ b/src/plugins/ps.rs @@ -40,7 +40,7 @@ async fn ps(tag: Tag) -> Vec> { let mut output = vec![]; while let Some(res) = processes.next().await { if let Ok((process, usage)) = res { - let mut dict = TaggedDictBuilder::new(tag); + let mut dict = TaggedDictBuilder::new(Tag::unknown_origin(tag.span)); dict.insert("pid", Value::int(process.pid())); if let Ok(name) = process.name().await { dict.insert("name", Value::string(name)); @@ -64,7 +64,7 @@ impl Plugin for Ps { } fn begin_filter(&mut self, callinfo: CallInfo) -> Result, ShellError> { - Ok(block_on(ps(Tag::unknown_origin(callinfo.name_tag))) + Ok(block_on(ps(Tag::unknown_origin(callinfo.name_span))) .into_iter() .map(ReturnSuccess::value) .collect()) diff --git a/src/plugins/skip.rs b/src/plugins/skip.rs index efd323152..cb259e99b 100644 --- a/src/plugins/skip.rs +++ b/src/plugins/skip.rs @@ -1,6 +1,6 @@ use nu::{ serve_plugin, CallInfo, CoerceInto, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError, - Signature, SyntaxShape, Tagged, TaggedItem, Value, + Signature, SyntaxType, Tagged, TaggedItem, Value, }; struct Skip { @@ -15,9 +15,9 @@ impl Skip { impl Plugin for Skip { fn config(&mut self) -> Result { - Ok(Signature::build("skip") + Ok(Signature::build("skip") .desc("Skip a number of rows") - .rest(SyntaxShape::Number) + .rest(SyntaxType::Number) .filter()) } fn begin_filter(&mut self, call_info: CallInfo) -> Result, ShellError> { @@ -34,7 +34,7 @@ impl Plugin for Skip { return Err(ShellError::labeled_error( "Unrecognized type in params", "expected an integer", - arg.tag(), + arg.span(), )) } } diff --git a/src/plugins/str.rs b/src/plugins/str.rs index c9e82ab15..99700449b 100644 --- a/src/plugins/str.rs +++ b/src/plugins/str.rs @@ -1,6 +1,6 @@ use nu::{ serve_plugin, CallInfo, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError, Signature, - SyntaxShape, Tagged, Value, + SyntaxType, Tagged, Value, }; use regex::Regex; @@ -174,7 +174,7 @@ impl Plugin for Str { .switch("to-int") .switch("replace") .switch("find-replace") - .rest(SyntaxShape::Member) + .rest(SyntaxType::Member) .filter()) } @@ -261,7 +261,7 @@ mod tests { use super::{Action, ReplaceAction, Str}; use indexmap::IndexMap; use nu::{ - CallInfo, EvaluatedArgs, Plugin, Primitive, ReturnSuccess, SourceMap, Tag, Tagged, + CallInfo, EvaluatedArgs, Plugin, Primitive, ReturnSuccess, SourceMap, Span, Tag, Tagged, TaggedDictBuilder, TaggedItem, Value, }; use num_bigint::BigInt; @@ -277,7 +277,6 @@ mod tests { } struct CallStub { - origin: uuid::Uuid, positionals: Vec>, flags: IndexMap>, } @@ -285,7 +284,6 @@ mod tests { impl CallStub { fn new() -> CallStub { CallStub { - origin: uuid::Uuid::nil(), positionals: vec![], flags: indexmap::IndexMap::new(), } @@ -294,14 +292,14 @@ mod tests { fn with_long_flag(&mut self, name: &str) -> &mut Self { self.flags.insert( name.to_string(), - Value::boolean(true).tagged(Tag::unknown()), + Value::boolean(true).simple_spanned(Span::unknown()), ); self } fn with_parameter(&mut self, name: &str) -> &mut Self { self.positionals - .push(Value::string(name.to_string()).tagged(Tag::unknown())); + .push(Value::string(name.to_string()).simple_spanned(Span::unknown())); self } @@ -309,7 +307,7 @@ mod tests { CallInfo { args: EvaluatedArgs::new(Some(self.positionals.clone()), Some(self.flags.clone())), source_map: SourceMap::new(), - name_tag: Tag::unknown_span(self.origin), + name_span: Span::unknown(), } } } diff --git a/src/plugins/sum.rs b/src/plugins/sum.rs index ffb39cb90..32ecd7a9c 100644 --- a/src/plugins/sum.rs +++ b/src/plugins/sum.rs @@ -1,6 +1,6 @@ use nu::{ serve_plugin, CallInfo, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError, Signature, - Tagged, TaggedItem, Value, + Tag, Tagged, Value, }; struct Sum { @@ -18,10 +18,11 @@ impl Sum { match &self.total { Some(Tagged { item: Value::Primitive(Primitive::Int(j)), - tag, + tag: Tag { span, .. }, }) => { //TODO: handle overflow - self.total = Some(Value::int(i + j).tagged(*tag)); + self.total = + Some(Tagged::from_simple_spanned_item(Value::int(i + j), span)); Ok(()) } None => { @@ -37,10 +38,11 @@ impl Sum { match self.total { Some(Tagged { item: Value::Primitive(Primitive::Bytes(j)), - tag, + tag: Tag { span, .. }, }) => { //TODO: handle overflow - self.total = Some(Value::bytes(b + j).tagged(tag)); + self.total = + Some(Tagged::from_simple_spanned_item(Value::bytes(b + j), span)); Ok(()) } None => { diff --git a/src/plugins/sys.rs b/src/plugins/sys.rs index 8030a86b8..db7de6e62 100644 --- a/src/plugins/sys.rs +++ b/src/plugins/sys.rs @@ -315,7 +315,7 @@ impl Plugin for Sys { } fn begin_filter(&mut self, callinfo: CallInfo) -> Result, ShellError> { - Ok(block_on(sysinfo(Tag::unknown_origin(callinfo.name_tag))) + Ok(block_on(sysinfo(Tag::unknown_origin(callinfo.name_span))) .into_iter() .map(ReturnSuccess::value) .collect()) diff --git a/src/prelude.rs b/src/prelude.rs index d58e7989a..a491aff5d 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -62,7 +62,7 @@ pub(crate) use crate::data::{Primitive, Value}; pub(crate) use crate::env::host::handle_unexpected; pub(crate) use crate::env::Host; pub(crate) use crate::errors::{CoerceInto, ShellError}; -pub(crate) use crate::parser::hir::SyntaxShape; +pub(crate) use crate::parser::hir::SyntaxType; pub(crate) use crate::parser::parse::parser::Number; pub(crate) use crate::parser::registry::Signature; pub(crate) use crate::shell::filesystem_shell::FilesystemShell; @@ -70,7 +70,8 @@ pub(crate) use crate::shell::help_shell::HelpShell; pub(crate) use crate::shell::shell_manager::ShellManager; pub(crate) use crate::shell::value_shell::ValueShell; pub(crate) use crate::stream::{InputStream, OutputStream}; -pub(crate) use crate::traits::{HasTag, ToDebug}; +pub(crate) use crate::traits::{HasSpan, ToDebug}; +pub(crate) use crate::Span; pub(crate) use crate::Text; pub(crate) use bigdecimal::BigDecimal; pub(crate) use futures::stream::BoxStream; diff --git a/src/shell/filesystem_shell.rs b/src/shell/filesystem_shell.rs index 1d26fa163..16cbf513f 100644 --- a/src/shell/filesystem_shell.rs +++ b/src/shell/filesystem_shell.rs @@ -81,27 +81,23 @@ impl Shell for FilesystemShell { dirs::home_dir() } - fn ls( - &self, - pattern: Option>, - command_tag: Tag, - ) -> Result { + fn ls(&self, args: EvaluatedWholeStreamCommandArgs) -> Result { let cwd = self.path(); let mut full_path = PathBuf::from(self.path()); - match &pattern { - Some(value) => full_path.push((*value).as_ref()), + match &args.nth(0) { + Some(value) => full_path.push(Path::new(&value.as_path()?)), _ => {} } let entries: Vec<_> = match glob::glob(&full_path.to_string_lossy()) { Ok(files) => files.collect(), Err(_) => { - if let Some(source) = pattern { + if let Some(source) = args.nth(0) { return Err(ShellError::labeled_error( "Invalid pattern", "Invalid pattern", - source.tag(), + source.span(), )); } else { return Err(ShellError::string("Invalid pattern.")); @@ -118,17 +114,17 @@ impl Shell for FilesystemShell { let entries = std::fs::read_dir(&entry); let entries = match entries { Err(e) => { - if let Some(s) = pattern { + if let Some(s) = args.nth(0) { return Err(ShellError::labeled_error( e.to_string(), e.to_string(), - s.tag(), + s.span(), )); } else { return Err(ShellError::labeled_error( e.to_string(), e.to_string(), - command_tag, + args.name_span(), )); } } @@ -142,7 +138,11 @@ impl Shell for FilesystemShell { } else { Path::new(&filepath) }; - let value = dir_entry_dict(filename, &entry.metadata()?, command_tag)?; + let value = dir_entry_dict( + filename, + &entry.metadata()?, + Tag::unknown_origin(args.call_info.name_span), + )?; shell_entries.push_back(ReturnSuccess::value(value)) } return Ok(shell_entries.to_output_stream()); @@ -159,7 +159,11 @@ impl Shell for FilesystemShell { Path::new(&entry) }; let metadata = std::fs::metadata(&entry)?; - let value = dir_entry_dict(filename, &metadata, command_tag)?; + let value = dir_entry_dict( + filename, + &metadata, + Tag::unknown_origin(args.call_info.name_span), + )?; shell_entries.push_back(ReturnSuccess::value(value)) } } @@ -175,7 +179,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( "Can not change to home directory", "can not go to home", - args.call_info.name_tag, + args.call_info.name_span, )) } }, @@ -193,7 +197,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( "Can not change to directory", "directory not found", - v.tag().clone(), + v.span().clone(), )) } } @@ -203,7 +207,8 @@ impl Shell for FilesystemShell { let mut stream = VecDeque::new(); - stream.push_back(ReturnSuccess::change_cwd( + stream.push_back( + ReturnSuccess::change_cwd( path.to_string_lossy().to_string(), )); @@ -217,10 +222,10 @@ impl Shell for FilesystemShell { dst, recursive, }: CopyArgs, - name: Tag, + name: Span, path: &str, ) -> Result { - let name_tag = name; + let name_span = name; let mut source = PathBuf::from(path); let mut destination = PathBuf::from(path); @@ -275,7 +280,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( e.to_string(), e.to_string(), - name_tag, + name_span, )); } Ok(o) => o, @@ -291,7 +296,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( e.to_string(), e.to_string(), - name_tag, + name_span, )); } Ok(o) => o, @@ -327,7 +332,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( e.to_string(), e.to_string(), - name_tag, + name_span, )); } Ok(o) => o, @@ -341,7 +346,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( e.to_string(), e.to_string(), - name_tag, + name_span, )); } Ok(o) => o, @@ -355,7 +360,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( "Copy aborted. Not a valid path", "Copy aborted. Not a valid path", - name_tag, + name_span, )) } } @@ -365,7 +370,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( e.to_string(), e.to_string(), - name_tag, + name_span, )); } Ok(o) => o, @@ -401,7 +406,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( e.to_string(), e.to_string(), - name_tag, + name_span, )); } Ok(o) => o, @@ -415,7 +420,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( e.to_string(), e.to_string(), - name_tag, + name_span, )); } Ok(o) => o, @@ -448,7 +453,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( "Copy aborted. Not a valid path", "Copy aborted. Not a valid path", - name_tag, + name_span, )) } } @@ -475,7 +480,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( "Copy aborted. Not a valid destination", "Copy aborted. Not a valid destination", - name_tag, + name_span, )) } } @@ -484,7 +489,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( format!("Copy aborted. (Does {:?} exist?)", destination_file_name), format!("Copy aborted. (Does {:?} exist?)", destination_file_name), - dst.tag(), + &dst.span(), )); } } @@ -495,7 +500,7 @@ impl Shell for FilesystemShell { fn mkdir( &self, MkdirArgs { rest: directories }: MkdirArgs, - name: Tag, + name: Span, path: &str, ) -> Result { let full_path = PathBuf::from(path); @@ -520,7 +525,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( reason.to_string(), reason.to_string(), - dir.tag(), + dir.span(), )) } Ok(_) => {} @@ -533,10 +538,10 @@ impl Shell for FilesystemShell { fn mv( &self, MoveArgs { src, dst }: MoveArgs, - name: Tag, + name: Span, path: &str, ) -> Result { - let name_tag = name; + let name_span = name; let mut source = PathBuf::from(path); let mut destination = PathBuf::from(path); @@ -562,7 +567,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( "Rename aborted. Not a valid destination", "Rename aborted. Not a valid destination", - dst.tag(), + dst.span(), )) } } @@ -576,7 +581,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( "Rename aborted. Not a valid entry name", "Rename aborted. Not a valid entry name", - name_tag, + name_span, )) } }; @@ -588,7 +593,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( format!("Rename aborted. {:}", e.to_string()), format!("Rename aborted. {:}", e.to_string()), - name_tag, + name_span, )) } }; @@ -612,7 +617,7 @@ impl Shell for FilesystemShell { destination_file_name, e.to_string(), ), - name_tag, + name_span, )); } Ok(o) => o, @@ -635,7 +640,7 @@ impl Shell for FilesystemShell { destination_file_name, e.to_string(), ), - name_tag, + name_span, )); } Ok(o) => o, @@ -657,7 +662,7 @@ impl Shell for FilesystemShell { destination_file_name, e.to_string(), ), - name_tag, + name_span, )); } Ok(o) => o, @@ -710,7 +715,7 @@ impl Shell for FilesystemShell { destination_file_name, e.to_string(), ), - name_tag, + name_span, )); } Ok(o) => o, @@ -734,7 +739,7 @@ impl Shell for FilesystemShell { destination_file_name, e.to_string(), ), - name_tag, + name_span, )); } Ok(o) => o, @@ -757,7 +762,7 @@ impl Shell for FilesystemShell { destination_file_name, e.to_string(), ), - name_tag, + name_span, )); } Ok(o) => o, @@ -789,7 +794,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( "Rename aborted. Not a valid entry name", "Rename aborted. Not a valid entry name", - name_tag, + name_span, )) } }; @@ -813,7 +818,7 @@ impl Shell for FilesystemShell { destination_file_name, e.to_string(), ), - name_tag, + name_span, )); } Ok(o) => o, @@ -825,7 +830,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( format!("Rename aborted. (Does {:?} exist?)", destination_file_name), format!("Rename aborted. (Does {:?} exist?)", destination_file_name), - dst.tag(), + dst.span(), )); } } @@ -836,16 +841,16 @@ impl Shell for FilesystemShell { fn rm( &self, RemoveArgs { target, recursive }: RemoveArgs, - name: Tag, + name: Span, path: &str, ) -> Result { - let name_tag = name; + let name_span = name; if target.item.to_str() == Some(".") || target.item.to_str() == Some("..") { return Err(ShellError::labeled_error( "Remove aborted. \".\" or \"..\" may not be removed.", "Remove aborted. \".\" or \"..\" may not be removed.", - target.tag(), + target.span(), )); } @@ -877,7 +882,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( format!("{:?} is a directory. Try using \"--recursive\".", file), format!("{:?} is a directory. Try using \"--recursive\".", file), - target.tag(), + target.span(), )); } } @@ -894,7 +899,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( "Remove aborted. Not a valid path", "Remove aborted. Not a valid path", - name_tag, + name_span, )) } } @@ -914,7 +919,7 @@ impl Shell for FilesystemShell { "Directory {:?} found somewhere inside. Try using \"--recursive\".", path_file_name ), - target.tag(), + target.span(), )); } @@ -928,7 +933,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( format!("Remove aborted. {:}", e.to_string()), format!("Remove aborted. {:}", e.to_string()), - name_tag, + name_span, )) } } @@ -949,7 +954,7 @@ impl Shell for FilesystemShell { return Err(ShellError::labeled_error( "unable to show current directory", "pwd command failed", - args.call_info.name_tag, + args.call_info.name_span, )); } }; @@ -957,7 +962,7 @@ impl Shell for FilesystemShell { let mut stream = VecDeque::new(); stream.push_back(ReturnSuccess::value( Value::Primitive(Primitive::String(p.to_string_lossy().to_string())) - .tagged(args.call_info.name_tag), + .simple_spanned(args.call_info.name_span), )); Ok(stream.into()) diff --git a/src/shell/help_shell.rs b/src/shell/help_shell.rs index 25f1b9c42..35c939d7d 100644 --- a/src/shell/help_shell.rs +++ b/src/shell/help_shell.rs @@ -126,11 +126,7 @@ impl Shell for HelpShell { self.path = path.clone(); } - fn ls( - &self, - _pattern: Option>, - _command_tag: Tag, - ) -> Result { + fn ls(&self, _args: EvaluatedWholeStreamCommandArgs) -> Result { Ok(self .commands() .map(|x| ReturnSuccess::value(x)) @@ -165,19 +161,24 @@ impl Shell for HelpShell { Ok(stream.into()) } - fn cp(&self, _args: CopyArgs, _name: Tag, _path: &str) -> Result { + fn cp(&self, _args: CopyArgs, _name: Span, _path: &str) -> Result { Ok(OutputStream::empty()) } - fn mv(&self, _args: MoveArgs, _name: Tag, _path: &str) -> Result { + fn mv(&self, _args: MoveArgs, _name: Span, _path: &str) -> Result { Ok(OutputStream::empty()) } - fn mkdir(&self, _args: MkdirArgs, _name: Tag, _path: &str) -> Result { + fn mkdir( + &self, + _args: MkdirArgs, + _name: Span, + _path: &str, + ) -> Result { Ok(OutputStream::empty()) } - fn rm(&self, _args: RemoveArgs, _name: Tag, _path: &str) -> Result { + fn rm(&self, _args: RemoveArgs, _name: Span, _path: &str) -> Result { Ok(OutputStream::empty()) } diff --git a/src/shell/helper.rs b/src/shell/helper.rs index 6fb454435..16802657d 100644 --- a/src/shell/helper.rs +++ b/src/shell/helper.rs @@ -66,7 +66,7 @@ impl Highlighter for Helper { } fn highlight<'l>(&self, line: &'l str, _pos: usize) -> Cow<'l, str> { - let tokens = crate::parser::pipeline(nom_input(line, uuid::Uuid::nil())); + let tokens = crate::parser::pipeline(nom_input(line)); match tokens { Err(_) => Cow::Borrowed(line), @@ -106,47 +106,47 @@ impl Highlighter for Helper { fn paint_token_node(token_node: &TokenNode, line: &str) -> String { let styled = match token_node { - TokenNode::Call(..) => Color::Cyan.bold().paint(token_node.tag().slice(line)), - TokenNode::Whitespace(..) => Color::White.normal().paint(token_node.tag().slice(line)), - TokenNode::Flag(..) => Color::Black.bold().paint(token_node.tag().slice(line)), - TokenNode::Member(..) => Color::Yellow.bold().paint(token_node.tag().slice(line)), - TokenNode::Path(..) => Color::Green.bold().paint(token_node.tag().slice(line)), - TokenNode::Error(..) => Color::Red.bold().paint(token_node.tag().slice(line)), - TokenNode::Delimited(..) => Color::White.paint(token_node.tag().slice(line)), - TokenNode::Operator(..) => Color::White.normal().paint(token_node.tag().slice(line)), - TokenNode::Pipeline(..) => Color::Blue.normal().paint(token_node.tag().slice(line)), + TokenNode::Call(..) => Color::Cyan.bold().paint(token_node.span().slice(line)), + TokenNode::Whitespace(..) => Color::White.normal().paint(token_node.span().slice(line)), + TokenNode::Flag(..) => Color::Black.bold().paint(token_node.span().slice(line)), + TokenNode::Member(..) => Color::Yellow.bold().paint(token_node.span().slice(line)), + TokenNode::Path(..) => Color::Green.bold().paint(token_node.span().slice(line)), + TokenNode::Error(..) => Color::Red.bold().paint(token_node.span().slice(line)), + TokenNode::Delimited(..) => Color::White.paint(token_node.span().slice(line)), + TokenNode::Operator(..) => Color::White.normal().paint(token_node.span().slice(line)), + TokenNode::Pipeline(..) => Color::Blue.normal().paint(token_node.span().slice(line)), TokenNode::Token(Tagged { item: RawToken::Number(..), .. - }) => Color::Purple.bold().paint(token_node.tag().slice(line)), + }) => Color::Purple.bold().paint(token_node.span().slice(line)), TokenNode::Token(Tagged { item: RawToken::Size(..), .. - }) => Color::Purple.bold().paint(token_node.tag().slice(line)), + }) => Color::Purple.bold().paint(token_node.span().slice(line)), TokenNode::Token(Tagged { item: RawToken::GlobPattern, .. - }) => Color::Cyan.normal().paint(token_node.tag().slice(line)), + }) => Color::Cyan.normal().paint(token_node.span().slice(line)), TokenNode::Token(Tagged { item: RawToken::String(..), .. - }) => Color::Green.normal().paint(token_node.tag().slice(line)), + }) => Color::Green.normal().paint(token_node.span().slice(line)), TokenNode::Token(Tagged { item: RawToken::Variable(..), .. - }) => Color::Yellow.bold().paint(token_node.tag().slice(line)), + }) => Color::Yellow.bold().paint(token_node.span().slice(line)), TokenNode::Token(Tagged { item: RawToken::Bare, .. - }) => Color::Green.normal().paint(token_node.tag().slice(line)), + }) => Color::Green.normal().paint(token_node.span().slice(line)), TokenNode::Token(Tagged { item: RawToken::ExternalCommand(..), .. - }) => Color::Cyan.bold().paint(token_node.tag().slice(line)), + }) => Color::Cyan.bold().paint(token_node.span().slice(line)), TokenNode::Token(Tagged { item: RawToken::ExternalWord, .. - }) => Color::Black.bold().paint(token_node.tag().slice(line)), + }) => Color::Black.bold().paint(token_node.span().slice(line)), }; styled.to_string() @@ -166,7 +166,7 @@ fn paint_pipeline_element(pipeline_element: &PipelineElement, line: &str) -> Str styled.push_str( &Color::Cyan .bold() - .paint(pipeline_element.call().head().tag().slice(line)) + .paint(pipeline_element.call().head().span().slice(line)) .to_string(), ); diff --git a/src/shell/shell.rs b/src/shell/shell.rs index c567e474a..549aa79d2 100644 --- a/src/shell/shell.rs +++ b/src/shell/shell.rs @@ -13,16 +13,12 @@ pub trait Shell: std::fmt::Debug { fn name(&self, source_map: &SourceMap) -> String; fn homedir(&self) -> Option; - fn ls( - &self, - pattern: Option>, - command_tag: Tag, - ) -> Result; + fn ls(&self, args: EvaluatedWholeStreamCommandArgs) -> Result; fn cd(&self, args: EvaluatedWholeStreamCommandArgs) -> Result; - fn cp(&self, args: CopyArgs, name: Tag, path: &str) -> Result; - fn mkdir(&self, args: MkdirArgs, name: Tag, path: &str) -> Result; - fn mv(&self, args: MoveArgs, name: Tag, path: &str) -> Result; - fn rm(&self, args: RemoveArgs, name: Tag, path: &str) -> Result; + fn cp(&self, args: CopyArgs, name: Span, path: &str) -> Result; + fn mkdir(&self, args: MkdirArgs, name: Span, path: &str) -> Result; + fn mv(&self, args: MoveArgs, name: Span, path: &str) -> Result; + fn rm(&self, args: RemoveArgs, name: Span, path: &str) -> Result; fn path(&self) -> String; fn pwd(&self, args: EvaluatedWholeStreamCommandArgs) -> Result; fn set_path(&mut self, path: String); diff --git a/src/shell/shell_manager.rs b/src/shell/shell_manager.rs index c4c42367e..53984c950 100644 --- a/src/shell/shell_manager.rs +++ b/src/shell/shell_manager.rs @@ -115,14 +115,10 @@ impl ShellManager { env[self.current_shell].homedir() } - pub fn ls( - &self, - path: Option>, - command_tag: Tag, - ) -> Result { + pub fn ls(&self, args: EvaluatedWholeStreamCommandArgs) -> Result { let env = self.shells.lock().unwrap(); - env[self.current_shell].ls(path, command_tag) + env[self.current_shell].ls(args) } pub fn cd(&self, args: EvaluatedWholeStreamCommandArgs) -> Result { diff --git a/src/shell/value_shell.rs b/src/shell/value_shell.rs index 175e232e7..010c7ae08 100644 --- a/src/shell/value_shell.rs +++ b/src/shell/value_shell.rs @@ -87,15 +87,13 @@ impl Shell for ValueShell { Some(PathBuf::from("/")) } - fn ls( - &self, - target: Option>, - command_name: Tag, - ) -> Result { + fn ls(&self, args: EvaluatedWholeStreamCommandArgs) -> Result { let mut full_path = PathBuf::from(self.path()); - match &target { - Some(value) => full_path.push(value.as_ref()), + let target = args.nth(0); + + match target { + Some(value) => full_path.push(Path::new(&value.as_path()?)), _ => {} } @@ -103,18 +101,18 @@ impl Shell for ValueShell { value_system.walk_decorate(&self.value)?; if !value_system.exists(&full_path) { - if let Some(target) = &target { + if let Some(target) = target { return Err(ShellError::labeled_error( "Can not list entries inside", "No such path exists", - target.tag(), + target.span(), )); } return Err(ShellError::labeled_error( "Can not list entries inside", "No such path exists", - command_name, + args.call_info.name_span, )); } @@ -159,14 +157,14 @@ impl Shell for ValueShell { return Err(ShellError::labeled_error( "Can not change to path inside", "No such path exists", - destination.tag(), + destination.span(), )); } return Err(ShellError::labeled_error( "Can not change to path inside", "No such path exists", - args.call_info.name_tag, + args.call_info.name_span, )); } @@ -175,7 +173,7 @@ impl Shell for ValueShell { Ok(stream.into()) } - fn cp(&self, _args: CopyArgs, name: Tag, _path: &str) -> Result { + fn cp(&self, _args: CopyArgs, name: Span, _path: &str) -> Result { Err(ShellError::labeled_error( "cp not currently supported on values", "not currently supported", @@ -183,7 +181,7 @@ impl Shell for ValueShell { )) } - fn mv(&self, _args: MoveArgs, name: Tag, _path: &str) -> Result { + fn mv(&self, _args: MoveArgs, name: Span, _path: &str) -> Result { Err(ShellError::labeled_error( "mv not currently supported on values", "not currently supported", @@ -191,7 +189,7 @@ impl Shell for ValueShell { )) } - fn mkdir(&self, _args: MkdirArgs, name: Tag, _path: &str) -> Result { + fn mkdir(&self, _args: MkdirArgs, name: Span, _path: &str) -> Result { Err(ShellError::labeled_error( "mkdir not currently supported on values", "not currently supported", @@ -199,7 +197,7 @@ impl Shell for ValueShell { )) } - fn rm(&self, _args: RemoveArgs, name: Tag, _path: &str) -> Result { + fn rm(&self, _args: RemoveArgs, name: Span, _path: &str) -> Result { Err(ShellError::labeled_error( "rm not currently supported on values", "not currently supported", @@ -215,7 +213,7 @@ impl Shell for ValueShell { let mut stream = VecDeque::new(); stream.push_back(ReturnSuccess::value(Tagged::from_item( Value::string(self.path()), - args.call_info.name_tag, + args.call_info.name_span, ))); Ok(stream.into()) } diff --git a/src/traits.rs b/src/traits.rs index 677d019ad..5b022c444 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -12,8 +12,8 @@ impl fmt::Display for Debuggable<'_, T> { } } -pub trait HasTag { - fn tag(&self) -> Tag; +pub trait HasSpan { + fn span(&self) -> Span; } pub trait ToDebug: Sized {