nushell/crates/nu-protocol/src/ast/import_pattern.rs
Ian Manske aec41f3df0
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.
2024-05-16 22:34:49 +00:00

91 lines
2.4 KiB
Rust

use serde::{Deserialize, Serialize};
use crate::{ModuleId, Span, VarId};
use std::collections::HashSet;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum ImportPatternMember {
Glob { span: Span },
Name { name: Vec<u8>, span: Span },
List { names: Vec<(Vec<u8>, Span)> },
}
impl ImportPatternMember {
pub fn span(&self) -> Span {
match self {
ImportPatternMember::Glob { span } | ImportPatternMember::Name { span, .. } => *span,
ImportPatternMember::List { names } => {
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)
}
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ImportPatternHead {
pub name: Vec<u8>,
pub id: Option<ModuleId>,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ImportPattern {
pub head: ImportPatternHead,
pub members: Vec<ImportPatternMember>,
// communicate to eval which decls/aliases were hidden during `parse_hide()` so it does not
// interpret these as env var names:
pub hidden: HashSet<Vec<u8>>,
// information for the eval which const values to put into stack as variables
pub constants: Vec<VarId>,
}
impl ImportPattern {
pub fn new() -> Self {
ImportPattern {
head: ImportPatternHead {
name: vec![],
id: None,
span: Span::unknown(),
},
members: vec![],
hidden: HashSet::new(),
constants: vec![],
}
}
pub fn span(&self) -> Span {
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 {
ImportPattern {
head: self.head,
members: self.members,
hidden,
constants: self.constants,
}
}
}
impl Default for ImportPattern {
fn default() -> Self {
Self::new()
}
}