parser: use Attr.arg field for `[name: arg]` (#6084)
parent
c7fae4dd6f
commit
fce106cf83
|
@ -2501,7 +2501,7 @@ On Unix-like platforms, the file can be run directly after making it executable
|
|||
|
||||
V has several attributes that modify the behavior of functions and structs.
|
||||
|
||||
An attribute is specified inside `[]` right before the function/struct declaration and applies only to the following definition.
|
||||
An attribute is specified inside `[]` right before a function/struct declaration and applies only to the following declaration.
|
||||
|
||||
```v
|
||||
// Calling this function will result in a deprecation warning
|
||||
|
|
|
@ -1115,18 +1115,7 @@ pub fn (mut f Fmt) or_expr(or_block ast.OrExpr) {
|
|||
|
||||
fn (mut f Fmt) attrs(attrs []table.Attr) {
|
||||
for attr in attrs {
|
||||
f.write('[')
|
||||
if attr.is_ctdefine {
|
||||
f.write('if ')
|
||||
}
|
||||
if attr.is_string {
|
||||
f.write("'")
|
||||
}
|
||||
f.write(attr.name)
|
||||
if attr.is_string {
|
||||
f.write("'")
|
||||
}
|
||||
f.writeln(']')
|
||||
f.writeln('[$attr]')
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1139,7 +1128,7 @@ fn (mut f Fmt) inline_attrs(attrs []table.Attr) {
|
|||
if i > 0 {
|
||||
f.write(';')
|
||||
}
|
||||
f.write(attr.name)
|
||||
f.write('$attr')
|
||||
}
|
||||
f.write(']')
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
[inline]
|
||||
[if debug]
|
||||
[foo: bar]
|
||||
[deprecated: 'use bar() instead']
|
||||
fn keep_attributes() {
|
||||
println('hi !')
|
||||
}
|
||||
|
|
|
@ -88,6 +88,19 @@ fn (mut g Gen) comptime_call(node ast.ComptimeCall) {
|
|||
}
|
||||
}
|
||||
|
||||
fn cgen_attrs(attrs []table.Attr) []string {
|
||||
mut res := []string{cap: attrs.len}
|
||||
for attr in attrs {
|
||||
// we currently don't quote 'arg' (otherwise we could just use `s := attr.str()`)
|
||||
mut s := attr.name
|
||||
if attr.arg.len > 0 {
|
||||
s += ': $attr.arg'
|
||||
}
|
||||
res << 'tos_lit("$s")'
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
fn (mut g Gen) comp_if(mut it ast.CompIf) {
|
||||
if it.stmts.len == 0 && it.else_stmts.len == 0 {
|
||||
return
|
||||
|
@ -175,10 +188,7 @@ fn (mut g Gen) comp_for(node ast.CompFor) {
|
|||
if method.attrs.len == 0 {
|
||||
g.writeln('\t${node.val_var}.attrs = __new_array_with_default(0, 0, sizeof(string), 0);')
|
||||
} else {
|
||||
mut attrs := []string{}
|
||||
for attrib in method.attrs {
|
||||
attrs << 'tos_lit("$attrib.name")'
|
||||
}
|
||||
attrs := cgen_attrs(method.attrs)
|
||||
g.writeln('\t${node.val_var}.attrs = new_array_from_c_array($attrs.len, $attrs.len, sizeof(string), _MOV((string[$attrs.len]){' +
|
||||
attrs.join(', ') + '}));')
|
||||
}
|
||||
|
@ -210,10 +220,7 @@ fn (mut g Gen) comp_for(node ast.CompFor) {
|
|||
if field.attrs.len == 0 {
|
||||
g.writeln('\t${node.val_var}.attrs = __new_array_with_default(0, 0, sizeof(string), 0);')
|
||||
} else {
|
||||
mut attrs := []string{}
|
||||
for attrib in field.attrs {
|
||||
attrs << 'tos_lit("$attrib.name")'
|
||||
}
|
||||
attrs := cgen_attrs(field.attrs)
|
||||
g.writeln('\t${node.val_var}.attrs = new_array_from_c_array($attrs.len, $attrs.len, sizeof(string), _MOV((string[$attrs.len]){' +
|
||||
attrs.join(', ') + '}));')
|
||||
}
|
||||
|
|
|
@ -83,8 +83,8 @@ $enc_fn_dec {
|
|||
}
|
||||
mut name := field.name
|
||||
for attr in field.attrs {
|
||||
if attr.name.starts_with('json:') {
|
||||
name = attr.name[5..]
|
||||
if attr.name == 'json' {
|
||||
name = attr.arg
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
|
@ -432,7 +432,7 @@ pub fn (mut p Parser) top_stmt() ast.Stmt {
|
|||
}
|
||||
}
|
||||
.lsbr {
|
||||
// attrs are stores in `p.attrs()`
|
||||
// attrs are stored in `p.attrs`
|
||||
p.attributes()
|
||||
continue
|
||||
}
|
||||
|
@ -737,7 +737,9 @@ fn (mut p Parser) parse_attr() table.Attr {
|
|||
is_ctdefine = true
|
||||
}
|
||||
mut name := ''
|
||||
mut arg := ''
|
||||
is_string := p.tok.kind == .string
|
||||
mut is_string_arg := false
|
||||
if is_string {
|
||||
name = p.tok.lit
|
||||
p.next()
|
||||
|
@ -749,12 +751,13 @@ fn (mut p Parser) parse_attr() table.Attr {
|
|||
p.error_with_pos('please use `[trusted]` instead', p.tok.position())
|
||||
}
|
||||
if p.tok.kind == .colon {
|
||||
name += ':'
|
||||
p.next()
|
||||
// `name: arg`
|
||||
if p.tok.kind == .name {
|
||||
name += p.check_name()
|
||||
} else if p.tok.kind == .string {
|
||||
name += p.tok.lit
|
||||
arg = p.check_name()
|
||||
} else if p.tok.kind == .string { // `name: 'arg'`
|
||||
arg = p.tok.lit
|
||||
is_string_arg = true
|
||||
p.next()
|
||||
}
|
||||
}
|
||||
|
@ -763,6 +766,8 @@ fn (mut p Parser) parse_attr() table.Attr {
|
|||
name: name
|
||||
is_string: is_string
|
||||
is_ctdefine: is_ctdefine
|
||||
arg: arg
|
||||
is_string_arg: is_string_arg
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,9 +6,38 @@ module table
|
|||
// e.g. `[unsafe]`
|
||||
pub struct Attr {
|
||||
pub:
|
||||
name string
|
||||
is_string bool // `['xxx']`
|
||||
is_ctdefine bool // `[if flag]`
|
||||
name string // [name]
|
||||
is_string bool // ['name']
|
||||
is_ctdefine bool // [if name]
|
||||
arg string // [name: arg]
|
||||
is_string_arg bool // [name: 'arg']
|
||||
}
|
||||
|
||||
// no square brackets
|
||||
pub fn (attr Attr) str() string {
|
||||
mut s := ''
|
||||
if attr.is_ctdefine {
|
||||
s += 'if '
|
||||
}
|
||||
if attr.is_string {
|
||||
s += "'$attr.name'"
|
||||
}
|
||||
else {
|
||||
s += attr.name
|
||||
if attr.arg.len > 0 {
|
||||
s += ': '
|
||||
if attr.is_string_arg {
|
||||
mut a := attr.arg.replace('\\', '\\\\')
|
||||
// FIXME: other escapes e.g. \r\n
|
||||
a = a.replace("'", "\\'")
|
||||
s += "'$a'"
|
||||
}
|
||||
else {
|
||||
s += attr.arg
|
||||
}
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
pub fn (attrs []Attr) contains(str string) bool {
|
||||
|
|
Loading…
Reference in New Issue