diff --git a/makezero/makezero.go b/makezero/makezero.go index 18bcad3..d4328a5 100644 --- a/makezero/makezero.go +++ b/makezero/makezero.go @@ -199,8 +199,7 @@ func (v *visitor) isSlice(node ast.Node) bool { obj := ident.Obj if obj == nil { if v.info != nil { - _, ok := v.info.ObjectOf(ident).Type().(*types.Slice) - return ok + return v.isSliceType(v.info.ObjectOf(ident).Type()) } return false } @@ -211,12 +210,28 @@ func (v *visitor) isSlice(node ast.Node) bool { node = spec.Type } + // handle imported types (e.g., types.S) + if sel, ok := node.(*ast.SelectorExpr); ok { + if v.info != nil { + return v.isSliceType(v.info.ObjectOf(sel.Sel).Type()) + } + return false + } + if node, ok := node.(*ast.ArrayType); ok { return node.Len == nil // only slices have zero length } return false } +func (v *visitor) isSliceType(t types.Type) bool { + if t == nil { + return false + } + _, ok := t.Underlying().(*types.Slice) + return ok +} + func (v *visitor) hasNoLintOnSameLine(node ast.Node) bool { nolint := regexp.MustCompile(`^\s*nozero\b`) nodePos := v.fset.Position(node.Pos()) diff --git a/pkg/analyzer/analyzer_test.go b/pkg/analyzer/analyzer_test.go index 490615e..d3c2a20 100644 --- a/pkg/analyzer/analyzer_test.go +++ b/pkg/analyzer/analyzer_test.go @@ -10,7 +10,7 @@ import ( func TestAppend(t *testing.T) { testdata := analysistest.TestData() a := analyzer.NewAnalyzer() - analysistest.Run(t, testdata, a, "./append") + analysistest.Run(t, testdata, a, "./src/append") } func TestAlways(t *testing.T) { @@ -20,5 +20,5 @@ func TestAlways(t *testing.T) { if err != nil { t.Fatalf("expected no error but got %q", err) } - analysistest.Run(t, testdata, a, "./always") + analysistest.Run(t, testdata, a, "./src/always") } diff --git a/pkg/analyzer/testdata/always/append.go b/pkg/analyzer/testdata/always/append.go deleted file mode 100644 index a0ecc6b..0000000 --- a/pkg/analyzer/testdata/always/append.go +++ /dev/null @@ -1,8 +0,0 @@ -package always - -import "fmt" - -func Foo() { - x := make([]int, 5) // want "slice `x` does not have non-zero initial length" - fmt.Println(x) -} diff --git a/pkg/analyzer/testdata/append/append.go b/pkg/analyzer/testdata/append/append.go deleted file mode 100644 index 1437742..0000000 --- a/pkg/analyzer/testdata/append/append.go +++ /dev/null @@ -1,9 +0,0 @@ -package append - -import "fmt" - -func Foo() { - x := make([]int, 5) - x = append(x, 1) // want "append to slice `x` with non-zero initialized length" - fmt.Println(x) -} diff --git a/pkg/analyzer/testdata/src/always/append.go b/pkg/analyzer/testdata/src/always/append.go new file mode 100644 index 0000000..73c37fc --- /dev/null +++ b/pkg/analyzer/testdata/src/always/append.go @@ -0,0 +1,22 @@ +package always + +import ( + "fmt" + "typespkg" +) + +func Foo() { + x := make([]int, 5) // want "slice `x` does not have non-zero initial length" + fmt.Println(x) +} + +func Bar() { + x := make(typespkg.S, 10) // want "slice `x` does not have non-zero initial length" + x = append(x, "...") // want "append to slice `x` with non-zero initialized length" + fmt.Println(x) +} + +func Baz() { + x := make(typespkg.M, 10) + fmt.Println(x) +} diff --git a/pkg/analyzer/testdata/src/append/append.go b/pkg/analyzer/testdata/src/append/append.go new file mode 100644 index 0000000..cfbd2b8 --- /dev/null +++ b/pkg/analyzer/testdata/src/append/append.go @@ -0,0 +1,23 @@ +package append + +import ( + "fmt" + "typespkg" +) + +func Foo() { + x := make([]int, 5) + x = append(x, 1) // want "append to slice `x` with non-zero initialized length" + fmt.Println(x) +} + +func Bar() { + x := make(typespkg.S, 10) + x = append(x, "...") // want "append to slice `x` with non-zero initialized length" + fmt.Println(x) +} + +func Baz() { + x := make(typespkg.M, 10) + fmt.Println(x) +} diff --git a/pkg/analyzer/testdata/src/typespkg/typespkg.go b/pkg/analyzer/testdata/src/typespkg/typespkg.go new file mode 100644 index 0000000..ce8058a --- /dev/null +++ b/pkg/analyzer/testdata/src/typespkg/typespkg.go @@ -0,0 +1,6 @@ +package typespkg + +type ( + S []string + M map[string]int +)