@@ -33,6 +33,7 @@ pub trait handler {
33
33
fn bump_err_count ( @mut self ) ;
34
34
fn has_errors ( @mut self ) -> bool ;
35
35
fn abort_if_errors ( @mut self ) ;
36
+ fn abort_error_print ( @mut self ) ;
36
37
fn warn ( @mut self , msg : & str ) ;
37
38
fn note ( @mut self , msg : & str ) ;
38
39
// used to indicate a bug in the compiler:
@@ -42,6 +43,7 @@ pub trait handler {
42
43
cmsp : Option < ( @codemap:: CodeMap , span ) > ,
43
44
msg : & str ,
44
45
lvl : level ) ;
46
+ fn emit_print ( @mut self , lvl : level ) ;
45
47
}
46
48
47
49
// a span-handler is like a handler but also
@@ -57,8 +59,15 @@ pub trait span_handler {
57
59
fn handler ( @mut self ) -> @handler ;
58
60
}
59
61
62
+ struct emitter_arg {
63
+ cmsp : Option < ( @codemap:: CodeMap , span ) > ,
64
+ msg : ~str ,
65
+ lvl : level ,
66
+ }
67
+
60
68
struct HandlerT {
61
69
err_count : uint ,
70
+ emitters : ~[ emitter_arg ] ,
62
71
emit : Emitter ,
63
72
}
64
73
@@ -69,15 +78,19 @@ struct CodemapT {
69
78
70
79
impl span_handler for CodemapT {
71
80
fn span_fatal ( @mut self , sp : span , msg : & str ) -> ! {
81
+ self . handler . bump_err_count ( ) ;
72
82
self . handler . emit ( Some ( ( self . cm , sp) ) , msg, fatal) ;
83
+ self . handler . emit_print ( error) ;
84
+ self . handler . emit_print ( note) ;
85
+ self . handler . abort_error_print ( ) ;
73
86
fail ! ( ) ;
74
87
}
75
88
fn span_err ( @mut self , sp : span , msg : & str ) {
76
89
self . handler . emit ( Some ( ( self . cm , sp) ) , msg, error) ;
77
90
self . handler . bump_err_count ( ) ;
78
91
}
79
92
fn span_warn ( @mut self , sp : span , msg : & str ) {
80
- self . handler . emit ( Some ( ( self . cm , sp) ) , msg, warning) ;
93
+ emit_one ( Some ( ( self . cm , sp) ) , msg, warning) ;
81
94
}
82
95
fn span_note ( @mut self , sp : span , msg : & str ) {
83
96
self . handler . emit ( Some ( ( self . cm , sp) ) , msg, note) ;
@@ -95,11 +108,13 @@ impl span_handler for CodemapT {
95
108
96
109
impl handler for HandlerT {
97
110
fn fatal(@mut self, msg: &str) -> ! {
98
- (self.emit)(None, msg, fatal);
111
+ self.emit_print(error);
112
+ self.emit_print(note);
113
+ emit_one(None, msg, fatal);
99
114
fail!();
100
115
}
101
116
fn err(@mut self, msg: &str) {
102
- (self.emit) (None, msg, error);
117
+ emit_one (None, msg, error);
103
118
self.bump_err_count();
104
119
}
105
120
fn bump_err_count(@mut self) {
@@ -118,13 +133,26 @@ impl handler for HandlerT {
118
133
}
119
134
self . fatal( s) ;
120
135
}
136
+ fn abort_error_print ( @mut self ) {
137
+ let s;
138
+ match self . err_count {
139
+ 0 u => return ,
140
+ 1 u => s = ~"aborting due to previous error",
141
+ _ => {
142
+ s = fmt ! ( "aborting due to %u previous errors" ,
143
+ self . err_count) ;
144
+ }
145
+ }
146
+ emit_one ( None , s, fatal) ;
147
+ }
121
148
fn warn ( @mut self , msg : & str ) {
122
- ( self . emit ) ( None , msg, warning) ;
149
+ emit_one ( None , msg, warning) ;
123
150
}
124
151
fn note ( @mut self , msg : & str ) {
125
- ( self . emit ) ( None , msg, note) ;
152
+ self . emit ( None , msg, note) ;
126
153
}
127
154
fn bug ( @mut self , msg : & str ) -> ! {
155
+ self . bump_err_count ( ) ;
128
156
self . fatal ( ice_msg ( msg) ) ;
129
157
}
130
158
fn unimpl ( @mut self , msg : & str ) -> ! {
@@ -135,6 +163,50 @@ impl handler for HandlerT {
135
163
msg: &str,
136
164
lvl: level) {
137
165
(self.emit)(cmsp, msg, lvl);
166
+ let emitter = emitter_arg { cmsp: cmsp,
167
+ msg: str::from_slice(msg),
168
+ lvl: lvl };
169
+ self.emitters.push(emitter);
170
+ }
171
+
172
+ fn emit_print(@mut self, lvl: level) {
173
+ let mut old_cmsp = None;
174
+ let mut old_line = 0u;
175
+
176
+ let emitters = self.emitters;
177
+ let length = emitters.len();
178
+ for uint::range(0, length) |i| {
179
+ let emitter = copy self.emitters[i];
180
+ let cmsp = emitter.cmsp;
181
+ let msg = emitter.msg;
182
+ if diagnosticstr(lvl) == diagnosticstr(emitter.lvl) {
183
+ match cmsp {
184
+ Some((cm, sp)) => {
185
+ let lo = cm.lookup_char_pos_adj(sp.lo);
186
+ let sp = cm.adjust_span(sp);
187
+ let ss = cm.span_to_str(sp);
188
+ if i == 0 || old_line == lo.line {
189
+ if old_line == lo.line {
190
+ highlight_lines_cmp(cmsp, old_cmsp);
191
+ }
192
+ print_diagnostic(ss, lvl, msg);
193
+ highlight_lines_cmp(old_cmsp, cmsp);
194
+ } else {
195
+ highlight_lines(old_cmsp);
196
+ print_macro_backtrace(old_cmsp);
197
+ print_diagnostic(ss, lvl, msg);
198
+ }
199
+ old_line = lo.line;
200
+ old_cmsp = emitter.cmsp;
201
+ }
202
+ None => {
203
+ print_diagnostic(~" ", lvl, msg) ;
204
+ }
205
+ }
206
+ }
207
+ }
208
+ highlight_lines ( old_cmsp) ;
209
+ print_macro_backtrace ( old_cmsp) ;
138
210
}
139
211
}
140
212
@@ -156,7 +228,9 @@ pub fn mk_handler(emitter: Option<Emitter>) -> @handler {
156
228
}
157
229
} ;
158
230
159
- @mut HandlerT { err_count : 0 , emit : emit } as @handler
231
+ @mut HandlerT { err_count : 0 ,
232
+ emitters : ~[ ] ,
233
+ emit : emit } as @handler
160
234
}
161
235
162
236
#[ deriving( Eq ) ]
@@ -208,23 +282,27 @@ pub fn collect(messages: @mut ~[~str])
208
282
f
209
283
}
210
284
211
- pub fn emit ( cmsp : Option < ( @codemap:: CodeMap , span ) > , msg : & str , lvl : level ) {
285
+ pub fn emit ( _cmsp : Option < ( @codemap:: CodeMap , span ) > , _msg : & str , _lvl : level ) {
286
+ // Nothing to do
287
+ }
288
+
289
+ pub fn emit_one ( cmsp : Option < ( @codemap:: CodeMap , span ) > ,
290
+ msg : & str , lvl : level ) {
212
291
match cmsp {
213
292
Some ( ( cm, sp) ) => {
214
293
let sp = cm. adjust_span ( sp) ;
215
294
let ss = cm. span_to_str ( sp) ;
216
- let lines = cm. span_to_lines ( sp) ;
217
295
print_diagnostic ( ss, lvl, msg) ;
218
- highlight_lines ( cm , sp , lines ) ;
219
- print_macro_backtrace ( cm , sp ) ;
296
+ highlight_lines ( cmsp ) ;
297
+ print_macro_backtrace ( cmsp ) ;
220
298
}
221
299
None => {
222
300
print_diagnostic ( ~"", lvl, msg) ;
223
301
}
224
302
}
225
303
}
226
304
227
- fn highlight_lines ( cm : @codemap:: CodeMap ,
305
+ fn highlight_lines_internal ( cm : @codemap:: CodeMap ,
228
306
sp : span ,
229
307
lines : @codemap:: FileLines ) {
230
308
let fm = lines. file ;
@@ -291,14 +369,70 @@ fn highlight_lines(cm: @codemap::CodeMap,
291
369
}
292
370
}
293
371
294
- fn print_macro_backtrace( cm: @codemap:: CodeMap , sp: span) {
372
+ fn highlight_lines( cmsp: Option < ( @codemap:: CodeMap , span ) > ) {
373
+ match cmsp {
374
+ Some ( ( cm, sp) ) => {
375
+ let sp = cm. adjust_span( sp) ;
376
+ let lines = cm. span_to_lines( sp) ;
377
+ highlight_lines_internal( cm, sp, lines) ;
378
+ }
379
+ None => ( )
380
+ }
381
+ }
382
+
383
+ fn highlight_lines_cmp( old_cmsp: Option < ( @codemap:: CodeMap , span ) > ,
384
+ cmsp: Option < ( @codemap:: CodeMap , span ) > ) {
385
+ let mut old_line = ~[ ] ;
386
+ let mut new_line = ~[ ] ;
387
+ let mut old_lo = 0 u;
388
+ let mut new_lo = 0 u;
389
+ let mut flag = true ;
390
+ match old_cmsp {
391
+ Some ( ( cm, sp) ) => {
392
+ let lo = cm. lookup_char_pos( sp. lo) ;
393
+ let sp = cm. adjust_span( sp) ;
394
+ let lines = cm. span_to_lines( sp) ;
395
+ old_line = lines. lines;
396
+ old_lo = lo. col. to_uint( ) ;
397
+ }
398
+ None => { flag = false ; }
399
+ }
400
+
401
+ match cmsp {
402
+ Some ( ( cm, sp) ) => {
403
+ let lo = cm. lookup_char_pos( sp. lo) ;
404
+ let sp = cm. adjust_span( sp) ;
405
+ let lines = cm. span_to_lines( sp) ;
406
+ new_line = lines. lines;
407
+ new_lo = lo. col. to_uint( ) ;
408
+ }
409
+ None => { flag = false ; }
410
+ }
411
+
412
+ if flag {
413
+ if old_line == new_line && old_lo > new_lo {
414
+ highlight_lines( cmsp) ;
415
+ }
416
+ }
417
+ }
418
+
419
+ fn print_macro_backtrace_internal( cm: @codemap:: CodeMap , sp: span) {
295
420
for sp. expn_info. each |ei| {
296
421
let ss = ei. callee. span. map_default( @~"", |span| @cm. span_to_str( * span) ) ;
297
422
print_diagnostic( * ss, note,
298
423
fmt ! ( "in expansion of %s!" , ei. callee. name) ) ;
299
424
let ss = cm. span_to_str( ei. call_site) ;
300
425
print_diagnostic( ss, note, ~"expansion site") ;
301
- print_macro_backtrace( cm, ei. call_site) ;
426
+ print_macro_backtrace_internal( cm, ei. call_site) ;
427
+ }
428
+ }
429
+
430
+ fn print_macro_backtrace( cmsp: Option <( @codemap:: CodeMap , span) >) {
431
+ match cmsp {
432
+ Some ( ( cm, sp) ) => {
433
+ print_macro_backtrace_internal( cm, sp) ;
434
+ }
435
+ None => ( )
302
436
}
303
437
}
304
438
0 commit comments