all: make `os` global in scripts (#5669)
							parent
							
								
									11866fb017
								
							
						
					
					
						commit
						7778cbe9f5
					
				| 
						 | 
				
			
			@ -57,14 +57,17 @@ pub fn new_builder(pref &pref.Preferences) Builder {
 | 
			
		|||
// parse all deps from already parsed files
 | 
			
		||||
pub fn (mut b Builder) parse_imports() {
 | 
			
		||||
	mut done_imports := []string{}
 | 
			
		||||
		if b.pref.is_script {
 | 
			
		||||
			done_imports << 'os'
 | 
			
		||||
		}
 | 
			
		||||
	// NB: b.parsed_files is appended in the loop,
 | 
			
		||||
	// so we can not use the shorter `for in` form.
 | 
			
		||||
	for i := 0; i < b.parsed_files.len; i++ {
 | 
			
		||||
		ast_file := b.parsed_files[i]
 | 
			
		||||
		for _, imp in ast_file.imports {
 | 
			
		||||
		for imp in ast_file.imports {
 | 
			
		||||
			mod := imp.mod
 | 
			
		||||
			if mod == 'builtin' {
 | 
			
		||||
				verror('cannot import module "$mod"')
 | 
			
		||||
				verror('cannot import module "builtin"')
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
			if mod in done_imports {
 | 
			
		||||
| 
						 | 
				
			
			@ -88,7 +91,7 @@ pub fn (mut b Builder) parse_imports() {
 | 
			
		|||
			for file in parsed_files {
 | 
			
		||||
				if file.mod.name != mod {
 | 
			
		||||
					// v.parsers[pidx].error_with_token_index('bad module definition: ${v.parsers[pidx].file_path} imports module "$mod" but $file is defined as module `$p_mod`', 1
 | 
			
		||||
					verror('bad module definition: ${ast_file.path} imports module "$mod" but $file.path is defined as module `$file.mod.name`')
 | 
			
		||||
					verror('bad module definition: $ast_file.path imports module "$mod" but $file.path is defined as module `$file.mod.name`')
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			b.parsed_files << parsed_files
 | 
			
		||||
| 
						 | 
				
			
			@ -109,16 +112,14 @@ pub fn (mut b Builder) resolve_deps() {
 | 
			
		|||
	graph := b.import_graph()
 | 
			
		||||
	deps_resolved := graph.resolve()
 | 
			
		||||
	cycles := deps_resolved.display_cycles()
 | 
			
		||||
	if cycles.len > 1 {
 | 
			
		||||
		eprintln('warning: import cycle detected between the following modules: \n' + cycles)
 | 
			
		||||
		// TODO: error, when v itself does not have v.table -> v.ast -> v.table cycles anymore
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if b.pref.is_verbose {
 | 
			
		||||
		eprintln('------ resolved dependencies graph: ------')
 | 
			
		||||
		eprintln(deps_resolved.display())
 | 
			
		||||
		eprintln('------------------------------------------')
 | 
			
		||||
	}
 | 
			
		||||
	if cycles.len > 1 {
 | 
			
		||||
		verror('error: import cycle detected between the following modules: \n' + cycles)
 | 
			
		||||
	}
 | 
			
		||||
	mut mods := []string{}
 | 
			
		||||
	for node in deps_resolved.nodes {
 | 
			
		||||
		mods << node.name
 | 
			
		||||
| 
						 | 
				
			
			@ -148,8 +149,14 @@ pub fn (b &Builder) import_graph() &depgraph.DepGraph {
 | 
			
		|||
		mut deps := []string{}
 | 
			
		||||
		if p.mod.name !in builtins {
 | 
			
		||||
			deps << 'builtin'
 | 
			
		||||
			if b.pref.backend == .c {
 | 
			
		||||
				// TODO JavaScript backend doesn't handle os for now
 | 
			
		||||
				if b.pref.is_script && p.mod.name != 'os' {
 | 
			
		||||
					deps << 'os'
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		for _, m in p.imports {
 | 
			
		||||
		for m in p.imports {
 | 
			
		||||
			deps << m.mod
 | 
			
		||||
		}
 | 
			
		||||
		graph.add(p.mod.name, deps)
 | 
			
		||||
| 
						 | 
				
			
			@ -200,7 +207,8 @@ pub fn (b Builder) find_module_path(mod, fpath string) ?string {
 | 
			
		|||
	vmod_file_location := mcache.get_by_file(fpath)
 | 
			
		||||
	mod_path := module_path(mod)
 | 
			
		||||
	mut module_lookup_paths := []string{}
 | 
			
		||||
	if vmod_file_location.vmod_file.len != 0 && vmod_file_location.vmod_folder !in b.module_search_paths {
 | 
			
		||||
	if vmod_file_location.vmod_file.len != 0 &&
 | 
			
		||||
		vmod_file_location.vmod_folder !in b.module_search_paths {
 | 
			
		||||
		module_lookup_paths << vmod_file_location.vmod_folder
 | 
			
		||||
	}
 | 
			
		||||
	module_lookup_paths << b.module_search_paths
 | 
			
		||||
| 
						 | 
				
			
			@ -237,7 +245,7 @@ fn (b &Builder) print_warnings_and_errors() {
 | 
			
		|||
			eprintln(ferror)
 | 
			
		||||
			if err.details.len > 0 {
 | 
			
		||||
				eprintln('details: $err.details')
 | 
			
		||||
			}                
 | 
			
		||||
			}
 | 
			
		||||
			// eprintln('')
 | 
			
		||||
			if i > b.max_nr_errors {
 | 
			
		||||
				return
 | 
			
		||||
| 
						 | 
				
			
			@ -255,7 +263,7 @@ fn (b &Builder) print_warnings_and_errors() {
 | 
			
		|||
			eprintln(ferror)
 | 
			
		||||
			if err.details.len > 0 {
 | 
			
		||||
				eprintln('details: $err.details')
 | 
			
		||||
			}                
 | 
			
		||||
			}
 | 
			
		||||
			// eprintln('')
 | 
			
		||||
			if i > b.max_nr_errors {
 | 
			
		||||
				return
 | 
			
		||||
| 
						 | 
				
			
			@ -274,7 +282,7 @@ fn (b &Builder) print_warnings_and_errors() {
 | 
			
		|||
						f := stmt as ast.FnDecl
 | 
			
		||||
						if f.name == fn_name {
 | 
			
		||||
							fline := f.pos.line_nr
 | 
			
		||||
							println('${file.path}:${fline}:')
 | 
			
		||||
							println('$file.path:$fline:')
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,7 +36,7 @@ pub fn compile(command string, pref &pref.Preferences) {
 | 
			
		|||
		.x64 { b.compile_x64() }
 | 
			
		||||
	}
 | 
			
		||||
	if pref.is_stats {
 | 
			
		||||
		println('compilation took: ${sw.elapsed().milliseconds()} ms')
 | 
			
		||||
		println('compilation took: $sw.elapsed().milliseconds() ms')
 | 
			
		||||
	}
 | 
			
		||||
	// running does not require the parsers anymore
 | 
			
		||||
	b.myfree()
 | 
			
		||||
| 
						 | 
				
			
			@ -59,9 +59,7 @@ fn (mut b Builder) run_compiled_executable_and_exit() {
 | 
			
		|||
	if b.pref.is_verbose {
 | 
			
		||||
		println('============ running $b.pref.out_name ============')
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	mut cmd := '"${b.pref.out_name}"'
 | 
			
		||||
	
 | 
			
		||||
	mut cmd := '"$b.pref.out_name"'
 | 
			
		||||
	if b.pref.backend == .js {
 | 
			
		||||
		cmd = 'node "${b.pref.out_name}.js"'
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -138,16 +136,23 @@ pub fn (v Builder) get_builtin_files() []string {
 | 
			
		|||
	// Lookup for built-in folder in lookup path.
 | 
			
		||||
	// Assumption: `builtin/` folder implies usable implementation of builtin
 | 
			
		||||
	for location in v.pref.lookup_path {
 | 
			
		||||
		if !os.exists(os.join_path(location, 'builtin')) {
 | 
			
		||||
			continue
 | 
			
		||||
		if os.exists(os.join_path(location, 'builtin')) {
 | 
			
		||||
			mut builtin_files := []string{}
 | 
			
		||||
			if v.pref.is_bare {
 | 
			
		||||
				builtin_files << v.v_files_from_dir(os.join_path(location, 'builtin', 'bare'))
 | 
			
		||||
			} else if v.pref.backend == .js {
 | 
			
		||||
				builtin_files << v.v_files_from_dir(os.join_path(location, 'builtin', 'js'))
 | 
			
		||||
			} else {
 | 
			
		||||
				builtin_files << v.v_files_from_dir(os.join_path(location, 'builtin'))
 | 
			
		||||
			}
 | 
			
		||||
			if v.pref.backend == .c {
 | 
			
		||||
				// TODO JavaScript backend doesn't handle os for now
 | 
			
		||||
				if v.pref.is_script && os.exists(os.join_path(location, 'os')) {
 | 
			
		||||
					builtin_files << v.v_files_from_dir(os.join_path(location, 'os'))
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			return builtin_files
 | 
			
		||||
		}
 | 
			
		||||
		if v.pref.is_bare {
 | 
			
		||||
			return v.v_files_from_dir(os.join_path(location, 'builtin', 'bare'))
 | 
			
		||||
		}
 | 
			
		||||
		if v.pref.backend == .js {
 | 
			
		||||
			return v.v_files_from_dir(os.join_path(location, 'builtin', 'js'))
 | 
			
		||||
		}
 | 
			
		||||
		return v.v_files_from_dir(os.join_path(location, 'builtin'))
 | 
			
		||||
	}
 | 
			
		||||
	// Panic. We couldn't find the folder.
 | 
			
		||||
	verror('`builtin/` not included on module lookup path.
 | 
			
		||||
| 
						 | 
				
			
			@ -159,7 +164,7 @@ pub fn (v Builder) get_user_files() []string {
 | 
			
		|||
	if v.pref.path == 'vlib/builtin' {
 | 
			
		||||
		// get_builtin_files() has already added the builtin files:
 | 
			
		||||
		return []
 | 
			
		||||
	}        
 | 
			
		||||
	}
 | 
			
		||||
	mut dir := v.pref.path
 | 
			
		||||
	v.log('get_v_files($dir)')
 | 
			
		||||
	// Need to store user files separately, because they have to be added after
 | 
			
		||||
| 
						 | 
				
			
			@ -227,11 +232,11 @@ pub fn (v Builder) get_user_files() []string {
 | 
			
		|||
		// Just compile one file and get parent dir
 | 
			
		||||
		user_files << single_v_file
 | 
			
		||||
		if v.pref.is_verbose {
 | 
			
		||||
			v.log('> just compile one file: "${single_v_file}"')
 | 
			
		||||
			v.log('> just compile one file: "$single_v_file"')
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		if v.pref.is_verbose {
 | 
			
		||||
			v.log('> add all .v files from directory "${dir}" ...')
 | 
			
		||||
			v.log('> add all .v files from directory "$dir" ...')
 | 
			
		||||
		}
 | 
			
		||||
		// Add .v files from the directory being compiled
 | 
			
		||||
		user_files << v.v_files_from_dir(dir)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1021,6 +1021,14 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type {
 | 
			
		|||
			f = f1
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if c.pref.is_script && !found {
 | 
			
		||||
		os_name := 'os.$fn_name'
 | 
			
		||||
		if f1 := c.table.find_fn(os_name) {
 | 
			
		||||
			call_expr.name = os_name
 | 
			
		||||
			found = true
 | 
			
		||||
			f = f1
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// check for arg (var) of fn type
 | 
			
		||||
	if !found {
 | 
			
		||||
		scope := c.file.scope.innermost(call_expr.pos.pos)
 | 
			
		||||
| 
						 | 
				
			
			@ -1181,7 +1189,6 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type {
 | 
			
		|||
			return true
 | 
			
		||||
		}
 | 
			
		||||
		*/
 | 
			
		||||
 | 
			
		||||
		if !c.check_types(typ, arg.typ) {
 | 
			
		||||
			// str method, allow type with str method if fn arg is string
 | 
			
		||||
			if arg_typ_sym.kind == .string && typ_sym.has_method('str') {
 | 
			
		||||
| 
						 | 
				
			
			@ -2835,9 +2842,9 @@ fn (mut c Checker) warn_or_error(message string, pos token.Position, warn bool)
 | 
			
		|||
	// print_backtrace()
 | 
			
		||||
	// }
 | 
			
		||||
	mut details := ''
 | 
			
		||||
	if c.error_details.len > 0 { 
 | 
			
		||||
	if c.error_details.len > 0 {
 | 
			
		||||
		details = c.error_details.join('\n')
 | 
			
		||||
		c.error_details = []        
 | 
			
		||||
		c.error_details = []
 | 
			
		||||
	}
 | 
			
		||||
	if warn && !c.pref.skip_warnings {
 | 
			
		||||
		c.nr_warnings++
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -115,13 +115,15 @@ pub fn parse_file(path string, b_table &table.Table, comments_mode scanner.Comme
 | 
			
		|||
		global_scope: global_scope
 | 
			
		||||
	}
 | 
			
		||||
	if pref.is_vet && p.scanner.text.contains('\n        ') {
 | 
			
		||||
		source_lines := os.read_lines(path) or { []string{} }
 | 
			
		||||
		source_lines := os.read_lines(path) or {
 | 
			
		||||
			[]string{}
 | 
			
		||||
		}
 | 
			
		||||
		for lnumber, line in source_lines {
 | 
			
		||||
			if line.starts_with('        ') {
 | 
			
		||||
				eprintln('${p.scanner.file_path}:${lnumber+1}: Looks like you are using spaces for indentation.')
 | 
			
		||||
				eprintln('$p.scanner.file_path:${lnumber+1}: Looks like you are using spaces for indentation.')
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		eprintln('NB: You can run `v fmt -w file.v` to fix these automatically')        
 | 
			
		||||
		eprintln('NB: You can run `v fmt -w file.v` to fix these automatically')
 | 
			
		||||
		exit(1)
 | 
			
		||||
	}
 | 
			
		||||
	return p.parse()
 | 
			
		||||
| 
						 | 
				
			
			@ -598,7 +600,7 @@ pub fn (mut p Parser) stmt(is_top_level bool) ast.Stmt {
 | 
			
		|||
			p.error_with_pos('const can only be defined at the top level (outside of functions)',
 | 
			
		||||
				p.tok.position())
 | 
			
		||||
		}
 | 
			
		||||
			// literals, 'if', etc. in here
 | 
			
		||||
		// literals, 'if', etc. in here
 | 
			
		||||
		else {
 | 
			
		||||
			return p.parse_multi_expr(is_top_level)
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue