https://mooseframework.inl.gov
Loading...
Searching...
No Matches
Classes | Public Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
MooseServer Class Reference

#include <MooseServer.h>

Inheritance diagram for MooseServer:
[legend]

Classes

struct  CheckState
 Helper for storing the state for a single document. More...
 
struct  SyntaxMetadata
 struct to store syntax metadata for each registration application type More...
 

Public Member Functions

 MooseServer (MooseApp &moose_app)
 
virtual ~MooseServer ()=default
 
std::shared_ptr< wasp::lsp::Connection > getConnection ()
 Get read / write connection - specific to this server implemention.
 
MooseAppgetCheckApp ()
 Public interface for writable check app reference with error checks.
 
void setDistPlotNumPoints (std::size_t num_points)
 Override number of discrete points in continuous distribution plots.
 

Private Types

using SortedLocationNodes = std::set< wasp::HITNodeView, std::function< bool(const wasp::HITNodeView &, const wasp::HITNodeView &)> >
 SortedLocationNodes - type alias for set of nodes sorted by location.
 

Private Member Functions

bool parseDocumentForDiagnostics (wasp::DataArray &diagnosticsList)
 Parse document for diagnostics - specific to this server implemention.
 
void addResourcesForDocument ()
 Add paths from includes and FileName parameters for client to watch.
 
void getFileNameTypeValues (std::set< std::string > &filename_vals, wasp::HITNodeView parent)
 Recursively walk input to gather all FileName type parameter values.
 
bool gatherDocumentCompletionItems (wasp::DataArray &completionItems, bool &is_incomplete, int line, int character)
 Gather document completion items - specific to this server implemention.
 
void getExistingInput (wasp::HITNodeView parent_node, std::set< std::string > &existing_params, std::set< std::string > &existing_subblocks)
 Get names of parameters and subblocks specified in given input node.
 
void getAllValidParameters (InputParameters &valid_params, const std::string &object_path, const std::string &object_type, std::set< std::string > &obj_act_tasks)
 Get all global parameters, action parameters, and object parameters.
 
void getActionParameters (InputParameters &valid_params, const std::string &object_path, std::set< std::string > &obj_act_tasks)
 Get all action parameters using requested object path to collection.
 
void getObjectParameters (InputParameters &valid_params, std::string object_type, const std::set< std::string > &obj_act_tasks)
 Get all object parameters using requested object path to collection.
 
bool addParametersToList (wasp::DataArray &completionItems, const InputParameters &valid_params, const std::set< std::string > &existing_params, int replace_line_beg, int replace_char_beg, int replace_line_end, int replace_char_end, const std::string &filtering_prefix)
 Add parameters that were previously gathered to list for completion.
 
bool addSubblocksToList (wasp::DataArray &completionItems, const std::string &object_path, int replace_line_beg, int replace_char_beg, int replace_line_end, int replace_char_end, const std::string &filtering_prefix, bool request_on_block_decl)
 Add subblocks to completion list for request path, line, and column.
 
bool addValuesToList (wasp::DataArray &completionItems, const InputParameters &valid_params, const std::set< std::string > &existing_params, const std::set< std::string > &existing_subblocks, const std::string &param_name, const std::set< std::string > &obj_act_tasks, const std::string &object_path, int replace_line_beg, int replace_char_beg, int replace_line_end, int replace_char_end)
 Add parameter values to completion list for request line and column.
 
template<typename MooseEnumType >
void getEnumsAndDocs (MooseEnumType &moose_enum_param, std::map< std::string, std::string > &options_and_descs)
 Fill map of all options and descriptions if parameter is moose enum.
 
void addObjectsFromWarehouses (const std::string &param_type, std::map< std::string, std::string > &options_and_descs)
 Supplement completion list with objects in warehouses if applicable.
 
bool gatherDocumentDefinitionLocations (wasp::DataArray &definitionLocations, int line, int character)
 Gather definition locations - specific to this server implemention.
 
void getInputLookupDefinitionNodes (SortedLocationNodes &location_nodes, const std::string &clean_type, const std::string &val_string)
 Get set of nodes from associated path lookups matching value string.
 
bool addLocationNodesToList (wasp::DataArray &defsOrRefsLocations, const SortedLocationNodes &location_nodes)
 Add set of nodes sorted by location to definition or reference list.
 
bool getHoverDisplayText (std::string &display_text, int line, int character)
 Get hover display text - logic specific to this server implemention.
 
bool gatherDocumentReferencesLocations (wasp::DataArray &referencesLocations, int line, int character, bool include_declaration)
 Gather references locations - specific to this server implemention.
 
void getNodesByValueAndTypes (SortedLocationNodes &match_nodes, wasp::HITNodeView view_parent, const std::string &target_value, const std::set< std::string > &target_types)
 Recursively walk input to gather all nodes matching value and types.
 
bool gatherDocumentFormattingTextEdits (wasp::DataArray &formattingTextEdits, int tab_size, bool insert_spaces)
 Gather formatting text edits - specific to this server implemention.
 
std::string formatDocument (wasp::HITNodeView parent, std::size_t &prev_line, std::size_t level)
 Recursively walk down whole nodeview tree while formatting document.
 
bool gatherDocumentSymbols (wasp::DataArray &documentSymbols)
 Gather document symbols - specific to this server implemention.
 
bool traverseParseTreeAndFillSymbols (wasp::HITNodeView view_parent, wasp::DataObject &data_parent)
 Recursively fill document symbols from the given node.
 
int getCompletionItemKind (const InputParameters &valid_params, const std::string &param_name, const std::string &clean_type, bool is_param)
 Get completion item kind value that client may use for icon in list.
 
int getDocumentSymbolKind (wasp::HITNodeView symbol_node)
 Get document symbol kind value that client may use for outline icon.
 
std::string getRequiredParamsText (const std::string &subblock_path, const std::string &subblock_type, const std::set< std::string > &existing_params, const std::string &indent_spaces)
 Get required parameter completion text list for given subblock path.
 
bool gatherExtensionResponses (wasp::DataArray &extensionResponses, const std::string &extensionMethod, int line, int character)
 Gather extension responses - specific to this server implemention.
 
bool gatherPlottingResponses (wasp::DataArray &plotting_responses, int line, int character)
 Build CustomPlot extension responses when method name is plotting.
 
void buildFuncPlotResponse (wasp::DataArray &plotting_responses, FEProblemBase &problem, const std::string &object_name, const std::string &object_type)
 Gather function data, build CustomPlot object, and add to responses.
 
void buildDistPlotResponses (wasp::DataArray &plotting_responses, FEProblemBase &problem, const std::string &object_name, const std::string &object_type)
 Compute PDF and CDF, build CustomPlot objects, and add to responses.
 
void buildLineGraphPlot (wasp::CustomPlot &plot_object, const std::string &plot_title, const std::string &x_axis_label, const std::string &y_axis_label, const std::vector< double > &graph_keys, const std::vector< double > &graph_vals)
 Build CustomPlot graph with provided keys, values, and plot title.
 
bool connectionRead (wasp::DataObject &object)
 Read from connection into object - specific to this server's connection.
 
bool connectionWrite (wasp::DataObject &object)
 Write object json to connection - specific to this server's connection.
 
bool rootIsValid () const
 
MooseAppgetRegistrationApp ()
 
SyntaxMetadatagetSyntaxMetadata ()
 
const hit::Node * queryRoot () const
 
const hit::Node & getRoot () const
 
const CheckStatequeryCheckState () const
 
CheckStatequeryCheckState ()
 
const MooseAppqueryCheckApp () const
 
MooseAppqueryCheckApp ()
 
const ParserqueryCheckParser () const
 
ParserqueryCheckParser ()
 

Private Attributes

MooseApp_moose_app
 _moose_app - reference to parent application that owns this server
 
std::map< std::string, CheckState_check_state
 _check_state - map from document paths to state (parser, app, text)
 
std::shared_ptr< wasp::lsp::IOStreamConnection > _connection
 _connection - shared pointer to this server's read / write iostream
 
std::map< std::string, SyntaxMetadata_app_type_to_syntax_metadata
 _app_type_to_syntax_metadata - syntax metadata per app type map
 
std::size_t _formatting_tab_size
 _formatting_tab_size - number of indent spaces for formatting
 
std::size_t _dist_plot_num_points
 _dist_plot_num_points - distribution plot sampling resolution
 
double _dist_plot_quantile_bound
 _dist_plot_quantile_bound - epsilon to bound plot range tails
 

Detailed Description

Definition at line 29 of file MooseServer.h.

Member Typedef Documentation

◆ SortedLocationNodes

using MooseServer::SortedLocationNodes = std::set<wasp::HITNodeView, std::function<bool(const wasp::HITNodeView &, const wasp::HITNodeView &)> >
private

SortedLocationNodes - type alias for set of nodes sorted by location.

Definition at line 59 of file MooseServer.h.

Constructor & Destructor Documentation

◆ MooseServer()

MooseServer::MooseServer ( MooseApp moose_app)

Definition at line 51 of file MooseServer.C.

52 : _moose_app(moose_app),
53 _connection(std::make_shared<wasp::lsp::IOStreamConnection>(this)),
57{
58 // add all implemented server capabilities to notify client in initialize
59 enableFullSync();
60 enableSymbols();
61 enableCompletion();
62 enableDefinition();
63 enableReferences();
64 enableFormatting();
65 enableHover();
66 enableExtension("plotting");
67 enableExtension("watcherRegistration");
68}
std::size_t _dist_plot_num_points
_dist_plot_num_points - distribution plot sampling resolution
std::size_t _formatting_tab_size
_formatting_tab_size - number of indent spaces for formatting
MooseApp & _moose_app
_moose_app - reference to parent application that owns this server
std::shared_ptr< wasp::lsp::IOStreamConnection > _connection
_connection - shared pointer to this server's read / write iostream
double _dist_plot_quantile_bound
_dist_plot_quantile_bound - epsilon to bound plot range tails

◆ ~MooseServer()

virtual MooseServer::~MooseServer ( )
virtualdefault

Member Function Documentation

◆ addLocationNodesToList()

bool MooseServer::addLocationNodesToList ( wasp::DataArray &  defsOrRefsLocations,
const SortedLocationNodes location_nodes 
)
private

Add set of nodes sorted by location to definition or reference list.

Parameters
defsOrRefsLocations- data array of locations objects to fill
location_nodes- set of nodes that have locations to be added
Returns
- true if filling of location objects completed successfully

Definition at line 1313 of file MooseServer.C.

1315{
1316 bool pass = true;
1317
1318 // walk over set of sorted nodes provided to add and build locations list
1319 for (const auto & location_nodes_iter : location_nodes)
1320 {
1321 // add file scheme prefix onto front of file path to build location uri
1322 auto location_uri = wasp::lsp::m_uri_prefix + location_nodes_iter.node_pool()->stream_name();
1323
1324 // add file uri with zero based line and column range to locations list
1325 defsOrRefsLocations.push_back(wasp::DataObject());
1326 wasp::DataObject * location = defsOrRefsLocations.back().to_object();
1327 pass &= wasp::lsp::buildLocationObject(*location,
1328 errors,
1329 location_uri,
1330 location_nodes_iter.line() - 1,
1331 location_nodes_iter.column() - 1,
1332 location_nodes_iter.last_line() - 1,
1333 location_nodes_iter.last_column());
1334 }
1335
1336 return pass;
1337}

Referenced by gatherDocumentDefinitionLocations(), and gatherDocumentReferencesLocations().

◆ addObjectsFromWarehouses()

void MooseServer::addObjectsFromWarehouses ( const std::string &  param_type,
std::map< std::string, std::string > &  options_and_descs 
)
private

Supplement completion list with objects in warehouses if applicable.

Parameters
param_type- parameter type string to pick suitable warehouse
options_and_descs- map to fill with options and descriptions

Definition at line 1090 of file MooseServer.C.

1092{
1093 // get check app of document and return with no items if its build failed
1094 auto app_ptr = queryCheckApp();
1095 if (!app_ptr)
1096 return;
1097
1098 // get problem from action warehouse and return without any items if null
1099 std::shared_ptr<FEProblemBase> & problem = app_ptr->actionWarehouse().problemBase();
1100 if (!problem)
1101 return;
1102
1103 if (param_type == "NonlinearVariableName")
1104 {
1105 for (const auto i : make_range(problem->numNonlinearSystems()))
1106 for (const auto & nls_var_name : problem->getNonlinearSystemBase(i).getVariableNames())
1107 options_and_descs[nls_var_name] = "from NonlinearSystem VariableWarehouse";
1108 }
1109 else if (param_type == "AuxVariableName")
1110 {
1111 for (const auto & aux_var_name : problem->getAuxiliarySystem().getVariableNames())
1112 options_and_descs[aux_var_name] = "from AuxiliarySystem VariableWarehouse";
1113 }
1114 else if (param_type == "VariableName")
1115 {
1116 for (const auto i : make_range(problem->numNonlinearSystems()))
1117 for (const auto & nls_var_name : problem->getNonlinearSystemBase(i).getVariableNames())
1118 options_and_descs[nls_var_name] = "from NonlinearSystem VariableWarehouse";
1119 for (const auto & aux_var_name : problem->getAuxiliarySystem().getVariableNames())
1120 options_and_descs[aux_var_name] = "from AuxiliarySystem VariableWarehouse";
1121 }
1122 else if (param_type == "MaterialPropertyName")
1123 {
1124 const auto & mat_prop_registry = problem->getMaterialPropertyRegistry();
1125 const std::vector<std::string> mat_prop_names(mat_prop_registry.idsToNamesBegin(),
1126 mat_prop_registry.idsToNamesEnd());
1127 for (const auto & mat_prop_name : mat_prop_names)
1128 options_and_descs[mat_prop_name] = "from MaterialPropertyRegistry";
1129 }
1130 else if (param_type == "MaterialName")
1131 {
1132 for (const auto & material : problem->getMaterialWarehouse().getObjects())
1133 options_and_descs[material->name()] = "from MaterialWarehouse";
1134 }
1135 else if (param_type == "FunctionName")
1136 {
1137 for (const auto & function : problem->getFunctionWarehouse().getObjects())
1138 options_and_descs[function->name()] = "from FunctionWarehouse";
1139 }
1140 else if (param_type == "OutputName")
1141 {
1142 for (const auto & output_name : app_ptr->getOutputWarehouse().getOutputNames<Output>())
1143 options_and_descs[output_name] = "from OutputWarehouse";
1144 for (const auto & reserved_name : app_ptr->getOutputWarehouse().getReservedNames())
1145 options_and_descs[reserved_name] = "from reserved names in OutputWarehouse";
1146 }
1147 else if (param_type == "UserObjectName")
1148 {
1149 std::vector<UserObject *> user_objects;
1150 problem->theWarehouse()
1151 .query()
1152 .condition<AttribSystem>("UserObject")
1153 .condition<AttribThread>(0)
1154 .queryIntoUnsorted(user_objects);
1155 for (const auto & user_object : user_objects)
1156 options_and_descs[user_object->name()] = "from UserObjectWarehouse";
1157 }
1158}
for(PetscInt i=0;i< nvars;++i)
const MooseApp * queryCheckApp() const
Based class for output objects.
Definition Output.h:52
std::string name(const ElemQuality q)
IntRange< T > make_range(T beg, T end)

Referenced by addValuesToList().

◆ addParametersToList()

