Skip to content

Commit e9242fa

Browse files
jdmbrson
authored andcommitted
---
yaml --- r: 3823 b: refs/heads/master c: fd24fd5 h: refs/heads/master i: 3821: 98d5e6c 3819: 4de6681 3815: 950f02b 3807: 0ba1e8d v: v3
1 parent d58c8d6 commit e9242fa

File tree

3 files changed

+51
-2
lines changed

3 files changed

+51
-2
lines changed

[refs]

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: b62fcdcc36a451a23a0b4639f78e4434949190ba
2+
refs/heads/master: fd24fd5e318c5bfbe0cba49f0b49edd3c112f451

trunk/src/comp/driver/session.rs

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import std::option;
1010
import std::option::some;
1111
import std::option::none;
1212
import std::str;
13+
import std::vec;
1314

1415
tag os { os_win32; os_macos; os_linux; }
1516

trunk/src/comp/syntax/codemap.rs

+49-1
Original file line numberDiff line numberDiff line change
@@ -78,17 +78,65 @@ fn emit_diagnostic(&option::t[span] sp, &str msg, &str kind, u8 color,
7878
io::stdout().write_str(#fmt(" %s\n", msg));
7979
alt (maybe_lines) {
8080
case (some(?lines)) {
81+
// FIXME: reading in the entire file is the worst possible way to
82+
// get access to the necessary lines.
8183
auto rdr = io::file_reader(lines.name);
8284
auto file = str::unsafe_from_bytes(rdr.read_whole_stream());
8385
auto fm = codemap::get_filemap(cm, lines.name);
84-
for (uint line in lines.lines) {
86+
87+
// arbitrarily only print up to six lines of the error
88+
auto max_lines = 6u;
89+
auto elided = false;
90+
auto display_lines = lines.lines;
91+
if (vec::len(display_lines) > max_lines) {
92+
display_lines = vec::slice(display_lines, 0u, max_lines);
93+
elided = true;
94+
}
95+
// Print the offending lines
96+
for (uint line in display_lines) {
8597
io::stdout().write_str(#fmt("%s:%u ", fm.name, line + 1u));
8698
auto s = codemap::get_line(fm, line as int, file);
8799
if (!str::ends_with(s, "\n")) {
88100
s += "\n";
89101
}
90102
io::stdout().write_str(s);
91103
}
104+
if (elided) {
105+
auto last_line = display_lines.(vec::len(display_lines) - 1u);
106+
auto s = #fmt("%s:%u ", fm.name, last_line + 1u);
107+
auto indent = str::char_len(s);
108+
auto out = "";
109+
while (indent > 0u) { out += " "; indent -= 1u; }
110+
out += "...\n";
111+
io::stdout().write_str(out);
112+
}
113+
114+
// If there's one line at fault we can easily point to the problem
115+
if (vec::len(lines.lines) == 1u) {
116+
auto lo = codemap::lookup_pos(cm, option::get(sp).lo);
117+
auto digits = 0u;
118+
auto num = lines.lines.(0) / 10u;
119+
120+
// how many digits must be indent past?
121+
while (num > 0u) { num /= 10u; digits += 1u; }
122+
123+
// indent past |name:## | and the 0-offset column location
124+
auto left = str::char_len(fm.name) + digits + lo.col + 3u;
125+
auto s = "";
126+
while (left > 0u) { str::push_char(s, ' '); left -= 1u; }
127+
128+
s += "^";
129+
auto hi = codemap::lookup_pos(cm, option::get(sp).hi);
130+
if (hi.col != lo.col) {
131+
// the ^ already takes up one space
132+
auto width = hi.col - lo.col - 1u;
133+
while (width > 0u) {
134+
str::push_char(s, '~');
135+
width -= 1u;
136+
}
137+
}
138+
io::stdout().write_str(s + "\n");
139+
}
92140
}
93141
case (_) {}
94142
}

0 commit comments

Comments
 (0)