scanner: fix interpolation with string args (#7214)
parent
cf755d40b7
commit
5fa1e403ec
|
@ -26,6 +26,7 @@ pub mut:
|
||||||
is_inside_string bool
|
is_inside_string bool
|
||||||
is_inter_start bool // for hacky string interpolation TODO simplify
|
is_inter_start bool // for hacky string interpolation TODO simplify
|
||||||
is_inter_end bool
|
is_inter_end bool
|
||||||
|
is_enclosed_inter bool
|
||||||
is_debug bool
|
is_debug bool
|
||||||
line_comment string
|
line_comment string
|
||||||
// prev_tok TokenKind
|
// prev_tok TokenKind
|
||||||
|
@ -34,6 +35,7 @@ pub mut:
|
||||||
is_print_colored_error bool
|
is_print_colored_error bool
|
||||||
is_print_rel_paths_on_error bool
|
is_print_rel_paths_on_error bool
|
||||||
quote byte // which quote is used to denote current string: ' or "
|
quote byte // which quote is used to denote current string: ' or "
|
||||||
|
inter_quote byte
|
||||||
line_ends []int // the positions of source lines ends (i.e. \n signs)
|
line_ends []int // the positions of source lines ends (i.e. \n signs)
|
||||||
nr_lines int // total number of lines in the source file that were scanned
|
nr_lines int // total number of lines in the source file that were scanned
|
||||||
is_vh bool // Keep newlines
|
is_vh bool // Keep newlines
|
||||||
|
@ -716,12 +718,14 @@ fn (mut s Scanner) text_scan() token.Token {
|
||||||
`}` {
|
`}` {
|
||||||
// s = `hello $name !`
|
// s = `hello $name !`
|
||||||
// s = `hello ${name} !`
|
// s = `hello ${name} !`
|
||||||
if s.is_inside_string {
|
if s.is_enclosed_inter {
|
||||||
s.pos++
|
s.pos++
|
||||||
if s.text[s.pos] == s.quote {
|
if s.text[s.pos] == s.quote {
|
||||||
s.is_inside_string = false
|
s.is_inside_string = false
|
||||||
|
s.is_enclosed_inter = false
|
||||||
return s.new_token(.string, '', 1)
|
return s.new_token(.string, '', 1)
|
||||||
}
|
}
|
||||||
|
s.is_enclosed_inter = false
|
||||||
ident_string := s.ident_string()
|
ident_string := s.ident_string()
|
||||||
return s.new_token(.string, ident_string, ident_string.len + 2) // + two quotes
|
return s.new_token(.string, ident_string, ident_string.len + 2) // + two quotes
|
||||||
} else {
|
} else {
|
||||||
|
@ -993,8 +997,12 @@ fn (mut s Scanner) ident_string() string {
|
||||||
is_quote := q == single_quote || q == double_quote
|
is_quote := q == single_quote || q == double_quote
|
||||||
is_raw := is_quote && s.pos > 0 && s.text[s.pos - 1] == `r`
|
is_raw := is_quote && s.pos > 0 && s.text[s.pos - 1] == `r`
|
||||||
is_cstr := is_quote && s.pos > 0 && s.text[s.pos - 1] == `c`
|
is_cstr := is_quote && s.pos > 0 && s.text[s.pos - 1] == `c`
|
||||||
if is_quote && !s.is_inside_string {
|
if is_quote {
|
||||||
s.quote = q
|
if s.is_inside_string {
|
||||||
|
s.inter_quote = q
|
||||||
|
} else {
|
||||||
|
s.quote = q
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// if s.file_path.contains('string_test') {
|
// if s.file_path.contains('string_test') {
|
||||||
// println('\nident_string() at char=${s.text[s.pos].str()}')
|
// println('\nident_string() at char=${s.text[s.pos].str()}')
|
||||||
|
@ -1002,6 +1010,10 @@ fn (mut s Scanner) ident_string() string {
|
||||||
// }
|
// }
|
||||||
mut n_cr_chars := 0
|
mut n_cr_chars := 0
|
||||||
mut start := s.pos
|
mut start := s.pos
|
||||||
|
if s.text[start] == s.quote ||
|
||||||
|
(s.text[start] == s.inter_quote && (s.is_inter_start || s.is_enclosed_inter)) {
|
||||||
|
start++
|
||||||
|
}
|
||||||
s.is_inside_string = false
|
s.is_inside_string = false
|
||||||
slash := `\\`
|
slash := `\\`
|
||||||
for {
|
for {
|
||||||
|
@ -1016,6 +1028,9 @@ fn (mut s Scanner) ident_string() string {
|
||||||
// handle '123\\' slash at the end
|
// handle '123\\' slash at the end
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
if c == s.inter_quote && (s.is_inter_start || s.is_enclosed_inter) {
|
||||||
|
break
|
||||||
|
}
|
||||||
if c == `\r` {
|
if c == `\r` {
|
||||||
n_cr_chars++
|
n_cr_chars++
|
||||||
}
|
}
|
||||||
|
@ -1054,6 +1069,7 @@ fn (mut s Scanner) ident_string() string {
|
||||||
// ${var} (ignore in vfmt mode) (skip \$)
|
// ${var} (ignore in vfmt mode) (skip \$)
|
||||||
if prevc == `$` && c == `{` && !is_raw && s.count_symbol_before(s.pos - 2, slash) % 2 == 0 {
|
if prevc == `$` && c == `{` && !is_raw && s.count_symbol_before(s.pos - 2, slash) % 2 == 0 {
|
||||||
s.is_inside_string = true
|
s.is_inside_string = true
|
||||||
|
s.is_enclosed_inter = true
|
||||||
// so that s.pos points to $ at the next step
|
// so that s.pos points to $ at the next step
|
||||||
s.pos -= 2
|
s.pos -= 2
|
||||||
break
|
break
|
||||||
|
@ -1068,9 +1084,6 @@ fn (mut s Scanner) ident_string() string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mut lit := ''
|
mut lit := ''
|
||||||
if s.text[start] == s.quote {
|
|
||||||
start++
|
|
||||||
}
|
|
||||||
mut end := s.pos
|
mut end := s.pos
|
||||||
if s.is_inside_string {
|
if s.is_inside_string {
|
||||||
end++
|
end++
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
fn show_info(a string) string {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_interpolation_string_args() {
|
||||||
|
assert '${show_info("abc")}' == 'abc'
|
||||||
|
assert '${show_info("bac")}' == 'bac'
|
||||||
|
assert '${"aaa"}' == 'aaa'
|
||||||
|
}
|
Loading…
Reference in New Issue