v.scanner: report the start of unfinished string literals too

pull/13004/head
Delyan Angelov 2021-12-30 18:20:27 +02:00
parent 93c40e696d
commit df8384b62e
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
3 changed files with 54 additions and 0 deletions

View File

@ -54,6 +54,7 @@ pub mut:
tidx int
eofs int
pref &pref.Preferences
error_details []string
errors []errors.Error
warnings []errors.Warning
notices []errors.Notice
@ -1142,6 +1143,11 @@ fn (s &Scanner) count_symbol_before(p int, sym byte) int {
[direct_array_access]
fn (mut s Scanner) ident_string() string {
lspos := token.Position{
line_nr: s.line_nr
pos: s.pos
col: s.pos - s.last_nl_pos - 1
}
q := s.text[s.pos]
is_quote := q == scanner.single_quote || q == scanner.double_quote
is_raw := is_quote && s.pos > 0 && s.text[s.pos - 1] == `r` && !s.is_inside_string
@ -1172,6 +1178,9 @@ fn (mut s Scanner) ident_string() string {
for {
s.pos++
if s.pos >= s.text.len {
if lspos.line_nr + 1 < s.line_nr {
s.add_error_detail_with_pos('literal started here', lspos)
}
s.error('unfinished string literal')
break
}
@ -1396,6 +1405,25 @@ pub fn (mut s Scanner) note(msg string) {
}
}
// call this *before* calling error or warn
pub fn (mut s Scanner) add_error_detail(msg string) {
s.error_details << msg
}
pub fn (mut s Scanner) add_error_detail_with_pos(msg string, pos token.Position) {
details := util.formatted_error('details:', msg, s.file_path, pos)
s.add_error_detail(details)
}
fn (mut s Scanner) eat_details() string {
mut details := ''
if s.error_details.len > 0 {
details = s.error_details.join('\n')
s.error_details = []
}
return details
}
pub fn (mut s Scanner) warn(msg string) {
if s.pref.warns_are_errors {
s.error(msg)
@ -1406,8 +1434,12 @@ pub fn (mut s Scanner) warn(msg string) {
pos: s.pos
col: s.current_column() - 1
}
details := s.eat_details()
if s.pref.output_mode == .stdout && !s.pref.check_only {
eprintln(util.formatted_error('warning:', msg, s.file_path, pos))
if details.len > 0 {
eprintln(details)
}
} else {
if s.pref.message_limit >= 0 && s.warnings.len >= s.pref.message_limit {
s.should_abort = true
@ -1418,6 +1450,7 @@ pub fn (mut s Scanner) warn(msg string) {
pos: pos
reporter: .scanner
message: msg
details: details
}
}
}
@ -1428,8 +1461,12 @@ pub fn (mut s Scanner) error(msg string) {
pos: s.pos
col: s.current_column() - 1
}
details := s.eat_details()
if s.pref.output_mode == .stdout && !s.pref.check_only {
eprintln(util.formatted_error('error:', msg, s.file_path, pos))
if details.len > 0 {
eprintln(details)
}
exit(1)
} else {
if s.pref.fatal_errors {
@ -1444,6 +1481,7 @@ pub fn (mut s Scanner) error(msg string) {
pos: pos
reporter: .scanner
message: msg
details: details
}
}
}

View File

@ -0,0 +1,10 @@
vlib/v/scanner/tests/unfinished_string_literal_err.vv:7:1: error: unfinished string literal
5 |
6 | zzzz
vlib/v/scanner/tests/unfinished_string_literal_err.vv:4:6: details: literal started here
2 | a := 'abc'
3 | println(a)
4 | x := 'asdka
| ^
5 |
6 | zzzz

View File

@ -0,0 +1,6 @@
// something
a := 'abc'
println(a)
x := 'asdka
zzzz