1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

scanner: fix new string interpolation - nested quotes (#16345)

This commit is contained in:
yuyi 2022-11-08 22:51:02 +08:00 committed by GitHub
parent bc30608e92
commit c7d0f0561e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 11 deletions

View File

@ -1326,9 +1326,15 @@ fn (mut s Scanner) ident_string() string {
fn (s Scanner) is_valid_interpolation(start_pos int) bool {
mut is_valid_inter := true
mut has_rcbr := false
mut is_assign := true
mut inside_par := false
for i := start_pos; i < s.text.len - 1; i++ {
if s.text[i] == s.quote {
if s.text[i] == `(` {
inside_par = true
}
if s.text[i] == `)` && inside_par {
inside_par = false
}
if s.text[i] == s.quote && !inside_par {
break
}
if s.text[i] == `}` {
@ -1337,12 +1343,12 @@ fn (s Scanner) is_valid_interpolation(start_pos int) bool {
}
if s.text[i] == `=` && (s.text[i - 1] in [`!`, `>`, `<`] || s.text[i + 1] == `=`) {
// `!=` `>=` `<=` `==`
is_assign = false
return true
}
if (s.text[i] == `=` && is_assign) || (s.text[i] == `:` && s.text[i + 1].is_space()) {
if s.text[i] == `=` || (s.text[i] == `:` && s.text[i + 1].is_space()) {
// We reached the end of the line or string without reaching "}".
// Also if there's "=", there's no way it's a valid interpolation expression:
// e.g. `println("{a.b = 42}")` `println('{foo:bar}')`
// e.g. `println("{a.b = 42}")` `println('{foo: bar}')`
is_valid_inter = false
break
}

View File

@ -16,13 +16,11 @@ fn test_string_new_interpolation() {
println('{a}{{{{{b}}}}}')
assert '{a}{{{{{b}}}}}' == '1{{{{2}}}}'
// vfmt off
s := 'hello'
println('{s == "hello"}')
assert '{s == "hello"}' == 'true'
println('{s != "hello"}')
assert '{s != "hello"}' == 'false'
// vfmt on
println('{s == 'hello'}')
assert '{s == 'hello'}' == 'true'
println('{s != 'hello'}')
assert '{s != 'hello'}' == 'false'
n := 22
println('{n >= 10}')
@ -39,4 +37,21 @@ fn test_string_new_interpolation() {
println('{@FILE}')
assert '{@FILE}'.contains('string_new_interpolation_test.v')
ret := foo()
println(ret)
assert ret == r'[]T{aaa, bbb, ccc}'
}
fn foo() string {
match true {
true {
fields := ['aaa', 'bbb', 'ccc']
return '[]T{{fields.join(', ')}}'
}
else {
fields := ['aaa', 'bbb', 'ccc']
return 'const ({fields.join(' ')})'
}
}
}