bool MooseServer::addParametersToList ( wasp::DataArray &  completionItems,
const InputParameters valid_params,
const std::set< std::string > &  existing_params,
int  replace_line_beg,
int  replace_char_beg,
int  replace_line_end,
int  replace_char_end,
const std::string &  filtering_prefix 
)
private

Add parameters that were previously gathered to list for completion.

Parameters
completionItems- list of completion objects to be filled out
valid_params- all valid parameters to add to completion list
existing_params- set of parameters already existing in input
replace_line_beg- start line of autocompletion replace range
replace_char_beg- start column of autocomplete replace range
replace_line_end- end line of autocomplete replacement range
replace_char_end- end column of autocompletion replace range
filtering_prefix- beginning text to filter list if not empty
Returns
- true if filling of completion items completed successfully

Definition at line 685 of file MooseServer.C.

693{
694 bool pass = true;
695
696 // walk over collection of all valid parameters and build completion list
697 for (const auto & valid_params_iter : valid_params)
698 {
699 const std::string & param_name = valid_params_iter.first;
700 bool deprecated = valid_params.isParamDeprecated(param_name);
701 bool is_private = valid_params.isPrivate(param_name);
702
703 // filter out parameters that are deprecated, private, or already exist
704 if (deprecated || is_private || existing_params.count(param_name))
705 continue;
706
707 // filter out parameters that do not begin with prefix if one was given
708 if (param_name.rfind(filtering_prefix, 0) != 0)
709 continue;
710
711 // process parameter description and type to use in input default value
712 std::string dirty_type = valid_params.type(param_name);
713 std::string clean_type = MooseUtils::prettyCppType(dirty_type);
714 std::string basic_type = JsonSyntaxTree::basicCppType(clean_type);
715 std::string doc_string = valid_params.getDocString(param_name);
716 MooseUtils::escape(doc_string);
717
718 // use basic type to decide if parameter is array and quotes are needed
719 bool is_array = basic_type.compare(0, 6, "Array:") == 0;
720
721 // remove any array prefixes from basic type string and leave base type
722 pcrecpp::RE("(Array:)*(.*)").GlobalReplace("\\2", &basic_type);
723
724 // prepare clean cpp type string to be used for key to find input paths
725 pcrecpp::RE(".+<([A-Za-z0-9_' ':]*)>.*").GlobalReplace("\\1", &clean_type);
726
727 // decide completion item kind that client may use to display list icon
728 int complete_kind = getCompletionItemKind(valid_params, param_name, clean_type, true);
729
730 // default value for completion to be built using parameter information
731 std::string default_value;
732
733 // first if parameter default is set then use it to build default value
734 if (valid_params.isParamValid(param_name))
735 {
736 default_value = JsonSyntaxTree::buildOutputString(valid_params_iter);
737 default_value = MooseUtils::trim(default_value);
738 }
739
740 // otherwise if parameter has coupled default then use as default value
741 else if (valid_params.hasDefaultCoupledValue(param_name))
742 {
743 std::ostringstream oss;
744 oss << valid_params.defaultCoupledValue(param_name);
745 default_value = oss.str();
746 }
747
748 // switch 1 to true or 0 to false if boolean parameter as default value
749 if (basic_type == "Boolean" && default_value == "1")
750 default_value = "true";
751 else if (basic_type == "Boolean" && default_value == "0")
752 default_value = "false";
753
754 // wrap default value with single quotes if it exists and type is array
755 std::string array_quote = is_array && !default_value.empty() ? "'" : "";
756
757 // choose format of insertion text based on if client supports snippets
758 int text_format;
759 std::string insert_text;
760 if (client_snippet_support && !default_value.empty())
761 {
762 text_format = wasp::lsp::m_text_format_snippet;
763 insert_text = param_name + " = " + array_quote + "${1:" + default_value + "}" + array_quote;
764 }
765 else
766 {
767 text_format = wasp::lsp::m_text_format_plaintext;
768 insert_text = param_name + " = " + array_quote + default_value + array_quote;
769 }
770 // finally build full insertion from parameter name, quote, and default
771
772 // add parameter label, insert text, and description to completion list
773 completionItems.push_back(wasp::DataObject());
774 wasp::DataObject * item = completionItems.back().to_object();
775 pass &= wasp::lsp::buildCompletionObject(*item,
776 errors,
777 param_name,
778 replace_line_beg,
779 replace_char_beg,
780 replace_line_end,
781 replace_char_end,
782 insert_text,
783 complete_kind,
784 "",
785 doc_string,
786 false,
787 false,
788 text_format);
789 }
790
791 return pass;
792}
bool isPrivate(const std::string &name) const
Returns a Boolean indicating whether the specified parameter is private or not.
std::string getDocString(const std::string &name) const
Returns the documentation string for the specified parameter name.
std::string type(const std::string &name) const
Prints the type of the requested parameter by name.
bool hasDefaultCoupledValue(const std::string &coupling_name) const
Return whether or not the requested parameter has a default coupled value.
Real defaultCoupledValue(const std::string &coupling_name, unsigned int i=0) const
Get the default value for an optionally coupled variable.
bool isParamDeprecated(const std::string &name) const
Returns True if the parameters is deprecated.
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another,...
static std::string basicCppType(const std::string &cpp_type)
static std::string buildOutputString(const std::iterator_traits< InputParameters::iterator >::value_type &p)
int getCompletionItemKind(const InputParameters &valid_params, const std::string &param_name, const std::string &clean_type, bool is_param)
Get completion item kind value that client may use for icon in list.
void escape(std::string &str)
Definition MooseUtils.C:218
std::string trim(const std::string &str, const std::string &white_space=" \t\n\v\f\r")
Standard scripting language trim function.
std::string prettyCppType(const std::string &cpp_type)

Referenced by gatherDocumentCompletionItems().

◆ addResourcesForDocument()

void MooseServer::addResourcesForDocument ( )
private

Add paths from includes and FileName parameters for client to watch.

Definition at line 298 of file MooseServer.C.

299{
300 // return without any resources added for document if parser root is null
301 auto root_ptr = queryRoot();
302 if (!root_ptr)
303 return;
304 auto & root = *root_ptr;
305
306 // return without document resources added if client does not watch files
307 if (!client_watcher_support)
308 return;
309
310 // get input parse tree root node to be used for gathering resource files
311 wasp::HITNodeView view_root = root.getNodeView();
312 std::set<std::string> include_paths, filename_vals, resource_uris;
313
314 // gather paths of include inputs and add to resource uris if files exist
315 view_root.node_pool()->descendant_include_paths(include_paths);
316 for (const auto & include_path : include_paths)
317 {
318 auto normalized = std::filesystem::path(include_path).lexically_normal().string();
319 if (MooseUtils::checkFileReadable(normalized, false, false, false))
320 resource_uris.insert(wasp::lsp::prefixUriScheme(normalized));
321 }
322
323 // gather paths of FileName types and add to resource uris if files exist
324 getFileNameTypeValues(filename_vals, view_root);
325 for (const auto & filename_val : filename_vals)
326 {
327 auto input_path = wasp::lsp::removeUriScheme(document_path);
328 auto input_base = std::filesystem::path(input_path).parent_path();
329 auto fname_path = std::filesystem::path(filename_val);
330 auto fname_absl = fname_path.is_absolute() ? fname_path : (input_base / fname_path);
331 auto normalized = fname_absl.lexically_normal().string();
332 if (MooseUtils::checkFileReadable(normalized, false, false, false))
333 resource_uris.insert(wasp::lsp::prefixUriScheme(normalized));
334 }
335
336 // add collection of all gathered paths as resources for current document
337 setResourcesForBase(document_path, resource_uris);
338}
void getFileNameTypeValues(std::set< std::string > &filename_vals, wasp::HITNodeView parent)
Recursively walk input to gather all FileName type parameter values.
const hit::Node * queryRoot() const
bool checkFileReadable(const std::string &filename, bool check_line_endings, bool throw_on_unreadable, bool check_for_git_lfs_pointer)
Definition MooseUtils.C:265

Referenced by parseDocumentForDiagnostics().

◆ addSubblocksToList()

bool MooseServer::addSubblocksToList ( wasp::DataArray &  completionItems,
const std::string &  object_path,
int  replace_line_beg,
int  replace_char_beg,
int  replace_line_end,
int  replace_char_end,
const std::string &  filtering_prefix,
bool  request_on_block_decl 
)
private

Add subblocks to completion list for request path, line, and column.

Parameters
completionItems- list of completion objects to be filled out
object_path- full node path where autocomplete was requested
replace_line_beg- start line of autocompletion replace range
replace_char_beg- start column of autocomplete replace range
replace_line_end- end line of autocomplete replacement range
replace_char_end- end column of autocompletion replace range
filtering_prefix- beginning text to filter list if not empty
Returns
- true if filling of completion items completed successfully

Definition at line 795 of file MooseServer.C.

803{
804 Syntax & syntax = getRegistrationApp().syntax();
805
806 // set used to prevent reprocessing syntax paths for more than one action
807 std::set<std::string> syntax_paths_processed;
808
809 // build map of all syntax paths to names for subblocks and save to reuse
810 auto & metadata = getSyntaxMetadata();
811 if (metadata.syntax_to_subblocks.empty())
812 {
813 for (const auto & syntax_path_iter : syntax.getAssociatedActions())
814 {
815 std::string syntax_path = "/" + syntax_path_iter.first;
816
817 // skip current syntax path if already processed for different action
818 if (!syntax_paths_processed.insert(syntax_path).second)
819 continue;
820
821 // walk backward through syntax path adding subblock names to parents
822 for (std::size_t last_sep; (last_sep = syntax_path.find_last_of("/")) != std::string::npos;)
823 {
824 std::string subblock_name = syntax_path.substr(last_sep + 1);
825 syntax_path = syntax_path.substr(0, last_sep);
826 metadata.syntax_to_subblocks[syntax_path].insert(subblock_name);
827 }
828 }
829 }
830
831 // get registered syntax from object path using map of paths to subblocks
832 auto registered_syntax = syntax.isAssociated(object_path, nullptr, metadata.syntax_to_subblocks);
833
834 bool pass = true;
835
836 // walk over subblock names if found or at root and build completion list
837 if (!registered_syntax.empty() || object_path == "/")
838 {
839 // choose format of insertion text based on if client supports snippets
840 int text_format = client_snippet_support ? wasp::lsp::m_text_format_snippet
841 : wasp::lsp::m_text_format_plaintext;
842
843 for (const auto & subblock_name : metadata.syntax_to_subblocks[registered_syntax])
844 {
845 // filter subblock if it does not begin with prefix and one was given
846 if (subblock_name != "*" && subblock_name.rfind(filtering_prefix, 0) != 0)
847 continue;
848
849 std::string doc_string;
850 std::string insert_text;
851 int complete_kind;
852
853 // build required parameter list for each block to use in insert text
854 const std::string full_block_path = object_path + "/" + subblock_name;
855 const std::string req_params = getRequiredParamsText(full_block_path, "", {}, " ");
856
857 // customize description and insert text for star and named subblocks
858 if (subblock_name == "*")
859 {
860 doc_string = "custom user named block";
861 insert_text = (request_on_block_decl ? "" : "[") +
862 (filtering_prefix.size() ? filtering_prefix : "block_name") + "]" +
863 req_params + "\n " + (client_snippet_support ? "$0" : "") + "\n[]";
864 complete_kind = wasp::lsp::m_comp_kind_variable;
865 }
866 else
867 {
868 doc_string = "application named block";
869 insert_text = (request_on_block_decl ? "" : "[") + subblock_name + "]" + req_params +
870 "\n " + (client_snippet_support ? "$0" : "") + "\n[]";
871 complete_kind = wasp::lsp::m_comp_kind_struct;
872 }
873
874 // add subblock name, insert text, and description to completion list
875 completionItems.push_back(wasp::DataObject());
876 wasp::DataObject * item = completionItems.back().to_object();
877 pass &= wasp::lsp::buildCompletionObject(*item,
878 errors,
879 subblock_name,
880 replace_line_beg,
881 replace_char_beg,
882 replace_line_end,
883 replace_char_end,
884 insert_text,
885 complete_kind,
886 "",
887 doc_string,
888 false,
889 false,
890 text_format);
891 }
892 }
893
894 return pass;
895}
Syntax & syntax()
Returns a writable reference to the syntax object.
Definition MooseApp.h:231
std::string getRequiredParamsText(const std::string &subblock_path, const std::string &subblock_type, const std::set< std::string > &existing_params, const std::string &indent_spaces)
Get required parameter completion text list for given subblock path.
MooseApp & getRegistrationApp()
SyntaxMetadata & getSyntaxMetadata()
Holding syntax for parsing input files.
Definition Syntax.h:22
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 ...
Definition Syntax.C:252

Referenced by gatherDocumentCompletionItems().

◆ addValuesToList()

bool MooseServer::addValuesToList ( wasp::DataArray &  completionItems,
const InputParameters valid_params,
const std::set< std::string > &  existing_params,
const std::set< std::string > &  existing_subblocks,
const std::string &  param_name,
const std::set< std::string > &  obj_act_tasks,
const std::string &  object_path,
int  replace_line_beg,
int  replace_char_beg,
int  replace_line_end,
int  replace_char_end 
)
private

Add parameter values to completion list for request line and column.

Parameters
completionItems- list of completion objects to be filled out
valid_params- all valid parameters used for value completion
existing_params- set of parameters already existing in input
existing_subblocks- active and inactive subblock name values
param_name- name of input parameter for value autocompletion
obj_act_tasks- tasks to verify object type with valid syntax
object_path- full node path where autocomplete was requested
replace_line_beg- start line of autocompletion replace range
replace_char_beg- start column of autocomplete replace range
replace_line_end- end line of autocomplete replacement range
replace_char_end- end column of autocompletion replace range
Returns
- true if filling of completion items completed successfully

Definition at line 898 of file MooseServer.C.

