checker: move struct name check from parser to checker
parent
54a02996f2
commit
04db2d02b8
|
@ -81,6 +81,21 @@ pub fn (c mut Checker) check_files(ast_files []ast.File) {
|
||||||
exit(1)
|
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 {
|
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 {
|
// typ := c.table.find_type(struct_init.typ.typ.name) or {
|
||||||
// c.error('unknown struct: $struct_init.typ.typ.name', struct_init.pos)
|
// 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
|
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')
|
// println('check struct $typ_sym.name')
|
||||||
match typ_sym.kind {
|
match type_sym.kind {
|
||||||
.placeholder {
|
.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
|
// string & array are also structs but .kind of string/array
|
||||||
.struct_, .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
|
is_short_syntax := struct_init.fields.len == 0
|
||||||
if struct_init.exprs.len > info.fields.len {
|
if struct_init.exprs.len > info.fields.len {
|
||||||
c.error('too many fields', struct_init.pos)
|
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 {
|
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)
|
struct_init.pos)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -160,7 +176,7 @@ pub fn (c mut Checker) struct_init(struct_init mut ast.StructInit) table.Type {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if table.type_is_ptr(field.typ) {
|
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)
|
struct_init.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -991,7 +1007,9 @@ fn (c mut Checker) stmt(node ast.Stmt) {
|
||||||
c.returns = true
|
c.returns = true
|
||||||
c.return_stmt(mut it)
|
c.return_stmt(mut it)
|
||||||
}
|
}
|
||||||
// ast.StructDecl {}
|
ast.StructDecl {
|
||||||
|
c.struct_decl(it)
|
||||||
|
}
|
||||||
ast.UnsafeStmt {
|
ast.UnsafeStmt {
|
||||||
c.stmts(it.stmts)
|
c.stmts(it.stmts)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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| }
|
|
@ -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
|
x := p.call_expr(is_c, is_js, mod) // TODO `node,typ :=` should work
|
||||||
node = x
|
node = x
|
||||||
}
|
}
|
||||||
} else if p.peek_tok.kind == .lcbr && (p.tok.lit[0].is_capital() || is_c || is_js || (p.builtin_mod &&
|
} else if p.peek_tok.kind == .lcbr && !p.inside_match && !p.inside_match_case && !p.inside_if &&
|
||||||
p.tok.lit in table.builtin_type_names)) && !p.inside_match && !p.inside_match_case && !p.inside_if &&
|
|
||||||
!p.inside_for {
|
!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
|
return p.struct_init(false) // short_syntax: false
|
||||||
} else if p.peek_tok.kind == .dot && (p.tok.lit[0].is_capital() && !known_var) {
|
} else if p.peek_tok.kind == .dot && (p.tok.lit[0].is_capital() && !known_var) {
|
||||||
// `Color.green`
|
// `Color.green`
|
||||||
|
@ -1546,6 +1543,7 @@ fn (p mut Parser) const_decl() ast.ConstDecl {
|
||||||
|
|
||||||
// structs and unions
|
// structs and unions
|
||||||
fn (p mut Parser) struct_decl() ast.StructDecl {
|
fn (p mut Parser) struct_decl() ast.StructDecl {
|
||||||
|
first_pos := p.tok.position()
|
||||||
is_pub := p.tok.kind == .key_pub
|
is_pub := p.tok.kind == .key_pub
|
||||||
if is_pub {
|
if is_pub {
|
||||||
p.next()
|
p.next()
|
||||||
|
@ -1574,6 +1572,7 @@ fn (p mut Parser) struct_decl() ast.StructDecl {
|
||||||
var mut_pos := -1
|
var mut_pos := -1
|
||||||
var pub_pos := -1
|
var pub_pos := -1
|
||||||
var pub_mut_pos := -1
|
var pub_mut_pos := -1
|
||||||
|
var last_pos := token.Position{}
|
||||||
if !no_body {
|
if !no_body {
|
||||||
p.check(.lcbr)
|
p.check(.lcbr)
|
||||||
for p.tok.kind != .rcbr {
|
for p.tok.kind != .rcbr {
|
||||||
|
@ -1649,6 +1648,7 @@ fn (p mut Parser) struct_decl() ast.StructDecl {
|
||||||
}
|
}
|
||||||
// println('struct field $ti.name $field_name')
|
// println('struct field $ti.name $field_name')
|
||||||
}
|
}
|
||||||
|
last_pos = p.tok.position()
|
||||||
p.check(.rcbr)
|
p.check(.rcbr)
|
||||||
}
|
}
|
||||||
if is_c {
|
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.error('cannot register type `$name`, another type with this name exists')
|
||||||
}
|
}
|
||||||
p.expr_mod = ''
|
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{
|
return ast.StructDecl{
|
||||||
name: name
|
name: name
|
||||||
is_pub: is_pub
|
is_pub: is_pub
|
||||||
fields: ast_fields
|
fields: ast_fields
|
||||||
pos: p.tok.position()
|
pos: pos
|
||||||
mut_pos: mut_pos
|
mut_pos: mut_pos
|
||||||
pub_pos: pub_pos
|
pub_pos: pub_pos
|
||||||
pub_mut_pos: pub_mut_pos
|
pub_mut_pos: pub_mut_pos
|
||||||
|
|
Loading…
Reference in New Issue