• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 Google LLC.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SKSL_ERROR_REPORTER
9 #define SKSL_ERROR_REPORTER
10 
11 #include "include/core/SkStringView.h"
12 #include "include/core/SkTypes.h"
13 #include "include/private/SkSLString.h"
14 
15 #include <string>
16 #include <vector>
17 
18 namespace SkSL {
19 
20 #ifndef __has_builtin
21     #define __has_builtin(x) 0
22 #endif
23 
24 class PositionInfo {
25 public:
26     PositionInfo(const char* file = nullptr, int line = -1)
fFile(file)27         : fFile(file)
28         , fLine(line) {}
29 
30 #if __has_builtin(__builtin_FILE) && __has_builtin(__builtin_LINE)
31     static PositionInfo Capture(const char* file = __builtin_FILE(), int line = __builtin_LINE()) {
32         return PositionInfo(file, line);
33     }
34 #else
Capture()35     static PositionInfo Capture() { return PositionInfo(); }
36 #endif // __has_builtin(__builtin_FILE) && __has_builtin(__builtin_LINE)
37 
file_name()38     const char* file_name() const {
39         return fFile;
40     }
41 
line()42     int line() {
43         return fLine;
44     }
45 
46 private:
47     const char* fFile = nullptr;
48     int32_t fLine = -1;
49 };
50 
51 /**
52  * Class which is notified in the event of an error.
53  */
54 class ErrorReporter {
55 public:
ErrorReporter()56     ErrorReporter() {}
57 
~ErrorReporter()58     virtual ~ErrorReporter() {
59         SkASSERT(fPendingErrors.empty());
60     }
61 
62     void error(skstd::string_view msg, PositionInfo position);
63 
64     /**
65      * Reports an error message at the given line of the source text. Errors reported
66      * with a line of -1 will be queued until line number information can be determined.
67      */
68     void error(int line, skstd::string_view msg);
69 
source()70     const char* source() const { return fSource; }
71 
setSource(const char * source)72     void setSource(const char* source) { fSource = source; }
73 
reportPendingErrors(PositionInfo pos)74     void reportPendingErrors(PositionInfo pos) {
75         for (const String& msg : fPendingErrors) {
76             this->handleError(msg, pos);
77         }
78         fPendingErrors.clear();
79     }
80 
errorCount()81     int errorCount() const {
82         return fErrorCount;
83     }
84 
resetErrorCount()85     void resetErrorCount() {
86         fErrorCount = 0;
87     }
88 
89 protected:
90     /**
91      * Called when an error is reported.
92      */
93     virtual void handleError(skstd::string_view msg, PositionInfo position) = 0;
94 
95 private:
96     PositionInfo position(int offset) const;
97 
98     const char* fSource = nullptr;
99     std::vector<String> fPendingErrors;
100     int fErrorCount = 0;
101 };
102 
103 /**
104  * Error reporter for tests that need an SkSL context; aborts immediately if an error is reported.
105  */
106 class TestingOnly_AbortErrorReporter : public ErrorReporter {
107 public:
handleError(skstd::string_view msg,PositionInfo pos)108     void handleError(skstd::string_view msg, PositionInfo pos) override {
109         SK_ABORT("%.*s", (int)msg.length(), msg.data());
110     }
111 };
112 
113 } // namespace SkSL
114 
115 #endif
116