909{
910 Syntax & syntax = getRegistrationApp().syntax();
911 Factory & factory = getRegistrationApp().getFactory();
912
913 // get clean type for path associations and basic type for boolean values
914 std::string dirty_type = valid_params.type(param_name);
915 std::string clean_type = MooseUtils::prettyCppType(dirty_type);
916 std::string basic_type = JsonSyntaxTree::basicCppType(clean_type);
917
918 // remove any array prefixes from basic type string and replace with base
919 pcrecpp::RE("(Array:)*(.*)").GlobalReplace("\\2", &basic_type);
920
921 // prepare clean cpp type string to be used for a key to find input paths
922 pcrecpp::RE(".+<([A-Za-z0-9_' ':]*)>.*").GlobalReplace("\\1", &clean_type);
923
924 // decide completion item kind that client may use to display a list icon
925 int complete_kind = getCompletionItemKind(valid_params, param_name, clean_type, false);
926
927 // map used to gather options and descriptions for value completion items
928 std::map<std::string, std::string> options_and_descs;
929
930 // first if parameter name is active or inactive then use input subblocks
931 if (param_name == "active" || param_name == "inactive")
932 for (const auto & subblock_name : existing_subblocks)
933 options_and_descs[subblock_name] = "subblock name";
934
935 // otherwise if parameter type is boolean then use true and false strings
936 else if (basic_type == "Boolean")
937 {
938 options_and_descs["true"];
939 options_and_descs["false"];
940 }
941
942 // otherwise if parameter type is one of the enums then use valid options
943 else if (valid_params.have_parameter<MooseEnum>(param_name))
944 getEnumsAndDocs(valid_params.get<MooseEnum>(param_name), options_and_descs);
945 else if (valid_params.have_parameter<MultiMooseEnum>(param_name))
946 getEnumsAndDocs(valid_params.get<MultiMooseEnum>(param_name), options_and_descs);
947 else if (valid_params.have_parameter<ExecFlagEnum>(param_name))
948 getEnumsAndDocs(valid_params.get<ExecFlagEnum>(param_name), options_and_descs);
949 else if (valid_params.have_parameter<std::vector<MooseEnum>>(param_name))
950 getEnumsAndDocs(valid_params.get<std::vector<MooseEnum>>(param_name)[0], options_and_descs);
951
952 // otherwise if parameter is Application type then use all available apps
953 else if (object_path == "/Application" && param_name == "type")
954 {
955 for (const auto & apps_iter : AppFactory::instance().registeredObjects())
956 {
957 const std::string & app_name = apps_iter.first;
958 const InputParameters & app_params = apps_iter.second->buildParameters();
959 std::string app_description = app_params.getClassDescription();
960 MooseUtils::escape(app_description);
961 options_and_descs[app_name] = app_description;
962 }
963 }
964
965 // otherwise if parameter name is type then use all verified object names
966 else if (param_name == "type")
967 {
968 // walk over entire set of objects that have been registered in factory
969 for (const auto & objects_iter : factory.registeredObjects())
970 {
971 const std::string & object_name = objects_iter.first;
972 const InputParameters & object_params = objects_iter.second->buildParameters();
973
974 // build required parameter list for each block to use in insert text
975 std::string req_params = getRequiredParamsText(object_path, object_name, existing_params, "");
976 req_params += req_params.size() ? "\n" + std::string(client_snippet_support ? "$0" : "") : "";
977
978 // check if object has registered base parameter that can be verified
979 if (!object_params.hasBase())
980 continue;
981 const std::string & moose_base = object_params.getBase();
982
983 // walk over gathered MooseObjectAction tasks and add if base matches
984 for (const auto & obj_act_task : obj_act_tasks)
985 {
986 if (!syntax.verifyMooseObjectTask(moose_base, obj_act_task))
987 continue;
988 std::string type_description = object_params.getClassDescription();
989 MooseUtils::escape(type_description);
990 options_and_descs[object_name + req_params] = type_description;
991 break;
992 }
993 }
994 }
995
996 // otherwise if parameter type has any associated syntax then use lookups
997 else
998 {
999 // build map of parameter types to input lookup paths and save to reuse
1000 auto & metadata = getSyntaxMetadata();
1001 if (metadata.type_to_input_paths.empty())
1002 {
1003 for (const auto & associated_types_iter : syntax.getAssociatedTypes())
1004 {
1005 const std::string & type = associated_types_iter.second;
1006 const std::string & path = associated_types_iter.first;
1007 metadata.type_to_input_paths[type].insert(path);
1008 }
1009 }
1010
1011 // check for input lookup paths that are associated with parameter type
1012 const auto & input_path_iter = metadata.type_to_input_paths.find(clean_type);
1013
1014 if (input_path_iter != metadata.type_to_input_paths.end())
1015 {
1016 wasp::HITNodeView view_root = getRoot().getNodeView();
1017
1018 // walk over all syntax paths that are associated with parameter type
1019 for (const auto & input_path : input_path_iter->second)
1020 {
1021 // use wasp siren to gather all input values at current lookup path
1022 wasp::SIRENInterpreter<> selector;
1023 if (!selector.parseString(input_path))
1024 continue;
1025 wasp::SIRENResultSet<wasp::HITNodeView> results;
1026 std::size_t count = selector.evaluate(view_root, results);
1027
1028 // walk over results and add each input value found at current path
1029 for (std::size_t i = 0; i < count; i++)
1030 if (results.adapted(i).type() == wasp::OBJECT)
1031 options_and_descs[results.adapted(i).name()] = "from /" + input_path;
1032 }
1033 }
1034
1035 // warehouse based completion is unavailable if problem failed to build
1036 // input lookup based completion works even when problem fails to build
1037 // so warehouse completion supplements lookups rather than replacing it
1038 addObjectsFromWarehouses(clean_type, options_and_descs);
1039 }
1040
1041 // choose format of insertion text based on if client has snippet support
1042 int text_format = client_snippet_support ? wasp::lsp::m_text_format_snippet
1043 : wasp::lsp::m_text_format_plaintext;
1044
1045 bool pass = true;
1046
1047 // walk over pairs of options with descriptions and build completion list
1048 for (const auto & option_and_desc : options_and_descs)
1049 {
1050 const std::string & insert_text = option_and_desc.first;
1051 const std::string & option_name = insert_text.substr(0, insert_text.find('\n'));
1052 const std::string & description = option_and_desc.second;
1053
1054 // add option name, insertion range, and description to completion list
1055 completionItems.push_back(wasp::DataObject());
1056 wasp::DataObject * item = completionItems.back().to_object();
1057 pass &= wasp::lsp::buildCompletionObject(*item,
1058 errors,
1059 option_name,
1060 replace_line_beg,
1061 replace_char_beg,
1062 replace_line_end,
1063 replace_char_end,
1064 insert_text,
1065 complete_kind,
1066 "",
1067 description,
1068 false,
1069 false,
1070 text_format);
1071 }
1072
1073 return pass;
1074}
unsigned int count
Definition MortarUtils.C:53
Generic AppFactory class for building Application objects.
Definition AppFactory.h:55
A MultiMooseEnum object to hold "execute_on" flags.
Generic factory class for build all sorts of objects.
Definition Factory.h:29
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
std::vector< std::pair< R1, R2 > > get(const std::string &param1, const std::string &param2) const
Combine two vector parameters into a single vector of pairs.
bool have_parameter(std::string_view name) const
A wrapper around the Parameters base class method.
std::string getClassDescription() const
Returns the class description.
const std::string & getBase() const
bool hasBase() const
Factory & getFactory()
Retrieve a writable reference to the Factory associated with this App.
Definition MooseApp.h:407
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition MooseEnum.h:55
void addObjectsFromWarehouses(const std::string &param_type, std::map< std::string, std::string > &options_and_descs)
Supplement completion list with objects in warehouses if applicable.
void getEnumsAndDocs(MooseEnumType &moose_enum_param, std::map< std::string, std::string > &options_and_descs)
Fill map of all options and descriptions if parameter is moose enum.
const hit::Node & getRoot() const
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type.
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...
Definition Syntax.C:335

Referenced by gatherDocumentCompletionItems().

◆ buildDistPlotResponses()

void MooseServer::buildDistPlotResponses ( wasp::DataArray &  plotting_responses,
FEProblemBase problem,
const std::string &  object_name,
const std::string &  object_type 
)
private

Compute PDF and CDF, build CustomPlot objects, and add to responses.

Parameters
plotting_responses- array to be filled by CustomPlot objects
problem- problem to query warehouses when building plot data
object_name- name of request object to use for problem query
object_type- type of request object to use in title for plot

Definition at line 1985 of file MooseServer.C.

1989{
1990 // get distribution from problem that is registered for given object name
1991 const Distribution & dist = problem.getDistribution(object_name);
1992
1993 // pick plot x-range using quantiles to be generic for distribution types
1994 const double min_x = dist.quantile(_dist_plot_quantile_bound);
1995 const double max_x = dist.quantile(1.0 - _dist_plot_quantile_bound);
1996 const double del_x = (max_x - min_x) / (_dist_plot_num_points - 1);
1997
1998 // return without any plots added if any calculated values are not finite
1999 if (!std::isfinite(min_x) || !std::isfinite(max_x) || max_x <= min_x || !std::isfinite(del_x))
2000 return;
2001
2002 // use uniform grid of x-axis graph keys to sample plot values for y-axis
2003 std::vector<double> graph_keys(_dist_plot_num_points);
2004 std::vector<double> pdf_values(_dist_plot_num_points);
2005 std::vector<double> cdf_values(_dist_plot_num_points);
2006
2007 // calculate PDF values and CDF values for each key within range of graph
2008 for (std::size_t i = 0; i < _dist_plot_num_points; i++)
2009 {
2010 graph_keys[i] = min_x + (i * del_x);
2011 pdf_values[i] = dist.pdf(graph_keys[i]);
2012 cdf_values[i] = dist.cdf(graph_keys[i]);
2013
2014 // return without any plots added if any PDF or CDF value is not finite
2015 if (!std::isfinite(pdf_values[i]) || !std::isfinite(cdf_values[i]))
2016 return;
2017 }
2018
2019 // lambda to build CustomPlot object for distribution and add to response
2020 auto add_dist_to_plot = [&](const std::string & dist_type, const std::vector<double> & graph_vals)
2021 {
2022 std::string plot_title = object_name + " " + object_type + " " + dist_type + " Distribution";
2023 std::string x_axis_label = "x values";
2024 std::string y_axis_label = dist_type + " values";
2025 wasp::CustomPlot plot_object;
2026 buildLineGraphPlot(plot_object, plot_title, x_axis_label, y_axis_label, graph_keys, graph_vals);
2027 plotting_responses.push_back(wasp::serializeCustomPlot(plot_object));
2028 };
2029
2030 // build CustomPlot object for PDF values, serialize, and add to response
2031 add_dist_to_plot("PDF", pdf_values);
2032
2033 // build CustomPlot object for CDF values, serialize, and add to response
2034 add_dist_to_plot("CDF", cdf_values);
2035}
All Distributions should inherit from this class.
virtual Real pdf(const Real &x) const =0
Compute the probability with given probability distribution function (PDF) at x.
virtual Real quantile(const Real &y) const =0
Compute the inverse CDF (quantile function) value for given variable value y.
virtual Real cdf(const Real &x) const =0
Compute the cumulative probability with given cumulative probability distribution (CDF) at x.
virtual Distribution & getDistribution(const std::string &name)
void buildLineGraphPlot(wasp::CustomPlot &plot_object, const std::string &plot_title, const std::string &x_axis_label, const std::string &y_axis_label, const std::vector< double > &graph_keys, const std::vector< double > &graph_vals)
Build CustomPlot graph with provided keys, values, and plot title.

Referenced by gatherPlottingResponses().

◆ buildFuncPlotResponse()

void MooseServer::buildFuncPlotResponse ( wasp::DataArray &  plotting_responses,
FEProblemBase problem,
const std::string &  object_name,
const std::string &  object_type 
)
private

Gather function data, build CustomPlot object, and add to responses.

Parameters
plotting_responses- array to be filled by CustomPlot objects
problem- problem to query warehouses when building plot data
object_name- name of request object to use for problem query
object_type- type of request object to use in title for plot

Definition at line 1953 of file MooseServer.C.

1957{
1958 // get function from problem and return with no plots added if wrong type
1959 const auto * pw_func = dynamic_cast<const PiecewiseBase *>(&problem.getFunction(object_name));
1960 if (!pw_func)
1961 return;
1962
1963 // return without adding plot response objects when function size is zero
1964 if (pw_func->functionSize() == 0)
1965 return;
1966
1967 // walk over piecewise function and gather keys and values for line graph
1968 std::vector<double> graph_keys, graph_vals;
1969 for (std::size_t i = 0; i < pw_func->functionSize(); i++)
1970 {
1971 graph_keys.push_back(pw_func->domain(i));
1972 graph_vals.push_back(pw_func->range(i));
1973 }
1974
1975 // build CustomPlot object from function data then serialize for response
1976 std::string plot_title = object_name + " " + object_type + " Function";
1977 std::string x_axis_label = "abscissa values";
1978 std::string y_axis_label = "ordinate values";
1979 wasp::CustomPlot plot_object;
1980 buildLineGraphPlot(plot_object, plot_title, x_axis_label, y_axis_label, graph_keys, graph_vals);
1981 plotting_responses.push_back(wasp::serializeCustomPlot(plot_object));
1982}
virtual Function & getFunction(const std::string &name, const THREAD_ID tid=0)
Function base which provides a piecewise approximation to a specified (x,y) point data set.

Referenced by gatherPlottingResponses().

◆ buildLineGraphPlot()

void MooseServer::buildLineGraphPlot ( wasp::CustomPlot &  plot_object,
const std::string &  plot_title,
const std::string &  x_axis_label,
const std::string &  y_axis_label,
const std::vector< double > &  graph_keys,
const std::vector< double > &  graph_vals 
)
private

Build CustomPlot graph with provided keys, values, and plot title.

Parameters
plot_object- CustomPlot object to be built into line graph
plot_title- title for plot composed of block name and type
x_axis_label- label for x-axis of plot dependent upon type
y_axis_label- label for y-axis of plot dependent upon type
graph_keys- x values of function or distribution for graph
graph_vals- y values of function or distribution for graph

Definition at line 2038 of file MooseServer.C.

2044{
2045 // axis ranges
2046 double min_key = *std::min_element(graph_keys.begin(), graph_keys.end());
2047 double max_key = *std::max_element(graph_keys.begin(), graph_keys.end());
2048 double min_val = *std::min_element(graph_vals.begin(), graph_vals.end());
2049 double max_val = *std::max_element(graph_vals.begin(), graph_vals.end());
2050
2051 // widen extents
2052 double pad_factor = 0.05;
2053 double pad_x_axis = (max_key - min_key) * pad_factor;
2054 double pad_y_axis = (max_val - min_val) * pad_factor;
2055 if (pad_y_axis == 0)
2056 pad_y_axis = pad_factor;
2057 min_key -= pad_x_axis;
2058 max_key += pad_x_axis;
2059 min_val -= pad_y_axis;
2060 max_val += pad_y_axis;
2061
2062 // plot setup
2063 plot_object.title().text(plot_title);
2064 plot_object.title().font().pointsize(18);
2065 plot_object.title().visible(true);
2066 plot_object.legend().visible(false);
2067
2068 // plot x-axis
2069 plot_object.x1Axis().label(x_axis_label);
2070 plot_object.x1Axis().rangeMin(min_key);
2071 plot_object.x1Axis().rangeMax(max_key);
2072 plot_object.x1Axis().scaleType(wasp::CustomPlot::stLinear);
2073 plot_object.x1Axis().labelType(wasp::CustomPlot::ltNumber);
2074 plot_object.x1Axis().labelFont().pointsize(18);
2075 plot_object.x1Axis().tickLabelFont().pointsize(16);
2076
2077 // plot y-axis
2078 plot_object.y1Axis().label(y_axis_label);
2079 plot_object.y1Axis().rangeMin(min_val);
2080 plot_object.y1Axis().rangeMax(max_val);
2081 plot_object.y1Axis().scaleType(wasp::CustomPlot::stLinear);
2082 plot_object.y1Axis().labelType(wasp::CustomPlot::ltNumber);
2083 plot_object.y1Axis().labelFont().pointsize(18);
2084 plot_object.y1Axis().tickLabelFont().pointsize(16);
2085
2086 // graph series
2087 auto line_graph = std::make_shared<wasp::CustomPlot::Graph>();
2088 line_graph->keys() = graph_keys;
2089 line_graph->values() = graph_vals;
2090 line_graph->scatterShape(wasp::CustomPlot::ssDisc);
2091 plot_object.series().push_back(line_graph);
2092}

Referenced by buildDistPlotResponses(), and buildFuncPlotResponse().

◆ connectionRead()

bool MooseServer::connectionRead ( wasp::DataObject &  object)
inlineprivate

Read from connection into object - specific to this server's connection.

Parameters
object- reference to object to be read into
Returns
- true if the read from the connection completed successfully

Definition at line 421 of file MooseServer.h.

421{ return _connection->read(object, errors); }

◆ connectionWrite()

bool MooseServer::connectionWrite ( wasp::DataObject &  object)
inlineprivate

