diff --git a/sliceinitiallength/slicemutation.go b/sliceinitiallength/slicemutation.go index 994dccc..d996eea 100644 --- a/sliceinitiallength/slicemutation.go +++ b/sliceinitiallength/slicemutation.go @@ -2,6 +2,7 @@ package sliceinitiallength import ( "go/ast" + "go/token" "go/types" "github.com/seiyab/gost/utils" @@ -13,6 +14,7 @@ type mutation int const ( appended mutation = iota + 1 assigned + replaced copied mixed ) @@ -62,17 +64,21 @@ func collectSliceMutations(pass *analysis.Pass) map[types.Object]mutation { } func visitAssign(n *ast.AssignStmt, pass *analysis.Pass) map[types.Object]mutation { + if n.Tok != token.ASSIGN { + return nil + } var muts = make(map[types.Object]mutation) for i, lhs := range n.Lhs { if i >= len(n.Rhs) { break } - if ident, ok := lhs.(*ast.Ident); ok { - t := pass.TypesInfo.TypeOf(ident) + switch lhs := lhs.(type) { + case *ast.Ident: + t := pass.TypesInfo.TypeOf(lhs) if t == nil { continue } - o := pass.TypesInfo.ObjectOf(ident) + o := pass.TypesInfo.ObjectOf(lhs) if o == nil { continue } @@ -81,17 +87,26 @@ func visitAssign(n *ast.AssignStmt, pass *analysis.Pass) map[types.Object]mutati } call, ok := n.Rhs[i].(*ast.CallExpr) if !ok { + muts[o] = replaced continue } if !appendMatcher.Matches(pass, call) { + muts[o] = replaced + continue + } + orig, ok := call.Args[0].(*ast.Ident) + if !ok { + muts[o] = replaced + continue + } + if pass.TypesInfo.ObjectOf(orig) != o { + muts[o] = replaced continue } muts[o] = appended continue - } - - if idx, ok := lhs.(*ast.IndexExpr); ok { - if ident, ok := idx.X.(*ast.Ident); ok { + case *ast.IndexExpr: + if ident, ok := lhs.X.(*ast.Ident); ok { t := pass.TypesInfo.TypeOf(ident) if t == nil { continue @@ -107,6 +122,7 @@ func visitAssign(n *ast.AssignStmt, pass *analysis.Pass) map[types.Object]mutati continue } } + } return muts } diff --git a/sliceinitiallength/testdata/a.go b/sliceinitiallength/testdata/a.go index e716ba7..54fbce1 100644 --- a/sliceinitiallength/testdata/a.go +++ b/sliceinitiallength/testdata/a.go @@ -54,3 +54,25 @@ func _() { } fmt.Println(ys) } + +func _() { + xs := []string{"a", "b", "c"} + ys := make([]int, len(xs)) + + ys = ys[:0] + for _, x := range xs { + ys = append(ys, len(x)) + } + fmt.Println(ys) +} + +func _() { + xs := []string{"a", "b", "c"} + ys := make([]int, len(xs)) + + ys = append(ys[:0], 0) + for _, x := range xs { + ys = append(ys, len(x)) + } + fmt.Println(ys) +}