v.parser: prohibit redeclaration of builtin types (#10563)

pull/10569/head
shadowninja55 2021-06-25 06:08:56 -04:00 committed by GitHub
parent e9de30373f
commit be8be3d319
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 59 additions and 34 deletions

View File

@ -85,18 +85,22 @@ fn on_error(receiver voidptr, e &Error, work &Work) {
```v oksyntax ```v oksyntax
module main module main
import eventbus
const eb = eventbus.new()
struct Work { struct Work {
hours int hours int
} }
struct Error { struct AnError {
message string message string
} }
fn do_work() { fn do_work() {
work := Work{20} work := Work{20}
// get a mutable Params instance & put some data into it // get a mutable Params instance & put some data into it
error := &Error{'Error: no internet connection.'} error := &AnError{'Error: no internet connection.'}
// publish the event // publish the event
eb.publish('error', work, error) eb.publish('error', work, error)
} }

View File

@ -542,44 +542,61 @@ pub fn (t &Table) unalias_num_type(typ Type) Type {
return typ return typ
} }
[inline] fn (mut t Table) check_for_already_registered_symbol(typ TypeSymbol, existing_idx int) int {
pub fn (mut t Table) register_type_symbol(typ TypeSymbol) int { ex_type := t.type_symbols[existing_idx]
// println('register_type_symbol( $typ.name )') match ex_type.kind {
existing_idx := t.type_idxs[typ.name] .placeholder {
if existing_idx > 0 { // override placeholder
ex_type := t.type_symbols[existing_idx] // println('overriding type placeholder `$typ.name`')
match ex_type.kind { t.type_symbols[existing_idx] = {
.placeholder { ...typ
// override placeholder methods: ex_type.methods
// println('overriding type placeholder `$typ.name`') }
t.type_symbols[existing_idx] = { return existing_idx
...typ }
methods: ex_type.methods else {
// builtin
// this will override the already registered builtin types
// with the actual v struct declaration in the source
if (existing_idx >= string_type_idx && existing_idx <= map_type_idx)
|| existing_idx == error_type_idx {
if existing_idx == string_type_idx {
// existing_type := t.type_symbols[existing_idx]
t.type_symbols[existing_idx] = TypeSymbol{
...typ
kind: ex_type.kind
}
} else {
t.type_symbols[existing_idx] = typ
} }
return existing_idx return existing_idx
} }
else { return -1
// builtin }
// this will override the already registered builtin types }
// with the actual v struct declaration in the source return -2
if (existing_idx >= string_type_idx && existing_idx <= map_type_idx) }
|| existing_idx == error_type_idx {
if existing_idx == string_type_idx { [inline]
// existing_type := t.type_symbols[existing_idx] pub fn (mut t Table) register_type_symbol(typ TypeSymbol) int {
t.type_symbols[existing_idx] = TypeSymbol{ mut typ_idx := -2
...typ mut existing_idx := t.type_idxs[typ.name]
kind: ex_type.kind if existing_idx > 0 {
} typ_idx = t.check_for_already_registered_symbol(typ, existing_idx)
} else { if typ_idx != -2 {
t.type_symbols[existing_idx] = typ return typ_idx
} }
return existing_idx }
} if typ.mod == 'main' {
return -1 existing_idx = t.type_idxs[typ.name.trim_prefix('main.')]
if existing_idx > 0 {
typ_idx = t.check_for_already_registered_symbol(typ, existing_idx)
if typ_idx != -2 {
return typ_idx
} }
} }
} }
typ_idx := t.type_symbols.len typ_idx = t.type_symbols.len
t.type_symbols << typ t.type_symbols << typ
t.type_idxs[typ.name] = typ_idx t.type_idxs[typ.name] = typ_idx
return typ_idx return typ_idx

View File

@ -0,0 +1,3 @@
vlib/v/parser/tests/prohibit_redeclaration_of_builtin_types.vv:1:8: error: cannot register struct `Option`, another type with this name exists
1 | struct Option {}
| ~~~~~~

View File

@ -0,0 +1 @@
struct Option {}