-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdiag.cpp
More file actions
151 lines (125 loc) · 4.49 KB
/
Copy pathdiag.cpp
File metadata and controls
151 lines (125 loc) · 4.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include "diag.hpp"
#include <cstdlib>
#include <ostream>
#include <string_view>
namespace rs {
namespace {
constexpr std::string_view KIRMIZI = "\033[1;31m";
constexpr std::string_view SARI = "\033[1;33m";
constexpr std::string_view MAVI = "\033[1;34m";
constexpr std::string_view CAMGOBEGI = "\033[1;36m";
constexpr std::string_view KALIN = "\033[1m";
constexpr std::string_view SIFIRLA = "\033[0m";
bool renkAcikMi() {
// NO_COLOR sözleşmesi: değişken TANIMLIYSA renk kapalı.
return std::getenv("NO_COLOR") == nullptr;
}
std::string_view etiket(Severity s) {
switch (s) {
case Severity::Error: return "hata";
case Severity::Warning: return "uyarı";
case Severity::Note: return "not";
}
return "hata";
}
std::string_view etiketRengi(Severity s) {
switch (s) {
case Severity::Error: return KIRMIZI;
case Severity::Warning: return SARI;
case Severity::Note: return CAMGOBEGI;
}
return KIRMIZI;
}
// UTF-8 farkındalıklı sütun -> ekran boşluğu. Sekmeleri sekme olarak korur ki
// ok işareti kaynaktaki gerçek hizayla örtüşsün.
std::string bosluklar(std::string_view satir, std::uint32_t sutun) {
std::string out;
std::uint32_t sayac = 1;
for (std::size_t i = 0; i < satir.size() && sayac < sutun; ++i) {
const auto b = static_cast<unsigned char>(satir[i]);
if ((b & 0xC0) == 0x80) {
continue; // UTF-8 devam baytı, sütun saymaz
}
out += (satir[i] == '\t') ? '\t' : ' ';
++sayac;
}
return out;
}
} // namespace
void Diagnostics::add(Severity sev, Span span, std::string mesaj, std::string ipucu) {
items_.push_back(Diagnostic{sev, span, std::move(mesaj), std::move(ipucu)});
if (sev == Severity::Error) {
++errorCount_;
} else if (sev == Severity::Warning) {
++warningCount_;
}
}
void Diagnostics::error(Span span, std::string mesaj, std::string ipucu) {
add(Severity::Error, span, std::move(mesaj), std::move(ipucu));
}
void Diagnostics::warning(Span span, std::string mesaj, std::string ipucu) {
add(Severity::Warning, span, std::move(mesaj), std::move(ipucu));
}
void Diagnostics::note(Span span, std::string mesaj, std::string ipucu) {
add(Severity::Note, span, std::move(mesaj), std::move(ipucu));
}
void Diagnostics::clear() noexcept {
items_.clear();
errorCount_ = 0;
warningCount_ = 0;
}
void Diagnostics::printOne(std::ostream& os, const Diagnostic& d, bool renk) const {
const auto lc = src_->lineCol(d.span.offset);
const std::string_view satir = src_->lineText(lc.line);
const std::string satirNo = std::to_string(lc.line);
const std::string oluk(satirNo.size(), ' '); // " |" hizası
const auto R = [&](std::string_view kod) { return renk ? kod : std::string_view{}; };
// hata: mesaj
os << R(etiketRengi(d.severity)) << etiket(d.severity) << R(SIFIRLA)
<< R(KALIN) << ": " << d.message << R(SIFIRLA) << '\n';
// --> dosya:satir:sutun
os << oluk << R(MAVI) << "--> " << R(SIFIRLA)
<< src_->name() << ':' << lc.line << ':' << lc.col << '\n';
// |
os << oluk << R(MAVI) << " |" << R(SIFIRLA) << '\n';
// 3 | x = $5
os << R(MAVI) << satirNo << " | " << R(SIFIRLA) << satir << '\n';
// | ^^^
const std::uint32_t isaretUzunluk = d.span.length > 0 ? d.span.length : 1;
os << oluk << R(MAVI) << " | " << R(SIFIRLA) << bosluklar(satir, lc.col)
<< R(etiketRengi(d.severity));
for (std::uint32_t i = 0; i < isaretUzunluk; ++i) {
os << '^';
}
os << R(SIFIRLA) << '\n';
if (!d.hint.empty()) {
os << oluk << R(MAVI) << " |" << R(SIFIRLA) << '\n';
os << oluk << R(MAVI) << " = " << R(SIFIRLA)
<< R(CAMGOBEGI) << "ipucu" << R(SIFIRLA) << ": " << d.hint << '\n';
}
os << '\n';
}
void Diagnostics::print(std::ostream& os) const {
const bool renk = renkAcikMi();
for (const auto& d : items_) {
printOne(os, d, renk);
}
}
void Diagnostics::printSummary(std::ostream& os) const {
if (items_.empty()) {
return;
}
const bool renk = renkAcikMi();
const auto R = [&](std::string_view kod) { return renk ? kod : std::string_view{}; };
if (errorCount_ > 0) {
os << R(KIRMIZI) << errorCount_ << " hata" << R(SIFIRLA);
}
if (warningCount_ > 0) {
if (errorCount_ > 0) {
os << ", ";
}
os << R(SARI) << warningCount_ << " uyarı" << R(SIFIRLA);
}
os << '\n';
}
} // namespace rs