OpenVDB  9.0.1
Logger.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3 
4 /// @file compiler/Logger.h
5 ///
6 /// @authors Richard Jones
7 ///
8 /// @brief Logging system to collect errors and warnings throughout the
9 /// different stages of parsing and compilation.
10 ///
11 
12 #ifndef OPENVDB_AX_COMPILER_LOGGER_HAS_BEEN_INCLUDED
13 #define OPENVDB_AX_COMPILER_LOGGER_HAS_BEEN_INCLUDED
14 
15 #include "../ast/AST.h"
16 
17 #include <openvdb/version.h>
18 
19 #include <functional>
20 #include <string>
21 #include <unordered_map>
22 
23 class TestLogger;
24 
25 namespace openvdb {
27 namespace OPENVDB_VERSION_NAME {
28 
29 namespace ax {
30 
31 /// @brief Logger for collecting errors and warnings that occur during AX
32 /// compilation.
33 ///
34 /// @details Error and warning output can be customised using the function
35 /// pointer arguments. These require a function that takes the formatted error
36 /// or warning string and handles the output, returning void.
37 /// e.g.
38 /// void streamCerr(const std::string& message) {
39 /// std::cerr << message << std::endl;
40 /// }
41 ///
42 /// The Logger handles formatting of messages, tracking of number of errors or
43 /// warnings and retrieval of errored lines of code to be printed if needed.
44 /// Use of the Logger to track new errors or warnings can be done either with
45 /// the line/column numbers directly (e.g during lexing and parsing where the
46 /// code is being iterated through) or referring to the AST node using its
47 /// position in the Tree (e.g. during codegen where only the AST node is known
48 /// directly, not the corresponding line/column numbers). To find the line or
49 /// column numbers for events logged using AST nodes, the Logger stores a map
50 /// of Node* to line and column numbers. This must be populated e.g. during
51 /// parsing, to allow resolution of code locations when they are not
52 /// explicitly available. The Logger also stores a pointer to the AST Tree
53 /// that these nodes belong to and the code used to create it.
54 class Logger
55 {
56 public:
57  using Ptr = std::shared_ptr<Logger>;
58 
59  using CodeLocation = std::pair<size_t, size_t>;
60  using OutputFunction = std::function<void(const std::string&)>;
61 
62  /// @brief Construct a Logger with optional error and warning output
63  /// functions, defaults stream errors to std::cerr and suppress warnings
64  /// @param errors Optional error output function
65  /// @param warnings Optional warning output function
66  Logger(const OutputFunction& errors =
67  [](const std::string& msg){
68  std::cerr << msg << std::endl;
69  },
70  const OutputFunction& warnings = [](const std::string&){});
71  ~Logger();
72 
73  /// @brief Log a compiler error and its offending code location. If the
74  /// offending location is (0,0), the message is treated as not having an
75  /// associated code location.
76  /// @param message The error message
77  /// @param lineCol The line/column number of the offending code
78  /// @return true if non-fatal and can continue to capture future messages.
79  bool error(const std::string& message, const CodeLocation& lineCol = CodeLocation(0,0));
80 
81  /// @brief Log a compiler error using the offending AST node. Used in AST
82  /// traversal.
83  /// @param message The error message
84  /// @param node The offending AST node causing the error
85  /// @return true if non-fatal and can continue to capture future messages.
86  bool error(const std::string& message, const ax::ast::Node* node);
87 
88  /// @brief Log a compiler warning and its offending code location. If the
89  /// offending location is (0,0), the message is treated as not having an
90  /// associated code location.
91  /// @param message The warning message
92  /// @param lineCol The line/column number of the offending code
93  /// @return true if non-fatal and can continue to capture future messages.
94  bool warning(const std::string& message, const CodeLocation& lineCol = CodeLocation(0,0));
95 
96  /// @brief Log a compiler warning using the offending AST node. Used in AST
97  /// traversal.
98  /// @param message The warning message
99  /// @param node The offending AST node causing the warning
100  /// @return true if non-fatal and can continue to capture future messages.
101  bool warning(const std::string& message, const ax::ast::Node* node);
102 
103  ///
104 
105  /// @brief Returns the number of errors that have been encountered
106  inline size_t errors() const { return mNumErrors; }
107  /// @brief Returns the number of warnings that have been encountered
108  inline size_t warnings() const { return mNumWarnings; }
109 
110  /// @brief Returns true if an error has been found, false otherwise
111  inline bool hasError() const { return this->errors() > 0; }
112  /// @brief Returns true if a warning has been found, false otherwise
113  inline bool hasWarning() const { return this->warnings() > 0; }
114  /// @brief Returns true if it has errored and the max errors has been hit
115  inline bool atErrorLimit() const {
116  return this->getMaxErrors() > 0 && this->errors() >= this->getMaxErrors();
117  }
118 
119  /// @brief Clear the tree-code mapping and reset the number of errors/warnings
120  /// @note The tree-code mapping must be repopulated to retrieve line and
121  /// column numbers during AST traversal i.e. code generation. The
122  /// openvdb::ax::ast::parse() function does this for a given input code
123  /// string.
124  void clear();
125 
126  /// @brief Set any warnings that are encountered to be promoted to errors
127  /// @param warnAsError If true, warnings will be treated as errors
128  void setWarningsAsErrors(const bool warnAsError = false);
129  /// @brief Returns if warning are promoted to errors
130  bool getWarningsAsErrors() const;
131 
132  /// @brief Sets the maximum number of errors that are allowed before
133  /// compilation should exit
134  /// @param maxErrors The number of allowed errors
135  void setMaxErrors(const size_t maxErrors = 0);
136  /// @brief Returns the number of allowed errors
137  size_t getMaxErrors() const;
138 
139  /// Error/warning formatting options
140 
141  /// @brief Set whether the output should number the errors/warnings
142  /// @param numbered If true, messages will be numbered
143  void setNumberedOutput(const bool numbered = true);
144  /// @brief Number of spaces to indent every new line before the message is formatted
145  void setIndent(const size_t ident = 0);
146  /// @brief Set a prefix for each warning message
147  void setErrorPrefix(const char* prefix = "error: ");
148  /// @brief Set a prefix for each warning message
149  void setWarningPrefix(const char* prefix = "warning: ");
150  /// @brief Set whether the output should include the offending line of code
151  /// @param print If true, offending lines of code will be appended to the
152  /// output message
153  void setPrintLines(const bool print = true);
154 
155  /// @brief Returns whether the messages will be numbered
156  bool getNumberedOutput() const;
157  /// @brief Returns the number of spaces to be printed before every new line
158  size_t getIndent() const;
159  /// @brief Returns the prefix for each error message
160  const char* getErrorPrefix() const;
161  /// @brief Returns the prefix for each warning message
162  const char* getWarningPrefix() const;
163  /// @brief Returns whether the messages will include the line of offending code
164  bool getPrintLines() const;
165 
166  /// @brief Set the source code that lines can be printed from if an error or
167  /// warning is raised
168  /// @param code The AX code as a c-style string
169  void setSourceCode(const char* code);
170 
171  /// These functions are only to be used during parsing to allow line and
172  /// column number retrieval during later stages of compilation when working
173  /// solely with an AST
174 
175  /// @brief Set the AST source tree which will be used as reference for the
176  /// locations of nodes when resolving line and column numbers during AST
177  /// traversal
178  /// @note To be used just by ax::parse before any AST modifications to
179  /// ensure traversal of original source tree is possible, when adding
180  /// messages using Node* which may correspond to modified trees
181  /// @param tree Pointer to const AST
182  void setSourceTree(openvdb::ax::ast::Tree::ConstPtr tree);
183 
184  /// @brief Add a node to the code location map
185  /// @param node Pointer to AST node
186  /// @param location Line and column number in code
187  void addNodeLocation(const ax::ast::Node* node, const CodeLocation& location);
188 
189  // forward declaration
190  struct Settings;
191  struct SourceCode;
192 
193 private:
194 
195  friend class ::TestLogger;
196 
197  std::function<void(const std::string&)> mErrorOutput;
198  std::function<void(const std::string&)> mWarningOutput;
199 
200  size_t mNumErrors;
201  size_t mNumWarnings;
202 
203  std::unique_ptr<Settings> mSettings;
204 
205  // components needed for verbose error info i.e. line/column numbers and
206  // lines from source code
207  std::unique_ptr<SourceCode> mCode;
208  ax::ast::Tree::ConstPtr mTreePtr;
209  std::unordered_map<const ax::ast::Node*, CodeLocation> mNodeToLineColMap;
210 };
211 
212 } // namespace ax
213 } // namespace OPENVDB_VERSION_NAME
214 } // namespace openvdb
215 
216 #endif // OPENVDB_AX_COMPILER_LOGGER_HAS_BEEN_INCLUDED
217 
Logger for collecting errors and warnings that occur during AX compilation.
Definition: Logger.h:54
bool hasWarning() const
Returns true if a warning has been found, false otherwise.
Definition: Logger.h:113
std::function< void(const std::string &)> OutputFunction
Definition: Logger.h:60
Definition: Exceptions.h:13
The base abstract node which determines the interface and required methods for all derived concrete n...
Definition: AST.h:101
std::shared_ptr< Logger > Ptr
Definition: Logger.h:57
size_t errors() const
Returns the number of errors that have been encountered.
Definition: Logger.h:106
bool hasError() const
Returns true if an error has been found, false otherwise.
Definition: Logger.h:111
size_t warnings() const
Returns the number of warnings that have been encountered.
Definition: Logger.h:108
bool atErrorLimit() const
Returns true if it has errored and the max errors has been hit.
Definition: Logger.h:115
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:116
std::pair< size_t, size_t > CodeLocation
Definition: Logger.h:59
void print(const ast::Node &node, const bool numberStatements=true, std::ostream &os=std::cout, const char *indent=" ")
Writes a descriptive printout of a Node hierarchy into a target stream.
std::shared_ptr< const Tree > ConstPtr
Definition: AST.h:564
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:202