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)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
			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