mirror of
https://github.com/vlang/v.git
synced 2025-09-15 07:22:27 +03:00
all: rollback to old interpolation (step 3) (#16380)
This commit is contained in:
parent
bbae7a705f
commit
26d643fc5d
27 changed files with 91 additions and 108 deletions
|
@ -112,10 +112,10 @@ pub fn (mut vgit_context VGitContext) compile_oldv_if_needed() {
|
||||||
mut command_for_selfbuilding := ''
|
mut command_for_selfbuilding := ''
|
||||||
if 'windows' == os.user_os() {
|
if 'windows' == os.user_os() {
|
||||||
command_for_building_v_from_c_source = '$vgit_context.cc -std=c99 -I ./thirdparty/stdatomic/win -municode -w -o cv.exe "$vgit_context.path_vc/v_win.c" '
|
command_for_building_v_from_c_source = '$vgit_context.cc -std=c99 -I ./thirdparty/stdatomic/win -municode -w -o cv.exe "$vgit_context.path_vc/v_win.c" '
|
||||||
command_for_selfbuilding = './cv.exe -o $vgit_context.vexename \{SOURCE}'
|
command_for_selfbuilding = './cv.exe -o $vgit_context.vexename {SOURCE}'
|
||||||
} else {
|
} else {
|
||||||
command_for_building_v_from_c_source = '$vgit_context.cc -std=gnu11 -I ./thirdparty/stdatomic/nix -w -o cv "$vgit_context.path_vc/v.c" -lm -lpthread'
|
command_for_building_v_from_c_source = '$vgit_context.cc -std=gnu11 -I ./thirdparty/stdatomic/nix -w -o cv "$vgit_context.path_vc/v.c" -lm -lpthread'
|
||||||
command_for_selfbuilding = './cv -o $vgit_context.vexename \{SOURCE}'
|
command_for_selfbuilding = './cv -o $vgit_context.vexename {SOURCE}'
|
||||||
}
|
}
|
||||||
scripting.chdir(vgit_context.workdir)
|
scripting.chdir(vgit_context.workdir)
|
||||||
clone_or_pull(vgit_context.v_repo_url, vgit_context.path_v)
|
clone_or_pull(vgit_context.v_repo_url, vgit_context.path_v)
|
||||||
|
@ -146,7 +146,7 @@ pub fn (mut vgit_context VGitContext) compile_oldv_if_needed() {
|
||||||
scripting.run('make fresh_tcc')
|
scripting.run('make fresh_tcc')
|
||||||
}
|
}
|
||||||
scripting.run(command_for_building_v_from_c_source)
|
scripting.run(command_for_building_v_from_c_source)
|
||||||
build_cmd := command_for_selfbuilding.replace('\{SOURCE}', vgit_context.vvlocation)
|
build_cmd := command_for_selfbuilding.replace('{SOURCE}', vgit_context.vvlocation)
|
||||||
scripting.run(build_cmd)
|
scripting.run(build_cmd)
|
||||||
// At this point, there exists a file vgit_context.vexepath
|
// At this point, there exists a file vgit_context.vexepath
|
||||||
// which should be a valid working V executable.
|
// which should be a valid working V executable.
|
||||||
|
|
|
@ -165,8 +165,8 @@ fn (mut context Context) parse_options() ! {
|
||||||
context.verbose = fp.bool('verbose', `v`, false, 'Be more verbose.')
|
context.verbose = fp.bool('verbose', `v`, false, 'Be more verbose.')
|
||||||
context.fail_on_maxtime = fp.int('max_time', `m`, max_time, 'Fail with exit code 2, when first cmd takes above M milliseconds (regression).')
|
context.fail_on_maxtime = fp.int('max_time', `m`, max_time, 'Fail with exit code 2, when first cmd takes above M milliseconds (regression).')
|
||||||
context.fail_on_regress_percent = fp.int('fail_percent', `f`, max_fail_percent, 'Fail with exit code 3, when first cmd is X% slower than the rest (regression).')
|
context.fail_on_regress_percent = fp.int('fail_percent', `f`, max_fail_percent, 'Fail with exit code 3, when first cmd is X% slower than the rest (regression).')
|
||||||
context.cmd_template = fp.string('template', `t`, r'{T}', r'Command template. {T} will be substituted with the current command.')
|
context.cmd_template = fp.string('template', `t`, '{T}', 'Command template. {T} will be substituted with the current command.')
|
||||||
cmd_params := fp.string_multi('parameter', `p`, r'A parameter substitution list. `{p}=val1,val2,val2` means that {p} in the template, will be substituted with each of val1, val2, val3.')
|
cmd_params := fp.string_multi('parameter', `p`, 'A parameter substitution list. `{p}=val1,val2,val2` means that {p} in the template, will be substituted with each of val1, val2, val3.')
|
||||||
context.nmins = fp.int('nmins', `i`, 0, 'Ignore the BOTTOM X results (minimum execution time). Makes the results more robust to performance flukes.')
|
context.nmins = fp.int('nmins', `i`, 0, 'Ignore the BOTTOM X results (minimum execution time). Makes the results more robust to performance flukes.')
|
||||||
context.nmaxs = fp.int('nmaxs', `a`, 1, 'Ignore the TOP X results (maximum execution time). Makes the results more robust to performance flukes.')
|
context.nmaxs = fp.int('nmaxs', `a`, 1, 'Ignore the TOP X results (maximum execution time). Makes the results more robust to performance flukes.')
|
||||||
for p in cmd_params {
|
for p in cmd_params {
|
||||||
|
@ -212,7 +212,7 @@ fn (mut context Context) clear_line() {
|
||||||
fn (mut context Context) expand_all_commands(commands []string) []string {
|
fn (mut context Context) expand_all_commands(commands []string) []string {
|
||||||
mut all_commands := []string{}
|
mut all_commands := []string{}
|
||||||
for cmd in commands {
|
for cmd in commands {
|
||||||
maincmd := context.cmd_template.replace(r'{T}', cmd)
|
maincmd := context.cmd_template.replace('{T}', cmd)
|
||||||
mut substituted_commands := []string{}
|
mut substituted_commands := []string{}
|
||||||
substituted_commands << maincmd
|
substituted_commands << maincmd
|
||||||
for paramk, paramlist in context.cmd_params {
|
for paramk, paramlist in context.cmd_params {
|
||||||
|
|
|
@ -141,7 +141,7 @@ $vdoctor_output
|
||||||
|
|
||||||
**What did you do?**
|
**What did you do?**
|
||||||
`v -g -o vdbg cmd/v && vdbg $file_path`
|
`v -g -o vdbg cmd/v && vdbg $file_path`
|
||||||
\{file_content}
|
{file_content}
|
||||||
|
|
||||||
**What did you expect to see?**
|
**What did you expect to see?**
|
||||||
|
|
||||||
|
@ -150,11 +150,11 @@ $expected_result
|
||||||
**What did you see instead?**
|
**What did you see instead?**
|
||||||
```
|
```
|
||||||
$build_output```'
|
$build_output```'
|
||||||
mut encoded_body := urllib.query_escape(raw_body.replace_once(r'{file_content}', '```v\n$file_content\n```'))
|
mut encoded_body := urllib.query_escape(raw_body.replace_once('{file_content}', '```v\n$file_content\n```'))
|
||||||
mut generated_uri := 'https://github.com/vlang/v/issues/new?labels=Bug&body=$encoded_body'
|
mut generated_uri := 'https://github.com/vlang/v/issues/new?labels=Bug&body=$encoded_body'
|
||||||
if generated_uri.len > 8192 {
|
if generated_uri.len > 8192 {
|
||||||
// GitHub doesn't support URLs longer than 8192 characters
|
// GitHub doesn't support URLs longer than 8192 characters
|
||||||
encoded_body = urllib.query_escape(raw_body.replace_once(r'{file_content}', 'See attached file `$file_path`'))
|
encoded_body = urllib.query_escape(raw_body.replace_once('{file_content}', 'See attached file `$file_path`'))
|
||||||
generated_uri = 'https://github.com/vlang/v/issues/new?labels=Bug&body=$encoded_body'
|
generated_uri = 'https://github.com/vlang/v/issues/new?labels=Bug&body=$encoded_body'
|
||||||
println('Your file is too big to be submitted. Head over to the following URL and attach your file.')
|
println('Your file is too big to be submitted. Head over to the following URL and attach your file.')
|
||||||
println(generated_uri)
|
println(generated_uri)
|
||||||
|
|
|
@ -29,7 +29,7 @@ const (
|
||||||
'hg': 'hg clone'
|
'hg': 'hg clone'
|
||||||
}
|
}
|
||||||
supported_vcs_outdated_steps = {
|
supported_vcs_outdated_steps = {
|
||||||
'git': ['git fetch', 'git rev-parse @', 'git rev-parse @\{u}']
|
'git': ['git fetch', 'git rev-parse @', 'git rev-parse @{u}']
|
||||||
'hg': ['hg incoming']
|
'hg': ['hg incoming']
|
||||||
}
|
}
|
||||||
supported_vcs_version_cmds = {
|
supported_vcs_version_cmds = {
|
||||||
|
|
|
@ -516,7 +516,7 @@ fn test_struct_print() {
|
||||||
}
|
}
|
||||||
a.b << b
|
a.b << b
|
||||||
a.b << b
|
a.b << b
|
||||||
assert a.str() == '\{Test [{1 2}, {1 2}]}'
|
assert a.str() == '{Test [{1 2}, {1 2}]}'
|
||||||
assert b.str() == '{1 2}'
|
assert b.str() == '{1 2}'
|
||||||
assert a.b.str() == '[{1 2}, {1 2}]'
|
assert a.b.str() == '[{1 2}, {1 2}]'
|
||||||
}
|
}
|
||||||
|
|
|
@ -504,7 +504,7 @@ fn test_struct_print() {
|
||||||
}
|
}
|
||||||
a.b << b
|
a.b << b
|
||||||
a.b << b
|
a.b << b
|
||||||
assert a.str() == r'{Test [{1 2}, {1 2}]}'
|
assert a.str() == '{Test [{1 2}, {1 2}]}'
|
||||||
assert b.str() == '{1 2}'
|
assert b.str() == '{1 2}'
|
||||||
assert a.b.str() == '[{1 2}, {1 2}]'
|
assert a.b.str() == '[{1 2}, {1 2}]'
|
||||||
}
|
}
|
||||||
|
|
|
@ -849,11 +849,6 @@ fn test_raw_inter() {
|
||||||
assert s.contains('$')
|
assert s.contains('$')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_new_inter() {
|
|
||||||
// world := 'world'
|
|
||||||
// assert 'hello {world}' == 'hello world'
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_c_r() {
|
fn test_c_r() {
|
||||||
// This used to break because of r'' and c''
|
// This used to break because of r'' and c''
|
||||||
c := 42
|
c := 42
|
||||||
|
|
|
@ -95,8 +95,8 @@ fn test_parse_form() {
|
||||||
'a': 'b'
|
'a': 'b'
|
||||||
'c': ' d '
|
'c': ' d '
|
||||||
}
|
}
|
||||||
assert parse_form(r'{json}') == {
|
assert parse_form('{json}') == {
|
||||||
'json': r'{json}'
|
'json': '{json}'
|
||||||
}
|
}
|
||||||
assert parse_form('{
|
assert parse_form('{
|
||||||
"_id": "76c",
|
"_id": "76c",
|
||||||
|
|
|
@ -68,7 +68,7 @@ pub fn default() string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mut fm := os.execute("fc-match --format='%\{file}\n' -s")
|
mut fm := os.execute("fc-match --format='%{file}\n' -s")
|
||||||
if fm.exit_code == 0 {
|
if fm.exit_code == 0 {
|
||||||
lines := fm.output.split('\n')
|
lines := fm.output.split('\n')
|
||||||
for l in lines {
|
for l in lines {
|
||||||
|
|
|
@ -71,9 +71,9 @@ const expected_string_outputs = [
|
||||||
|
|
||||||
fn test_find_between_pair_family() {
|
fn test_find_between_pair_family() {
|
||||||
assert strings.find_between_pair_rune('xx♡ok❦yy', `♡`, `❦`) == 'ok'
|
assert strings.find_between_pair_rune('xx♡ok❦yy', `♡`, `❦`) == 'ok'
|
||||||
assert strings.find_between_pair_u8('xx\{ok}yy', `{`, `}`) == 'ok'
|
assert strings.find_between_pair_u8('xx{ok}yy', `{`, `}`) == 'ok'
|
||||||
assert strings.find_between_pair_string('xx/*ok*/yy', '/*', '*/') == 'ok'
|
assert strings.find_between_pair_string('xx/*ok*/yy', '/*', '*/') == 'ok'
|
||||||
assert strings.find_between_pair_u8('xx\{ok}yy', `{`, `}`) == 'ok'
|
assert strings.find_between_pair_u8('xx{ok}yy', `{`, `}`) == 'ok'
|
||||||
assert strings.find_between_pair_string('xxxxokyyyy', 'xxx', 'yyy') == 'xok'
|
assert strings.find_between_pair_string('xxxxokyyyy', 'xxx', 'yyy') == 'xok'
|
||||||
|
|
||||||
for i, tstr in test_rune_and_byte {
|
for i, tstr in test_rune_and_byte {
|
||||||
|
|
|
@ -4,31 +4,52 @@ vlib/v/checker/tests/str_interpol_invalid_err.vv:8:13: error: illegal format spe
|
||||||
8 | _ = '${[1]:x}'
|
8 | _ = '${[1]:x}'
|
||||||
| ^
|
| ^
|
||||||
9 | _ = '${[1]!:x}'
|
9 | _ = '${[1]!:x}'
|
||||||
10 | // _ = '${Foo{}:x}'
|
10 | _ = '${Foo{}:x}'
|
||||||
vlib/v/checker/tests/str_interpol_invalid_err.vv:9:14: error: illegal format specifier `x` for type `[1]int`
|
vlib/v/checker/tests/str_interpol_invalid_err.vv:9:14: error: illegal format specifier `x` for type `[1]int`
|
||||||
7 | fn main() {
|
7 | fn main() {
|
||||||
8 | _ = '${[1]:x}'
|
8 | _ = '${[1]:x}'
|
||||||
9 | _ = '${[1]!:x}'
|
9 | _ = '${[1]!:x}'
|
||||||
| ^
|
| ^
|
||||||
10 | // _ = '${Foo{}:x}'
|
10 | _ = '${Foo{}:x}'
|
||||||
11 | _ = '${[1]:f}'
|
11 | _ = '${[1]:f}'
|
||||||
|
vlib/v/checker/tests/str_interpol_invalid_err.vv:10:15: error: illegal format specifier `x` for type `Foo`
|
||||||
|
8 | _ = '${[1]:x}'
|
||||||
|
9 | _ = '${[1]!:x}'
|
||||||
|
10 | _ = '${Foo{}:x}'
|
||||||
|
| ^
|
||||||
|
11 | _ = '${[1]:f}'
|
||||||
|
12 | _ := '${none:F}'
|
||||||
vlib/v/checker/tests/str_interpol_invalid_err.vv:11:13: error: illegal format specifier `f` for type `[]int`
|
vlib/v/checker/tests/str_interpol_invalid_err.vv:11:13: error: illegal format specifier `f` for type `[]int`
|
||||||
9 | _ = '${[1]!:x}'
|
9 | _ = '${[1]!:x}'
|
||||||
10 | // _ = '${Foo{}:x}'
|
10 | _ = '${Foo{}:x}'
|
||||||
11 | _ = '${[1]:f}'
|
11 | _ = '${[1]:f}'
|
||||||
| ^
|
| ^
|
||||||
12 | _ := '${none:F}'
|
12 | _ := '${none:F}'
|
||||||
13 | // _ = '${{"a": "b"}:x}'
|
13 | _ = '${{"a": "b"}:x}'
|
||||||
vlib/v/checker/tests/str_interpol_invalid_err.vv:12:15: error: illegal format specifier `F` for type `none`
|
vlib/v/checker/tests/str_interpol_invalid_err.vv:12:15: error: illegal format specifier `F` for type `none`
|
||||||
10 | // _ = '${Foo{}:x}'
|
10 | _ = '${Foo{}:x}'
|
||||||
11 | _ = '${[1]:f}'
|
11 | _ = '${[1]:f}'
|
||||||
12 | _ := '${none:F}'
|
12 | _ := '${none:F}'
|
||||||
| ^
|
| ^
|
||||||
13 | // _ = '${{"a": "b"}:x}'
|
13 | _ = '${{"a": "b"}:x}'
|
||||||
14 | // _ = '${Alias(Foo{}):x}'
|
14 | _ = '${Alias(Foo{}):x}'
|
||||||
|
vlib/v/checker/tests/str_interpol_invalid_err.vv:13:20: error: illegal format specifier `x` for type `map[string]string`
|
||||||
|
11 | _ = '${[1]:f}'
|
||||||
|
12 | _ := '${none:F}'
|
||||||
|
13 | _ = '${{"a": "b"}:x}'
|
||||||
|
| ^
|
||||||
|
14 | _ = '${Alias(Foo{}):x}'
|
||||||
|
15 | _ = '${SumType(int(5)):o}'
|
||||||
|
vlib/v/checker/tests/str_interpol_invalid_err.vv:14:22: error: illegal format specifier `x` for type `Alias`
|
||||||
|
12 | _ := '${none:F}'
|
||||||
|
13 | _ = '${{"a": "b"}:x}'
|
||||||
|
14 | _ = '${Alias(Foo{}):x}'
|
||||||
|
| ^
|
||||||
|
15 | _ = '${SumType(int(5)):o}'
|
||||||
|
16 | }
|
||||||
vlib/v/checker/tests/str_interpol_invalid_err.vv:15:25: error: illegal format specifier `o` for type `SumType`
|
vlib/v/checker/tests/str_interpol_invalid_err.vv:15:25: error: illegal format specifier `o` for type `SumType`
|
||||||
13 | // _ = '${{"a": "b"}:x}'
|
13 | _ = '${{"a": "b"}:x}'
|
||||||
14 | // _ = '${Alias(Foo{}):x}'
|
14 | _ = '${Alias(Foo{}):x}'
|
||||||
15 | _ = '${SumType(int(5)):o}'
|
15 | _ = '${SumType(int(5)):o}'
|
||||||
| ^
|
| ^
|
||||||
16 | }
|
16 | }
|
||||||
|
|
|
@ -7,10 +7,10 @@ type SumType = Alias | int
|
||||||
fn main() {
|
fn main() {
|
||||||
_ = '${[1]:x}'
|
_ = '${[1]:x}'
|
||||||
_ = '${[1]!:x}'
|
_ = '${[1]!:x}'
|
||||||
// _ = '${Foo{}:x}'
|
_ = '${Foo{}:x}'
|
||||||
_ = '${[1]:f}'
|
_ = '${[1]:f}'
|
||||||
_ := '${none:F}'
|
_ := '${none:F}'
|
||||||
// _ = '${{"a": "b"}:x}'
|
_ = '${{"a": "b"}:x}'
|
||||||
// _ = '${Alias(Foo{}):x}'
|
_ = '${Alias(Foo{}):x}'
|
||||||
_ = '${SumType(int(5)):o}'
|
_ = '${SumType(int(5)):o}'
|
||||||
}
|
}
|
||||||
|
|
|
@ -1685,7 +1685,7 @@ pub fn (mut f Fmt) array_init(node ast.ArrayInit) {
|
||||||
}
|
}
|
||||||
f.write(f.table.type_to_str_using_aliases(node.elem_type, f.mod2alias))
|
f.write(f.table.type_to_str_using_aliases(node.elem_type, f.mod2alias))
|
||||||
if node.has_default {
|
if node.has_default {
|
||||||
f.write('\{init: ')
|
f.write('{init: ')
|
||||||
f.expr(node.default_expr)
|
f.expr(node.default_expr)
|
||||||
f.write('}')
|
f.write('}')
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -802,13 +802,9 @@ fn (mut s Scanner) text_scan() token.Token {
|
||||||
return s.new_token(.rsbr, '', 1)
|
return s.new_token(.rsbr, '', 1)
|
||||||
}
|
}
|
||||||
`{` {
|
`{` {
|
||||||
if s.is_inside_string {
|
|
||||||
// Handle new `hello {name}` string interpolation
|
|
||||||
if !s.text[s.pos + 1].is_space() && s.text[s.pos - 1] != `$` {
|
|
||||||
return s.new_token(.str_dollar, '', 1)
|
|
||||||
}
|
|
||||||
if s.text[s.pos - 1] == `$` {
|
|
||||||
// Skip { in `${` in strings
|
// Skip { in `${` in strings
|
||||||
|
if s.is_inside_string {
|
||||||
|
if s.text[s.pos - 1] == `$` {
|
||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
s.inter_cbr_count++
|
s.inter_cbr_count++
|
||||||
|
@ -1229,32 +1225,6 @@ fn (mut s Scanner) ident_string() string {
|
||||||
s.pos -= 2
|
s.pos -= 2
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// {var} (ignore in vfmt mode) (skip \{)
|
|
||||||
if c == `{` && util.is_name_char(s.text[s.pos + 1]) && prevc != `$` && !is_raw
|
|
||||||
&& s.count_symbol_before(s.pos - 1, scanner.backslash) % 2 == 0 {
|
|
||||||
// Detect certain strings with "{" that are not interpolation:
|
|
||||||
// e.g. "{init: " (no "}" at the end)
|
|
||||||
mut is_valid_inter := true
|
|
||||||
for i := s.pos + 1; i < s.text.len; i++ {
|
|
||||||
if s.text[i] == `}` {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if s.text[i] in [`=`, `:`, `\n`, s.inter_quote] {
|
|
||||||
// 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}')`
|
|
||||||
is_valid_inter = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if is_valid_inter {
|
|
||||||
s.is_inside_string = true
|
|
||||||
s.is_enclosed_inter = true
|
|
||||||
// so that s.pos points to $ at the next step
|
|
||||||
s.pos -= 1
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if c != scanner.backslash {
|
if c != scanner.backslash {
|
||||||
backslash_count = 0
|
backslash_count = 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,12 +9,9 @@ fn test_string_interpolation_inner_cbr() {
|
||||||
println(s1)
|
println(s1)
|
||||||
assert s1 == '22'
|
assert s1 == '22'
|
||||||
|
|
||||||
/*
|
|
||||||
XTODO
|
|
||||||
s2 := '${St{}}'
|
s2 := '${St{}}'
|
||||||
println(s2)
|
println(s2)
|
||||||
assert s2 == 'St{}'
|
assert s2 == 'St{}'
|
||||||
*/
|
|
||||||
|
|
||||||
s3 := '${{
|
s3 := '${{
|
||||||
'a': 1
|
'a': 1
|
||||||
|
|
|
@ -18,7 +18,7 @@ pub fn (mut p Pos) free() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (p Pos) line_str() string {
|
pub fn (p Pos) line_str() string {
|
||||||
return '\{l: ${p.line_nr + 1:5}, c: ${p.col:3}, p: ${p.pos:5}, ll: ${p.last_line + 1:5}}'
|
return '{l: ${p.line_nr + 1:5}, c: ${p.col:3}, p: ${p.pos:5}, ll: ${p.last_line + 1:5}}'
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (pos Pos) extend(end Pos) Pos {
|
pub fn (pos Pos) extend(end Pos) Pos {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue