Fix command name lookup for known externals (#7830)

Fixes https://github.com/nushell/nushell/issues/7822
This commit is contained in:
Jakub Žádník 2023-01-22 21:40:18 +02:00 committed by GitHub
parent 3552d03f6c
commit ba12b0de0d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 1 deletions

View File

@ -51,7 +51,15 @@ impl Command for KnownExternal {
let mut extern_call = Call::new(head_span);
let extern_name = engine_state.get_decl(call.decl_id).name();
let extern_name = if let Some(name_bytes) = engine_state.find_decl_name(call.decl_id, &[]) {
String::from_utf8_lossy(name_bytes)
} else {
return Err(ShellError::NushellFailedSpanned(
"known external name not found".to_string(),
"could not find name for this command".to_string(),
call.head,
));
};
let extern_name: Vec<_> = extern_name.split(' ').collect();

View File

@ -585,6 +585,24 @@ impl EngineState {
None
}
pub fn find_decl_name(&self, decl_id: DeclId, removed_overlays: &[Vec<u8>]) -> Option<&[u8]> {
let mut visibility: Visibility = Visibility::new();
for overlay_frame in self.active_overlays(removed_overlays).iter().rev() {
visibility.append(&overlay_frame.visibility);
if visibility.is_decl_id_visible(&decl_id) {
for ((name, _), id) in overlay_frame.decls.iter() {
if id == &decl_id {
return Some(name);
}
}
}
}
None
}
pub fn find_alias(&self, name: &[u8], removed_overlays: &[Vec<u8>]) -> Option<AliasId> {
let mut visibility: Visibility = Visibility::new();

View File

@ -76,3 +76,34 @@ fn known_external_misc_values() -> TestResult {
"abc a b c",
)
}
/// GitHub issue #7822
#[test]
fn known_external_subcommand_from_module() -> TestResult {
run_test_contains(
r#"
module cargo {
export extern check []
};
use cargo;
cargo check -h
"#,
"cargo check",
)
}
/// GitHub issue #7822
#[test]
fn known_external_aliased_subcommand_from_module() -> TestResult {
run_test_contains(
r#"
module cargo {
export extern check []
};
use cargo;
alias cc = cargo check;
cc -h
"#,
"cargo check",
)
}