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 1308 of file MooseServer.C.

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

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 1085 of file MooseServer.C.

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

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

292{
293 // return without any resources added for document if parser root is null
294 auto root_ptr = queryRoot();
295 if (!root_ptr)
296 return;
297 auto & root = *root_ptr;
298
299 // return without document resources added if client does not watch files
300 if (!client_watcher_support)
301 return;
302
303 // get input parse tree root node to be used for gathering resource files
304 wasp::HITNodeView view_root = root.getNodeView();
305 std::set<std::string> include_paths, filename_vals, resource_uris;
306
307 // gather paths of include inputs and add to resource uris if files exist
308 view_root.node_pool()->descendant_include_paths(include_paths);
309 for (const auto & include_path : include_paths)
310 {
311 auto normalized = std::filesystem::path(include_path).lexically_normal().string();
312 if (MooseUtils::checkFileReadable(normalized, false, false, false))
313 resource_uris.insert(wasp::lsp::prefixUriScheme(normalized));
314 }
315
316 // gather paths of FileName types and add to resource uris if files exist
317 getFileNameTypeValues(filename_vals, view_root);
318 for (const auto & filename_val : filename_vals)
319 {
320 auto input_path = wasp::lsp::removeUriScheme(document_path);
321 auto input_base = std::filesystem::path(input_path).parent_path();
322 auto fname_path = std::filesystem::path(filename_val);
323 auto fname_absl = fname_path.is_absolute() ? fname_path : (input_base / fname_path);
324 auto normalized = fname_absl.lexically_normal().string();
325 if (MooseUtils::checkFileReadable(normalized, false, false, false))
326 resource_uris.insert(wasp::lsp::prefixUriScheme(normalized));
327 }
328
329 // add collection of all gathered paths as resources for current document
330 setResourcesForBase(document_path, resource_uris);
331}
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 788 of file MooseServer.C.

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

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

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

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

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

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 1617 of file MooseServer.C.

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

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

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

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

◆ 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 1448 of file MooseServer.C.

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

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

1901{
1902 // use appropriate method to fill response based on extension method name
1903 bool pass = true;
1904 if (extensionMethod == "plotting")
1905 pass = gatherPlottingResponses(extensionResponses, line, character);
1906 return pass;
1907}
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 1910 of file MooseServer.C.

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

583{
584 Syntax & syntax = getRegistrationApp().syntax();
586
587 // get registered syntax path identifier using actual object context path
588 bool is_parent;
589 std::string registered_syntax = syntax.isAssociated(object_path, &is_parent);
590
591 // use is_parent to skip action parameters when not explicitly registered
592 if (!is_parent)
593 {
594 // get action objects associated with registered syntax path identifier
595 auto action_range = syntax.getActions(registered_syntax);
596
597 // traverse action objects for syntax to gather valid action parameters
598 for (auto action_iter = action_range.first; action_iter != action_range.second; action_iter++)
599 {
600 const std::string & action_name = action_iter->second._action;
601
602 // use action name to get set of valid parameters from action factory
603 InputParameters action_params = action_factory.getValidParams(action_name);
604
605 // gather all MooseObjectAction tasks for verifying object parameters
606 if (action_params.have_parameter<bool>("isObjectAction"))
607 {
608 if (action_params.get<bool>("isObjectAction"))
609 {
610 std::set<std::string> tasks_by_actions = action_factory.getTasksByAction(action_name);
611 obj_act_tasks.insert(tasks_by_actions.begin(), tasks_by_actions.end());
612 }
613
614 // filter parameter from completion list as it is not used in input
615 action_params.remove("isObjectAction");
616 }
617
618 // add parameters from action to full valid collection being gathered
619 valid_params += action_params;
620 }
621 }
622}
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 568 of file MooseServer.C.

572{
573 // gather global parameters then action parameters then object parameters
574 valid_params += Moose::Builder::validParams();
575 getActionParameters(valid_params, object_path, obj_act_tasks);
576 getObjectParameters(valid_params, object_type, obj_act_tasks);
577}
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 2152 of file MooseServer.C.

2153{
2154 if (auto app_ptr = queryCheckApp())
2155 {
2156 auto & app = *app_ptr;
2157 mooseAssert(queryCheckParser(), "Should have a parser");
2158 mooseAssert(&app.parser() == queryCheckParser(), "Parser should be the app's parser");
2159 return app;
2160 }
2161 mooseError("MooseServer::getCheckApp(): App not available");
2162}
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 1792 of file MooseServer.C.

