Skip to content

Commit

Permalink
tools.vet: add notice for empty strings conditions
Browse files Browse the repository at this point in the history
  • Loading branch information
ttytm committed May 4, 2024
1 parent 387af74 commit c705dd8
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 0 deletions.
8 changes: 8 additions & 0 deletions cmd/tools/vvet/tests/empty_string.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
cmd/tools/vvet/tests/empty_string.vv:3: notice: Use `foo == ''` instead of `foo.len == 0`
cmd/tools/vvet/tests/empty_string.vv:4: notice: Use `foo != ''` instead of `foo.len != 0`
cmd/tools/vvet/tests/empty_string.vv:5: notice: Use `foo == ''` instead of `foo.len < 1`
cmd/tools/vvet/tests/empty_string.vv:6: notice: Use `foo != ''` instead of `foo.len > 0`
cmd/tools/vvet/tests/empty_string.vv:9: notice: Use `'' == bar` instead of `0 == bar.len`
cmd/tools/vvet/tests/empty_string.vv:10: notice: Use `'' != bar` instead of `0 != bar.len`
cmd/tools/vvet/tests/empty_string.vv:11: notice: Use `'' == bar` instead of `1 > bar.len`
cmd/tools/vvet/tests/empty_string.vv:12: notice: Use `'' != bar` instead of `0 < bar.len`
13 changes: 13 additions & 0 deletions cmd/tools/vvet/tests/empty_string.vv
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
fn main() {
foo := 'foo'
foo.len == 0
foo.len != 0
foo.len < 1
foo.len > 0

bar := 'bar'
0 == bar.len
0 != bar.len
1 > bar.len
0 < bar.len
}
32 changes: 32 additions & 0 deletions cmd/tools/vvet/vvet.v
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ fn (mut vt Vet) expr(expr ast.Expr) {
vt.filtered_lines.assigns(expr.pos)
}
ast.InfixExpr {
vt.vet_empty_str(expr)
vt.expr(expr.right)
}
ast.CallExpr {
Expand All @@ -310,6 +311,37 @@ fn (mut vt Vet) expr(expr ast.Expr) {
}
}

fn (mut vt Vet) vet_empty_str(expr ast.InfixExpr) {
if expr.left is ast.SelectorExpr && expr.right is ast.IntegerLiteral
&& expr.left.field_name == 'len' {
if expr.right.val == '0' && expr.op != .lt {
// TODO: remove as when values can be smart casted.
expr_str := (expr.left as ast.SelectorExpr).expr.str()
op := if expr.op == .gt { '!=' } else { expr.op.str() }
vt.notice("Use `${expr_str} ${op} ''` instead of `${expr_str}.len ${expr.op} 0`",
expr.pos.line_nr, .unknown)
} else if expr.right.val == '1' && expr.op in [.lt, .gt] {
expr_str := (expr.left as ast.SelectorExpr).expr.str()
op := if expr.op == .lt { '==' } else { '!=' }
vt.notice("Use `${expr_str} ${op} ''` instead of `${expr_str}.len ${expr.op} 1`",
expr.pos.line_nr, .unknown)
}
} else if expr.left is ast.IntegerLiteral && expr.right is ast.SelectorExpr
&& expr.right.field_name == 'len' {
if (expr.left as ast.IntegerLiteral).val == '0' && expr.op != .gt {
expr_str := expr.right.expr.str()
op := if expr.op == .lt { '!=' } else { expr.op.str() }
vt.notice("Use `'' ${op} ${expr_str}` instead of `0 ${expr.op} ${expr_str}.len`",
expr.pos.line_nr, .unknown)
} else if (expr.left as ast.IntegerLiteral).val == '1' && expr.op in [.lt, .gt] {
expr_str := expr.right.expr.str()
op := if expr.op == .lt { '!=' } else { '==' }
vt.notice("Use `'' ${op} ${expr_str}` instead of `1 ${expr.op} ${expr_str}.len`",
expr.pos.line_nr, .unknown)
}
}
}

fn (vt &Vet) vprintln(s string) {
if !vt.opt.is_verbose {
return
Expand Down

0 comments on commit c705dd8

Please sign in to comment.