parser: add warning for s.$field.name without brackets (#8411)

pull/8445/head
Nick Treleaven 2021-01-30 11:56:10 +00:00 committed by GitHub
parent 97cb7687a2
commit c0685eeefc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 30 additions and 33 deletions

View File

@ -1,7 +1,7 @@
vlib/v/checker/tests/comptime_field_selector_not_in_for_err.vv:9:5: error: expected selector expression e.g. `$(field.name)`
vlib/v/checker/tests/comptime_field_selector_not_in_for_err.vv:9:6: error: expected selector expression e.g. `$(field.name)`
7 | mut t := T{}
8 | name := 'test'
9 | t.$name = '3'
| ~~~~
9 | t.$(name) = '3'
| ~~~~
10 | }
11 |

View File

@ -6,7 +6,7 @@ struct Foo {
fn test<T>() {
mut t := T{}
name := 'test'
t.$name = '3'
t.$(name) = '3'
}
fn main() {

View File

@ -1,21 +1,21 @@
vlib/v/checker/tests/comptime_field_selector_not_name_err.vv:10:7: error: expected `string` instead of `FieldData` (e.g. `field.name`)
vlib/v/checker/tests/comptime_field_selector_not_name_err.vv:10:8: error: expected `string` instead of `FieldData` (e.g. `field.name`)
8 | $for f in T.fields {
9 | $if f.typ is string {
10 | t.$f = '3'
| ^
10 | t.$(f) = '3'
| ^
11 | fv := Foo{}
12 | _ = t.$fv.name
vlib/v/checker/tests/comptime_field_selector_not_name_err.vv:12:11: error: unknown `$for` variable `fv`
10 | t.$f = '3'
12 | _ = t.$(fv.name)
vlib/v/checker/tests/comptime_field_selector_not_name_err.vv:12:12: error: unknown `$for` variable `fv`
10 | t.$(f) = '3'
11 | fv := Foo{}
12 | _ = t.$fv.name
| ~~
12 | _ = t.$(fv.name)
| ~~
13 | }
14 | }
vlib/v/checker/tests/comptime_field_selector_not_name_err.vv:15:9: error: compile time field access can only be used when iterating over `T.fields`
vlib/v/checker/tests/comptime_field_selector_not_name_err.vv:15:10: error: compile time field access can only be used when iterating over `T.fields`
13 | }
14 | }
15 | _ = t.$f.name
| ^
15 | _ = t.$(f.name)
| ^
16 | }
17 |

View File

@ -7,12 +7,12 @@ fn test<T>() {
mut t := T{}
$for f in T.fields {
$if f.typ is string {
t.$f = '3'
t.$(f) = '3'
fv := Foo{}
_ = t.$fv.name
_ = t.$(fv.name)
}
}
_ = t.$f.name
_ = t.$(f.name)
}
fn main() {

View File

@ -1156,8 +1156,7 @@ pub fn (mut f Fmt) comptime_call(node ast.ComptimeCall) {
}
pub fn (mut f Fmt) comptime_selector(node ast.ComptimeSelector) {
field_expr := if node.has_parens { '($node.field_expr)' } else { node.field_expr.str() }
f.write('${node.left}.$$field_expr')
f.write('${node.left}.\$($node.field_expr)')
}
pub fn (mut f Fmt) concat_expr(node ast.ConcatExpr) {

View File

@ -13,7 +13,7 @@ fn test<T>() {
t.name = '2'
$for f in T.fields {
$if f.typ is string {
println(t.$f.name)
println(t.$(f.name))
}
}
}

View File

@ -256,17 +256,9 @@ fn (mut p Parser) at() ast.AtExpr {
fn (mut p Parser) comptime_selector(left ast.Expr) ast.Expr {
p.check(.dollar)
mut has_parens := false
if p.tok.kind == .lpar {
p.check(.lpar)
has_parens = true
}
if p.peek_tok.kind == .lpar {
method_name := p.check_name()
// `app.$action()` (`action` is a string)
if has_parens {
p.check(.rpar)
}
p.check(.lpar)
mut args_var := ''
if p.tok.kind == .name {
@ -279,12 +271,18 @@ fn (mut p Parser) comptime_selector(left ast.Expr) ast.Expr {
p.check(.lcbr)
}
return ast.ComptimeCall{
has_parens: has_parens
left: left
method_name: method_name
args_var: args_var
}
}
mut has_parens := false
if p.tok.kind == .lpar {
p.check(.lpar)
has_parens = true
} else {
p.warn_with_pos('use brackets instead e.g. `s.$(field.name)` - run vfmt', p.tok.position())
}
expr := p.expr(0)
if has_parens {
p.check(.rpar)

View File

@ -12,7 +12,7 @@ fn comptime_field_selector_read<T>() []string {
mut value_list := []string{}
$for f in T.fields {
$if f.typ is string {
value_list << t.$f.name
value_list << t.$(f.name)
}
}
return value_list
@ -26,10 +26,10 @@ fn comptime_field_selector_write<T>() T {
mut t := T{}
$for f in T.fields {
$if f.typ is string {
t.$f.name = '1'
t.$(f.name) = '1'
}
$if f.typ is int {
t.$f.name = 1
t.$(f.name) = 1
}
}
return t