1796{
1797 // set up completion item kind value that client may use for icon in list
1798 auto associated_types = getRegistrationApp().syntax().getAssociatedTypes();
1799 if (is_param && valid_params.isParamRequired(param_name) &&
1800 !valid_params.isParamValid(param_name))
1801 return wasp::lsp::m_comp_kind_event;
1802 else if (param_name == "active" || param_name == "inactive")
1803 return wasp::lsp::m_comp_kind_class;
1804 else if (clean_type == "bool")
1805 return wasp::lsp::m_comp_kind_interface;
1806 else if (valid_params.have_parameter<MooseEnum>(param_name) ||
1807 valid_params.have_parameter<MultiMooseEnum>(param_name) ||
1808 valid_params.have_parameter<ExecFlagEnum>(param_name) ||
1809 valid_params.have_parameter<std::vector<MooseEnum>>(param_name))
1810 return is_param ? wasp::lsp::m_comp_kind_enum : wasp::lsp::m_comp_kind_enum_member;
1811 else if (param_name == "type")
1812 return wasp::lsp::m_comp_kind_type_param;
1813 else if (std::find_if(associated_types.begin(),
1814 associated_types.end(),
1815 [&](const auto & entry)
1816 { return entry.second == clean_type; }) != associated_types.end())
1817 return wasp::lsp::m_comp_kind_reference;
1818 else
1819 return is_param ? wasp::lsp::m_comp_kind_keyword : wasp::lsp::m_comp_kind_value;
1820}
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 1823 of file MooseServer.C.

1824{
1825 // lambdas that check if parameter is a boolean or number for symbol kind
1826 auto is_boolean = [](wasp::HITNodeView symbol_node)
1827 {
1828 bool convert;
1829 std::istringstream iss(MooseUtils::toLower(symbol_node.last_as_string()));
1830 return (iss >> std::boolalpha >> convert && !iss.fail());
1831 };
1832 auto is_number = [](wasp::HITNodeView symbol_node)
1833 {
1834 double convert;
1835 std::istringstream iss(symbol_node.last_as_string());
1836 return (iss >> convert && iss.eof());
1837 };
1838
1839 // set up document symbol kind value that client may use for outline icon
1840 if (symbol_node.type() == wasp::OBJECT)
1841 return wasp::lsp::m_symbol_kind_struct;
1842 else if (symbol_node.type() == wasp::FILE)
1843 return wasp::lsp::m_symbol_kind_file;
1844 else if (symbol_node.type() == wasp::ARRAY)
1845 return wasp::lsp::m_symbol_kind_array;
1846 else if (symbol_node.type() == wasp::KEYED_VALUE && symbol_node.name() == std::string("type"))
1847 return wasp::lsp::m_symbol_kind_type_param;
1848 else if (symbol_node.type() == wasp::KEYED_VALUE && is_boolean(symbol_node))
1849 return wasp::lsp::m_symbol_kind_boolean;
1850 else if (symbol_node.type() == wasp::KEYED_VALUE && is_number(symbol_node))
1851 return wasp::lsp::m_symbol_kind_number;
1852 else if (symbol_node.type() == wasp::KEYED_VALUE)
1853 return wasp::lsp::m_symbol_kind_key;
1854 else if (symbol_node.type() == wasp::VALUE)
1855 return wasp::lsp::m_symbol_kind_string;
1856 else
1857 return wasp::lsp::m_symbol_kind_property;
1858}
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 1073 of file MooseServer.C.

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

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 550 of file MooseServer.C.

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

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 334 of file MooseServer.C.

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

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

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

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 1523 of file MooseServer.C.

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

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 625 of file MooseServer.C.

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

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

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 1861 of file MooseServer.C.

