Migrate the function's is_autoload field into its immutable properties

Continuing to simplify functions. No functional change here.
This commit is contained in:
ridiculousfish 2021-10-21 13:23:49 -07:00
parent 12134c19d9
commit 17d9ae16be
2 changed files with 34 additions and 19 deletions

View File

@ -40,10 +40,8 @@ class function_info_t {
function_properties_ref_t props; function_properties_ref_t props;
/// Function description. This may be changed after the function is created. /// Function description. This may be changed after the function is created.
wcstring description; wcstring description;
/// Flag for specifying that this function was automatically loaded.
const bool is_autoload;
function_info_t(function_properties_ref_t props, wcstring desc, bool autoload); function_info_t(function_properties_ref_t props, wcstring desc);
}; };
/// Type wrapping up the set of all functions. /// Type wrapping up the set of all functions.
@ -68,6 +66,12 @@ struct function_set_t {
return iter == funcs.end() ? nullptr : &iter->second; return iter == funcs.end() ? nullptr : &iter->second;
} }
/// Get the properties for a function, or nullptr if none.
function_properties_ref_t get_props(const wcstring &name) const {
auto iter = funcs.find(name);
return iter == funcs.end() ? nullptr : iter->second.props;
}
/// \return true if we should allow autoloading a given function. /// \return true if we should allow autoloading a given function.
bool allow_autoload(const wcstring &name) const; bool allow_autoload(const wcstring &name) const;
@ -80,8 +84,8 @@ static owning_lock<function_set_t> function_set;
bool function_set_t::allow_autoload(const wcstring &name) const { bool function_set_t::allow_autoload(const wcstring &name) const {
// Prohibit autoloading if we have a non-autoload (explicit) function, or if the function is // Prohibit autoloading if we have a non-autoload (explicit) function, or if the function is
// tombstoned. // tombstoned.
auto info = get_info(name); auto props = get_props(name);
bool has_explicit_func = info && !info->is_autoload; bool has_explicit_func = props && !props->is_autoload;
bool is_tombstoned = autoload_tombstones.count(name) > 0; bool is_tombstoned = autoload_tombstones.count(name) > 0;
return !has_explicit_func && !is_tombstoned; return !has_explicit_func && !is_tombstoned;
} }
@ -141,10 +145,11 @@ static void autoload_names(std::unordered_set<wcstring> &names, int get_hidden)
} }
} }
function_info_t::function_info_t(function_properties_ref_t props, wcstring desc, bool autoload) function_info_t::function_info_t(function_properties_ref_t props, wcstring desc)
: props(std::move(props)), description(std::move(desc)), is_autoload(autoload) {} : props(std::move(props)), description(std::move(desc)) {}
void function_add(wcstring name, wcstring description, function_properties_ref_t props) { void function_add(wcstring name, wcstring description,
std::shared_ptr<function_properties_t> props) {
ASSERT_IS_MAIN_THREAD(); ASSERT_IS_MAIN_THREAD();
assert(props && "Null props"); assert(props && "Null props");
auto funcset = function_set.acquire(); auto funcset = function_set.acquire();
@ -158,11 +163,11 @@ void function_add(wcstring name, wcstring description, function_properties_ref_t
funcset->remove(name); funcset->remove(name);
// Check if this is a function that we are autoloading. // Check if this is a function that we are autoloading.
bool is_autoload = funcset->autoloader.autoload_in_progress(name); props->is_autoload = funcset->autoloader.autoload_in_progress(name);
// Create and store a new function. // Create and store a new function.
auto ins = funcset->funcs.emplace( auto ins = funcset->funcs.emplace(std::move(name),
std::move(name), function_info_t(std::move(props), std::move(description), is_autoload)); function_info_t(std::move(props), std::move(description)));
assert(ins.second && "Function should not already be present in the table"); assert(ins.second && "Function should not already be present in the table");
(void)ins; (void)ins;
} }
@ -263,11 +268,16 @@ bool function_copy(const wcstring &name, const wcstring &new_name) {
} }
const function_info_t &src_func = iter->second; const function_info_t &src_func = iter->second;
// Copy the function's props.
// This new instance of the function shouldn't be tied to the definition file of the // This new instance of the function shouldn't be tied to the definition file of the
// original, so pass NULL filename, etc. // original, so clear the filename, etc.
auto new_props = std::make_shared<function_properties_t>(*src_func.props);
new_props->is_autoload = false;
new_props->definition_file = nullptr;
// Note this will NOT overwrite an existing function with the new name. // Note this will NOT overwrite an existing function with the new name.
// TODO: rationalize if this behavior is desired. // TODO: rationalize if this behavior is desired.
funcset->funcs.emplace(new_name, function_info_t(src_func.props, src_func.description, false)); funcset->funcs.emplace(new_name, function_info_t(new_props, src_func.description));
return true; return true;
} }
@ -295,9 +305,10 @@ const wchar_t *function_get_definition_file(const wcstring &name) {
} }
bool function_is_autoloaded(const wcstring &name) { bool function_is_autoloaded(const wcstring &name) {
const auto funcset = function_set.acquire(); if (auto func = function_get_properties(name)) {
const function_info_t *func = funcset->get_info(name); return func->is_autoload;
return func ? func->is_autoload : false; }
return false;
} }
int function_get_definition_lineno(const wcstring &name) { int function_get_definition_lineno(const wcstring &name) {
@ -322,7 +333,7 @@ void function_invalidate_path() {
auto funcset = function_set.acquire(); auto funcset = function_set.acquire();
wcstring_list_t autoloadees; wcstring_list_t autoloadees;
for (const auto &kv : funcset->funcs) { for (const auto &kv : funcset->funcs) {
if (kv.second.is_autoload) { if (kv.second.props->is_autoload) {
autoloadees.push_back(kv.first); autoloadees.push_back(kv.first);
} }
} }

View File

@ -38,6 +38,9 @@ struct function_properties_t {
/// Set to true if invoking this function shadows the variables of the underlying function. /// Set to true if invoking this function shadows the variables of the underlying function.
bool shadow_scope{true}; bool shadow_scope{true};
/// Whether the function was autoloaded.
bool is_autoload{false};
/// The file from which the function was created (intern'd string), or nullptr if not from a /// The file from which the function was created (intern'd string), or nullptr if not from a
/// file. /// file.
const wchar_t *definition_file{}; const wchar_t *definition_file{};
@ -45,8 +48,9 @@ struct function_properties_t {
using function_properties_ref_t = std::shared_ptr<const function_properties_t>; using function_properties_ref_t = std::shared_ptr<const function_properties_t>;
/// Add a function. /// Add a function. This may mutate \p props to set is_autoload.
void function_add(wcstring name, wcstring description, function_properties_ref_t props); void function_add(wcstring name, wcstring description,
std::shared_ptr<function_properties_t> props);
/// Remove the function with the specified name. /// Remove the function with the specified name.
void function_remove(const wcstring &name); void function_remove(const wcstring &name);