Write object json to connection - specific to this server's connection.

Parameters
object- reference to object with contents to write to connection
Returns
- true if the write to the connection completed successfully

Definition at line 428 of file MooseServer.h.

428{ return _connection->write(object, errors); }

◆ formatDocument()

std::string MooseServer::formatDocument ( wasp::HITNodeView  parent,
std::size_t &  prev_line,
std::size_t  level 
)
private

Recursively walk down whole nodeview tree while formatting document.

Parameters
parent- nodeview for recursive tree traversal starting point
prev_line- line of last print for blanks and inline comments
level- current level in document tree to use for indentation
Returns
- formatted string that gets appended to each recursive call

Definition at line 1622 of file MooseServer.C.

1623{
1624 // build string of newline and indentation spaces from level and tab size
1625 std::string newline_indent = "\n" + std::string(level * _formatting_tab_size, ' ');
1626
1627 // lambda to format include data by replacing consecutive spaces with one
1628 auto collapse_spaces = [](std::string string_copy)
1629 {
1630 pcrecpp::RE("\\s+").Replace(" ", &string_copy);
1631 return string_copy;
1632 };
1633
1634 // formatted string that will be built recursively by appending each call
1635 std::string format_string;
1636
1637 // walk over all children of this node context and build formatted string
1638 for (const auto i : make_range(parent.child_count()))
1639 {
1640 // walk must be index based to catch file include and skip its children
1641 wasp::HITNodeView child = parent.child_at(i);
1642
1643 // get declarator to address shorthand syntax object with no declarator
1644 auto decl = child.child_count_by_name("decl") ? child.first_child_by_name("decl").data() : "";
1645
1646 // add blank line if necessary after previous line and before this line
1647 std::string blank = child.line() > prev_line + 1 ? "\n" : "";
1648
1649 // format include directive with indentation and collapse extra spacing
1650 if (child.type() == wasp::FILE)
1651 format_string += blank + newline_indent + MooseUtils::trim(collapse_spaces(child.data()));
1652
1653 // format normal comment with indentation and inline comment with space
1654 else if (child.type() == wasp::COMMENT)
1655 format_string += (child.line() == prev_line ? " " : blank + newline_indent) +
1656 MooseUtils::trim(child.data());
1657
1658 // pass object with no declarator through without increased indentation
1659 else if (child.type() == wasp::OBJECT && decl.empty())
1660 format_string += formatDocument(child, prev_line, level);
1661
1662 // format object recursively with indentation and without legacy syntax
1663 else if (child.type() == wasp::OBJECT)
1664 format_string += blank + newline_indent + "[" + decl + "]" +
1665 formatDocument(child, prev_line, level + 1) + newline_indent + "[]";
1666
1667 // format keyed value with indentation and calling reusable hit methods
1668 else if (child.type() == wasp::KEYED_VALUE || child.type() == wasp::ARRAY)
1669 {
1670 const std::string assign = wasp::is_override(child) ? child.child_at(1).data() : "=";
1671 const std::string prefix = newline_indent + decl + " " + assign + " ";
1672
1673 const std::string render_val = hit::extractValue(child.data());
1674 std::size_t val_column = child.child_count() > 2 ? child.child_at(2).column() : 0;
1675 std::size_t prefix_len = prefix.size() - 1;
1676
1677 format_string += blank + prefix + hit::formatValue(render_val, val_column, prefix_len);
1678 }
1679
1680 // set previous line reference used for blank lines and inline comments
1681 prev_line = child.last_line();
1682 }
1683
1684 // return formatted text string that gets appended to each recursive call
1685 return format_string;
1686}
std::string formatDocument(wasp::HITNodeView parent, std::size_t &prev_line, std::size_t level)
Recursively walk down whole nodeview tree while formatting document.

Referenced by formatDocument(), and gatherDocumentFormattingTextEdits().

◆ gatherDocumentCompletionItems()

bool MooseServer::gatherDocumentCompletionItems ( wasp::DataArray &  completionItems,
bool &  is_incomplete,
int  line,
int  character 
)
private

Gather document completion items - specific to this server implemention.

Parameters
completionItems- data array of completion item objects to fill
is_incomplete- flag indicating if the completions are complete
line- line to be used for completions gathering logic
character- column to be used for completions gathering logic
Returns
- true if the gathering of items completed successfully

Definition at line 397 of file MooseServer.C.

401{
402 auto root_ptr = queryRoot();
403
404 // add only root level blocks to completion list when parser root is null
405 if (!root_ptr)
406 return addSubblocksToList(completionItems, "/", line, character, line, character, "", false);
407 auto & root = *root_ptr;
408
409 // lambdas that will be used for checking completion request context type
410 auto is_request_in_open_block = [](wasp::HITNodeView request_context)
411 {
412 return request_context.type() == wasp::OBJECT || request_context.type() == wasp::DOCUMENT_ROOT;
413 };
414 auto is_request_on_param_decl = [](wasp::HITNodeView request_context)
415 {
416 return request_context.type() == wasp::DECL && request_context.has_parent() &&
417 (request_context.parent().type() == wasp::KEYED_VALUE ||
418 request_context.parent().type() == wasp::ARRAY);
419 };
420 auto is_request_on_block_decl = [](wasp::HITNodeView request_context)
421 {
422 return request_context.type() == wasp::DECL && request_context.has_parent() &&
423 request_context.parent().type() == wasp::OBJECT;
424 };
425
426 // get document tree root used to find node under request line and column
427 wasp::HITNodeView view_root = root.getNodeView();
428 wasp::HITNodeView request_context;
429
430 // find node under request location if it is not past all defined content
431 if (line + 1 < (int)view_root.last_line() ||
432 (line + 1 == (int)view_root.last_line() && character <= (int)view_root.last_column()))
433 request_context = wasp::findNodeUnderLineColumn(view_root, line + 1, character + 1);
434
435 // otherwise find last node in document with last line and column of tree
436 else
437 {
438 request_context =
439 wasp::findNodeUnderLineColumn(view_root, view_root.last_line(), view_root.last_column());
440
441 // change context to be parent block or grandparent if block terminator
442 wasp::HITNodeView object_context = request_context;
443 while (object_context.type() != wasp::OBJECT && object_context.has_parent())
444 object_context = object_context.parent();
445 if (request_context.type() == wasp::OBJECT_TERM && object_context.has_parent())
446 object_context = object_context.parent();
447 request_context = object_context;
448 }
449
450 // change context to equal sign if it is preceding node and in open block
451 if (is_request_in_open_block(request_context))
452 {
453 wasp::HITNodeView backup_context = request_context;
454 for (int backup_char = character; backup_context == request_context && --backup_char > 0;)
455 backup_context = wasp::findNodeUnderLineColumn(request_context, line + 1, backup_char + 1);
456 if (backup_context.type() == wasp::ASSIGN || backup_context.type() == wasp::OVERRIDE_ASSIGN)
457 request_context = backup_context;
458 }
459
460 // use request context type to set up replacement range and prefix filter
461 int replace_line_beg = line;
462 int replace_char_beg = character;
463 int replace_line_end = line;
464 int replace_char_end = character;
465 std::string filtering_prefix;
466 if (request_context.type() == wasp::DECL || request_context.type() == wasp::VALUE)
467 {
468 // completion on existing block name, parameter name, or value replaces
469 replace_line_beg = request_context.line() - 1;
470 replace_char_beg = request_context.column() - 1;
471 replace_line_end = request_context.last_line() - 1;
472 replace_char_end = request_context.last_column();
473 filtering_prefix = request_context.data();
474
475 // empty block name columns are same as bracket so bump replace columns
476 if (is_request_on_block_decl(request_context) && filtering_prefix.empty())
477 {
478 replace_char_beg++;
479 replace_char_end++;
480 }
481 }
482
483 // get name of request context direct parent node so it can be used later
484 const auto & parent_name = request_context.has_parent() ? request_context.parent().name() : "";
485
486 // get object context and value of type parameter for request if provided
487 wasp::HITNodeView object_context = request_context;
488 while (object_context.type() != wasp::OBJECT && object_context.has_parent())
489 object_context = object_context.parent();
490 if (is_request_on_block_decl(request_context))
491 object_context = object_context.parent();
492 const std::string & object_path = object_context.path();
493 wasp::HITNodeView type_node = object_context.first_child_by_name("type");
494 const std::string & object_type =
495 type_node.is_null() ? "" : wasp::strip_quotes(hit::extractValue(type_node.data()));
496
497 // get set of all parameter and subblock names already specified in input
498 std::set<std::string> existing_params, existing_subblocks;
499 getExistingInput(object_context, existing_params, existing_subblocks);
500
501 // set used to gather all parameters valid from object context of request
502 InputParameters valid_params = emptyInputParameters();
503
504 // set used to gather MooseObjectAction tasks to verify object parameters
505 std::set<std::string> obj_act_tasks;
506
507 // get set of global parameters, action parameters, and object parameters
508 getAllValidParameters(valid_params, object_path, object_type, obj_act_tasks);
509
510 bool pass = true;
511
512 // add gathered parameters to completion list with input range and prefix
513 if (is_request_in_open_block(request_context) || is_request_on_param_decl(request_context))
514 pass &= addParametersToList(completionItems,
515 valid_params,
516 existing_params,
517 replace_line_beg,
518 replace_char_beg,
519 replace_line_end,
520 replace_char_end,
521 filtering_prefix);
522
523 // add all valid subblocks to completion list with input range and prefix
524 if (is_request_in_open_block(request_context) || is_request_on_param_decl(request_context) ||
525 is_request_on_block_decl(request_context))
526 pass &= addSubblocksToList(completionItems,
527 object_path,
528 replace_line_beg,
529 replace_char_beg,
530 replace_line_end,
531 replace_char_end,
532 filtering_prefix,
533 is_request_on_block_decl(request_context));
534
535 // add valid parameter value options to completion list using input range
536 if ((request_context.type() == wasp::VALUE || request_context.type() == wasp::ASSIGN ||
537 request_context.type() == wasp::OVERRIDE_ASSIGN) &&
538 valid_params.getParametersList().count(parent_name))
539 pass &= addValuesToList(completionItems,
540 valid_params,
541 existing_params,
542 existing_subblocks,
543 parent_name,
544 obj_act_tasks,
545 object_path,
546 replace_line_beg,
547 replace_char_beg,
548 replace_line_end,
549 replace_char_end);
550
551 is_incomplete = !pass;
552
553 return pass;
554}
InputParameters emptyInputParameters()
void ErrorVector unsigned int
std::set< std::string > getParametersList() const
bool addSubblocksToList(wasp::DataArray &completionItems, const std::string &object_path, int replace_line_beg, int replace_char_beg, int replace_line_end, int replace_char_end, const std::string &filtering_prefix, bool request_on_block_decl)
Add subblocks to completion list for request path, line, and column.
void getExistingInput(wasp::HITNodeView parent_node, std::set< std::string > &existing_params, std::set< std::string > &existing_subblocks)
Get names of parameters and subblocks specified in given input node.
bool addParametersToList(wasp::DataArray &completionItems, const InputParameters &valid_params, const std::set< std::string > &existing_params, int replace_line_beg, int replace_char_beg, int replace_line_end, int replace_char_end, const std::string &filtering_prefix)
Add parameters that were previously gathered to list for completion.
bool addValuesToList(wasp::DataArray &completionItems, const InputParameters &valid_params, const std::set< std::string > &existing_params, const std::set< std::string > &existing_subblocks, const std::string &param_name, const std::set< std::string > &obj_act_tasks, const std::string &object_path, int replace_line_beg, int replace_char_beg, int replace_line_end, int replace_char_end)
Add parameter values to completion list for request line and column.
void getAllValidParameters(InputParameters &valid_params, const std::string &object_path, const std::string &object_type, std::set< std::string > &obj_act_tasks)
Get all global parameters, action parameters, and object parameters.

◆ gatherDocumentDefinitionLocations()

bool MooseServer::gatherDocumentDefinitionLocations ( wasp::DataArray &  definitionLocations,
int  line,
int  character 
)
private

Gather definition locations - specific to this server implemention.

Parameters
definitionLocations- data array of locations objects to fill
line- line to be used for locations gathering logic
character- column to be used for locations gathering logic
Returns
- true if the gathering of locations completed successfully

Definition at line 1161 of file MooseServer.C.

1164{
1165 Factory & factory = getRegistrationApp().getFactory();
1166
1167 // return without any definition locations added when parser root is null
1168 auto root_ptr = queryRoot();
1169 if (!root_ptr)
1170 return true;
1171 auto & root = *root_ptr;
1172
1173 // find hit node for zero based request line and column number from input
1174 wasp::HITNodeView view_root = root.getNodeView();
1175 wasp::HITNodeView request_context =
1176 wasp::findNodeUnderLineColumn(view_root, line + 1, character + 1);
1177
1178 // return without any definition locations added when node not value type
1179 if (request_context.type() != wasp::VALUE)
1180 return true;
1181
1182 // get name of parameter node parent of value and value string from input
1183 std::string param_name = request_context.has_parent() ? request_context.parent().name() : "";
1184 std::string val_string = request_context.last_as_string();
1185
1186 // add source code location if type parameter with registered object name
1187 if (param_name == "type" && factory.isRegistered(val_string))
1188 {
1189 // get file path and line number of source code registering object type
1190 FileLineInfo file_line_info = factory.getLineInfo(val_string);
1191
1192 // return without any definition locations added if file cannot be read
1193 if (!file_line_info.isValid() ||
1194 !MooseUtils::checkFileReadable(file_line_info.file(), false, false, false))
1195 return true;
1196
1197 // add file scheme prefix to front of file path to build definition uri
1198 auto location_uri = wasp::lsp::m_uri_prefix + file_line_info.file();
1199
1200 // add file uri and zero based line and column range to definition list
1201 definitionLocations.push_back(wasp::DataObject());
1202 wasp::DataObject * location = definitionLocations.back().to_object();
1203 return wasp::lsp::buildLocationObject(*location,
1204 errors,
1205 location_uri,
1206 file_line_info.line() - 1,
1207 0,
1208 file_line_info.line() - 1,
1209 1000);
1210 }
1211
1212 // get object context and value of type parameter for request if provided
1213 wasp::HITNodeView object_context = request_context;
1214 while (object_context.type() != wasp::OBJECT && object_context.has_parent())
1215 object_context = object_context.parent();
1216 const std::string & object_path = object_context.path();
1217 wasp::HITNodeView type_node = object_context.first_child_by_name("type");
1218 const std::string & object_type =
1219 type_node.is_null() ? "" : wasp::strip_quotes(hit::extractValue(type_node.data()));
1220
1221 // set used to gather all parameters valid from object context of request
1222 InputParameters valid_params = emptyInputParameters();
1223
1224 // set used to gather MooseObjectAction tasks to verify object parameters
1225 std::set<std::string> obj_act_tasks;
1226
1227 // get set of global parameters, action parameters, and object parameters
1228 getAllValidParameters(valid_params, object_path, object_type, obj_act_tasks);
1229
1230 // set used to gather nodes from input lookups custom sorted by locations
1231 SortedLocationNodes location_nodes(
1232 [](const wasp::HITNodeView & l, const wasp::HITNodeView & r)
1233 {
1234 const std::string & l_file = l.node_pool()->stream_name();
1235 const std::string & r_file = r.node_pool()->stream_name();
1236 return (l_file < r_file || (l_file == r_file && l.line() < r.line()) ||
1237 (l_file == r_file && l.line() == r.line() && l.column() < r.column()));
1238 });
1239
1240 // gather all lookup path nodes matching value if parameter name is valid
1241 for (const auto & valid_params_iter : valid_params)
1242 {
1243 if (valid_params_iter.first == param_name)
1244 {
1245 // get cpp type and prepare string for use as key finding input paths
1246 std::string dirty_type = valid_params.type(param_name);
1247 std::string clean_type = MooseUtils::prettyCppType(dirty_type);
1248 pcrecpp::RE(".+<([A-Za-z0-9_' ':]*)>.*").GlobalReplace("\\1", &clean_type);
1249
1250 // get set of nodes from associated path lookups matching input value
1251 getInputLookupDefinitionNodes(location_nodes, clean_type, val_string);
1252 break;
1253 }
1254 }
1255
1256 // add parameter declarator to set if none were gathered by input lookups
1257 if (location_nodes.empty() && request_context.has_parent() &&
1258 request_context.parent().child_count_by_name("decl"))
1259 location_nodes.insert(request_context.parent().first_child_by_name("decl"));
1260
1261 // add locations to definition list using lookups or parameter declarator
1262 return addLocationNodesToList(definitionLocations, location_nodes);
1263}
bool isRegistered(const std::string &obj_name) const
Returns a Boolean indicating whether an object type has been registered.
Definition Factory.h:152
FileLineInfo getLineInfo(const std::string &name) const
Gets file and line information where an object was initially registered.
Definition Factory.C:284
Holds file and line information.
bool isValid() const
int line() const
std::string file() const
void getInputLookupDefinitionNodes(SortedLocationNodes &location_nodes, const std::string &clean_type, const std::string &val_string)
Get set of nodes from associated path lookups matching value string.
std::set< wasp::HITNodeView, std::function< bool(const wasp::HITNodeView &, const wasp::HITNodeView &)> > SortedLocationNodes
SortedLocationNodes - type alias for set of nodes sorted by location.
Definition MooseServer.h:61
bool addLocationNodesToList(wasp::DataArray &defsOrRefsLocations, const SortedLocationNodes &location_nodes)
Add set of nodes sorted by location to definition or reference list.