1865{
1866 // gather global, action, and object parameters in request object context
1867 InputParameters valid_params = emptyInputParameters();
1868 std::set<std::string> obj_act_tasks;
1869 getAllValidParameters(valid_params, subblock_path, subblock_type, obj_act_tasks);
1870
1871 // walk over collection of all parameters and build text of ones required
1872 std::string required_param_text;
1873 std::size_t param_index = 1;
1874
1875 // increment parameter tab stop index when adding custom user named block
1876 // this will allow first stop to be placeholder selecting that block name
1877 if (subblock_type.empty() && !subblock_path.empty() && subblock_path.back() == '*')
1878 param_index++;
1879
1880 for (const auto & valid_params_iter : valid_params)
1881 {
1882 // skip parameter if deprecated, private, defaulted, optional, existing
1883 const std::string & param_name = valid_params_iter.first;
1884 if (!valid_params.isParamDeprecated(param_name) && !valid_params.isPrivate(param_name) &&
1885 !valid_params.isParamValid(param_name) && valid_params.isParamRequired(param_name) &&
1886 !existing_params.count(param_name))
1887 {
1888 std::string tab_stop = client_snippet_support ? "$" + std::to_string(param_index++) : "";
1889 required_param_text += "\n" + indent_spaces + param_name + " = " + tab_stop;
1890 }
1891 }
1892
1893 return required_param_text;
1894}

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 2179 of file MooseServer.C.

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

Referenced by addValuesToList(), and getInputLookupDefinitionNodes().

◆ getSyntaxMetadata()

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

Definition at line 2173 of file MooseServer.C.

