Add Span merging functions (#12511)

# Description
This PR adds a few functions to `Span` for merging spans together:
- `Span::append`: merges two spans that are known to be in order.
- `Span::concat`: returns a span that encompasses all the spans in a
slice. The spans must be in order.
- `Span::merge`: merges two spans (no order necessary).
- `Span::merge_many`: merges an iterator of spans into a single span (no
order necessary).

These are meant to replace the free-standing `nu_protocol::span`
function.

The spans in a `LiteCommand` (the `parts`) should always be in order
based on the lite parser and lexer. So, the parser code sees the most
usage of `Span::append` and `Span::concat` where the order is known. In
other code areas, `Span::merge` and `Span::merge_many` are used since
the order between spans is often not known.
This commit is contained in:
Ian Manske
2024-05-16 22:34:49 +00:00
committed by GitHub
parent 2a09dccc11
commit aec41f3df0
15 changed files with 305 additions and 241 deletions

View File

@ -1,6 +1,6 @@
use serde::{Deserialize, Serialize};
use crate::{span, ModuleId, Span, VarId};
use crate::{ModuleId, Span, VarId};
use std::collections::HashSet;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
@ -12,17 +12,22 @@ pub enum ImportPatternMember {
impl ImportPatternMember {
pub fn span(&self) -> Span {
let mut spans = vec![];
match self {
ImportPatternMember::Glob { span } => spans.push(*span),
ImportPatternMember::Name { name: _, span } => spans.push(*span),
ImportPatternMember::Glob { span } | ImportPatternMember::Name { span, .. } => *span,
ImportPatternMember::List { names } => {
for (_, span) in names {
spans.push(*span);
}
let first = names
.first()
.map(|&(_, span)| span)
.unwrap_or(Span::unknown());
let last = names
.last()
.map(|&(_, span)| span)
.unwrap_or(Span::unknown());
Span::append(first, last)
}
}
span(&spans)
}
}
@ -59,13 +64,13 @@ impl ImportPattern {
}
pub fn span(&self) -> Span {
let mut spans = vec![self.head.span];
for member in &self.members {
spans.push(member.span());
}
span(&spans)
Span::append(
self.head.span,
self.members
.last()
.map(ImportPatternMember::span)
.unwrap_or(self.head.span),
)
}
pub fn with_hidden(self, hidden: HashSet<Vec<u8>>) -> Self {