From cf85bf9be309f29564cfb474b6211c11484796ba Mon Sep 17 00:00:00 2001 From: Fabian Homborg Date: Thu, 10 Mar 2022 18:26:45 +0100 Subject: [PATCH] Let function-scoped variables be queried This uses the same logic we use to create the variables to find them - go through the scopes, the topmost local scope *is* function-scope. Fixes #8684 --- src/env.cpp | 20 ++++++++++++++++++++ tests/checks/set.fish | 23 +++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/src/env.cpp b/src/env.cpp index ce586e3d2..49fc2c75a 100644 --- a/src/env.cpp +++ b/src/env.cpp @@ -600,6 +600,7 @@ class env_scoped_impl_t : public environment_t, noncopyable_t { // query. maybe_t try_get_computed(const wcstring &key) const; maybe_t try_get_local(const wcstring &key) const; + maybe_t try_get_function(const wcstring &key) const; maybe_t try_get_global(const wcstring &key) const; maybe_t try_get_universal(const wcstring &key) const; @@ -772,6 +773,22 @@ maybe_t env_scoped_impl_t::try_get_local(const wcstring &key) const { return entry; // this is either the entry or none() from find_entry } +maybe_t env_scoped_impl_t::try_get_function(const wcstring &key) const { + maybe_t entry; + auto node = locals_; + while (node->next) { + node = node->next; + // The first node that introduces a new scope is ours. + // If this doesn't happen, we go on until we've reached the + // topmost local scope. + if (node->new_scope) break; + } + for (auto cur = node; cur; cur=cur->next) { + if ((entry = cur->find_entry(key))) break; + } + return entry; // this is either the entry or none() from find_entry +} + maybe_t env_scoped_impl_t::try_get_global(const wcstring &key) const { return globals_->find_entry(key); } @@ -792,6 +809,9 @@ maybe_t env_scoped_impl_t::get(const wcstring &key, env_mode_flags_t if (!result && query.local) { result = try_get_local(key); } + if (!result && query.function) { + result = try_get_function(key); + } if (!result && query.global) { result = try_get_global(key); } diff --git a/tests/checks/set.fish b/tests/checks/set.fish index 31f82b3d5..65cb9b1f5 100644 --- a/tests/checks/set.fish +++ b/tests/checks/set.fish @@ -868,6 +868,29 @@ end erase-funcvar +set -f foo +set -l banana +set -g global +begin + set -qf foo + and echo foo is function scoped + # CHECK: foo is function scoped + + set -l localvar414 + set -qf localvar414 + or echo localvar414 is not function scoped + # CHECK: localvar414 is not function scoped + + set -qf banana + and echo banana is function scoped + # CHECK: banana is function scoped + + set -l global + set -qf global + or echo global is not function scoped + # CHECK: global is not function scoped +end + set --query $this_is_not_set echo $status # CHECK: 255