Migrate function getters to use function_get_properties

This replaces some of the teensy function getters with the function
that just returns a shared_ptr to the properties struct.
This commit is contained in:
ridiculousfish 2018-02-11 17:21:24 -08:00
parent db33ed0fc7
commit 976514597d
4 changed files with 46 additions and 52 deletions

View file

@ -134,12 +134,13 @@ static wcstring functions_def(const wcstring &name) {
out.append(esc_desc);
}
if (!function_get_shadow_scope(name)) {
auto props = function_get_properties(name);
assert(props && "Should have function properties");
if (!props->shadow_scope) {
out.append(L" --no-scope-shadowing");
}
for (size_t i = 0; i < ev.size(); i++) {
const event_t *next = ev.at(i).get();
for (const auto &next : ev) {
switch (next->type) {
case EVENT_SIGNAL: {
append_format(out, L" --on-signal %ls", sig2wcs(next->param1.signal));
@ -172,11 +173,11 @@ static wcstring functions_def(const wcstring &name) {
}
}
wcstring_list_t named = function_get_named_arguments(name);
const wcstring_list_t &named = props->named_arguments;
if (!named.empty()) {
append_format(out, L" --argument");
for (size_t i = 0; i < named.size(); i++) {
append_format(out, L" %ls", named.at(i).c_str());
for (const auto &name : named) {
append_format(out, L" %ls", name.c_str());
}
}
@ -188,17 +189,14 @@ static wcstring functions_def(const wcstring &name) {
// Output any inherited variables as `set -l` lines.
std::map<wcstring, env_var_t> inherit_vars = function_get_inherit_vars(name);
for (std::map<wcstring, env_var_t>::const_iterator it = inherit_vars.begin(),
end = inherit_vars.end();
it != end; ++it) {
for (const auto &kv : inherit_vars) {
wcstring_list_t lst;
it->second.to_list(lst);
kv.second.to_list(lst);
// This forced tab is crummy, but we don't know what indentation style the function uses.
append_format(out, L"\n\tset -l %ls", it->first.c_str());
for (wcstring_list_t::const_iterator arg_it = lst.begin(), arg_end = lst.end();
arg_it != arg_end; ++arg_it) {
wcstring earg = escape_string(*arg_it, ESCAPE_ALL);
append_format(out, L"\n\tset -l %ls", kv.first.c_str());
for (const auto &arg : lst) {
wcstring earg = escape_string(arg, ESCAPE_ALL);
out.push_back(L' ');
out.append(earg);
}
@ -224,6 +222,7 @@ static int report_function_metadata(const wchar_t *funcname, bool verbose, io_st
int line_number = 0;
if (function_exists(funcname)) {
auto props = function_get_properties(funcname);
path = function_get_definition_file(funcname);
if (path) {
autoloaded = function_is_autoloaded(funcname) ? L"autoloaded" : L"not-autoloaded";
@ -231,8 +230,7 @@ static int report_function_metadata(const wchar_t *funcname, bool verbose, io_st
} else {
path = L"stdin";
}
shadows_scope =
function_get_shadow_scope(funcname) ? L"scope-shadowing" : L"no-scope-shadowing";
shadows_scope = props->shadow_scope ? L"scope-shadowing" : L"no-scope-shadowing";
function_get_desc(funcname, &description);
description = escape_string(description, ESCAPE_NO_QUOTED);
}

View file

@ -792,19 +792,19 @@ void exec_job(parser_t &parser, job_t *j) {
switch (p->type) {
case INTERNAL_FUNCTION: {
const wcstring func_name = p->argv0();
wcstring def;
bool function_exists = function_get_definition(func_name, &def);
bool shadow_scope = function_get_shadow_scope(func_name);
const std::map<wcstring, env_var_t> inherit_vars =
function_get_inherit_vars(func_name);
if (!function_exists) {
auto props = function_get_properties(func_name);
if (!props) {
debug(0, _(L"Unknown function '%ls'"), p->argv0());
break;
}
wcstring def;
function_get_definition(func_name, &def);
const std::map<wcstring, env_var_t> inherit_vars =
function_get_inherit_vars(func_name);
function_block_t *fb =
parser.push_block<function_block_t>(p, func_name, shadow_scope);
parser.push_block<function_block_t>(p, func_name, props->shadow_scope);
function_prepare_environment(func_name, p->get_argv() + 1, inherit_vars);
parser.forbid_function(func_name);

View file

@ -177,6 +177,16 @@ void function_add(const function_data_t &data, const parser_t &parser) {
}
}
std::shared_ptr<const function_properties_t> function_get_properties(const wcstring &name) {
if (parser_keywords_is_reserved(name)) return nullptr;
scoped_rlock locker(functions_lock);
auto where = loaded_functions.find(name);
if (where != loaded_functions.end()) {
return where->second.props;
}
return nullptr;
}
int function_exists(const wcstring &cmd) {
if (parser_keywords_is_reserved(cmd)) return 0;
scoped_rlock locker(functions_lock);
@ -242,24 +252,12 @@ bool function_get_definition(const wcstring &name, wcstring *out_definition) {
return func != NULL;
}
wcstring_list_t function_get_named_arguments(const wcstring &name) {
scoped_rlock locker(functions_lock);
const function_info_t *func = function_get(name);
return func ? func->props->named_arguments : wcstring_list_t();
}
std::map<wcstring, env_var_t> function_get_inherit_vars(const wcstring &name) {
scoped_rlock locker(functions_lock);
const function_info_t *func = function_get(name);
return func ? func->inherit_vars : std::map<wcstring, env_var_t>();
}
bool function_get_shadow_scope(const wcstring &name) {
scoped_rlock locker(functions_lock);
const function_info_t *func = function_get(name);
return func ? func->props->shadow_scope : false;
}
bool function_get_desc(const wcstring &name, wcstring *out_desc) {
// Empty length string goes to NULL.
scoped_rlock locker(functions_lock);
@ -348,21 +346,20 @@ int function_get_definition_lineno(const wcstring &name) {
void function_prepare_environment(const wcstring &name, const wchar_t *const *argv,
const std::map<wcstring, env_var_t> &inherited_vars) {
env_set_argv(argv);
const wcstring_list_t named_arguments = function_get_named_arguments(name);
if (!named_arguments.empty()) {
auto props = function_get_properties(name);
if (props && !props->named_arguments.empty()) {
const wchar_t *const *arg = argv;
for (size_t i = 0; i < named_arguments.size(); i++) {
for (const wcstring &named_arg : props->named_arguments) {
if (*arg) {
env_set_one(named_arguments.at(i), ENV_LOCAL | ENV_USER, *arg);
env_set_one(named_arg, ENV_LOCAL | ENV_USER, *arg);
arg++;
} else {
env_set_empty(named_arguments.at(i), ENV_LOCAL | ENV_USER);
env_set_empty(named_arg, ENV_LOCAL | ENV_USER);
}
}
}
for (auto it = inherited_vars.begin(), end = inherited_vars.end(); it != end; ++it) {
env_set(it->first, ENV_LOCAL | ENV_USER, it->second.as_list());
for (const auto &kv : inherited_vars) {
env_set(kv.first, ENV_LOCAL | ENV_USER, kv.second.as_list());
}
}

View file

@ -53,18 +53,24 @@ void function_add(const function_data_t &data, const parser_t &parser);
/// Remove the function with the specified name.
void function_remove(const wcstring &name);
/// Returns the properties for a function, or nullptr if none. This does not trigger autoloading.
std::shared_ptr<const function_properties_t> function_get_properties(const wcstring &name);
/// Returns by reference the definition of the function with the name \c name. Returns true if
/// successful, false if no function with the given name exists.
/// This does not trigger autoloading.
bool function_get_definition(const wcstring &name, wcstring *out_definition);
/// Returns by reference the description of the function with the name \c name. Returns true if the
/// function exists and has a nonempty description, false if it does not.
/// This does not trigger autoloading.
bool function_get_desc(const wcstring &name, wcstring *out_desc);
/// Sets the description of the function with the name \c name.
void function_set_desc(const wcstring &name, const wcstring &desc);
/// Returns true if the function with the name name exists.
/// This may autoload.
int function_exists(const wcstring &name);
/// Attempts to load a function if not yet loaded. This is used by the completion machinery.
@ -91,14 +97,9 @@ bool function_is_autoloaded(const wcstring &name);
const wchar_t *function_get_definition_file(const wcstring &name);
/// Returns the linenumber where the definition of the specified function started.
///
/// This function does not autoload functions, it will only work on functions that have already been
/// defined.
/// This does not trigger autoloading.
int function_get_definition_lineno(const wcstring &name);
/// Returns a list of all named arguments of the specified function.
wcstring_list_t function_get_named_arguments(const wcstring &name);
/// Returns a mapping of all variables of the specified function that were inherited from the scope
/// of the function definition to their values.
std::map<wcstring, env_var_t> function_get_inherit_vars(const wcstring &name);
@ -107,8 +108,6 @@ std::map<wcstring, env_var_t> function_get_inherit_vars(const wcstring &name);
/// is successful.
bool function_copy(const wcstring &name, const wcstring &new_name);
/// Returns whether this function shadows variables of the underlying function.
bool function_get_shadow_scope(const wcstring &name);
/// Prepares the environment for executing a function.
void function_prepare_environment(const wcstring &name, const wchar_t *const *argv,