aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/Antonboom/nilnil
diff options
context:
space:
mode:
authorTaras Madan <tarasmadan@google.com>2022-09-05 14:27:54 +0200
committerGitHub <noreply@github.com>2022-09-05 12:27:54 +0000
commitb2f2446b46bf02821d90ebedadae2bf7ae0e880e (patch)
tree923cf42842918d6bebca1d6bbdc08abed54d274d /vendor/github.com/Antonboom/nilnil
parente6654faff4bcca4be92e9a8596fd4b77f747c39e (diff)
go.mod, vendor: update (#3358)
* go.mod, vendor: remove unnecessary dependencies Commands: 1. go mod tidy 2. go mod vendor * go.mod, vendor: update cloud.google.com/go Commands: 1. go get -u cloud.google.com/go 2. go mod tidy 3. go mod vendor * go.mod, vendor: update cloud.google.com/* Commands: 1. go get -u cloud.google.com/storage cloud.google.com/logging 2. go mod tidy 3. go mod vendor * go.mod, .golangci.yml, vendor: update *lint* Commands: 1. go get -u golang.org/x/tools github.com/golangci/golangci-lint@v1.47.0 2. go mod tidy 3. go mod vendor 4. edit .golangci.yml to suppress new errors (resolved in the same PR later) * all: fix lint errors hash.go: copy() recommended by gosimple parse.go: ent is never nil verifier.go: signal.Notify() with unbuffered channel is bad. Have no idea why. * .golangci.yml: adjust godot rules check-all is deprecated, but still work if you're hesitating too - I'll remove this commit
Diffstat (limited to 'vendor/github.com/Antonboom/nilnil')
-rw-r--r--vendor/github.com/Antonboom/nilnil/LICENSE21
-rw-r--r--vendor/github.com/Antonboom/nilnil/pkg/analyzer/analyzer.go148
-rw-r--r--vendor/github.com/Antonboom/nilnil/pkg/analyzer/config.go77
-rw-r--r--vendor/github.com/Antonboom/nilnil/pkg/analyzer/func_type_stack.go29
4 files changed, 275 insertions, 0 deletions
diff --git a/vendor/github.com/Antonboom/nilnil/LICENSE b/vendor/github.com/Antonboom/nilnil/LICENSE
new file mode 100644
index 000000000..e2002e4d4
--- /dev/null
+++ b/vendor/github.com/Antonboom/nilnil/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 Anton Telyshev
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/Antonboom/nilnil/pkg/analyzer/analyzer.go b/vendor/github.com/Antonboom/nilnil/pkg/analyzer/analyzer.go
new file mode 100644
index 000000000..71a9ddf40
--- /dev/null
+++ b/vendor/github.com/Antonboom/nilnil/pkg/analyzer/analyzer.go
@@ -0,0 +1,148 @@
+package analyzer
+
+import (
+ "go/ast"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/inspect"
+ "golang.org/x/tools/go/ast/inspector"
+)
+
+const (
+ name = "nilnil"
+ doc = "Checks that there is no simultaneous return of `nil` error and an invalid value."
+
+ reportMsg = "return both the `nil` error and invalid value: use a sentinel error instead"
+)
+
+// New returns new nilnil analyzer.
+func New() *analysis.Analyzer {
+ n := newNilNil()
+
+ a := &analysis.Analyzer{
+ Name: name,
+ Doc: doc,
+ Run: n.run,
+ Requires: []*analysis.Analyzer{inspect.Analyzer},
+ }
+ a.Flags.Var(&n.checkedTypes, "checked-types", "coma separated list")
+
+ return a
+}
+
+type nilNil struct {
+ checkedTypes checkedTypes
+}
+
+func newNilNil() *nilNil {
+ return &nilNil{
+ checkedTypes: newDefaultCheckedTypes(),
+ }
+}
+
+var (
+ types = []ast.Node{(*ast.TypeSpec)(nil)}
+
+ funcAndReturns = []ast.Node{
+ (*ast.FuncDecl)(nil),
+ (*ast.FuncLit)(nil),
+ (*ast.ReturnStmt)(nil),
+ }
+)
+
+type typeSpecByName map[string]*ast.TypeSpec
+
+func (n *nilNil) run(pass *analysis.Pass) (interface{}, error) {
+ insp := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
+
+ typeSpecs := typeSpecByName{}
+ insp.Preorder(types, func(node ast.Node) {
+ t := node.(*ast.TypeSpec)
+ typeSpecs[t.Name.Name] = t
+ })
+
+ var fs funcTypeStack
+ insp.Nodes(funcAndReturns, func(node ast.Node, push bool) (proceed bool) {
+ switch v := node.(type) {
+ case *ast.FuncLit:
+ if push {
+ fs.Push(v.Type)
+ } else {
+ fs.Pop()
+ }
+
+ case *ast.FuncDecl:
+ if push {
+ fs.Push(v.Type)
+ } else {
+ fs.Pop()
+ }
+
+ case *ast.ReturnStmt:
+ ft := fs.Top() // Current function.
+
+ if !push || len(v.Results) != 2 || ft == nil || ft.Results == nil || len(ft.Results.List) != 2 {
+ return false
+ }
+
+ fRes1, fRes2 := ft.Results.List[0], ft.Results.List[1]
+ if !(n.isDangerNilField(fRes1, typeSpecs) && n.isErrorField(fRes2)) {
+ return
+ }
+
+ rRes1, rRes2 := v.Results[0], v.Results[1]
+ if isNil(rRes1) && isNil(rRes2) {
+ pass.Reportf(v.Pos(), reportMsg)
+ }
+ }
+
+ return true
+ })
+
+ return nil, nil //nolint:nilnil
+}
+
+func (n *nilNil) isDangerNilField(f *ast.Field, typeSpecs typeSpecByName) bool {
+ return n.isDangerNilType(f.Type, typeSpecs)
+}
+
+func (n *nilNil) isDangerNilType(t ast.Expr, typeSpecs typeSpecByName) bool {
+ switch v := t.(type) {
+ case *ast.StarExpr:
+ return n.checkedTypes.Contains(ptrType)
+
+ case *ast.FuncType:
+ return n.checkedTypes.Contains(funcType)
+
+ case *ast.InterfaceType:
+ return n.checkedTypes.Contains(ifaceType)
+
+ case *ast.MapType:
+ return n.checkedTypes.Contains(mapType)
+
+ case *ast.ChanType:
+ return n.checkedTypes.Contains(chanType)
+
+ case *ast.Ident:
+ if t, ok := typeSpecs[v.Name]; ok {
+ return n.isDangerNilType(t.Type, nil)
+ }
+ }
+ return false
+}
+
+func (n *nilNil) isErrorField(f *ast.Field) bool {
+ return isIdent(f.Type, "error")
+}
+
+func isNil(e ast.Expr) bool {
+ return isIdent(e, "nil")
+}
+
+func isIdent(n ast.Node, name string) bool {
+ i, ok := n.(*ast.Ident)
+ if !ok {
+ return false
+ }
+ return i.Name == name
+}
diff --git a/vendor/github.com/Antonboom/nilnil/pkg/analyzer/config.go b/vendor/github.com/Antonboom/nilnil/pkg/analyzer/config.go
new file mode 100644
index 000000000..520b813a5
--- /dev/null
+++ b/vendor/github.com/Antonboom/nilnil/pkg/analyzer/config.go
@@ -0,0 +1,77 @@
+package analyzer
+
+import (
+ "fmt"
+ "sort"
+ "strings"
+)
+
+func newDefaultCheckedTypes() checkedTypes {
+ return checkedTypes{
+ ptrType: struct{}{},
+ funcType: struct{}{},
+ ifaceType: struct{}{},
+ mapType: struct{}{},
+ chanType: struct{}{},
+ }
+}
+
+const separator = ','
+
+type typeName string
+
+func (t typeName) S() string {
+ return string(t)
+}
+
+const (
+ ptrType typeName = "ptr"
+ funcType typeName = "func"
+ ifaceType typeName = "iface"
+ mapType typeName = "map"
+ chanType typeName = "chan"
+)
+
+var knownTypes = []typeName{ptrType, funcType, ifaceType, mapType, chanType}
+
+type checkedTypes map[typeName]struct{}
+
+func (c checkedTypes) Contains(t typeName) bool {
+ _, ok := c[t]
+ return ok
+}
+
+func (c checkedTypes) String() string {
+ result := make([]string, 0, len(c))
+ for t := range c {
+ result = append(result, t.S())
+ }
+
+ sort.Strings(result)
+ return strings.Join(result, string(separator))
+}
+
+func (c checkedTypes) Set(s string) error {
+ types := strings.FieldsFunc(s, func(c rune) bool { return c == separator })
+ if len(types) == 0 {
+ return nil
+ }
+
+ c.disableAll()
+ for _, t := range types {
+ switch tt := typeName(t); tt {
+ case ptrType, funcType, ifaceType, mapType, chanType:
+ c[tt] = struct{}{}
+ default:
+ return fmt.Errorf("unknown checked type name %q (see help)", t)
+ }
+ }
+
+ return nil
+}
+
+func (c checkedTypes) disableAll() {
+ for k := range c {
+ delete(c, k)
+ }
+}
diff --git a/vendor/github.com/Antonboom/nilnil/pkg/analyzer/func_type_stack.go b/vendor/github.com/Antonboom/nilnil/pkg/analyzer/func_type_stack.go
new file mode 100644
index 000000000..081761547
--- /dev/null
+++ b/vendor/github.com/Antonboom/nilnil/pkg/analyzer/func_type_stack.go
@@ -0,0 +1,29 @@
+package analyzer
+
+import (
+ "go/ast"
+)
+
+type funcTypeStack []*ast.FuncType
+
+func (s *funcTypeStack) Push(f *ast.FuncType) {
+ *s = append(*s, f)
+}
+
+func (s *funcTypeStack) Pop() *ast.FuncType {
+ if len(*s) == 0 {
+ return nil
+ }
+
+ last := len(*s) - 1
+ f := (*s)[last]
+ *s = (*s)[:last]
+ return f
+}
+
+func (s *funcTypeStack) Top() *ast.FuncType {
+ if len(*s) == 0 {
+ return nil
+ }
+ return (*s)[len(*s)-1]
+}