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"))); + 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"))); - // 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"))); 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 ErrorInfo::programName = std::nullopt; -string showErrLine(ErrLine &errLine) +ErrorInfo ErrorInfo::ProgramError(const string &name, + const string &description, + const std::optional &hf) +{ + return ProgramEI(elError, name, description, hf); +} + +ErrorInfo ErrorInfo::ProgramWarning(const string &name, + const string &description, + const std::optional &hf) +{ + return ProgramEI(elWarning, name, description, hf); +} + + + +ErrorInfo ErrorInfo::ProgramEI(ErrLevel level, + const string &name, + const string &description, + const std::optional &hf) +{ + ErrorInfo ei(elError); + ei.name = name; + ei.description = description; + if (hf.has_value()) + ei.hint = std::optional(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,153 +41,8 @@ class NixCode public: std::optional nixFile; std::optional errLine; - - ErrLine& ensureErrLine() - { - if (!this->errLine.has_value()) - this->errLine = std::optional(ErrLine()); - return *this->errLine; - } }; -// ------------------------------------------------- -// ErrorInfo. - -// Forward friend class declarations. "builder classes" -template -class AddName; - -template -class AddDescription; - -template -class AddPos; - -template -class AddLOC; - -// The error info class itself. -class ErrorInfo -{ -public: - ErrLevel level; - string name; - string description; - std::optional nixCode; - std::optional hint; - ErrorInfo& GetEI() - { - return *this; - } - - static std::optional programName; - - // give these access to the private constructor, - // when they are direct descendants (children but not grandchildren). - friend AddName; - friend AddDescription; - friend AddPos; - friend AddLOC; - - 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) {} -}; - -// Init as warning -class EIWarning : public ErrorInfo -{ -protected: - EIWarning() : ErrorInfo(elWarning) {} -}; - -// Builder class definitions. -template -class AddName : private T -{ -public: - T& name(const std::string &name) - { - GetEI().name = name; - return *this; - } -protected: - ErrorInfo& GetEI() - { - return T::GetEI(); - } -}; - -template -class AddDescription : private T -{ -public: - T& description(const std::string &description) - { - GetEI().description = description; - return *this; - } -protected: - ErrorInfo& GetEI() - { - return T::GetEI(); - } -}; - -template -class AddPos : private T -{ -public: - template - T& pos(const P &aPos) - { - GetEI().ensureNixCode().nixFile = aPos.file; - GetEI().ensureNixCode().ensureErrLine().lineNumber = aPos.line; - GetEI().ensureNixCode().ensureErrLine().columnRange = { .start = aPos.column, .len = 1 }; - return *this; - } -protected: - ErrorInfo& GetEI() - { - return T::GetEI(); - } -}; - -template -class AddLOC : private T -{ -public: - T& linesOfCode(std::optional prevloc, string loc, std::optional nextloc) - { - GetEI().ensureNixCode().ensureErrLine().prevLineOfCode = prevloc; - GetEI().ensureNixCode().ensureErrLine().errLineOfCode = loc; - GetEI().ensureNixCode().ensureErrLine().nextLineOfCode = nextloc; - return *this; - } -protected: - ErrorInfo& GetEI() - { - return T::GetEI(); - } -}; - - // ---------------------------------------------------------------- // format for hints. same as fmt, except templated values // are always in yellow. @@ -229,7 +84,6 @@ public: friend class AddHint; private: format fmt; - }; template @@ -240,6 +94,143 @@ inline hintformat hintfmt(const std::string & fs, const Args & ... args) return f; } +// ------------------------------------------------- +// ErrorInfo. +class ErrorInfo +{ +public: + ErrLevel level; + string name; + string description; + std::optional nixCode; + std::optional hint; + + static std::optional programName; + + static ErrorInfo ProgramError(const string &name, + const string &description, + const std::optional &hf); + + + static ErrorInfo ProgramWarning(const string &name, + const string &description, + const std::optional &hf); + + + template + static ErrorInfo NixLangError(const string &name, + const string &description, + const P &pos, + std::optional prevloc, + string loc, + std::optional nextloc, + const std::optional &hf) + { + return NixLangEI(elError, name, description, pos, prevloc, loc, nextloc, hf); + } + + + template + static ErrorInfo NixLangWarning(const string &name, + const string &description, + const P &pos, + std::optional prevloc, + string loc, + std::optional nextloc, + const std::optional &hf) + { + return NixLangEI(elWarning, name, description, pos, prevloc, loc, nextloc, hf); + } + + + +private: + template + static ErrorInfo NixLangEI(ErrLevel level, + const string &name, + const string &description, + const P &pos, + std::optional prevloc, + string loc, + std::optional nextloc, + const std::optional &hf) + { + ErrorInfo ei(level); + ei.name = name; + ei.description = description; + if (hf.has_value()) + ei.hint = std::optional(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; + } + + static ErrorInfo ProgramEI(ErrLevel level, + const string &name, + const string &description, + const std::optional &hf); + + + + // constructor is protected, so only the builder classes can create an ErrorInfo. + ErrorInfo(ErrLevel level) + { + this->level = level; + } +}; + +/* +template +class AddPos : private T +{ +public: + template + T& pos(const P &aPos) + { + GetEI().ensureNixCode().nixFile = aPos.file; + GetEI().ensureNixCode().ensureErrLine().lineNumber = aPos.line; + GetEI().ensureNixCode().ensureErrLine().columnRange = { .start = aPos.column, .len = 1 }; + return *this; + } +protected: + ErrorInfo& GetEI() + { + return T::GetEI(); + } +}; + +template +class AddLOC : private T +{ +public: + T& linesOfCode(std::optional prevloc, string loc, std::optional nextloc) + { + GetEI().ensureNixCode().ensureErrLine().prevLineOfCode = prevloc; + GetEI().ensureNixCode().ensureErrLine().errLineOfCode = loc; + GetEI().ensureNixCode().ensureErrLine().nextLineOfCode = nextloc; + return *this; + } +protected: + ErrorInfo& GetEI() + { + return T::GetEI(); + } +}; +*/ + +/* // the template layer for adding a hint. template 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); }