diff --git a/tests/bool-cmp.go b/tests/bool-cmp.go deleted file mode 100644 index 6211a69..0000000 --- a/tests/bool-cmp.go +++ /dev/null @@ -1,29 +0,0 @@ -package pkg - -func fn1() bool { return false } -func fn2() bool { return false } - -func fn() { - type T bool - var x T - const t T = false - if x == t { - } - if fn1() == true { // MATCH /simplified to fn1\(\)/ - } - if fn1() != true { // MATCH /simplified to !fn1\(\)/ - } - if fn1() == false { // MATCH /simplified to !fn1\(\)/ - } - if fn1() != false { // MATCH /simplified to fn1\(\)/ - } - if fn1() && (fn1() || fn1()) || (fn1() && fn1()) == true { // MATCH /simplified to \(fn1\(\) && fn1\(\)\)/ - } - - if (fn1() && fn2()) == false { // MATCH /simplified to !\(fn1\(\) && fn2\(\)\)/ - } - - var y bool - for y != true { // MATCH /simplified to !y/ - } -} diff --git a/tests/compare.go b/tests/compare.go deleted file mode 100644 index 18d4b17..0000000 --- a/tests/compare.go +++ /dev/null @@ -1,10 +0,0 @@ -package pkg - -import "bytes" - -func fn() { - _ = bytes.Compare(nil, nil) == 0 // MATCH / bytes.Equal/ - _ = bytes.Compare(nil, nil) != 0 // MATCH /!bytes.Equal/ - _ = bytes.Compare(nil, nil) > 0 - _ = bytes.Compare(nil, nil) < 0 -} diff --git a/tests/contains.go b/tests/contains.go deleted file mode 100644 index a60ac40..0000000 --- a/tests/contains.go +++ /dev/null @@ -1,39 +0,0 @@ -package pkg - -import ( - "bytes" - "strings" -) - -func fn() { - _ = strings.IndexRune("", 'x') > -1 // MATCH / strings.ContainsRune/ - _ = strings.IndexRune("", 'x') >= 0 // MATCH / strings.ContainsRune/ - _ = strings.IndexRune("", 'x') > 0 - _ = strings.IndexRune("", 'x') >= -1 - _ = strings.IndexRune("", 'x') != -1 // MATCH / strings.ContainsRune/ - _ = strings.IndexRune("", 'x') == -1 // MATCH /!strings.ContainsRune/ - _ = strings.IndexRune("", 'x') != 0 - _ = strings.IndexRune("", 'x') < 0 // MATCH /!strings.ContainsRune/ - - _ = strings.IndexAny("", "") > -1 // MATCH / strings.ContainsAny/ - _ = strings.IndexAny("", "") >= 0 // MATCH / strings.ContainsAny/ - _ = strings.IndexAny("", "") > 0 - _ = strings.IndexAny("", "") >= -1 - _ = strings.IndexAny("", "") != -1 // MATCH / strings.ContainsAny/ - _ = strings.IndexAny("", "") == -1 // MATCH /!strings.ContainsAny/ - _ = strings.IndexAny("", "") != 0 - _ = strings.IndexAny("", "") < 0 // MATCH /!strings.ContainsAny/ - - _ = strings.Index("", "") > -1 // MATCH / strings.Contains/ - _ = strings.Index("", "") >= 0 // MATCH / strings.Contains/ - _ = strings.Index("", "") > 0 - _ = strings.Index("", "") >= -1 - _ = strings.Index("", "") != -1 // MATCH / strings.Contains/ - _ = strings.Index("", "") == -1 // MATCH /!strings.Contains/ - _ = strings.Index("", "") != 0 - _ = strings.Index("", "") < 0 // MATCH /!strings.Contains/ - - _ = bytes.IndexRune("", 'x') > -1 // MATCH / bytes.ContainsRune/ - _ = bytes.IndexAny("", "") > -1 // MATCH / bytes.ContainsAny/ - _ = bytes.Index(nil, nil) > -1 // MATCH / bytes.Contains/ -} diff --git a/tests/convert.go b/tests/convert.go deleted file mode 100644 index dfccf8d..0000000 --- a/tests/convert.go +++ /dev/null @@ -1,26 +0,0 @@ -package pkg - -type t1 struct { - a int - b int -} - -type t2 struct { - a int - b int -} - -type t3 t1 - -func fn() { - v1 := t1{1, 2} - _ = t2{v1.a, v1.b} // MATCH /should use type conversion/ - _ = t2{a: v1.a, b: v1.b} // MATCH /should use type conversion/ - _ = t2{b: v1.b, a: v1.a} // MATCH /should use type conversion/ - _ = t3{v1.a, v1.b} // MATCH /should use type conversion/ - - _ = t2{v1.b, v1.a} - _ = t2{a: v1.b, b: v1.a} - _ = t2{a: v1.a} - _ = t1{v1.a, v1.b} -} diff --git a/tests/copy.go b/tests/copy.go deleted file mode 100644 index d4c130b..0000000 --- a/tests/copy.go +++ /dev/null @@ -1,30 +0,0 @@ -package pkg - -func fn() { - var b1, b2 []byte - for i, v := range b1 { // MATCH /should use copy/ - b2[i] = v - } - - for i := range b1 { // MATCH /should use copy/ - b2[i] = b1[i] - } - - type T [][16]byte - var a T - b := make([]interface{}, len(a)) - for i := range b { - b[i] = a[i] - } - - var b3, b4 []*byte - for i := range b3 { // MATCH /should use copy/ - b4[i] = b3[i] - } - - var m map[int]byte - for i, v := range b1 { - m[i] = v - } - -} diff --git a/tests/for-true.go b/tests/for-true.go deleted file mode 100644 index b806eae..0000000 --- a/tests/for-true.go +++ /dev/null @@ -1,12 +0,0 @@ -package pkg - -func fn() { - for false { - } - for true { // MATCH /should use for/ - } - for { - } - for i := 0; true; i++ { - } -} diff --git a/tests/format-int.go b/tests/format-int.go deleted file mode 100644 index 8590fe0..0000000 --- a/tests/format-int.go +++ /dev/null @@ -1,33 +0,0 @@ -package pkg - -import "strconv" - -func ifn() int { return 0 } -func ifn32() int32 { return 0 } -func ifn64() int64 { return 0 } - -func fn() { - var i int - var i32 int32 - var i64 int64 - const c = 0 - const c32 int32 = 0 - const c64 int64 = 0 - - strconv.FormatInt(int64(i), 10) // MATCH /strconv.Itoa instead of strconv.FormatInt/ - strconv.FormatInt(int64(i), 2) - strconv.FormatInt(int64(i32), 10) // MATCH /strconv.Itoa instead of strconv.FormatInt/ - strconv.FormatInt(int64(i64), 10) - strconv.FormatInt(i64, 10) - strconv.FormatInt(123, 10) // MATCH /strconv.Itoa instead of strconv.FormatInt/ - strconv.FormatInt(int64(123), 10) // MATCH /strconv.Itoa instead of strconv.FormatInt/ - strconv.FormatInt(int64(999999999999999999), 10) - strconv.FormatInt(int64(int64(123)), 10) - strconv.FormatInt(c, 10) // MATCH /strconv.Itoa instead of strconv.FormatInt/ - strconv.FormatInt(int64(c), 10) // MATCH /strconv.Itoa instead of strconv.FormatInt/ - strconv.FormatInt(int64(c32), 10) // MATCH /strconv.Itoa instead of strconv.FormatInt/ - strconv.FormatInt(c64, 10) - strconv.FormatInt(int64(ifn()), 10) // MATCH /strconv.Itoa instead of strconv.FormatInt/ - strconv.FormatInt(int64(ifn32()), 10) // MATCH /strconv.Itoa instead of strconv.FormatInt/ - strconv.FormatInt(int64(ifn64()), 10) -} diff --git a/tests/gocheck/aligncheck/aligncheck.go b/tests/gocheck/aligncheck/aligncheck.go deleted file mode 100755 index 8fce639..0000000 --- a/tests/gocheck/aligncheck/aligncheck.go +++ /dev/null @@ -1,117 +0,0 @@ -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -package aligncheck - -import ( - "fmt" - "go/build" - "log" - "sort" - "unsafe" - - "github.com/kisielk/gotool" - "go/types" - "golang.org/x/tools/go/loader" -) - -var stdSizes = types.StdSizes{ - WordSize: int64(unsafe.Sizeof(int(0))), - MaxAlign: 8, -} - -func AlignCheck(path string) ([]string, error) { - importPaths := gotool.ImportPaths([]string{path}) - if len(importPaths) == 0 { - importPaths = []string{"."} - } - - ctx := build.Default - loadcfg := loader.Config{ - Build: &ctx, - } - rest, err := loadcfg.FromArgs(importPaths, false) - if err != nil { - log.Fatalf("could not parse arguments: %s", err) - } - if len(rest) > 0 { - log.Fatalf("unhandled extra arguments: %v", rest) - } - - program, err := loadcfg.Load() - if err != nil { - log.Fatalf("could not type check: %s", err) - } - - var lines []string - - for _, pkgInfo := range program.InitialPackages() { - for _, obj := range pkgInfo.Defs { - if obj == nil { - continue - } - - if _, ok := obj.(*types.TypeName); !ok { - continue - } - - typ, ok := obj.Type().(*types.Named) - if !ok { - continue - } - - strukt, ok := typ.Underlying().(*types.Struct) - if !ok { - continue - } - - structAlign := int(stdSizes.Alignof(strukt)) - structSize := int(stdSizes.Sizeof(strukt)) - if structSize%structAlign != 0 { - structSize += structAlign - structSize%structAlign - } - - minSize := 0 - for i := 0; i < strukt.NumFields(); i++ { - field := strukt.Field(i) - fieldType := field.Type() - typeSize := int(stdSizes.Sizeof(fieldType)) - minSize += typeSize - } - if minSize%structAlign != 0 { - minSize += structAlign - minSize%structAlign - } - - if minSize != structSize { - pos := program.Fset.Position(obj.Pos()) - lines = append(lines, fmt.Sprintf( - "%s: %s:%d:%d: struct %s could have size %d (currently %d)", - obj.Pkg().Path(), - pos.Filename, - pos.Line, - pos.Column, - obj.Name(), - minSize, - structSize, - )) - } - } - } - - sort.Strings(lines) - // for _, line := range lines { - // fmt.Println(line) - // } - - return lines, nil -} diff --git a/tests/gocheck/gocheck.go b/tests/gocheck/gocheck.go deleted file mode 100755 index de1e088..0000000 --- a/tests/gocheck/gocheck.go +++ /dev/null @@ -1,55 +0,0 @@ -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -package gocheck - -import ( - "fmt" - - "360.cn/apollo/apollo/gocheck/aligncheck" - "360.cn/apollo/apollo/gocheck/structcheck" - "360.cn/apollo/apollo/gocheck/varcheck" -) - -func Check(dirs map[string]string) map[string][]string { - checks := make(map[string][]string) - fmt.Println("Checking var...") - for _, dir := range dirs { - varchecks, err := varcheck.VarCheck(string(dir)) - if err != nil { - fmt.Println(err) - } else { - checks[dir] = append(checks[dir], varchecks...) - } - } - fmt.Println("Checking struct...") - for _, dir := range dirs { - structchecks, err := structcheck.StructCheck(string(dir)) - if err != nil { - fmt.Println(err) - } else { - checks[dir] = append(checks[dir], structchecks...) - } - } - fmt.Println("Checking align...") - for _, dir := range dirs { - alignchecks, err := aligncheck.AlignCheck(string(dir)) - if err != nil { - fmt.Println(err) - } else { - checks[dir] = append(checks[dir], alignchecks...) - } - } - - return checks -} diff --git a/tests/gocheck/structcheck/structcheck.go b/tests/gocheck/structcheck/structcheck.go deleted file mode 100755 index 3caf340..0000000 --- a/tests/gocheck/structcheck/structcheck.go +++ /dev/null @@ -1,214 +0,0 @@ -// structcheck -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -package structcheck - -import ( - "fmt" - "go/ast" - "go/build" - "os" - - "go/types" - - "github.com/kisielk/gotool" - "golang.org/x/tools/go/loader" -) - -var ( - // , "Count assignments only") - assignmentsOnly = false - // , "Load test files too") - loadTestFiles = false - // , "Report exported fields") - reportExported = false -) - -type visitor struct { - prog *loader.Program - pkg *loader.PackageInfo - m map[types.Type]map[string]int - skip map[types.Type]struct{} -} - -func (v *visitor) decl(t types.Type, fieldName string) { - if _, ok := v.m[t]; !ok { - v.m[t] = make(map[string]int) - } - if _, ok := v.m[t][fieldName]; !ok { - v.m[t][fieldName] = 0 - } -} - -func (v *visitor) assignment(t types.Type, fieldName string) { - if _, ok := v.m[t]; !ok { - v.m[t] = make(map[string]int) - } - if _, ok := v.m[t][fieldName]; ok { - v.m[t][fieldName]++ - } else { - v.m[t][fieldName] = 1 - } -} - -func (v *visitor) typeSpec(node *ast.TypeSpec) { - if strukt, ok := node.Type.(*ast.StructType); ok { - t := v.pkg.Info.Defs[node.Name].Type() - for _, f := range strukt.Fields.List { - if len(f.Names) > 0 { - fieldName := f.Names[0].Name - v.decl(t, fieldName) - } - } - } -} - -func (v *visitor) typeAndFieldName(expr *ast.SelectorExpr) (types.Type, string, bool) { - selection := v.pkg.Info.Selections[expr] - if selection == nil { - return nil, "", false - } - recv := selection.Recv() - if ptr, ok := recv.(*types.Pointer); ok { - recv = ptr.Elem() - } - return recv, selection.Obj().Name(), true -} - -func (v *visitor) assignStmt(node *ast.AssignStmt) { - for _, lhs := range node.Lhs { - var selector *ast.SelectorExpr - switch expr := lhs.(type) { - case *ast.SelectorExpr: - selector = expr - case *ast.IndexExpr: - if expr, ok := expr.X.(*ast.SelectorExpr); ok { - selector = expr - } - } - if selector != nil { - if t, fn, ok := v.typeAndFieldName(selector); ok { - v.assignment(t, fn) - } - } - } -} - -func (v *visitor) compositeLiteral(node *ast.CompositeLit) { - t := v.pkg.Info.Types[node.Type].Type - for _, expr := range node.Elts { - if kv, ok := expr.(*ast.KeyValueExpr); ok { - if ident, ok := kv.Key.(*ast.Ident); ok { - v.assignment(t, ident.Name) - } - } else { - // Struct literal with positional values. - // All the fields are assigned. - v.skip[t] = struct{}{} - break - } - } -} - -func (v *visitor) Visit(node ast.Node) ast.Visitor { - switch node := node.(type) { - case *ast.TypeSpec: - v.typeSpec(node) - - case *ast.AssignStmt: - if assignmentsOnly { - v.assignStmt(node) - } - - case *ast.SelectorExpr: - if !assignmentsOnly { - if t, fn, ok := v.typeAndFieldName(node); ok { - v.assignment(t, fn) - } - } - - case *ast.CompositeLit: - v.compositeLiteral(node) - } - - return v -} - -func StructCheck(path string) ([]string, error) { - importPaths := gotool.ImportPaths([]string{path}) - if len(importPaths) == 0 { - importPaths = []string{"."} - } - ctx := build.Default - loadcfg := loader.Config{ - Build: &ctx, - } - rest, err := loadcfg.FromArgs(importPaths, loadTestFiles) - if err != nil { - fmt.Fprintf(os.Stderr, "could not parse arguments: %s", err) - os.Exit(1) - } - if len(rest) > 0 { - fmt.Fprintf(os.Stderr, "unhandled extra arguments: %v", rest) - os.Exit(1) - } - - program, err := loadcfg.Load() - if err != nil { - fmt.Fprintf(os.Stderr, "could not type check: %s", err) - os.Exit(1) - } - - structchecks := make([]string, 0) - for _, pkg := range program.InitialPackages() { - visitor := &visitor{ - m: make(map[types.Type]map[string]int), - skip: make(map[types.Type]struct{}), - prog: program, - pkg: pkg, - } - for _, f := range pkg.Files { - ast.Walk(visitor, f) - } - - for t := range visitor.m { - if _, skip := visitor.skip[t]; skip { - continue - } - for fieldName, v := range visitor.m[t] { - if !reportExported && ast.IsExported(fieldName) { - continue - } - if v == 0 { - field, _, _ := types.LookupFieldOrMethod(t, false, pkg.Pkg, fieldName) - if fieldName == "XMLName" { - if named, ok := field.Type().(*types.Named); ok && named.Obj().Pkg().Path() == "encoding/xml" { - continue - } - } - pos := program.Fset.Position(field.Pos()) - structchecks = append(structchecks, fmt.Sprintf("%s: %s:%d:%d: %s.%s\n", - pkg.Pkg.Path(), pos.Filename, pos.Line, pos.Column, - types.TypeString(t, nil), fieldName, - )) - // fmt.Printf("%s: %s:%d:%d: %s.%s\n", - // pkg.Pkg.Path(), pos.Filename, pos.Line, pos.Column, - // types.TypeString(t, nil), fieldName, - // ) - } - } - } - } - return structchecks, nil -} diff --git a/tests/gocheck/varcheck/varcheck.go b/tests/gocheck/varcheck/varcheck.go deleted file mode 100755 index 6a2e82f..0000000 --- a/tests/gocheck/varcheck/varcheck.go +++ /dev/null @@ -1,177 +0,0 @@ -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -package varcheck - -import ( - "fmt" - "go/ast" - "go/build" - "go/token" - "log" - "sort" - "strings" - - "github.com/kisielk/gotool" - "go/types" - "golang.org/x/tools/go/loader" -) - -var ( - //, "Report exported variables and constants") - reportExported = false -) - -type object struct { - pkgPath string - name string -} - -type visitor struct { - prog *loader.Program - pkg *loader.PackageInfo - uses map[object]int - positions map[object]token.Position - insideFunc bool -} - -func getKey(obj types.Object) object { - if obj == nil { - return object{} - } - - pkg := obj.Pkg() - pkgPath := "" - if pkg != nil { - pkgPath = pkg.Path() - } - - return object{ - pkgPath: pkgPath, - name: obj.Name(), - } -} - -func (v *visitor) decl(obj types.Object) { - key := getKey(obj) - if _, ok := v.uses[key]; !ok { - v.uses[key] = 0 - } - if _, ok := v.positions[key]; !ok { - v.positions[key] = v.prog.Fset.Position(obj.Pos()) - } -} - -func (v *visitor) use(obj types.Object) { - key := getKey(obj) - if _, ok := v.uses[key]; ok { - v.uses[key]++ - } else { - v.uses[key] = 1 - } -} - -func isReserved(name string) bool { - return name == "_" || strings.HasPrefix(strings.ToLower(name), "_cgo_") -} - -func (v *visitor) Visit(node ast.Node) ast.Visitor { - switch node := node.(type) { - case *ast.Ident: - v.use(v.pkg.Info.Uses[node]) - - case *ast.ValueSpec: - if !v.insideFunc { - for _, ident := range node.Names { - if !isReserved(ident.Name) { - v.decl(v.pkg.Info.Defs[ident]) - } - } - } - for _, val := range node.Values { - ast.Walk(v, val) - } - return nil - - case *ast.FuncDecl: - if node.Body != nil { - v.insideFunc = true - ast.Walk(v, node.Body) - v.insideFunc = false - } - - return nil - } - - return v -} - -func VarCheck(path string) ([]string, error) { - importPaths := gotool.ImportPaths([]string{path}) - if len(importPaths) == 0 { - importPaths = []string{"."} - } - - ctx := build.Default - loadcfg := loader.Config{ - Build: &ctx, - } - rest, err := loadcfg.FromArgs(importPaths, true) - if err != nil { - log.Fatalf("could not parse arguments: %s", err) - } - if len(rest) > 0 { - log.Fatalf("unhandled extra arguments: %v", rest) - } - - program, err := loadcfg.Load() - if err != nil { - log.Fatalf("could not type check: %s", err) - } - - uses := make(map[object]int) - positions := make(map[object]token.Position) - - for _, pkgInfo := range program.InitialPackages() { - if pkgInfo.Pkg.Path() == "unsafe" { - continue - } - - v := &visitor{ - prog: program, - pkg: pkgInfo, - uses: uses, - positions: positions, - } - - for _, f := range v.pkg.Files { - ast.Walk(v, f) - } - } - - var lines []string - - for obj, useCount := range uses { - if useCount == 0 && (reportExported || !ast.IsExported(obj.name)) { - pos := positions[obj] - lines = append(lines, fmt.Sprintf("%s: %s:%d:%d: %s", obj.pkgPath, pos.Filename, pos.Line, pos.Column, obj.name)) - } - } - - sort.Strings(lines) - // for _, line := range lines { - // fmt.Println(line) - // } - - return lines, nil -} diff --git a/tests/if-return.go b/tests/if-return.go deleted file mode 100644 index 80ff76f..0000000 --- a/tests/if-return.go +++ /dev/null @@ -1,57 +0,0 @@ -package pkg - -func fn1() bool { - x := true - if x { // MATCH /should use 'return '/ - return true - } - return false -} - -func fn2() bool { - x := true - if !x { - return true - } - if x { - return true - } - return false -} - -func fn3() int { - if x { - return 1 - } - return 2 -} - -func fn4() bool { return true } - -func fn5() bool { - if fn3() { // MATCH /should use 'return '/ - return false - } - return true -} - -func fn6() bool { - if fn3() != fn3() { // MATCH /should use 'return '/ - return true - } - return false -} - -func fn7() bool { - if 1 > 2 { // MATCH /should use 'return '/ - return true - } - return false -} - -func fn8() bool { - if fn3() || fn3() { - return true - } - return false -} diff --git a/tests/if-simpler-return.go b/tests/if-simpler-return.go deleted file mode 100644 index b37d7d4..0000000 --- a/tests/if-simpler-return.go +++ /dev/null @@ -1,105 +0,0 @@ -package pkg - -import "errors" - -func fn1() error { - var err error - - if err != nil { // MATCH /simplified/ - return err - } - return nil - - _ = nil - - if err != nil { // MATCH /simplified/ - return err - } - return err -} - -func fn2() (int, string, error) { - var x int - var y string - var z int - var err error - - if err != nil { // MATCH /simplified/ - return x, y, err - } - return x, y, nil - - _ = nil - - if err != nil { // MATCH /simplified/ - return x, y, err - } - return x, y, err - - _ = nil - - if err != nil { - return x, y, err - } - return z, y, err - - _ = nil - - if err != nil { - return 0, "", err - } - return x, y, err - - _ = nil - - // TODO(dominikh): currently, only returning identifiers is - // supported - if err != nil { - return 42, "foo", err - } - return 42, "foo", err -} - -func fn3() error { - var err error - if err != nil { - return err - } - if err != nil { - return err - } - return nil -} - -func fn4(i int, err error) error { - if err != nil { - return err - } else if i == 1 { - return errors.New("some non-nil error") - } - return nil -} - -func fn4() interface{} { - var i *int - if i != nil { - return i - } - return nil - - var v interface{} - if v != nil { // MATCH /simplified/ - return v - } - return nil -} - -func fn5() { - func() error { - var err error - if err != nil { // MATCH /simplified/ - return err - } - return nil - } -} diff --git a/tests/loop-append.go b/tests/loop-append.go deleted file mode 100644 index 2f4eefd..0000000 --- a/tests/loop-append.go +++ /dev/null @@ -1,78 +0,0 @@ -package pkg - -type T struct { - F string -} - -func fn1() { - var x []interface{} - var y []int - - for _, v := range y { - x = append(x, v) - } - - var a, b []int - for _, v := range a { // MATCH /should replace loop/ - b = append(b, v) - } - - var m map[string]int - var c []int - for _, v := range m { - c = append(c, v) - } - - var t []T - var m2 map[string][]T - - for _, tt := range t { - m2[tt.F] = append(m2[tt.F], tt) - } - - var out []T - for _, tt := range t { - out = append(m2[tt.F], tt) - } - _ = out -} - -func fn2() { - var v struct { - V int - } - var in []int - var out []int - - for _, v.V = range in { - out = append(out, v.V) - } -} - -func fn3() { - var t []T - var out [][]T - var m2 map[string][]T - - for _, tt := range t { - out = append(out, m2[tt.F]) - } -} - -func fn4() { - var a, b, c []int - for _, v := range a { - b = append(c, v) - } - _ = b -} - -func fn5() { - var t []T - var m2 map[string][]T - var out []T - for _, tt := range t { - out = append(m2[tt.F], tt) - } - _ = out -} diff --git a/tests/nil-len.go b/tests/nil-len.go deleted file mode 100644 index 2de90d4..0000000 --- a/tests/nil-len.go +++ /dev/null @@ -1,64 +0,0 @@ -package pkg - -func fn() { - var pa *[5]int - var s []int - var m map[int]int - var ch chan int - - if s == nil || len(s) == 0 { // MATCH /should omit nil check/ - } - if m == nil || len(m) == 0 { // MATCH /should omit nil check/ - } - if ch == nil || len(ch) == 0 { // MATCH /should omit nil check/ - } - - if s != nil && len(s) != 0 { // MATCH /should omit nil check/ - } - if m != nil && len(m) > 0 { // MATCH /should omit nil check/ - } - if s != nil && len(s) > 5 { // MATCH /should omit nil check/ - } - if s != nil && len(s) >= 5 { // MATCH /should omit nil check/ - } - const five = 5 - if s != nil && len(s) == five { // MATCH /should omit nil check/ - } - - if ch != nil && len(ch) == 5 { // MATCH /should omit nil check/ - } - - if pa == nil || len(pa) == 0 { // nil check cannot be removed with pointer to an array - } - if s == nil || len(m) == 0 { // different variables - } - if s != nil && len(m) == 1 { // different variables - } - - var ch2 chan int - if ch == ch2 || len(ch) == 0 { // not comparing with nil - } - if ch != ch2 && len(ch) != 0 { // not comparing with nil - } - - const zero = 0 - if s != nil && len(s) == zero { // nil check is not redundant here - } - if s != nil && len(s) == 0 { // nil check is not redundant here - } - if s != nil && len(s) >= 0 { // nil check is not redundant here (though len(s) >= 0 is) - } - one := 1 - if s != nil && len(s) == one { // nil check is not redundant here - } - if s != nil && len(s) == len(m) { // nil check is not redundant here - } - if s != nil && len(s) != 1 { // nil check is not redundant here - } - if s != nil && len(s) < 5 { // nil check is not redundant here - } - if s != nil && len(s) <= 5 { // nil check is not redundant here - } - if s != nil && len(s) != len(ch) { // nil check is not redundant here - } -} diff --git a/tests/range.go b/tests/range.go deleted file mode 100644 index 07a97a6..0000000 --- a/tests/range.go +++ /dev/null @@ -1,40 +0,0 @@ -package pkg - -func fn() { - var m map[string]int - - // with := - for x, _ := range m { - _ = x - } - // with = - var y string - _ = y - for y, _ = range m { - } - - for _ = range m { // MATCH /should omit values.*range.*equivalent.*for range/ - } - - for _, _ = range m { // MATCH /should omit values.*range.*equivalent.*for range/ - } - - // all OK: - for x := range m { - _ = x - } - for x, y := range m { - _, _ = x, y - } - for _, y := range m { - _ = y - } - var x int - _ = x - for y = range m { - } - for y, x = range m { - } - for _, x = range m { - } -} diff --git a/tests/receive-blank.go b/tests/receive-blank.go deleted file mode 100644 index 23c8a61..0000000 --- a/tests/receive-blank.go +++ /dev/null @@ -1,15 +0,0 @@ -package pkg - -func fn() { - var ch chan int - <-ch - _ = <-ch // MATCH /_ = <-ch/ - select { - case <-ch: - case _ = <-ch: // MATCH /_ = <-ch/ - } - x := <-ch - y, _ := <-ch, <-ch // MATCH /_ = <-ch/ - _, z := <-ch, <-ch // MATCH /_ = <-ch/ - _, _, _ = x, y, z -} diff --git a/tests/regexp-raw.go b/tests/regexp-raw.go deleted file mode 100644 index b32d781..0000000 --- a/tests/regexp-raw.go +++ /dev/null @@ -1,18 +0,0 @@ -package pkg - -import "regexp" - -func fn2() string { return "" } - -func fn() { - x := "abc" - const y = "abc" - regexp.MustCompile(`\\.`) - regexp.MustCompile("\\.") // MATCH /should use raw string.+\.MustCompile/ - regexp.Compile("\\.") // MATCH /should use raw string.+\.Compile/ - regexp.MustCompile("(?m:^lease (.+?) {\n((?s).+?)\\n}\n)") - regexp.MustCompile("\\*/[ \t\n\r\f\v]*;") - regexp.MustCompile(fn2()) - regexp.MustCompile(x) - regexp.MustCompile(y) -} diff --git a/tests/single-case-select.go b/tests/single-case-select.go deleted file mode 100644 index efaced1..0000000 --- a/tests/single-case-select.go +++ /dev/null @@ -1,28 +0,0 @@ -package pkg - -func fn() { - var ch chan int - select { // MATCH /should use a simple channel send/ - case <-ch: - } -outer: - for { // MATCH /should use for range/ - select { - case <-ch: - break outer - } - } - - for { // MATCH /should use for range/ - select { - case x := <-ch: - _ = x - } - } - - for { - select { // MATCH /should use a simple channel send/ - case ch <- 0: - } - } -} diff --git a/tests/slicing.go b/tests/slicing.go deleted file mode 100644 index f49fb70..0000000 --- a/tests/slicing.go +++ /dev/null @@ -1,9 +0,0 @@ -package pkg - -func fn() { - var s []int - _ = s[:len(s)] // MATCH /omit second index/ - - len := func(s []int) int { return -1 } - _ = s[:len(s)] -} diff --git a/tests/time-since.go b/tests/time-since.go deleted file mode 100644 index d77e268..0000000 --- a/tests/time-since.go +++ /dev/null @@ -1,9 +0,0 @@ -package pkg - -import "time" - -func fn() { - t1 := time.Now() - _ = time.Now().Sub(t1) // MATCH /time\.Since/ - _ = time.Date(0, 0, 0, 0, 0, 0, 0, nil).Sub(t1) -} diff --git a/tests/trim.go b/tests/trim.go deleted file mode 100644 index 7eca4a7..0000000 --- a/tests/trim.go +++ /dev/null @@ -1,123 +0,0 @@ -package pkg - -import ( - "bytes" - "strings" -) - -func foo(s string) int { return 0 } -func gen() string { - return "" -} - -func fn() { - const s1 = "a string value" - var s2 = "a string value" - const n = 14 - - var id1 = "a string value" - var id2 string - if strings.HasPrefix(id1, s1) { // MATCH /should replace.*with.*strings.TrimPrefix/ - id1 = id1[len(s1):] - } - - if strings.HasSuffix(id1, s2) { // MATCH /should replace.*with.*strings.TrimSuffix/ - id1 = id1[:len(id1)-len(s2)] - } - - var x, y []string - var i int - if strings.HasPrefix(x[i], s1) { // MATCH /should replace.*with.*strings.TrimPrefix/ - x[i] = x[i][len(s1):] - } - - if strings.HasPrefix(x[i], y[i]) { // MATCH /should replace.*with.*strings.TrimPrefix/ - x[i] = x[i][len(y[i]):] - } - - var t struct{ x string } - if strings.HasPrefix(t.x, s1) { // MATCH /should replace.*with.*strings.TrimPrefix/ - t.x = t.x[len(s1):] - } - - if strings.HasPrefix(id1, "test") { // MATCH /should replace.*with.*strings.TrimPrefix/ - id1 = id1[len("test"):] - } - - if strings.HasPrefix(id1, "test") { // MATCH /should replace.*with.*strings.TrimPrefix/ - id1 = id1[4:] - } - - if strings.HasPrefix(id1, s1) { // MATCH /should replace.*with.*strings.TrimPrefix/ - id1 = id1[14:] - } - - if strings.HasPrefix(id1, s1) { // MATCH /should replace.*with.*strings.TrimPrefix/ - id1 = id1[n:] - } - - var b1, b2 []byte - if bytes.HasPrefix(b1, b2) { // MATCH /should replace.*with.*bytes.TrimPrefix/ - b1 = b1[len(b2):] - } - - id3 := s2 - if strings.HasPrefix(id1, id3) { // MATCH /should replace.*with.*strings.TrimPrefix/ - id1 = id1[len(id3):] - } - - if strings.HasSuffix(id1, s2) { - id1 = id1[:len(id1)+len(s2)] // wrong operator - } - - if strings.HasSuffix(id1, s2) { - id1 = id1[:len(s2)-len(id1)] // wrong math - } - - if strings.HasSuffix(id1, s2) { - id1 = id1[:len(id1)-len(id1)] // wrong string length - } - - if strings.HasPrefix(id1, gen()) { - id1 = id1[len(gen()):] // dunamic id3 - } - - if strings.HasPrefix(id1, s1) { - id1 = id1[foo(s1):] // wrong function - } - - if strings.HasPrefix(id1, s1) { - id1 = id1[len(id1):] // len() on wrong value - } - - if strings.HasPrefix(id1, "test") { - id1 = id1[5:] // wrong length - } - - if strings.HasPrefix(id1, s1) { - id1 = id1[len(s1)+1:] // wrong length due to math - } - - if strings.HasPrefix(id1, s1) { - id2 = id1[len(s1):] // assigning to the wrong variable - } - - if strings.HasPrefix(id1, s1) { - id1 = id1[len(s1):15] // has a max - } - - if strings.HasPrefix(id1, s1) { - id1 = id2[len(s1):] // assigning the wrong value - } - - if strings.HasPrefix(id1, s1) { - id1 = id1[len(s1):] - id1 += "" // doing more work in the if - } - - if strings.HasPrefix(id1, s1) { - id1 = id1[len(s1):] - } else { - id1 = "game over" // else branch - } -}