2174{
2176}
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 // error has filename that matches document currently getting processed
126 if (err.filename && *err.filename == parse_file_path)
127 {
128 // Has line information that is valid
129 if (err.lineinfo && err.lineinfo->start_line && err.lineinfo->start_column &&
130 err.lineinfo->end_line && err.lineinfo->end_column)
131 {
132 diagnostic(err.message,
133 err.lineinfo->start_line - 1,
134 err.lineinfo->start_column - 1,
135 err.lineinfo->end_line - 1,
136 err.lineinfo->end_column - 1);
137 return;
138 }
139 }
140
141 // no filename, or filename not matching this document, or no line info
142 zero_line_diagnostic(err.prefixed_message);
143 };
144
145 // Runs a try catch loop with the given action, collecting diagnostics
146 // from the known exceptions; returns a bool that is true if we executed
147 // without throwing anything
148 const auto try_catch = [&hit_error_message_diagnostic,
149 &hit_node_diagnostic,
150 &zero_line_diagnostic](const auto & action) -> bool
151 {
152 Moose::ScopedThrowOnError scoped_throw_on_error;
153
154 try
155 {
156 action();
157 }
158 // Will be thrown from the Parser while building the tree or
159 // by the builder while building the input parameters
160 catch (Parser::Error & err)
161 {
162 for (const auto & error_message : err.error_messages)
163 hit_error_message_diagnostic(error_message);
164 }
165 // Will be thrown by mooseError() when _throw_on_error is set
166 // to true, hopefully with hit node context
167 catch (MooseRuntimeError & err)
168 {
169 hit_node_diagnostic(err.getNode(), err.what());
170 }
171 // General catch all for everything else without context
172 catch (std::exception & err)
173 {
174 zero_line_diagnostic(err.what());
175 }
176
177 // continue to build app if parsing fails and run app if building fails
178 // so that problem is there for plotting and warehouse based completion
179 return true;
180 };
181
182 // Setup command line (needed by the Parser)
183 auto command_line = std::make_unique<CommandLine>(_moose_app.commandLine()->getArguments());
184 if (command_line->hasArgument("--language-server"))
185 command_line->removeArgument("--language-server");
186 command_line->addArgument("--check-input");
187 command_line->addArgument("--error-unused");
188 command_line->addArgument("--error");
189 command_line->addArgument("--color=off");
190 command_line->addArgument("--disable-perf-graph-live");
191 command_line->parse();
192
193 // Setup the parser that will be used in the app
194 auto parser = std::make_shared<Parser>(parse_file_path, document_text);
195 mooseAssert(parser->getInputFileNames()[0] == parse_file_path, "Should be consistent");
196 parser->setAppType(_moose_app.type());
197 parser->setCommandLineParams(command_line->buildHitParams());
198 parser->setThrowOnError(true);
199
200 // Try to parse the document
201 const bool parse_success = try_catch([&parser]() { parser->parse(); });
202 // If the Parser has a valid root, store it because we can use it
203 // in the future (hover text etc with a partially complete document)
204 CheckState * state = nullptr;
205 if (auto parser_root_ptr = parser->queryRoot();
206 parser_root_ptr && !parser_root_ptr->getNodeView().is_null())
207 {
208 auto it_inserted_pair = _check_state.emplace(document_path, parser);
209 mooseAssert(it_inserted_pair.second, "Should not already exist");
210 state = &it_inserted_pair.first->second;
211 }
212 // We have no root or an empty document, nothing else to do
213 else
214 return true;
215
216 // Failed to parse, don't bother building the app. But... we might
217 // have a root node at least!
218 if (!parse_success)
219 return pass;
220
221 // Try to instantiate the application
222 std::unique_ptr<MooseApp> app = nullptr;
223 const auto do_build_app = [this, &parse_file_path, &diagnostic, &parser, &command_line, &app]()
224 {
225 // get app type from parser which is Application block type if provided
226 const std::string & app_type = parser->getAppType();
227
228 // error if Application type specified in input has not been registered
229 if (!AppFactory::instance().isRegistered(app_type))
230 {
231 // get line and column range of Application/type/value for diagnostic
232 int error_line_beg = 0, error_char_beg = 0, error_line_end = 0, error_char_end = 0;
233 if (auto app_type_field = parser->getRoot().find("Application/type");
234 app_type_field && app_type_field->filename() == parse_file_path)
235 {
236 auto app_type_value = app_type_field->getNodeView().first_child_by_name("value");
237 if (!app_type_value.is_null())
238 {
239 error_line_beg = app_type_value.line() - 1;
240 error_char_beg = app_type_value.column() - 1;
241 error_line_end = app_type_value.last_line() - 1;
242 error_char_end = app_type_value.last_column();
243 }
244 }
245
246 // build error message string with available app types for diagnostic
247 std::vector<std::string> app_types;
248 for (const auto & apps_iter : AppFactory::instance().registeredObjects())
249 app_types.push_back(apps_iter.first);
250 const auto message = "'" + app_type + "' is not a registered application type. Registered" +
251 " application types are [" + MooseUtils::join(app_types, ", ") + "].";
252
253 // add diagnostic to get reported for Application/type not registered
254 diagnostic(message, error_line_beg, error_char_beg, error_line_end, error_char_end);
255 return;
256 }
257
258 // set up options from app type parameters with parser and command line
259 InputParameters app_params = AppFactory::instance().getValidParams(app_type);
260 app_params.set<std::shared_ptr<Parser>>("_parser") = parser;
261 app_params.set<std::shared_ptr<CommandLine>>("_command_line") = std::move(command_line);
262
263 // create application to use for diagnostic checks and input assistance
265 app_type, AppFactory::main_app_name, app_params, _moose_app.getCommunicator()->get());
266 };
267 if (!try_catch(do_build_app))
268 {
269 if (app)
270 app.reset();
271 return pass;
272 }
273
274 // do not attempt to run application if it is null after build from error
275 if (app)
276 {
277 // store application when it is valid and then run it to invoke builder
278 state->app = std::move(app);
279 const auto do_run_app = [this]() { getCheckApp().run(); };
280 if (!try_catch(do_run_app))
281 state->app.reset();
282 }
283
284 // add all resource files of document that will be registered with client
286
287 return pass;
288}
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:2033
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:308
OStreamProxy err(std::cerr)

◆ queryCheckApp() [1/2]

MooseApp * MooseServer::queryCheckApp ( )
private

Definition at line 2146 of file MooseServer.C.

2147{
2148 return const_cast<MooseApp *>(std::as_const(*this).queryCheckApp());
2149}
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 2138 of file MooseServer.C.

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

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

◆ queryCheckParser() [1/2]

Parser * MooseServer::queryCheckParser ( )
private

Definition at line 2132 of file MooseServer.C.

2133{
2134 return const_cast<Parser *>(std::as_const(*this).queryCheckParser());
2135}
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 2125 of file MooseServer.C.

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

Referenced by getCheckApp(), and queryRoot().

◆ queryCheckState() [1/2]

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

Definition at line 2119 of file MooseServer.C.

2120{
2121 return const_cast<MooseServer::CheckState *>(std::as_const(*this).queryCheckState());
2122}
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 2112 of file MooseServer.C.

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

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 2096 of file MooseServer.C.

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

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 1740 of file MooseServer.C.

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

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: