@@ -49,7 +49,7 @@ struct Annotation {
49
49
/// column.
50
50
start_col : usize ,
51
51
52
- /// End column within the line.
52
+ /// End column within the line (exclusive)
53
53
end_col : usize ,
54
54
55
55
/// Is this annotation derived from primary span
@@ -349,24 +349,40 @@ impl FileInfo {
349
349
label : Option < String > ) {
350
350
assert ! ( lines. len( ) > 0 ) ;
351
351
352
- // If a span covers multiple lines, just put the label on the
353
- // first one. This is a sort of arbitrary choice and not
354
- // obviously correct.
355
- let ( line0, remaining_lines) = lines. split_first ( ) . unwrap ( ) ;
356
- let index = self . ensure_source_line ( line0. line_index ) ;
357
- self . lines [ index] . push_annotation ( line0. start_col ,
358
- line0. end_col ,
352
+ // If a span covers multiple lines, we reduce it to a single
353
+ // point at the start of the span. This means that instead
354
+ // of producing output like this:
355
+ //
356
+ // ```
357
+ // --> foo.rs:2:1
358
+ // 2 |> fn conflicting_items<'grammar>(state: &LR0State<'grammar>)
359
+ // |> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
360
+ // 3 |> -> Set<LR0Item<'grammar>>
361
+ // |> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
362
+ // (and so on)
363
+ // ```
364
+ //
365
+ // we produce:
366
+ //
367
+ // ```
368
+ // --> foo.rs:2:1
369
+ // 2 |> fn conflicting_items<'grammar>(state: &LR0State<'grammar>)
370
+ // ^
371
+ // ```
372
+ //
373
+ // Basically, although this loses information, multi-line spans just
374
+ // never look good.
375
+
376
+ let ( line, start_col, end_col) = if lines. len ( ) == 1 {
377
+ ( lines[ 0 ] . line_index , lines[ 0 ] . start_col , lines[ 0 ] . end_col )
378
+ } else {
379
+ ( lines[ 0 ] . line_index , lines[ 0 ] . start_col , CharPos ( lines[ 0 ] . start_col . 0 + 1 ) )
380
+ } ;
381
+ let index = self . ensure_source_line ( line) ;
382
+ self . lines [ index] . push_annotation ( start_col,
383
+ end_col,
359
384
is_primary,
360
385
label) ;
361
- for line in remaining_lines {
362
- if line. end_col > line. start_col {
363
- let index = self . ensure_source_line ( line. line_index ) ;
364
- self . lines [ index] . push_annotation ( line. start_col ,
365
- line. end_col ,
366
- is_primary,
367
- None ) ;
368
- }
369
- }
370
386
}
371
387
372
388
/// Ensure that we have a `Line` struct corresponding to
@@ -414,57 +430,10 @@ impl FileInfo {
414
430
}
415
431
416
432
fn render_file_lines ( & self , codemap : & Rc < CodeMap > ) -> Vec < RenderedLine > {
417
- // Group our lines by those with annotations and those without
418
- let mut lines_iter = self . lines . iter ( ) . peekable ( ) ;
419
-
420
- let mut line_groups = vec ! [ ] ;
421
-
422
- loop {
423
- match lines_iter. next ( ) {
424
- None => break ,
425
- Some ( line) if line. annotations . is_empty ( ) => {
426
- // Collect unannotated group
427
- let mut unannotated_group : Vec < & Line > = vec ! [ ] ;
428
-
429
- unannotated_group. push ( line) ;
430
-
431
- loop {
432
- let next_line =
433
- match lines_iter. peek ( ) {
434
- None => break ,
435
- Some ( x) if !x. annotations . is_empty ( ) => break ,
436
- Some ( x) => x. clone ( )
437
- } ;
438
-
439
- unannotated_group. push ( next_line) ;
440
- lines_iter. next ( ) ;
441
- }
442
-
443
- line_groups. push ( ( false , unannotated_group) ) ;
444
- }
445
- Some ( line) => {
446
- // Collect annotated group
447
- let mut annotated_group : Vec < & Line > = vec ! [ ] ;
448
-
449
- annotated_group. push ( line) ;
450
-
451
- loop {
452
- let next_line =
453
- match lines_iter. peek ( ) {
454
- None => break ,
455
- Some ( x) if x. annotations . is_empty ( ) => break ,
456
- Some ( x) => x. clone ( )
457
- } ;
458
-
459
- annotated_group. push ( next_line) ;
460
- lines_iter. next ( ) ;
461
- }
462
-
463
- line_groups. push ( ( true , annotated_group) ) ;
464
- }
465
- }
466
- }
433
+ // As a first step, we elide any instance of more than one
434
+ // continuous unannotated line.
467
435
436
+ let mut lines_iter = self . lines . iter ( ) ;
468
437
let mut output = vec ! [ ] ;
469
438
470
439
// First insert the name of the file.
@@ -493,65 +462,30 @@ impl FileInfo {
493
462
}
494
463
}
495
464
496
- for & ( is_annotated, ref group) in line_groups. iter ( ) {
497
- if is_annotated {
498
- let mut annotation_ends_at_eol = false ;
499
- let mut prev_ends_at_eol = false ;
500
- let mut elide_unlabeled_region = false ;
501
-
502
- for group_line in group. iter ( ) {
503
- let source_string_len =
504
- self . file . get_line ( group_line. line_index )
505
- . map ( |s| s. len ( ) )
506
- . unwrap_or ( 0 ) ;
507
-
508
- for annotation in & group_line. annotations {
509
- if annotation. end_col == source_string_len {
510
- annotation_ends_at_eol = true ;
511
- }
512
- }
513
-
514
- let is_single_unlabeled_annotated_line =
515
- if group_line. annotations . len ( ) == 1 {
516
- if let Some ( annotation) = group_line. annotations . first ( ) {
517
- match annotation. label {
518
- Some ( _) => false ,
519
- None => annotation. start_col == 0 &&
520
- annotation. end_col == source_string_len
521
- }
522
- } else {
523
- false
524
- }
525
- } else {
526
- false
527
- } ;
528
-
529
- if prev_ends_at_eol && is_single_unlabeled_annotated_line {
530
- if !elide_unlabeled_region {
531
- output. push ( RenderedLine :: from ( ( String :: new ( ) ,
532
- Style :: NoStyle ,
533
- RenderedLineKind :: Elision ) ) ) ;
534
- elide_unlabeled_region = true ;
535
- prev_ends_at_eol = true ;
536
- }
537
- continue ;
538
- }
539
-
540
- let mut v = self . render_line ( group_line) ;
541
- output. append ( & mut v) ;
465
+ let mut next_line = lines_iter. next ( ) ;
466
+ while next_line. is_some ( ) {
467
+ // Consume lines with annotations.
468
+ while let Some ( line) = next_line {
469
+ if line. annotations . is_empty ( ) { break ; }
470
+ output. append ( & mut self . render_line ( line) ) ;
471
+ next_line = lines_iter. next ( ) ;
472
+ }
542
473
543
- prev_ends_at_eol = annotation_ends_at_eol;
544
- }
545
- } else {
546
- if group. len ( ) > 1 {
547
- output. push ( RenderedLine :: from ( ( String :: new ( ) ,
548
- Style :: NoStyle ,
549
- RenderedLineKind :: Elision ) ) ) ;
550
- } else {
551
- let mut v: Vec < RenderedLine > =
552
- group. iter ( ) . flat_map ( |line| self . render_line ( line) ) . collect ( ) ;
553
- output. append ( & mut v) ;
554
- }
474
+ // Emit lines without annotations, but only if they are
475
+ // followed by a line with an annotation.
476
+ let unannotated_line = next_line;
477
+ let mut unannotated_lines = 0 ;
478
+ while let Some ( line) = next_line {
479
+ if !line. annotations . is_empty ( ) { break ; }
480
+ unannotated_lines += 1 ;
481
+ next_line = lines_iter. next ( ) ;
482
+ }
483
+ if unannotated_lines > 1 {
484
+ output. push ( RenderedLine :: from ( ( String :: new ( ) ,
485
+ Style :: NoStyle ,
486
+ RenderedLineKind :: Elision ) ) ) ;
487
+ } else if let Some ( line) = unannotated_line {
488
+ output. append ( & mut self . render_line ( line) ) ;
555
489
}
556
490
}
557
491
0 commit comments