v.parser: prohibit registering selectively imported (structs / enums / aliases / interfaces) (#10579)

pull/10597/head
shadowninja55 2021-06-28 03:26:09 -04:00 committed by GitHub
parent 67d1b72e36
commit 830cf4645c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 46 additions and 1 deletions

View File

@ -2962,6 +2962,11 @@ fn (mut p Parser) enum_decl() ast.EnumDecl {
end_pos) end_pos)
return ast.EnumDecl{} return ast.EnumDecl{}
} }
if enum_name in p.imported_symbols {
p.error_with_pos('cannot register enum `$enum_name`, this type was already imported',
end_pos)
return ast.EnumDecl{}
}
name := p.prepend_mod(enum_name) name := p.prepend_mod(enum_name)
p.check(.lcbr) p.check(.lcbr)
enum_decl_comments := p.eat_comments({}) enum_decl_comments := p.eat_comments({})
@ -3059,6 +3064,11 @@ fn (mut p Parser) type_decl() ast.TypeDecl {
decl_pos) decl_pos)
return ast.FnTypeDecl{} return ast.FnTypeDecl{}
} }
if name in p.imported_symbols {
p.error_with_pos('cannot register alias `$name`, this type was already imported',
end_pos)
return ast.AliasTypeDecl{}
}
mut sum_variants := []ast.TypeNode{} mut sum_variants := []ast.TypeNode{}
p.check(.assign) p.check(.assign)
mut type_pos := p.tok.position() mut type_pos := p.tok.position()

View File

@ -73,6 +73,11 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
p.error_with_pos('struct names must have more than one character', name_pos) p.error_with_pos('struct names must have more than one character', name_pos)
return ast.StructDecl{} return ast.StructDecl{}
} }
if name in p.imported_symbols {
p.error_with_pos('cannot register struct `$name`, this type was already imported',
name_pos)
return ast.StructDecl{}
}
mut orig_name := name mut orig_name := name
if language == .c { if language == .c {
name = 'C.$name' name = 'C.$name'
@ -449,10 +454,16 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
} }
name_pos := p.tok.position() name_pos := p.tok.position()
p.check_for_impure_v(language, name_pos) p.check_for_impure_v(language, name_pos)
interface_name := p.prepend_mod(p.check_name()).clone() modless_name := p.check_name()
interface_name := p.prepend_mod(modless_name).clone()
// println('interface decl $interface_name') // println('interface decl $interface_name')
p.check(.lcbr) p.check(.lcbr)
pre_comments := p.eat_comments({}) pre_comments := p.eat_comments({})
if modless_name in p.imported_symbols {
p.error_with_pos('cannot register interface `$interface_name`, this type was already imported',
name_pos)
return ast.InterfaceDecl{}
}
// Declare the type // Declare the type
reg_idx := p.table.register_type_symbol( reg_idx := p.table.register_type_symbol(
is_public: is_pub is_public: is_pub

View File

@ -0,0 +1,4 @@
vlib/v/parser/tests/register_imported_alias.vv:2:6: error: cannot register alias `Duration`, this type was already imported
1 | import time { Duration }
2 | type Duration = bool
| ~~~~~~~~

View File

@ -0,0 +1,2 @@
import time { Duration }
type Duration = bool

View File

@ -0,0 +1,4 @@
vlib/v/parser/tests/register_imported_enum.vv:2:6: error: cannot register enum `Method`, this type was already imported
1 | import net.http { Method }
2 | enum Method { foo bar }
| ~~~~~~

View File

@ -0,0 +1,2 @@
import net.http { Method }
enum Method { foo bar }

View File

@ -0,0 +1,4 @@
vlib/v/parser/tests/register_imported_interface.vv:2:11: error: cannot register interface `Reader`, this type was already imported
1 | import io { Reader }
2 | interface Reader {}
| ~~~~~~

View File

@ -0,0 +1,2 @@
import io { Reader }
interface Reader {}

View File

@ -0,0 +1,4 @@
vlib/v/parser/tests/register_imported_struct.vv:2:8: error: cannot register struct `File`, this type was already imported
1 | import os { File }
2 | struct File {}
| ~~~~

View File

@ -0,0 +1,2 @@
import os { File }
struct File {}