◆ gatherDocumentFormattingTextEdits()

bool MooseServer::gatherDocumentFormattingTextEdits ( wasp::DataArray &  formattingTextEdits,
int  tab_size,
bool  insert_spaces 
)
private

Gather formatting text edits - specific to this server implemention.

Parameters
formattingTextEdits- data array of text edit objects to fill
tab_size- value of the size of a tab in spaces for formatting
insert_spaces- flag indicating whether to use spaces for tabs
Returns
- true if the gathering of text edits completed successfully

Definition at line 1573 of file MooseServer.C.

1576{
1577 // strip scheme prefix from document uri if it exists for parse file path
1578 std::string parse_file_path = document_path;
1579 pcrecpp::RE("(.*://)(.*)").Replace("\\2", &parse_file_path);
1580
1581 // input check expanded any brace expressions in cached tree so reprocess
1582 std::stringstream input_errors, input_stream(getDocumentText());
1583 wasp::DefaultHITInterpreter interpreter(input_errors);
1584
1585 // return without adding any formatting text edits if input parsing fails
1586 if (!interpreter.parseStream(input_stream, parse_file_path))
1587 return true;
1588
1589 // return without adding any formatting text edits if parser root is null
1590 if (interpreter.root().is_null())
1591 return true;
1592
1593 // get input root node line and column range to represent entire document
1594 wasp::HITNodeView view_root = interpreter.root();
1595 int document_start_line = view_root.line() - 1;
1596 int document_start_char = view_root.column() - 1;
1597 int document_last_line = view_root.last_line() - 1;
1598 int document_last_char = view_root.last_column();
1599
1600 // set number of spaces for indentation and build formatted document text
1601 _formatting_tab_size = tab_size;
1602 std::size_t starting_line = view_root.line() - 1;
1603 std::string document_format = formatDocument(view_root, starting_line, 0);
1604
1605 // remove beginning newline character from formatted document text string
1606 document_format.erase(0, 1);
1607
1608 // add formatted text with whole line and column range to formatting list
1609 formattingTextEdits.push_back(wasp::DataObject());
1610 wasp::DataObject * item = formattingTextEdits.back().to_object();
1611 bool pass = wasp::lsp::buildTextEditObject(*item,
1612 errors,
1613 document_start_line,
1614 document_start_char,
1615 document_last_line,
1616 document_last_char,
1617 document_format);
1618 return pass;
1619}

◆ gatherDocumentReferencesLocations()

bool MooseServer::gatherDocumentReferencesLocations ( wasp::DataArray &  referencesLocations,
int  line,
int  character,
bool  include_declaration 
)
private

Gather references locations - specific to this server implemention.

Parameters
referencesLocations- data array of locations objects to fill
line- line to be used for locations gathering logic
character- column to be used for locations gathering logic
include_declaration- flag indicating declaration inclusion
Returns
- true if the gathering of locations completed successfully

Definition at line 1453 of file MooseServer.C.

1457{
1458 Syntax & syntax = getRegistrationApp().syntax();
1459
1460 // return without adding any reference locations when parser root is null
1461 auto root_ptr = queryRoot();
1462 if (!root_ptr)
1463 return true;
1464 auto & root = *root_ptr;
1465
1466 // find hit node for zero based request line and column number from input
1467 wasp::HITNodeView view_root = root.getNodeView();
1468 wasp::HITNodeView request_context =
1469 wasp::findNodeUnderLineColumn(view_root, line + 1, character + 1);
1470
1471 // return without adding any references when request not block declarator
1472 if ((request_context.type() != wasp::DECL && request_context.type() != wasp::DOT_SLASH &&
1473 request_context.type() != wasp::LBRACKET && request_context.type() != wasp::RBRACKET) ||
1474 !request_context.has_parent() || request_context.parent().type() != wasp::OBJECT)
1475 return true;
1476
1477 // get input path and block name of declarator located at request context
1478 const std::string & inp_path = request_context.parent().path();
1479 const std::string & inp_name = request_context.parent().name();
1480
1481 // build map from input lookup paths to parameter types and save to reuse
1482 auto & metadata = getSyntaxMetadata();
1483 if (metadata.input_path_to_types.empty())
1484 for (const auto & associated_types_iter : syntax.getAssociatedTypes())
1485 {
1486 const std::string & path = associated_types_iter.first;
1487 const std::string & type = associated_types_iter.second;
1488 metadata.input_path_to_types[path].insert(type);
1489 }
1490
1491 // get registered syntax from block path with map of input paths to types
1492 bool is_parent;
1493 auto registered_syntax = syntax.isAssociated(inp_path, &is_parent, metadata.input_path_to_types);
1494
1495 // return without adding any references if syntax has no types associated
1496 if (is_parent || !metadata.input_path_to_types.count(registered_syntax))
1497 return true;
1498
1499 // get set of parameter types which are associated with registered syntax
1500 const std::set<std::string> & target_types = metadata.input_path_to_types.at(registered_syntax);
1501
1502 // set used to gather nodes collected by value custom sorted by locations
1503 SortedLocationNodes match_nodes(
1504 [](const wasp::HITNodeView & l, const wasp::HITNodeView & r)
1505 {
1506 const std::string & l_file = l.node_pool()->stream_name();
1507 const std::string & r_file = r.node_pool()->stream_name();
1508 return (l_file < r_file || (l_file == r_file && l.line() < r.line()) ||
1509 (l_file == r_file && l.line() == r.line() && l.column() < r.column()));
1510 });
1511
1512 // walk input recursively and gather all nodes that match value and types
1513 getNodesByValueAndTypes(match_nodes, view_root, inp_name, target_types);
1514
1515 // return without adding any references if no nodes match value and types
1516 if (match_nodes.empty())
1517 return true;
1518
1519 // add request context node to set if declaration inclusion was specified
1520 if (include_declaration && request_context.parent().child_count_by_name("decl"))
1521 match_nodes.insert(request_context.parent().first_child_by_name("decl"));
1522
1523 // add locations to references list with nodes that match value and types
1524 return addLocationNodesToList(referencesLocations, match_nodes);
1525}
void getNodesByValueAndTypes(SortedLocationNodes &match_nodes, wasp::HITNodeView view_parent, const std::string &target_value, const std::set< std::string > &target_types)
Recursively walk input to gather all nodes matching value and types.

◆ gatherDocumentSymbols()

bool MooseServer::gatherDocumentSymbols ( wasp::DataArray &  documentSymbols)
private

Gather document symbols - specific to this server implemention.

Parameters
documentSymbols- data array of symbols data objects to fill
Returns
- true if the gathering of symbols completed successfully

Definition at line 1689 of file MooseServer.C.

1690{
1691 // return prior to starting document symbol tree when parser root is null
1692 auto root_ptr = queryRoot();
1693 if (!root_ptr)
1694 return true;
1695 auto & root = *root_ptr;
1696
1697 wasp::HITNodeView view_root = root.getNodeView();
1698
1699 bool pass = true;
1700
1701 // walk over all children of root node context and build document symbols
1702 for (const auto i : make_range(view_root.child_count()))
1703 {
1704 // walk must be index based to catch file include and skip its children
1705 wasp::HITNodeView view_child = view_root.child_at(i);
1706
1707 // set up name, zero based line and column range, kind, and detail info
1708 std::string name = view_child.name();
1709 int line = view_child.line() - 1;
1710 int column = view_child.column() - 1;
1711 int last_line = view_child.last_line() - 1;
1712 int last_column = view_child.last_column();
1713 int symbol_kind = getDocumentSymbolKind(view_child);
1714 std::string detail =
1715 !view_child.first_child_by_name("type").is_null()
1716 ? wasp::strip_quotes(hit::extractValue(view_child.first_child_by_name("type").data()))
1717 : "";
1718
1719 // build document symbol object from node child info and push to array
1720 documentSymbols.push_back(wasp::DataObject());
1721 wasp::DataObject * data_child = documentSymbols.back().to_object();
1722 pass &= wasp::lsp::buildDocumentSymbolObject(*data_child,
1723 errors,
1724 (name.empty() ? "void" : name),
1725 detail,
1726 symbol_kind,
1727 false,
1728 line,
1729 column,
1730 last_line,
1731 last_column,
1732 line,
1733 column,
1734 last_line,
1735 last_column);
1736
1737 // call method to recursively fill document symbols for each node child
1738 pass &= traverseParseTreeAndFillSymbols(view_child, *data_child);
1739 }
1740
1741 return pass;
1742}
int getDocumentSymbolKind(wasp::HITNodeView symbol_node)
Get document symbol kind value that client may use for outline icon.
bool traverseParseTreeAndFillSymbols(wasp::HITNodeView view_parent, wasp::DataObject &data_parent)
Recursively fill document symbols from the given node.

◆ gatherExtensionResponses()

bool MooseServer::gatherExtensionResponses ( wasp::DataArray &  extensionResponses,
const std::string &  extensionMethod,
int  line,
int  character 
)
private

Gather extension responses - specific to this server implemention.

Parameters
extensionResponses- data array of custom responses to fill
extensionMethod- name for current extension request method
line- zero-based line to use for logic of custom extension
character- zero-based column for logic of custom extension
Returns
- true if request successfully handled with response built

Definition at line 1896 of file MooseServer.C.

1900{
1901 // use appropriate method to fill response based on extension method name
1902 bool pass = true;
1903 if (extensionMethod == "plotting")
1904 pass = gatherPlottingResponses(extensionResponses, line, character);
1905 return pass;
1906}
bool gatherPlottingResponses(wasp::DataArray &plotting_responses, int line, int character)
Build CustomPlot extension responses when method name is plotting.

◆ gatherPlottingResponses()

bool MooseServer::gatherPlottingResponses ( wasp::DataArray &  plotting_responses,
int  line,
int  character 
)
private

Build CustomPlot extension responses when method name is plotting.

Parameters
plotting_responses- array for CustomPlot responses to fill
line- zero-based line to use for logic of custom extension
character- zero-based column for logic of custom extension
Returns
- true if request successfully handled with response built

Definition at line 1909 of file MooseServer.C.

1910{
1911 // return without adding any plot response objects if parser root is null
1912 auto root_ptr = queryRoot();
1913 if (!root_ptr)
1914 return true;
1915 auto & root = *root_ptr;
1916
1917 // find hit node for zero based request line and column number from input
1918 wasp::HITNodeView view_root = root.getNodeView();
1919 wasp::HITNodeView request_context =
1920 wasp::findNodeUnderLineColumn(view_root, line + 1, character + 1);
1921
1922 // get object context and value of type parameter for request if provided
1923 wasp::HITNodeView object_context = request_context;
1924 while (object_context.type() != wasp::OBJECT && object_context.has_parent())
1925 object_context = object_context.parent();
1926 const std::string & object_name = object_context.name();
1927 wasp::HITNodeView type_node = object_context.first_child_by_name("type");
1928 const std::string & object_type =
1929 type_node.is_null() ? "" : wasp::strip_quotes(hit::extractValue(type_node.data()));
1930
1931 // get check app of document and return with no plots if its build failed
1932 auto app_ptr = queryCheckApp();
1933 if (!app_ptr)
1934 return true;
1935
1936 // get problem from action warehouse and return without any plots if null
1937 std::shared_ptr<FEProblemBase> & problem = app_ptr->actionWarehouse().problemBase();
1938 if (!problem)
1939 return true;
1940
1941 // check problem to build function plot if request is from function block
1942 if (problem->hasFunction(object_name))
1943 buildFuncPlotResponse(plotting_responses, *problem, object_name, object_type);
1944
1945 // check problem to build PDF and CDF plots if request is in distribution
1946 else if (problem->hasDistribution(object_name))
1947 buildDistPlotResponses(plotting_responses, *problem, object_name, object_type);
1948
1949 return true;
1950}
void buildFuncPlotResponse(wasp::DataArray &plotting_responses, FEProblemBase &problem, const std::string &object_name, const std::string &object_type)
Gather function data, build CustomPlot object, and add to responses.
void buildDistPlotResponses(wasp::DataArray &plotting_responses, FEProblemBase &problem, const std::string &object_name, const std::string &object_type)
Compute PDF and CDF, build CustomPlot objects, and add to responses.

Referenced by gatherExtensionResponses().

◆ getActionParameters()

void MooseServer::getActionParameters ( InputParameters valid_params,
const std::string &  object_path,
std::set< std::string > &  obj_act_tasks 
)
private

Get all action parameters using requested object path to collection.

Parameters
valid_params- collection for filling action input parameters
object_path- full node path where autocomplete was requested
obj_act_tasks- set for adding in all MooseObjectAction tasks

Definition at line 587 of file MooseServer.C.

