checker: fix ctdefine check in non-main modules (#8332)
							parent
							
								
									cb885d30b4
								
							
						
					
					
						commit
						2b30c48770
					
				| 
						 | 
					@ -148,7 +148,7 @@ pub fn (mut c Checker) check_files(ast_files []ast.File) {
 | 
				
			||||||
		if file.mod.name == 'main' {
 | 
							if file.mod.name == 'main' {
 | 
				
			||||||
			files_from_main_module << file
 | 
								files_from_main_module << file
 | 
				
			||||||
			has_main_mod_file = true
 | 
								has_main_mod_file = true
 | 
				
			||||||
			if c.check_file_in_main(file) {
 | 
								if c.file_has_main_fn(file) {
 | 
				
			||||||
				has_main_fn = true
 | 
									has_main_fn = true
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -205,11 +205,10 @@ pub fn (mut c Checker) check_files(ast_files []ast.File) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// do checks specific to files in main module
 | 
					// do checks specific to files in main module
 | 
				
			||||||
// returns `true` if a main function is in the file
 | 
					// returns `true` if a main function is in the file
 | 
				
			||||||
fn (mut c Checker) check_file_in_main(file ast.File) bool {
 | 
					fn (mut c Checker) file_has_main_fn(file ast.File) bool {
 | 
				
			||||||
	mut has_main_fn := false
 | 
						mut has_main_fn := false
 | 
				
			||||||
	for stmt in file.stmts {
 | 
						for stmt in file.stmts {
 | 
				
			||||||
		match stmt {
 | 
							if stmt is ast.FnDecl {
 | 
				
			||||||
			ast.FnDecl {
 | 
					 | 
				
			||||||
			if stmt.name == 'main.main' {
 | 
								if stmt.name == 'main.main' {
 | 
				
			||||||
				if has_main_fn {
 | 
									if has_main_fn {
 | 
				
			||||||
					c.error('function `main` is already defined', stmt.pos)
 | 
										c.error('function `main` is already defined', stmt.pos)
 | 
				
			||||||
| 
						 | 
					@ -224,27 +223,11 @@ fn (mut c Checker) check_file_in_main(file ast.File) bool {
 | 
				
			||||||
				if stmt.no_body {
 | 
									if stmt.no_body {
 | 
				
			||||||
					c.error('function `main` must declare a body', stmt.pos)
 | 
										c.error('function `main` must declare a body', stmt.pos)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				} else {
 | 
								} else if stmt.attrs.contains('console') {
 | 
				
			||||||
					for attr in stmt.attrs {
 | 
									c.error('only `main` can have the `[console]` attribute', stmt.pos)
 | 
				
			||||||
						if attr.name == 'console' {
 | 
					 | 
				
			||||||
							c.error('only `main` can have the `[console]` attribute',
 | 
					 | 
				
			||||||
								stmt.pos)
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
				if stmt.return_type != table.void_type {
 | 
					 | 
				
			||||||
					for attr in stmt.attrs {
 | 
					 | 
				
			||||||
						if attr.is_ctdefine {
 | 
					 | 
				
			||||||
							c.error('only functions that do NOT return values can have `[if $attr.name]` tags',
 | 
					 | 
				
			||||||
								stmt.pos)
 | 
					 | 
				
			||||||
							break
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			else {}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return has_main_fn
 | 
						return has_main_fn
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5270,6 +5253,15 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
 | 
				
			||||||
	if node.language == .v && !c.is_builtin_mod {
 | 
						if node.language == .v && !c.is_builtin_mod {
 | 
				
			||||||
		c.check_valid_snake_case(node.name, 'function name', node.pos)
 | 
							c.check_valid_snake_case(node.name, 'function name', node.pos)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if node.return_type != table.void_type {
 | 
				
			||||||
 | 
							for attr in node.attrs {
 | 
				
			||||||
 | 
								if attr.is_ctdefine {
 | 
				
			||||||
 | 
									c.error('only functions that do NOT return values can have `[if $attr.name]` tags',
 | 
				
			||||||
 | 
										node.pos)
 | 
				
			||||||
 | 
									break
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if node.is_method {
 | 
						if node.is_method {
 | 
				
			||||||
		mut sym := c.table.get_type_symbol(node.receiver.typ)
 | 
							mut sym := c.table.get_type_symbol(node.receiver.typ)
 | 
				
			||||||
		if sym.kind == .array && !c.is_builtin_mod && node.name == 'map' {
 | 
							if sym.kind == .array && !c.is_builtin_mod && node.name == 'map' {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,12 @@
 | 
				
			||||||
 | 
					vlib/v/checker/tests/ctdefine.vv:4:1: error: only functions that do NOT return values can have `[if test]` tags
 | 
				
			||||||
 | 
					    2 |
 | 
				
			||||||
 | 
					    3 | [if test]
 | 
				
			||||||
 | 
					    4 | fn only_called_in_test() string {
 | 
				
			||||||
 | 
					      | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
				
			||||||
 | 
					    5 |     return 'bah'
 | 
				
			||||||
 | 
					    6 | }
 | 
				
			||||||
 | 
					vlib/v/checker/tests/ctdefine.vv:1:1: error: project must include a `main` module or be a shared library (compile with `v -shared`)
 | 
				
			||||||
 | 
					    1 | module notmain
 | 
				
			||||||
 | 
					      | ^
 | 
				
			||||||
 | 
					    2 |
 | 
				
			||||||
 | 
					    3 | [if test]
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,6 @@
 | 
				
			||||||
 | 
					module notmain
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[if test]
 | 
				
			||||||
 | 
					fn only_called_in_test() string {
 | 
				
			||||||
 | 
						return 'bah'
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue