diff options
Diffstat (limited to 'vendor/github.com/mgechev/revive/rule/modifies-value-receiver.go')
-rw-r--r-- | vendor/github.com/mgechev/revive/rule/modifies-value-receiver.go | 134 |
1 files changed, 0 insertions, 134 deletions
diff --git a/vendor/github.com/mgechev/revive/rule/modifies-value-receiver.go b/vendor/github.com/mgechev/revive/rule/modifies-value-receiver.go deleted file mode 100644 index 4fe22ddf3f..0000000000 --- a/vendor/github.com/mgechev/revive/rule/modifies-value-receiver.go +++ /dev/null @@ -1,134 +0,0 @@ -package rule - -import ( - "go/ast" - "strings" - - "github.com/mgechev/revive/lint" -) - -// ModifiesValRecRule lints assignments to value method-receivers. -type ModifiesValRecRule struct{} - -// Apply applies the rule to given file. -func (r *ModifiesValRecRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - onFailure := func(failure lint.Failure) { - failures = append(failures, failure) - } - - w := lintModifiesValRecRule{file: file, onFailure: onFailure} - file.Pkg.TypeCheck() - ast.Walk(w, file.AST) - - return failures -} - -// Name returns the rule name. -func (r *ModifiesValRecRule) Name() string { - return "modifies-value-receiver" -} - -type lintModifiesValRecRule struct { - file *lint.File - onFailure func(lint.Failure) -} - -func (w lintModifiesValRecRule) Visit(node ast.Node) ast.Visitor { - switch n := node.(type) { - case *ast.FuncDecl: - if n.Recv == nil { - return nil // skip, not a method - } - - receiver := n.Recv.List[0] - if _, ok := receiver.Type.(*ast.StarExpr); ok { - return nil // skip, method with pointer receiver - } - - if w.skipType(receiver.Type) { - return nil // skip, receiver is a map or array - } - - if len(receiver.Names) < 1 { - return nil // skip, anonymous receiver - } - - receiverName := receiver.Names[0].Name - if receiverName == "_" { - return nil // skip, anonymous receiver - } - - fselect := func(n ast.Node) bool { - // look for assignments with the receiver in the right hand - asgmt, ok := n.(*ast.AssignStmt) - if !ok { - return false - } - - for _, exp := range asgmt.Lhs { - switch e := exp.(type) { - case *ast.IndexExpr: // receiver...[] = ... - continue - case *ast.StarExpr: // *receiver = ... - continue - case *ast.SelectorExpr: // receiver.field = ... - name := w.getNameFromExpr(e.X) - if name == "" || name != receiverName { - continue - } - - if w.skipType(ast.Expr(e.Sel)) { - continue - } - - case *ast.Ident: // receiver := ... - if e.Name != receiverName { - continue - } - default: - continue - } - - return true - } - - return false - } - - assignmentsToReceiver := pick(n.Body, fselect, nil) - - for _, assignment := range assignmentsToReceiver { - w.onFailure(lint.Failure{ - Node: assignment, - Confidence: 1, - Failure: "suspicious assignment to a by-value method receiver", - }) - } - } - - return w -} - -func (w lintModifiesValRecRule) skipType(t ast.Expr) bool { - rt := w.file.Pkg.TypeOf(t) - if rt == nil { - return false - } - - rt = rt.Underlying() - rtName := rt.String() - - // skip when receiver is a map or array - return strings.HasPrefix(rtName, "[]") || strings.HasPrefix(rtName, "map[") -} - -func (lintModifiesValRecRule) getNameFromExpr(ie ast.Expr) string { - ident, ok := ie.(*ast.Ident) - if !ok { - return "" - } - - return ident.Name -} |