From eeea257467def8415e90fd2ce274667360c38d94 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Tue, 22 Oct 2019 18:38:17 +0300 Subject: [PATCH] clean up empty lines in errors; simplify source line tracking --- vlib/compiler/compile_errors.v | 15 ++++++--------- vlib/compiler/scanner.v | 26 +++++++++++++++++++++----- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/vlib/compiler/compile_errors.v b/vlib/compiler/compile_errors.v index fc3c6ee6ea..51fe9552e4 100644 --- a/vlib/compiler/compile_errors.v +++ b/vlib/compiler/compile_errors.v @@ -95,11 +95,11 @@ fn (s &Scanner) error_with_col(msg string, col int) { // to find the source file, when the IDE has a different working folder than v itself. eprintln('${fullpath}:${s.line_nr + 1}:${col}: $final_message') - if s.should_print_line_on_error && s.file_lines.len > 0 { - context_start_line := imax(0, (s.line_nr - error_context_before + 1 )) - context_end_line := imin(s.file_lines.len, (s.line_nr + error_context_after + 1 )) + if s.should_print_line_on_error && s.nlines > 0 { + context_start_line := imax(0, (s.line_nr - error_context_before + 1 )) + context_end_line := imin(s.nlines-1, (s.line_nr + error_context_after + 1 )) for cline := context_start_line; cline < context_end_line; cline++ { - line := '${(cline+1):5d}| ' + s.file_lines[ cline ] + line := '${(cline+1):5d}| ' + s.line( cline ) coloredline := if cline == s.line_nr && color_on { term.red(line) } else { line } eprintln( coloredline ) if cline != s.line_nr { continue } @@ -225,9 +225,8 @@ fn (s mut Scanner) get_scanner_pos_of_token(t &Token) ScannerPos { // Starting from the start, scan the source lines // till the desired tline is reached, then // s.pos + tcol would be the proper position - // of the token. Continue scanning for some more lines of context too. + // of the token. s.goto_scanner_position(ScannerPos{}) - s.file_lines = []string mut prevlinepos := 0 // NB: TCC BUG workaround: removing the `mut ate:=0 ate++` line @@ -251,15 +250,13 @@ fn (s mut Scanner) get_scanner_pos_of_token(t &Token) ScannerPos { for { prevlinepos = s.pos if s.pos >= s.text.len { break } - if s.line_nr > tline + 10 { break } + if s.line_nr > tline { break } //////////////////////////////////////// if tline == s.line_nr { sptoken = s.get_scanner_pos() sptoken.pos += tcol } s.ignore_line() s.eat_single_newline() - sline := s.text.substr( prevlinepos, s.pos )//.trim_right('\r\n') - s.file_lines << sline } ////////////////////////////////////////////////// s.goto_scanner_position(cpos) diff --git a/vlib/compiler/scanner.v b/vlib/compiler/scanner.v index 773345b995..39d3bc92a0 100644 --- a/vlib/compiler/scanner.v +++ b/vlib/compiler/scanner.v @@ -39,7 +39,8 @@ mut: should_print_errors_in_color bool should_print_relative_paths_on_error bool quote byte // which quote is used to denote current string: ' or " - file_lines []string // filled *only on error* by rescanning the source till the error (and several lines more) + line_ends []int // the positions of source lines ends (i.e. \n signs) + nlines int // total number of lines in the source file that were scanned } // new scanner from file. @@ -632,7 +633,7 @@ fn (s mut Scanner) ident_string() string { s.inc_line_number() } // Don't allow \0 - if c == `0` && s.pos > 2 && s.text[s.pos - 1] == `\\` { + if c == `0` && s.pos > 2 && s.text[s.pos - 1] == slash { s.error('0 character in a string literal') } // Don't allow \x00 @@ -640,14 +641,14 @@ fn (s mut Scanner) ident_string() string { s.error('0 character in a string literal') } // ${var} - if c == `{` && prevc == `$` && s.count_symbol_before(s.pos-2, `\\`) % 2 == 0 { + if c == `{` && prevc == `$` && s.count_symbol_before(s.pos-2, slash) % 2 == 0 { s.inside_string = true // so that s.pos points to $ at the next step s.pos -= 2 break } // $var - if (c.is_letter() || c == `_`) && prevc == `$` && s.count_symbol_before(s.pos-2, `\\`) % 2 == 0 { + if (c.is_letter() || c == `_`) && prevc == `$` && s.count_symbol_before(s.pos-2, slash) % 2 == 0 { s.inside_string = true s.inter_start = true s.pos -= 2 @@ -748,7 +749,7 @@ fn (s mut Scanner) debug_tokens() { fn (s mut Scanner) ignore_line() { - s.eat_to_end_of_line() + s.eat_to_end_of_line() s.inc_line_number() } @@ -761,6 +762,21 @@ fn (s mut Scanner) eat_to_end_of_line(){ fn (s mut Scanner) inc_line_number() { s.last_nl_pos = s.pos s.line_nr++ + s.line_ends << s.pos + s.nlines++ +} + +fn (s Scanner) line(n int) string { + mut res := '' + if n >= 0 && + n < s.line_ends.len { + nline_start := if n == 0 { 0 } else { s.line_ends[ n - 1 ] } + nline_end := s.line_ends[n] + if nline_start <= nline_end { + res = s.text.substr( nline_start, nline_end ) + } + } + return res.trim_right('\r\n').trim_left('\r\n') } fn is_name_char(c byte) bool {