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.
|
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
|
```v
|
||||||
// Calling this function will result in a deprecation warning
|
// 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) {
|
fn (mut f Fmt) attrs(attrs []table.Attr) {
|
||||||
for attr in attrs {
|
for attr in attrs {
|
||||||
f.write('[')
|
f.writeln('[$attr]')
|
||||||
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(']')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1139,7 +1128,7 @@ fn (mut f Fmt) inline_attrs(attrs []table.Attr) {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
f.write(';')
|
f.write(';')
|
||||||
}
|
}
|
||||||
f.write(attr.name)
|
f.write('$attr')
|
||||||
}
|
}
|
||||||
f.write(']')
|
f.write(']')
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
[inline]
|
[inline]
|
||||||
[if debug]
|
[if debug]
|
||||||
|
[foo: bar]
|
||||||
|
[deprecated: 'use bar() instead']
|
||||||
fn keep_attributes() {
|
fn keep_attributes() {
|
||||||
println('hi !')
|
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) {
|
fn (mut g Gen) comp_if(mut it ast.CompIf) {
|
||||||
if it.stmts.len == 0 && it.else_stmts.len == 0 {
|
if it.stmts.len == 0 && it.else_stmts.len == 0 {
|
||||||
return
|
return
|
||||||
|
@ -175,10 +188,7 @@ fn (mut g Gen) comp_for(node ast.CompFor) {
|
||||||
if method.attrs.len == 0 {
|
if method.attrs.len == 0 {
|
||||||
g.writeln('\t${node.val_var}.attrs = __new_array_with_default(0, 0, sizeof(string), 0);')
|
g.writeln('\t${node.val_var}.attrs = __new_array_with_default(0, 0, sizeof(string), 0);')
|
||||||
} else {
|
} else {
|
||||||
mut attrs := []string{}
|
attrs := cgen_attrs(method.attrs)
|
||||||
for attrib in method.attrs {
|
|
||||||
attrs << 'tos_lit("$attrib.name")'
|
|
||||||
}
|
|
||||||
g.writeln('\t${node.val_var}.attrs = new_array_from_c_array($attrs.len, $attrs.len, sizeof(string), _MOV((string[$attrs.len]){' +
|
g.writeln('\t${node.val_var}.attrs = new_array_from_c_array($attrs.len, $attrs.len, sizeof(string), _MOV((string[$attrs.len]){' +
|
||||||
attrs.join(', ') + '}));')
|
attrs.join(', ') + '}));')
|
||||||
}
|
}
|
||||||
|
@ -210,10 +220,7 @@ fn (mut g Gen) comp_for(node ast.CompFor) {
|
||||||
if field.attrs.len == 0 {
|
if field.attrs.len == 0 {
|
||||||
g.writeln('\t${node.val_var}.attrs = __new_array_with_default(0, 0, sizeof(string), 0);')
|
g.writeln('\t${node.val_var}.attrs = __new_array_with_default(0, 0, sizeof(string), 0);')
|
||||||
} else {
|
} else {
|
||||||
mut attrs := []string{}
|
attrs := cgen_attrs(field.attrs)
|
||||||
for attrib in field.attrs {
|
|
||||||
attrs << 'tos_lit("$attrib.name")'
|
|
||||||
}
|
|
||||||
g.writeln('\t${node.val_var}.attrs = new_array_from_c_array($attrs.len, $attrs.len, sizeof(string), _MOV((string[$attrs.len]){' +
|
g.writeln('\t${node.val_var}.attrs = new_array_from_c_array($attrs.len, $attrs.len, sizeof(string), _MOV((string[$attrs.len]){' +
|
||||||
attrs.join(', ') + '}));')
|
attrs.join(', ') + '}));')
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,8 +83,8 @@ $enc_fn_dec {
|
||||||
}
|
}
|
||||||
mut name := field.name
|
mut name := field.name
|
||||||
for attr in field.attrs {
|
for attr in field.attrs {
|
||||||
if attr.name.starts_with('json:') {
|
if attr.name == 'json' {
|
||||||
name = attr.name[5..]
|
name = attr.arg
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -432,7 +432,7 @@ pub fn (mut p Parser) top_stmt() ast.Stmt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.lsbr {
|
.lsbr {
|
||||||
// attrs are stores in `p.attrs()`
|
// attrs are stored in `p.attrs`
|
||||||
p.attributes()
|
p.attributes()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -737,7 +737,9 @@ fn (mut p Parser) parse_attr() table.Attr {
|
||||||
is_ctdefine = true
|
is_ctdefine = true
|
||||||
}
|
}
|
||||||
mut name := ''
|
mut name := ''
|
||||||
|
mut arg := ''
|
||||||
is_string := p.tok.kind == .string
|
is_string := p.tok.kind == .string
|
||||||
|
mut is_string_arg := false
|
||||||
if is_string {
|
if is_string {
|
||||||
name = p.tok.lit
|
name = p.tok.lit
|
||||||
p.next()
|
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())
|
p.error_with_pos('please use `[trusted]` instead', p.tok.position())
|
||||||
}
|
}
|
||||||
if p.tok.kind == .colon {
|
if p.tok.kind == .colon {
|
||||||
name += ':'
|
|
||||||
p.next()
|
p.next()
|
||||||
|
// `name: arg`
|
||||||
if p.tok.kind == .name {
|
if p.tok.kind == .name {
|
||||||
name += p.check_name()
|
arg = p.check_name()
|
||||||
} else if p.tok.kind == .string {
|
} else if p.tok.kind == .string { // `name: 'arg'`
|
||||||
name += p.tok.lit
|
arg = p.tok.lit
|
||||||
|
is_string_arg = true
|
||||||
p.next()
|
p.next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -763,6 +766,8 @@ fn (mut p Parser) parse_attr() table.Attr {
|
||||||
name: name
|
name: name
|
||||||
is_string: is_string
|
is_string: is_string
|
||||||
is_ctdefine: is_ctdefine
|
is_ctdefine: is_ctdefine
|
||||||
|
arg: arg
|
||||||
|
is_string_arg: is_string_arg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,38 @@ module table
|
||||||
// e.g. `[unsafe]`
|
// e.g. `[unsafe]`
|
||||||
pub struct Attr {
|
pub struct Attr {
|
||||||
pub:
|
pub:
|
||||||
name string
|
name string // [name]
|
||||||
is_string bool // `['xxx']`
|
is_string bool // ['name']
|
||||||
is_ctdefine bool // `[if flag]`
|
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 {
|
pub fn (attrs []Attr) contains(str string) bool {
|
||||||
|
|
Loading…
Reference in New Issue