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 18namespace SkSL { 19 20#ifndef __has_builtin 21 #define __has_builtin(x) 0 22#endif 23 24class PositionInfo { 25public: 26 PositionInfo(const char* file = nullptr, int line = -1) 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 35 static PositionInfo Capture() { return PositionInfo(); } 36#endif // __has_builtin(__builtin_FILE) && __has_builtin(__builtin_LINE) 37 38 const char* file_name() const { 39 return fFile; 40 } 41 42 int line() { 43 return fLine; 44 } 45 46private: 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 */ 54class ErrorReporter { 55public: 56 ErrorReporter() {} 57 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 70 const char* source() const { return fSource; } 71 72 void setSource(const char* source) { fSource = source; } 73 74 void reportPendingErrors(PositionInfo pos) { 75 for (const String& msg : fPendingErrors) { 76 this->handleError(msg, pos); 77 } 78 fPendingErrors.clear(); 79 } 80 81 int errorCount() const { 82 return fErrorCount; 83 } 84 85 void resetErrorCount() { 86 fErrorCount = 0; 87 } 88 89protected: 90 /** 91 * Called when an error is reported. 92 */ 93 virtual void handleError(skstd::string_view msg, PositionInfo position) = 0; 94 95private: 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 */ 106class TestingOnly_AbortErrorReporter : public ErrorReporter { 107public: 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