#ifndef PORYGONLANG_DIAGNOSTICSHOLDER_HPP #define PORYGONLANG_DIAGNOSTICSHOLDER_HPP #include #include #include #include "DiagnosticSeverity.hpp" #include "DiagnosticCode.hpp" #include "Diagnostic.hpp" using namespace std; namespace Porygon::Diagnostics { class DiagnosticsHolder { byte _hasErrors; vector _diagnostics; vector _lineStarts; vector _lineLength; public: explicit DiagnosticsHolder(const u16string& str) : _hasErrors(static_cast(0)), _lineStarts(vector{0}) { size_t lineLength = 0; for (size_t i = 0; i < str.size(); i++){ lineLength++; if (str[i] == '\n'){ _lineStarts.push_back(i + 1); _lineLength.push_back(lineLength); lineLength = 0; } } } ~DiagnosticsHolder() { _diagnostics.clear(); } void Log(DiagnosticSeverity severity, DiagnosticCode code, unsigned int start, unsigned int length, const std::vector& arguments = {}); void LogError(DiagnosticCode code, unsigned int start, unsigned int length, const std::vector& arguments = {}); void LogWarning(DiagnosticCode code, unsigned int start, unsigned int length, const std::vector& arguments = {}); void LogInfo(DiagnosticCode code, unsigned int start, unsigned int length, const std::vector& arguments = {}); bool HasErrors(); vector GetDiagnostics(); inline int DiagnosticsCount(); Diagnostic *GetDiagnosticAt(int position); size_t GetLineFromPosition(size_t i); [[nodiscard]] inline size_t GetStartPositionForLine(size_t i){ return _lineStarts[i]; } std::string* GetFullDiagnostic(Diagnostic* diagnostic); }; } #endif //PORYGONLANG_DIAGNOSTICSHOLDER_HPP