590{
591 Syntax & syntax = getRegistrationApp().syntax();
593
594 // get registered syntax path identifier using actual object context path
595 bool is_parent;
596 std::string registered_syntax = syntax.isAssociated(object_path, &is_parent);
597
598 // use is_parent to skip action parameters when not explicitly registered
599 if (!is_parent)
600 {
601 // get action objects associated with registered syntax path identifier
602 auto action_range = syntax.getActions(registered_syntax);
603
604 // traverse action objects for syntax to gather valid action parameters
605 for (auto action_iter = action_range.first; action_iter != action_range.second; action_iter++)
606 {
607 const std::string & action_name = action_iter->second._action;
608
609 // use action name to get set of valid parameters from action factory
610 InputParameters action_params = action_factory.getValidParams(action_name);
611
612 // gather all MooseObjectAction tasks for verifying object parameters
613 if (action_params.have_parameter<bool>("isObjectAction"))
614 {
615 if (action_params.get<bool>("isObjectAction"))
616 {
617 std::set<std::string> tasks_by_actions = action_factory.getTasksByAction(action_name);
618 obj_act_tasks.insert(tasks_by_actions.begin(), tasks_by_actions.end());
619 }
620
621 // filter parameter from completion list as it is not used in input
622 action_params.remove("isObjectAction");
623 }
624
625 // add parameters from action to full valid collection being gathered
626 valid_params += action_params;
627 }
628 }
629}
Specialized factory for generic Action System objects.
std::set< std::string > getTasksByAction(const std::string &action) const
InputParameters getValidParams(const std::string &name)
ActionFactory & getActionFactory()
Retrieve a writable reference to the ActionFactory associated with this App.
Definition MooseApp.h:412
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...
Definition Syntax.C:329
void remove(std::string_view)

Referenced by getAllValidParameters().

◆ getAllValidParameters()

void MooseServer::getAllValidParameters ( InputParameters valid_params,
const std::string &  object_path,
const std::string &  object_type,
std::set< std::string > &  obj_act_tasks 
)
private

Get all global parameters, action parameters, and object parameters.

Parameters
valid_params- collection to fill with valid input parameters
object_path- full node path where autocomplete was requested
object_type- type of object where autocomplete was requested
obj_act_tasks- set for adding in all MooseObjectAction tasks

Definition at line 575 of file MooseServer.C.

579{
580 // gather global parameters then action parameters then object parameters
581 valid_params += Moose::Builder::validParams();
582 getActionParameters(valid_params, object_path, obj_act_tasks);
583 getObjectParameters(valid_params, object_type, obj_act_tasks);
584}
void getActionParameters(InputParameters &valid_params, const std::string &object_path, std::set< std::string > &obj_act_tasks)
Get all action parameters using requested object path to collection.
void getObjectParameters(InputParameters &valid_params, std::string object_type, const std::set< std::string > &obj_act_tasks)
Get all object parameters using requested object path to collection.
static InputParameters validParams()
Parameters that are processed directly by the Parser and are valid anywhere in the input.
Definition Builder.C:121

Referenced by gatherDocumentCompletionItems(), gatherDocumentDefinitionLocations(), getFileNameTypeValues(), getHoverDisplayText(), getNodesByValueAndTypes(), and getRequiredParamsText().

◆ getCheckApp()

MooseApp & MooseServer::getCheckApp ( )

Public interface for writable check app reference with error checks.

Returns
- writable reference to check app for current input document

Definition at line 2151 of file MooseServer.C.

2152{
2153 if (auto app_ptr = queryCheckApp())
2154 {
2155 auto & app = *app_ptr;
2156 mooseAssert(queryCheckParser(), "Should have a parser");
2157 mooseAssert(&app.parser() == queryCheckParser(), "Parser should be the app's parser");
2158 return app;
2159 }
2160 mooseError("MooseServer::getCheckApp(): App not available");
2161}
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
const Parser * queryCheckParser() const

Referenced by parseDocumentForDiagnostics().

◆ getCompletionItemKind()

int MooseServer::getCompletionItemKind ( const InputParameters valid_params,
const std::string &  param_name,
const std::string &  clean_type,
bool  is_param 
)
private

Get completion item kind value that client may use for icon in list.

Parameters
valid_params- valid parameters used for completion item kind
param_name- name of input parameter for completion item kind
clean_type- type to decide if reference completion item kind
is_param- boolean denoting if kind is for parameter or value
Returns
- enumerated kind value that client may use for icon in list

Definition at line 1797 of file MooseServer.C.

1801{
1802 // set up completion item kind value that client may use for icon in list
1803 auto associated_types = getRegistrationApp().syntax().getAssociatedTypes();
1804 if (is_param && valid_params.isParamRequired(param_name) &&
1805 !valid_params.isParamValid(param_name))
1806 return wasp::lsp::m_comp_kind_event;
1807 else if (param_name == "active" || param_name == "inactive")
1808 return wasp::lsp::m_comp_kind_class;
1809 else if (clean_type == "bool")
1810 return wasp::lsp::m_comp_kind_interface;
1811 else if (valid_params.have_parameter<MooseEnum>(param_name) ||
1812 valid_params.have_parameter<MultiMooseEnum>(param_name) ||
1813 valid_params.have_parameter<ExecFlagEnum>(param_name) ||
1814 valid_params.have_parameter<std::vector<MooseEnum>>(param_name))
1815 return is_param ? wasp::lsp::m_comp_kind_enum : wasp::lsp::m_comp_kind_enum_member;
1816 else if (param_name == "type")
1817 return wasp::lsp::m_comp_kind_type_param;
1818 else if (std::find_if(associated_types.begin(),
1819 associated_types.end(),
1820 [&](const auto & entry)
1821 { return entry.second == clean_type; }) != associated_types.end())
1822 return wasp::lsp::m_comp_kind_reference;
1823 else
1824 return is_param ? wasp::lsp::m_comp_kind_keyword : wasp::lsp::m_comp_kind_value;
1825}
bool isParamRequired(const std::string &name) const
Returns a boolean indicating whether the specified parameter is required or not.
const std::multimap< std::string, std::string > & getAssociatedTypes() const
Get a multimap of registered associations of syntax with type.
Definition Syntax.C:369

Referenced by addParametersToList(), and addValuesToList().

◆ getConnection()

std::shared_ptr< wasp::lsp::Connection > MooseServer::getConnection ( )
inline

Get read / write connection - specific to this server implemention.

Returns
- shared pointer to the server's read / write connection

Definition at line 40 of file MooseServer.h.

40{ return _connection; }

◆ getDocumentSymbolKind()

int MooseServer::getDocumentSymbolKind ( wasp::HITNodeView  symbol_node)
private

Get document symbol kind value that client may use for outline icon.

Parameters
symbol_node- node that will be added to symbol tree for kind
Returns
- enumerated kind value that client may use for outline icon

Definition at line 1828 of file MooseServer.C.

1829{
1830 // lambdas that check if parameter is a boolean or number for symbol kind
1831 auto is_boolean = [](wasp::HITNodeView symbol_node)
1832 {
1833 bool convert;
1834 std::istringstream iss(MooseUtils::toLower(symbol_node.last_as_string()));
1835 return (iss >> std::boolalpha >> convert && !iss.fail());
1836 };
1837 auto is_number = [](wasp::HITNodeView symbol_node)
1838 {
1839 double convert;
1840 std::istringstream iss(symbol_node.last_as_string());
1841 return (iss >> convert && iss.eof());
1842 };
1843
1844 // set up document symbol kind value that client may use for outline icon
1845 if (symbol_node.type() == wasp::OBJECT)
1846 return wasp::lsp::m_symbol_kind_struct;
1847 else if (symbol_node.type() == wasp::FILE)
1848 return wasp::lsp::m_symbol_kind_file;
1849 else if (symbol_node.type() == wasp::ARRAY)
1850 return wasp::lsp::m_symbol_kind_array;
1851 else if (symbol_node.type() == wasp::KEYED_VALUE && symbol_node.name() == std::string("type"))
1852 return wasp::lsp::m_symbol_kind_type_param;
1853 else if (symbol_node.type() == wasp::KEYED_VALUE && is_boolean(symbol_node))
1854 return wasp::lsp::m_symbol_kind_boolean;
1855 else if (symbol_node.type() == wasp::KEYED_VALUE && is_number(symbol_node))
1856 return wasp::lsp::m_symbol_kind_number;
1857 else if (symbol_node.type() == wasp::KEYED_VALUE)
1858 return wasp::lsp::m_symbol_kind_key;
1859 else if (symbol_node.type() == wasp::VALUE)
1860 return wasp::lsp::m_symbol_kind_string;
1861 else
1862 return wasp::lsp::m_symbol_kind_property;
1863}
bool convert(const std::string &str, T &value, const bool throw_on_failure)
Takes the string representation of a value and converts it to the value.
std::string toLower(std::string name)
Convert supplied string to lower case.

Referenced by gatherDocumentSymbols(), and traverseParseTreeAndFillSymbols().

◆ getEnumsAndDocs()

template<typename MooseEnumType >
void MooseServer::getEnumsAndDocs ( MooseEnumType &  moose_enum_param,
std::map< std::string, std::string > &  options_and_descs 
)
private

Fill map of all options and descriptions if parameter is moose enum.

Parameters
moose_enum_param- parameter to get documentation and options
options_and_descs- map to fill with options and descriptions

Definition at line 1078 of file MooseServer.C.

1080{
1081 // get map that contains any documentation strings provided for each item
1082 const auto & enum_docs = moose_enum_param.getItemDocumentation();
1083
1084 // walk over enums filling map with options and any provided descriptions
1085 for (const auto & item : moose_enum_param.items())
1086 options_and_descs[item.name()] = enum_docs.count(item) ? enum_docs.at(item) : "";
1087}

Referenced by addValuesToList(), and getHoverDisplayText().

◆ getExistingInput()

void MooseServer::getExistingInput ( wasp::HITNodeView  parent_node,
std::set< std::string > &  existing_params,
std::set< std::string > &  existing_subblocks 
)
private

Get names of parameters and subblocks specified in given input node.

Parameters
parent_node- object node context under which to gather input
existing_params- set to fill with parameter names from input
existing_subblocks- set to fill with subblock names in input

Definition at line 557 of file MooseServer.C.

560{
561 // gather names of all parameters and subblocks provided in input context
562 for (auto itr = parent_node.begin(); itr != parent_node.end(); itr.next())
563 {
564 auto child_node = itr.get();
565
566 // add key value or array type as parameter and object type as subblock
567 if (child_node.type() == wasp::KEYED_VALUE || child_node.type() == wasp::ARRAY)
568 existing_params.insert(child_node.name());
569 else if (child_node.type() == wasp::OBJECT)
570 existing_subblocks.insert(child_node.name());
571 }
572}

Referenced by gatherDocumentCompletionItems().

◆ getFileNameTypeValues()

void MooseServer::getFileNameTypeValues ( std::set< std::string > &  filename_vals,
wasp::HITNodeView  parent 
)
private

Recursively walk input to gather all FileName type parameter values.

Parameters
filename_vals- set to fill up with FileName parameter values
parent- nodeview for recursive tree traversal starting point

Definition at line 341 of file MooseServer.C.

