diff --git a/cmd/tools/preludes/tests_assertions.v b/cmd/tools/preludes/tests_assertions.v index f6769ec4ff..bee5e9a923 100644 --- a/cmd/tools/preludes/tests_assertions.v +++ b/cmd/tools/preludes/tests_assertions.v @@ -1,7 +1,6 @@ module main import os -import term // ////////////////////////////////////////////////////////////////// // / This file will get compiled as part of the main program, // / for a _test.v file. diff --git a/vlib/v/ast/scope.v b/vlib/v/ast/scope.v index 0dbaa9d493..9c3c3e6c63 100644 --- a/vlib/v/ast/scope.v +++ b/vlib/v/ast/scope.v @@ -4,7 +4,6 @@ module ast import v.table -import v.token pub struct Scope { //mut: diff --git a/vlib/v/builder/builder.v b/vlib/v/builder/builder.v index 8dc3ba366d..ca6f32eace 100644 --- a/vlib/v/builder/builder.v +++ b/vlib/v/builder/builder.v @@ -1,7 +1,6 @@ module builder import os -import time import v.ast import v.table import v.pref @@ -9,10 +8,6 @@ import v.util import v.vmod import v.checker import v.parser -import v.errors -import v.gen -import v.gen.js -import v.gen.x64 import v.depgraph const ( diff --git a/vlib/v/builder/compile.v b/vlib/v/builder/compile.v index 769544195e..61d9d34a88 100644 --- a/vlib/v/builder/compile.v +++ b/vlib/v/builder/compile.v @@ -6,8 +6,6 @@ module builder import time import os import v.pref -import v.util -import strings fn get_vtmp_folder() string { vtmp := os.join_path(os.temp_dir(), 'v') diff --git a/vlib/v/builder/x64.v b/vlib/v/builder/x64.v index a49446f8e3..e2cd86802c 100644 --- a/vlib/v/builder/x64.v +++ b/vlib/v/builder/x64.v @@ -1,7 +1,6 @@ module builder import time -import os import v.parser import v.pref import v.gen diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 3618fe73d7..7fec79f1fb 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -4,13 +4,11 @@ module checker import v.ast -import v.depgraph import v.table import v.token import v.pref import v.util import v.errors -import os const ( max_nr_errors = 300 diff --git a/vlib/v/checker/tests/import_not_found_err.vv b/vlib/v/checker/tests/import_not_found_err.vv index fa7ae37441..5e89bde984 100644 --- a/vlib/v/checker/tests/import_not_found_err.vv +++ b/vlib/v/checker/tests/import_not_found_err.vv @@ -1,4 +1,4 @@ import notexist fn main() { - println('hello, world') + println(notexist.name) } diff --git a/vlib/v/checker/tests/import_unused_warning.out b/vlib/v/checker/tests/import_unused_warning.out new file mode 100644 index 0000000000..58ead92609 --- /dev/null +++ b/vlib/v/checker/tests/import_unused_warning.out @@ -0,0 +1,2 @@ +`vlib/v/checker/tests/import_unused_warning.v` warning: the following imports were never used: + * time diff --git a/vlib/v/checker/tests/import_unused_warning.vv b/vlib/v/checker/tests/import_unused_warning.vv new file mode 100644 index 0000000000..1fb573fcd5 --- /dev/null +++ b/vlib/v/checker/tests/import_unused_warning.vv @@ -0,0 +1,4 @@ +import time +fn main() { + println('hello, world') +} diff --git a/vlib/v/gen/cheaders.v b/vlib/v/gen/cheaders.v index 0c1e386ab2..ae5b2e827d 100644 --- a/vlib/v/gen/cheaders.v +++ b/vlib/v/gen/cheaders.v @@ -1,7 +1,5 @@ module gen -import v.util - // NB: @@@ here serve as placeholders. // They will be replaced with correct strings // for each constant, during C code generation. diff --git a/vlib/v/gen/js/js.v b/vlib/v/gen/js/js.v index 6d5d45a157..c459409dba 100644 --- a/vlib/v/gen/js/js.v +++ b/vlib/v/gen/js/js.v @@ -3,8 +3,6 @@ module js import strings import v.ast import v.table -import v.depgraph -import v.token import v.pref import term import v.util diff --git a/vlib/v/gen/live.v b/vlib/v/gen/live.v index 2f307f1c22..f1508c762f 100644 --- a/vlib/v/gen/live.v +++ b/vlib/v/gen/live.v @@ -1,7 +1,5 @@ module gen -import os -import time import v.pref import v.util diff --git a/vlib/v/parser/assign.v b/vlib/v/parser/assign.v index feaba7d22c..fb4c77d3b8 100644 --- a/vlib/v/parser/assign.v +++ b/vlib/v/parser/assign.v @@ -4,8 +4,6 @@ module parser import v.ast -import v.table -import v.token fn (mut p Parser) assign_stmt() ast.Stmt { is_static := p.tok.kind == .key_static diff --git a/vlib/v/parser/for.v b/vlib/v/parser/for.v index 0e3c1194d2..30b0e07275 100644 --- a/vlib/v/parser/for.v +++ b/vlib/v/parser/for.v @@ -5,7 +5,6 @@ module parser import v.ast import v.table -import v.token fn (mut p Parser) for_stmt() ast.Stmt { p.check(.key_for) diff --git a/vlib/v/parser/module.v b/vlib/v/parser/module.v index 6546d0bea1..10c52bce66 100644 --- a/vlib/v/parser/module.v +++ b/vlib/v/parser/module.v @@ -17,3 +17,27 @@ fn (p &Parser) prepend_mod(name string) string { } return '${p.mod}.$name' } + +fn (p &Parser) is_used_import(alias string) bool { + return alias in p.used_imports +} + +fn (mut p Parser) register_used_import(alias string) { + if alias !in p.used_imports { + p.used_imports << alias + } +} + +fn (p mut Parser) check_unused_imports() { + mut output := '' + for alias, mod in p.imports { + if !p.is_used_import(alias) { + mod_alias := if alias == mod { alias } else { '$alias ($mod)' } + output += '\n * $mod_alias' + } + } + if output == '' { + return + } + eprintln('`$p.file_name` warning: the following imports were never used: $output') +} diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v index 931ce51180..58687ec1c9 100644 --- a/vlib/v/parser/parse_type.v +++ b/vlib/v/parser/parse_type.v @@ -23,7 +23,7 @@ pub fn (mut p Parser) parse_array_type() table.Type { // detect attr not_attr := p.peek_tok.kind != .name && p.peek_tok2.kind !in [.semicolon, .rsbr] - + for p.tok.kind == .lsbr && not_attr { p.next() p.check(.rsbr) @@ -146,6 +146,9 @@ pub fn (mut p Parser) parse_any_type(is_c, is_js, is_ptr bool) table.Type { println(p.table.imports) p.error('unknown module `$p.tok.lit`') } + if p.tok.lit in p.imports { + p.register_used_import(p.tok.lit) + } p.next() p.check(.dot) // prefix with full module diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 69fc8e15b6..b92155840e 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -10,7 +10,6 @@ import v.table import v.pref import v.util import v.errors -import term import os pub struct Parser { @@ -38,8 +37,9 @@ mut: expr_mod string // for constructing full type names in parse_type() scope &ast.Scope global_scope &ast.Scope - imports map[string]string - ast_imports []ast.Import + imports map[string]string // alias => mod_name + ast_imports []ast.Import // mod_names + used_imports []string // alias is_amp bool // for generating the right code for `&Foo{}` returns bool inside_match bool // to separate `match A { }` from `Struct{}` @@ -115,6 +115,8 @@ pub fn parse_file(path string, b_table &table.Table, comments_mode scanner.Comme file: p.file_name return_type: table.void_type } + } else { + p.check_unused_imports() } break } @@ -285,6 +287,9 @@ fn (mut p Parser) check(expected token.Kind) { fn (mut p Parser) check_name() string { name := p.tok.lit + if p.peek_tok.kind == .dot && name in p.imports { + p.register_used_import(name) + } p.check(.name) return name } @@ -697,6 +702,9 @@ pub fn (mut p Parser) name_expr() ast.Expr { } else if is_js { mod = 'JS' } else { + if p.tok.lit in p.imports { + p.register_used_import(p.tok.lit) + } // prepend the full import mod = p.imports[p.tok.lit] } diff --git a/vlib/v/pref/default.v b/vlib/v/pref/default.v index f02892ec93..e2888bdeb9 100644 --- a/vlib/v/pref/default.v +++ b/vlib/v/pref/default.v @@ -4,7 +4,6 @@ module pref import os -import term pub const ( default_module_path = mpath()