diff options
| author | Taras Madan <tarasmadan@google.com> | 2022-09-05 14:27:54 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-09-05 12:27:54 +0000 |
| commit | b2f2446b46bf02821d90ebedadae2bf7ae0e880e (patch) | |
| tree | 923cf42842918d6bebca1d6bbdc08abed54d274d /vendor/github.com/butuzov | |
| parent | e6654faff4bcca4be92e9a8596fd4b77f747c39e (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/butuzov')
| -rw-r--r-- | vendor/github.com/butuzov/ireturn/LICENSE | 21 | ||||
| -rw-r--r-- | vendor/github.com/butuzov/ireturn/analyzer/analyzer.go | 193 | ||||
| -rw-r--r-- | vendor/github.com/butuzov/ireturn/analyzer/disallow.go | 45 | ||||
| -rw-r--r-- | vendor/github.com/butuzov/ireturn/analyzer/std.go | 186 | ||||
| -rw-r--r-- | vendor/github.com/butuzov/ireturn/config/allow.go | 17 | ||||
| -rw-r--r-- | vendor/github.com/butuzov/ireturn/config/config.go | 66 | ||||
| -rw-r--r-- | vendor/github.com/butuzov/ireturn/config/new.go | 74 | ||||
| -rw-r--r-- | vendor/github.com/butuzov/ireturn/config/reject.go | 17 | ||||
| -rw-r--r-- | vendor/github.com/butuzov/ireturn/types/iface.go | 7 | ||||
| -rw-r--r-- | vendor/github.com/butuzov/ireturn/types/names.go | 8 | ||||
| -rw-r--r-- | vendor/github.com/butuzov/ireturn/types/types.go | 11 |
11 files changed, 645 insertions, 0 deletions
diff --git a/vendor/github.com/butuzov/ireturn/LICENSE b/vendor/github.com/butuzov/ireturn/LICENSE new file mode 100644 index 000000000..a9752e972 --- /dev/null +++ b/vendor/github.com/butuzov/ireturn/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Oleg Butuzov + +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/butuzov/ireturn/analyzer/analyzer.go b/vendor/github.com/butuzov/ireturn/analyzer/analyzer.go new file mode 100644 index 000000000..f4fdaaed6 --- /dev/null +++ b/vendor/github.com/butuzov/ireturn/analyzer/analyzer.go @@ -0,0 +1,193 @@ +package analyzer + +import ( + "flag" + "fmt" + "go/ast" + gotypes "go/types" + "strings" + "sync" + + "github.com/butuzov/ireturn/config" + "github.com/butuzov/ireturn/types" + + "golang.org/x/tools/go/analysis" + "golang.org/x/tools/go/analysis/passes/inspect" + "golang.org/x/tools/go/ast/inspector" +) + +const name string = "ireturn" // linter name + +type validator interface { + IsValid(types.IFace) bool +} + +type analyzer struct { + once sync.Once + handler validator + err error + + found []analysis.Diagnostic +} + +func (a *analyzer) run(pass *analysis.Pass) (interface{}, error) { + // 00. Part 1. Handling Configuration Only Once. + a.once.Do(func() { a.readConfiguration(&pass.Analyzer.Flags) }) + + // 00. Part 2. Handling Errors + if a.err != nil { + return nil, a.err + } + + // 01. Running Inspection. + ins, _ := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) + ins.Preorder([]ast.Node{(*ast.FuncDecl)(nil)}, func(node ast.Node) { + // 001. Casting to funcdecl + f, _ := node.(*ast.FuncDecl) + + // 002. Does it return any results ? + if f.Type == nil || f.Type.Results == nil { + return + } + + // 003. Is it allowed to be checked? + // TODO(butuzov): add inline comment + if hasDisallowDirective(f.Doc) { + return + } + + // 004. Filtering Results. + for _, i := range filterInterfaces(pass, f.Type.Results) { + + if a.handler.IsValid(i) { + continue + } + + a.found = append(a.found, analysis.Diagnostic{ //nolint: exhaustivestruct + Pos: f.Pos(), + Message: fmt.Sprintf("%s returns interface (%s)", f.Name.Name, i.Name), + }) + } + }) + + // 02. Printing reports. + for i := range a.found { + pass.Report(a.found[i]) + } + + return nil, nil +} + +func (a *analyzer) readConfiguration(fs *flag.FlagSet) { + cnf, err := config.New(fs) + if err != nil { + a.err = err + return + } + + if validatorImpl, ok := cnf.(validator); ok { + a.handler = validatorImpl + return + } + + a.handler = config.DefaultValidatorConfig() +} + +func NewAnalyzer() *analysis.Analyzer { + a := analyzer{} //nolint: exhaustivestruct + + return &analysis.Analyzer{ + Name: name, + Doc: "Accept Interfaces, Return Concrete Types", + Run: a.run, + Requires: []*analysis.Analyzer{inspect.Analyzer}, + Flags: flags(), + } +} + +func flags() flag.FlagSet { + set := flag.NewFlagSet("", flag.PanicOnError) + set.String("allow", "", "accept-list of the comma-separated interfaces") + set.String("reject", "", "reject-list of the comma-separated interfaces") + return *set +} + +func filterInterfaces(pass *analysis.Pass, fl *ast.FieldList) []types.IFace { + var results []types.IFace + + for pos, el := range fl.List { + switch v := el.Type.(type) { + // ----- empty or anonymous interfaces + case *ast.InterfaceType: + + if len(v.Methods.List) == 0 { + results = append(results, issue("interface{}", pos, types.EmptyInterface)) + continue + } + + results = append(results, issue("anonymous interface", pos, types.AnonInterface)) + + // ------ Errors and interfaces from same package + case *ast.Ident: + + t1 := pass.TypesInfo.TypeOf(el.Type) + if !gotypes.IsInterface(t1.Underlying()) { + continue + } + + word := t1.String() + // only build in interface is error + if obj := gotypes.Universe.Lookup(word); obj != nil { + results = append(results, issue(obj.Name(), pos, types.ErrorInterface)) + + continue + } + + results = append(results, issue(word, pos, types.NamedInterface)) + + // ------- standard library and 3rd party interfaces + case *ast.SelectorExpr: + + t1 := pass.TypesInfo.TypeOf(el.Type) + if !gotypes.IsInterface(t1.Underlying()) { + continue + } + + word := t1.String() + if isStdLib(word) { + results = append(results, issue(word, pos, types.NamedStdInterface)) + + continue + } + + results = append(results, issue(word, pos, types.NamedInterface)) + } + } + + return results +} + +// isStdLib will run small checks against pkg to find out if named interface +// we lookling on comes from a standard library or not. +func isStdLib(named string) bool { + // find last dot index. + idx := strings.LastIndex(named, ".") + if idx == -1 { + return false + } + + if _, ok := std[named[0:idx]]; ok { + return true + } + + return false +} + +// issue is shortcut that creates issue for next filtering. +func issue(name string, pos int, interfaceType types.IType) types.IFace { + return types.IFace{ + Name: name, + Pos: pos, + Type: interfaceType, + } +} diff --git a/vendor/github.com/butuzov/ireturn/analyzer/disallow.go b/vendor/github.com/butuzov/ireturn/analyzer/disallow.go new file mode 100644 index 000000000..36b6fcb4f --- /dev/null +++ b/vendor/github.com/butuzov/ireturn/analyzer/disallow.go @@ -0,0 +1,45 @@ +package analyzer + +import ( + "go/ast" + "strings" +) + +const nolintPrefix = "//nolint" + +func hasDisallowDirective(cg *ast.CommentGroup) bool { + if cg == nil { + return false + } + + return directiveFound(cg) +} + +func directiveFound(cg *ast.CommentGroup) bool { + for i := len(cg.List) - 1; i >= 0; i-- { + comment := cg.List[i] + if !strings.HasPrefix(comment.Text, nolintPrefix) { + continue + } + + startingIdx := len(nolintPrefix) + for { + idx := strings.Index(comment.Text[startingIdx:], name) + if idx == -1 { + break + } + + if len(comment.Text[startingIdx+idx:]) == len(name) { + return true + } + + c := comment.Text[startingIdx+idx+len(name)] + if c == '.' || c == ',' || c == ' ' || c == ' ' { + return true + } + startingIdx += idx + 1 + } + } + + return false +} diff --git a/vendor/github.com/butuzov/ireturn/analyzer/std.go b/vendor/github.com/butuzov/ireturn/analyzer/std.go new file mode 100644 index 000000000..2af5284a3 --- /dev/null +++ b/vendor/github.com/butuzov/ireturn/analyzer/std.go @@ -0,0 +1,186 @@ +// Code generated using std.sh; DO NOT EDIT. + +// We will ignore that fact that some of packages +// were removed from stdlib. + +package analyzer + +var std = map[string]struct{}{ + // added in Go v1.2 in compare to v1.1 (docker image) + "archive/tar": {}, + "archive/zip": {}, + "bufio": {}, + "bytes": {}, + "cmd/cgo": {}, + "cmd/fix": {}, + "cmd/go": {}, + "cmd/gofmt": {}, + "cmd/yacc": {}, + "compress/bzip2": {}, + "compress/flate": {}, + "compress/gzip": {}, + "compress/lzw": {}, + "compress/zlib": {}, + "container/heap": {}, + "container/list": {}, + "container/ring": {}, + "crypto": {}, + "crypto/aes": {}, + "crypto/cipher": {}, + "crypto/des": {}, + "crypto/dsa": {}, + "crypto/ecdsa": {}, + "crypto/elliptic": {}, + "crypto/hmac": {}, + "crypto/md5": {}, + "crypto/rand": {}, + "crypto/rc4": {}, + "crypto/rsa": {}, + "crypto/sha1": {}, + "crypto/sha256": {}, + "crypto/sha512": {}, + "crypto/subtle": {}, + "crypto/tls": {}, + "crypto/x509": {}, + "crypto/x509/pkix": {}, + "database/sql": {}, + "database/sql/driver": {}, + "debug/dwarf": {}, + "debug/elf": {}, + "debug/gosym": {}, + "debug/macho": {}, + "debug/pe": {}, + "encoding": {}, + "encoding/ascii85": {}, + "encoding/asn1": {}, + "encoding/base32": {}, + "encoding/base64": {}, + "encoding/binary": {}, + "encoding/csv": {}, + "encoding/gob": {}, + "encoding/hex": {}, + "encoding/json": {}, + "encoding/pem": {}, + "encoding/xml": {}, + "errors": {}, + "expvar": {}, + "flag": {}, + "fmt": {}, + "go/ast": {}, + "go/build": {}, + "go/doc": {}, + "go/format": {}, + "go/parser": {}, + "go/printer": {}, + "go/scanner": {}, + "go/token": {}, + "hash": {}, + "hash/adler32": {}, + "hash/crc32": {}, + "hash/crc64": {}, + "hash/fnv": {}, + "html": {}, + "html/template": {}, + "image": {}, + "image/color": {}, + "image/color/palette": {}, + "image/draw": {}, + "image/gif": {}, + "image/jpeg": {}, + "image/png": {}, + "index/suffixarray": {}, + "io": {}, + "io/ioutil": {}, + "log": {}, + "log/syslog": {}, + "math": {}, + "math/big": {}, + "math/cmplx": {}, + "math/rand": {}, + "mime": {}, + "mime/multipart": {}, + "net": {}, + "net/http": {}, + "net/http/cgi": {}, + "net/http/cookiejar": {}, + "net/http/fcgi": {}, + "net/http/httptest": {}, + "net/http/httputil": {}, + "net/http/pprof": {}, + "net/mail": {}, + "net/rpc": {}, + "net/rpc/jsonrpc": {}, + "net/smtp": {}, + "net/textproto": {}, + "net/url": {}, + "os": {}, + "os/exec": {}, + "os/signal": {}, + "os/user": {}, + "path": {}, + "path/filepath": {}, + "reflect": {}, + "regexp": {}, + "regexp/syntax": {}, + "runtime": {}, + "runtime/cgo": {}, + "runtime/debug": {}, + "runtime/pprof": {}, + "runtime/race": {}, + "sort": {}, + "strconv": {}, + "strings": {}, + "sync": {}, + "sync/atomic": {}, + "syscall": {}, + "testing": {}, + "testing/iotest": {}, + "testing/quick": {}, + "text/scanner": {}, + "text/tabwriter": {}, + "text/template": {}, + "text/template/parse": {}, + "time": {}, + "unicode": {}, + "unicode/utf16": {}, + "unicode/utf8": {}, + "unsafe": {}, + // added in Go v1.3 in compare to v1.2 (docker image) + "cmd/addr2line": {}, + "cmd/nm": {}, + "cmd/objdump": {}, + "cmd/pack": {}, + "debug/plan9obj": {}, + // added in Go v1.4 in compare to v1.3 (docker image) + "cmd/pprof": {}, + // added in Go v1.5 in compare to v1.4 (docker image) + "go/constant": {}, + "go/importer": {}, + "go/types": {}, + "mime/quotedprintable": {}, + "runtime/trace": {}, + // added in Go v1.6 in compare to v1.5 (docker image) + // added in Go v1.7 in compare to v1.6 (docker image) + "context": {}, + "net/http/httptrace": {}, + // added in Go v1.8 in compare to v1.7 (docker image) + "plugin": {}, + // added in Go v1.9 in compare to v1.8 (docker image) + "math/bits": {}, + // added in Go v1.10 in compare to v1.9 (docker image) + // added in Go v1.11 in compare to v1.10 (docker image) + // added in Go v1.12 in compare to v1.11 (docker image) + // added in Go v1.13 in compare to v1.12 (docker image) + "crypto/ed25519": {}, + // added in Go v1.14 in compare to v1.13 (docker image) + "hash/maphash": {}, + // added in Go v1.15 in compare to v1.14 (docker image) + "time/tzdata": {}, + // added in Go v1.16 in compare to v1.15 (docker image) + "embed": {}, + "go/build/constraint": {}, + "io/fs": {}, + "runtime/metrics": {}, + "testing/fstest": {}, + // added in Go v1.17 in compare to v1.16 (docker image) +} diff --git a/vendor/github.com/butuzov/ireturn/config/allow.go b/vendor/github.com/butuzov/ireturn/config/allow.go new file mode 100644 index 000000000..c171a255d --- /dev/null +++ b/vendor/github.com/butuzov/ireturn/config/allow.go @@ -0,0 +1,17 @@ +package config + +import "github.com/butuzov/ireturn/types" + +// allowConfig specifies a list of interfaces (keywords, patters and regular expressions) +// that are allowed by ireturn as valid to return, any non listed interface are rejected. +type allowConfig struct { + *defaultConfig +} + +func allowAll(patterns []string) *allowConfig { + return &allowConfig{&defaultConfig{List: patterns}} +} + +func (ac *allowConfig) IsValid(i types.IFace) bool { + return ac.Has(i) +} diff --git a/vendor/github.com/butuzov/ireturn/config/config.go b/vendor/github.com/butuzov/ireturn/config/config.go new file mode 100644 index 000000000..7307ab3ea --- /dev/null +++ b/vendor/github.com/butuzov/ireturn/config/config.go @@ -0,0 +1,66 @@ +package config + +import ( + "regexp" + + "github.com/butuzov/ireturn/types" +) + +// defaultConfig is core of the validation, ... +// todo(butuzov): write proper intro... + +type defaultConfig struct { + List []string + + // private fields (for search optimization look ups) + init bool + quick uint8 + list []*regexp.Regexp +} + +func (config *defaultConfig) Has(i types.IFace) bool { + if !config.init { + config.compileList() + config.init = true + } + + if config.quick&uint8(i.Type) > 0 { + return true + } + + // not a named interface (because error, interface{}, anon interface has keywords.) + if i.Type&types.NamedInterface == 0 && i.Type&types.NamedStdInterface == 0 { + return false + } + + for _, re := range config.list { + if re.MatchString(i.Name) { + return true + } + } + + return false +} + +// compileList will transform text list into a bitmask for quick searches and +// slice of regular expressions for quick searches. +func (config *defaultConfig) compileList() { + for _, str := range config.List { + switch str { + case types.NameError: + config.quick |= uint8(types.ErrorInterface) + case types.NameEmpty: + config.quick |= uint8(types.EmptyInterface) + case types.NameAnon: + config.quick |= uint8(types.AnonInterface) + case types.NameStdLib: + config.quick |= uint8(types.NamedStdInterface) + } + + // allow to parse regular expressions + // todo(butuzov): how can we log error in golangci-lint? + if re, err := regexp.Compile(str); err == nil { + config.list = append(config.list, re) + } + } +} diff --git a/vendor/github.com/butuzov/ireturn/config/new.go b/vendor/github.com/butuzov/ireturn/config/new.go new file mode 100644 index 000000000..cfaa274a1 --- /dev/null +++ b/vendor/github.com/butuzov/ireturn/config/new.go @@ -0,0 +1,74 @@ +package config + +import ( + "errors" + "flag" + "strings" + + "github.com/butuzov/ireturn/types" +) + +var ErrCollisionOfInterests = errors.New("can't have both `-accept` and `-reject` specified at same time") + +//nolint: exhaustivestruct +func DefaultValidatorConfig() *allowConfig { + return allowAll([]string{ + types.NameEmpty, // "empty": empty interfaces (interface{}) + types.NameError, // "error": for all error's + types.NameAnon, // "anon": for all empty interfaces with methods (interface {Method()}) + types.NameStdLib, // "std": for all standard library packages + }) +} + +// New is factory function that return allowConfig or rejectConfig depending +// on provided arguments. +func New(fs *flag.FlagSet) (interface{}, error) { + var ( + allowList = toSlice(getFlagVal(fs, "allow")) + rejectList = toSlice(getFlagVal(fs, "reject")) + ) + + // can't have both at same time. + if len(allowList) != 0 && len(rejectList) != 0 { + return nil, ErrCollisionOfInterests + } + + switch { + case len(allowList) > 0: + return allowAll(allowList), nil + case len(rejectList) > 0: + return rejectAll(rejectList), nil + } + + // can have none at same time. + return nil, nil +} + +// both constants used to cleanup items provided in comma separated list. +const ( + SepTab string = " " + SepSpace string = " " +) + +func toSlice(s string) []string { + var results []string + + for _, pattern := range strings.Split(s, ",") { + pattern = strings.Trim(pattern, SepTab+SepSpace) + if pattern != "" { + results = append(results, pattern) + } + } + + return results +} + +func getFlagVal(fs *flag.FlagSet, name string) string { + flg := fs.Lookup(name) + + if flg == nil { + return "" + } + + return flg.Value.String() +} diff --git a/vendor/github.com/butuzov/ireturn/config/reject.go b/vendor/github.com/butuzov/ireturn/config/reject.go new file mode 100644 index 000000000..21e50114b --- /dev/null +++ b/vendor/github.com/butuzov/ireturn/config/reject.go @@ -0,0 +1,17 @@ +package config + +import "github.com/butuzov/ireturn/types" + +// rejectConfig specifies a list of interfaces (keywords, patters and regular expressions) +// that are rejected by ireturn as valid to return, any non listed interface are allowed. +type rejectConfig struct { + *defaultConfig +} + +func rejectAll(patterns []string) *rejectConfig { + return &rejectConfig{&defaultConfig{List: patterns}} +} + +func (rc *rejectConfig) IsValid(i types.IFace) bool { + return !rc.Has(i) +} diff --git a/vendor/github.com/butuzov/ireturn/types/iface.go b/vendor/github.com/butuzov/ireturn/types/iface.go new file mode 100644 index 000000000..e9baa37c0 --- /dev/null +++ b/vendor/github.com/butuzov/ireturn/types/iface.go @@ -0,0 +1,7 @@ +package types + +type IFace struct { + Name string // Preserved for named interfaces + Pos int // Position in return tuple + Type IType // Type of the interface +} diff --git a/vendor/github.com/butuzov/ireturn/types/names.go b/vendor/github.com/butuzov/ireturn/types/names.go new file mode 100644 index 000000000..0b286c4c8 --- /dev/null +++ b/vendor/github.com/butuzov/ireturn/types/names.go @@ -0,0 +1,8 @@ +package types + +const ( + NameEmpty = "empty" + NameAnon = "anon" + NameError = "error" + NameStdLib = "stdlib" +) diff --git a/vendor/github.com/butuzov/ireturn/types/types.go b/vendor/github.com/butuzov/ireturn/types/types.go new file mode 100644 index 000000000..837570db4 --- /dev/null +++ b/vendor/github.com/butuzov/ireturn/types/types.go @@ -0,0 +1,11 @@ +package types + +type IType uint8 + +const ( + EmptyInterface IType = 1 << iota // ref as empty + AnonInterface // ref as anon + ErrorInterface // ref as error + NamedInterface // ref as named + NamedStdInterface // ref as named stdlib +) |
