diff --git a/crates/nu-parser/src/lite_parse.rs b/crates/nu-parser/src/lite_parse.rs index 58145d8844..ab166be3fb 100644 --- a/crates/nu-parser/src/lite_parse.rs +++ b/crates/nu-parser/src/lite_parse.rs @@ -35,11 +35,43 @@ pub struct LitePipeline { pub commands: Vec, } +impl LitePipeline { + pub(crate) fn span(&self) -> Span { + let start = if !self.commands.is_empty() { + self.commands[0].name.span.start() + } else { + 0 + }; + + if let Some((last, _)) = self.commands[..].split_last() { + Span::new(start, last.span().end()) + } else { + Span::new(start, 0) + } + } +} + #[derive(Debug, Clone)] pub struct LiteBlock { pub block: Vec, } +impl LiteBlock { + pub(crate) fn span(&self) -> Span { + let start = if !self.block.is_empty() { + self.block[0].span().start() + } else { + 0 + }; + + if let Some((last, _)) = self.block[..].split_last() { + Span::new(start, last.span().end()) + } else { + Span::new(start, 0) + } + } +} + impl From> for LiteCommand { fn from(v: Spanned) -> LiteCommand { LiteCommand::new(v) @@ -277,6 +309,10 @@ pub fn lite_parse(src: &str, span_offset: usize) -> ParseResult { mod tests { use super::*; + fn span(left: usize, right: usize) -> Span { + Span::new(left, right) + } + mod bare { use super::*; @@ -287,8 +323,7 @@ mod tests { let input = &mut input.char_indices().peekable(); let result = bare(input, 0).unwrap(); - assert_eq!(result.span.start(), 0); - assert_eq!(result.span.end(), 3); + assert_eq!(result.span, span(0, 3)); } #[test] @@ -298,8 +333,7 @@ mod tests { let input = &mut input.char_indices().peekable(); let result = bare(input, 0).unwrap(); - assert_eq!(result.span.start(), 0); - assert_eq!(result.span.end(), 9); + assert_eq!(result.span, span(0, 9)); } #[test] @@ -309,8 +343,7 @@ mod tests { let input = &mut input.char_indices().peekable(); let result = bare(input, 0).unwrap(); - assert_eq!(result.span.start(), 0); - assert_eq!(result.span.end(), 10); + assert_eq!(result.span, span(0, 10)); } #[test] @@ -320,8 +353,7 @@ mod tests { let input = &mut input.char_indices().peekable(); let result = bare(input, 0).unwrap(); - assert_eq!(result.span.start(), 0); - assert_eq!(result.span.end(), 9); + assert_eq!(result.span, span(0, 9)); } #[test] @@ -331,8 +363,7 @@ mod tests { let input = &mut input.char_indices().peekable(); let result = bare(input, 0).unwrap(); - assert_eq!(result.span.start(), 0); - assert_eq!(result.span.end(), 9); + assert_eq!(result.span, span(0, 9)); } #[test] @@ -342,8 +373,7 @@ mod tests { let input = &mut input.char_indices().peekable(); let result = bare(input, 0).unwrap(); - assert_eq!(result.span.start(), 0); - assert_eq!(result.span.end(), 5); + assert_eq!(result.span, span(0, 5)); } #[test] @@ -353,8 +383,7 @@ mod tests { let input = &mut input.char_indices().peekable(); let result = bare(input, 0).unwrap(); - assert_eq!(result.span.start(), 0); - assert_eq!(result.span.end(), 2); + assert_eq!(result.span, span(0, 2)); } #[test] @@ -364,8 +393,7 @@ mod tests { let input = &mut input.char_indices().peekable(); let result = bare(input, 0).unwrap(); - assert_eq!(result.span.start(), 1); - assert_eq!(result.span.end(), 3); + assert_eq!(result.span, span(1, 3)); } #[test] @@ -375,8 +403,17 @@ mod tests { let input = &mut input.char_indices().peekable(); let result = bare(input, 0).unwrap(); - assert_eq!(result.span.start(), 1); - assert_eq!(result.span.end(), 6); + assert_eq!(result.span, span(1, 6)); + } + + #[test] + fn simple_10() { + let input = "[foo, bar]"; + + let input = &mut input.char_indices().peekable(); + let result = bare(input, 0).unwrap(); + + assert_eq!(result.span, span(0, 10)); } #[test] @@ -386,8 +423,7 @@ mod tests { let input = &mut input.char_indices().peekable(); let result = bare(input, 0).unwrap(); - assert_eq!(result.span.start(), 0); - assert_eq!(result.span.end(), 3); + assert_eq!(result.span, span(0, 3)); } #[test] @@ -424,13 +460,20 @@ mod tests { mod lite_parse { use super::*; + #[test] + fn pipeline() { + let result = lite_parse("cmd1 | cmd2 ; deploy", 0).unwrap(); + assert_eq!(result.span(), span(0, 20)); + assert_eq!(result.block[0].span(), span(0, 11)); + assert_eq!(result.block[1].span(), span(14, 20)); + } + #[test] fn simple_1() { let result = lite_parse("foo", 0).unwrap(); assert_eq!(result.block.len(), 1); assert_eq!(result.block[0].commands.len(), 1); - assert_eq!(result.block[0].commands[0].name.span.start(), 0); - assert_eq!(result.block[0].commands[0].name.span.end(), 3); + assert_eq!(result.block[0].commands[0].name.span, span(0, 3)); } #[test] @@ -438,8 +481,7 @@ mod tests { let result = lite_parse("foo", 10).unwrap(); assert_eq!(result.block.len(), 1); assert_eq!(result.block[0].commands.len(), 1); - assert_eq!(result.block[0].commands[0].name.span.start(), 10); - assert_eq!(result.block[0].commands[0].name.span.end(), 13); + assert_eq!(result.block[0].commands[0].name.span, span(10, 13)); } #[test] diff --git a/crates/nu-parser/src/parse.rs b/crates/nu-parser/src/parse.rs index fbd18d6da7..b9004e5552 100644 --- a/crates/nu-parser/src/parse.rs +++ b/crates/nu-parser/src/parse.rs @@ -1318,8 +1318,7 @@ fn classify_pipeline( lite_pipeline: &LitePipeline, registry: &dyn SignatureRegistry, ) -> (ClassifiedPipeline, Option) { - // FIXME: fake span - let mut commands = Commands::new(Span::new(0, 0)); + let mut commands = Commands::new(lite_pipeline.span()); let mut error = None; let mut iter = lite_pipeline.commands.iter().peekable(); @@ -1524,8 +1523,7 @@ fn expand_shorthand_forms( } pub fn classify_block(lite_block: &LiteBlock, registry: &dyn SignatureRegistry) -> ClassifiedBlock { - // FIXME: fake span - let mut block = Block::new(Span::new(0, 0)); + let mut block = Block::new(lite_block.span()); let mut error = None; for lite_pipeline in &lite_block.block {