aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/mgechev
diff options
context:
space:
mode:
authorTaras Madan <tarasmadan@google.com>2023-02-22 22:16:50 +0100
committerTaras Madan <tarasmadan@google.com>2023-02-24 12:47:23 +0100
commit4165372ec8fd142475a4e35fd0cf4f8042132208 (patch)
tree21cd62211b4dd80bee469054c5b65db77342333c /vendor/github.com/mgechev
parent2b3ed821a493b8936c8bacfa6f8b4f1c90a00855 (diff)
dependencies: update
set go min requirements to 1.19 update dependencies update vendor
Diffstat (limited to 'vendor/github.com/mgechev')
-rw-r--r--vendor/github.com/mgechev/revive/config/config.go1
-rw-r--r--vendor/github.com/mgechev/revive/formatter/sarif.go4
-rw-r--r--vendor/github.com/mgechev/revive/rule/add-constant.go101
-rw-r--r--vendor/github.com/mgechev/revive/rule/comment-spacings.go82
-rw-r--r--vendor/github.com/mgechev/revive/rule/early-return.go156
-rw-r--r--vendor/github.com/mgechev/revive/rule/empty-lines.go4
-rw-r--r--vendor/github.com/mgechev/revive/rule/function-length.go8
-rw-r--r--vendor/github.com/mgechev/revive/rule/identical-branches.go4
-rw-r--r--vendor/github.com/mgechev/revive/rule/nested-structs.go10
-rw-r--r--vendor/github.com/mgechev/revive/rule/string-format.go36
-rw-r--r--vendor/github.com/mgechev/revive/rule/unconditional-recursion.go6
-rw-r--r--vendor/github.com/mgechev/revive/rule/unhandled-error.go66
12 files changed, 410 insertions, 68 deletions
diff --git a/vendor/github.com/mgechev/revive/config/config.go b/vendor/github.com/mgechev/revive/config/config.go
index 5c63f35b3..d6b4f4100 100644
--- a/vendor/github.com/mgechev/revive/config/config.go
+++ b/vendor/github.com/mgechev/revive/config/config.go
@@ -86,6 +86,7 @@ var allRules = append([]lint.Rule{
&rule.OptimizeOperandsOrderRule{},
&rule.UseAnyRule{},
&rule.DataRaceRule{},
+ &rule.CommentSpacingsRule{},
}, defaultRules...)
var allFormatters = []lint.Formatter{
diff --git a/vendor/github.com/mgechev/revive/formatter/sarif.go b/vendor/github.com/mgechev/revive/formatter/sarif.go
index ee62adcc0..c6288db76 100644
--- a/vendor/github.com/mgechev/revive/formatter/sarif.go
+++ b/vendor/github.com/mgechev/revive/formatter/sarif.go
@@ -81,8 +81,8 @@ func (l *reviveRunLog) AddResult(failure lint.Failure) {
}
position := failure.Position
filename := position.Start.Filename
- line := positiveOrZero(position.Start.Line - 1) // https://docs.oasis-open.org/sarif/sarif/v2.1.0/csprd01/sarif-v2.1.0-csprd01.html#def_line
- column := positiveOrZero(position.Start.Column - 1) // https://docs.oasis-open.org/sarif/sarif/v2.1.0/csprd01/sarif-v2.1.0-csprd01.html#def_column
+ line := positiveOrZero(position.Start.Line) // https://docs.oasis-open.org/sarif/sarif/v2.1.0/csprd01/sarif-v2.1.0-csprd01.html#def_line
+ column := positiveOrZero(position.Start.Column) // https://docs.oasis-open.org/sarif/sarif/v2.1.0/csprd01/sarif-v2.1.0-csprd01.html#def_column
result := garif.NewResult(garif.NewMessageFromText(failure.Failure))
location := garif.NewLocation().WithURI(filename).WithLineColumn(line, column)
diff --git a/vendor/github.com/mgechev/revive/rule/add-constant.go b/vendor/github.com/mgechev/revive/rule/add-constant.go
index 414be38c3..36a7003da 100644
--- a/vendor/github.com/mgechev/revive/rule/add-constant.go
+++ b/vendor/github.com/mgechev/revive/rule/add-constant.go
@@ -3,6 +3,7 @@ package rule
import (
"fmt"
"go/ast"
+ "regexp"
"strconv"
"strings"
"sync"
@@ -32,8 +33,9 @@ func (wl whiteList) add(kind, list string) {
// AddConstantRule lints unused params in functions.
type AddConstantRule struct {
- whiteList whiteList
- strLitLimit int
+ whiteList whiteList
+ ignoreFunctions []*regexp.Regexp
+ strLitLimit int
sync.Mutex
}
@@ -47,7 +49,13 @@ func (r *AddConstantRule) Apply(file *lint.File, arguments lint.Arguments) []lin
failures = append(failures, failure)
}
- w := lintAddConstantRule{onFailure: onFailure, strLits: make(map[string]int), strLitLimit: r.strLitLimit, whiteLst: r.whiteList}
+ w := lintAddConstantRule{
+ onFailure: onFailure,
+ strLits: make(map[string]int),
+ strLitLimit: r.strLitLimit,
+ whiteLst: r.whiteList,
+ ignoreFunctions: r.ignoreFunctions,
+ }
ast.Walk(w, file.AST)
@@ -60,28 +68,76 @@ func (*AddConstantRule) Name() string {
}
type lintAddConstantRule struct {
- onFailure func(lint.Failure)
- strLits map[string]int
- strLitLimit int
- whiteLst whiteList
+ onFailure func(lint.Failure)
+ strLits map[string]int
+ strLitLimit int
+ whiteLst whiteList
+ ignoreFunctions []*regexp.Regexp
}
func (w lintAddConstantRule) Visit(node ast.Node) ast.Visitor {
switch n := node.(type) {
+ case *ast.CallExpr:
+ w.checkFunc(n)
+ return nil
case *ast.GenDecl:
return nil // skip declarations
case *ast.BasicLit:
- switch kind := n.Kind.String(); kind {
- case kindFLOAT, kindINT:
- w.checkNumLit(kind, n)
- case kindSTRING:
- w.checkStrLit(n)
- }
+ w.checkLit(n)
}
return w
}
+func (w lintAddConstantRule) checkFunc(expr *ast.CallExpr) {
+ fName := w.getFuncName(expr)
+
+ for _, arg := range expr.Args {
+ switch t := arg.(type) {
+ case *ast.CallExpr:
+ w.checkFunc(t)
+ case *ast.BasicLit:
+ if w.isIgnoredFunc(fName) {
+ continue
+ }
+ w.checkLit(t)
+ }
+ }
+}
+
+func (w lintAddConstantRule) getFuncName(expr *ast.CallExpr) string {
+ switch f := expr.Fun.(type) {
+ case *ast.SelectorExpr:
+ switch prefix := f.X.(type) {
+ case *ast.Ident:
+ return prefix.Name + "." + f.Sel.Name
+ }
+ case *ast.Ident:
+ return f.Name
+ }
+
+ return ""
+}
+
+func (w lintAddConstantRule) checkLit(n *ast.BasicLit) {
+ switch kind := n.Kind.String(); kind {
+ case kindFLOAT, kindINT:
+ w.checkNumLit(kind, n)
+ case kindSTRING:
+ w.checkStrLit(n)
+ }
+}
+
+func (w lintAddConstantRule) isIgnoredFunc(fName string) bool {
+ for _, pattern := range w.ignoreFunctions {
+ if pattern.MatchString(fName) {
+ return true
+ }
+ }
+
+ return false
+}
+
func (w lintAddConstantRule) checkStrLit(n *ast.BasicLit) {
if w.whiteLst[kindSTRING][n.Value] {
return
@@ -158,6 +214,25 @@ func (r *AddConstantRule) configure(arguments lint.Arguments) {
panic(fmt.Sprintf("Invalid argument to the add-constant rule, expecting string representation of an integer. Got '%v'", v))
}
r.strLitLimit = limit
+ case "ignoreFuncs":
+ excludes, ok := v.(string)
+ if !ok {
+ panic(fmt.Sprintf("Invalid argument to the ignoreFuncs parameter of add-constant rule, string expected. Got '%v' (%T)", v, v))
+ }
+
+ for _, exclude := range strings.Split(excludes, ",") {
+ exclude = strings.Trim(exclude, " ")
+ if exclude == "" {
+ panic("Invalid argument to the ignoreFuncs parameter of add-constant rule, expected regular expression must not be empty.")
+ }
+
+ exp, err := regexp.Compile(exclude)
+ if err != nil {
+ panic(fmt.Sprintf("Invalid argument to the ignoreFuncs parameter of add-constant rule: regexp %q does not compile: %v", exclude, err))
+ }
+
+ r.ignoreFunctions = append(r.ignoreFunctions, exp)
+ }
}
}
}
diff --git a/vendor/github.com/mgechev/revive/rule/comment-spacings.go b/vendor/github.com/mgechev/revive/rule/comment-spacings.go
new file mode 100644
index 000000000..abe2ad76d
--- /dev/null
+++ b/vendor/github.com/mgechev/revive/rule/comment-spacings.go
@@ -0,0 +1,82 @@
+package rule
+
+import (
+ "fmt"
+ "strings"
+ "sync"
+
+ "github.com/mgechev/revive/lint"
+)
+
+// CommentSpacings Rule check the whether there is a space between
+// the comment symbol( // ) and the start of the comment text
+type CommentSpacingsRule struct {
+ allowList []string
+ sync.Mutex
+}
+
+func (r *CommentSpacingsRule) configure(arguments lint.Arguments) {
+ r.Lock()
+ defer r.Unlock()
+
+ if r.allowList == nil {
+ r.allowList = []string{
+ "//go:",
+ "//revive:",
+ }
+
+ for _, arg := range arguments {
+ allow, ok := arg.(string) // Alt. non panicking version
+ if !ok {
+ panic(fmt.Sprintf("invalid argument %v for %s; expected string but got %T", arg, r.Name(), arg))
+ }
+ r.allowList = append(r.allowList, `//`+allow+`:`)
+ }
+ }
+}
+
+func (r *CommentSpacingsRule) Apply(file *lint.File, args lint.Arguments) []lint.Failure {
+ r.configure(args)
+
+ var failures []lint.Failure
+
+ for _, cg := range file.AST.Comments {
+ for _, comment := range cg.List {
+ commentLine := comment.Text
+ if len(commentLine) < 3 {
+ continue // nothing to do
+ }
+
+ isOK := commentLine[2] == ' '
+ if isOK {
+ continue
+ }
+
+ if r.isAllowed(commentLine) {
+ continue
+ }
+
+ failures = append(failures, lint.Failure{
+ Node: comment,
+ Confidence: 1,
+ Category: "style",
+ Failure: "no space between comment delimiter and comment text",
+ })
+ }
+ }
+ return failures
+}
+
+func (*CommentSpacingsRule) Name() string {
+ return "comment-spacings"
+}
+
+func (r *CommentSpacingsRule) isAllowed(line string) bool {
+ for _, allow := range r.allowList {
+ if strings.HasPrefix(line, allow) {
+ return true
+ }
+ }
+
+ return false
+}
diff --git a/vendor/github.com/mgechev/revive/rule/early-return.go b/vendor/github.com/mgechev/revive/rule/early-return.go
index bfbf6717c..ed0fcfae4 100644
--- a/vendor/github.com/mgechev/revive/rule/early-return.go
+++ b/vendor/github.com/mgechev/revive/rule/early-return.go
@@ -1,12 +1,15 @@
package rule
import (
+ "fmt"
"go/ast"
+ "go/token"
"github.com/mgechev/revive/lint"
)
-// EarlyReturnRule lints given else constructs.
+// EarlyReturnRule finds opportunities to reduce nesting by inverting
+// the condition of an "if" block.
type EarlyReturnRule struct{}
// Apply applies the rule to given file.
@@ -32,47 +35,142 @@ type lintEarlyReturnRule struct {
}
func (w lintEarlyReturnRule) Visit(node ast.Node) ast.Visitor {
- switch n := node.(type) {
+ ifStmt, ok := node.(*ast.IfStmt)
+ if !ok {
+ return w
+ }
+
+ w.visitIf(ifStmt, false, false)
+ return nil
+}
+
+func (w lintEarlyReturnRule) visitIf(ifStmt *ast.IfStmt, hasNonReturnBranch, hasIfInitializer bool) {
+ // look for other if-else chains nested inside this if { } block
+ ast.Walk(w, ifStmt.Body)
+
+ if ifStmt.Else == nil {
+ // no else branch
+ return
+ }
+
+ if as, ok := ifStmt.Init.(*ast.AssignStmt); ok && as.Tok == token.DEFINE {
+ hasIfInitializer = true
+ }
+ bodyFlow := w.branchFlow(ifStmt.Body)
+
+ switch elseBlock := ifStmt.Else.(type) {
case *ast.IfStmt:
- if n.Else == nil {
- // no else branch
- return w
+ if bodyFlow.canFlowIntoNext() {
+ hasNonReturnBranch = true
}
+ w.visitIf(elseBlock, hasNonReturnBranch, hasIfInitializer)
+
+ case *ast.BlockStmt:
+ // look for other if-else chains nested inside this else { } block
+ ast.Walk(w, elseBlock)
- elseBlock, ok := n.Else.(*ast.BlockStmt)
- if !ok {
- // is if-else-if
- return w
+ if hasNonReturnBranch && bodyFlow != branchFlowEmpty {
+ // if we de-indent this block then a previous branch
+ // might flow into it, affecting program behaviour
+ return
}
- lenElseBlock := len(elseBlock.List)
- if lenElseBlock < 1 {
- // empty else block, continue (there is another rule that warns on empty blocks)
- return w
+ if !bodyFlow.canFlowIntoNext() {
+ // avoid overlapping with superfluous-else
+ return
}
- 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 }",
- })
+ elseFlow := w.branchFlow(elseBlock)
+ if !elseFlow.canFlowIntoNext() {
+ failMsg := fmt.Sprintf("if c {%[1]s } else {%[2]s } can be simplified to if !c {%[2]s }%[1]s",
+ bodyFlow, elseFlow)
- return w
- }
+ if hasIfInitializer {
+ // if statement has a := initializer, so we might need to move the assignment
+ // onto its own line in case the body references it
+ failMsg += " (move short variable declaration to its own line if necessary)"
+ }
- _, 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 } ...",
+ Node: ifStmt,
+ Failure: failMsg,
})
}
+
+ default:
+ panic("invalid node type for else")
}
+}
- return w
+type branchFlowKind int
+
+const (
+ branchFlowEmpty branchFlowKind = iota
+ branchFlowReturn
+ branchFlowPanic
+ branchFlowContinue
+ branchFlowBreak
+ branchFlowGoto
+ branchFlowRegular
+)
+
+func (w lintEarlyReturnRule) branchFlow(block *ast.BlockStmt) branchFlowKind {
+ blockLen := len(block.List)
+ if blockLen == 0 {
+ return branchFlowEmpty
+ }
+
+ switch stmt := block.List[blockLen-1].(type) {
+ case *ast.ReturnStmt:
+ return branchFlowReturn
+ case *ast.BlockStmt:
+ return w.branchFlow(stmt)
+ case *ast.BranchStmt:
+ switch stmt.Tok {
+ case token.BREAK:
+ return branchFlowBreak
+ case token.CONTINUE:
+ return branchFlowContinue
+ case token.GOTO:
+ return branchFlowGoto
+ }
+ case *ast.ExprStmt:
+ if call, ok := stmt.X.(*ast.CallExpr); ok && isIdent(call.Fun, "panic") {
+ return branchFlowPanic
+ }
+ }
+
+ return branchFlowRegular
+}
+
+// Whether this branch's control can flow into the next statement following the if-else chain
+func (k branchFlowKind) canFlowIntoNext() bool {
+ switch k {
+ case branchFlowReturn, branchFlowPanic, branchFlowContinue, branchFlowBreak, branchFlowGoto:
+ return false
+ default:
+ return true
+ }
+}
+
+func (k branchFlowKind) String() string {
+ switch k {
+ case branchFlowEmpty:
+ return ""
+ case branchFlowReturn:
+ return " ... return"
+ case branchFlowPanic:
+ return " ... panic()"
+ case branchFlowContinue:
+ return " ... continue"
+ case branchFlowBreak:
+ return " ... break"
+ case branchFlowGoto:
+ return " ... goto"
+ case branchFlowRegular:
+ return " ..."
+ default:
+ panic("invalid kind")
+ }
}
diff --git a/vendor/github.com/mgechev/revive/rule/empty-lines.go b/vendor/github.com/mgechev/revive/rule/empty-lines.go
index 12866072e..2710a8979 100644
--- a/vendor/github.com/mgechev/revive/rule/empty-lines.go
+++ b/vendor/github.com/mgechev/revive/rule/empty-lines.go
@@ -51,7 +51,7 @@ func (w lintEmptyLines) checkStart(block *ast.BlockStmt) {
firstNode := block.List[0]
firstStmt := w.position(firstNode.Pos())
- firstBlockLineIsStmt := firstStmt.Line-(blockStart.Line+1) == 0
+ firstBlockLineIsStmt := firstStmt.Line-(blockStart.Line+1) <= 0
_, firstBlockLineIsComment := w.cmap[blockStart.Line+1]
if firstBlockLineIsStmt || firstBlockLineIsComment {
return
@@ -70,7 +70,7 @@ func (w lintEmptyLines) checkEnd(block *ast.BlockStmt) {
lastNode := block.List[len(block.List)-1]
lastStmt := w.position(lastNode.End())
- lastBlockLineIsStmt := (blockEnd.Line-1)-lastStmt.Line == 0
+ lastBlockLineIsStmt := (blockEnd.Line-1)-lastStmt.Line <= 0
_, lastBlockLineIsComment := w.cmap[blockEnd.Line-1]
if lastBlockLineIsStmt || lastBlockLineIsComment {
return
diff --git a/vendor/github.com/mgechev/revive/rule/function-length.go b/vendor/github.com/mgechev/revive/rule/function-length.go
index 717ddbf7b..d600d7a2a 100644
--- a/vendor/github.com/mgechev/revive/rule/function-length.go
+++ b/vendor/github.com/mgechev/revive/rule/function-length.go
@@ -11,17 +11,19 @@ import (
// FunctionLength lint.
type FunctionLength struct {
- maxStmt int
- maxLines int
+ maxStmt int
+ maxLines int
+ configured bool
sync.Mutex
}
func (r *FunctionLength) configure(arguments lint.Arguments) {
r.Lock()
- if r.maxLines == 0 {
+ if !r.configured {
maxStmt, maxLines := r.parseArguments(arguments)
r.maxStmt = int(maxStmt)
r.maxLines = int(maxLines)
+ r.configured = true
}
r.Unlock()
}
diff --git a/vendor/github.com/mgechev/revive/rule/identical-branches.go b/vendor/github.com/mgechev/revive/rule/identical-branches.go
index b1a69097f..9222c8a9c 100644
--- a/vendor/github.com/mgechev/revive/rule/identical-branches.go
+++ b/vendor/github.com/mgechev/revive/rule/identical-branches.go
@@ -63,8 +63,10 @@ func (lintIdenticalBranches) identicalBranches(branches []*ast.BlockStmt) bool {
}
ref := gofmt(branches[0])
+ refSize := len(branches[0].List)
for i := 1; i < len(branches); i++ {
- if gofmt(branches[i]) != ref {
+ currentSize := len(branches[i].List)
+ if currentSize != refSize || gofmt(branches[i]) != ref {
return false
}
}
diff --git a/vendor/github.com/mgechev/revive/rule/nested-structs.go b/vendor/github.com/mgechev/revive/rule/nested-structs.go
index b4f7352db..fd1226991 100644
--- a/vendor/github.com/mgechev/revive/rule/nested-structs.go
+++ b/vendor/github.com/mgechev/revive/rule/nested-structs.go
@@ -37,12 +37,22 @@ type lintNestedStructs struct {
func (l *lintNestedStructs) Visit(n ast.Node) ast.Visitor {
switch v := n.(type) {
+ case *ast.TypeSpec:
+ _, isInterface := v.Type.(*ast.InterfaceType)
+ if isInterface {
+ return nil // do not analyze interface declarations
+ }
case *ast.FuncDecl:
if v.Body != nil {
ast.Walk(l, v.Body)
}
return nil
case *ast.Field:
+ _, isChannelField := v.Type.(*ast.ChanType)
+ if isChannelField {
+ return nil
+ }
+
filter := func(n ast.Node) bool {
switch n.(type) {
case *ast.StructType:
diff --git a/vendor/github.com/mgechev/revive/rule/string-format.go b/vendor/github.com/mgechev/revive/rule/string-format.go
index e7841e8c3..0e30ebf8b 100644
--- a/vendor/github.com/mgechev/revive/rule/string-format.go
+++ b/vendor/github.com/mgechev/revive/rule/string-format.go
@@ -68,6 +68,7 @@ type stringFormatSubrule struct {
parent *lintStringFormatRule
scope stringFormatSubruleScope
regexp *regexp.Regexp
+ negated bool
errorMessage string
}
@@ -89,17 +90,18 @@ var parseStringFormatScope = regexp.MustCompile(
func (w *lintStringFormatRule) parseArguments(arguments lint.Arguments) {
for i, argument := range arguments {
- scope, regex, errorMessage := w.parseArgument(argument, i)
+ scope, regex, negated, errorMessage := w.parseArgument(argument, i)
w.rules = append(w.rules, stringFormatSubrule{
parent: w,
scope: scope,
regexp: regex,
+ negated: negated,
errorMessage: errorMessage,
})
}
}
-func (w lintStringFormatRule) parseArgument(argument interface{}, ruleNum int) (scope stringFormatSubruleScope, regex *regexp.Regexp, errorMessage string) {
+func (w lintStringFormatRule) parseArgument(argument interface{}, ruleNum int) (scope stringFormatSubruleScope, regex *regexp.Regexp, negated bool, errorMessage string) {
g, ok := argument.([]interface{}) // Cast to generic slice first
if !ok {
w.configError("argument is not a slice", ruleNum, 0)
@@ -146,7 +148,12 @@ func (w lintStringFormatRule) parseArgument(argument interface{}, ruleNum int) (
}
// Strip / characters from the beginning and end of rule[1] before compiling
- regex, err := regexp.Compile(rule[1][1 : len(rule[1])-1])
+ negated = rule[1][0] == '!'
+ offset := 1
+ if negated {
+ offset++
+ }
+ regex, err := regexp.Compile(rule[1][offset : len(rule[1])-1])
if err != nil {
w.parseError(fmt.Sprintf("unable to compile %s as regexp", rule[1]), ruleNum, 1)
}
@@ -155,7 +162,7 @@ func (w lintStringFormatRule) parseArgument(argument interface{}, ruleNum int) (
if len(rule) == 3 {
errorMessage = rule[2]
}
- return scope, regex, errorMessage
+ return scope, regex, negated, errorMessage
}
// Report an invalid config, this is specifically the user's fault
@@ -261,7 +268,26 @@ func (r *stringFormatSubrule) Apply(call *ast.CallExpr) {
}
func (r *stringFormatSubrule) lintMessage(s string, node ast.Node) {
- // Fail if the string doesn't match the user's regex
+ if r.negated {
+ if !r.regexp.MatchString(s) {
+ return
+ }
+ // Fail if the string does match the user's regex
+ var failure string
+ if len(r.errorMessage) > 0 {
+ failure = r.errorMessage
+ } else {
+ failure = fmt.Sprintf("string literal matches user defined regex /%s/", r.regexp.String())
+ }
+ r.parent.onFailure(lint.Failure{
+ Confidence: 1,
+ Failure: failure,
+ Node: node,
+ })
+ return
+ }
+
+ // Fail if the string does NOT match the user's regex
if r.regexp.MatchString(s) {
return
}
diff --git a/vendor/github.com/mgechev/revive/rule/unconditional-recursion.go b/vendor/github.com/mgechev/revive/rule/unconditional-recursion.go
index f0e83b0ce..bad907533 100644
--- a/vendor/github.com/mgechev/revive/rule/unconditional-recursion.go
+++ b/vendor/github.com/mgechev/revive/rule/unconditional-recursion.go
@@ -28,12 +28,12 @@ func (*UnconditionalRecursionRule) Name() string {
}
type funcDesc struct {
- reciverID *ast.Ident
- id *ast.Ident
+ receiverID *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
+ receiversAreEqual := (fd.receiverID == nil && other.receiverID == nil) || fd.receiverID != nil && other.receiverID != nil && fd.receiverID.Name == other.receiverID.Name
idsAreEqual := (fd.id == nil && other.id == nil) || fd.id.Name == other.id.Name
return receiversAreEqual && idsAreEqual
diff --git a/vendor/github.com/mgechev/revive/rule/unhandled-error.go b/vendor/github.com/mgechev/revive/rule/unhandled-error.go
index 6cde24b7f..32a5fe48b 100644
--- a/vendor/github.com/mgechev/revive/rule/unhandled-error.go
+++ b/vendor/github.com/mgechev/revive/rule/unhandled-error.go
@@ -4,6 +4,8 @@ import (
"fmt"
"go/ast"
"go/types"
+ "regexp"
+ "strings"
"sync"
"github.com/mgechev/revive/lint"
@@ -11,24 +13,30 @@ import (
// UnhandledErrorRule lints given else constructs.
type UnhandledErrorRule struct {
- ignoreList ignoreListType
+ ignoreList []*regexp.Regexp
sync.Mutex
}
-type ignoreListType map[string]struct{}
-
func (r *UnhandledErrorRule) configure(arguments lint.Arguments) {
r.Lock()
if r.ignoreList == nil {
- r.ignoreList = make(ignoreListType, len(arguments))
-
for _, arg := range arguments {
argStr, ok := arg.(string)
if !ok {
panic(fmt.Sprintf("Invalid argument to the unhandled-error rule. Expecting a string, got %T", arg))
}
- r.ignoreList[argStr] = struct{}{}
+ argStr = strings.Trim(argStr, " ")
+ if argStr == "" {
+ panic("Invalid argument to the unhandled-error rule, expected regular expression must not be empty.")
+ }
+
+ exp, err := regexp.Compile(argStr)
+ if err != nil {
+ panic(fmt.Sprintf("Invalid argument to the unhandled-error rule: regexp %q does not compile: %v", argStr, err))
+ }
+
+ r.ignoreList = append(r.ignoreList, exp)
}
}
r.Unlock()
@@ -60,7 +68,7 @@ func (*UnhandledErrorRule) Name() string {
}
type lintUnhandledErrors struct {
- ignoreList ignoreListType
+ ignoreList []*regexp.Regexp
pkg *lint.Package
onFailure func(lint.Failure)
}
@@ -102,8 +110,8 @@ func (w *lintUnhandledErrors) Visit(node ast.Node) ast.Visitor {
}
func (w *lintUnhandledErrors) addFailure(n *ast.CallExpr) {
- funcName := gofmt(n.Fun)
- if _, mustIgnore := w.ignoreList[funcName]; mustIgnore {
+ name := w.funcName(n)
+ if w.isIgnoredFunc(name) {
return
}
@@ -111,10 +119,34 @@ func (w *lintUnhandledErrors) addFailure(n *ast.CallExpr) {
Category: "bad practice",
Confidence: 1,
Node: n,
- Failure: fmt.Sprintf("Unhandled error in call to function %v", funcName),
+ Failure: fmt.Sprintf("Unhandled error in call to function %v", gofmt(n.Fun)),
})
}
+func (w *lintUnhandledErrors) funcName(call *ast.CallExpr) string {
+ fn, ok := w.getFunc(call)
+ if !ok {
+ return gofmt(call.Fun)
+ }
+
+ name := fn.FullName()
+ name = strings.Replace(name, "(", "", -1)
+ name = strings.Replace(name, ")", "", -1)
+ name = strings.Replace(name, "*", "", -1)
+
+ return name
+}
+
+func (w *lintUnhandledErrors) isIgnoredFunc(funcName string) bool {
+ for _, pattern := range w.ignoreList {
+ if len(pattern.FindString(funcName)) == len(funcName) {
+ return true
+ }
+ }
+
+ return false
+}
+
func (*lintUnhandledErrors) isTypeError(t *types.Named) bool {
const errorTypeName = "_.error"
@@ -130,3 +162,17 @@ func (w *lintUnhandledErrors) returnsAnError(tt *types.Tuple) bool {
}
return false
}
+
+func (w *lintUnhandledErrors) getFunc(call *ast.CallExpr) (*types.Func, bool) {
+ sel, ok := call.Fun.(*ast.SelectorExpr)
+ if !ok {
+ return nil, false
+ }
+
+ fn, ok := w.pkg.TypesInfo().ObjectOf(sel.Sel).(*types.Func)
+ if !ok {
+ return nil, false
+ }
+
+ return fn, true
+}