From 31ffbc7a8727497d60f97dbf499c0106a519b191 Mon Sep 17 00:00:00 2001 From: yuyi Date: Thu, 6 Apr 2023 17:11:15 +0800 Subject: [PATCH] scanner: fix string interpolation string literal with fmt (#17895) --- vlib/v/scanner/scanner.v | 20 +++++++++++++------ ...g_interpolation_string_lit_with_fmt_test.v | 6 ++++++ 2 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 vlib/v/tests/string_interpolation_string_lit_with_fmt_test.v diff --git a/vlib/v/scanner/scanner.v b/vlib/v/scanner/scanner.v index 56b607c40c..872ec9a03a 100644 --- a/vlib/v/scanner/scanner.v +++ b/vlib/v/scanner/scanner.v @@ -34,6 +34,7 @@ pub mut: last_nl_pos int = -1 // for calculating column is_crlf bool // special check when computing columns is_inside_string bool // set to true in a string, *at the start* of an $var or ${expr} + is_nested_string bool // '${'abc':-12s}' is_inter_start bool // for hacky string interpolation TODO simplify is_inter_end bool is_enclosed_inter bool @@ -268,7 +269,7 @@ fn (mut s Scanner) ident_bin_number() string { s.error('cannot use `_` consecutively') } if !c.is_bin_digit() && c != scanner.num_sep { - if (!c.is_digit() && !c.is_letter()) || s.is_inside_string { + if (!c.is_digit() && !c.is_letter()) || s.is_inside_string || s.is_nested_string { break } else if !has_wrong_digit { has_wrong_digit = true @@ -312,7 +313,7 @@ fn (mut s Scanner) ident_hex_number() string { s.error('cannot use `_` consecutively') } if !c.is_hex_digit() && c != scanner.num_sep { - if !c.is_letter() || s.is_inside_string { + if !c.is_letter() || s.is_inside_string || s.is_nested_string { break } else if !has_wrong_digit { has_wrong_digit = true @@ -352,7 +353,7 @@ fn (mut s Scanner) ident_oct_number() string { s.error('cannot use `_` consecutively') } if !c.is_oct_digit() && c != scanner.num_sep { - if (!c.is_digit() && !c.is_letter()) || s.is_inside_string { + if (!c.is_digit() && !c.is_letter()) || s.is_inside_string || s.is_nested_string { break } else if !has_wrong_digit { has_wrong_digit = true @@ -390,7 +391,7 @@ fn (mut s Scanner) ident_dec_number() string { s.error('cannot use `_` consecutively') } if !c.is_digit() && c != scanner.num_sep { - if !c.is_letter() || c in [`e`, `E`] || s.is_inside_string { + if !c.is_letter() || c in [`e`, `E`] || s.is_inside_string || s.is_nested_string { break } else if !has_wrong_digit { has_wrong_digit = true @@ -415,7 +416,8 @@ fn (mut s Scanner) ident_dec_number() string { for s.pos < s.text.len { c := s.text[s.pos] if !c.is_digit() { - if !c.is_letter() || c in [`e`, `E`] || s.is_inside_string { + if !c.is_letter() || c in [`e`, `E`] || s.is_inside_string + || s.is_nested_string { // 5.5.str() if c == `.` && s.pos + 1 < s.text.len && s.text[s.pos + 1].is_letter() { call_method = true @@ -461,7 +463,7 @@ fn (mut s Scanner) ident_dec_number() string { for s.pos < s.text.len { c := s.text[s.pos] if !c.is_digit() { - if !c.is_letter() || s.is_inside_string { + if !c.is_letter() || s.is_inside_string || s.is_nested_string { // 5e5.str() if c == `.` && s.pos + 1 < s.text.len && s.text[s.pos + 1].is_letter() { call_method = true @@ -1130,6 +1132,12 @@ fn (s &Scanner) count_symbol_before(p int, sym u8) int { [direct_array_access] fn (mut s Scanner) ident_string() string { + // determines if it is a nested string + if s.is_inside_string { + s.is_nested_string = true + } else { + s.is_nested_string = false + } lspos := token.Pos{ line_nr: s.line_nr pos: s.pos diff --git a/vlib/v/tests/string_interpolation_string_lit_with_fmt_test.v b/vlib/v/tests/string_interpolation_string_lit_with_fmt_test.v new file mode 100644 index 0000000000..93b8c3d8e4 --- /dev/null +++ b/vlib/v/tests/string_interpolation_string_lit_with_fmt_test.v @@ -0,0 +1,6 @@ +fn test_string_interpolation_string_lit_with_fmt() { + println('${'hello':-12s}') + assert '${'hello':-12s}' == 'hello ' + println('${'hello':12s}') + assert '${'hello':12s}' == ' hello' +}