Bug 1865597 - Add error checking when initializing parallel marking and disable on...
[gecko.git] / js / src / frontend / ErrorReporter.h
blob4b3b7a4298276cbb830887881de8857abec20e29
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef frontend_ErrorReporter_h
8 #define frontend_ErrorReporter_h
10 #include "mozilla/Variant.h"
12 #include <optional>
13 #include <stdarg.h> // for va_list
14 #include <stddef.h> // for size_t
15 #include <stdint.h> // for uint32_t
17 #include "js/ColumnNumber.h" // JS::LimitedColumnNumberOneOrigin
18 #include "js/UniquePtr.h"
19 #include "vm/ErrorReporting.h" // ErrorMetadata, ReportCompile{Error,Warning}
21 namespace JS {
22 class JS_PUBLIC_API ReadOnlyCompileOptions;
25 namespace js {
26 namespace frontend {
28 // An interface class to provide strictMode getter method, which is used by
29 // ErrorReportMixin::strictModeError* methods.
31 // This class is separated to be used as a back-channel from TokenStream to the
32 // strict mode flag which is available inside Parser, to avoid exposing the
33 // rest of SharedContext to TokenStream.
34 class StrictModeGetter {
35 public:
36 virtual bool strictMode() const = 0;
39 // This class provides error reporting methods, including warning, extra
40 // warning, and strict mode error.
42 // A class that inherits this class must provide the following methods:
43 // * options
44 // * getContext
45 // * computeErrorMetadata
46 class ErrorReportMixin : public StrictModeGetter {
47 public:
48 // Returns a compile options (extra warning, warning as error) for current
49 // compilation.
50 virtual const JS::ReadOnlyCompileOptions& options() const = 0;
52 // Returns the current context.
53 virtual FrontendContext* getContext() const = 0;
55 // A variant class for the offset of the error or warning.
56 struct Current {};
57 struct NoOffset {};
58 using ErrorOffset = mozilla::Variant<uint32_t, Current, NoOffset>;
60 // Fills ErrorMetadata fields for an error or warning at given offset.
61 // * offset is uint32_t if methods ending with "At" is called
62 // * offset is NoOffset if methods ending with "NoOffset" is called
63 // * offset is Current otherwise
64 [[nodiscard]] virtual bool computeErrorMetadata(
65 ErrorMetadata* err, const ErrorOffset& offset) const = 0;
67 // ==== error ====
69 // Reports an error.
71 // Methods ending with "At" are for an error at given offset.
72 // The offset is passed to computeErrorMetadata method and is transparent
73 // for this class.
75 // Methods ending with "NoOffset" are for an error that doesn't correspond
76 // to any offset. NoOffset is passed to computeErrorMetadata for them.
78 // Other methods except errorWithNotesAtVA are for an error at the current
79 // offset. Current is passed to computeErrorMetadata for them.
81 // Methods contains "WithNotes" can be used if there are error notes.
83 // errorWithNotesAtVA is the actual implementation for all of above.
84 // This can be called if the caller already has a va_list.
86 void error(unsigned errorNumber, ...) const {
87 va_list args;
88 va_start(args, errorNumber);
90 errorWithNotesAtVA(nullptr, mozilla::AsVariant(Current()), errorNumber,
91 &args);
93 va_end(args);
95 void errorWithNotes(UniquePtr<JSErrorNotes> notes, unsigned errorNumber,
96 ...) const {
97 va_list args;
98 va_start(args, errorNumber);
100 errorWithNotesAtVA(std::move(notes), mozilla::AsVariant(Current()),
101 errorNumber, &args);
103 va_end(args);
105 void errorAt(uint32_t offset, unsigned errorNumber, ...) const {
106 va_list args;
107 va_start(args, errorNumber);
109 errorWithNotesAtVA(nullptr, mozilla::AsVariant(offset), errorNumber, &args);
111 va_end(args);
113 void errorWithNotesAt(UniquePtr<JSErrorNotes> notes, uint32_t offset,
114 unsigned errorNumber, ...) const {
115 va_list args;
116 va_start(args, errorNumber);
118 errorWithNotesAtVA(std::move(notes), mozilla::AsVariant(offset),
119 errorNumber, &args);
121 va_end(args);
123 void errorNoOffset(unsigned errorNumber, ...) const {
124 va_list args;
125 va_start(args, errorNumber);
127 errorWithNotesAtVA(nullptr, mozilla::AsVariant(NoOffset()), errorNumber,
128 &args);
130 va_end(args);
132 void errorWithNotesNoOffset(UniquePtr<JSErrorNotes> notes,
133 unsigned errorNumber, ...) const {
134 va_list args;
135 va_start(args, errorNumber);
137 errorWithNotesAtVA(std::move(notes), mozilla::AsVariant(NoOffset()),
138 errorNumber, &args);
140 va_end(args);
142 void errorWithNotesAtVA(UniquePtr<JSErrorNotes> notes,
143 const ErrorOffset& offset, unsigned errorNumber,
144 va_list* args) const {
145 ErrorMetadata metadata;
146 if (!computeErrorMetadata(&metadata, offset)) {
147 return;
150 ReportCompileErrorLatin1VA(getContext(), std::move(metadata),
151 std::move(notes), errorNumber, args);
154 // ==== warning ====
156 // Reports a warning.
158 // Returns true if the warning is reported.
159 // Returns false if the warning is treated as an error, or an error occurs
160 // while reporting.
162 // See the comment on the error section for details on what the arguments
163 // and function names indicate for all these functions.
165 [[nodiscard]] bool warning(unsigned errorNumber, ...) const {
166 va_list args;
167 va_start(args, errorNumber);
169 bool result = warningWithNotesAtVA(nullptr, mozilla::AsVariant(Current()),
170 errorNumber, &args);
172 va_end(args);
174 return result;
176 [[nodiscard]] bool warningAt(uint32_t offset, unsigned errorNumber,
177 ...) const {
178 va_list args;
179 va_start(args, errorNumber);
181 bool result = warningWithNotesAtVA(nullptr, mozilla::AsVariant(offset),
182 errorNumber, &args);
184 va_end(args);
186 return result;
188 [[nodiscard]] bool warningNoOffset(unsigned errorNumber, ...) const {
189 va_list args;
190 va_start(args, errorNumber);
192 bool result = warningWithNotesAtVA(nullptr, mozilla::AsVariant(NoOffset()),
193 errorNumber, &args);
195 va_end(args);
197 return result;
199 [[nodiscard]] bool warningWithNotesAtVA(UniquePtr<JSErrorNotes> notes,
200 const ErrorOffset& offset,
201 unsigned errorNumber,
202 va_list* args) const {
203 ErrorMetadata metadata;
204 if (!computeErrorMetadata(&metadata, offset)) {
205 return false;
208 return compileWarning(std::move(metadata), std::move(notes), errorNumber,
209 args);
212 // ==== strictModeError ====
214 // Reports an error if in strict mode code, or warn if not.
216 // Returns true if not in strict mode and a warning is reported.
217 // Returns false if the error reported, or an error occurs while reporting.
219 // See the comment on the error section for details on what the arguments
220 // and function names indicate for all these functions.
222 [[nodiscard]] bool strictModeError(unsigned errorNumber, ...) const {
223 va_list args;
224 va_start(args, errorNumber);
226 bool result = strictModeErrorWithNotesAtVA(
227 nullptr, mozilla::AsVariant(Current()), errorNumber, &args);
229 va_end(args);
231 return result;
233 [[nodiscard]] bool strictModeErrorWithNotes(UniquePtr<JSErrorNotes> notes,
234 unsigned errorNumber, ...) const {
235 va_list args;
236 va_start(args, errorNumber);
238 bool result = strictModeErrorWithNotesAtVA(
239 std::move(notes), mozilla::AsVariant(Current()), errorNumber, &args);
241 va_end(args);
243 return result;
245 [[nodiscard]] bool strictModeErrorAt(uint32_t offset, unsigned errorNumber,
246 ...) const {
247 va_list args;
248 va_start(args, errorNumber);
250 bool result = strictModeErrorWithNotesAtVA(
251 nullptr, mozilla::AsVariant(offset), errorNumber, &args);
253 va_end(args);
255 return result;
257 [[nodiscard]] bool strictModeErrorWithNotesAt(UniquePtr<JSErrorNotes> notes,
258 uint32_t offset,
259 unsigned errorNumber,
260 ...) const {
261 va_list args;
262 va_start(args, errorNumber);
264 bool result = strictModeErrorWithNotesAtVA(
265 std::move(notes), mozilla::AsVariant(offset), errorNumber, &args);
267 va_end(args);
269 return result;
271 [[nodiscard]] bool strictModeErrorNoOffset(unsigned errorNumber, ...) const {
272 va_list args;
273 va_start(args, errorNumber);
275 bool result = strictModeErrorWithNotesAtVA(
276 nullptr, mozilla::AsVariant(NoOffset()), errorNumber, &args);
278 va_end(args);
280 return result;
282 [[nodiscard]] bool strictModeErrorWithNotesNoOffset(
283 UniquePtr<JSErrorNotes> notes, unsigned errorNumber, ...) const {
284 va_list args;
285 va_start(args, errorNumber);
287 bool result = strictModeErrorWithNotesAtVA(
288 std::move(notes), mozilla::AsVariant(NoOffset()), errorNumber, &args);
290 va_end(args);
292 return result;
294 [[nodiscard]] bool strictModeErrorWithNotesAtVA(UniquePtr<JSErrorNotes> notes,
295 const ErrorOffset& offset,
296 unsigned errorNumber,
297 va_list* args) const {
298 if (!strictMode()) {
299 return true;
302 ErrorMetadata metadata;
303 if (!computeErrorMetadata(&metadata, offset)) {
304 return false;
307 ReportCompileErrorLatin1VA(getContext(), std::move(metadata),
308 std::move(notes), errorNumber, args);
309 return false;
312 // Reports a warning, or an error if the warning is treated as an error.
313 [[nodiscard]] bool compileWarning(ErrorMetadata&& metadata,
314 UniquePtr<JSErrorNotes> notes,
315 unsigned errorNumber, va_list* args) const {
316 return ReportCompileWarning(getContext(), std::move(metadata),
317 std::move(notes), errorNumber, args);
321 // An interface class to provide miscellaneous methods used by error reporting
322 // etc. They're mostly used by BytecodeCompiler, BytecodeEmitter, and helper
323 // classes for emitter.
324 class ErrorReporter : public ErrorReportMixin {
325 public:
326 // Returns Some(true) if the given offset is inside the given line
327 // number `lineNum`, or Some(false) otherwise.
329 // Return None if an error happens. This method itself doesn't report an
330 // error, and any failure is supposed to be reported as OOM in the caller.
331 virtual std::optional<bool> isOnThisLine(size_t offset,
332 uint32_t lineNum) const = 0;
334 // Returns the line number for given offset.
335 virtual uint32_t lineAt(size_t offset) const = 0;
337 // Returns the column number for given offset.
338 virtual JS::LimitedColumnNumberOneOrigin columnAt(size_t offset) const = 0;
341 } // namespace frontend
342 } // namespace js
344 #endif // frontend_ErrorReporter_h