Line data Source code
1 : //* This file is part of the MOOSE framework
2 : //* https://mooseframework.inl.gov
3 : //*
4 : //* All rights reserved, see COPYRIGHT for full restrictions
5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 : //*
7 : //* Licensed under LGPL 2.1, please see LICENSE for details
8 : //* https://www.gnu.org/licenses/lgpl-2.1.html
9 :
10 : #pragma once
11 :
12 : #include "MooseApp.h"
13 : #include "wasplsp/LSP.h"
14 : #include "wasplsp/ServerImpl.h"
15 : #include "wasplsp/Connection.h"
16 : #include "libmesh/ignore_warnings.h"
17 : #include "wasplsp/IOStreamConnection.h"
18 : #include "libmesh/restore_warnings.h"
19 : #include "waspcore/Object.h"
20 : #include "wasphit/HITNodeView.h"
21 : #include "waspsiren/SIRENInterpreter.h"
22 : #include "waspsiren/SIRENResultSet.h"
23 : #include "waspplot/CustomPlotFile.h"
24 : #include <string>
25 : #include <memory>
26 : #include <set>
27 : #include <map>
28 :
29 : class MooseServer : public wasp::lsp::ServerImpl
30 : {
31 : public:
32 : MooseServer(MooseApp & moose_app);
33 :
34 4 : virtual ~MooseServer() = default;
35 :
36 : /**
37 : * Get read / write connection - specific to this server implemention.
38 : * @return - shared pointer to the server's read / write connection
39 : */
40 2 : std::shared_ptr<wasp::lsp::Connection> getConnection() { return _connection; }
41 :
42 : /**
43 : * Public interface for writable check app reference with error checks.
44 : * @return - writable reference to check app for current input document
45 : */
46 : MooseApp & getCheckApp();
47 :
48 : private:
49 : /**
50 : * SortedLocationNodes - type alias for set of nodes sorted by location
51 : */
52 : using SortedLocationNodes =
53 : std::set<wasp::HITNodeView,
54 : std::function<bool(const wasp::HITNodeView &, const wasp::HITNodeView &)>>;
55 :
56 : /**
57 : * Parse document for diagnostics - specific to this server implemention.
58 : * @param diagnosticsList - data array of diagnostics data objects to fill
59 : * @return - true if completed successfully - does not indicate parse fail
60 : */
61 : bool parseDocumentForDiagnostics(wasp::DataArray & diagnosticsList);
62 :
63 : /**
64 : * Add paths from includes and FileName parameters for client to watch.
65 : */
66 : void addResourcesForDocument();
67 :
68 : /**
69 : * Recursively walk input to gather all FileName type parameter values.
70 : * @param filename_vals - set to fill up with FileName parameter values
71 : * @param parent - nodeview for recursive tree traversal starting point
72 : */
73 : void getFileNameTypeValues(std::set<std::string> & filename_vals, wasp::HITNodeView parent);
74 :
75 : /**
76 : * Gather document completion items - specific to this server implemention.
77 : * @param completionItems - data array of completion item objects to fill
78 : * @param is_incomplete - flag indicating if the completions are complete
79 : * @param line - line to be used for completions gathering logic
80 : * @param character - column to be used for completions gathering logic
81 : * @return - true if the gathering of items completed successfully
82 : */
83 : bool gatherDocumentCompletionItems(wasp::DataArray & completionItems,
84 : bool & is_incomplete,
85 : int line,
86 : int character);
87 :
88 : /**
89 : * Get names of parameters and subblocks specified in given input node.
90 : * @param parent_node - object node context under which to gather input
91 : * @param existing_params - set to fill with parameter names from input
92 : * @param existing_subblocks - set to fill with subblock names in input
93 : */
94 : void getExistingInput(wasp::HITNodeView parent_node,
95 : std::set<std::string> & existing_params,
96 : std::set<std::string> & existing_subblocks);
97 :
98 : /**
99 : * Get all global parameters, action parameters, and object parameters.
100 : * @param valid_params - collection to fill with valid input parameters
101 : * @param object_path - full node path where autocomplete was requested
102 : * @param object_type - type of object where autocomplete was requested
103 : * @param obj_act_tasks - set for adding in all MooseObjectAction tasks
104 : */
105 : void getAllValidParameters(InputParameters & valid_params,
106 : const std::string & object_path,
107 : const std::string & object_type,
108 : std::set<std::string> & obj_act_tasks);
109 :
110 : /**
111 : * Get all action parameters using requested object path to collection.
112 : * @param valid_params - collection for filling action input parameters
113 : * @param object_path - full node path where autocomplete was requested
114 : * @param obj_act_tasks - set for adding in all MooseObjectAction tasks
115 : */
116 : void getActionParameters(InputParameters & valid_params,
117 : const std::string & object_path,
118 : std::set<std::string> & obj_act_tasks);
119 :
120 : /**
121 : * Get all object parameters using requested object path to collection.
122 : * @param valid_params - collection for filling object input parameters
123 : * @param object_type - type of object where autocomplete was requested
124 : * @param obj_act_tasks - tasks to verify object type with valid syntax
125 : */
126 : void getObjectParameters(InputParameters & valid_params,
127 : std::string object_type,
128 : const std::set<std::string> & obj_act_tasks);
129 :
130 : /**
131 : * Add parameters that were previously gathered to list for completion.
132 : * @param completionItems - list of completion objects to be filled out
133 : * @param valid_params - all valid parameters to add to completion list
134 : * @param existing_params - set of parameters already existing in input
135 : * @param replace_line_beg - start line of autocompletion replace range
136 : * @param replace_char_beg - start column of autocomplete replace range
137 : * @param replace_line_end - end line of autocomplete replacement range
138 : * @param replace_char_end - end column of autocompletion replace range
139 : * @param filtering_prefix - beginning text to filter list if not empty
140 : * @return - true if filling of completion items completed successfully
141 : */
142 : bool addParametersToList(wasp::DataArray & completionItems,
143 : const InputParameters & valid_params,
144 : const std::set<std::string> & existing_params,
145 : int replace_line_beg,
146 : int replace_char_beg,
147 : int replace_line_end,
148 : int replace_char_end,
149 : const std::string & filtering_prefix);
150 :
151 : /**
152 : * Add subblocks to completion list for request path, line, and column.
153 : * @param completionItems - list of completion objects to be filled out
154 : * @param object_path - full node path where autocomplete was requested
155 : * @param replace_line_beg - start line of autocompletion replace range
156 : * @param replace_char_beg - start column of autocomplete replace range
157 : * @param replace_line_end - end line of autocomplete replacement range
158 : * @param replace_char_end - end column of autocompletion replace range
159 : * @param filtering_prefix - beginning text to filter list if not empty
160 : * @return - true if filling of completion items completed successfully
161 : */
162 : bool addSubblocksToList(wasp::DataArray & completionItems,
163 : const std::string & object_path,
164 : int replace_line_beg,
165 : int replace_char_beg,
166 : int replace_line_end,
167 : int replace_char_end,
168 : const std::string & filtering_prefix,
169 : bool request_on_block_decl);
170 :
171 : /**
172 : * Add parameter values to completion list for request line and column.
173 : * @param completionItems - list of completion objects to be filled out
174 : * @param valid_params - all valid parameters used for value completion
175 : * @param existing_params - set of parameters already existing in input
176 : * @param existing_subblocks - active and inactive subblock name values
177 : * @param param_name - name of input parameter for value autocompletion
178 : * @param obj_act_tasks - tasks to verify object type with valid syntax
179 : * @param object_path - full node path where autocomplete was requested
180 : * @param replace_line_beg - start line of autocompletion replace range
181 : * @param replace_char_beg - start column of autocomplete replace range
182 : * @param replace_line_end - end line of autocomplete replacement range
183 : * @param replace_char_end - end column of autocompletion replace range
184 : * @return - true if filling of completion items completed successfully
185 : */
186 : bool addValuesToList(wasp::DataArray & completionItems,
187 : const InputParameters & valid_params,
188 : const std::set<std::string> & existing_params,
189 : const std::set<std::string> & existing_subblocks,
190 : const std::string & param_name,
191 : const std::set<std::string> & obj_act_tasks,
192 : const std::string & object_path,
193 : int replace_line_beg,
194 : int replace_char_beg,
195 : int replace_line_end,
196 : int replace_char_end);
197 :
198 : /**
199 : * Fill map of all options and descriptions if parameter is moose enum.
200 : * @param moose_enum_param - parameter to get documentation and options
201 : * @param options_and_descs - map to fill with options and descriptions
202 : */
203 : template <typename MooseEnumType>
204 : void getEnumsAndDocs(MooseEnumType & moose_enum_param,
205 : std::map<std::string, std::string> & options_and_descs);
206 :
207 : /**
208 : * Supplement completion list with objects in warehouses if applicable.
209 : * @param param_type - parameter type string to pick suitable warehouse
210 : * @param options_and_descs - map to fill with options and descriptions
211 : */
212 : void addObjectsFromWarehouses(const std::string & param_type,
213 : std::map<std::string, std::string> & options_and_descs);
214 :
215 : /**
216 : * Gather definition locations - specific to this server implemention.
217 : * @param definitionLocations - data array of locations objects to fill
218 : * @param line - line to be used for locations gathering logic
219 : * @param character - column to be used for locations gathering logic
220 : * @return - true if the gathering of locations completed successfully
221 : */
222 : bool
223 : gatherDocumentDefinitionLocations(wasp::DataArray & definitionLocations, int line, int character);
224 :
225 : /**
226 : * Get set of nodes from associated path lookups matching value string.
227 : * @param location_nodes - set to fill with lookup nodes matching value
228 : * @param clean_type - cpp type string used for key finding input paths
229 : * @param val_string - specified value used for gathering input lookups
230 : */
231 : void getInputLookupDefinitionNodes(SortedLocationNodes & location_nodes,
232 : const std::string & clean_type,
233 : const std::string & val_string);
234 :
235 : /**
236 : * Add set of nodes sorted by location to definition or reference list.
237 : * @param defsOrRefsLocations - data array of locations objects to fill
238 : * @param location_nodes - set of nodes that have locations to be added
239 : * @return - true if filling of location objects completed successfully
240 : */
241 : bool addLocationNodesToList(wasp::DataArray & defsOrRefsLocations,
242 : const SortedLocationNodes & location_nodes);
243 :
244 : /**
245 : * Get hover display text - logic specific to this server implemention.
246 : * @param display_text - string reference to add hover text for display
247 : * @param line - zero-based line to use for finding node and hover text
248 : * @param character - zero-based column for finding node and hover text
249 : * @return - true if display text was added or left empty without error
250 : */
251 : bool getHoverDisplayText(std::string & display_text, int line, int character);
252 :
253 : /**
254 : * Gather references locations - specific to this server implemention.
255 : * @param referencesLocations - data array of locations objects to fill
256 : * @param line - line to be used for locations gathering logic
257 : * @param character - column to be used for locations gathering logic
258 : * @param include_declaration - flag indicating declaration inclusion
259 : * @return - true if the gathering of locations completed successfully
260 : */
261 : bool gatherDocumentReferencesLocations(wasp::DataArray & referencesLocations,
262 : int line,
263 : int character,
264 : bool include_declaration);
265 :
266 : /**
267 : * Recursively walk input to gather all nodes matching value and types.
268 : * @param match_nodes - set to fill with nodes matching value and types
269 : * @param view_parent - nodeview used to start recursive tree traversal
270 : * @param target_value -
271 : * @param target_types -
272 : */
273 : void getNodesByValueAndTypes(SortedLocationNodes & match_nodes,
274 : wasp::HITNodeView view_parent,
275 : const std::string & target_value,
276 : const std::set<std::string> & target_types);
277 :
278 : /**
279 : * Gather formatting text edits - specific to this server implemention.
280 : * @param formattingTextEdits - data array of text edit objects to fill
281 : * @param tab_size - value of the size of a tab in spaces for formatting
282 : * @param insert_spaces - flag indicating whether to use spaces for tabs
283 : * @return - true if the gathering of text edits completed successfully
284 : */
285 : bool gatherDocumentFormattingTextEdits(wasp::DataArray & formattingTextEdits,
286 : int tab_size,
287 : bool insert_spaces);
288 :
289 : /**
290 : * Recursively walk down whole nodeview tree while formatting document.
291 : * @param parent - nodeview for recursive tree traversal starting point
292 : * @param prev_line - line of last print for blanks and inline comments
293 : * @param level - current level in document tree to use for indentation
294 : * @return - formatted string that gets appended to each recursive call
295 : */
296 : std::string formatDocument(wasp::HITNodeView parent, std::size_t & prev_line, std::size_t level);
297 :
298 : /**
299 : * Gather document symbols - specific to this server implemention.
300 : * @param documentSymbols - data array of symbols data objects to fill
301 : * @return - true if the gathering of symbols completed successfully
302 : */
303 : bool gatherDocumentSymbols(wasp::DataArray & documentSymbols);
304 :
305 : /**
306 : * Recursively fill document symbols from the given node.
307 : * @param view_parent - nodeview used in recursive tree traversal
308 : * @param data_parent - data object with array of symbol children
309 : * @return - true if no problems with this level of the resursion
310 : */
311 : bool traverseParseTreeAndFillSymbols(wasp::HITNodeView view_parent,
312 : wasp::DataObject & data_parent);
313 :
314 : /**
315 : * Get completion item kind value that client may use for icon in list.
316 : * @param valid_params - valid parameters used for completion item kind
317 : * @param param_name - name of input parameter for completion item kind
318 : * @param clean_type - type to decide if reference completion item kind
319 : * @param is_param - boolean denoting if kind is for parameter or value
320 : * @return - enumerated kind value that client may use for icon in list
321 : */
322 : int getCompletionItemKind(const InputParameters & valid_params,
323 : const std::string & param_name,
324 : const std::string & clean_type,
325 : bool is_param);
326 :
327 : /**
328 : * Get document symbol kind value that client may use for outline icon.
329 : * @param symbol_node - node that will be added to symbol tree for kind
330 : * @return - enumerated kind value that client may use for outline icon
331 : */
332 : int getDocumentSymbolKind(wasp::HITNodeView symbol_node);
333 :
334 : /**
335 : * Get required parameter completion text list for given subblock path.
336 : * @param subblock_path - subblock path for finding required parameters
337 : * @param subblock_type - subblock type for finding required parameters
338 : * @param existing_params - set of parameters already existing in input
339 : * @param indent_spaces - indentation to be added before each parameter
340 : * @return - list of required parameters to use in subblock insert text
341 : */
342 : std::string getRequiredParamsText(const std::string & subblock_path,
343 : const std::string & subblock_type,
344 : const std::set<std::string> & existing_params,
345 : const std::string & indent_spaces);
346 :
347 : /**
348 : * Gather extension responses - specific to this server implemention.
349 : * @param extensionResponses - data array of custom responses to fill
350 : * @param extensionMethod - name for current extension request method
351 : * @param line - zero-based line to use for logic of custom extension
352 : * @param character - zero-based column for logic of custom extension
353 : * @return - true if request successfully handled with response built
354 : */
355 : bool gatherExtensionResponses(wasp::DataArray & extensionResponses,
356 : const std::string & extensionMethod,
357 : int line,
358 : int character);
359 :
360 : /**
361 : * Build CustomPlot extension responses when method name is plotting.
362 : * @param plottingResponses - array to fill with CustomPlot responses
363 : * @param line - zero-based line to use for logic of custom extension
364 : * @param character - zero-based column for logic of custom extension
365 : * @return - true if request successfully handled with response built
366 : */
367 : bool gatherPlottingResponses(wasp::DataArray & plottingResponses, int line, int character);
368 :
369 : /**
370 : * Build CustomPlot graph with provided keys, values, and plot title.
371 : * @param plot_object - CustomPlot object to be built into line graph
372 : * @param plot_title - title for plot composed of block name and type
373 : * @param graph_keys - abscissa values from function for graph x-axis
374 : * @param graph_vals - ordinate values from function for graph y-axis
375 : */
376 : void buildLineGraphPlot(wasp::CustomPlot & plot_object,
377 : const std::string & plot_title,
378 : const std::vector<double> & graph_keys,
379 : const std::vector<double> & graph_vals);
380 :
381 : /**
382 : * Read from connection into object - specific to this server's connection.
383 : * @param object - reference to object to be read into
384 : * @return - true if the read from the connection completed successfully
385 : */
386 0 : bool connectionRead(wasp::DataObject & object) { return _connection->read(object, errors); }
387 :
388 : /**
389 : * Write object json to connection - specific to this server's connection.
390 : * @param object - reference to object with contents to write to connection
391 : * @return - true if the write to the connection completed successfully
392 : */
393 0 : bool connectionWrite(wasp::DataObject & object) { return _connection->write(object, errors); }
394 :
395 : /**
396 : * @return Whether or not the root is valid
397 : *
398 : * Will be true if the app is valid, the root is not nullptr, and the root node view is not null
399 : */
400 : bool rootIsValid() const;
401 :
402 : /**
403 : * Helper for storing the state for a single document
404 : */
405 : struct CheckState
406 : {
407 26 : CheckState(std::shared_ptr<Parser> & parser) : parser(parser) {}
408 : std::shared_ptr<Parser> parser;
409 : std::unique_ptr<MooseApp> app;
410 : };
411 :
412 : /**
413 : * @return The check state for the current document path, if any
414 : */
415 : ///@{
416 : const CheckState * queryCheckState() const;
417 : CheckState * queryCheckState();
418 : ///@}
419 : /**
420 : * @return The check app for the current document path, if any
421 : */
422 : ///@{
423 : const MooseApp * queryCheckApp() const;
424 : MooseApp * queryCheckApp();
425 : ///@}
426 : /**
427 : * @return The check parser for the current document path, if any
428 : */
429 : ///@{
430 : const Parser * queryCheckParser() const;
431 : Parser * queryCheckParser();
432 : ///@}
433 : /**
434 : * @return The root node from the check parser for the current document path, if any
435 : */
436 : const hit::Node * queryRoot() const;
437 :
438 : /**
439 : * @return The root node from the check parser for the current document path, with error checking
440 : * on if it exists
441 : */
442 : const hit::Node & getRoot() const;
443 :
444 : /**
445 : * @brief _moose_app - reference to parent application that owns this server
446 : */
447 : MooseApp & _moose_app;
448 :
449 : /**
450 : * @brief _check_state - map from document paths to state (parser, app, text)
451 : */
452 : std::map<std::string, CheckState> _check_state;
453 :
454 : /**
455 : * @brief _connection - shared pointer to this server's read / write iostream
456 : */
457 : std::shared_ptr<wasp::lsp::IOStreamConnection> _connection;
458 :
459 : /**
460 : * @brief _syntax_to_subblocks - map of syntax paths to valid subblocks
461 : */
462 : std::map<std::string, std::set<std::string>> _syntax_to_subblocks;
463 :
464 : /**
465 : * @brief _type_to_input_paths - map of parameter types to lookup paths
466 : */
467 : std::map<std::string, std::set<std::string>> _type_to_input_paths;
468 :
469 : /**
470 : * @brief _type_to_input_paths - map of lookup paths to parameter types
471 : */
472 : std::map<std::string, std::set<std::string>> _input_path_to_types;
473 :
474 : /**
475 : * @brief _formatting_tab_size - number of indent spaces for formatting
476 : */
477 : std::size_t _formatting_tab_size;
478 : };
|