diff --git a/crates/nu-engine/src/scope.rs b/crates/nu-engine/src/scope.rs index 913ff22ec9ff..02837f7e6a50 100644 --- a/crates/nu-engine/src/scope.rs +++ b/crates/nu-engine/src/scope.rs @@ -1,4 +1,5 @@ use nu_protocol::{ + ast::Expr, engine::{Command, EngineState, Stack, Visibility}, ModuleId, Signature, Span, SyntaxShape, Type, Value, }; @@ -52,7 +53,9 @@ impl<'e, 's> ScopeData<'e, 's> { for (var_name, var_id) in &self.vars_map { let var_name = Value::string(String::from_utf8_lossy(var_name).to_string(), span); - let var_type = Value::string(self.engine_state.get_var(**var_id).ty.to_string(), span); + let var = self.engine_state.get_var(**var_id); + let var_type = Value::string(var.ty.to_string(), span); + let is_const = Value::bool(var.const_val.is_some(), span); let var_value = if let Ok(val) = self.stack.get_var(**var_id, span) { val @@ -67,9 +70,10 @@ impl<'e, 's> ScopeData<'e, 's> { "name".to_string(), "type".to_string(), "value".to_string(), + "is_const".to_string(), "var_id".to_string(), ], - vals: vec![var_name, var_type, var_value, var_id_val], + vals: vec![var_name, var_type, var_value, is_const, var_id_val], span, }) } @@ -472,12 +476,20 @@ impl<'e, 's> ScopeData<'e, 's> { if self.visibility.is_decl_id_visible(&decl_id) { let decl = self.engine_state.get_decl(decl_id); if let Some(alias) = decl.as_alias() { + let aliased_decl_id = if let Expr::Call(wrapped_call) = &alias.wrapped_call.expr + { + Value::int(wrapped_call.decl_id as i64, span) + } else { + Value::nothing(span) + }; + aliases.push(Value::Record { cols: vec![ "name".into(), "expansion".into(), "usage".into(), "decl_id".into(), + "aliased_decl_id".into(), ], vals: vec![ Value::String { @@ -499,6 +511,7 @@ impl<'e, 's> ScopeData<'e, 's> { val: decl_id as i64, span, }, + aliased_decl_id, ], span, }); diff --git a/tests/scope/mod.rs b/tests/scope/mod.rs index c6019489b1c7..843b9fde1edd 100644 --- a/tests/scope/mod.rs +++ b/tests/scope/mod.rs @@ -211,9 +211,26 @@ fn correct_scope_aliases_fields() { ]; let actual = nu!(cwd: dirs.test(), &inp.join("; ")); assert_eq!(actual.out, "false"); + + let inp = &[ + "use spam.nu", + "scope aliases | where name == 'spam xaz' | get 0.aliased_decl_id | is-empty", + ]; + let actual = nu!(cwd: dirs.test(), &inp.join("; ")); + assert_eq!(actual.out, "false"); }) } +#[test] +fn scope_alias_aliased_decl_id_external() { + let inp = &[ + "alias c = cargo", + "scope aliases | where name == c | get 0.aliased_decl_id | is-empty", + ]; + let actual = nu!(&inp.join("; ")); + assert_eq!(actual.out, "true"); +} + #[test] fn correct_scope_externs_fields() { let module_setup = r#" @@ -266,3 +283,41 @@ fn scope_externs_sorted() { let actual = nu!(&inp.join("; ")); assert_eq!(actual.out, "abc"); } + +#[test] +fn correct_scope_variables_fields() { + let inp = &[ + "let x = 'x'", + "scope variables | where name == '$x' | get 0.type", + ]; + let actual = nu!(&inp.join("; ")); + assert_eq!(actual.out, "string"); + + let inp = &[ + "let x = 'x'", + "scope variables | where name == '$x' | get 0.value", + ]; + let actual = nu!(&inp.join("; ")); + assert_eq!(actual.out, "x"); + + let inp = &[ + "let x = 'x'", + "scope variables | where name == '$x' | get 0.is_const", + ]; + let actual = nu!(&inp.join("; ")); + assert_eq!(actual.out, "false"); + + let inp = &[ + "const x = 'x'", + "scope variables | where name == '$x' | get 0.is_const", + ]; + let actual = nu!(&inp.join("; ")); + assert_eq!(actual.out, "true"); + + let inp = &[ + "let x = 'x'", + "scope variables | where name == '$x' | get 0.var_id | is-empty", + ]; + let actual = nu!(&inp.join("; ")); + assert_eq!(actual.out, "false"); +}