aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/mgechev/revive
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/mgechev/revive')
-rw-r--r--vendor/github.com/mgechev/revive/formatter/friendly.go21
-rw-r--r--vendor/github.com/mgechev/revive/rule/cognitive-complexity.go4
-rw-r--r--vendor/github.com/mgechev/revive/rule/defer.go137
-rw-r--r--vendor/github.com/mgechev/revive/rule/early-return.go78
-rw-r--r--vendor/github.com/mgechev/revive/rule/empty-block.go63
-rw-r--r--vendor/github.com/mgechev/revive/rule/identical-branches.go82
-rw-r--r--vendor/github.com/mgechev/revive/rule/unconditional-recursion.go183
-rw-r--r--vendor/github.com/mgechev/revive/rule/unexported-naming.go115
-rw-r--r--vendor/github.com/mgechev/revive/rule/unused-receiver.go4
-rw-r--r--vendor/github.com/mgechev/revive/rule/utils.go4
10 files changed, 639 insertions, 52 deletions
diff --git a/vendor/github.com/mgechev/revive/formatter/friendly.go b/vendor/github.com/mgechev/revive/formatter/friendly.go
index a543eebe00..d0a3099f8f 100644
--- a/vendor/github.com/mgechev/revive/formatter/friendly.go
+++ b/vendor/github.com/mgechev/revive/formatter/friendly.go
@@ -10,11 +10,6 @@ import (
"github.com/olekukonko/tablewriter"
)
-var (
- errorEmoji = color.RedString("✘")
- warningEmoji = color.YellowString("⚠")
-)
-
var newLines = map[rune]bool{
0x000A: true,
0x000B: true,
@@ -25,6 +20,14 @@ var newLines = map[rune]bool{
0x2029: true,
}
+func getErrorEmoji() string {
+ return color.RedString("✘")
+}
+
+func getWarningEmoji() string {
+ return color.YellowString("⚠")
+}
+
// Friendly is an implementation of the Formatter interface
// which formats the errors to JSON.
type Friendly struct {
@@ -68,9 +71,9 @@ func (f *Friendly) printFriendlyFailure(failure lint.Failure, severity lint.Seve
}
func (f *Friendly) printHeaderRow(failure lint.Failure, severity lint.Severity) {
- emoji := warningEmoji
+ emoji := getWarningEmoji()
if severity == lint.SeverityError {
- emoji = errorEmoji
+ emoji = getErrorEmoji()
}
fmt.Print(f.table([][]string{{emoji, "https://revive.run/r#" + failure.RuleName, color.GreenString(failure.Failure)}}))
}
@@ -85,9 +88,9 @@ type statEntry struct {
}
func (f *Friendly) printSummary(errors, warnings int) {
- emoji := warningEmoji
+ emoji := getWarningEmoji()
if errors > 0 {
- emoji = errorEmoji
+ emoji = getErrorEmoji()
}
problemsLabel := "problems"
if errors+warnings == 1 {
diff --git a/vendor/github.com/mgechev/revive/rule/cognitive-complexity.go b/vendor/github.com/mgechev/revive/rule/cognitive-complexity.go
index 711aa22897..ccd36bd09f 100644
--- a/vendor/github.com/mgechev/revive/rule/cognitive-complexity.go
+++ b/vendor/github.com/mgechev/revive/rule/cognitive-complexity.go
@@ -52,7 +52,7 @@ type cognitiveComplexityLinter struct {
func (w cognitiveComplexityLinter) lint() {
f := w.file
for _, decl := range f.AST.Decls {
- if fn, ok := decl.(*ast.FuncDecl); ok {
+ if fn, ok := decl.(*ast.FuncDecl); ok && fn.Body != nil {
v := cognitiveComplexityVisitor{}
c := v.subTreeComplexity(fn.Body)
if c > w.maxComplexity {
@@ -109,7 +109,7 @@ func (v *cognitiveComplexityVisitor) Visit(n ast.Node) ast.Visitor {
return nil // skip visiting binexp sub-tree (already visited by binExpComplexity)
case *ast.BranchStmt:
if n.Label != nil {
- v.complexity += 1
+ v.complexity++
}
}
// TODO handle (at least) direct recursion
diff --git a/vendor/github.com/mgechev/revive/rule/defer.go b/vendor/github.com/mgechev/revive/rule/defer.go
new file mode 100644
index 0000000000..2ec7ef47c2
--- /dev/null
+++ b/vendor/github.com/mgechev/revive/rule/defer.go
@@ -0,0 +1,137 @@
+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,
+ })
+}
diff --git a/vendor/github.com/mgechev/revive/rule/early-return.go b/vendor/github.com/mgechev/revive/rule/early-return.go
new file mode 100644
index 0000000000..ffb568a867
--- /dev/null
+++ b/vendor/github.com/mgechev/revive/rule/early-return.go
@@ -0,0 +1,78 @@
+package rule
+
+import (
+ "go/ast"
+
+ "github.com/mgechev/revive/lint"
+)
+
+// EarlyReturnRule lints given else constructs.
+type EarlyReturnRule struct{}
+
+// Apply applies the rule to given file.
+func (r *EarlyReturnRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
+ var failures []lint.Failure
+
+ onFailure := func(failure lint.Failure) {
+ failures = append(failures, failure)
+ }
+
+ w := lintEarlyReturnRule{onFailure: onFailure}
+ ast.Walk(w, file.AST)
+ return failures
+}
+
+// Name returns the rule name.
+func (r *EarlyReturnRule) Name() string {
+ return "early-return"
+}
+
+type lintEarlyReturnRule struct {
+ onFailure func(lint.Failure)
+}
+
+func (w lintEarlyReturnRule) Visit(node ast.Node) ast.Visitor {
+ switch n := node.(type) {
+ case *ast.IfStmt:
+ if n.Else == nil {
+ // no else branch
+ return w
+ }
+
+ elseBlock, ok := n.Else.(*ast.BlockStmt)
+ if !ok {
+ // is if-else-if
+ return w
+ }
+
+ lenElseBlock := len(elseBlock.List)
+ if lenElseBlock < 1 {
+ // empty else block, continue (there is another rule that warns on empty blocks)
+ return w
+ }
+
+ lenThenBlock := len(n.Body.List)
+ if lenThenBlock < 1 {
+ // then block is empty thus the stmt can be simplified
+ w.onFailure(lint.Failure{
+ Confidence: 1,
+ Node: n,
+ Failure: "if c { } else {... return} can be simplified to if !c { ... return }",
+ })
+
+ return w
+ }
+
+ _, lastThenStmtIsReturn := n.Body.List[lenThenBlock-1].(*ast.ReturnStmt)
+ _, lastElseStmtIsReturn := elseBlock.List[lenElseBlock-1].(*ast.ReturnStmt)
+ if lastElseStmtIsReturn && !lastThenStmtIsReturn {
+ w.onFailure(lint.Failure{
+ Confidence: 1,
+ Node: n,
+ Failure: "if c {...} else {... return } can be simplified to if !c { ... return } ...",
+ })
+ }
+ }
+
+ return w
+}
diff --git a/vendor/github.com/mgechev/revive/rule/empty-block.go b/vendor/github.com/mgechev/revive/rule/empty-block.go
index 7861394b32..fbec4d93c5 100644
--- a/vendor/github.com/mgechev/revive/rule/empty-block.go
+++ b/vendor/github.com/mgechev/revive/rule/empty-block.go
@@ -17,7 +17,7 @@ func (r *EmptyBlockRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure
failures = append(failures, failure)
}
- w := lintEmptyBlock{make([]*ast.BlockStmt, 0), onFailure}
+ w := lintEmptyBlock{make(map[*ast.BlockStmt]bool, 0), onFailure}
ast.Walk(w, file.AST)
return failures
}
@@ -28,49 +28,38 @@ func (r *EmptyBlockRule) Name() string {
}
type lintEmptyBlock struct {
- ignore []*ast.BlockStmt
+ ignore map[*ast.BlockStmt]bool
onFailure func(lint.Failure)
}
func (w lintEmptyBlock) Visit(node ast.Node) ast.Visitor {
- fd, ok := node.(*ast.FuncDecl)
- if ok {
- w.ignore = append(w.ignore, fd.Body)
+ switch n := node.(type) {
+ case *ast.FuncDecl:
+ w.ignore[n.Body] = true
return w
- }
-
- fl, ok := node.(*ast.FuncLit)
- if ok {
- w.ignore = append(w.ignore, fl.Body)
- return w
- }
-
- block, ok := node.(*ast.BlockStmt)
- if !ok {
- return w
- }
-
- if mustIgnore(block, w.ignore) {
+ case *ast.FuncLit:
+ w.ignore[n.Body] = true
return w
- }
-
- if len(block.List) == 0 {
- w.onFailure(lint.Failure{
- Confidence: 1,
- Node: block,
- Category: "logic",
- Failure: "this block is empty, you can remove it",
- })
+ case *ast.RangeStmt:
+ if len(n.Body.List) == 0 {
+ w.onFailure(lint.Failure{
+ Confidence: 0.9,
+ Node: n,
+ Category: "logic",
+ Failure: "this block is empty, you can remove it",
+ })
+ return nil // skip visiting the range subtree (it will produce a duplicated failure)
+ }
+ case *ast.BlockStmt:
+ if !w.ignore[n] && len(n.List) == 0 {
+ w.onFailure(lint.Failure{
+ Confidence: 1,
+ Node: n,
+ Category: "logic",
+ Failure: "this block is empty, you can remove it",
+ })
+ }
}
return w
}
-
-func mustIgnore(block *ast.BlockStmt, blackList []*ast.BlockStmt) bool {
- for _, b := range blackList {
- if b == block {
- return true
- }
- }
- return false
-}
diff --git a/vendor/github.com/mgechev/revive/rule/identical-branches.go b/vendor/github.com/mgechev/revive/rule/identical-branches.go
new file mode 100644
index 0000000000..094a79147b
--- /dev/null
+++ b/vendor/github.com/mgechev/revive/rule/identical-branches.go
@@ -0,0 +1,82 @@
+package rule
+
+import (
+ "go/ast"
+
+ "github.com/mgechev/revive/lint"
+)
+
+// IdenticalBranchesRule warns on constant logical expressions.
+type IdenticalBranchesRule struct{}
+
+// Apply applies the rule to given file.
+func (r *IdenticalBranchesRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
+ var failures []lint.Failure
+
+ onFailure := func(failure lint.Failure) {
+ failures = append(failures, failure)
+ }
+
+ astFile := file.AST
+ w := &lintIdenticalBranches{astFile, onFailure}
+ ast.Walk(w, astFile)
+ return failures
+}
+
+// Name returns the rule name.
+func (r *IdenticalBranchesRule) Name() string {
+ return "identical-branches"
+}
+
+type lintIdenticalBranches struct {
+ file *ast.File
+ onFailure func(lint.Failure)
+}
+
+func (w *lintIdenticalBranches) Visit(node ast.Node) ast.Visitor {
+ n, ok := node.(*ast.IfStmt)
+ if !ok {
+ return w
+ }
+
+ if n.Else == nil {
+ return w
+ }
+ branches := []*ast.BlockStmt{n.Body}
+
+ elseBranch, ok := n.Else.(*ast.BlockStmt)
+ if !ok { // if-else-if construction
+ return w
+ }
+ branches = append(branches, elseBranch)
+
+ if w.identicalBranches(branches) {
+ w.newFailure(n, "both branches of the if are identical")
+ }
+
+ return w
+}
+
+func (w *lintIdenticalBranches) identicalBranches(branches []*ast.BlockStmt) bool {
+ if len(branches) < 2 {
+ return false
+ }
+
+ ref := gofmt(branches[0])
+ for i := 1; i < len(branches); i++ {
+ if gofmt(branches[i]) != ref {
+ return false
+ }
+ }
+
+ return true
+}
+
+func (w lintIdenticalBranches) newFailure(node ast.Node, msg string) {
+ w.onFailure(lint.Failure{
+ Confidence: 1,
+ Node: node,
+ Category: "logic",
+ Failure: msg,
+ })
+}
diff --git a/vendor/github.com/mgechev/revive/rule/unconditional-recursion.go b/vendor/github.com/mgechev/revive/rule/unconditional-recursion.go
new file mode 100644
index 0000000000..c06626b5ac
--- /dev/null
+++ b/vendor/github.com/mgechev/revive/rule/unconditional-recursion.go
@@ -0,0 +1,183 @@
+package rule
+
+import (
+ "go/ast"
+
+ "github.com/mgechev/revive/lint"
+)
+
+// UnconditionalRecursionRule lints given else constructs.
+type UnconditionalRecursionRule struct{}
+
+// Apply applies the rule to given file.
+func (r *UnconditionalRecursionRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
+ var failures []lint.Failure
+
+ onFailure := func(failure lint.Failure) {
+ failures = append(failures, failure)
+ }
+
+ w := lintUnconditionalRecursionRule{onFailure: onFailure}
+ ast.Walk(w, file.AST)
+ return failures
+}
+
+// Name returns the rule name.
+func (r *UnconditionalRecursionRule) Name() string {
+ return "unconditional-recursion"
+}
+
+type funcDesc struct {
+ reciverID *ast.Ident
+ id *ast.Ident
+}
+
+func (fd *funcDesc) equal(other *funcDesc) bool {
+ receiversAreEqual := (fd.reciverID == nil && other.reciverID == nil) || fd.reciverID != nil && other.reciverID != nil && fd.reciverID.Name == other.reciverID.Name
+ idsAreEqual := (fd.id == nil && other.id == nil) || fd.id.Name == other.id.Name
+
+ return receiversAreEqual && idsAreEqual
+}
+
+type funcStatus struct {
+ funcDesc *funcDesc
+ seenConditionalExit bool
+}
+
+type lintUnconditionalRecursionRule struct {
+ onFailure func(lint.Failure)
+ currentFunc *funcStatus
+}
+
+// Visit will traverse the file AST.
+// The rule is based in the following algorithm: inside each function body we search for calls to the function itself.
+// We do not search inside conditional control structures (if, for, switch, ...) because any recursive call inside them is conditioned
+// We do search inside conditional control structures are statements that will take the control out of the function (return, exit, panic)
+// If we find conditional control exits, it means the function is NOT unconditionally-recursive
+// If we find a recursive call before finding any conditional exit, a failure is generated
+// In resume: if we found a recursive call control-dependant from the entry point of the function then we raise a failure.
+func (w lintUnconditionalRecursionRule) Visit(node ast.Node) ast.Visitor {
+ switch n := node.(type) {
+ case *ast.FuncDecl:
+ var rec *ast.Ident
+ switch {
+ case n.Recv == nil || n.Recv.NumFields() < 1 || len(n.Recv.List[0].Names) < 1:
+ rec = nil
+ default:
+ rec = n.Recv.List[0].Names[0]
+ }
+
+ w.currentFunc = &funcStatus{&funcDesc{rec, n.Name}, false}
+ case *ast.CallExpr:
+ var funcID *ast.Ident
+ var selector *ast.Ident
+ switch c := n.Fun.(type) {
+ case *ast.Ident:
+ selector = nil
+ funcID = c
+ case *ast.SelectorExpr:
+ var ok bool
+ selector, ok = c.X.(*ast.Ident)
+ if !ok { // a.b....Foo()
+ return nil
+ }
+ funcID = c.Sel
+ default:
+ return w
+ }
+
+ if w.currentFunc != nil && // not in a func body
+ !w.currentFunc.seenConditionalExit && // there is a conditional exit in the function
+ w.currentFunc.funcDesc.equal(&funcDesc{selector, funcID}) {
+ w.onFailure(lint.Failure{
+ Category: "logic",
+ Confidence: 1,
+ Node: n,
+ Failure: "unconditional recursive call",
+ })
+ }
+ case *ast.IfStmt:
+ w.updateFuncStatus(n.Body)
+ w.updateFuncStatus(n.Else)
+ return nil
+ case *ast.SelectStmt:
+ w.updateFuncStatus(n.Body)
+ return nil
+ case *ast.RangeStmt:
+ w.updateFuncStatus(n.Body)
+ return nil
+ case *ast.TypeSwitchStmt:
+ w.updateFuncStatus(n.Body)
+ return nil
+ case *ast.SwitchStmt:
+ w.updateFuncStatus(n.Body)
+ return nil
+ case *ast.GoStmt:
+ for _, a := range n.Call.Args {
+ ast.Walk(w, a) // check if arguments have a recursive call
+ }
+ return nil // recursive async call is not an issue
+ case *ast.ForStmt:
+ if n.Cond != nil {
+ return nil
+ }
+ // unconditional loop
+ return w
+ }
+
+ return w
+}
+
+func (w *lintUnconditionalRecursionRule) updateFuncStatus(node ast.Node) {
+ if node == nil || w.currentFunc == nil || w.currentFunc.seenConditionalExit {
+ return
+ }
+
+ w.currentFunc.seenConditionalExit = w.hasControlExit(node)
+}
+
+var exitFunctions = map[string]map[string]bool{
+ "os": map[string]bool{"Exit": true},
+ "syscall": map[string]bool{"Exit": true},
+ "log": map[string]bool{
+ "Fatal": true,
+ "Fatalf": true,
+ "Fatalln": true,
+ "Panic": true,
+ "Panicf": true,
+ "Panicln": true,
+ },
+}
+
+func (w *lintUnconditionalRecursionRule) hasControlExit(node ast.Node) bool {
+ // isExit returns true if the given node makes control exit the function
+ isExit := func(node ast.Node) bool {
+ switch n := node.(type) {
+ case *ast.ReturnStmt:
+ return true
+ case *ast.CallExpr:
+ if isIdent(n.Fun, "panic") {
+ return true
+ }
+ se, ok := n.Fun.(*ast.SelectorExpr)
+ if !ok {
+ return false
+ }
+
+ id, ok := se.X.(*ast.Ident)
+ if !ok {
+ return false
+ }
+
+ fn := se.Sel.Name
+ pkg := id.Name
+ if exitFunctions[pkg] != nil && exitFunctions[pkg][fn] { // it's a call to an exit function
+ return true
+ }
+ }
+
+ return false
+ }
+
+ return len(pick(node, isExit, nil)) != 0
+}
diff --git a/vendor/github.com/mgechev/revive/rule/unexported-naming.go b/vendor/github.com/mgechev/revive/rule/unexported-naming.go
new file mode 100644
index 0000000000..96cec3e46d
--- /dev/null
+++ b/vendor/github.com/mgechev/revive/rule/unexported-naming.go
@@ -0,0 +1,115 @@
+package rule
+
+import (
+ "fmt"
+ "go/ast"
+ "go/token"
+
+ "github.com/mgechev/revive/lint"
+)
+
+// UnexportedNamingRule lints wrongly named unexported symbols.
+type UnexportedNamingRule struct{}
+
+// Apply applies the rule to given file.
+func (r *UnexportedNamingRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
+ var failures []lint.Failure
+ onFailure := func(failure lint.Failure) {
+ failures = append(failures, failure)
+ }
+
+ ba := &unexportablenamingLinter{onFailure}
+ ast.Walk(ba, file.AST)
+
+ return failures
+}
+
+// Name returns the rule name.
+func (r *UnexportedNamingRule) Name() string {
+ return "unexported-naming"
+}
+
+type unexportablenamingLinter struct {
+ onFailure func(lint.Failure)
+}
+
+func (unl unexportablenamingLinter) Visit(node ast.Node) ast.Visitor {
+ switch n := node.(type) {
+ case *ast.FuncDecl:
+ unl.lintFunction(n.Type, n.Body)
+ return nil
+ case *ast.FuncLit:
+ unl.lintFunction(n.Type, n.Body)
+
+ return nil
+ case *ast.AssignStmt:
+ if n.Tok != token.DEFINE {
+ return nil
+ }
+
+ ids := []*ast.Ident{}
+ for _, e := range n.Lhs {
+ id, ok := e.(*ast.Ident)
+ if !ok {
+ continue
+ }
+ ids = append(ids, id)
+ }
+
+ unl.lintIDs(ids)
+
+ case *ast.DeclStmt:
+ gd, ok := n.Decl.(*ast.GenDecl)
+ if !ok {
+ return nil
+ }
+
+ if len(gd.Specs) < 1 {
+ return nil
+ }
+
+ vs, ok := gd.Specs[0].(*ast.ValueSpec)
+ if !ok {
+ return nil
+ }
+
+ unl.lintIDs(vs.Names)
+ }
+
+ return unl
+}
+
+func (unl unexportablenamingLinter) lintFunction(ft *ast.FuncType, body *ast.BlockStmt) {
+ unl.lintFields(ft.Params)
+ unl.lintFields(ft.Results)
+
+ if body != nil {
+ ast.Walk(unl, body)
+ }
+}
+
+func (unl unexportablenamingLinter) lintFields(fields *ast.FieldList) {
+ if fields == nil {
+ return
+ }
+
+ ids := []*ast.Ident{}
+ for _, field := range fields.List {
+ ids = append(ids, field.Names...)
+ }
+
+ unl.lintIDs(ids)
+}
+
+func (unl unexportablenamingLinter) lintIDs(ids []*ast.Ident) {
+ for _, id := range ids {
+ if id.IsExported() {
+ unl.onFailure(lint.Failure{
+ Node: id,
+ Confidence: 1,
+ Category: "naming",
+ Failure: fmt.Sprintf("the symbol %s is local, its name should start with a lowercase letter", id.String()),
+ })
+ }
+ }
+}
diff --git a/vendor/github.com/mgechev/revive/rule/unused-receiver.go b/vendor/github.com/mgechev/revive/rule/unused-receiver.go
index 43eaf83a49..2289a517e5 100644
--- a/vendor/github.com/mgechev/revive/rule/unused-receiver.go
+++ b/vendor/github.com/mgechev/revive/rule/unused-receiver.go
@@ -11,7 +11,7 @@ import (
type UnusedReceiverRule struct{}
// Apply applies the rule to given file.
-func (_ *UnusedReceiverRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
+func (*UnusedReceiverRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
var failures []lint.Failure
onFailure := func(failure lint.Failure) {
@@ -26,7 +26,7 @@ func (_ *UnusedReceiverRule) Apply(file *lint.File, _ lint.Arguments) []lint.Fai
}
// Name returns the rule name.
-func (_ *UnusedReceiverRule) Name() string {
+func (*UnusedReceiverRule) Name() string {
return "unused-receiver"
}
diff --git a/vendor/github.com/mgechev/revive/rule/utils.go b/vendor/github.com/mgechev/revive/rule/utils.go
index 6ba542b716..38677c839d 100644
--- a/vendor/github.com/mgechev/revive/rule/utils.go
+++ b/vendor/github.com/mgechev/revive/rule/utils.go
@@ -182,8 +182,8 @@ func isExprABooleanLit(n ast.Node) (lexeme string, ok bool) {
return oper.Name, (oper.Name == trueName || oper.Name == falseName)
}
-// gofmt returns a string representation of the expression.
-func gofmt(x ast.Expr) string {
+// gofmt returns a string representation of an AST subtree.
+func gofmt(x interface{}) string {
buf := bytes.Buffer{}
fs := token.NewFileSet()
printer.Fprint(&buf, fs, x)