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