Recommend replacing "x := make([]T, 0)" with "var x []T".
The former is almost always pointless (it's often used immediately
before appending to x), and mainly due to a new Go programmer not
knowing that the zero value of a slice is equally good.
diff --git a/lint.go b/lint.go
index ca24383..80db56e 100644
--- a/lint.go
+++ b/lint.go
@@ -87,6 +87,7 @@
f.lintErrorStrings()
f.lintReceiverNames()
f.lintIncDec()
+ f.lintMake()
return f.problems
}
@@ -886,6 +887,35 @@
})
}
+// lineMake examines statements that declare and initialize a variable with make.
+// It complains if they are constructing a zero element slice.
+func (f *file) lintMake() {
+ f.walk(func(n ast.Node) bool {
+ as, ok := n.(*ast.AssignStmt)
+ if !ok {
+ return true
+ }
+ // Only want single var := assignment statements.
+ if len(as.Lhs) != 1 || as.Tok != token.DEFINE {
+ return true
+ }
+ ce, ok := as.Rhs[0].(*ast.CallExpr)
+ if !ok {
+ return true
+ }
+ // Check if ce is make([]T, 0).
+ if !isIdent(ce.Fun, "make") || len(ce.Args) != 2 || !isZero(ce.Args[1]) {
+ return true
+ }
+ at, ok := ce.Args[0].(*ast.ArrayType)
+ if !ok || at.Len != nil {
+ return true
+ }
+ f.errorf(as, 0.8, "", `can probably use "var %s %s" instead`, f.render(as.Lhs[0]), f.render(at))
+ return true
+ })
+}
+
func receiverType(fn *ast.FuncDecl) string {
switch e := fn.Recv.List[0].Type.(type) {
case *ast.Ident:
@@ -941,6 +971,11 @@
return ok && isIdent(sel.X, pkg) && isIdent(sel.Sel, name)
}
+func isZero(expr ast.Expr) bool {
+ lit, ok := expr.(*ast.BasicLit)
+ return ok && lit.Kind == token.INT && lit.Value == "0"
+}
+
func isOne(expr ast.Expr) bool {
lit, ok := expr.(*ast.BasicLit)
return ok && lit.Kind == token.INT && lit.Value == "1"
diff --git a/testdata/make.go b/testdata/make.go
new file mode 100644
index 0000000..5211375
--- /dev/null
+++ b/testdata/make.go
@@ -0,0 +1,10 @@
+// Test for pointless make() calls.
+
+// Package pkg ...
+package pkg
+
+func f() {
+ x := make([]T, 0) // MATCH /var x \[\]T/
+ y := make([]somepkg.Foo_Bar, 0) // MATCH /var y \[\]somepkg.Foo_Bar/
+ z = make([]T, 0) // ok, because we don't know where z is declared
+}