31#include "libmesh/parallel.h"
32#include "libmesh/fparser.hh"
47 const hit::Node * n = &node;
50 const auto section = n->parent();
54 if (
const auto active = section->find(
"active");
55 active && active->type() == hit::NodeType::Field && active->parent() == section)
57 const auto vars = active->param<std::vector<std::string>>();
58 return std::find_if(
vars.begin(),
60 [&n](
const auto & var)
61 { return n->path() == hit::pathNorm(var); }) !=
vars.end();
64 if (
const auto inactive = section->find(
"inactive");
65 inactive && inactive->type() == hit::NodeType::Field && inactive->parent() == section)
67 const auto vars = inactive->param<std::vector<std::string>>();
68 return std::find_if(
vars.begin(),
70 [&n](
const auto & var)
71 { return n->path() == hit::pathNorm(var); }) ==
vars.end();
79std::vector<std::string>
80findSimilar(
const std::string & param,
const std::vector<std::string> & options)
82 std::vector<std::string> candidates;
83 if (options.size() == 0)
87 for (
const auto &
opt : options)
91 const int dist_cutoff = 1 + param.size() / 5;
92 if (dist > dist_cutoff || dist > mindist)
100 candidates.push_back(
opt);
108 _factory(app.getFactory()),
109 _action_wh(action_wh),
110 _action_factory(app.getActionFactory()),
111 _syntax(_action_wh.syntax()),
113 _root(_parser.getRoot()),
114 _syntax_formatter(nullptr)
129 params.
addParam<std::vector<std::string>>(
131 std::vector<std::string>({
"__all__"}),
132 "If specified only the blocks named will be visited and made active");
133 params.
addParam<std::vector<std::string>>(
135 std::vector<std::string>(),
136 "If specified blocks matching these identifiers will be skipped.");
141std::vector<std::string>
148 std::vector<std::string> paramlist;
149 for (
auto it = iters.first; it != iters.second; ++it)
152 for (
const auto & it : params)
153 paramlist.push_back(it.first);
164 if (!
_used.count(fullpath) && nodename !=
"active" && nodename !=
"inactive" &&
167 auto section_name = fullpath.substr(0, fullpath.rfind(
"/"));
169 const auto candidates =
findSimilar(nodename, paramlist);
170 if (candidates.size() > 0)
172 "unused parameter '" + fullpath +
"'; did you mean '" + candidates[0] +
"'?", n);
174 errors.emplace_back(
"unused parameter '" + fullpath +
"'", n);
182 return (strip_leading_path ? path.filename() : std::filesystem::absolute(path)).
string();
191 const std::string section_name = n->fullpath();
192 const std::string curr_identifier = n->fullpath();
206 if (
const auto [begin, end] =
_syntax.
getActions(registered_identifier); begin == end)
209 "section '[" + curr_identifier +
210 "]' does not have an associated Action; you likely misspelled the Action/section name "
211 "or the app you are running does not support this Action/syntax",
218 std::set<const Syntax::ActionInfo *> processed_actions;
224 for (; it != end && processed_actions.count(&it->second); ++it)
232 processed_actions.insert(&it->second);
247 params.
set<std::string>(
"task") = it->second._task;
248 params.
set<std::string>(
"registered_identifier") = registered_identifier;
250 if (!(params.
have_parameter<
bool>(
"isObjectAction") && params.
get<
bool>(
"isObjectAction")))
251 params.
set<std::vector<std::string>>(
"control_tags")
255 std::shared_ptr<Action> action_obj =
260 std::shared_ptr<MooseObjectAction> object_action =
261 std::dynamic_pointer_cast<MooseObjectAction>(action_obj);
264 auto & object_params = object_action->getObjectParams();
265 object_params.setHitNode(*n, {});
267 object_params.set<std::vector<std::string>>(
"control_tags")
271 std::shared_ptr<AddActionComponentAction> component_action =
272 std::dynamic_pointer_cast<AddActionComponentAction>(action_obj);
273 if (component_action)
275 auto & component_params = component_action->getComponentParams();
276 component_params.setHitNode(*n, {});
278 component_params.set<std::vector<std::string>>(
"control_tags")
289Builder::walk(
const std::string & fullpath,
const std::string & nodepath, hit::Node * n)
296 walkRaw(fullpath, nodepath, n);
307 const auto need_action_syntax_first = [
this](
const auto & action_name)
310 mooseAssert(syntax.size(),
"Empty syntax");
311 std::copy(syntax.begin(), syntax.end(), std::back_inserter(
_secs_need_first));
317 need_action_syntax_first(
"SetupDebugAction");
322 need_action_syntax_first(
"GlobalParamsAction");
327 need_action_syntax_first(
"DynamicObjectRegistrationAction");
331 if (
auto n =
_root.find(sec))
332 walkRaw(n->parent()->fullpath(), n->path(), n);
335 _root.walk(
this, hit::NodeType::Section);
340 std::vector<std::string> messages;
342 messages.push_back(key_message_pair.second);
361 if (!warn_unused && !err_unused)
364 std::vector<hit::ErrorMessage> messages;
380 messages.emplace_back(
"unused command line parameter '" + arg +
"'");
394 "\n\nAppend --allow-unused (or -w) on the command line to ignore unused parameters.");
411 mooseError(
"Unrecognized Syntax Formatter requested");
419 std::vector<std::pair<std::string, Syntax::ActionInfo>> all_names;
433 if (act_info.
_task ==
"")
436 all_names.push_back(std::make_pair(iter.first, act_info));
440 for (
const auto & act_names : all_names)
442 const auto & act_info = act_names.second;
443 const std::string & action = act_info._action;
444 const std::string & task = act_info._task;
445 const std::string syntax = act_names.first;
459 for (
auto & t : tasks)
472 action_obj_params.
get<
bool>(
"isObjectAction"))
476 auto moose_obj_params = obj->buildParameters();
480 const std::vector<std::string> & buildable_types = action_obj_params.
getBuildableTypes();
483 if ((buildable_types.empty() ||
484 std::find(buildable_types.begin(), buildable_types.end(), moose_obj_name) !=
485 buildable_types.end()) &&
486 moose_obj_params.hasBase() &&
494 bool is_action_params =
false;
495 bool is_type =
false;
496 if (syntax[syntax.size() - 1] ==
'*')
501 name = syntax.substr(0, pos - 1) + moose_obj_name;
504 name = syntax.substr(0, pos - 1) +
"/<type>/" + moose_obj_name;
505 is_action_params =
true;
510 name = syntax +
"/<type>/" + moose_obj_name;
513 moose_obj_params.set<std::string>(
"type") = moose_obj_name;
530 if (syntax !=
"ActionComponents/*")
535 for (
auto it = iters.first; it != iters.second; ++it)
538 const auto component_name = it->second;
551 if (syntax[syntax.size() - 1] ==
'*')
553 size_t pos = syntax.size();
554 name = syntax.substr(0, pos - 1) + component_name;
556 component_params.set<std::string>(
"type") = component_name;
564 "AddActionComponentAction",
579 std::vector<std::pair<std::string, Syntax::ActionInfo>> all_names;
589 if (act_info.
_task ==
"")
592 all_names.push_back(std::pair<std::string, Syntax::ActionInfo>(iter.first, act_info));
595 for (
const auto & act_names : all_names)
599 act_names.first, act_names.second._action,
true, &action_obj_params);
601 const std::string & task = act_names.second._task;
602 std::string act_name = act_names.first;
610 action_obj_params.
get<
bool>(
"isObjectAction"))
614 auto moose_obj_params = obj->buildParameters();
619 const std::vector<std::string> & buildable_types = action_obj_params.
getBuildableTypes();
622 if ((buildable_types.empty() ||
623 std::find(buildable_types.begin(), buildable_types.end(), moose_obj_name) !=
624 buildable_types.end()) &&
625 moose_obj_params.hasBase() &&
633 bool is_action_params =
false;
634 if (act_name[act_name.size() - 1] ==
'*')
636 pos = act_name.size();
639 name = act_name.substr(0, pos - 1) + moose_obj_name;
642 name = act_name.substr(0, pos - 1) +
"/<type>/" + moose_obj_name;
643 is_action_params =
true;
648 name = act_name +
"/<type>/" + moose_obj_name;
651 moose_obj_params.set<std::string>(
"type") = moose_obj_name;
653 _syntax_formatter->insertNode(name, moose_obj_name, is_action_params, &moose_obj_params);
667 mooseAssert(section_node->type() == hit::NodeType::Section,
"Node type should be a section");
669 for (
const auto & [name, par_unique_ptr] : p)
674 const hit::Node * param_node =
nullptr;
682 if (
const auto section_param_node = section_node->find(param_name);
683 section_param_node && section_param_node->type() == hit::NodeType::Field &&
684 section_param_node->parent() == section_node)
685 param_node = section_param_node;
691 global_node && global_node->type() == hit::NodeType::Field &&
694 mooseAssert(
isGlobal(*global_node),
"Could not detect global-ness");
695 param_node = global_node;
702 const auto fullpath = param_node->fullpath();
707 const auto global =
isGlobal(*param_node);
713 std::string key =
"";
715 key += *object_type_ptr +
"_";
724 if (!global && std::find_if(
_errors.begin(),
726 [¶m_node](
const auto & err)
727 { return err.node == param_node; }) ==
_errors.end())
728 _errors.emplace_back(
"parameter '" + fullpath +
"' is private and cannot be set",
734 const auto param_field =
dynamic_cast<const hit::Field *
>(param_node);
735 mooseAssert(param_field,
"Is not a field");
736 bool set_param =
false;
742 catch (hit::Error & e)
744 _errors.emplace_back(e.message, param_node);
746 catch (std::exception & e)
748 _errors.emplace_back(e.what(), param_node);
756 if (
auto cast_par =
dynamic_cast<InputParameters::Parameter<std::vector<VariableName>
> *>(
757 par_unique_ptr.get()))
759 _errors.emplace_back(*error, param_node);
764 *par_unique_ptr, param_node->fullpath(), param_node->path(),
true))
765 _errors.emplace_back(error->second, param_node);
778 if (
auto out_par_ptr =
779 dynamic_cast<InputParameters::Parameter<OutFileBase> *
>(par_unique_ptr.get()))
782 mooseAssert(input_file_name.size(),
"Input Filename is empty");
783 const auto pos = input_file_name.find_last_of(
'.');
784 mooseAssert(pos != std::string::npos,
"Unable to determine suffix of input file name");
785 out_par_ptr->set() = input_file_name.substr(0, pos) +
"_out";
794 const auto & [base_name, num_repeat] = base_name_num_repeat_pair;
799 const auto vec_size = p.
get<
unsigned int>(num_repeat);
800 const std::string & name = p.
get<std::string>(base_name);
802 std::vector<VariableName> variable_names(vec_size);
803 for (
const auto i : index_range(variable_names))
805 std::ostringstream oss;
807 variable_names[i] = oss.str();
811 p.
set<std::vector<VariableName>>(param_name) = variable_names;
819 const auto node =
_root.find(prefix);
820 extractParams((node && node->type() == hit::NodeType::Section) ? node :
nullptr, p);
827 return global_params_node && node.parent() == global_params_node;
836 mooseAssert(syntax.size() == 1,
"Unexpected GlobalParamsAction syntax size");
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
void mooseUnused(Args &&... args)
Warning message used to notify the users of unused parts of their input files Really used internally ...
void mooseDeprecated(Args &&... args)
Emit a deprecated code/feature message with the given stringified, concatenated args.
std::string getTaskName(const std::string &action)
std::set< std::string > getTasksByAction(const std::string &action) const
std::shared_ptr< Action > create(const std::string &action, const std::string &action_name, InputParameters ¶meters)
std::pair< std::multimap< std::string, std::string >::const_iterator, std::multimap< std::string, std::string >::const_iterator > getActionsByTask(const std::string &task) const
Returns begin and end iterators in a multimap from tasks to actions names.
FileLineInfo getLineInfo(const std::string &name, const std::string &task) const
Gets file and line information where an action was registered.
InputParameters getValidParams(const std::string &name)
Storage for action instances.
void addActionBlock(std::shared_ptr< Action > blk)
This method add an Action instance to the warehouse.
static InputParameters validParams()
An inteface for the _console for outputting to the Console object.
static InputParameters validParams()
const auto & registeredObjects() const
Returns a reference to the map from names to RegistryEntryBase pointers.
std::string associatedClassName(const std::string &name) const
Get the associated class name for an object name.
FileLineInfo getLineInfo(const std::string &name) const
Gets file and line information where an object was initially registered.
Holds the syntax in a Json::Value tree.
bool addParameters(const std::string &parent_path, const std::string &path, bool is_type, const std::string &action, bool is_action, InputParameters *params, const FileLineInfo &lineinfo, const std::string &classname)
Add parameters to the tree.
void addSyntaxType(const std::string &path, const std::string type)
Add an associated type to a block.
void addActionTask(const std::string &path, const std::string &action, const std::string &task, const FileLineInfo &lineinfo)
Add a task to the tree.
void addGlobal()
Add the global section to the output.
Base class for MOOSE-based applications.
std::shared_ptr< CommandLine > commandLine() const
Get the command line.
std::optional< const hit::Node * > _global_params_node
The hit Node for the [GlobalParams] block, if any If set (could be null), it means we have searched f...
std::string getPrimaryFileName(bool stripLeadingPath=true) const
Return the primary (first) filename that was parsed.
void walkRaw(std::string fullpath, std::string nodepath, hit::Node *n)
std::set< std::string > _extracted_vars
The set of all variables extracted from the input file.
void build()
Parse an input file (or text string if provided) consisting of hit syntax and setup objects in the MO...
void buildJsonSyntaxTree(JsonSyntaxTree &tree) const
Use MOOSE Factories to construct a parameter tree for documentation or echoing input.
std::map< std::string, std::string > _deprecated_params
Deprecation warnings (object type/param name) -> (message)
ActionWarehouse & _action_wh
Action warehouse that will be filled by actions.
void walk(const std::string &fullpath, const std::string &nodepath, hit::Node *n)
Syntax & _syntax
Reference to an object that defines input file syntax.
Factory & _factory
The Factory associated with that MooseApp.
ActionFactory & _action_factory
The Factory that builds actions.
std::vector< hit::ErrorMessage > _errors
The errors accumulated during the walk.
void errorCheck(const libMesh::Parallel::Communicator &comm, bool warn_unused, bool err_unused)
const hit::Node * queryGlobalParamsNode() const
Get the [GlobalParams] section node if it exists.
std::vector< std::string > _secs_need_first
The sections that we need to execute first (read during the final walk)
MooseApp & _app
The MooseApp this Parser is part of.
bool isGlobal(const hit::Node &node) const
Parser & _parser
The front parser.
std::vector< std::string > listValidParams(std::string §ion_name)
Builder(MooseApp &app, ActionWarehouse &action_wh, Parser &parser)
void initSyntaxFormatter(SyntaxFormatterType type, bool dump_mode)
Creates a syntax formatter for printing.
hit::Node & _root
The root node from the Parser.
void buildFullTree(const std::string &search_string)
Use MOOSE Factories to construct a full parse tree for documentation or echoing input.
std::unique_ptr< SyntaxTree > _syntax_formatter
Object for holding the syntax parse tree.
void extractParams(const hit::Node *const section_node, InputParameters &p)
Attempt to extract values from input starting with the section in input in section_node based on the ...
static InputParameters validParams()
Parameters that are processed directly by the Parser and are valid anywhere in the input.
static ParameterRegistry & get()
Get the singleton registry.
void set(libMesh::Parameters::Value &value, const hit::Field &field) const
Sets a parameter value given a hit field.
std::vector< hit::ErrorMessage > errors
std::set< std::string > _used
void walk(const std::string &fullpath, const std::string &nodename, hit::Node *n) override
Class for parsing input files.
static void appendErrorMessages(std::vector< hit::ErrorMessage > &to, const std::vector< hit::ErrorMessage > &from)
Helper for accumulating errors from a walker into an accumulation of errors.
const hit::Node & getCommandLineRoot() const
std::filesystem::path getLastInputFilePath() const
bool getThrowOnError() const
void parseError(std::vector< hit::ErrorMessage > messages) const
Helper for throwing an error with the given messages.
const hit::Node * queryCommandLineRoot() const
const std::set< std::string > & getExtractedVars() const
static std::string joinErrorMessages(const std::vector< hit::ErrorMessage > &error_messages)
Helper for combining error messages into a single, newline separated message.
std::pair< std::multimap< std::string, ActionInfo >::const_iterator, std::multimap< std::string, ActionInfo >::const_iterator > getActions(const std::string &syntax) const
Returns a pair of multimap iterators to all the ActionInfo objects associated with a given piece of s...
const std::multimap< std::string, ActionInfo > & getAssociatedActions() const
Return all Syntax to Action associations.
std::string isAssociated(const std::string &real_id, bool *is_parent, const std::map< std::string, std::set< std::string > > &alt_map={}) const
Method for determining whether a piece of syntax is associated with an Action an optional syntax map ...
bool verifyMooseObjectTask(const std::string &base, const std::string &task) const
Returns a Boolean indicating whether a task is associated with on of the MOOSE pluggable systems (BAS...
FileLineInfo getLineInfo(const std::string &syntax, const std::string &action, const std::string &task) const
Gets the file and line where the syntax/action/task combo was registered.
const std::multimap< std::string, std::string > & getAssociatedTypes() const
Get a multimap of registered associations of syntax with type.
bool isDeprecatedSyntax(const std::string &syntax) const
Returns a Boolean indicating whether the syntax has been deprecated through a call to deprecateAction...
std::string deprecatedActionSyntaxMessage(const std::string syntax)
Returns the deprecation message for a given syntax that has been deprecated by deprecateActionSyntax.
std::vector< std::string > getSyntaxByAction(const std::string &action, const std::string &task="")
Retrieve the syntax associated with the passed in action type string.
std::string baseName(const std::string &name)
int levenshteinDist(const std::string &s1, const std::string &s2)
std::string stringJoin(const std::vector< std::string > &values, const std::string &separator=" ")
Concatenates value into a single string separated by separator.
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
std::vector< std::string > findSimilar(const std::string ¶m, const std::vector< std::string > &options)
bool isSectionActive(const hit::Node &node)
void mooseDeprecatedStream(S &oss, const bool expired, const bool print_title, const bool show_trace, Args &&... args)