diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 9449540af..25f3e8ee8 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -23,17 +23,6 @@ class ColumnRange { class ErrorInfo; -// ------------------------------------------------- -// forward declarations before ErrLine. -template -class AddLineNumber; - -template -class AddColumnRange; - -template -class AddLOC; - class ErrLine { public: int lineNumber; @@ -42,107 +31,25 @@ class ErrLine { string errLineOfCode; optional nextLineOfCode; - friend AddLineNumber; - friend AddColumnRange; - friend AddLOC; - ErrLine& GetEL() { return *this; } - private: - ErrLine() {} }; -template -class AddLineNumber : public T -{ - public: - T& lineNumber(int lineNumber) { - GetEL().lineNumber = lineNumber; - return *this; - } - protected: - ErrLine& GetEL() { return T::GetEL(); } -}; - -template -class AddColumnRange : public T -{ - public: - T& columnRange(unsigned int start, unsigned int len) { - GetEL().columnRange = { start, len }; - return *this; - } - protected: - ErrLine& GetEL() { return T::GetEL(); } -}; - -template -class AddLOC : public T -{ - public: - T& linesOfCode(optional prevloc, string loc, optional nextloc) { - GetEL().prevLineOfCode = prevloc; - GetEL().errLineOfCode = loc; - GetEL().nextLineOfCode = nextloc; - return *this; - } - protected: - ErrLine& GetEL() { return T::GetEL(); } -}; - -typedef AddLineNumber>> MkErrLine; -MkErrLine mkErrLine; - - -// ------------------------------------------------- -// NixCode. - -template -class AddNixFile; - -template -class AddErrLine; - class NixCode { public: optional nixFile; optional errLine; - friend AddNixFile; - friend AddErrLine; - friend ErrorInfo; - NixCode& GetNC() { return *this; } - private: - NixCode() {} -}; - -template -class AddNixFile : public T -{ - public: - T& nixFile(string filename) { - GetNC().nixFile = filename; - return *this; + ErrLine& ensureErrLine() + { + if (!this->errLine.has_value()) + this->errLine = optional(ErrLine()); + return *this->errLine; } - protected: - NixCode& GetNC() { return T::GetNC(); } }; -template -class AddErrLine : public T -{ - public: - T& errLine(ErrLine errline) { - GetNC().errLine = errline; - return *this; - } - protected: - NixCode& GetNC() { return T::GetNC(); } -}; - -typedef AddNixFile> MkNixCode; - // ------------------------------------------------- // ErrorInfo. +// Forward friend class declarations. "builder classes" template class AddName; @@ -152,6 +59,22 @@ class AddDescription; template class AddNixCode; +template +class AddNixFile; + +template +class AddErrLine; + +template +class AddLineNumber; + +template +class AddColumnRange; + +template +class AddLOC; + +// The error info class itself. class ErrorInfo { public: ErrLevel level; @@ -167,9 +90,23 @@ class ErrorInfo { friend AddName; friend AddDescription; friend AddNixCode; + friend AddNixFile; + friend AddErrLine; + friend AddLineNumber; + friend AddColumnRange; + friend AddLOC; + NixCode& ensureNixCode() + { + if (!this->nixCode.has_value()) + this->nixCode = optional(NixCode()); + return *this->nixCode; + } protected: + // constructor is protected, so only the builder classes can create an ErrorInfo. ErrorInfo(ErrLevel level) { this->level = level; } + + }; class EIError : public ErrorInfo @@ -208,23 +145,73 @@ class AddDescription : private T ErrorInfo& GetEI() { return T::GetEI(); } }; -template -class AddNixCode : private T +template +class AddNixFile : public T { public: - T& nixcode(const NixCode &nixcode){ - GetEI().nixCode = nixcode; + T& nixFile(string filename) { + GetEI().ensureNixCode().nixFile = filename; + return *this; + } + protected: + ErrorInfo& GetEI() { return T::GetEI(); } +}; + +template +class AddLineNumber : public T +{ + public: + T& lineNumber(int lineNumber) { + GetEI().ensureNixCode().ensureErrLine().lineNumber = lineNumber; return *this; } protected: ErrorInfo& GetEI() { return T::GetEI(); } }; +template +class AddColumnRange : public T +{ + public: + T& columnRange(unsigned int start, unsigned int len) { + GetEI().ensureNixCode().ensureErrLine().columnRange = { start, len }; + return *this; + } + protected: + ErrorInfo& GetEI() { return T::GetEI(); } +}; + +template +class AddLOC : public T +{ + public: + T& linesOfCode(optional prevloc, string loc, 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(); } +}; + +typedef AddNixFile> MkNixCode; + typedef AddName> StandardError; typedef AddName> StandardWarning; -typedef AddName>> MkNixError; -typedef AddName>> MkNixWarning; +typedef AddName< + AddDescription< + AddNixFile< + AddLineNumber< + AddColumnRange< + AddLOC>>>>> MkNixError; +typedef AddName< + AddDescription< + AddNixFile< + AddLineNumber< + AddColumnRange< + AddLOC>>>>> MkNixWarning; string showErrLine(ErrLine &errLine); diff --git a/tests/errors/main.cc b/tests/errors/main.cc index c2c4d0060..6b024d287 100644 --- a/tests/errors/main.cc +++ b/tests/errors/main.cc @@ -34,41 +34,34 @@ using namespace nix; print_error(generic); */ - StandardError standardError; - - print_error(standardError + print_error(StandardError() .name("name") .description("description")); - StandardWarning standardWarning; - - print_error(standardWarning + print_error(StandardWarning() .name("warning name") .description("warning description")); - print_error(MkNixError() - .name("name") - .description("description") - .nixcode( - MkNixCode() - .nixFile("myfile.nix") - .errLine(MkErrLine().lineNumber(40) - .columnRange(13,7) - .linesOfCode(nullopt - ,"this is the problem line of code" - ,nullopt)))); print_error(MkNixWarning() - .name("name") - .description("description") - .nixcode( - MkNixCode() - .nixFile("myfile.nix") - .errLine(MkErrLine().lineNumber(40) - .columnRange(13,7) - .linesOfCode(nullopt - ,"this is the problem line of code" - ,nullopt)))); + .name("warning name") + .description("warning description") + .nixFile("myfile.nix") + .lineNumber(40) + .columnRange(13,7) + .linesOfCode(nullopt + ,"this is the problem line of code" + ,nullopt)); + + print_error(MkNixError() + .name("error name") + .description("warning description") + .nixFile("myfile.nix") + .lineNumber(40) + .columnRange(13,7) + .linesOfCode(nullopt + ,"this is the problem line of code" + ,nullopt)); return 0; }