diff options
-rw-r--r-- | src/error-demo/error-demo.cc | 73 | ||||
-rw-r--r-- | src/libutil/error.cc | 42 | ||||
-rw-r--r-- | src/libutil/error.hh | 251 |
3 files changed, 204 insertions, 162 deletions
diff --git a/src/error-demo/error-demo.cc b/src/error-demo/error-demo.cc index 8fb20d38c..fdb574b25 100644 --- a/src/error-demo/error-demo.cc +++ b/src/error-demo/error-demo.cc @@ -22,21 +22,25 @@ int main() // created. // ProgramError takes name, description, and an optional hint. - printErrorInfo( ProgramError() - .name("name") - .description("error description") - .nohint() - ); + printErrorInfo( + ErrorInfo::ProgramError("name", + "error description", + std::nullopt)); // ProgramWarning takes name, description, and an optional hint. // The hint is in the form of a hintfmt class, which wraps boost::format(), // and makes all the substituted text yellow. - printErrorInfo( ProgramWarning() - .name("warning name") - .description("warning description") - // the templated value, 'warning', is automatically colored yellow. - .hint(hintfmt("there was a %1%", "warning")) - ); + printErrorInfo( + ErrorInfo::ProgramWarning("name", + "warning description", + std::optional(hintfmt("there was a %1%", "warning")))); + + // printErrorInfo( ProgramWarning() + // .name("warning name") + // .description("warning description") + // // the templated value, 'warning', is automatically colored yellow. + // .hint(hintfmt("there was a %1%", "warning")) + // ); /* // some invalid errors: @@ -63,25 +67,34 @@ int main() SymbolTable testTable; auto problem_symbol = testTable.create("problem"); - printErrorInfo(NixLangWarning() - .name("warning name") - .description("warning description") - .pos(Pos(problem_symbol, 40, 13)) - .linesOfCode(std::nullopt, - "this is the problem line of code", - std::nullopt) - .hint(hintfmt("this hint has %1% templated %2%!!", "yellow" , "values"))); - - // NixLangError is just the same as NixLangWarning, except for the Error - // flag. - printErrorInfo(NixLangError() - .name("error name") - .description("error description") - .pos(Pos(problem_symbol, 40, 13)) - .linesOfCode(std::optional("previous line of code"), - "this is the problem line of code", - std::optional("next line of code")) - .hint(hintfmt("this hint has %1% templated %2%!!", "yellow", "values"))); + printErrorInfo(ErrorInfo::NixLangWarning( + "warning name", + "warning description", + Pos(problem_symbol, 40, 13), + std::nullopt, + "this is the problem line of code", + std::nullopt, + hintfmt("this hint has %1% templated %2%!!", "yellow", "values"))); + + // // NixLangError is just the same as NixLangWarning, except for the Error + // // flag. + // printErrorInfo(NixLangError() + // .name("error name") + // .description("error description") + // .pos(Pos(problem_symbol, 40, 13)) + // .linesOfCode(std::optional("previous line of code"), + // "this is the problem line of code", + // std::optional("next line of code")) + // .hint(hintfmt("this hint has %1% templated %2%!!", "yellow", "values"))); + printErrorInfo(ErrorInfo::NixLangError( + "error name", + "error description", + Pos(problem_symbol, 40, 13), + std::optional("previous line of code"), + "this is the problem line of code", + std::optional("next line of code"), + hintfmt("this hint has %1% templated %2%!!", "yellow", "values"))); + return 0; } diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 8ab4a2dea..41fabbbcf 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -8,7 +8,43 @@ namespace nix std::optional<string> ErrorInfo::programName = std::nullopt; -string showErrLine(ErrLine &errLine) +ErrorInfo ErrorInfo::ProgramError(const string &name, + const string &description, + const std::optional<hintformat> &hf) +{ + return ProgramEI(elError, name, description, hf); +} + +ErrorInfo ErrorInfo::ProgramWarning(const string &name, + const string &description, + const std::optional<hintformat> &hf) +{ + return ProgramEI(elWarning, name, description, hf); +} + + + +ErrorInfo ErrorInfo::ProgramEI(ErrLevel level, + const string &name, + const string &description, + const std::optional<hintformat> &hf) +{ + ErrorInfo ei(elError); + ei.name = name; + ei.description = description; + if (hf.has_value()) + ei.hint = std::optional<string>(hf->str()); + else + ei.hint = std::nullopt; + return ei; +} + + + + + + +string showErrLine(const ErrLine &errLine) { if (errLine.columnRange.has_value()) { return (format("(%1%:%2%)") % errLine.lineNumber % errLine.columnRange->start).str(); @@ -17,7 +53,7 @@ string showErrLine(ErrLine &errLine) }; } -void printCodeLines(string &prefix, NixCode &nixCode) +void printCodeLines(const string &prefix, const NixCode &nixCode) { if (nixCode.errLine.has_value()) { @@ -69,7 +105,7 @@ void printCodeLines(string &prefix, NixCode &nixCode) } -void printErrorInfo(ErrorInfo &einfo) +void printErrorInfo(const ErrorInfo &einfo) { int errwidth = 80; string prefix = " "; diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 57a9944be..a73b6639e 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -41,32 +41,61 @@ class NixCode public: std::optional<string> nixFile; std::optional<ErrLine> errLine; - - ErrLine& ensureErrLine() - { - if (!this->errLine.has_value()) - this->errLine = std::optional(ErrLine()); - return *this->errLine; - } }; -// ------------------------------------------------- -// ErrorInfo. +// ---------------------------------------------------------------- +// format for hints. same as fmt, except templated values +// are always in yellow. -// Forward friend class declarations. "builder classes" template <class T> -class AddName; +class yellowify +{ +public: + yellowify(T &s) : value(s) {} + T &value; +}; template <class T> -class AddDescription; +std::ostream& operator<<(std::ostream &out, const yellowify<T> &y) +{ + return out << ANSI_YELLOW << y.value << ANSI_NORMAL; +} -template <class T> -class AddPos; +class hintformat +{ +public: + hintformat(string format) :fmt(format) + { + fmt.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit); + } + template<class T> + hintformat& operator%(const T &value) + { + fmt % yellowify(value); + return *this; + } -template <class T> -class AddLOC; + std::string str() const + { + return fmt.str(); + } + + template <typename U> + friend class AddHint; +private: + format fmt; +}; + +template<typename... Args> +inline hintformat hintfmt(const std::string & fs, const Args & ... args) +{ + hintformat f(fs); + formatHelper(f, args...); + return f; +} -// The error info class itself. +// ------------------------------------------------- +// ErrorInfo. class ErrorInfo { public: @@ -75,81 +104,94 @@ public: string description; std::optional<NixCode> nixCode; std::optional<string> hint; - ErrorInfo& GetEI() - { - return *this; - } static std::optional<string> programName; - // give these access to the private constructor, - // when they are direct descendants (children but not grandchildren). - friend AddName<ErrorInfo>; - friend AddDescription<ErrorInfo>; - friend AddPos<ErrorInfo>; - friend AddLOC<ErrorInfo>; + static ErrorInfo ProgramError(const string &name, + const string &description, + const std::optional<hintformat> &hf); - NixCode& ensureNixCode() - { - if (!this->nixCode.has_value()) - this->nixCode = std::optional(NixCode()); - return *this->nixCode; - } -protected: - // constructor is protected, so only the builder classes can create an ErrorInfo. - ErrorInfo(ErrLevel level) - { - this->level = level; - } -}; -// Init as error -class EIError : public ErrorInfo -{ -protected: - EIError() : ErrorInfo(elError) {} -}; + static ErrorInfo ProgramWarning(const string &name, + const string &description, + const std::optional<hintformat> &hf); -// Init as warning -class EIWarning : public ErrorInfo -{ -protected: - EIWarning() : ErrorInfo(elWarning) {} -}; -// Builder class definitions. -template <class T> -class AddName : private T -{ -public: - T& name(const std::string &name) + template <class P> + static ErrorInfo NixLangError(const string &name, + const string &description, + const P &pos, + std::optional<string> prevloc, + string loc, + std::optional<string> nextloc, + const std::optional<hintformat> &hf) { - GetEI().name = name; - return *this; + return NixLangEI(elError, name, description, pos, prevloc, loc, nextloc, hf); } -protected: - ErrorInfo& GetEI() + + + template <class P> + static ErrorInfo NixLangWarning(const string &name, + const string &description, + const P &pos, + std::optional<string> prevloc, + string loc, + std::optional<string> nextloc, + const std::optional<hintformat> &hf) { - return T::GetEI(); + return NixLangEI(elWarning, name, description, pos, prevloc, loc, nextloc, hf); } -}; -template <class T> -class AddDescription : private T -{ -public: - T& description(const std::string &description) + + +private: + template <class P> + static ErrorInfo NixLangEI(ErrLevel level, + const string &name, + const string &description, + const P &pos, + std::optional<string> prevloc, + string loc, + std::optional<string> nextloc, + const std::optional<hintformat> &hf) { - GetEI().description = description; - return *this; + ErrorInfo ei(level); + ei.name = name; + ei.description = description; + if (hf.has_value()) + ei.hint = std::optional<string>(hf->str()); + else + ei.hint = std::nullopt; + + ErrLine errline; + errline.lineNumber = pos.line; + errline.columnRange = { .start = pos.column, .len = 1 }; + errline.prevLineOfCode = prevloc; + errline.errLineOfCode = loc; + errline.nextLineOfCode = nextloc; + NixCode nixcode; + nixcode.nixFile = pos.file; + nixcode.errLine = std::optional(errline); + ei.nixCode = std::optional(nixcode); + + return ei; } -protected: - ErrorInfo& GetEI() + + static ErrorInfo ProgramEI(ErrLevel level, + const string &name, + const string &description, + const std::optional<hintformat> &hf); + + + + // constructor is protected, so only the builder classes can create an ErrorInfo. + ErrorInfo(ErrLevel level) { - return T::GetEI(); + this->level = level; } }; +/* template <class T> class AddPos : private T { @@ -186,60 +228,9 @@ protected: return T::GetEI(); } }; +*/ - -// ---------------------------------------------------------------- -// format for hints. same as fmt, except templated values -// are always in yellow. - -template <class T> -class yellowify -{ -public: - yellowify(T &s) : value(s) {} - T &value; -}; - -template <class T> -std::ostream& operator<<(std::ostream &out, const yellowify<T> &y) -{ - return out << ANSI_YELLOW << y.value << ANSI_NORMAL; -} - -class hintformat -{ -public: - hintformat(string format) :fmt(format) - { - fmt.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit); - } - template<class T> - hintformat& operator%(const T &value) - { - fmt % yellowify(value); - return *this; - } - - std::string str() const - { - return fmt.str(); - } - - template <typename U> - friend class AddHint; -private: - format fmt; - -}; - -template<typename... Args> -inline hintformat hintfmt(const std::string & fs, const Args & ... args) -{ - hintformat f(fs); - formatHelper(f, args...); - return f; -} - +/* // the template layer for adding a hint. template <class T> class AddHint : private T @@ -261,11 +252,12 @@ protected: return T::GetEI(); } }; +*/ // -------------------------------------------------------- // error types -typedef AddName< +/*typedef AddName< AddDescription< AddHint< EIError>>> ProgramError; @@ -290,11 +282,12 @@ typedef AddName< EIWarning>>>>> NixLangWarning; +*/ // -------------------------------------------------------- // error printing // just to cout for now. -void printErrorInfo(ErrorInfo &einfo); +void printErrorInfo(const ErrorInfo &einfo); } |