342{
343 // cache set of FileName types for parameters that contain resource files
344 static const std::set<std::string> filename_types = {
345 "FileName", "FileNameNoExtension", "MeshFileName", "MatrixFileName"};
346
347 // walk over children in tree and skip any nodes that are not object type
348 for (const auto & child : parent)
349 {
350 if (child.type() == wasp::OBJECT)
351 {
352 // get object context path and object type value of node if it exists
353 wasp::HITNodeView object_node = child;
354 const std::string object_path = object_node.path();
355 wasp::HITNodeView type_node = object_node.first_child_by_name("type");
356 const std::string object_type =
357 type_node.is_null() ? "" : wasp::strip_quotes(hit::extractValue(type_node.data()));
358
359 // gather global, action, and object parameters for context of object
360 InputParameters valid_params = emptyInputParameters();
361 std::set<std::string> obj_act_tasks;
362 getAllValidParameters(valid_params, object_path, object_type, obj_act_tasks);
363
364 // walk over children and skip any nodes that are not parameter types
365 for (const auto & child : object_node)
366 {
367 if (child.type() == wasp::KEYED_VALUE || child.type() == wasp::ARRAY)
368 {
369 // get name of node to use for finding in set of valid parameters
370 wasp::HITNodeView param_node = child;
371 std::string param_name = param_node.name();
372
373 // add parameter values to collection if valid with FileName type
374 if (valid_params.getParametersList().count(param_name))
375 {
376 // get parameter type and prepare to check if in FileName types
377 std::string dirty_type = valid_params.type(param_name);
378 std::string clean_type = MooseUtils::prettyCppType(dirty_type);
379 pcrecpp::RE(".+<([A-Za-z0-9_' ':]*)>.*").GlobalReplace("\\1", &clean_type);
380
381 // add parameter values to set if type is one of FileName types
382 if (filename_types.count(clean_type))
383 for (const auto & child : param_node)
384 if (child.type() == wasp::VALUE)
385 filename_vals.insert(child.to_string());
386 }
387 }
388 }
389
390 // recurse deeper into input and continue search since node is object
391 getFileNameTypeValues(filename_vals, object_node);
392 }
393 }
394}
if(!dmm->_nl) SETERRQ(PETSC_COMM_WORLD

Referenced by addResourcesForDocument(), and getFileNameTypeValues().

◆ getHoverDisplayText()

bool MooseServer::getHoverDisplayText ( std::string &  display_text,
int  line,
int  character 
)
private

Get hover display text - logic specific to this server implemention.

Parameters
display_text- string reference to add hover text for display
line- zero-based line to use for finding node and hover text
character- zero-based column for finding node and hover text
Returns
- true if display text was added or left empty without error

Definition at line 1340 of file MooseServer.C.

1341{
1342 Factory & factory = getRegistrationApp().getFactory();
1343 Syntax & syntax = getRegistrationApp().syntax();
1344
1345 // return and leave display text as empty string when parser root is null
1346 auto root_ptr = queryRoot();
1347 if (!root_ptr)
1348 return true;
1349 auto & root = *root_ptr;
1350
1351 // find hit node for zero based request line and column number from input
1352 wasp::HITNodeView view_root = root.getNodeView();
1353 wasp::HITNodeView request_context =
1354 wasp::findNodeUnderLineColumn(view_root, line + 1, character + 1);
1355
1356 // return and leave display text as empty string when not on key or value
1357 if ((request_context.type() != wasp::DECL && request_context.type() != wasp::VALUE) ||
1358 !request_context.has_parent() ||
1359 (request_context.parent().type() != wasp::KEYED_VALUE &&
1360 request_context.parent().type() != wasp::ARRAY))
1361 return true;
1362
1363 // get name of parameter node and value string that is specified in input
1364 std::string paramkey = request_context.parent().name();
1365 std::string paramval = request_context.last_as_string();
1366
1367 // get object context path and object type value for request if it exists
1368 wasp::HITNodeView object_context = request_context;
1369 while (object_context.type() != wasp::OBJECT && object_context.has_parent())
1370 object_context = object_context.parent();
1371 const std::string object_path = object_context.path();
1372 wasp::HITNodeView type_node = object_context.first_child_by_name("type");
1373 const std::string object_type =
1374 type_node.is_null() ? "" : wasp::strip_quotes(hit::extractValue(type_node.data()));
1375
1376 // gather global, action, and object parameters in request object context
1377 InputParameters valid_params = emptyInputParameters();
1378 std::set<std::string> obj_act_tasks;
1379 getAllValidParameters(valid_params, object_path, object_type, obj_act_tasks);
1380
1381 // use class description as display text when request is Application type
1382 if (request_context.type() == wasp::VALUE && paramkey == "type" &&
1383 object_path == "/Application" && AppFactory::instance().isRegistered(paramval))
1384 {
1385 InputParameters app_params = AppFactory::instance().getValidParams(paramval);
1386 display_text = app_params.getClassDescription();
1387 MooseUtils::escape(display_text);
1388 }
1389
1390 // use class description as display text when request is valid type value
1391 else if (request_context.type() == wasp::VALUE && paramkey == "type" &&
1392 factory.isRegistered(paramval))
1393 {
1394 const InputParameters & object_params = factory.getValidParams(paramval);
1395 if (object_params.hasBase())
1396 {
1397 const std::string & moose_base = object_params.getBase();
1398 for (const auto & obj_act_task : obj_act_tasks)
1399 {
1400 if (syntax.verifyMooseObjectTask(moose_base, obj_act_task))
1401 {
1402 display_text = object_params.getClassDescription();
1403 MooseUtils::escape(display_text);
1404 break;
1405 }
1406 }
1407 }
1408 }
1409
1410 // use item documentation as display text when request is enum type value
1411 else if (request_context.type() == wasp::VALUE)
1412 {
1413 std::map<std::string, std::string> options_and_descs;
1414 if (valid_params.have_parameter<MooseEnum>(paramkey))
1415 getEnumsAndDocs(valid_params.get<MooseEnum>(paramkey), options_and_descs);
1416 else if (valid_params.have_parameter<MultiMooseEnum>(paramkey))
1417 getEnumsAndDocs(valid_params.get<MultiMooseEnum>(paramkey), options_and_descs);
1418 else if (valid_params.have_parameter<ExecFlagEnum>(paramkey))
1419 getEnumsAndDocs(valid_params.get<ExecFlagEnum>(paramkey), options_and_descs);
1420 else if (valid_params.have_parameter<std::vector<MooseEnum>>(paramkey))
1421 getEnumsAndDocs(valid_params.get<std::vector<MooseEnum>>(paramkey)[0], options_and_descs);
1422 if (options_and_descs.count(paramval))
1423 {
1424 display_text = options_and_descs.find(paramval)->second;
1425 MooseUtils::escape(display_text);
1426 }
1427 }
1428
1429 // use parameter documentation as display text when request is valid name
1430 else if (request_context.type() == wasp::DECL && valid_params.getParametersList().count(paramkey))
1431 {
1432 display_text = valid_params.getDocString(paramkey);
1433 MooseUtils::escape(display_text);
1434
1435 // add units information to hover text if it is specified for parameter
1436 std::string doc_units = valid_params.getDocUnit(paramkey);
1437 if (!doc_units.empty())
1438 display_text += "\n\nUnits: " + doc_units;
1439
1440 // add range information to hover text if it is specified for parameter
1441 if (valid_params.isRangeChecked(paramkey))
1442 {
1443 std::string doc_range = valid_params.rangeCheckedFunction(paramkey);
1444 if (!doc_range.empty())
1445 display_text += "\n\nRange: " + doc_range;
1446 }
1447 }
1448
1449 return true;
1450}
bool isRegistered(const std::string &app_name) const
Returns a Boolean indicating whether an application type has been registered.
Definition AppFactory.h:168
InputParameters getValidParams(const std::string &name)
Get valid parameters for the object.
Definition AppFactory.C:35
static AppFactory & instance()
Get the instance of the AppFactory.
Definition AppFactory.C:20
InputParameters getValidParams(const std::string &name) const
Get valid parameters for the object.
Definition Factory.C:68
std::string rangeCheckedFunction(const std::string &name) const
Return the range check function for any parameter (empty string if it is not range checked)
std::string getDocUnit(const std::string &name) const
Returns the documentation unit string for the specified parameter name.
bool isRangeChecked(const std::string &param_name) const
Return whether a parameter has a range check.

◆ getInputLookupDefinitionNodes()

void MooseServer::getInputLookupDefinitionNodes ( SortedLocationNodes location_nodes,
const std::string &  clean_type,
const std::string &  val_string 
)
private

Get set of nodes from associated path lookups matching value string.

Parameters
location_nodes- set to fill with lookup nodes matching value
clean_type- cpp type string used for key finding input paths
val_string- specified value used for gathering input lookups

Definition at line 1266 of file MooseServer.C.

1269{
1270 Syntax & syntax = getRegistrationApp().syntax();
1271
1272 // build map from parameter types to input lookup paths and save to reuse
1273 auto & metadata = getSyntaxMetadata();
1274 if (metadata.type_to_input_paths.empty())
1275 {
1276 for (const auto & associated_types_iter : syntax.getAssociatedTypes())
1277 {
1278 const std::string & type = associated_types_iter.second;
1279 const std::string & path = associated_types_iter.first;
1280 metadata.type_to_input_paths[type].insert(path);
1281 }
1282 }
1283
1284 // find set of input lookup paths that are associated with parameter type
1285 const auto & input_path_iter = metadata.type_to_input_paths.find(clean_type);
1286
1287 // return without any definition locations added when no paths associated
1288 if (input_path_iter == metadata.type_to_input_paths.end())
1289 return;
1290
1291 // get root node from input to use in input lookups with associated paths
1292 wasp::HITNodeView view_root = getRoot().getNodeView();
1293
1294 // walk over all syntax paths that are associated with parameter type
1295 for (const auto & input_path : input_path_iter->second)
1296 {
1297 // use wasp siren to gather all nodes from current lookup path in input
1298 wasp::SIRENInterpreter<> selector;
1299 if (!selector.parseString(input_path))
1300 continue;
1301 wasp::SIRENResultSet<wasp::HITNodeView> results;
1302 std::size_t count = selector.evaluate(view_root, results);
1303
1304 // walk over results and add nodes that have name matching value to set
1305 for (std::size_t i = 0; i < count; i++)
1306 if (results.adapted(i).type() == wasp::OBJECT && results.adapted(i).name() == val_string &&
1307 results.adapted(i).child_count_by_name("decl"))
1308 location_nodes.insert(results.adapted(i).first_child_by_name("decl"));
1309 }
1310}

Referenced by gatherDocumentDefinitionLocations().

◆ getNodesByValueAndTypes()

void MooseServer::getNodesByValueAndTypes ( SortedLocationNodes match_nodes,
wasp::HITNodeView  view_parent,
const std::string &  target_value,
const std::set< std::string > &  target_types 
)
private

Recursively walk input to gather all nodes matching value and types.

Parameters
match_nodes- set to fill with nodes matching value and types
view_parent- nodeview used to start recursive tree traversal
target_value-
target_types-

Definition at line 1528 of file MooseServer.C.

1532{
1533 // walk over children of context to gather nodes matching value and types
1534 for (const auto & view_child : view_parent)
1535 {
1536 // check for parameter type match if node is value matching target data
1537 if (view_child.type() == wasp::VALUE && view_child.to_string() == target_value)
1538 {
1539 // get object context path and object type value of node if it exists
1540 wasp::HITNodeView object_context = view_child;
1541 while (object_context.type() != wasp::OBJECT && object_context.has_parent())
1542 object_context = object_context.parent();
1543 const std::string object_path = object_context.path();
1544 wasp::HITNodeView type_node = object_context.first_child_by_name("type");
1545 const std::string object_type =
1546 type_node.is_null() ? "" : wasp::strip_quotes(hit::extractValue(type_node.data()));
1547
1548 // gather global, action, and object parameters for context of object
1549 InputParameters valid_params = emptyInputParameters();
1550 std::set<std::string> obj_act_tasks;
1551 getAllValidParameters(valid_params, object_path, object_type, obj_act_tasks);
1552
1553 // get name from parent of current value node which is parameter node
1554 std::string param_name = view_child.has_parent() ? view_child.parent().name() : "";
1555
1556 // get type of parameter and prepare string to check target set match
1557 std::string dirty_type = valid_params.type(param_name);
1558 std::string clean_type = MooseUtils::prettyCppType(dirty_type);
1559 pcrecpp::RE(".+<([A-Za-z0-9_' ':]*)>.*").GlobalReplace("\\1", &clean_type);
1560
1561 // add input node to collection if its type is also in set of targets
1562 if (target_types.count(clean_type))
1563 match_nodes.insert(view_child);
1564 }
1565
1566 // recurse deeper into input to search for matches if node has children
1567 if (!view_child.is_leaf())
1568 getNodesByValueAndTypes(match_nodes, view_child, target_value, target_types);
1569 }
1570}

Referenced by gatherDocumentReferencesLocations(), and getNodesByValueAndTypes().

◆ getObjectParameters()

void MooseServer::getObjectParameters ( InputParameters valid_params,
std::string  object_type,
const std::set< std::string > &  obj_act_tasks 
)
private

Get all object parameters using requested object path to collection.

Parameters
valid_params- collection for filling object input parameters
object_type- type of object where autocomplete was requested
obj_act_tasks- tasks to verify object type with valid syntax

Definition at line 632 of file MooseServer.C.

635{
636 Syntax & syntax = getRegistrationApp().syntax();
637 Factory & factory = getRegistrationApp().getFactory();
638
639 // use type parameter default if it exists and is not provided from input
640 if (object_type.empty() && valid_params.have_parameter<std::string>("type") &&
641 !valid_params.get<std::string>("type").empty())
642 {
643 object_type = valid_params.get<std::string>("type");
644
645 // make type parameter not required in input since it has default value
646 valid_params.makeParamNotRequired("type");
647 }
648
649 // check if object type has been registered to prevent unregistered error
650 if (factory.isRegistered(object_type))
651 {
652 // use object type to get set of valid parameters registered in factory
653 InputParameters object_params = factory.getValidParams(object_type);
654
655 // check if object has base associated with any MooseObjectAction tasks
656 if (object_params.hasBase())
657 {
658 const std::string & moose_base = object_params.getBase();
659
660 for (const auto & obj_act_task : obj_act_tasks)
661 {
662 if (syntax.verifyMooseObjectTask(moose_base, obj_act_task))
663 {
664 // add parameters from object to valid collection if base matches
665 valid_params += object_params;
666 break;
667 }
668 }
669 }
670 }
671
672 // make parameters from list of those set by action not required in input
673 if (valid_params.have_parameter<std::vector<std::string>>("_object_params_set_by_action"))
674 {
675 auto names = valid_params.get<std::vector<std::string>>("_object_params_set_by_action");
676 for (const auto & name : names)
677 valid_params.makeParamNotRequired(name);
678
679 // filter parameter from completion list since it is not used for input
680 valid_params.remove("_object_params_set_by_action");
681 }
682}
void makeParamNotRequired(const std::string &name)
Changes the parameter to not be required.

Referenced by getAllValidParameters().

◆ getRegistrationApp()

MooseApp & MooseServer::getRegistrationApp ( )
private
Returns
- current document check app or fall back to return parent app to get Syntax, Factory, and ActionFactory static registration metadata when parent app could still be beneficial if check app failed to build

Definition at line 2164 of file MooseServer.C.

2165{
2166 if (auto * app = queryCheckApp())
2167 return *app;
2168 return _moose_app;
2169}

Referenced by addSubblocksToList(), addValuesToList(), gatherDocumentDefinitionLocations(), gatherDocumentReferencesLocations(), getActionParameters(), getCompletionItemKind(), getHoverDisplayText(), getInputLookupDefinitionNodes(), getObjectParameters(), and getSyntaxMetadata().

◆ getRequiredParamsText()

std::string MooseServer::getRequiredParamsText ( const std::string &  subblock_path,
const std::string &  subblock_type,
const std::set< std::string > &  existing_params,
const std::string &  indent_spaces 
)
private

Get required parameter completion text list for given subblock path.

Parameters
subblock_path- subblock path for finding required parameters
subblock_type- subblock type for finding required parameters
existing_params- set of parameters already existing in input
indent_spaces- indentation to be added before each parameter
Returns
- list of required parameters to use in subblock insert text

Definition at line 1866 of file MooseServer.C.

1870{
1871 // gather global, action, and object parameters in request object context
1872 InputParameters valid_params = emptyInputParameters();
1873 std::set<std::string> obj_act_tasks;
1874 getAllValidParameters(valid_params, subblock_path, subblock_type, obj_act_tasks);
1875
1876 // walk over collection of all parameters and build text of ones required
1877 std::string required_param_text;
1878 std::size_t param_index = 1;
1879 for (const auto & valid_params_iter : valid_params)
1880 {
1881 // skip parameter if deprecated, private, defaulted, optional, existing
1882 const std::string & param_name = valid_params_iter.first;
1883 if (!valid_params.isParamDeprecated(param_name) && !valid_params.isPrivate(param_name) &&
1884 !valid_params.isParamValid(param_name) && valid_params.isParamRequired(param_name) &&
1885 !existing_params.count(param_name))
1886 {
1887 std::string tab_stop = client_snippet_support ? "$" + std::to_string(param_index++) : "";
1888 required_param_text += "\n" + indent_spaces + param_name + " = " + tab_stop;
1889 }
1890 }
1891
1892 return required_param_text;
1893}

Referenced by addSubblocksToList(), and addValuesToList().

◆ getRoot()

const hit::Node & MooseServer::getRoot ( ) const
private
Returns
The root node from the check parser for the current document path, with error checking on if it exists

Definition at line 2178 of file MooseServer.C.

2179{
2180 if (auto root_ptr = queryRoot())
2181 return *root_ptr;
2182 mooseError("MooseServer::getRoot(): Root not available");
2183}

Referenced by addValuesToList(), and getInputLookupDefinitionNodes().

◆ getSyntaxMetadata()

MooseServer::SyntaxMetadata & MooseServer::getSyntaxMetadata ( )
private
Returns
- syntax metadata for type of current registration application

Definition at line 2172 of file MooseServer.C.

2173{
2175}
const std::string & type() const
Get the type of this class.
Definition MooseBase.h:93
std::map< std::string, SyntaxMetadata > _app_type_to_syntax_metadata
_app_type_to_syntax_metadata - syntax metadata per app type map

Referenced by addSubblocksToList(), addValuesToList(), gatherDocumentReferencesLocations(), and getInputLookupDefinitionNodes().

◆ parseDocumentForDiagnostics()

bool MooseServer::parseDocumentForDiagnostics ( wasp::DataArray &  diagnosticsList)
private

Parse document for diagnostics - specific to this server implemention.

Parameters
diagnosticsList- data array of diagnostics data objects to fill
Returns
- true if completed successfully - does not indicate parse fail

Definition at line 71 of file MooseServer.C.

72{
73 // Reset old parsers and applications if we have them
74 if (const auto it = _check_state.find(document_path); it != _check_state.end())
75 _check_state.erase(it);
76
77 // strip prefix from document uri if it exists to get parse file path
78 std::string parse_file_path = document_path;
79 pcrecpp::RE("(.*://)(.*)").Replace("\\2", &parse_file_path);
80
81 bool pass = true;
82
83 // Adds a single diagnostic
84 const auto diagnostic = [this, &diagnosticsList, &pass](const std::string & message,
85 const int start_line,
86 const int start_column,
87 const std::optional<int> end_line = {},
88 const std::optional<int> end_column = {})
89 {
90 diagnosticsList.push_back(wasp::DataObject());
91 auto & diagnostic = *diagnosticsList.back().to_object();
92 pass &= wasp::lsp::buildDiagnosticObject(diagnostic,
93 errors,
94 start_line,
95 start_column,
96 end_line ? *end_line : start_line,
97 end_column ? *end_column : start_column,
98 1,
99 "moose_srv",
100 "check_inp",
101 message);
102 };
103
104 // Adds a diagnostic on line zero
105 const auto zero_line_diagnostic = [&diagnostic](const std::string & message)
106 { diagnostic(message, 0, 0); };
107
108 // Adds a diagnostic from a hit node, if the context of the hit node is valid
109 const auto hit_node_diagnostic = [&zero_line_diagnostic, &diagnostic, &parse_file_path](
110 const hit::Node * const node, const std::string & message)
111 {
112 // No node, root node, wrong file, or no line information: line zero diagnostic
113 if (!node || node->isRoot() || node->filename() != parse_file_path || !node->line() ||
114 !node->column())
115 zero_line_diagnostic(message);
116 // Have file and line context, diagnostic there
117 else
118 diagnostic(message, node->line() - 1, node->column() - 1);
119 };
120
121 // Adds a diagnostic from a hit::ErrorMessage if the context is valid
122 const auto hit_error_message_diagnostic =
123 [&diagnostic, &zero_line_diagnostic, &parse_file_path](const hit::ErrorMessage & err)
124 {
125 // Has a filename
126 if (err.filename)
127 {
128 // For the open file
129 if (*err.filename == parse_file_path)
130 {
131 // Has line information that is valid
132 if (err.lineinfo && err.lineinfo->start_line && err.lineinfo->start_column &&
133 err.lineinfo->end_line && err.lineinfo->end_column)
134 {
135 diagnostic(err.message,
136 err.lineinfo->start_line - 1,
137 err.lineinfo->start_column - 1,
138 err.lineinfo->end_line - 1,
139 err.lineinfo->end_column - 1);
140 return;
141 }
142 }
143 // Has a file but not for this file, no diagnostic
144 else
145 return;
146 }
147
148 // Don't have a filename, or have a filename that is this file without line info
149 zero_line_diagnostic(err.prefixed_message);
150 };
151
152 // Runs a try catch loop with the given action, collecting diagnostics
153 // from the known exceptions; returns a bool that is true if we executed
154 // without throwing anything
155 const auto try_catch = [&hit_error_message_diagnostic,
156 &hit_node_diagnostic,
157 &zero_line_diagnostic](const auto & action) -> bool
158 {
159 Moose::ScopedThrowOnError scoped_throw_on_error;
160
161 try
162 {
163 action();
164 }
165 // Will be thrown from the Parser while building the tree or
166 // by the builder while building the input parameters
167 catch (Parser::Error & err)
168 {
169 for (const auto & error_message : err.error_messages)
170 hit_error_message_diagnostic(error_message);
171 }
172 // Will be thrown by mooseError() when _throw_on_error is set
173 // to true, hopefully with hit node context
174 catch (MooseRuntimeError & err)
175 {
176 hit_node_diagnostic(err.getNode(), err.what());
177 }
178 // General catch all for everything else without context
179 catch (std::exception & err)
180 {
181 zero_line_diagnostic(err.what());
182 }
183
184 // continue to build app if parsing fails and run app if building fails
185 // so that problem is there for plotting and warehouse based completion
186 return true;
187 };
188
189 // Setup command line (needed by the Parser)
190 auto command_line = std::make_unique<CommandLine>(_moose_app.commandLine()->getArguments());
191 if (command_line->hasArgument("--language-server"))
192 command_line->removeArgument("--language-server");
193 command_line->addArgument("--check-input");
194 command_line->addArgument("--error-unused");
195 command_line->addArgument("--error");
196 command_line->addArgument("--color=off");
197 command_line->addArgument("--disable-perf-graph-live");
198 command_line->parse();
199
200 // Setup the parser that will be used in the app
201 auto parser = std::make_shared<Parser>(parse_file_path, document_text);
202 mooseAssert(parser->getInputFileNames()[0] == parse_file_path, "Should be consistent");
203 parser->setAppType(_moose_app.type());
204 parser->setCommandLineParams(command_line->buildHitParams());
205 parser->setThrowOnError(true);
206
207 // Try to parse the document
208 const bool parse_success = try_catch([&parser]() { parser->parse(); });
209 // If the Parser has a valid root, store it because we can use it
210 // in the future (hover text etc with a partially complete document)
211 CheckState * state = nullptr;
212 if (auto parser_root_ptr = parser->queryRoot();
213 parser_root_ptr && !parser_root_ptr->getNodeView().is_null())
214 {
215 auto it_inserted_pair = _check_state.emplace(document_path, parser);
216 mooseAssert(it_inserted_pair.second, "Should not already exist");
217 state = &it_inserted_pair.first->second;
218 }
219 // We have no root or an empty document, nothing else to do
220 else
221 return true;
222
223 // Failed to parse, don't bother building the app. But... we might
224 // have a root node at least!
225 if (!parse_success)
226 return pass;
227
228 // Try to instantiate the application
229 std::unique_ptr<MooseApp> app = nullptr;
230 const auto do_build_app = [this, &parse_file_path, &diagnostic, &parser, &command_line, &app]()
231 {
232 // get app type from parser which is Application block type if provided
233 const std::string & app_type = parser->getAppType();
234
235 // error if Application type specified in input has not been registered
236 if (!AppFactory::instance().isRegistered(app_type))
237 {
238 // get line and column range of Application/type/value for diagnostic
239 int error_line_beg = 0, error_char_beg = 0, error_line_end = 0, error_char_end = 0;
240 if (auto app_type_field = parser->getRoot().find("Application/type");
241 app_type_field && app_type_field->filename() == parse_file_path)
242 {
243 auto app_type_value = app_type_field->getNodeView().first_child_by_name("value");
244 if (!app_type_value.is_null())
245 {
246 error_line_beg = app_type_value.line() - 1;
247 error_char_beg = app_type_value.column() - 1;
248 error_line_end = app_type_value.last_line() - 1;
249 error_char_end = app_type_value.last_column();
250 }
251 }
252
253 // build error message string with available app types for diagnostic
254 std::vector<std::string> app_types;
255 for (const auto & apps_iter : AppFactory::instance().registeredObjects())
256 app_types.push_back(apps_iter.first);
257 const auto message = "'" + app_type + "' is not a registered application type. Registered" +
258 " application types are [" + MooseUtils::join(app_types, ", ") + "].";
259
260 // add diagnostic to get reported for Application/type not registered
261 diagnostic(message, error_line_beg, error_char_beg, error_line_end, error_char_end);
262 return;
263 }
264
265 // set up options from app type parameters with parser and command line
266 InputParameters app_params = AppFactory::instance().getValidParams(app_type);
267 app_params.set<std::shared_ptr<Parser>>("_parser") = parser;
268 app_params.set<std::shared_ptr<CommandLine>>("_command_line") = std::move(command_line);
269
270 // create application to use for diagnostic checks and input assistance
272 app_type, AppFactory::main_app_name, app_params, _moose_app.getCommunicator()->get());
273 };
274 if (!try_catch(do_build_app))
275 {
276 if (app)
277 app.reset();
278 return pass;
279 }
280
281 // do not attempt to run application if it is null after build from error
282 if (app)
283 {
284 // store application when it is valid and then run it to invoke builder
285 state->app = std::move(app);
286 const auto do_run_app = [this]() { getCheckApp().run(); };
287 if (!try_catch(do_run_app))
288 state->app.reset();
289 }
290
291 // add all resource files of document that will be registered with client
293
294 return pass;
295}
static std::unique_ptr< MooseApp > create(const std::string &app_type, const std::vector< std::string > &cli_args={})
Create an app with no input and command line arguments.
Definition AppFactory.C:64
static const std::string main_app_name
The name for the "main" moose application.
Definition AppFactory.h:68
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
virtual void run()
Run the application.
Definition MooseApp.C:2027
const std::shared_ptr< libMesh::Parallel::Communicator > getCommunicator() const
Definition MooseApp.h:1058
std::shared_ptr< CommandLine > commandLine() const
Get the command line.
Definition MooseApp.h:424
Exception to be thrown whenever we have _throw_on_error set and a mooseError() is emitted.
Definition MooseError.h:118
MooseApp & getCheckApp()
Public interface for writable check app reference with error checks.
std::map< std::string, CheckState > _check_state
_check_state - map from document paths to state (parser, app, text)
void addResourcesForDocument()
Add paths from includes and FileName parameters for client to watch.
Scoped helper for setting Moose::_throw_on_error during this scope.
Definition Moose.h:298
OStreamProxy err(std::cerr)

