aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/mgechev/revive/rule/defer.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/mgechev/revive/rule/defer.go')
-rw-r--r--vendor/github.com/mgechev/revive/rule/defer.go137
1 files changed, 0 insertions, 137 deletions
diff --git a/vendor/github.com/mgechev/revive/rule/defer.go b/vendor/github.com/mgechev/revive/rule/defer.go
deleted file mode 100644
index 2ec7ef47c2..0000000000
--- a/vendor/github.com/mgechev/revive/rule/defer.go
+++ /dev/null
@@ -1,137 +0,0 @@
-package rule
-
-import (
- "fmt"
- "go/ast"
-
- "github.com/mgechev/revive/lint"
-)
-
-// DeferRule lints unused params in functions.
-type DeferRule struct{}
-
-// Apply applies the rule to given file.
-func (r *DeferRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
- allow := r.allowFromArgs(arguments)
-
- var failures []lint.Failure
- onFailure := func(failure lint.Failure) {
- failures = append(failures, failure)
- }
-
- w := lintDeferRule{onFailure: onFailure, allow: allow}
-
- ast.Walk(w, file.AST)
-
- return failures
-}
-
-// Name returns the rule name.
-func (r *DeferRule) Name() string {
- return "defer"
-}
-
-func (r *DeferRule) allowFromArgs(args lint.Arguments) map[string]bool {
- if len(args) < 1 {
- allow := map[string]bool{
- "loop": true,
- "call-chain": true,
- "method-call": true,
- "return": true,
- "recover": true,
- }
-
- return allow
- }
-
- aa, ok := args[0].([]interface{})
- if !ok {
- panic(fmt.Sprintf("Invalid argument '%v' for 'defer' rule. Expecting []string, got %T", args[0], args[0]))
- }
-
- allow := make(map[string]bool, len(aa))
- for _, subcase := range aa {
- sc, ok := subcase.(string)
- if !ok {
- panic(fmt.Sprintf("Invalid argument '%v' for 'defer' rule. Expecting string, got %T", subcase, subcase))
- }
- allow[sc] = true
- }
-
- return allow
-}
-
-type lintDeferRule struct {
- onFailure func(lint.Failure)
- inALoop bool
- inADefer bool
- inAFuncLit bool
- allow map[string]bool
-}
-
-func (w lintDeferRule) Visit(node ast.Node) ast.Visitor {
- switch n := node.(type) {
- case *ast.ForStmt:
- w.visitSubtree(n.Body, w.inADefer, true, w.inAFuncLit)
- return nil
- case *ast.RangeStmt:
- w.visitSubtree(n.Body, w.inADefer, true, w.inAFuncLit)
- return nil
- case *ast.FuncLit:
- w.visitSubtree(n.Body, w.inADefer, false, true)
- return nil
- case *ast.ReturnStmt:
- if len(n.Results) != 0 && w.inADefer && w.inAFuncLit {
- w.newFailure("return in a defer function has no effect", n, 1.0, "logic", "return")
- }
- case *ast.CallExpr:
- if isIdent(n.Fun, "recover") && !w.inADefer {
- // confidence is not 1 because recover can be in a function that is deferred elsewhere
- w.newFailure("recover must be called inside a deferred function", n, 0.8, "logic", "recover")
- }
- case *ast.DeferStmt:
- w.visitSubtree(n.Call.Fun, true, false, false)
-
- if w.inALoop {
- w.newFailure("prefer not to defer inside loops", n, 1.0, "bad practice", "loop")
- }
-
- switch fn := n.Call.Fun.(type) {
- case *ast.CallExpr:
- w.newFailure("prefer not to defer chains of function calls", fn, 1.0, "bad practice", "call-chain")
- case *ast.SelectorExpr:
- if id, ok := fn.X.(*ast.Ident); ok {
- isMethodCall := id != nil && id.Obj != nil && id.Obj.Kind == ast.Typ
- if isMethodCall {
- w.newFailure("be careful when deferring calls to methods without pointer receiver", fn, 0.8, "bad practice", "method-call")
- }
- }
- }
- return nil
- }
-
- return w
-}
-
-func (w lintDeferRule) visitSubtree(n ast.Node, inADefer, inALoop, inAFuncLit bool) {
- nw := &lintDeferRule{
- onFailure: w.onFailure,
- inADefer: inADefer,
- inALoop: inALoop,
- inAFuncLit: inAFuncLit,
- allow: w.allow}
- ast.Walk(nw, n)
-}
-
-func (w lintDeferRule) newFailure(msg string, node ast.Node, confidence float64, cat string, subcase string) {
- if !w.allow[subcase] {
- return
- }
-
- w.onFailure(lint.Failure{
- Confidence: confidence,
- Node: node,
- Category: cat,
- Failure: msg,
- })
-}