mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 08:06:03 +02:00
Hide alias (#4432)
* Add alias interning Now, AliasId is used to reference aliases stored in EngineState, similar to decls, blocks, etc. * Fix wrong message * Fix using decl instead of alias * Extend also alias id visibility * Merge also aliases from delta * Add alias hiding code Does not work yet but passes tests at least. * Fix wrong alias lookup and visibility appending * Add hide alias tests * Fmt & Clippy * Fix random clippy warnings in "which" command
This commit is contained in:
@ -1320,14 +1320,21 @@ pub fn parse_hide(
|
||||
if let Some(overlay_id) = working_set.find_overlay(&import_pattern.head.name) {
|
||||
(true, working_set.get_overlay(overlay_id).clone())
|
||||
} else if import_pattern.members.is_empty() {
|
||||
// The pattern head can be e.g. a function name, not just a module
|
||||
if let Some(id) = working_set.find_decl(&import_pattern.head.name) {
|
||||
// The pattern head can be:
|
||||
if let Some(id) = working_set.find_alias(&import_pattern.head.name) {
|
||||
// an alias,
|
||||
let mut overlay = Overlay::new();
|
||||
overlay.add_alias(&import_pattern.head.name, id);
|
||||
|
||||
(false, overlay)
|
||||
} else if let Some(id) = working_set.find_decl(&import_pattern.head.name) {
|
||||
// a custom command,
|
||||
let mut overlay = Overlay::new();
|
||||
overlay.add_decl(&import_pattern.head.name, id);
|
||||
|
||||
(false, overlay)
|
||||
} else {
|
||||
// Or it could be an env var
|
||||
// , or it could be an env var (handled by the engine)
|
||||
(false, Overlay::new())
|
||||
}
|
||||
} else {
|
||||
@ -1338,49 +1345,71 @@ pub fn parse_hide(
|
||||
};
|
||||
|
||||
// This kind of inverts the import pattern matching found in parse_use()
|
||||
let decls_to_hide = if import_pattern.members.is_empty() {
|
||||
let (aliases_to_hide, decls_to_hide) = if import_pattern.members.is_empty() {
|
||||
if is_module {
|
||||
overlay.decls_with_head(&import_pattern.head.name)
|
||||
(
|
||||
overlay.alias_names_with_head(&import_pattern.head.name),
|
||||
overlay.decl_names_with_head(&import_pattern.head.name),
|
||||
)
|
||||
} else {
|
||||
overlay.decls()
|
||||
(overlay.alias_names(), overlay.decl_names())
|
||||
}
|
||||
} else {
|
||||
match &import_pattern.members[0] {
|
||||
ImportPatternMember::Glob { .. } => overlay.decls(),
|
||||
ImportPatternMember::Glob { .. } => (overlay.alias_names(), overlay.decl_names()),
|
||||
ImportPatternMember::Name { name, span } => {
|
||||
let mut output = vec![];
|
||||
let mut aliases = vec![];
|
||||
let mut decls = vec![];
|
||||
|
||||
if let Some(item) = overlay.decl_with_head(name, &import_pattern.head.name) {
|
||||
output.push(item);
|
||||
if let Some(item) =
|
||||
overlay.alias_name_with_head(name, &import_pattern.head.name)
|
||||
{
|
||||
aliases.push(item);
|
||||
} else if let Some(item) =
|
||||
overlay.decl_name_with_head(name, &import_pattern.head.name)
|
||||
{
|
||||
decls.push(item);
|
||||
} else if !overlay.has_env_var(name) {
|
||||
error = error.or(Some(ParseError::ExportNotFound(*span)));
|
||||
}
|
||||
|
||||
output
|
||||
(aliases, decls)
|
||||
}
|
||||
ImportPatternMember::List { names } => {
|
||||
let mut output = vec![];
|
||||
let mut aliases = vec![];
|
||||
let mut decls = vec![];
|
||||
|
||||
for (name, span) in names {
|
||||
if let Some(item) = overlay.decl_with_head(name, &import_pattern.head.name)
|
||||
if let Some(item) =
|
||||
overlay.alias_name_with_head(name, &import_pattern.head.name)
|
||||
{
|
||||
output.push(item);
|
||||
aliases.push(item);
|
||||
} else if let Some(item) =
|
||||
overlay.decl_name_with_head(name, &import_pattern.head.name)
|
||||
{
|
||||
decls.push(item);
|
||||
} else if !overlay.has_env_var(name) {
|
||||
error = error.or(Some(ParseError::ExportNotFound(*span)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
output
|
||||
(aliases, decls)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let import_pattern = {
|
||||
let aliases: HashSet<Vec<u8>> = aliases_to_hide.iter().cloned().collect();
|
||||
let decls: HashSet<Vec<u8>> = decls_to_hide.iter().cloned().collect();
|
||||
|
||||
import_pattern.with_hidden(decls.union(&aliases).cloned().collect())
|
||||
};
|
||||
|
||||
// TODO: `use spam; use spam foo; hide foo` will hide both `foo` and `spam foo` since
|
||||
// they point to the same DeclId. Do we want to keep it that way?
|
||||
working_set.hide_decls(&decls_to_hide);
|
||||
let import_pattern = import_pattern
|
||||
.with_hidden(decls_to_hide.iter().map(|(name, _)| name.clone()).collect());
|
||||
working_set.hide_aliases(&aliases_to_hide);
|
||||
|
||||
// Create a new Use command call to pass the new import pattern
|
||||
let import_pattern_expr = Expression {
|
||||
|
@ -828,9 +828,11 @@ pub fn parse_call(
|
||||
|
||||
if expand_aliases {
|
||||
// If the word is an alias, expand it and re-parse the expression
|
||||
if let Some(expansion) = working_set.find_alias(&name) {
|
||||
if let Some(alias_id) = working_set.find_alias(&name) {
|
||||
trace!("expanding alias");
|
||||
|
||||
let expansion = working_set.get_alias(alias_id);
|
||||
|
||||
let orig_span = spans[pos];
|
||||
let mut new_spans: Vec<Span> = vec![];
|
||||
new_spans.extend(&spans[0..pos]);
|
||||
|
Reference in New Issue
Block a user