nushell/crates/nu-protocol/src/ast/import_pattern.rs
WindSoilder fb3350ebc3
Error on use path item1 item2, if item1 is not a module (#11183)
# Description
Fixes: #11143

# User-Facing Changes
Take the following as example:
```nushell
module foo { export def bar [] {}; export def baz [] {} }
```

`use foo bar baz` will be error:
```
❯ use foo c d
Error: nu::parser::wrong_import_pattern

  × Wrong import pattern structure.
   ╭─[entry #2:1:1]
 1 │ use foo c d
   ·           ┬
   ·           ╰── Trying to import something but the parent `c` is not a module, maybe you want to try `use <module> [<name1>, <name2>]`
   ╰────
```

# Tests + Formatting
Done
2023-12-05 11:38:45 +01:00

86 lines
2.2 KiB
Rust

use serde::{Deserialize, Serialize};
use crate::{span, 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 {
let mut spans = vec![];
match self {
ImportPatternMember::Glob { span } => spans.push(*span),
ImportPatternMember::Name { name: _, span } => spans.push(*span),
ImportPatternMember::List { names } => {
for (_, span) in names {
spans.push(*span);
}
}
}
span(&spans)
}
}
#[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 {
let mut spans = vec![self.head.span];
for member in &self.members {
spans.push(member.span());
}
span(&spans)
}
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()
}
}