mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
parser: fix incorrect duplicate struct attr error
This commit is contained in:
parent
0052ab71e9
commit
effa0061e8
@ -567,6 +567,14 @@ pub struct Attr {
|
||||
pub:
|
||||
name string
|
||||
}
|
||||
pub fn (attrs []Attr) contains(attr Attr) bool {
|
||||
for a in attrs {
|
||||
if attr.name == a.name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
pub struct EnumVal {
|
||||
pub:
|
||||
|
@ -414,12 +414,7 @@ pub fn (mut p Parser) top_stmt() ast.Stmt {
|
||||
}
|
||||
}
|
||||
.lsbr {
|
||||
start_pos := p.tok.position()
|
||||
attrs := p.attributes()
|
||||
if attrs.len == 0 {
|
||||
end_pos := p.tok.position()
|
||||
p.error_with_pos('attributes cannot be empty', start_pos.extend(end_pos))
|
||||
}
|
||||
attrs := p.attributes(true)
|
||||
return attrs[0]
|
||||
}
|
||||
.key_interface {
|
||||
@ -626,11 +621,19 @@ fn (mut p Parser) expr_list() []ast.Expr {
|
||||
return exprs
|
||||
}
|
||||
|
||||
fn (mut p Parser) attributes() []ast.Attr {
|
||||
// when is_top_stmt is true attrs are added to p.attrs
|
||||
fn (mut p Parser) attributes(is_top_stmt bool) []ast.Attr {
|
||||
mut attrs := []ast.Attr{}
|
||||
p.check(.lsbr)
|
||||
for p.tok.kind != .rsbr {
|
||||
start_pos := p.tok.position()
|
||||
attr := p.parse_attr()
|
||||
if attr in attrs || (is_top_stmt && attr.name in p.attrs) {
|
||||
p.error_with_pos('duplicate attribute `$attr.name`', start_pos.extend(p.prev_tok.position()))
|
||||
}
|
||||
if is_top_stmt {
|
||||
p.attrs << attr.name
|
||||
}
|
||||
attrs << attr
|
||||
if p.tok.kind != .semicolon {
|
||||
expected := `;`
|
||||
@ -642,11 +645,13 @@ fn (mut p Parser) attributes() []ast.Attr {
|
||||
}
|
||||
p.next()
|
||||
}
|
||||
if attrs.len == 0 {
|
||||
p.error_with_pos('attributes cannot be empty', p.prev_tok.position().extend(p.tok.position()))
|
||||
}
|
||||
return attrs
|
||||
}
|
||||
|
||||
fn (mut p Parser) parse_attr() ast.Attr {
|
||||
start_pos := p.prev_tok.position()
|
||||
mut is_if_attr := false
|
||||
if p.tok.kind == .key_if {
|
||||
p.next()
|
||||
@ -663,10 +668,6 @@ fn (mut p Parser) parse_attr() ast.Attr {
|
||||
p.next()
|
||||
}
|
||||
}
|
||||
if name in p.attrs {
|
||||
p.error_with_pos('duplicate attribute `$name`', start_pos.extend(p.tok.position()))
|
||||
}
|
||||
p.attrs << name
|
||||
if is_if_attr {
|
||||
p.attr_ctdefine = name
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
|
||||
*/
|
||||
mut attrs := []string{}
|
||||
if p.tok.kind == .lsbr {
|
||||
parsed_attrs := p.attributes()
|
||||
parsed_attrs := p.attributes(false)
|
||||
for attr in parsed_attrs {
|
||||
attrs << attr.name
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
vlib/v/parser/tests/fn_attributes_duplicate_multiple.v:2:1: error: duplicate attribute `inline`
|
||||
vlib/v/parser/tests/fn_attributes_duplicate_multiple.v:2:2: error: duplicate attribute `inline`
|
||||
1 | [inline]
|
||||
2 | [inline]
|
||||
| ~~~~~~~~
|
||||
| ~~~~~~
|
||||
3 | fn foo() {}
|
||||
4 |
|
||||
|
@ -1,5 +1,5 @@
|
||||
vlib/v/parser/tests/fn_attributes_duplicate_single.v:1:8: error: duplicate attribute `inline`
|
||||
vlib/v/parser/tests/fn_attributes_duplicate_single.v:1:10: error: duplicate attribute `inline`
|
||||
1 | [inline; inline]
|
||||
| ~~~~~~~~~
|
||||
| ~~~~~~
|
||||
2 | fn foo() {}
|
||||
3 |
|
||||
|
Loading…
Reference in New Issue
Block a user