parser: fail when interface name is duplicated (#5828)

pull/5825/head
Enzo 2020-07-14 18:52:51 +02:00 committed by GitHub
parent d301611de7
commit de0b96f52c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 31 additions and 9 deletions

View File

@ -33,11 +33,11 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
p.next() // .
}
is_typedef := 'typedef' in p.attrs
end_pos := p.tok.position()
name_pos := p.tok.position()
mut name := p.check_name()
if name.len == 1 && name[0].is_capital() {
p.error_with_pos('single letter capital names are reserved for generic template types.',
end_pos)
name_pos)
}
mut generic_types := []table.Type{}
if p.tok.kind == .lt {
@ -56,10 +56,10 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
p.error('`$p.tok.lit` lacks body')
}
if language == .v && p.mod != 'builtin' && name.len > 0 && !name[0].is_capital() {
p.error_with_pos('struct name `$name` must begin with capital letter', end_pos)
p.error_with_pos('struct name `$name` must begin with capital letter', name_pos)
}
if name.len == 1 {
p.error_with_pos('struct names must have more than one character', end_pos)
p.error_with_pos('struct names must have more than one character', name_pos)
}
// println('struct decl $name')
mut ast_fields := []ast.StructField{}
@ -246,14 +246,15 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
ret = p.table.register_type_symbol(t)
}
if ret == -1 {
p.error('cannot register type `$name`, another type with this name exists')
p.error_with_pos('cannot register struct `$name`, another type with this name exists',
name_pos)
}
p.expr_mod = ''
return ast.StructDecl{
name: name
is_pub: is_pub
fields: ast_fields
pos: start_pos.extend(end_pos)
pos: start_pos.extend(name_pos)
mut_pos: mut_pos
pub_pos: pub_pos
pub_mut_pos: pub_mut_pos
@ -339,20 +340,25 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
p.next()
}
p.next() // `interface`
name_pos := p.tok.position()
interface_name := p.prepend_mod(p.check_name())
// println('interface decl $interface_name')
p.check(.lcbr)
// Declare the type
t := table.TypeSymbol{
reg_idx := p.table.register_type_symbol(table.TypeSymbol{
kind: .interface_
name: interface_name
mod: p.mod
info: table.Interface{
types: []
}
})
if reg_idx == -1 {
p.error_with_pos('cannot register interface `$interface_name`, another type with this name exists',
name_pos)
}
typ := table.new_type(p.table.register_type_symbol(t))
ts := p.table.get_type_symbol(typ) // TODO t vs ts
typ := table.new_type(reg_idx)
ts := p.table.get_type_symbol(typ)
// Parse methods
mut methods := []ast.FnDecl{}
for p.tok.kind != .rcbr && p.tok.kind != .eof {

View File

@ -0,0 +1,5 @@
vlib/v/parser/tests/duplicate_type_a.v:3:11: error: cannot register interface `Foo`, another type with this name exists
1 | struct Foo {}
2 |
3 | interface Foo {}
| ~~~

View File

@ -0,0 +1,3 @@
struct Foo {}
interface Foo {}

View File

@ -0,0 +1,5 @@
vlib/v/parser/tests/duplicate_type_b.v:3:8: error: cannot register struct `Foo`, another type with this name exists
1 | interface Foo {}
2 |
3 | struct Foo {}
| ~~~

View File

@ -0,0 +1,3 @@
interface Foo {}
struct Foo {}