1
-
1
+ import std:: uint;
2
+ import std:: str;
2
3
import std:: vec;
3
4
import std:: term;
4
5
import std:: io;
@@ -58,8 +59,12 @@ fn span_to_str(&span sp, &codemap cm) -> str {
58
59
fn emit_diagnostic ( & option:: t[ span] sp , & str msg, & str kind , u8 color ,
59
60
& codemap cm) {
60
61
auto ss = "<input>:0:0:0:0" ;
62
+ let option:: t[ @file_lines] maybe_lines = none;
61
63
alt ( sp) {
62
- case ( some ( ?ssp) ) { ss = span_to_str ( ssp, cm) ; }
64
+ case ( some ( ?ssp) ) {
65
+ ss = span_to_str ( ssp, cm) ;
66
+ maybe_lines = some ( span_to_lines ( ssp, cm) ) ;
67
+ }
63
68
case ( none) { }
64
69
}
65
70
io:: stdout ( ) . write_str ( ss + ": " ) ;
@@ -71,6 +76,22 @@ fn emit_diagnostic(&option::t[span] sp, &str msg, &str kind, u8 color,
71
76
term:: reset ( io:: stdout ( ) . get_buf_writer ( ) ) ;
72
77
}
73
78
io:: stdout ( ) . write_str ( #fmt ( " %s\n " , msg) ) ;
79
+ alt ( maybe_lines) {
80
+ case ( some ( ?lines) ) {
81
+ auto rdr = io:: file_reader ( lines. name ) ;
82
+ auto file = str:: unsafe_from_bytes ( rdr. read_whole_stream ( ) ) ;
83
+ auto fm = codemap:: get_filemap ( cm, lines. name ) ;
84
+ for ( uint line in lines. lines) {
85
+ io:: stdout ( ) . write_str ( #fmt ( "%s:%u " , fm. name , line + 1 u) ) ;
86
+ auto s = codemap:: get_line ( fm, line as int , file) ;
87
+ if ( !str:: ends_with ( s, "\n " ) ) {
88
+ s += "\n " ;
89
+ }
90
+ io:: stdout ( ) . write_str ( s) ;
91
+ }
92
+ }
93
+ case ( _) { }
94
+ }
74
95
}
75
96
76
97
fn emit_warning ( & option:: t[ span] sp , & str msg, & codemap cm) {
@@ -83,6 +104,38 @@ fn emit_note(&option::t[span] sp, &str msg, &codemap cm) {
83
104
emit_diagnostic ( sp, msg, "note" , 10u8 , cm) ;
84
105
}
85
106
107
+ type file_lines = rec ( str name , vec[ uint] lines ) ;
108
+
109
+ fn span_to_lines ( span sp, codemap:: codemap cm) -> @file_lines {
110
+ auto lo = codemap:: lookup_pos ( cm, sp. lo ) ;
111
+ auto hi = codemap:: lookup_pos ( cm, sp. hi ) ;
112
+ auto lines = [ ] ;
113
+ for each ( uint i in uint:: range( lo. line - 1 u, hi. line as uint) ) {
114
+ lines += [ i] ;
115
+ }
116
+ ret @rec( name=lo. filename , lines=lines) ;
117
+ }
118
+
119
+ fn get_line ( filemap fm, int line , & str file ) -> str {
120
+ let uint end;
121
+ if ( ( line as uint ) + 1 u >= vec:: len ( fm. lines ) ) {
122
+ end = str:: byte_len ( file) ;
123
+ } else {
124
+ end = fm. lines . ( line + 1 ) ;
125
+ }
126
+ ret str:: slice ( file, fm. lines . ( line) , end) ;
127
+ }
128
+
129
+ fn get_filemap ( codemap cm, str filename ) -> filemap {
130
+ for ( filemap fm in cm. files) {
131
+ if ( fm. name == filename) {
132
+ ret fm;
133
+ }
134
+ }
135
+ //XXjdm the following triggers a mismatched type bug
136
+ // (or expected function, found _|_)
137
+ fail; // ("asking for " + filename + " which we don't know about");
138
+ }
86
139
87
140
//
88
141
// Local Variables:
0 commit comments