camelcase; optional hint

This commit is contained in:
Ben Burdette 2020-03-27 10:03:02 -06:00
parent d44c9c5581
commit a3ef00be6c
3 changed files with 119 additions and 57 deletions

View file

@ -24,55 +24,55 @@ string showErrLine(ErrLine &errLine)
}; };
} }
void print_code_lines(string &prefix, NixCode &nix_code) void printCodeLines(string &prefix, NixCode &nixCode)
{ {
if (nix_code.errLine.has_value()) if (nixCode.errLine.has_value())
{ {
// previous line of code. // previous line of code.
if (nix_code.errLine->prevLineOfCode.has_value()) { if (nixCode.errLine->prevLineOfCode.has_value()) {
cout << format("%1% %|2$5d|| %3%") cout << format("%1% %|2$5d|| %3%")
% prefix % prefix
% (nix_code.errLine->lineNumber - 1) % (nixCode.errLine->lineNumber - 1)
% *nix_code.errLine->prevLineOfCode % *nixCode.errLine->prevLineOfCode
<< endl; << endl;
} }
// line of code containing the error.%2$+5d% // line of code containing the error.%2$+5d%
cout << format("%1% %|2$5d|| %3%") cout << format("%1% %|2$5d|| %3%")
% prefix % prefix
% (nix_code.errLine->lineNumber) % (nixCode.errLine->lineNumber)
% nix_code.errLine->errLineOfCode % nixCode.errLine->errLineOfCode
<< endl; << endl;
// error arrows for the column range. // error arrows for the column range.
if (nix_code.errLine->columnRange.has_value()) if (nixCode.errLine->columnRange.has_value())
{ {
int start = nix_code.errLine->columnRange->start; int start = nixCode.errLine->columnRange->start;
std::string spaces; std::string spaces;
for (int i = 0; i < start; ++i) for (int i = 0; i < start; ++i)
{ {
spaces.append(" "); spaces.append(" ");
} }
int len = nix_code.errLine->columnRange->len; int len = nixCode.errLine->columnRange->len;
std::string arrows; std::string arrows;
for (int i = 0; i < len; ++i) for (int i = 0; i < len; ++i)
{ {
arrows.append("^"); arrows.append("^");
} }
cout << format("%1% |%2%" ANSI_RED "%3%" ANSI_NORMAL) % prefix % spaces % arrows; cout << format("%1% |%2%" ANSI_RED "%3%" ANSI_NORMAL) % prefix % spaces % arrows << endl;
} }
// next line of code. // next line of code.
if (nix_code.errLine->nextLineOfCode.has_value()) { if (nixCode.errLine->nextLineOfCode.has_value()) {
cout << format("%1% %|2$5d|| %3%") cout << format("%1% %|2$5d|| %3%")
% prefix % prefix
% (nix_code.errLine->lineNumber + 1) % (nixCode.errLine->lineNumber + 1)
% *nix_code.errLine->nextLineOfCode % *nixCode.errLine->nextLineOfCode
<< endl; << endl;
} }
@ -80,36 +80,36 @@ void print_code_lines(string &prefix, NixCode &nix_code)
} }
void print_error(ErrorInfo &einfo) void printErrorInfo(ErrorInfo &einfo)
{ {
int errwidth = 80; int errwidth = 80;
string prefix = " "; string prefix = " ";
string level_string; string levelString;
switch (einfo.level) switch (einfo.level)
{ {
case ErrLevel::elError: case ErrLevel::elError:
{ {
level_string = ANSI_RED; levelString = ANSI_RED;
level_string += "error:"; levelString += "error:";
level_string += ANSI_NORMAL; levelString += ANSI_NORMAL;
break; break;
} }
case ErrLevel::elWarning: case ErrLevel::elWarning:
{ {
level_string = ANSI_YELLOW; levelString = ANSI_YELLOW;
level_string += "warning:"; levelString += "warning:";
level_string += ANSI_NORMAL; levelString += ANSI_NORMAL;
break; break;
} }
default: default:
{ {
level_string = "wat:"; levelString = "wat:";
break; break;
} }
} }
int ndl = prefix.length() + level_string.length() + 3 + einfo.name.length() + einfo.programName.value_or("").length(); int ndl = prefix.length() + levelString.length() + 3 + einfo.name.length() + einfo.programName.value_or("").length();
int dashwidth = ndl > (errwidth - 3) ? 3 : 80 - ndl; int dashwidth = ndl > (errwidth - 3) ? 3 : 80 - ndl;
string dashes; string dashes;
@ -119,7 +119,7 @@ void print_error(ErrorInfo &einfo)
// divider. // divider.
cout << format("%1%%2%" ANSI_BLUE " %3% %4% %5% %6%" ANSI_NORMAL) cout << format("%1%%2%" ANSI_BLUE " %3% %4% %5% %6%" ANSI_NORMAL)
% prefix % prefix
% level_string % levelString
% "---" % "---"
% einfo.name % einfo.name
% dashes % dashes
@ -152,11 +152,15 @@ void print_error(ErrorInfo &einfo)
// lines of code. // lines of code.
if (einfo.nixCode.has_value()) if (einfo.nixCode.has_value())
print_code_lines(prefix, *einfo.nixCode); printCodeLines(prefix, *einfo.nixCode);
// hint // hint
cout << prefix << einfo.hint << endl; if (einfo.hint.has_value())
cout << prefix << endl; {
cout << prefix << endl;
cout << prefix << *einfo.hint << endl;
cout << prefix << endl;
}
} }

View file

@ -1,12 +1,16 @@
#pragma once #pragma once
#include "types.hh" #include "util.hh"
#include <string> #include <string>
#include <optional> #include <optional>
#include <iostream> #include <iostream>
#include <iomanip>
using std::string; using std::string;
using std::optional; using std::optional;
using boost::format;
using std::cout;
using std::endl;
namespace nix { namespace nix {
@ -81,13 +85,13 @@ class ErrorInfo {
string name; string name;
string description; string description;
optional<NixCode> nixCode; optional<NixCode> nixCode;
string hint; optional<string> hint;
ErrorInfo& GetEI() { return *this; } ErrorInfo& GetEI() { return *this; }
static optional<string> programName; static optional<string> programName;
// give these access to the private constructor, // give these access to the private constructor,
// when they are direct descendants. // when they are direct descendants (children but not grandchildren).
friend AddName<ErrorInfo>; friend AddName<ErrorInfo>;
friend AddDescription<ErrorInfo>; friend AddDescription<ErrorInfo>;
friend AddNixCode<ErrorInfo>; friend AddNixCode<ErrorInfo>;
@ -150,7 +154,7 @@ class AddDescription : private T
}; };
template <class T> template <class T>
class AddNixFile : public T class AddNixFile : private T
{ {
public: public:
T& nixFile(string filename) { T& nixFile(string filename) {
@ -162,7 +166,7 @@ class AddNixFile : public T
}; };
template <class T> template <class T>
class AddLineNumber : public T class AddLineNumber : private T
{ {
public: public:
T& lineNumber(int lineNumber) { T& lineNumber(int lineNumber) {
@ -174,7 +178,7 @@ class AddLineNumber : public T
}; };
template <class T> template <class T>
class AddColumnRange : public T class AddColumnRange : private T
{ {
public: public:
T& columnRange(unsigned int start, unsigned int len) { T& columnRange(unsigned int start, unsigned int len) {
@ -186,7 +190,7 @@ class AddColumnRange : public T
}; };
template <class T> template <class T>
class AddLOC : public T class AddLOC : private T
{ {
public: public:
T& linesOfCode(optional<string> prevloc, string loc, optional<string> nextloc) { T& linesOfCode(optional<string> prevloc, string loc, optional<string> nextloc) {
@ -199,17 +203,64 @@ class AddLOC : public T
ErrorInfo& GetEI() { return T::GetEI(); } ErrorInfo& GetEI() { return T::GetEI(); }
}; };
typedef AddNixFile<AddErrLine<NixCode>> MkNixCode; template <class T>
class yellowify
{
public:
yellowify(T &s) : value(s) {}
T &value;
};
typedef AddName<AddDescription<EIError>> StandardError; template <class T>
typedef AddName<AddDescription<EIWarning>> StandardWarning; std::ostream& operator<<(std::ostream &out, const yellowify<T> &y)
{
return out << ANSI_YELLOW << y.value << ANSI_NORMAL;
}
// hint format shows templated values in yellow.
class hintfmt
{
public:
hintfmt(string format) :fmt(format) {}
template<class T>
hintfmt& operator%(const T &value) { fmt % yellowify(value); return *this; }
template <typename U>
friend class AddHint;
private:
format fmt;
};
template <class T>
class AddHint : private T
{
public:
T& hint(hintfmt &hfmt) {
GetEI().hint = optional(hfmt.fmt.str());
return *this;
}
T& nohint() {
GetEI().hint = std::nullopt;
return *this;
}
protected:
ErrorInfo& GetEI() { return T::GetEI(); }
};
// --------------------------------------------------------
// error types
typedef AddName<AddDescription<AddHint<EIError>>> StandardError;
typedef AddName<AddDescription<AddHint<EIWarning>>> StandardWarning;
typedef AddName< typedef AddName<
AddDescription< AddDescription<
AddNixFile< AddNixFile<
AddLineNumber< AddLineNumber<
AddColumnRange< AddColumnRange<
AddLOC<EIError>>>>>> MkNixError; AddLOC<
AddHint<EIError>>>>>>> MkNixError;
typedef AddName< typedef AddName<
AddDescription< AddDescription<
AddNixFile< AddNixFile<
@ -217,10 +268,15 @@ typedef AddName<
AddColumnRange< AddColumnRange<
AddLOC<EIWarning>>>>>> MkNixWarning; AddLOC<EIWarning>>>>>> MkNixWarning;
// --------------------------------------------------------
// error printing
void printErrorInfo(ErrorInfo &einfo);
string showErrLine(ErrLine &errLine); string showErrLine(ErrLine &errLine);
void print_code_lines(string &prefix, NixCode &nix_code); void printCodeLines(string &prefix, NixCode &nixCode);
void print_error(ErrorInfo &einfo);
} }

View file

@ -8,9 +8,9 @@ using std::nullopt;
using std::cout; using std::cout;
using std::endl; using std::endl;
int main() { int main()
{
using namespace nix; using namespace nix;
ErrorInfo::programName = optional("errorTest"); ErrorInfo::programName = optional("errorTest");
@ -35,19 +35,23 @@ using namespace nix;
generic.program = "nixtool.exe"; generic.program = "nixtool.exe";
generic.nixCode = nixcode; generic.nixCode = nixcode;
print_error(generic); printErrorInfo(generic);
*/ */
print_error(StandardError() printErrorInfo(StandardError()
.name("name") .name("name")
.description("description")); .description("description")
.nohint()
);
print_error(StandardWarning() printErrorInfo(StandardWarning()
.name("warning name") .name("warning name")
.description("warning description")); .description("warning description")
.nohint()
);
print_error(MkNixWarning() printErrorInfo(MkNixWarning()
.name("warning name") .name("warning name")
.description("warning description") .description("warning description")
.nixFile("myfile.nix") .nixFile("myfile.nix")
@ -57,19 +61,17 @@ using namespace nix;
,"this is the problem line of code" ,"this is the problem line of code"
,nullopt)); ,nullopt));
print_error(MkNixError() printErrorInfo(MkNixError()
.name("error name") .name("error name")
.description("error description") .description("error description")
.nixFile("myfile.nix") .nixFile("myfile.nix")
.lineNumber(40) .lineNumber(40)
.columnRange(13,7) .columnRange(13,7)
.linesOfCode(nullopt .linesOfCode(optional("previous line of code")
,"this is the problem line of code" ,"this is the problem line of code"
,nullopt)); ,optional("next line of code"))
.hint(hintfmt("this hint has %1% templated %2%!!") % "yellow" % "values")
);
return 0; return 0;
} }