2020// FIXME spec the JSON output properly.
2121
2222
23- use codemap:: { Span , MultiSpan , CodeMap } ;
23+ use codemap:: { self , Span , MultiSpan , CodeMap } ;
2424use diagnostics:: registry:: Registry ;
2525use errors:: { Level , DiagnosticBuilder , SubDiagnostic , RenderSpan , CodeSuggestion } ;
2626use errors:: emitter:: Emitter ;
@@ -197,8 +197,8 @@ impl DiagnosticSpan {
197197
198198 fn from_render_span ( rsp : & RenderSpan , je : & JsonEmitter ) -> Vec < DiagnosticSpan > {
199199 match * rsp {
200- // FIXME(#30701) handle Suggestion properly
201200 RenderSpan :: FullSpan ( ref msp) |
201+ // FIXME(#30701) handle Suggestion properly
202202 RenderSpan :: Suggestion ( CodeSuggestion { ref msp, .. } ) => {
203203 DiagnosticSpan :: from_multispan ( msp, je)
204204 }
@@ -207,13 +207,13 @@ impl DiagnosticSpan {
207207 let end = je. cm . lookup_char_pos ( span. hi ) ;
208208 DiagnosticSpan {
209209 file_name : end. file . name . clone ( ) ,
210- byte_start : span. lo . 0 ,
210+ byte_start : span. hi . 0 ,
211211 byte_end : span. hi . 0 ,
212- line_start : 0 ,
212+ line_start : end . line ,
213213 line_end : end. line ,
214- column_start : 0 ,
214+ column_start : end . col . 0 + 1 ,
215215 column_end : end. col . 0 + 1 ,
216- text : DiagnosticSpanLine :: from_span ( span, je) ,
216+ text : DiagnosticSpanLine :: from_span_end ( span, je) ,
217217 }
218218 } ) . collect ( )
219219 }
@@ -237,25 +237,70 @@ impl DiagnosticSpan {
237237 }
238238}
239239
240- impl DiagnosticSpanLine {
241- fn from_span ( span : & Span , je : & JsonEmitter ) -> Vec < DiagnosticSpanLine > {
242- let lines = match je. cm . span_to_lines ( * span) {
240+ macro_rules! get_lines_for_span {
241+ ( $ span: ident , $ je: ident ) = > {
242+ match $ je. cm. span_to_lines( * $ span) {
243243 Ok ( lines) => lines,
244244 Err ( _) => {
245245 debug!( "unprintable span" ) ;
246246 return Vec :: new( ) ;
247247 }
248- } ;
248+ }
249+ }
250+ }
251+
252+ impl DiagnosticSpanLine {
253+ fn line_from_filemap ( fm : & codemap:: FileMap ,
254+ index : usize ,
255+ h_start : usize ,
256+ h_end : usize )
257+ -> DiagnosticSpanLine {
258+ DiagnosticSpanLine {
259+ text : fm. get_line ( index) . unwrap ( ) . to_owned ( ) ,
260+ highlight_start : h_start,
261+ highlight_end : h_end,
262+ }
263+ }
264+
265+ /// Create a list of DiagnosticSpanLines from span - each line with any part
266+ /// of `span` gets a DiagnosticSpanLine, with the highlight indicating the
267+ /// `span` within the line.
268+ fn from_span ( span : & Span , je : & JsonEmitter ) -> Vec < DiagnosticSpanLine > {
269+ let lines = get_lines_for_span ! ( span, je) ;
249270
250271 let mut result = Vec :: new ( ) ;
251272 let fm = & * lines. file ;
252273
253274 for line in & lines. lines {
254- result. push ( DiagnosticSpanLine {
255- text : fm. get_line ( line. line_index ) . unwrap ( ) . to_owned ( ) ,
256- highlight_start : line. start_col . 0 + 1 ,
257- highlight_end : line. end_col . 0 + 1 ,
258- } ) ;
275+ result. push ( DiagnosticSpanLine :: line_from_filemap ( fm,
276+ line. line_index ,
277+ line. start_col . 0 + 1 ,
278+ line. end_col . 0 + 1 ) ) ;
279+ }
280+
281+ result
282+ }
283+
284+ /// Create a list of DiagnosticSpanLines from span - the result covers all
285+ /// of `span`, but the highlight is zero-length and at the end of `span`.
286+ fn from_span_end ( span : & Span , je : & JsonEmitter ) -> Vec < DiagnosticSpanLine > {
287+ let lines = get_lines_for_span ! ( span, je) ;
288+
289+ let mut result = Vec :: new ( ) ;
290+ let fm = & * lines. file ;
291+
292+ for ( i, line) in lines. lines . iter ( ) . enumerate ( ) {
293+ // Invariant - CodeMap::span_to_lines will not return extra context
294+ // lines - the last line returned is the last line of `span`.
295+ let highlight = if i == lines. lines . len ( ) - 1 {
296+ ( line. end_col . 0 + 1 , line. end_col . 0 + 1 )
297+ } else {
298+ ( 0 , 0 )
299+ } ;
300+ result. push ( DiagnosticSpanLine :: line_from_filemap ( fm,
301+ line. line_index ,
302+ highlight. 0 ,
303+ highlight. 1 ) ) ;
259304 }
260305
261306 result
0 commit comments