mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: move struct name check from parser to checker
This commit is contained in:
parent
54a02996f2
commit
04db2d02b8
@ -81,6 +81,21 @@ pub fn (c mut Checker) check_files(ast_files []ast.File) {
|
||||
exit(1)
|
||||
}
|
||||
|
||||
pub fn (c mut Checker) struct_decl(decl ast.StructDecl) {
|
||||
splitted_full_name := decl.name.split('.')
|
||||
is_builtin := splitted_full_name[0] == 'builtin'
|
||||
name := splitted_full_name.last()
|
||||
if !name[0].is_capital() && !decl.is_c && !is_builtin && name !in table.builtin_type_names {
|
||||
pos := token.Position{
|
||||
line_nr: decl.pos.line_nr
|
||||
pos: decl.pos.pos + 7
|
||||
len: name.len
|
||||
}
|
||||
c.error('struct name must begin with capital letter', pos)
|
||||
}
|
||||
// && (p.tok.lit[0].is_capital() || is_c || (p.builtin_mod && Sp.tok.lit in table.builtin_type_names))
|
||||
}
|
||||
|
||||
pub fn (c mut Checker) struct_init(struct_init mut ast.StructInit) table.Type {
|
||||
// typ := c.table.find_type(struct_init.typ.typ.name) or {
|
||||
// c.error('unknown struct: $struct_init.typ.typ.name', struct_init.pos)
|
||||
@ -94,15 +109,16 @@ pub fn (c mut Checker) struct_init(struct_init mut ast.StructInit) table.Type {
|
||||
}
|
||||
struct_init.typ = c.expected_type
|
||||
}
|
||||
typ_sym := c.table.get_type_symbol(struct_init.typ)
|
||||
type_sym := c.table.get_type_symbol(struct_init.typ)
|
||||
|
||||
// println('check struct $typ_sym.name')
|
||||
match typ_sym.kind {
|
||||
match type_sym.kind {
|
||||
.placeholder {
|
||||
c.error('unknown struct: $typ_sym.name', struct_init.pos)
|
||||
c.error('unknown struct: $type_sym.name', struct_init.pos)
|
||||
}
|
||||
// string & array are also structs but .kind of string/array
|
||||
.struct_, .string, .array {
|
||||
info := typ_sym.info as table.Struct
|
||||
info := type_sym.info as table.Struct
|
||||
is_short_syntax := struct_init.fields.len == 0
|
||||
if struct_init.exprs.len > info.fields.len {
|
||||
c.error('too many fields', struct_init.pos)
|
||||
@ -138,7 +154,7 @@ pub fn (c mut Checker) struct_init(struct_init mut ast.StructInit) table.Type {
|
||||
}
|
||||
}
|
||||
if !found_field {
|
||||
c.error('struct init: no such field `$field_name` for struct `$typ_sym.name`',
|
||||
c.error('struct init: no such field `$field_name` for struct `$type_sym.name`',
|
||||
struct_init.pos)
|
||||
continue
|
||||
}
|
||||
@ -160,7 +176,7 @@ pub fn (c mut Checker) struct_init(struct_init mut ast.StructInit) table.Type {
|
||||
continue
|
||||
}
|
||||
if table.type_is_ptr(field.typ) {
|
||||
c.warn('reference field `${typ_sym.name}.${field.name}` must be initialized',
|
||||
c.warn('reference field `${type_sym.name}.${field.name}` must be initialized',
|
||||
struct_init.pos)
|
||||
}
|
||||
}
|
||||
@ -991,7 +1007,9 @@ fn (c mut Checker) stmt(node ast.Stmt) {
|
||||
c.returns = true
|
||||
c.return_stmt(mut it)
|
||||
}
|
||||
// ast.StructDecl {}
|
||||
ast.StructDecl {
|
||||
c.struct_decl(it)
|
||||
}
|
||||
ast.UnsafeStmt {
|
||||
c.stmts(it.stmts)
|
||||
}
|
||||
|
5
vlib/v/checker/tests/inout/struct_name.out
Normal file
5
vlib/v/checker/tests/inout/struct_name.out
Normal file
@ -0,0 +1,5 @@
|
||||
vlib/v/checker/tests/inout/struct_name.v:1:8: error: struct name must begin with capital letter
|
||||
1| struct abc {
|
||||
~~~
|
||||
2|
|
||||
3| }
|
3
vlib/v/checker/tests/inout/struct_name.vv
Normal file
3
vlib/v/checker/tests/inout/struct_name.vv
Normal file
@ -0,0 +1,3 @@
|
||||
struct abc {
|
||||
|
||||
}
|
@ -696,11 +696,8 @@ pub fn (p mut Parser) name_expr() ast.Expr {
|
||||
x := p.call_expr(is_c, is_js, mod) // TODO `node,typ :=` should work
|
||||
node = x
|
||||
}
|
||||
} else if p.peek_tok.kind == .lcbr && (p.tok.lit[0].is_capital() || is_c || is_js || (p.builtin_mod &&
|
||||
p.tok.lit in table.builtin_type_names)) && !p.inside_match && !p.inside_match_case && !p.inside_if &&
|
||||
} else if p.peek_tok.kind == .lcbr && !p.inside_match && !p.inside_match_case && !p.inside_if &&
|
||||
!p.inside_for {
|
||||
// (p.tok.lit.len in [1, 2] || !p.tok.lit[p.tok.lit.len - 1].is_capital()) &&
|
||||
// || p.table.known_type(p.tok.lit)) {
|
||||
return p.struct_init(false) // short_syntax: false
|
||||
} else if p.peek_tok.kind == .dot && (p.tok.lit[0].is_capital() && !known_var) {
|
||||
// `Color.green`
|
||||
@ -1546,6 +1543,7 @@ fn (p mut Parser) const_decl() ast.ConstDecl {
|
||||
|
||||
// structs and unions
|
||||
fn (p mut Parser) struct_decl() ast.StructDecl {
|
||||
first_pos := p.tok.position()
|
||||
is_pub := p.tok.kind == .key_pub
|
||||
if is_pub {
|
||||
p.next()
|
||||
@ -1574,6 +1572,7 @@ fn (p mut Parser) struct_decl() ast.StructDecl {
|
||||
var mut_pos := -1
|
||||
var pub_pos := -1
|
||||
var pub_mut_pos := -1
|
||||
var last_pos := token.Position{}
|
||||
if !no_body {
|
||||
p.check(.lcbr)
|
||||
for p.tok.kind != .rcbr {
|
||||
@ -1649,6 +1648,7 @@ fn (p mut Parser) struct_decl() ast.StructDecl {
|
||||
}
|
||||
// println('struct field $ti.name $field_name')
|
||||
}
|
||||
last_pos = p.tok.position()
|
||||
p.check(.rcbr)
|
||||
}
|
||||
if is_c {
|
||||
@ -1679,11 +1679,16 @@ fn (p mut Parser) struct_decl() ast.StructDecl {
|
||||
p.error('cannot register type `$name`, another type with this name exists')
|
||||
}
|
||||
p.expr_mod = ''
|
||||
pos := token.Position{
|
||||
line_nr: first_pos.line_nr
|
||||
pos: first_pos.pos
|
||||
len: last_pos.pos - first_pos.pos + last_pos.len
|
||||
}
|
||||
return ast.StructDecl{
|
||||
name: name
|
||||
is_pub: is_pub
|
||||
fields: ast_fields
|
||||
pos: p.tok.position()
|
||||
pos: pos
|
||||
mut_pos: mut_pos
|
||||
pub_pos: pub_pos
|
||||
pub_mut_pos: pub_mut_pos
|
||||
|
Loading…
Reference in New Issue
Block a user