mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
check unused and unmodified vars in all modules, not just main
This commit is contained in:
@ -43,7 +43,7 @@ mut:
|
||||
|
||||
fn new_cgen(out_name_c string) &CGen {
|
||||
path := out_name_c
|
||||
mut out := os.create(path) or {
|
||||
out := os.create(path) or {
|
||||
println('failed to create $path')
|
||||
return &CGen{}
|
||||
}
|
||||
@ -192,7 +192,7 @@ fn (g mut CGen) register_thread_fn(wrapper_name, wrapper_text, struct_text strin
|
||||
}
|
||||
|
||||
fn (v &V) prof_counters() string {
|
||||
mut res := []string
|
||||
res := []string
|
||||
// Global fns
|
||||
//for f in c.table.fns {
|
||||
//res << 'double ${c.table.cgen_name(f)}_time;'
|
||||
@ -212,7 +212,7 @@ fn (v &V) prof_counters() string {
|
||||
}
|
||||
|
||||
fn (p &Parser) print_prof_counters() string {
|
||||
mut res := []string
|
||||
res := []string
|
||||
// Global fns
|
||||
//for f in p.table.fns {
|
||||
//counter := '${p.table.cgen_name(f)}_time'
|
||||
@ -410,10 +410,10 @@ fn (v &V) interface_table() string {
|
||||
sb.writeln('// NR methods = $t.gen_types.len')
|
||||
for i, gen_type in t.gen_types {
|
||||
methods += '{'
|
||||
for i, method in t.methods {
|
||||
for j, method in t.methods {
|
||||
// Cat_speak
|
||||
methods += '${gen_type}_${method.name}'
|
||||
if i < t.methods.len - 1 {
|
||||
if j < t.methods.len - 1 {
|
||||
methods += ', '
|
||||
}
|
||||
}
|
||||
|
@ -213,8 +213,8 @@ fn (s mut Scanner) goto_scanner_position(scp ScannerPos) {
|
||||
s.last_nl_pos = scp.last_nl_pos
|
||||
}
|
||||
|
||||
fn (s mut Scanner) get_last_nl_from_pos(_pos int) int {
|
||||
mut pos := if _pos >= s.text.len { s.text.len-1 } else { _pos }
|
||||
fn (s &Scanner) get_last_nl_from_pos(_pos int) int {
|
||||
pos := if _pos >= s.text.len { s.text.len-1 } else { _pos }
|
||||
for i := pos; i >= 0; i-- {
|
||||
if s.text[i] == `\n` {
|
||||
return i
|
||||
@ -223,7 +223,7 @@ fn (s mut Scanner) get_last_nl_from_pos(_pos int) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
fn (s mut Scanner) get_scanner_pos_of_token(tok &Token) ScannerPos {
|
||||
fn (s &Scanner) get_scanner_pos_of_token(tok &Token) ScannerPos {
|
||||
return ScannerPos{
|
||||
pos: tok.pos
|
||||
line_nr: tok.line_nr
|
||||
|
@ -265,7 +265,7 @@ fn (p mut Parser) comptime_method_call(typ Type) {
|
||||
p.check(.dollar)
|
||||
var := p.check_name()
|
||||
mut j := 0
|
||||
for i, method in typ.methods {
|
||||
for method in typ.methods {
|
||||
if method.typ != 'void' {
|
||||
|
||||
continue
|
||||
|
@ -392,7 +392,7 @@ fn (p mut Parser) expression() string {
|
||||
//p.print_tok()
|
||||
//}
|
||||
ph := p.cgen.add_placeholder()
|
||||
mut typ := p.indot_expr()
|
||||
typ := p.indot_expr()
|
||||
is_str := typ=='string'
|
||||
is_ustr := typ=='ustring'
|
||||
// `a << b` ==> `array_push(&a, b)`
|
||||
|
@ -72,7 +72,7 @@ fn (a []TypeInst) str() string {
|
||||
return r.str()
|
||||
}
|
||||
|
||||
fn (p mut Parser) find_var_or_const(name string) ?Var {
|
||||
fn (p &Parser) find_var_or_const(name string) ?Var {
|
||||
if p.known_var(name) {
|
||||
return p.find_var(name)
|
||||
}
|
||||
@ -150,14 +150,14 @@ fn (p mut Parser) mark_arg_moved(v Var) {
|
||||
p.table.fns[p.cur_fn.name] = p.cur_fn
|
||||
}
|
||||
|
||||
fn (p mut Parser) known_var(name string) bool {
|
||||
fn (p &Parser) known_var(name string) bool {
|
||||
_ = p.find_var(name) or {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
fn (p mut Parser) known_var_check_new_var(name string) bool {
|
||||
fn (p &Parser) known_var_check_new_var(name string) bool {
|
||||
_ = p.find_var_check_new_var(name) or {
|
||||
return false
|
||||
}
|
||||
@ -561,15 +561,18 @@ fn (p mut Parser) fn_decl() {
|
||||
// p.error('unclosed {')
|
||||
}
|
||||
// Make sure all vars in this function are used (only in main for now)
|
||||
/*
|
||||
if p.mod != 'main' {
|
||||
p.genln('}')
|
||||
return
|
||||
}
|
||||
*/
|
||||
p.genln('}')
|
||||
p.check_unused_variables()
|
||||
p.set_current_fn( EmptyFn )
|
||||
if !p.builtin_mod && p.mod != 'os' {
|
||||
p.check_unused_and_mut_vars()
|
||||
}
|
||||
p.set_current_fn(EmptyFn)
|
||||
p.returns = false
|
||||
|
||||
}
|
||||
|
||||
[inline]
|
||||
@ -611,7 +614,7 @@ fn (p &Parser) get_linkage_prefix() string {
|
||||
}
|
||||
}
|
||||
|
||||
fn (p mut Parser) check_unused_variables() {
|
||||
fn (p mut Parser) check_unused_and_mut_vars() {
|
||||
for var in p.local_vars {
|
||||
if var.name == '' {
|
||||
break
|
||||
@ -1365,7 +1368,7 @@ fn (p mut Parser) fn_call_vargs(f Fn) (string, []string) {
|
||||
return '', []string
|
||||
}
|
||||
last_arg := f.args.last()
|
||||
mut varg_def_type := last_arg.typ[3..]
|
||||
//varg_def_type := last_arg.typ[3..]
|
||||
mut types := []string
|
||||
mut values := []string
|
||||
for p.tok != .rpar {
|
||||
@ -1450,7 +1453,7 @@ fn (p mut Parser) dispatch_generic_fn_instance(f mut Fn, ti &TypeInst) {
|
||||
}
|
||||
if !new_inst {
|
||||
rename_generic_fn_instance(mut f, ti)
|
||||
_f := p.table.find_fn(f.name) or {
|
||||
_ = p.table.find_fn(f.name) or {
|
||||
p.error('function instance `$f.name` not found')
|
||||
return
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ fn (p mut Parser) get_type2() Type{
|
||||
mut mul := false
|
||||
mut nr_muls := 0
|
||||
mut typ := ''
|
||||
mut cat := TypeCategory.struct_
|
||||
cat := TypeCategory.struct_
|
||||
// multiple returns
|
||||
if p.tok == .lpar {
|
||||
//p.warn('`()` are no longer necessary in multiple returns' +
|
||||
|
@ -133,7 +133,7 @@ pub mut:
|
||||
}
|
||||
|
||||
// Should be called by main at the end of the compilation process, to cleanup
|
||||
pub fn (v mut V) finalize_compilation(){
|
||||
pub fn (v &V) finalize_compilation(){
|
||||
// TODO remove
|
||||
if v.pref.autofree {
|
||||
/*
|
||||
@ -1184,7 +1184,7 @@ pub fn set_vroot_folder(vroot_path string) {
|
||||
// Preparation for the compiler module:
|
||||
// VEXE env variable is needed so that compiler.vexe_path()
|
||||
// can return it later to whoever needs it:
|
||||
mut vname := if os.user_os() == 'windows' { 'v.exe' } else { 'v' }
|
||||
vname := if os.user_os() == 'windows' { 'v.exe' } else { 'v' }
|
||||
os.setenv('VEXE', os.realpath( [vroot_path, vname].join(os.path_separator) ), true)
|
||||
}
|
||||
|
||||
|
@ -23,8 +23,8 @@ mut:
|
||||
fns strings.Builder
|
||||
types strings.Builder
|
||||
tokens []Token
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// `mod` == "vlib/os"
|
||||
fn generate_vh(mod string) {
|
||||
@ -45,10 +45,10 @@ fn generate_vh(mod string) {
|
||||
out.writeln('module $mod_def\n')
|
||||
// Consts
|
||||
println(full_mod_path)
|
||||
mut vfiles := os.walk_ext(full_mod_path, '.v')
|
||||
vfiles := os.walk_ext(full_mod_path, '.v')
|
||||
//mut vfiles := os.ls(full_mod_path) or {
|
||||
//exit(1)
|
||||
//}
|
||||
//}
|
||||
filtered := vfiles.filter(it.ends_with('.v') && !it.ends_with('test.v') &&
|
||||
!it.ends_with('_windows.v') && !it.ends_with('_win.v') &&
|
||||
!it.ends_with('_lin.v') &&
|
||||
@ -74,20 +74,20 @@ fn generate_vh(mod string) {
|
||||
for ; g.i < p.tokens.len; g.i++ {
|
||||
if !p.tokens[g.i].tok.is_decl() {
|
||||
continue
|
||||
}
|
||||
}
|
||||
match g.tokens[g.i].tok {
|
||||
.key_fn { g.generate_fn() }
|
||||
.key_const { g.generate_const() }
|
||||
.key_struct { g.generate_type() }
|
||||
.key_type { g.generate_alias() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
result :=
|
||||
g.types.str() +
|
||||
g.consts.str() +
|
||||
g.fns.str().replace('\n\n\n', '\n').replace('\n\n', '\n')
|
||||
|
||||
|
||||
out.writeln(result.replace('[ ] ', '[]').replace('? ', '?'))
|
||||
out.close()
|
||||
}
|
||||
@ -95,22 +95,22 @@ fn generate_vh(mod string) {
|
||||
fn (g mut VhGen) generate_fn() {
|
||||
if g.i >= g.tokens.len - 2 {
|
||||
return
|
||||
}
|
||||
}
|
||||
mut next := g.tokens[g.i+1]
|
||||
if g.i > 0 && g.tokens[g.i-1].tok != .key_pub {
|
||||
// Skip private fns
|
||||
//return ''
|
||||
}
|
||||
|
||||
|
||||
if next.tok == .name && next.lit == 'C' {
|
||||
//println('skipping C')
|
||||
return
|
||||
}
|
||||
}
|
||||
//out.write('pub ')
|
||||
mut tok := g.tokens[g.i]
|
||||
for g.i < g.tokens.len - 1 && tok.tok != .lcbr {
|
||||
next = g.tokens[g.i+1]
|
||||
|
||||
|
||||
g.fns.write(tok.str())
|
||||
if tok.tok != .lpar && !(next.tok in [.comma, .rpar]) {
|
||||
// No space after (), [], etc
|
||||
@ -118,10 +118,10 @@ fn (g mut VhGen) generate_fn() {
|
||||
}
|
||||
g.i++
|
||||
tok = g.tokens[g.i]
|
||||
}
|
||||
}
|
||||
g.fns.writeln('')
|
||||
//g.i--
|
||||
}
|
||||
}
|
||||
|
||||
fn (g mut VhGen) generate_alias() {
|
||||
mut tok := g.tokens[g.i]
|
||||
@ -130,7 +130,7 @@ fn (g mut VhGen) generate_alias() {
|
||||
g.types.write(' ')
|
||||
if tok.line_nr != g.tokens[g.i+1].line_nr {
|
||||
break
|
||||
}
|
||||
}
|
||||
g.i++
|
||||
tok = g.tokens[g.i]
|
||||
}
|
||||
@ -145,7 +145,7 @@ fn (g mut VhGen) generate_const() {
|
||||
g.consts.write(' ')
|
||||
if g.tokens[g.i+2].tok == .assign {
|
||||
g.consts.write('\n\t')
|
||||
}
|
||||
}
|
||||
g.i++
|
||||
tok = g.tokens[g.i]
|
||||
}
|
||||
@ -161,7 +161,7 @@ fn (g mut VhGen) generate_type() {
|
||||
g.types.write(' ')
|
||||
if g.tokens[g.i+1].line_nr != g.tokens[g.i].line_nr {
|
||||
g.types.write('\n\t')
|
||||
}
|
||||
}
|
||||
g.i++
|
||||
tok = g.tokens[g.i]
|
||||
}
|
||||
|
@ -282,7 +282,7 @@ fn (p &Parser) log(s string) {
|
||||
*/
|
||||
}
|
||||
|
||||
pub fn (p mut Parser) save_state() ParserState {
|
||||
pub fn (p &Parser) save_state() ParserState {
|
||||
return ParserState{
|
||||
scanner_line_nr: p.scanner.line_nr
|
||||
scanner_text : p.scanner.text
|
||||
@ -1577,7 +1577,7 @@ fn (p mut Parser) var_decl() {
|
||||
p.gen('$var_name = ${p.var_decl_name}.var_$i')
|
||||
continue
|
||||
}
|
||||
// decleration
|
||||
// declaration
|
||||
p.gen('$var_type $var_name = ${p.var_decl_name}.var_$i')
|
||||
}
|
||||
p.register_var(Var {
|
||||
@ -1722,6 +1722,12 @@ fn (p mut Parser) var_expr(v Var) string {
|
||||
// println('var expr is_tmp=$p.cgen.is_tmp\n')
|
||||
if !v.is_const {
|
||||
p.mark_var_used(v)
|
||||
// `C.foo(&var)` means that `var` is changed. Mark it as changed
|
||||
// to avoid `var was declared as mutable but was never changed` errors.
|
||||
if p.calling_c && !v.is_changed {
|
||||
//println('marking C var changed: $v.name')
|
||||
p.mark_var_changed(v)
|
||||
}
|
||||
}
|
||||
fn_ph := p.cgen.add_placeholder()
|
||||
p.expr_var = v
|
||||
@ -1806,10 +1812,10 @@ fn (p mut Parser) dot(str_typ_ string, method_ph int) string {
|
||||
//if p.fileis('orm_test') {
|
||||
//println('ORM dot $str_typ')
|
||||
//}
|
||||
mut str_typ := str_typ_
|
||||
str_typ := str_typ_
|
||||
p.check(.dot)
|
||||
is_variadic_arg := str_typ.starts_with('varg_')
|
||||
mut typ := p.find_type(str_typ)
|
||||
typ := p.find_type(str_typ)
|
||||
if typ.name.len == 0 {
|
||||
p.error('dot(): cannot find type `$str_typ`')
|
||||
}
|
||||
@ -2513,7 +2519,6 @@ fn (p mut Parser) array_init() string {
|
||||
mut typ := ''
|
||||
new_arr_ph := p.cgen.add_placeholder()
|
||||
mut i := 0
|
||||
pos := p.cgen.cur_line.len// remember cur line to fetch first number in cgen for [0; 10]
|
||||
for p.tok != .rsbr {
|
||||
val_typ := p.bool_expression()
|
||||
// Get the type of the first expression
|
||||
@ -3095,7 +3100,7 @@ fn (p mut Parser) check_unused_imports() {
|
||||
p.production_error_with_token_index( 'the following imports were never used: $output', 0 )
|
||||
}
|
||||
|
||||
fn (p mut Parser) is_expr_fn_call(start_tok_idx int) (bool, string) {
|
||||
fn (p &Parser) is_expr_fn_call(start_tok_idx int) (bool, string) {
|
||||
mut expr := p.tokens[start_tok_idx-1].str()
|
||||
mut is_fn_call := p.tokens[start_tok_idx].tok == .lpar
|
||||
if !is_fn_call {
|
||||
|
@ -13,7 +13,7 @@ fn (scanner mut Scanner) fgen(s_ string) {
|
||||
if scanner.fmt_line_empty {
|
||||
s = strings.repeat(`\t`, scanner.fmt_indent) + s
|
||||
}
|
||||
|
||||
|
||||
//scanner.fmt_out << s
|
||||
scanner.fmt_out.write(s)
|
||||
scanner.fmt_line_empty = false
|
||||
@ -42,7 +42,7 @@ fn (scanner mut Scanner) fgen_nl() {
|
||||
fn (p mut Parser) fgen(s string) {
|
||||
if p.pass != .main {
|
||||
return
|
||||
}
|
||||
}
|
||||
p.scanner.fgen(s)
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@ fn (p mut Parser) fgen(s string) {
|
||||
fn (p mut Parser) fspace() {
|
||||
if p.first_pass() {
|
||||
return
|
||||
}
|
||||
}
|
||||
p.fgen(' ')
|
||||
}
|
||||
|
||||
@ -59,7 +59,7 @@ fn (p mut Parser) fspace() {
|
||||
fn (p mut Parser) fgenln(s string) {
|
||||
if p.pass != .main {
|
||||
return
|
||||
}
|
||||
}
|
||||
p.scanner.fgenln(s)
|
||||
}
|
||||
|
||||
@ -67,11 +67,11 @@ fn (p mut Parser) fgenln(s string) {
|
||||
fn (p mut Parser) fgen_nl() {
|
||||
if p.pass != .main {
|
||||
return
|
||||
}
|
||||
}
|
||||
println(p.tok)
|
||||
if p.prev_tok == .line_comment {
|
||||
return
|
||||
}
|
||||
}
|
||||
p.scanner.fgen_nl()
|
||||
}
|
||||
|
||||
@ -92,7 +92,7 @@ fn (p mut Parser) peek() TokenKind {
|
||||
fn (p mut Parser) fmt_inc() {
|
||||
if p.pass != .main {
|
||||
return
|
||||
}
|
||||
}
|
||||
p.scanner.fmt_indent++
|
||||
}
|
||||
|
||||
@ -100,7 +100,7 @@ fn (p mut Parser) fmt_inc() {
|
||||
fn (p mut Parser) fmt_dec() {
|
||||
if p.pass != .main {
|
||||
return
|
||||
}
|
||||
}
|
||||
p.scanner.fmt_indent--
|
||||
}
|
||||
|
||||
@ -121,31 +121,31 @@ fn (p mut Parser) fnext() {
|
||||
if p.tok == .rcbr && !p.inside_if_expr && p.prev_tok != .lcbr {
|
||||
p.fmt_dec()
|
||||
}
|
||||
mut s := p.strtok()
|
||||
s := p.strtok()
|
||||
if p.tok != .eof {
|
||||
p.fgen(s)
|
||||
}
|
||||
// vfmt: increase indentation on `{` unless it's `{}`
|
||||
mut inc_indent := false
|
||||
inc_indent := false
|
||||
if p.tok == .lcbr && !p.inside_if_expr && p.peek() != .rcbr {
|
||||
p.fgen_nl()
|
||||
p.fmt_inc()
|
||||
}
|
||||
|
||||
|
||||
// Skip comments and add them to vfmt output
|
||||
if p.tokens[p.token_idx].tok in [.line_comment, .mline_comment] {
|
||||
// Newline before the comment and after consts and closing }
|
||||
if p.inside_const {
|
||||
p.fgen_nl()
|
||||
p.fgen_nl()
|
||||
}
|
||||
is_rcbr := p.tok == .rcbr
|
||||
}
|
||||
//is_rcbr := p.tok == .rcbr
|
||||
for p.token_idx < p.tokens.len - 1 {
|
||||
i := p.token_idx
|
||||
tok := p.tokens[p.token_idx].tok
|
||||
if tok != .line_comment && tok != .mline_comment {
|
||||
break
|
||||
}
|
||||
}
|
||||
comment_token := p.tokens[p.token_idx]
|
||||
next := p.tokens[p.token_idx+1]
|
||||
comment_on_new_line := p.token_idx == 0 ||
|
||||
@ -155,11 +155,11 @@ fn (p mut Parser) fnext() {
|
||||
if i > 0 && p.tokens[i-1].tok != .line_comment &&
|
||||
comment_token.line_nr > p.tokens[i-1].line_nr {
|
||||
p.fgen_nl()
|
||||
}
|
||||
}
|
||||
if tok == .line_comment {
|
||||
if !comment_on_new_line { //prev_token.line_nr < comment_token.line_nr {
|
||||
p.fgen(' ')
|
||||
}
|
||||
}
|
||||
p.fgen('// ' + comment)
|
||||
/*
|
||||
if false && i > 0 {
|
||||
@ -168,19 +168,19 @@ fn (p mut Parser) fnext() {
|
||||
'line_nr=$comment_token.line_nr next=${next.str()} next_line_nr=$next.line_nr')
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
} else {
|
||||
p.fgen(comment)
|
||||
}
|
||||
}
|
||||
if next.tok == .line_comment && comment_token.line_nr < next.line_nr {
|
||||
p.fgen_nl()
|
||||
}
|
||||
p.token_idx++
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if inc_indent {
|
||||
p.fgen_nl()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -192,13 +192,13 @@ fn (p mut Parser) gen_fmt() {
|
||||
}
|
||||
if p.file_name == '' {
|
||||
return
|
||||
}
|
||||
}
|
||||
//s := p.scanner.fmt_out.str().replace('\n\n\n', '\n').trim_space()
|
||||
s := p.scanner.fmt_out.str().trim_space()
|
||||
//s := p.scanner.fmt_out.join('').trim_space()
|
||||
if s == '' {
|
||||
return
|
||||
}
|
||||
}
|
||||
println('generating ${p.file_name}.v')
|
||||
mut out := os.create('/var/tmp/fmt/' + p.file_name) or {
|
||||
verror('failed to create fmt.v')
|
||||
|
@ -162,7 +162,7 @@ fn (g mut Gen) mov64(reg Register, val i64) {
|
||||
|
||||
fn (g mut Gen) call(addr int) {
|
||||
//rel := g.abs_to_rel_addr(addr)
|
||||
rel := 0xffffffff - int(abs(addr - g.buf.len))-1
|
||||
//rel := 0xffffffff - int(abs(addr - g.buf.len))-1
|
||||
|
||||
println('call addr=$addr rel_addr=$addr pos=$g.buf.len')
|
||||
g.write8(0xe8)
|
||||
|
Reference in New Issue
Block a user