diff options
| author | Taras Madan <tarasmadan@google.com> | 2025-01-22 16:07:17 +0100 |
|---|---|---|
| committer | Taras Madan <tarasmadan@google.com> | 2025-01-23 10:42:36 +0000 |
| commit | 7b4377ad9d8a7205416df8d6217ef2b010f89481 (patch) | |
| tree | e6fec4fd12ff807a16d847923f501075bf71d16c /vendor/github.com/polyfloyd | |
| parent | 475a4c203afb8b7d3af51c4fd32bb170ff32a45e (diff) | |
vendor: delete
Diffstat (limited to 'vendor/github.com/polyfloyd')
6 files changed, 0 insertions, 912 deletions
diff --git a/vendor/github.com/polyfloyd/go-errorlint/LICENSE b/vendor/github.com/polyfloyd/go-errorlint/LICENSE deleted file mode 100644 index b7f88cf1c..000000000 --- a/vendor/github.com/polyfloyd/go-errorlint/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2019 polyfloyd - -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/polyfloyd/go-errorlint/errorlint/allowed.go b/vendor/github.com/polyfloyd/go-errorlint/errorlint/allowed.go deleted file mode 100644 index c639af6f3..000000000 --- a/vendor/github.com/polyfloyd/go-errorlint/errorlint/allowed.go +++ /dev/null @@ -1,253 +0,0 @@ -package errorlint - -import ( - "fmt" - "go/ast" - "go/types" - "strings" -) - -type AllowPair struct { - Err string - Fun string -} - -var allowedErrorsMap = make(map[string]map[string]struct{}) - -func setDefaultAllowedErrors() { - allowedMapAppend([]AllowPair{ - // pkg/archive/tar - {Err: "io.EOF", Fun: "(*archive/tar.Reader).Next"}, - {Err: "io.EOF", Fun: "(*archive/tar.Reader).Read"}, - // pkg/bufio - {Err: "io.EOF", Fun: "(*bufio.Reader).Discard"}, - {Err: "io.EOF", Fun: "(*bufio.Reader).Peek"}, - {Err: "io.EOF", Fun: "(*bufio.Reader).Read"}, - {Err: "io.EOF", Fun: "(*bufio.Reader).ReadByte"}, - {Err: "io.EOF", Fun: "(*bufio.Reader).ReadBytes"}, - {Err: "io.EOF", Fun: "(*bufio.Reader).ReadLine"}, - {Err: "io.EOF", Fun: "(*bufio.Reader).ReadSlice"}, - {Err: "io.EOF", Fun: "(*bufio.Reader).ReadString"}, - {Err: "io.EOF", Fun: "(*bufio.Scanner).Scan"}, - // pkg/bytes - {Err: "io.EOF", Fun: "(*bytes.Buffer).Read"}, - {Err: "io.EOF", Fun: "(*bytes.Buffer).ReadByte"}, - {Err: "io.EOF", Fun: "(*bytes.Buffer).ReadBytes"}, - {Err: "io.EOF", Fun: "(*bytes.Buffer).ReadRune"}, - {Err: "io.EOF", Fun: "(*bytes.Buffer).ReadString"}, - {Err: "io.EOF", Fun: "(*bytes.Reader).Read"}, - {Err: "io.EOF", Fun: "(*bytes.Reader).ReadAt"}, - {Err: "io.EOF", Fun: "(*bytes.Reader).ReadByte"}, - {Err: "io.EOF", Fun: "(*bytes.Reader).ReadRune"}, - {Err: "io.EOF", Fun: "(*bytes.Reader).ReadString"}, - // pkg/database/sql - {Err: "database/sql.ErrNoRows", Fun: "(*database/sql.Row).Scan"}, - // pkg/debug/elf - {Err: "io.EOF", Fun: "debug/elf.Open"}, - {Err: "io.EOF", Fun: "debug/elf.NewFile"}, - // pkg/io - {Err: "io.EOF", Fun: "(io.ReadCloser).Read"}, - {Err: "io.EOF", Fun: "(io.Reader).Read"}, - {Err: "io.EOF", Fun: "(io.ReaderAt).ReadAt"}, - {Err: "io.EOF", Fun: "(*io.LimitedReader).Read"}, - {Err: "io.EOF", Fun: "(*io.SectionReader).Read"}, - {Err: "io.EOF", Fun: "(*io.SectionReader).ReadAt"}, - {Err: "io.ErrClosedPipe", Fun: "(*io.PipeWriter).Write"}, - {Err: "io.EOF", Fun: "io.ReadAtLeast"}, - {Err: "io.ErrShortBuffer", Fun: "io.ReadAtLeast"}, - {Err: "io.ErrUnexpectedEOF", Fun: "io.ReadAtLeast"}, - {Err: "io.EOF", Fun: "io.ReadFull"}, - {Err: "io.ErrUnexpectedEOF", Fun: "io.ReadFull"}, - // pkg/mime - {Err: "mime.ErrInvalidMediaParameter", Fun: "mime.ParseMediaType"}, - // pkg/net/http - {Err: "net/http.ErrServerClosed", Fun: "(*net/http.Server).ListenAndServe"}, - {Err: "net/http.ErrServerClosed", Fun: "(*net/http.Server).ListenAndServeTLS"}, - {Err: "net/http.ErrServerClosed", Fun: "(*net/http.Server).Serve"}, - {Err: "net/http.ErrServerClosed", Fun: "(*net/http.Server).ServeTLS"}, - {Err: "net/http.ErrServerClosed", Fun: "net/http.ListenAndServe"}, - {Err: "net/http.ErrServerClosed", Fun: "net/http.ListenAndServeTLS"}, - {Err: "net/http.ErrServerClosed", Fun: "net/http.Serve"}, - {Err: "net/http.ErrServerClosed", Fun: "net/http.ServeTLS"}, - // pkg/os - {Err: "io.EOF", Fun: "(*os.File).Read"}, - {Err: "io.EOF", Fun: "(*os.File).ReadAt"}, - {Err: "io.EOF", Fun: "(*os.File).ReadDir"}, - {Err: "io.EOF", Fun: "(*os.File).Readdir"}, - {Err: "io.EOF", Fun: "(*os.File).Readdirnames"}, - // pkg/strings - {Err: "io.EOF", Fun: "(*strings.Reader).Read"}, - {Err: "io.EOF", Fun: "(*strings.Reader).ReadAt"}, - {Err: "io.EOF", Fun: "(*strings.Reader).ReadByte"}, - {Err: "io.EOF", Fun: "(*strings.Reader).ReadRune"}, - // pkg/context - {Err: "context.DeadlineExceeded", Fun: "(context.Context).Err"}, - {Err: "context.Canceled", Fun: "(context.Context).Err"}, - // pkg/encoding/json - {Err: "io.EOF", Fun: "(*encoding/json.Decoder).Decode"}, - {Err: "io.EOF", Fun: "(*encoding/json.Decoder).Token"}, - // pkg/encoding/csv - {Err: "io.EOF", Fun: "(*encoding/csv.Reader).Read"}, - // pkg/mime/multipart - {Err: "io.EOF", Fun: "(*mime/multipart.Reader).NextPart"}, - {Err: "io.EOF", Fun: "(*mime/multipart.Reader).NextRawPart"}, - {Err: "mime/multipart.ErrMessageTooLarge", Fun: "(*mime/multipart.Reader).ReadForm"}, - }) -} - -func allowedMapAppend(ap []AllowPair) { - for _, pair := range ap { - if _, ok := allowedErrorsMap[pair.Err]; !ok { - allowedErrorsMap[pair.Err] = make(map[string]struct{}) - } - allowedErrorsMap[pair.Err][pair.Fun] = struct{}{} - } -} - -var allowedErrorWildcards = []AllowPair{ - // pkg/syscall - {Err: "syscall.E", Fun: "syscall."}, - // golang.org/x/sys/unix - {Err: "golang.org/x/sys/unix.E", Fun: "golang.org/x/sys/unix."}, -} - -func allowedWildcardAppend(ap []AllowPair) { - allowedErrorWildcards = append(allowedErrorWildcards, ap...) -} - -func isAllowedErrAndFunc(err, fun string) bool { - if allowedFuncs, allowErr := allowedErrorsMap[err]; allowErr { - if _, allow := allowedFuncs[fun]; allow { - return true - } - } - - for _, allow := range allowedErrorWildcards { - if strings.HasPrefix(fun, allow.Fun) && strings.HasPrefix(err, allow.Err) { - return true - } - } - - return false -} - -func isAllowedErrorComparison(pass *TypesInfoExt, a, b ast.Expr) bool { - var errName string // `<package>.<name>`, e.g. `io.EOF` - var callExprs []*ast.CallExpr - - // Figure out which half of the expression is the returned error and which - // half is the presumed error declaration. - for _, expr := range []ast.Expr{a, b} { - switch t := expr.(type) { - case *ast.SelectorExpr: - // A selector which we assume refers to a staticaly declared error - // in a package. - errName = selectorToString(pass, t) - case *ast.Ident: - // Identifier, most likely to be the `err` variable or whatever - // produces it. - callExprs = assigningCallExprs(pass, t, map[types.Object]bool{}) - case *ast.CallExpr: - callExprs = append(callExprs, t) - } - } - - // Unimplemented or not sure, disallow the expression. - if errName == "" || len(callExprs) == 0 { - return false - } - - // Map call expressions to the function name format of the allow list. - functionNames := make([]string, len(callExprs)) - for i, callExpr := range callExprs { - functionSelector, ok := callExpr.Fun.(*ast.SelectorExpr) - if !ok { - // If the function is not a selector it is not an Std function that is - // allowed. - return false - } - if sel, ok := pass.TypesInfo.Selections[functionSelector]; ok { - functionNames[i] = fmt.Sprintf("(%s).%s", sel.Recv(), sel.Obj().Name()) - } else { - // If there is no selection, assume it is a package. - functionNames[i] = selectorToString(pass, callExpr.Fun.(*ast.SelectorExpr)) - } - } - - // All assignments done must be allowed. - for _, funcName := range functionNames { - if !isAllowedErrAndFunc(errName, funcName) { - return false - } - } - return true -} - -// assigningCallExprs finds all *ast.CallExpr nodes that are part of an -// *ast.AssignStmt that assign to the subject identifier. -func assigningCallExprs(pass *TypesInfoExt, subject *ast.Ident, visitedObjects map[types.Object]bool) []*ast.CallExpr { - if subject.Obj == nil { - return nil - } - - // Find other identifiers that reference this same object. - sobj := pass.TypesInfo.ObjectOf(subject) - - if visitedObjects[sobj] { - return nil - } - visitedObjects[sobj] = true - - // Make sure to exclude the subject identifier as it will cause an infinite recursion and is - // being used in a read operation anyway. - identifiers := []*ast.Ident{} - for _, ident := range pass.IdentifiersForObject[sobj] { - if subject.Pos() != ident.Pos() { - identifiers = append(identifiers, ident) - } - } - - // Find out whether the identifiers are part of an assignment statement. - var callExprs []*ast.CallExpr - for _, ident := range identifiers { - parent := pass.NodeParent[ident] - switch declT := parent.(type) { - case *ast.AssignStmt: - // The identifier is LHS of an assignment. - assignment := declT - - assigningExpr := assignment.Rhs[0] - // If the assignment is comprised of multiple expressions, find out - // which RHS expression we should use by finding its index in the LHS. - if len(assignment.Lhs) == len(assignment.Rhs) { - for i, lhs := range assignment.Lhs { - if ident, ok := lhs.(*ast.Ident); ok && subject.Name == ident.Name { - assigningExpr = assignment.Rhs[i] - break - } - } - } - - switch assignT := assigningExpr.(type) { - case *ast.CallExpr: - // Found the function call. - callExprs = append(callExprs, assignT) - case *ast.Ident: - // Skip assignments here the RHS points to the same object as the subject. - if assignT.Obj == subject.Obj { - continue - } - // The subject was the result of assigning from another identifier. - callExprs = append(callExprs, assigningCallExprs(pass, assignT, visitedObjects)...) - default: - // TODO: inconclusive? - } - } - } - return callExprs -} - -func selectorToString(pass *TypesInfoExt, selExpr *ast.SelectorExpr) string { - o := pass.TypesInfo.Uses[selExpr.Sel] - return fmt.Sprintf("%s.%s", o.Pkg().Path(), o.Name()) -} diff --git a/vendor/github.com/polyfloyd/go-errorlint/errorlint/analysis.go b/vendor/github.com/polyfloyd/go-errorlint/errorlint/analysis.go deleted file mode 100644 index 84ebd6cf8..000000000 --- a/vendor/github.com/polyfloyd/go-errorlint/errorlint/analysis.go +++ /dev/null @@ -1,116 +0,0 @@ -package errorlint - -import ( - "go/ast" - "go/types" - "sort" - - "golang.org/x/tools/go/analysis" -) - -func NewAnalyzer(opts ...Option) *analysis.Analyzer { - for _, o := range opts { - o() - } - - setDefaultAllowedErrors() - - a := &analysis.Analyzer{ - Name: "errorlint", - Doc: "Source code linter for Go software that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13.", - Run: run, - } - - a.Flags.BoolVar(&checkComparison, "comparison", true, "Check for plain error comparisons") - a.Flags.BoolVar(&checkAsserts, "asserts", true, "Check for plain type assertions and type switches") - a.Flags.BoolVar(&checkErrorf, "errorf", false, "Check whether fmt.Errorf uses the %w verb for formatting errors. See the readme for caveats") - a.Flags.BoolVar(&checkErrorfMulti, "errorf-multi", true, "Permit more than 1 %w verb, valid per Go 1.20 (Requires -errorf=true)") - - return a -} - -var ( - checkComparison bool - checkAsserts bool - checkErrorf bool - checkErrorfMulti bool -) - -func run(pass *analysis.Pass) (interface{}, error) { - var lints []analysis.Diagnostic - extInfo := newTypesInfoExt(pass) - if checkComparison { - l := LintErrorComparisons(extInfo) - lints = append(lints, l...) - } - if checkAsserts { - l := LintErrorTypeAssertions(pass.Fset, extInfo) - lints = append(lints, l...) - } - if checkErrorf { - l := LintFmtErrorfCalls(pass.Fset, *pass.TypesInfo, checkErrorfMulti) - lints = append(lints, l...) - } - sort.Sort(ByPosition(lints)) - - for _, l := range lints { - pass.Report(l) - } - return nil, nil -} - -type TypesInfoExt struct { - *analysis.Pass - - // Maps AST nodes back to the node they are contained within. - NodeParent map[ast.Node]ast.Node - - // Maps an object back to all identifiers to refer to it. - IdentifiersForObject map[types.Object][]*ast.Ident -} - -func newTypesInfoExt(pass *analysis.Pass) *TypesInfoExt { - nodeParent := map[ast.Node]ast.Node{} - for node := range pass.TypesInfo.Scopes { - file, ok := node.(*ast.File) - if !ok { - continue - } - stack := []ast.Node{file} - ast.Inspect(file, func(n ast.Node) bool { - nodeParent[n] = stack[len(stack)-1] - if n == nil { - stack = stack[:len(stack)-1] - } else { - stack = append(stack, n) - } - return true - }) - } - - identifiersForObject := map[types.Object][]*ast.Ident{} - for node, obj := range pass.TypesInfo.Defs { - identifiersForObject[obj] = append(identifiersForObject[obj], node) - } - for node, obj := range pass.TypesInfo.Uses { - identifiersForObject[obj] = append(identifiersForObject[obj], node) - } - - return &TypesInfoExt{ - Pass: pass, - NodeParent: nodeParent, - IdentifiersForObject: identifiersForObject, - } -} - -func (info *TypesInfoExt) ContainingFuncDecl(node ast.Node) *ast.FuncDecl { - for parent := info.NodeParent[node]; ; parent = info.NodeParent[parent] { - if _, ok := parent.(*ast.File); ok { - break - } - if fun, ok := parent.(*ast.FuncDecl); ok { - return fun - } - } - return nil -} diff --git a/vendor/github.com/polyfloyd/go-errorlint/errorlint/lint.go b/vendor/github.com/polyfloyd/go-errorlint/errorlint/lint.go deleted file mode 100644 index ed3dd0dc6..000000000 --- a/vendor/github.com/polyfloyd/go-errorlint/errorlint/lint.go +++ /dev/null @@ -1,385 +0,0 @@ -package errorlint - -import ( - "fmt" - "go/ast" - "go/constant" - "go/token" - "go/types" - - "golang.org/x/tools/go/analysis" -) - -type ByPosition []analysis.Diagnostic - -func (l ByPosition) Len() int { return len(l) } -func (l ByPosition) Swap(i, j int) { l[i], l[j] = l[j], l[i] } - -func (l ByPosition) Less(i, j int) bool { - return l[i].Pos < l[j].Pos -} - -func LintFmtErrorfCalls(fset *token.FileSet, info types.Info, multipleWraps bool) []analysis.Diagnostic { - var lints []analysis.Diagnostic - - for expr, t := range info.Types { - // Search for error expressions that are the result of fmt.Errorf - // invocations. - if t.Type.String() != "error" { - continue - } - call, ok := isFmtErrorfCallExpr(info, expr) - if !ok { - continue - } - - // Find all % fields in the format string. - formatVerbs, ok := printfFormatStringVerbs(info, call) - if !ok { - continue - } - - // For any arguments that are errors, check whether the wrapping verb is used. %w may occur - // for multiple errors in one Errorf invocation, unless multipleWraps is true. We raise an - // issue if at least one error does not have a corresponding wrapping verb. - args := call.Args[1:] - if !multipleWraps { - wrapCount := 0 - for i := 0; i < len(args) && i < len(formatVerbs); i++ { - arg := args[i] - if !implementsError(info.Types[arg].Type) { - continue - } - verb := formatVerbs[i] - - if verb.format == "w" { - wrapCount++ - if wrapCount > 1 { - lints = append(lints, analysis.Diagnostic{ - Message: "only one %w verb is permitted per format string", - Pos: arg.Pos(), - }) - break - } - } - - if wrapCount == 0 { - lints = append(lints, analysis.Diagnostic{ - Message: "non-wrapping format verb for fmt.Errorf. Use `%w` to format errors", - Pos: args[i].Pos(), - }) - break - } - } - - } else { - var lint *analysis.Diagnostic - argIndex := 0 - for _, verb := range formatVerbs { - if verb.index != -1 { - argIndex = verb.index - } else { - argIndex++ - } - - if verb.format == "w" || verb.format == "T" { - continue - } - if argIndex-1 >= len(args) { - continue - } - arg := args[argIndex-1] - if !implementsError(info.Types[arg].Type) { - continue - } - - strStart := call.Args[0].Pos() - if lint == nil { - lint = &analysis.Diagnostic{ - Message: "non-wrapping format verb for fmt.Errorf. Use `%w` to format errors", - Pos: arg.Pos(), - } - } - lint.SuggestedFixes = append(lint.SuggestedFixes, analysis.SuggestedFix{ - Message: "Use `%w` to format errors", - TextEdits: []analysis.TextEdit{{ - Pos: strStart + token.Pos(verb.formatOffset) + 1, - End: strStart + token.Pos(verb.formatOffset) + 2, - NewText: []byte("w"), - }}, - }) - } - if lint != nil { - lints = append(lints, *lint) - } - } - } - return lints -} - -// printfFormatStringVerbs returns a normalized list of all the verbs that are used per argument to -// the printf function. The index of each returned element corresponds to the index of the -// respective argument. -func printfFormatStringVerbs(info types.Info, call *ast.CallExpr) ([]verb, bool) { - if len(call.Args) <= 1 { - return nil, false - } - strLit, ok := call.Args[0].(*ast.BasicLit) - if !ok { - // Ignore format strings that are not literals. - return nil, false - } - formatString := constant.StringVal(info.Types[strLit].Value) - - pp := printfParser{str: formatString} - verbs, err := pp.ParseAllVerbs() - if err != nil { - return nil, false - } - - return verbs, true -} - -func isFmtErrorfCallExpr(info types.Info, expr ast.Expr) (*ast.CallExpr, bool) { - call, ok := expr.(*ast.CallExpr) - if !ok { - return nil, false - } - fn, ok := call.Fun.(*ast.SelectorExpr) - if !ok { - // TODO: Support fmt.Errorf variable aliases? - return nil, false - } - obj := info.Uses[fn.Sel] - - pkg := obj.Pkg() - if pkg != nil && pkg.Name() == "fmt" && obj.Name() == "Errorf" { - return call, true - } - return nil, false -} - -func LintErrorComparisons(info *TypesInfoExt) []analysis.Diagnostic { - var lints []analysis.Diagnostic - - for expr := range info.TypesInfo.Types { - // Find == and != operations. - binExpr, ok := expr.(*ast.BinaryExpr) - if !ok { - continue - } - if binExpr.Op != token.EQL && binExpr.Op != token.NEQ { - continue - } - // Comparing errors with nil is okay. - if isNil(binExpr.X) || isNil(binExpr.Y) { - continue - } - // Find comparisons of which one side is a of type error. - if !isErrorType(info.TypesInfo, binExpr.X) && !isErrorType(info.TypesInfo, binExpr.Y) { - continue - } - // Some errors that are returned from some functions are exempt. - if isAllowedErrorComparison(info, binExpr.X, binExpr.Y) { - continue - } - // Comparisons that happen in `func (type) Is(error) bool` are okay. - if isNodeInErrorIsFunc(info, binExpr) { - continue - } - - lints = append(lints, analysis.Diagnostic{ - Message: fmt.Sprintf("comparing with %s will fail on wrapped errors. Use errors.Is to check for a specific error", binExpr.Op), - Pos: binExpr.Pos(), - }) - } - - for scope := range info.TypesInfo.Scopes { - // Find value switch blocks. - switchStmt, ok := scope.(*ast.SwitchStmt) - if !ok { - continue - } - // Check whether the switch operates on an error type. - if !isErrorType(info.TypesInfo, switchStmt.Tag) { - continue - } - - var problematicCaseClause *ast.CaseClause - outer: - for _, stmt := range switchStmt.Body.List { - caseClause := stmt.(*ast.CaseClause) - for _, caseExpr := range caseClause.List { - if isNil(caseExpr) { - continue - } - // Some errors that are returned from some functions are exempt. - if !isAllowedErrorComparison(info, switchStmt.Tag, caseExpr) { - problematicCaseClause = caseClause - break outer - } - } - } - if problematicCaseClause == nil { - continue - } - // Comparisons that happen in `func (type) Is(error) bool` are okay. - if isNodeInErrorIsFunc(info, switchStmt) { - continue - } - - if switchComparesNonNil(switchStmt) { - lints = append(lints, analysis.Diagnostic{ - Message: "switch on an error will fail on wrapped errors. Use errors.Is to check for specific errors", - Pos: problematicCaseClause.Pos(), - }) - } - } - - return lints -} - -func isNil(ex ast.Expr) bool { - ident, ok := ex.(*ast.Ident) - return ok && ident.Name == "nil" -} - -func isErrorType(info *types.Info, ex ast.Expr) bool { - t := info.Types[ex].Type - return t != nil && t.String() == "error" -} - -func isNodeInErrorIsFunc(info *TypesInfoExt, node ast.Node) bool { - funcDecl := info.ContainingFuncDecl(node) - if funcDecl == nil { - return false - } - - if funcDecl.Name.Name != "Is" { - return false - } - if funcDecl.Recv == nil { - return false - } - // There should be 1 argument of type error. - if ii := funcDecl.Type.Params.List; len(ii) != 1 || info.TypesInfo.Types[ii[0].Type].Type.String() != "error" { - return false - } - // The return type should be bool. - if ii := funcDecl.Type.Results.List; len(ii) != 1 || info.TypesInfo.Types[ii[0].Type].Type.String() != "bool" { - return false - } - - return true -} - -// switchComparesNonNil returns true if one of its clauses compares by value. -func switchComparesNonNil(switchStmt *ast.SwitchStmt) bool { - for _, caseBlock := range switchStmt.Body.List { - caseClause, ok := caseBlock.(*ast.CaseClause) - if !ok { - continue - } - for _, clause := range caseClause.List { - switch clause := clause.(type) { - case nil: - // default label is safe - continue - case *ast.Ident: - // `case nil` is safe - if clause.Name == "nil" { - continue - } - } - // anything else (including an Ident other than nil) isn't safe - return true - } - } - return false -} - -func LintErrorTypeAssertions(fset *token.FileSet, info *TypesInfoExt) []analysis.Diagnostic { - var lints []analysis.Diagnostic - - for expr := range info.TypesInfo.Types { - // Find type assertions. - typeAssert, ok := expr.(*ast.TypeAssertExpr) - if !ok { - continue - } - - // Find type assertions that operate on values of type error. - if !isErrorTypeAssertion(*info.TypesInfo, typeAssert) { - continue - } - - if isNodeInErrorIsFunc(info, typeAssert) { - continue - } - - // If the asserted type is not an error, allow the expression. - if !implementsError(info.TypesInfo.Types[typeAssert.Type].Type) { - continue - } - - lints = append(lints, analysis.Diagnostic{ - Message: "type assertion on error will fail on wrapped errors. Use errors.As to check for specific errors", - Pos: typeAssert.Pos(), - }) - } - - for scope := range info.TypesInfo.Scopes { - // Find type switches. - typeSwitch, ok := scope.(*ast.TypeSwitchStmt) - if !ok { - continue - } - - // Find the type assertion in the type switch. - var typeAssert *ast.TypeAssertExpr - switch t := typeSwitch.Assign.(type) { - case *ast.ExprStmt: - typeAssert = t.X.(*ast.TypeAssertExpr) - case *ast.AssignStmt: - typeAssert = t.Rhs[0].(*ast.TypeAssertExpr) - } - - // Check whether the type switch is on a value of type error. - if !isErrorTypeAssertion(*info.TypesInfo, typeAssert) { - continue - } - - if isNodeInErrorIsFunc(info, typeSwitch) { - continue - } - - lints = append(lints, analysis.Diagnostic{ - Message: "type switch on error will fail on wrapped errors. Use errors.As to check for specific errors", - Pos: typeAssert.Pos(), - }) - } - - return lints -} - -func isErrorTypeAssertion(info types.Info, typeAssert *ast.TypeAssertExpr) bool { - t := info.Types[typeAssert.X] - return t.Type.String() == "error" -} - -func implementsError(t types.Type) bool { - mset := types.NewMethodSet(t) - - for i := 0; i < mset.Len(); i++ { - if mset.At(i).Kind() != types.MethodVal { - continue - } - - obj := mset.At(i).Obj() - if obj.Name() == "Error" && obj.Type().String() == "func() string" { - return true - } - } - - return false -} diff --git a/vendor/github.com/polyfloyd/go-errorlint/errorlint/options.go b/vendor/github.com/polyfloyd/go-errorlint/errorlint/options.go deleted file mode 100644 index 4d7c742d8..000000000 --- a/vendor/github.com/polyfloyd/go-errorlint/errorlint/options.go +++ /dev/null @@ -1,15 +0,0 @@ -package errorlint - -type Option func() - -func WithAllowedErrors(ap []AllowPair) Option { - return func() { - allowedMapAppend(ap) - } -} - -func WithAllowedWildcard(ap []AllowPair) Option { - return func() { - allowedWildcardAppend(ap) - } -} diff --git a/vendor/github.com/polyfloyd/go-errorlint/errorlint/printf.go b/vendor/github.com/polyfloyd/go-errorlint/errorlint/printf.go deleted file mode 100644 index 4c0e12525..000000000 --- a/vendor/github.com/polyfloyd/go-errorlint/errorlint/printf.go +++ /dev/null @@ -1,122 +0,0 @@ -package errorlint - -import ( - "fmt" - "io" - "strconv" - "strings" -) - -type verb struct { - format string - formatOffset int - index int -} - -type printfParser struct { - str string - at int -} - -func (pp *printfParser) ParseAllVerbs() ([]verb, error) { - verbs := []verb{} - for { - verb, err := pp.parseVerb() - if err == io.EOF { - break - } else if err != nil { - return nil, err - } - verbs = append(verbs, *verb) - } - return verbs, nil -} - -func (pp *printfParser) parseVerb() (*verb, error) { - if err := pp.skipToPercent(); err != nil { - return nil, err - } - if pp.next() != '%' { - return nil, fmt.Errorf("expected '%%'") - } - - index := -1 - for { - switch pp.peek() { - case '%': - pp.next() - return pp.parseVerb() - case '+', '#': - pp.next() - continue - case '[': - var err error - index, err = pp.parseIndex() - if err != nil { - return nil, err - } - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.': - pp.parsePrecision() - case 0: - return nil, io.EOF - } - break - } - - format := pp.next() - - return &verb{format: string(format), formatOffset: pp.at - 1, index: index}, nil -} - -func (pp *printfParser) parseIndex() (int, error) { - if pp.next() != '[' { - return -1, fmt.Errorf("expected '['") - } - end := strings.Index(pp.str, "]") - if end == -1 { - return -1, fmt.Errorf("unterminated indexed verb") - } - index, err := strconv.Atoi(pp.str[:end]) - if err != nil { - return -1, err - } - pp.str = pp.str[end+1:] - pp.at += end + 1 - return index, nil -} - -func (pp *printfParser) parsePrecision() { - for { - if r := pp.peek(); (r < '0' || '9' < r) && r != '.' { - break - } - pp.next() - } -} - -func (pp *printfParser) skipToPercent() error { - i := strings.Index(pp.str, "%") - if i == -1 { - return io.EOF - } - pp.str = pp.str[i:] - pp.at += i - return nil -} - -func (pp *printfParser) peek() rune { - if len(pp.str) == 0 { - return 0 - } - return rune(pp.str[0]) -} - -func (pp *printfParser) next() rune { - if len(pp.str) == 0 { - return 0 - } - r := rune(pp.str[0]) - pp.str = pp.str[1:] - pp.at++ - return r -} |
