mirror of
https://github.com/nushell/nushell
synced 2024-12-26 04:53:09 +00:00
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
This commit is contained in:
parent
2ffe30ecf0
commit
fb3350ebc3
4 changed files with 47 additions and 13 deletions
|
@ -296,3 +296,18 @@ fn use_main_not_exported() {
|
|||
|
||||
assert!(actual.err.contains("external_command"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn use_sub_subname_error_if_not_from_submodule() {
|
||||
let inp = r#"module spam { export def foo [] {}; export def bar [] {} }; use spam foo bar"#;
|
||||
let actual = nu!(inp);
|
||||
assert!(actual.err.contains("try `use <module> [<name1>, <name2>]`"))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_use_sub_subname_from_submodule() {
|
||||
let inp =
|
||||
r#"module spam { export module foo { export def bar [] {"bar"} } }; use spam foo bar; bar"#;
|
||||
let actual = nu!(inp);
|
||||
assert_eq!(actual.out, "bar")
|
||||
}
|
||||
|
|
|
@ -10,6 +10,22 @@ pub enum ImportPatternMember {
|
|||
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>,
|
||||
|
@ -46,15 +62,7 @@ impl ImportPattern {
|
|||
let mut spans = vec![self.head.span];
|
||||
|
||||
for member in &self.members {
|
||||
match member {
|
||||
ImportPatternMember::Glob { span } => spans.push(*span),
|
||||
ImportPatternMember::Name { name: _, span } => spans.push(*span),
|
||||
ImportPatternMember::List { names } => {
|
||||
for (_, span) in names {
|
||||
spans.push(*span);
|
||||
}
|
||||
}
|
||||
}
|
||||
spans.push(member.span());
|
||||
}
|
||||
|
||||
span(&spans)
|
||||
|
|
|
@ -157,6 +157,17 @@ impl Module {
|
|||
|
||||
match head {
|
||||
ImportPatternMember::Name { name, span } => {
|
||||
// raise errors if user wants to do something like this:
|
||||
// `use a b c`: but b is not a sub-module of a.
|
||||
let errors = if !rest.is_empty() && self.submodules.get(name).is_none() {
|
||||
vec![ParseError::WrongImportPattern(
|
||||
format!("Trying to import something but the parent `{}` is not a module, maybe you want to try `use <module> [<name1>, <name2>]`", String::from_utf8_lossy(name)),
|
||||
rest[0].span(),
|
||||
)]
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
|
||||
if name == b"main" {
|
||||
if let Some(main_decl_id) = self.main {
|
||||
(
|
||||
|
@ -165,7 +176,7 @@ impl Module {
|
|||
vec![],
|
||||
vec![],
|
||||
),
|
||||
vec![],
|
||||
errors,
|
||||
)
|
||||
} else {
|
||||
(
|
||||
|
@ -176,7 +187,7 @@ impl Module {
|
|||
} else if let Some(decl_id) = self.decls.get(name) {
|
||||
(
|
||||
ResolvedImportPattern::new(vec![(name.clone(), *decl_id)], vec![], vec![]),
|
||||
vec![],
|
||||
errors,
|
||||
)
|
||||
} else if let Some(var_id) = self.constants.get(name) {
|
||||
match working_set.get_constant(*var_id) {
|
||||
|
@ -186,7 +197,7 @@ impl Module {
|
|||
vec![],
|
||||
vec![(name.clone(), const_val.clone())],
|
||||
),
|
||||
vec![],
|
||||
errors,
|
||||
),
|
||||
Err(err) => (
|
||||
ResolvedImportPattern::new(vec![], vec![], vec![]),
|
||||
|
|
|
@ -425,7 +425,7 @@ pub enum ParseError {
|
|||
MissingImportPattern(#[label = "needs an import pattern"] Span),
|
||||
|
||||
#[error("Wrong import pattern structure.")]
|
||||
#[diagnostic(code(nu::parser::missing_import_pattern))]
|
||||
#[diagnostic(code(nu::parser::wrong_import_pattern))]
|
||||
WrongImportPattern(String, #[label = "{0}"] Span),
|
||||
|
||||
#[error("Export not found.")]
|
||||
|
|
Loading…
Reference in a new issue