◆ queryCheckApp() [1/2]

MooseApp * MooseServer::queryCheckApp ( )
private

Definition at line 2145 of file MooseServer.C.

2146{
2147 return const_cast<MooseApp *>(std::as_const(*this).queryCheckApp());
2148}
Base class for MOOSE-based applications.
Definition MooseApp.h:110

◆ queryCheckApp() [2/2]

const MooseApp * MooseServer::queryCheckApp ( ) const
private
Returns
The check app for the current document path, if any

Definition at line 2137 of file MooseServer.C.

2138{
2139 if (auto state = queryCheckState())
2140 return state->app.get();
2141 return nullptr;
2142}
const CheckState * queryCheckState() const

Referenced by addObjectsFromWarehouses(), gatherPlottingResponses(), getCheckApp(), getRegistrationApp(), and queryRoot().

◆ queryCheckParser() [1/2]

Parser * MooseServer::queryCheckParser ( )
private

Definition at line 2131 of file MooseServer.C.

2132{
2133 return const_cast<Parser *>(std::as_const(*this).queryCheckParser());
2134}
Class for parsing input files.
Definition Parser.h:102

◆ queryCheckParser() [2/2]

const Parser * MooseServer::queryCheckParser ( ) const
private
Returns
The check parser for the current document path, if any

Definition at line 2124 of file MooseServer.C.

2125{
2126 const auto state = queryCheckState();
2127 return state ? state->parser.get() : nullptr;
2128}

Referenced by getCheckApp(), and queryRoot().

◆ queryCheckState() [1/2]

MooseServer::CheckState * MooseServer::queryCheckState ( )
private

Definition at line 2118 of file MooseServer.C.

2119{
2120 return const_cast<MooseServer::CheckState *>(std::as_const(*this).queryCheckState());
2121}
Helper for storing the state for a single document.

◆ queryCheckState() [2/2]

const MooseServer::CheckState * MooseServer::queryCheckState ( ) const
private
Returns
The check state for the current document path, if any

Definition at line 2111 of file MooseServer.C.

2112{
2113 const auto it = _check_state.find(document_path);
2114 return it == _check_state.end() ? nullptr : &it->second;
2115}

Referenced by queryCheckApp(), and queryCheckParser().

◆ queryRoot()

const hit::Node * MooseServer::queryRoot ( ) const
private
Returns
The root node from the check parser for the current document path, if any

Definition at line 2095 of file MooseServer.C.

2096{
2097 if (const auto parser_ptr = queryCheckParser())
2098 {
2099#ifndef NDEBUG
2100 if (const auto app_ptr = queryCheckApp())
2101 mooseAssert(&app_ptr->parser() == parser_ptr, "App should have this parser");
2102#endif
2103 if (const auto root_ptr = parser_ptr->queryRoot())
2104 if (!root_ptr->getNodeView().is_null())
2105 return root_ptr;
2106 }
2107 return nullptr;
2108}

Referenced by addResourcesForDocument(), gatherDocumentCompletionItems(), gatherDocumentDefinitionLocations(), gatherDocumentReferencesLocations(), gatherDocumentSymbols(), gatherPlottingResponses(), getHoverDisplayText(), and getRoot().

◆ rootIsValid()

bool MooseServer::rootIsValid ( ) const
private
Returns
Whether or not the root is valid

Will be true if the app is valid, the root is not nullptr, and the root node view is not null

◆ setDistPlotNumPoints()

void MooseServer::setDistPlotNumPoints ( std::size_t  num_points)
inline

Override number of discrete points in continuous distribution plots.

Used by plotting unit test to lower sampling resolution for testing.

Parameters
num_points- number of discrete points for distribution plots

Definition at line 53 of file MooseServer.h.

53{ _dist_plot_num_points = num_points; }

◆ traverseParseTreeAndFillSymbols()

bool MooseServer::traverseParseTreeAndFillSymbols ( wasp::HITNodeView  view_parent,
wasp::DataObject &  data_parent 
)
private

Recursively fill document symbols from the given node.

Parameters
view_parent- nodeview used in recursive tree traversal
data_parent- data object with array of symbol children
Returns
- true if no problems with this level of the resursion

Definition at line 1745 of file MooseServer.C.

1747{
1748 // return without adding any children if parent node is file include type
1749 if (wasp::is_nested_file(view_parent))
1750 return true;
1751
1752 bool pass = true;
1753
1754 // walk over all children of this node context and build document symbols
1755 for (const auto i : make_range(view_parent.child_count()))
1756 {
1757 // walk must be index based to catch file include and skip its children
1758 wasp::HITNodeView view_child = view_parent.child_at(i);
1759
1760 // set up name, zero based line and column range, kind, and detail info
1761 std::string name = view_child.name();
1762 int line = view_child.line() - 1;
1763 int column = view_child.column() - 1;
1764 int last_line = view_child.last_line() - 1;
1765 int last_column = view_child.last_column();
1766 int symbol_kind = getDocumentSymbolKind(view_child);
1767 std::string detail =
1768 !view_child.first_child_by_name("type").is_null()
1769 ? wasp::strip_quotes(hit::extractValue(view_child.first_child_by_name("type").data()))
1770 : "";
1771
1772 // build document symbol object from node child info and push to array
1773 wasp::DataObject & data_child = wasp::lsp::addDocumentSymbolChild(data_parent);
1774 pass &= wasp::lsp::buildDocumentSymbolObject(data_child,
1775 errors,
1776 (name.empty() ? "void" : name),
1777 detail,
1778 symbol_kind,
1779 false,
1780 line,
1781 column,
1782 last_line,
1783 last_column,
1784 line,
1785 column,
1786 last_line,
1787 last_column);
1788
1789 // call method to recursively fill document symbols for each node child
1790 pass &= traverseParseTreeAndFillSymbols(view_child, data_child);
1791 }
1792
1793 return pass;
1794}

Referenced by gatherDocumentSymbols(), and traverseParseTreeAndFillSymbols().

Member Data Documentation

◆ _app_type_to_syntax_metadata

std::map<std::string, SyntaxMetadata> MooseServer::_app_type_to_syntax_metadata
private

_app_type_to_syntax_metadata - syntax metadata per app type map

Definition at line 519 of file MooseServer.h.

Referenced by getSyntaxMetadata().

◆ _check_state

std::map<std::string, CheckState> MooseServer::_check_state
private

_check_state - map from document paths to state (parser, app, text)

Definition at line 509 of file MooseServer.h.

Referenced by parseDocumentForDiagnostics(), and queryCheckState().

◆ _connection

std::shared_ptr<wasp::lsp::IOStreamConnection> MooseServer::_connection
private

_connection - shared pointer to this server's read / write iostream

Definition at line 514 of file MooseServer.h.

Referenced by connectionRead(), connectionWrite(), and getConnection().

◆ _dist_plot_num_points

std::size_t MooseServer::_dist_plot_num_points
private

_dist_plot_num_points - distribution plot sampling resolution

Definition at line 529 of file MooseServer.h.

Referenced by buildDistPlotResponses(), and setDistPlotNumPoints().

◆ _dist_plot_quantile_bound

double MooseServer::_dist_plot_quantile_bound
private

_dist_plot_quantile_bound - epsilon to bound plot range tails

Definition at line 534 of file MooseServer.h.

Referenced by buildDistPlotResponses().

◆ _formatting_tab_size

std::size_t MooseServer::_formatting_tab_size
private

_formatting_tab_size - number of indent spaces for formatting

Definition at line 524 of file MooseServer.h.

Referenced by formatDocument(), and gatherDocumentFormattingTextEdits().

◆ _moose_app

MooseApp& MooseServer::_moose_app
private

_moose_app - reference to parent application that owns this server

Definition at line 504 of file MooseServer.h.

Referenced by getRegistrationApp(), and parseDocumentForDiagnostics().


The documentation for this class was generated from the following files: