Skip to content

Commit bc75918

Browse files
mvdandominikh
authored andcommitted
simple: reverse "len(x) > 0" as "len(x) == 0"
Rather than "len(x) <= 0", which is technically correct, but not actually what most Go programmers would write, since funcs like len or cap can never return negative integers. Do the same for cap and copy, which never return negative ints either. Fixes #1422.
1 parent ddee6bb commit bc75918

File tree

2 files changed

+17
-3
lines changed

2 files changed

+17
-3
lines changed

simple/lint.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ func CheckIfReturn(pass *analysis.Pass) (interface{}, error) {
546546
cond := m1.State["cond"].(ast.Expr)
547547
origCond := cond
548548
if ret1.Name == "false" {
549-
cond = negate(cond)
549+
cond = negate(pass, cond)
550550
}
551551
report.Report(pass, n1,
552552
fmt.Sprintf("should use 'return %s' instead of 'if %s { return %s }; return %s'",
@@ -558,7 +558,7 @@ func CheckIfReturn(pass *analysis.Pass) (interface{}, error) {
558558
return nil, nil
559559
}
560560

561-
func negate(expr ast.Expr) ast.Expr {
561+
func negate(pass *analysis.Pass, expr ast.Expr) ast.Expr {
562562
switch expr := expr.(type) {
563563
case *ast.BinaryExpr:
564564
out := *expr
@@ -568,7 +568,14 @@ func negate(expr ast.Expr) ast.Expr {
568568
case token.LSS:
569569
out.Op = token.GEQ
570570
case token.GTR:
571-
out.Op = token.LEQ
571+
// Some builtins never return negative ints; "len(x) <= 0" should be "len(x) == 0".
572+
if call, ok := expr.X.(*ast.CallExpr); ok &&
573+
code.IsCallToAny(pass, call, "len", "cap", "copy") &&
574+
code.IsIntegerLiteral(pass, expr.Y, constant.MakeInt64(0)) {
575+
out.Op = token.EQL
576+
} else {
577+
out.Op = token.LEQ
578+
}
572579
case token.NEQ:
573580
out.Op = token.EQL
574581
case token.LEQ:

simple/testdata/src/example.com/CheckIfReturn/if-return.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,3 +153,10 @@ func fn21(x bool) bool {
153153
}
154154
return false
155155
}
156+
157+
func fn22(x string) bool {
158+
if len(x) > 0 { //@ diag(`should use 'return len(x) == 0'`)
159+
return false
160+
}
161+
return true
162+
}

0 commit comments

Comments
 (0)