237 lines
4.7 KiB
C++
237 lines
4.7 KiB
C++
|
|
#pragma once
|
|
|
|
#include <utility>
|
|
#include <vector>
|
|
#include <iostream>
|
|
|
|
#include "bolt/ByteString.hpp"
|
|
#include "bolt/CST.hpp"
|
|
#include "bolt/Type.hpp"
|
|
|
|
namespace bolt {
|
|
|
|
class Diagnostic;
|
|
class TypeclassSignature;
|
|
class Type;
|
|
class Node;
|
|
|
|
class DiagnosticEngine {
|
|
|
|
bool HasError = false;
|
|
|
|
public:
|
|
|
|
inline bool hasError() const noexcept {
|
|
return HasError;
|
|
}
|
|
|
|
virtual void addDiagnostic(Diagnostic* Diagnostic) = 0;
|
|
|
|
template<typename D, typename ...Ts>
|
|
void add(Ts&&... Args) {
|
|
HasError = true;
|
|
addDiagnostic(new D { std::forward<Ts>(Args)... });
|
|
}
|
|
|
|
virtual ~DiagnosticEngine() {}
|
|
|
|
};
|
|
|
|
/**
|
|
* Keeps diagnostics alive in-memory until a seperate procedure processes them.
|
|
*/
|
|
class DiagnosticStore : public DiagnosticEngine {
|
|
public:
|
|
|
|
std::vector<Diagnostic*> Diagnostics;
|
|
|
|
void addDiagnostic(Diagnostic* Diagnostic) {
|
|
Diagnostics.push_back(Diagnostic);
|
|
}
|
|
|
|
void clear() {
|
|
Diagnostics.clear();
|
|
}
|
|
|
|
~DiagnosticStore();
|
|
|
|
};
|
|
|
|
enum class Color {
|
|
None,
|
|
Black,
|
|
White,
|
|
Red,
|
|
Yellow,
|
|
Green,
|
|
Blue,
|
|
Cyan,
|
|
Magenta,
|
|
};
|
|
|
|
enum StyleFlags : unsigned {
|
|
StyleFlags_None = 0,
|
|
StyleFlags_Bold = 1 << 0,
|
|
StyleFlags_Underline = 1 << 1,
|
|
StyleFlags_Italic = 1 << 2,
|
|
};
|
|
|
|
class Style {
|
|
|
|
unsigned Flags = StyleFlags_None;
|
|
|
|
Color FgColor = Color::None;
|
|
Color BgColor = Color::None;
|
|
|
|
public:
|
|
|
|
Color getForegroundColor() const noexcept {
|
|
return FgColor;
|
|
}
|
|
|
|
Color getBackgroundColor() const noexcept {
|
|
return BgColor;
|
|
}
|
|
|
|
void setForegroundColor(Color NewColor) noexcept {
|
|
FgColor = NewColor;
|
|
}
|
|
|
|
void setBackgroundColor(Color NewColor) noexcept {
|
|
BgColor = NewColor;
|
|
}
|
|
|
|
bool hasForegroundColor() const noexcept {
|
|
return FgColor != Color::None;
|
|
}
|
|
|
|
bool hasBackgroundColor() const noexcept {
|
|
return BgColor != Color::None;
|
|
}
|
|
|
|
void clearForegroundColor() noexcept {
|
|
FgColor = Color::None;
|
|
}
|
|
|
|
void clearBackgroundColor() noexcept {
|
|
BgColor = Color::None;
|
|
}
|
|
|
|
bool isUnderline() const noexcept {
|
|
return Flags & StyleFlags_Underline;
|
|
}
|
|
|
|
bool isItalic() const noexcept {
|
|
return Flags & StyleFlags_Italic;
|
|
}
|
|
|
|
bool isBold() const noexcept {
|
|
return Flags & StyleFlags_Bold;
|
|
}
|
|
|
|
void setUnderline(bool Enable) noexcept {
|
|
if (Enable) {
|
|
Flags |= StyleFlags_Underline;
|
|
} else {
|
|
Flags &= ~StyleFlags_Underline;
|
|
}
|
|
}
|
|
|
|
void setItalic(bool Enable) noexcept {
|
|
if (Enable) {
|
|
Flags |= StyleFlags_Italic;
|
|
} else {
|
|
Flags &= ~StyleFlags_Italic;
|
|
}
|
|
}
|
|
|
|
void setBold(bool Enable) noexcept {
|
|
if (Enable) {
|
|
Flags |= StyleFlags_Bold;
|
|
} else {
|
|
Flags &= ~StyleFlags_Bold;
|
|
}
|
|
}
|
|
|
|
void reset() noexcept {
|
|
FgColor = Color::None;
|
|
BgColor = Color::None;
|
|
Flags = 0;
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Prints any diagnostic message that was added to it to the console.
|
|
*/
|
|
class ConsoleDiagnostics : public DiagnosticEngine {
|
|
|
|
std::ostream& Out;
|
|
|
|
Style ActiveStyle;
|
|
|
|
void setForegroundColor(Color C);
|
|
void setBackgroundColor(Color C);
|
|
void applyStyles();
|
|
|
|
void setBold(bool Enable);
|
|
void setItalic(bool Enable);
|
|
void setUnderline(bool Enable);
|
|
void resetStyles();
|
|
|
|
void writeGutter(
|
|
std::size_t GutterWidth,
|
|
std::string Text
|
|
);
|
|
|
|
void writeHighlight(
|
|
std::size_t GutterWidth,
|
|
TextRange Range,
|
|
Color HighlightColor,
|
|
std::size_t Line,
|
|
std::size_t LineLength
|
|
);
|
|
|
|
void writeExcerpt(
|
|
const TextFile& File,
|
|
TextRange ToPrint,
|
|
TextRange ToHighlight,
|
|
Color HighlightColor
|
|
);
|
|
|
|
void writeNode(const Node* N);
|
|
|
|
void writePrefix(const Diagnostic& D);
|
|
void writeBinding(const ByteString& Name);
|
|
void writeType(std::size_t I);
|
|
void writeType(const Type* Ty, const TypePath& Underline);
|
|
void writeType(const Type* Ty);
|
|
void writeLoc(const TextFile& File, const TextLoc& Loc);
|
|
void writeTypeclassName(const ByteString& Name);
|
|
void writeTypeclassSignature(const TypeclassSignature& Sig);
|
|
|
|
void write(const std::string_view& S);
|
|
void write(std::size_t N);
|
|
|
|
public:
|
|
|
|
unsigned ExcerptLinesPre = 2;
|
|
unsigned ExcerptLinesPost = 2;
|
|
std::size_t MaxTypeSubsitutionCount = 0;
|
|
bool PrintFilePosition = true;
|
|
bool PrintExcerpts = true;
|
|
bool EnableColors = true;
|
|
|
|
ConsoleDiagnostics(std::ostream& Out = std::cerr);
|
|
|
|
/**
|
|
* Assumes the diagnostic is to be owned by this ConsoleDiagnostics.
|
|
*/
|
|
void addDiagnostic(Diagnostic* Diagnostic);
|
|
|
|
void printDiagnostic(const Diagnostic& D);
|
|
|
|
};
|
|
|
|
}
|