aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/go-critic
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2021-02-22 20:37:25 +0100
committerDmitry Vyukov <dvyukov@google.com>2021-02-22 21:02:12 +0100
commitfcc6d71be2c3ce7d9305c04fc2e87af554571bac (patch)
treeb01dbb3d1e2988e28ea158d2d543d603ec0b9569 /vendor/github.com/go-critic
parent8f23c528ad5a943b9ffec5dcaf332fd0f614006e (diff)
go.mod: update golangci-lint to v1.37
Diffstat (limited to 'vendor/github.com/go-critic')
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/appendAssign_checker.go6
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/appendCombine_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/argOrder_checker.go17
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/assignOp_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/badCall_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/badCond_checker.go8
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/badLock_checker.go116
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/badRegexp_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/boolExprSimplify_checker.go18
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/builtinShadowDecl_checker.go63
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/builtinShadow_checker.go6
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/captLocal_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/caseOrder_checker.go14
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/codegenComment_checker.go6
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/commentFormatting_checker.go6
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/commentedOutCode_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/commentedOutImport_checker.go6
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/defaultCaseOrder_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/deferUnlambda_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/deprecatedComment_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/docStub_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/dupArg_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/dupBranchBody_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/dupCase_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/dupImports_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/dupSubExpr_checker.go6
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/elseif_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/emptyFallthrough_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/emptyStringTest_checker.go6
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/equalFold_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/evalOrder_checker.go6
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/exitAfterDefer_checker.go16
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/filepathJoin_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/flagDeref_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/flagName_checker.go28
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/hexLiteral_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/hugeParam_checker.go6
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/ifElseChain_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/importShadow_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/indexAlloc_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/initClause_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/expr_walker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/func_decl_walker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/local_expr_walker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/stmt_list_walker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/stmt_walker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/mapKey_checker.go6
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/methodExprCall_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/nestingReduce_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/newDeref_checker.go6
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/nilValReturn_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/octalLiteral_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/offBy1_checker.go10
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/paramTypeCombine_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/ptrToRefParam_checker.go6
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/rangeExprCopy_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/rangeValCopy_checker.go6
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/regexpMust_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/regexpPattern_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/regexpSimplify_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/ruleguard_checker.go91
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/singleCaseSwitch_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/sloppyLen_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/sloppyReassign_checker.go10
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/sloppyTypeAssert_checker.go8
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/sortSlice_checker.go6
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/sqlQuery_checker.go8
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/stringXbytes_checker.go8
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/switchTrue_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/truncateCmp_checker.go8
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/typeAssertChain_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/typeDefFirst_checker.go88
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/typeSwitchVar_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/typeUnparen_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/underef_checker.go10
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/unlabelStmt_checker.go6
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/unlambda_checker.go37
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/unnamedResult_checker.go6
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/unnecessaryBlock_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/unnecessaryDefer_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/unslice_checker.go6
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/valSwap_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/weakCond_checker.go6
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/whyNoLint_checker.go6
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/wrapperFunc_checker.go6
-rw-r--r--vendor/github.com/go-critic/go-critic/checkers/yodaStyleExpr_checker.go4
-rw-r--r--vendor/github.com/go-critic/go-critic/framework/linter/checkers_db.go15
-rw-r--r--vendor/github.com/go-critic/go-critic/framework/linter/lintpack.go28
88 files changed, 654 insertions, 259 deletions
diff --git a/vendor/github.com/go-critic/go-critic/checkers/appendAssign_checker.go b/vendor/github.com/go-critic/go-critic/checkers/appendAssign_checker.go
index d26921770..42fa97a54 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/appendAssign_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/appendAssign_checker.go
@@ -24,8 +24,8 @@ p.negatives = append(p.negatives, y)`
p.positives = append(p.positives, x)
p.negatives = append(p.negatives, y)`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForStmt(&appendAssignChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForStmt(&appendAssignChecker{ctx: ctx}), nil
})
}
@@ -81,7 +81,7 @@ func (c *appendAssignChecker) checkAppend(x ast.Expr, call *ast.CallExpr) {
switch y := call.Args[0].(type) {
case *ast.SliceExpr:
- if _, ok := c.ctx.TypesInfo.TypeOf(y.X).(*types.Array); ok {
+ if _, ok := c.ctx.TypeOf(y.X).(*types.Array); ok {
// Arrays are frequently used as scratch storages.
return
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/appendCombine_checker.go b/vendor/github.com/go-critic/go-critic/checkers/appendCombine_checker.go
index a761f2a8f..03662fc21 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/appendCombine_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/appendCombine_checker.go
@@ -20,8 +20,8 @@ xs = append(xs, 1)
xs = append(xs, 2)`
info.After = `xs = append(xs, 1, 2)`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForStmtList(&appendCombineChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForStmtList(&appendCombineChecker{ctx: ctx}), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/argOrder_checker.go b/vendor/github.com/go-critic/go-critic/checkers/argOrder_checker.go
index 2eb7cf7d8..98cabc54f 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/argOrder_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/argOrder_checker.go
@@ -20,8 +20,8 @@ func init() {
info.Before = `strings.HasPrefix("#", userpass)`
info.After = `strings.HasPrefix(userpass, "#")`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForExpr(&argOrderChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForExpr(&argOrderChecker{ctx: ctx}), nil
})
}
@@ -34,7 +34,7 @@ func (c *argOrderChecker) VisitExpr(expr ast.Expr) {
call := astcast.ToCallExpr(expr)
// For now only handle functions of 2 args.
- // TODO(Quasilyte): generalize the algorithm and add more patterns.
+ // TODO(quasilyte): generalize the algorithm and add more patterns.
if len(call.Args) != 2 {
return
}
@@ -59,23 +59,22 @@ func (c *argOrderChecker) VisitExpr(expr ast.Expr) {
}
func (c *argOrderChecker) isConstLiteral(x ast.Expr) bool {
- if c.ctx.TypesInfo.Types[x].Value != nil {
- return true
- }
-
// Also permit byte slices.
switch x := x.(type) {
+ case *ast.BasicLit:
+ return true
+
case *ast.CallExpr:
// Handle `[]byte("abc")` as well.
if len(x.Args) != 1 || !astp.IsBasicLit(x.Args[0]) {
return false
}
- typ, ok := c.ctx.TypesInfo.TypeOf(x.Fun).(*types.Slice)
+ typ, ok := c.ctx.TypeOf(x.Fun).(*types.Slice)
return ok && typep.HasUint8Kind(typ.Elem())
case *ast.CompositeLit:
// Check if it's a const byte slice.
- typ, ok := c.ctx.TypesInfo.TypeOf(x).(*types.Slice)
+ typ, ok := c.ctx.TypeOf(x).(*types.Slice)
if !ok || !typep.HasUint8Kind(typ.Elem()) {
return false
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/assignOp_checker.go b/vendor/github.com/go-critic/go-critic/checkers/assignOp_checker.go
index e3acd09ef..d0bf64417 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/assignOp_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/assignOp_checker.go
@@ -19,8 +19,8 @@ func init() {
info.Before = `x = x * 2`
info.After = `x *= 2`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForStmt(&assignOpChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForStmt(&assignOpChecker{ctx: ctx}), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/badCall_checker.go b/vendor/github.com/go-critic/go-critic/checkers/badCall_checker.go
index 3e96a39cb..7435ee57b 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/badCall_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/badCall_checker.go
@@ -17,8 +17,8 @@ func init() {
info.Before = `strings.Replace(s, from, to, 0)`
info.After = `strings.Replace(s, from, to, -1)`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForExpr(&badCallChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForExpr(&badCallChecker{ctx: ctx}), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/badCond_checker.go b/vendor/github.com/go-critic/go-critic/checkers/badCond_checker.go
index 6ce81f358..149f0ac88 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/badCond_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/badCond_checker.go
@@ -29,8 +29,8 @@ for i := 0; i < n; i++ {
xs[i] = 0
}`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForFuncDecl(&badCondChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForFuncDecl(&badCondChecker{ctx: ctx}), nil
})
}
@@ -52,7 +52,7 @@ func (c *badCondChecker) VisitFuncDecl(decl *ast.FuncDecl) {
}
func (c *badCondChecker) checkExpr(expr ast.Expr) {
- // TODO(Quasilyte): recognize more patterns.
+ // TODO(quasilyte): recognize more patterns.
cond := astcast.ToBinaryExpr(expr)
lhs := astcast.ToBinaryExpr(astutil.Unparen(cond.X))
@@ -102,7 +102,7 @@ func (c *badCondChecker) lessAndGreater(lhs, rhs *ast.BinaryExpr) bool {
}
func (c *badCondChecker) checkForStmt(stmt *ast.ForStmt) {
- // TODO(Quasilyte): handle other kinds of bad conditionals.
+ // TODO(quasilyte): handle other kinds of bad conditionals.
init := astcast.ToAssignStmt(stmt.Init)
if init.Tok != token.DEFINE || len(init.Lhs) != 1 || len(init.Rhs) != 1 {
diff --git a/vendor/github.com/go-critic/go-critic/checkers/badLock_checker.go b/vendor/github.com/go-critic/go-critic/checkers/badLock_checker.go
new file mode 100644
index 000000000..8628ff2d7
--- /dev/null
+++ b/vendor/github.com/go-critic/go-critic/checkers/badLock_checker.go
@@ -0,0 +1,116 @@
+package checkers
+
+import (
+ "go/ast"
+
+ "github.com/go-critic/go-critic/checkers/internal/astwalk"
+ "github.com/go-critic/go-critic/framework/linter"
+ "github.com/go-toolsmith/astequal"
+)
+
+func init() {
+ var info linter.CheckerInfo
+ info.Name = "badLock"
+ info.Tags = []string{"diagnostic", "experimental"}
+ info.Summary = "Detects suspicious mutex lock/unlock operations"
+ info.Before = `
+mu.Lock()
+mu.Unlock()`
+ info.After = `
+mu.Lock()
+defer mu.Unlock()`
+
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForStmtList(&badLockChecker{ctx: ctx}), nil
+ })
+}
+
+type badLockChecker struct {
+ astwalk.WalkHandler
+ ctx *linter.CheckerContext
+}
+
+func (c *badLockChecker) VisitStmtList(list []ast.Stmt) {
+ if len(list) < 2 {
+ return
+ }
+
+ for i := 0; i < len(list)-1; i++ {
+ current, ok := list[i].(*ast.ExprStmt)
+ if !ok {
+ continue
+ }
+ deferred := false
+ var next ast.Expr
+ switch x := list[i+1].(type) {
+ case *ast.ExprStmt:
+ next = x.X
+ case *ast.DeferStmt:
+ next = x.Call
+ deferred = true
+ default:
+ continue
+ }
+
+ mutex1, lockFunc, ok := c.asLockedMutex(current.X)
+ if !ok {
+ continue
+ }
+ mutex2, unlockFunc, ok := c.asUnlockedMutex(next)
+ if !ok {
+ continue
+ }
+ if !astequal.Expr(mutex1, mutex2) {
+ continue
+ }
+
+ switch {
+ case !deferred:
+ c.warnImmediateUnlock(mutex2)
+ case lockFunc == "Lock" && unlockFunc == "RUnlock":
+ c.warnMismatchingUnlock(mutex2, "Unlock")
+ case lockFunc == "RLock" && unlockFunc == "Unlock":
+ c.warnMismatchingUnlock(mutex2, "RUnlock")
+ }
+ }
+}
+
+func (c *badLockChecker) asLockedMutex(e ast.Expr) (ast.Expr, string, bool) {
+ call, ok := e.(*ast.CallExpr)
+ if !ok || len(call.Args) != 0 {
+ return nil, "", false
+ }
+ switch fn := call.Fun.(type) {
+ case *ast.SelectorExpr:
+ if fn.Sel.Name == "Lock" || fn.Sel.Name == "RLock" {
+ return fn.X, fn.Sel.Name, true
+ }
+ return nil, "", false
+ default:
+ return nil, "", false
+ }
+}
+
+func (c *badLockChecker) asUnlockedMutex(e ast.Expr) (ast.Expr, string, bool) {
+ call, ok := e.(*ast.CallExpr)
+ if !ok || len(call.Args) != 0 {
+ return nil, "", false
+ }
+ switch fn := call.Fun.(type) {
+ case *ast.SelectorExpr:
+ if fn.Sel.Name == "Unlock" || fn.Sel.Name == "RUnlock" {
+ return fn.X, fn.Sel.Name, true
+ }
+ return nil, "", false
+ default:
+ return nil, "", false
+ }
+}
+
+func (c *badLockChecker) warnImmediateUnlock(cause ast.Node) {
+ c.ctx.Warn(cause, "defer is missing, mutex is unlocked immediately")
+}
+
+func (c *badLockChecker) warnMismatchingUnlock(cause ast.Node, suggestion string) {
+ c.ctx.Warn(cause, "suspicious unlock, maybe %s was intended?", suggestion)
+}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/badRegexp_checker.go b/vendor/github.com/go-critic/go-critic/checkers/badRegexp_checker.go
index 1025454df..e0d4b7487 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/badRegexp_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/badRegexp_checker.go
@@ -21,13 +21,13 @@ func init() {
info.Before = "regexp.MustCompile(`(?:^aa|bb|cc)foo[aba]`)"
info.After = "regexp.MustCompile(`^(?:aa|bb|cc)foo[ab]`)"
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
opts := &syntax.ParserOptions{}
c := &badRegexpChecker{
ctx: ctx,
parser: syntax.NewParser(opts),
}
- return astwalk.WalkerForExpr(c)
+ return astwalk.WalkerForExpr(c), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/boolExprSimplify_checker.go b/vendor/github.com/go-critic/go-critic/checkers/boolExprSimplify_checker.go
index 8c599031d..325fb56a3 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/boolExprSimplify_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/boolExprSimplify_checker.go
@@ -29,8 +29,8 @@ b := !(x) == !(y)`
a := elapsed < expectElapsedMin
b := (x) == (y)`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForExpr(&boolExprSimplifyChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForExpr(&boolExprSimplifyChecker{ctx: ctx}), nil
})
}
@@ -47,7 +47,7 @@ func (c *boolExprSimplifyChecker) VisitExpr(x ast.Expr) {
// Throw away non-bool expressions and avoid redundant
// AST copying below.
- if typ := c.ctx.TypesInfo.TypeOf(x); typ == nil || !typep.HasBoolKind(typ.Underlying()) {
+ if typ := c.ctx.TypeOf(x); typ == nil || !typep.HasBoolKind(typ.Underlying()) {
return
}
@@ -55,8 +55,8 @@ func (c *boolExprSimplifyChecker) VisitExpr(x ast.Expr) {
// this is why we record valuable info before doing it.
c.hasFloats = lintutil.ContainsNode(x, func(n ast.Node) bool {
if x, ok := n.(*ast.BinaryExpr); ok {
- return typep.HasFloatProp(c.ctx.TypesInfo.TypeOf(x.X).Underlying()) ||
- typep.HasFloatProp(c.ctx.TypesInfo.TypeOf(x.Y).Underlying())
+ return typep.HasFloatProp(c.ctx.TypeOf(x.X).Underlying()) ||
+ typep.HasFloatProp(c.ctx.TypeOf(x.Y).Underlying())
}
return false
})
@@ -289,7 +289,8 @@ func (c *boolExprSimplifyChecker) foldRanges(cur *astutil.Cursor) bool {
// `x >= c && x <= c` => `x == c`
{token.GEQ, token.LEQ, 0, 0},
}
- for _, comb := range combTable {
+ for i := range combTable {
+ comb := combTable[i]
if match(&comb) {
lhs.Op = token.EQL
v := c1 + comb.resDelta
@@ -310,7 +311,8 @@ func (c *boolExprSimplifyChecker) foldRanges(cur *astutil.Cursor) bool {
// `x <= c || x >= c+2` => `x != c+1`
{token.LEQ, token.GEQ, 2, 1},
}
- for _, comb := range combTable {
+ for i := range combTable {
+ comb := combTable[i]
if match(&comb) {
lhs.Op = token.NEQ
v := c1 + comb.resDelta
@@ -325,7 +327,7 @@ func (c *boolExprSimplifyChecker) foldRanges(cur *astutil.Cursor) bool {
}
func (c *boolExprSimplifyChecker) int64val(x ast.Expr) (int64, bool) {
- // TODO(Quasilyte): if we had types info, we could use TypesInfo.Types[x].Value,
+ // TODO(quasilyte): if we had types info, we could use TypesInfo.Types[x].Value,
// but since copying erases leaves us without it, only basic literals are handled.
lit, ok := x.(*ast.BasicLit)
if !ok {
diff --git a/vendor/github.com/go-critic/go-critic/checkers/builtinShadowDecl_checker.go b/vendor/github.com/go-critic/go-critic/checkers/builtinShadowDecl_checker.go
new file mode 100644
index 000000000..94d51a996
--- /dev/null
+++ b/vendor/github.com/go-critic/go-critic/checkers/builtinShadowDecl_checker.go
@@ -0,0 +1,63 @@
+package checkers
+
+import (
+ "go/ast"
+
+ "github.com/go-critic/go-critic/checkers/internal/astwalk"
+ "github.com/go-critic/go-critic/framework/linter"
+)
+
+func init() {
+ var info linter.CheckerInfo
+ info.Name = "builtinShadowDecl"
+ info.Tags = []string{"diagnostic", "experimental"}
+ info.Summary = "Detects top-level declarations that shadow the predeclared identifiers"
+ info.Before = `type int struct {}`
+ info.After = `type myInt struct {}`
+
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return &builtinShadowDeclChecker{ctx: ctx}, nil
+ })
+}
+
+type builtinShadowDeclChecker struct {
+ astwalk.WalkHandler
+ ctx *linter.CheckerContext
+}
+
+func (c *builtinShadowDeclChecker) WalkFile(f *ast.File) {
+ for _, decl := range f.Decls {
+ switch decl := decl.(type) {
+ case *ast.FuncDecl:
+ // Don't check methods. They can shadow anything safely.
+ if decl.Recv == nil {
+ c.checkName(decl.Name)
+ }
+ case *ast.GenDecl:
+ c.visitGenDecl(decl)
+ }
+ }
+}
+
+func (c *builtinShadowDeclChecker) visitGenDecl(decl *ast.GenDecl) {
+ for _, spec := range decl.Specs {
+ switch spec := spec.(type) {
+ case *ast.ValueSpec:
+ for _, name := range spec.Names {
+ c.checkName(name)
+ }
+ case *ast.TypeSpec:
+ c.checkName(spec.Name)
+ }
+ }
+}
+
+func (c *builtinShadowDeclChecker) checkName(name *ast.Ident) {
+ if isBuiltin(name.Name) {
+ c.warn(name)
+ }
+}
+
+func (c *builtinShadowDeclChecker) warn(ident *ast.Ident) {
+ c.ctx.Warn(ident, "shadowing of predeclared identifier: %s", ident)
+}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/builtinShadow_checker.go b/vendor/github.com/go-critic/go-critic/checkers/builtinShadow_checker.go
index ff5e51746..1e1661deb 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/builtinShadow_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/builtinShadow_checker.go
@@ -11,12 +11,12 @@ func init() {
var info linter.CheckerInfo
info.Name = "builtinShadow"
info.Tags = []string{"style", "opinionated"}
- info.Summary = "Detects when predeclared identifiers shadowed in assignments"
+ info.Summary = "Detects when predeclared identifiers are shadowed in assignments"
info.Before = `len := 10`
info.After = `length := 10`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForLocalDef(&builtinShadowChecker{ctx: ctx}, ctx.TypesInfo)
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForLocalDef(&builtinShadowChecker{ctx: ctx}, ctx.TypesInfo), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/captLocal_checker.go b/vendor/github.com/go-critic/go-critic/checkers/captLocal_checker.go
index 76b6fb4fc..d9b4b7e75 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/captLocal_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/captLocal_checker.go
@@ -21,10 +21,10 @@ func init() {
info.Before = `func f(IN int, OUT *int) (ERR error) {}`
info.After = `func f(in int, out *int) (err error) {}`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
c := &captLocalChecker{ctx: ctx}
c.paramsOnly = info.Params.Bool("paramsOnly")
- return astwalk.WalkerForLocalDef(c, ctx.TypesInfo)
+ return astwalk.WalkerForLocalDef(c, ctx.TypesInfo), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/caseOrder_checker.go b/vendor/github.com/go-critic/go-critic/checkers/caseOrder_checker.go
index 950367520..047ea4fee 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/caseOrder_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/caseOrder_checker.go
@@ -28,8 +28,8 @@ case ast.Expr:
fmt.Println("expr")
}`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForStmt(&caseOrderChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForStmt(&caseOrderChecker{ctx: ctx}), nil
})
}
@@ -56,9 +56,9 @@ func (c *caseOrderChecker) checkTypeSwitch(s *ast.TypeSwitchStmt) {
for _, cc := range s.Body.List {
cc := cc.(*ast.CaseClause)
for _, x := range cc.List {
- typ := c.ctx.TypesInfo.TypeOf(x)
- if typ == nil {
- c.warnTypeImpl(cc, x)
+ typ := c.ctx.TypeOf(x)
+ if typ == linter.UnknownType {
+ c.warnUnknownType(cc, x)
return
}
for _, iface := range ifaces {
@@ -78,11 +78,11 @@ func (c *caseOrderChecker) warnTypeSwitch(cause, concrete, iface ast.Node) {
c.ctx.Warn(cause, "case %s must go before the %s case", concrete, iface)
}
-func (c *caseOrderChecker) warnTypeImpl(cause, concrete ast.Node) {
+func (c *caseOrderChecker) warnUnknownType(cause, concrete ast.Node) {
c.ctx.Warn(cause, "type is not defined %s", concrete)
}
func (c *caseOrderChecker) checkSwitch(s *ast.SwitchStmt) {
- // TODO(Quasilyte): can handle expression cases that overlap.
+ // TODO(quasilyte): can handle expression cases that overlap.
// Cases that have narrower value range should go before wider ones.
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/codegenComment_checker.go b/vendor/github.com/go-critic/go-critic/checkers/codegenComment_checker.go
index ecadba10e..52a72d28c 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/codegenComment_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/codegenComment_checker.go
@@ -17,7 +17,7 @@ func init() {
info.Before = `// This file was automatically generated by foogen`
info.After = `// Code generated by foogen. DO NOT EDIT.`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
patterns := []string{
"this (?:file|code) (?:was|is) auto(?:matically)? generated",
"this (?:file|code) (?:was|is) generated automatically",
@@ -26,13 +26,13 @@ func init() {
"this (?:file|code) (?:was|is) generated",
"code in this file (?:was|is) auto(?:matically)? generated",
"generated (?:file|code) - do not edit",
- // TODO(Quasilyte): more of these.
+ // TODO(quasilyte): more of these.
}
re := regexp.MustCompile("(?i)" + strings.Join(patterns, "|"))
return &codegenCommentChecker{
ctx: ctx,
badCommentRE: re,
- }
+ }, nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/commentFormatting_checker.go b/vendor/github.com/go-critic/go-critic/checkers/commentFormatting_checker.go
index de7bfc198..83b6d506e 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/commentFormatting_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/commentFormatting_checker.go
@@ -19,11 +19,11 @@ func init() {
info.Before = `//This is a comment`
info.After = `// This is a comment`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
parts := []string{
`^//go:generate .*$`, // e.g.: go:generate value
`^//\w+:.*$`, // e.g.: key: value
- `^//nolint$`, // e.g.: nolint
+ `^//nolint\b`, // e.g.: nolint
`^//line /.*:\d+`, // e.g.: line /path/to/file:123
`^//export \w+$`, // e.g.: export Foo
}
@@ -32,7 +32,7 @@ func init() {
return astwalk.WalkerForComment(&commentFormattingChecker{
ctx: ctx,
pragmaRE: pragmaRE,
- })
+ }), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/commentedOutCode_checker.go b/vendor/github.com/go-critic/go-critic/checkers/commentedOutCode_checker.go
index 8d9387045..554e0621f 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/commentedOutCode_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/commentedOutCode_checker.go
@@ -22,11 +22,11 @@ func init() {
foo(1, 2)`
info.After = `foo(1, 2)`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
return astwalk.WalkerForLocalComment(&commentedOutCodeChecker{
ctx: ctx,
notQuiteFuncCall: regexp.MustCompile(`\w+\s+\([^)]*\)\s*$`),
- })
+ }), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/commentedOutImport_checker.go b/vendor/github.com/go-critic/go-critic/checkers/commentedOutImport_checker.go
index 096a90241..3c086569b 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/commentedOutImport_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/commentedOutImport_checker.go
@@ -24,12 +24,12 @@ import (
"fmt"
)`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
const pattern = `(?m)^(?://|/\*)?\s*"([a-zA-Z0-9_/]+)"\s*(?:\*/)?$`
return &commentedOutImportChecker{
ctx: ctx,
importStringRE: regexp.MustCompile(pattern),
- }
+ }, nil
})
}
@@ -41,7 +41,7 @@ type commentedOutImportChecker struct {
}
func (c *commentedOutImportChecker) WalkFile(f *ast.File) {
- // TODO(Quasilyte): handle commented-out import spec,
+ // TODO(quasilyte): handle commented-out import spec,
// for example: // import "errors".
for _, decl := range f.Decls {
diff --git a/vendor/github.com/go-critic/go-critic/checkers/defaultCaseOrder_checker.go b/vendor/github.com/go-critic/go-critic/checkers/defaultCaseOrder_checker.go
index 755449e07..e06944d62 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/defaultCaseOrder_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/defaultCaseOrder_checker.go
@@ -31,8 +31,8 @@ default: // <- last case (could also be the first one)
// ...
}`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForStmt(&defaultCaseOrderChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForStmt(&defaultCaseOrderChecker{ctx: ctx}), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/deferUnlambda_checker.go b/vendor/github.com/go-critic/go-critic/checkers/deferUnlambda_checker.go
index 3cab7827c..b312bfb68 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/deferUnlambda_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/deferUnlambda_checker.go
@@ -17,8 +17,8 @@ func init() {
info.Before = `defer func() { f() }()`
info.After = `f()`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForStmt(&deferUnlambdaChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForStmt(&deferUnlambdaChecker{ctx: ctx}), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/deprecatedComment_checker.go b/vendor/github.com/go-critic/go-critic/checkers/deprecatedComment_checker.go
index 82f300b37..f60e58b58 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/deprecatedComment_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/deprecatedComment_checker.go
@@ -21,7 +21,7 @@ func FuncOld() int`
// Deprecated: use FuncNew instead
func FuncOld() int`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
c := &deprecatedCommentChecker{ctx: ctx}
c.commonPatterns = []*regexp.Regexp{
@@ -55,7 +55,7 @@ func FuncOld() int`
c.commonTypos[i] = strings.ToUpper(c.commonTypos[i])
}
- return astwalk.WalkerForDocComment(c)
+ return astwalk.WalkerForDocComment(c), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/docStub_checker.go b/vendor/github.com/go-critic/go-critic/checkers/docStub_checker.go
index 2a3b393a0..d8aaaf743 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/docStub_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/docStub_checker.go
@@ -26,13 +26,13 @@ func Foo() {}
// Foo is a demonstration-only function.
func Foo() {}`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
re := `(?i)^\.\.\.$|^\.$|^xxx\.?$|^whatever\.?$`
c := &docStubChecker{
ctx: ctx,
stubCommentRE: regexp.MustCompile(re),
}
- return c
+ return c, nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/dupArg_checker.go b/vendor/github.com/go-critic/go-critic/checkers/dupArg_checker.go
index 24e921b09..9f116d781 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/dupArg_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/dupArg_checker.go
@@ -18,7 +18,7 @@ func init() {
info.Before = `copy(dst, dst)`
info.After = `copy(dst, src)`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
c := &dupArgChecker{ctx: ctx}
// newMatcherFunc returns a function that matches a call if
// args[xIndex] and args[yIndex] are equal.
@@ -95,7 +95,7 @@ func init() {
// TODO(quasilyte): more of these.
}
- return astwalk.WalkerForExpr(c)
+ return astwalk.WalkerForExpr(c), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/dupBranchBody_checker.go b/vendor/github.com/go-critic/go-critic/checkers/dupBranchBody_checker.go
index 3399f0531..83de50528 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/dupBranchBody_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/dupBranchBody_checker.go
@@ -26,8 +26,8 @@ if cond {
println("cond=false")
}`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForStmt(&dupBranchBodyChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForStmt(&dupBranchBodyChecker{ctx: ctx}), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/dupCase_checker.go b/vendor/github.com/go-critic/go-critic/checkers/dupCase_checker.go
index 89ec66bbf..0c1962682 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/dupCase_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/dupCase_checker.go
@@ -22,8 +22,8 @@ switch x {
case ys[0], ys[1], ys[2], ys[3], ys[4]:
}`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForStmt(&dupCaseChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForStmt(&dupCaseChecker{ctx: ctx}), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/dupImports_checker.go b/vendor/github.com/go-critic/go-critic/checkers/dupImports_checker.go
index 27b796cdc..54658eb9f 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/dupImports_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/dupImports_checker.go
@@ -22,8 +22,8 @@ import(
"fmt"
)`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return &dupImportChecker{ctx: ctx}
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return &dupImportChecker{ctx: ctx}, nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/dupSubExpr_checker.go b/vendor/github.com/go-critic/go-critic/checkers/dupSubExpr_checker.go
index 4966cd2a5..00f8fd0eb 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/dupSubExpr_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/dupSubExpr_checker.go
@@ -25,7 +25,7 @@ sort.Slice(xs, func(i, j int) bool {
return xs[i].v < xs[j].v
})`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
c := &dupSubExprChecker{ctx: ctx}
ops := []struct {
@@ -59,7 +59,7 @@ sort.Slice(xs, func(i, j int) bool {
}
}
- return astwalk.WalkerForExpr(c)
+ return astwalk.WalkerForExpr(c), nil
})
}
@@ -93,7 +93,7 @@ func (c *dupSubExprChecker) checkBinaryExpr(expr *ast.BinaryExpr) {
}
func (c *dupSubExprChecker) resultIsFloat(expr ast.Expr) bool {
- typ, ok := c.ctx.TypesInfo.TypeOf(expr).(*types.Basic)
+ typ, ok := c.ctx.TypeOf(expr).(*types.Basic)
return ok && typ.Info()&types.IsFloat != 0
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/elseif_checker.go b/vendor/github.com/go-critic/go-critic/checkers/elseif_checker.go
index 9e56d1c40..d017ee6ca 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/elseif_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/elseif_checker.go
@@ -30,10 +30,10 @@ if cond1 {
} else if x := cond2; x {
}`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
c := &elseifChecker{ctx: ctx}
c.skipBalanced = info.Params.Bool("skipBalanced")
- return astwalk.WalkerForStmt(c)
+ return astwalk.WalkerForStmt(c), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/emptyFallthrough_checker.go b/vendor/github.com/go-critic/go-critic/checkers/emptyFallthrough_checker.go
index 16bfa7e45..2a995b758 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/emptyFallthrough_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/emptyFallthrough_checker.go
@@ -24,8 +24,8 @@ case reflect.Int, reflect.Int32:
return Int
}`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForStmt(&emptyFallthroughChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForStmt(&emptyFallthroughChecker{ctx: ctx}), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/emptyStringTest_checker.go b/vendor/github.com/go-critic/go-critic/checkers/emptyStringTest_checker.go
index 20d647ffa..27ccbd2f2 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/emptyStringTest_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/emptyStringTest_checker.go
@@ -20,8 +20,8 @@ func init() {
info.After = `s == ""`
info.Note = "See https://dmitri.shuralyov.com/idiomatic-go#empty-string-check."
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForExpr(&emptyStringTestChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForExpr(&emptyStringTestChecker{ctx: ctx}), nil
})
}
@@ -40,7 +40,7 @@ func (c *emptyStringTestChecker) VisitExpr(e ast.Expr) {
return
}
s := lenCall.Args[0]
- if !typep.HasStringProp(c.ctx.TypesInfo.TypeOf(s)) {
+ if !typep.HasStringProp(c.ctx.TypeOf(s)) {
return
}
zero := astcast.ToBasicLit(cmp.Y)
diff --git a/vendor/github.com/go-critic/go-critic/checkers/equalFold_checker.go b/vendor/github.com/go-critic/go-critic/checkers/equalFold_checker.go
index b8dfdc02f..13f7fdbe2 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/equalFold_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/equalFold_checker.go
@@ -18,8 +18,8 @@ func init() {
info.Before = `strings.ToLower(x) == strings.ToLower(y)`
info.After = `strings.EqualFold(x, y)`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForExpr(&equalFoldChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForExpr(&equalFoldChecker{ctx: ctx}), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/evalOrder_checker.go b/vendor/github.com/go-critic/go-critic/checkers/evalOrder_checker.go
index 0bec0e83a..6ba07fe86 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/evalOrder_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/evalOrder_checker.go
@@ -24,8 +24,8 @@ err := f(&x)
return x, err
`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForStmt(&evalOrderChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForStmt(&evalOrderChecker{ctx: ctx}), nil
})
}
@@ -75,7 +75,7 @@ func (c *evalOrderChecker) VisitStmt(stmt ast.Stmt) {
}
func (c *evalOrderChecker) hasPtrRecv(fn *ast.Ident) bool {
- sig, ok := c.ctx.TypesInfo.TypeOf(fn).(*types.Signature)
+ sig, ok := c.ctx.TypeOf(fn).(*types.Signature)
if !ok {
return false
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/exitAfterDefer_checker.go b/vendor/github.com/go-critic/go-critic/checkers/exitAfterDefer_checker.go
index 65800fc54..63e0049f2 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/exitAfterDefer_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/exitAfterDefer_checker.go
@@ -27,8 +27,8 @@ if bad {
return
}`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForFuncDecl(&exitAfterDeferChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForFuncDecl(&exitAfterDeferChecker{ctx: ctx}), nil
})
}
@@ -38,7 +38,7 @@ type exitAfterDeferChecker struct {
}
func (c *exitAfterDeferChecker) VisitFuncDecl(fn *ast.FuncDecl) {
- // TODO(Quasilyte): handle goto and other kinds of flow that break
+ // TODO(quasilyte): handle goto and other kinds of flow that break
// the algorithm below that expects the latter statement to be
// executed after the ones that come before it.
@@ -52,6 +52,14 @@ func (c *exitAfterDeferChecker) VisitFuncDecl(fn *ast.FuncDecl) {
case *ast.DeferStmt:
deferStmt = n
case *ast.CallExpr:
+ // See #995. We allow `defer os.Exit()` calls
+ // as it's harder to determine whether they're going
+ // to clutter anything without actually trying to
+ // simulate the defer stack + understanding the control flow.
+ // TODO: can we use CFG here?
+ if _, ok := cur.Parent().(*ast.DeferStmt); ok {
+ return true
+ }
if deferStmt != nil {
switch qualifiedName(n.Fun) {
case "log.Fatal", "log.Fatalf", "log.Fatalln", "os.Exit":
@@ -72,5 +80,5 @@ func (c *exitAfterDeferChecker) warn(cause *ast.CallExpr, deferStmt *ast.DeferSt
// collapse the function literals.
s = "defer " + astfmt.Sprint(fnlit.Type) + "{...}(...)"
}
- c.ctx.Warn(cause, "%s clutters `%s`", cause.Fun, s)
+ c.ctx.Warn(cause, "%s will exit, and `%s` will not run", cause.Fun, s)
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/filepathJoin_checker.go b/vendor/github.com/go-critic/go-critic/checkers/filepathJoin_checker.go
index b11dc2470..698f5366d 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/filepathJoin_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/filepathJoin_checker.go
@@ -17,8 +17,8 @@ func init() {
info.Before = `filepath.Join("dir/", filename)`
info.After = `filepath.Join("dir", filename)`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForExpr(&filepathJoinChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForExpr(&filepathJoinChecker{ctx: ctx}), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/flagDeref_checker.go b/vendor/github.com/go-critic/go-critic/checkers/flagDeref_checker.go
index 393274c43..3fe5e52fb 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/flagDeref_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/flagDeref_checker.go
@@ -21,7 +21,7 @@ flag.BoolVar(&b, "b", false, "b docs")`
Dereferencing returned pointers will lead to hard to find errors
where flag values are not updated after flag.Parse().`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
c := &flagDerefChecker{
ctx: ctx,
flagPtrFuncs: map[string]bool{
@@ -35,7 +35,7 @@ where flag values are not updated after flag.Parse().`
"flag.Uint64": true,
},
}
- return astwalk.WalkerForExpr(c)
+ return astwalk.WalkerForExpr(c), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/flagName_checker.go b/vendor/github.com/go-critic/go-critic/checkers/flagName_checker.go
index 36d2e4506..7f6ce3c01 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/flagName_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/flagName_checker.go
@@ -15,12 +15,13 @@ func init() {
var info linter.CheckerInfo
info.Name = "flagName"
info.Tags = []string{"diagnostic"}
- info.Summary = "Detects flag names with whitespace"
+ info.Summary = "Detects suspicious flag names"
info.Before = `b := flag.Bool(" foo ", false, "description")`
info.After = `b := flag.Bool("foo", false, "description")`
+ info.Note = "https://github.com/golang/go/issues/41792"
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForExpr(&flagNameChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForExpr(&flagNameChecker{ctx: ctx}), nil
})
}
@@ -58,11 +59,30 @@ func (c *flagNameChecker) checkFlagName(call *ast.CallExpr, arg ast.Expr) {
return // Non-constant name
}
name := constant.StringVal(cv)
- if strings.Contains(name, " ") {
+ switch {
+ case name == "":
+ c.warnEmpty(call)
+ case strings.HasPrefix(name, "-"):
+ c.warnHypenPrefix(call, name)
+ case strings.Contains(name, "="):
+ c.warnEq(call, name)
+ case strings.Contains(name, " "):
c.warnWhitespace(call, name)
}
}
+func (c *flagNameChecker) warnEmpty(cause ast.Node) {
+ c.ctx.Warn(cause, "empty flag name")
+}
+
+func (c *flagNameChecker) warnHypenPrefix(cause ast.Node, name string) {
+ c.ctx.Warn(cause, "flag name %q should not start with a hypen", name)
+}
+
+func (c *flagNameChecker) warnEq(cause ast.Node, name string) {
+ c.ctx.Warn(cause, "flag name %q should not contain '='", name)
+}
+
func (c *flagNameChecker) warnWhitespace(cause ast.Node, name string) {
c.ctx.Warn(cause, "flag name %q contains whitespace", name)
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/hexLiteral_checker.go b/vendor/github.com/go-critic/go-critic/checkers/hexLiteral_checker.go
index f3f9c535c..ae61a1125 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/hexLiteral_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/hexLiteral_checker.go
@@ -25,8 +25,8 @@ y := 0xff
// (B)
y := 0xFF`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForExpr(&hexLiteralChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForExpr(&hexLiteralChecker{ctx: ctx}), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/hugeParam_checker.go b/vendor/github.com/go-critic/go-critic/checkers/hugeParam_checker.go
index 54be77638..c430431a7 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/hugeParam_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/hugeParam_checker.go
@@ -21,11 +21,11 @@ func init() {
info.Before = `func f(x [1024]int) {}`
info.After = `func f(x *[1024]int) {}`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
return astwalk.WalkerForFuncDecl(&hugeParamChecker{
ctx: ctx,
sizeThreshold: int64(info.Params.Int("sizeThreshold")),
- })
+ }), nil
})
}
@@ -48,7 +48,7 @@ func (c *hugeParamChecker) VisitFuncDecl(decl *ast.FuncDecl) {
func (c *hugeParamChecker) checkParams(params []*ast.Field) {
for _, p := range params {
for _, id := range p.Names {
- typ := c.ctx.TypesInfo.TypeOf(id)
+ typ := c.ctx.TypeOf(id)
size := c.ctx.SizesInfo.Sizeof(typ)
if size >= c.sizeThreshold {
c.warn(id, size)
diff --git a/vendor/github.com/go-critic/go-critic/checkers/ifElseChain_checker.go b/vendor/github.com/go-critic/go-critic/checkers/ifElseChain_checker.go
index 91e1cfb39..b1fcf4147 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/ifElseChain_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/ifElseChain_checker.go
@@ -34,8 +34,8 @@ Permits single else or else-if; repeated else-if or else + else-if
will trigger suggestion to use switch statement.
See [EffectiveGo#switch](https://golang.org/doc/effective_go.html#switch).`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForStmt(&ifElseChainChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForStmt(&ifElseChainChecker{ctx: ctx}), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/importShadow_checker.go b/vendor/github.com/go-critic/go-critic/checkers/importShadow_checker.go
index 60c0ab21e..5ac711fc1 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/importShadow_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/importShadow_checker.go
@@ -19,9 +19,9 @@ filepath := "foo.txt"`
info.After = `
filename := "foo.txt"`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
ctx.Require.PkgObjects = true
- return astwalk.WalkerForLocalDef(&importShadowChecker{ctx: ctx}, ctx.TypesInfo)
+ return astwalk.WalkerForLocalDef(&importShadowChecker{ctx: ctx}, ctx.TypesInfo), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/indexAlloc_checker.go b/vendor/github.com/go-critic/go-critic/checkers/indexAlloc_checker.go
index 733998873..908285c03 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/indexAlloc_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/indexAlloc_checker.go
@@ -18,8 +18,8 @@ func init() {
info.After = `bytes.Index(x, []byte(y))`
info.Note = `See Go issue for details: https://github.com/golang/go/issues/25864`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForExpr(&indexAllocChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForExpr(&indexAllocChecker{ctx: ctx}), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/initClause_checker.go b/vendor/github.com/go-critic/go-critic/checkers/initClause_checker.go
index 91e8816d2..a1b6b2a8a 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/initClause_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/initClause_checker.go
@@ -19,8 +19,8 @@ func init() {
if cond {
}`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForStmt(&initClauseChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForStmt(&initClauseChecker{ctx: ctx}), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/expr_walker.go b/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/expr_walker.go
index 64098b2b7..de66c1081 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/expr_walker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/expr_walker.go
@@ -1,6 +1,8 @@
package astwalk
-import "go/ast"
+import (
+ "go/ast"
+)
type exprWalker struct {
visitor ExprVisitor
diff --git a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/func_decl_walker.go b/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/func_decl_walker.go
index 90d921f6f..c7e3a4371 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/func_decl_walker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/func_decl_walker.go
@@ -1,6 +1,8 @@
package astwalk
-import "go/ast"
+import (
+ "go/ast"
+)
type funcDeclWalker struct {
visitor FuncDeclVisitor
diff --git a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/local_expr_walker.go b/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/local_expr_walker.go
index 951fd97e5..e455b3f8b 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/local_expr_walker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/local_expr_walker.go
@@ -1,6 +1,8 @@
package astwalk
-import "go/ast"
+import (
+ "go/ast"
+)
type localExprWalker struct {
visitor LocalExprVisitor
diff --git a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/stmt_list_walker.go b/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/stmt_list_walker.go
index 1cc0493a4..45c406e7e 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/stmt_list_walker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/stmt_list_walker.go
@@ -1,6 +1,8 @@
package astwalk
-import "go/ast"
+import (
+ "go/ast"
+)
type stmtListWalker struct {
visitor StmtListVisitor
diff --git a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/stmt_walker.go b/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/stmt_walker.go
index 722eeb116..912de867d 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/stmt_walker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/stmt_walker.go
@@ -1,6 +1,8 @@
package astwalk
-import "go/ast"
+import (
+ "go/ast"
+)
type stmtWalker struct {
visitor StmtVisitor
diff --git a/vendor/github.com/go-critic/go-critic/checkers/mapKey_checker.go b/vendor/github.com/go-critic/go-critic/checkers/mapKey_checker.go
index fdbbb45a2..64c2821dd 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/mapKey_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/mapKey_checker.go
@@ -29,8 +29,8 @@ _ = map[string]int{
"bar": 2,
}`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForExpr(&mapKeyChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForExpr(&mapKeyChecker{ctx: ctx}), nil
})
}
@@ -47,7 +47,7 @@ func (c *mapKeyChecker) VisitExpr(expr ast.Expr) {
return
}
- typ, ok := c.ctx.TypesInfo.TypeOf(lit).Underlying().(*types.Map)
+ typ, ok := c.ctx.TypeOf(lit).Underlying().(*types.Map)
if !ok {
return
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/methodExprCall_checker.go b/vendor/github.com/go-critic/go-critic/checkers/methodExprCall_checker.go
index efd631143..2553def14 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/methodExprCall_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/methodExprCall_checker.go
@@ -21,8 +21,8 @@ foo.bar(f)`
info.After = `f := foo{}
f.bar()`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForExpr(&methodExprCallChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForExpr(&methodExprCallChecker{ctx: ctx}), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/nestingReduce_checker.go b/vendor/github.com/go-critic/go-critic/checkers/nestingReduce_checker.go
index de02c7eec..a68acecca 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/nestingReduce_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/nestingReduce_checker.go
@@ -32,10 +32,10 @@ for _, v := range a {
body()
}`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
c := &nestingReduceChecker{ctx: ctx}
c.bodyWidth = info.Params.Int("bodyWidth")
- return astwalk.WalkerForStmt(c)
+ return astwalk.WalkerForStmt(c), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/newDeref_checker.go b/vendor/github.com/go-critic/go-critic/checkers/newDeref_checker.go
index 7b9f02bd3..7e564b70f 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/newDeref_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/newDeref_checker.go
@@ -18,8 +18,8 @@ func init() {
info.Before = `x := *new(bool)`
info.After = `x := false`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForExpr(&newDerefChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForExpr(&newDerefChecker{ctx: ctx}), nil
})
}
@@ -32,7 +32,7 @@ func (c *newDerefChecker) VisitExpr(expr ast.Expr) {
deref := astcast.ToStarExpr(expr)
call := astcast.ToCallExpr(deref.X)
if astcast.ToIdent(call.Fun).Name == "new" {
- typ := c.ctx.TypesInfo.TypeOf(call.Args[0])
+ typ := c.ctx.TypeOf(call.Args[0])
zv := lintutil.ZeroValueOf(astutil.Unparen(call.Args[0]), typ)
if zv != nil {
c.warn(expr, zv)
diff --git a/vendor/github.com/go-critic/go-critic/checkers/nilValReturn_checker.go b/vendor/github.com/go-critic/go-critic/checkers/nilValReturn_checker.go
index 37f964f70..e53ca0cc0 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/nilValReturn_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/nilValReturn_checker.go
@@ -29,8 +29,8 @@ if err != nil {
return err
}`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForStmt(&nilValReturnChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForStmt(&nilValReturnChecker{ctx: ctx}), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/octalLiteral_checker.go b/vendor/github.com/go-critic/go-critic/checkers/octalLiteral_checker.go
index a1d968043..486940452 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/octalLiteral_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/octalLiteral_checker.go
@@ -18,7 +18,7 @@ func init() {
info.Before = `foo(02)`
info.After = `foo(2)`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
c := &octalLiteralChecker{
ctx: ctx,
octFriendlyPkg: map[string]bool{
@@ -26,7 +26,7 @@ func init() {
"io/ioutil": true,
},
}
- return astwalk.WalkerForExpr(c)
+ return astwalk.WalkerForExpr(c), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/offBy1_checker.go b/vendor/github.com/go-critic/go-critic/checkers/offBy1_checker.go
index df20b429a..ece3fdfdb 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/offBy1_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/offBy1_checker.go
@@ -20,8 +20,8 @@ func init() {
info.Before = `xs[len(xs)]`
info.After = `xs[len(xs)-1]`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForExpr(&offBy1Checker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForExpr(&offBy1Checker{ctx: ctx}), nil
})
}
@@ -31,15 +31,15 @@ type offBy1Checker struct {
}
func (c *offBy1Checker) VisitExpr(e ast.Expr) {
- // TODO(Quasilyte): handle more off-by-1 patterns.
- // TODO(Quasilyte): check whether go/analysis can help here.
+ // TODO(quasilyte): handle more off-by-1 patterns.
+ // TODO(quasilyte): check whether go/analysis can help here.
// Detect s[len(s)] expressions that always panic.
// The correct form is s[len(s)-1].
indexExpr := astcast.ToIndexExpr(e)
indexed := indexExpr.X
- if !typep.IsSlice(c.ctx.TypesInfo.TypeOf(indexed)) {
+ if !typep.IsSlice(c.ctx.TypeOf(indexed)) {
return
}
if !typep.SideEffectFree(c.ctx.TypesInfo, indexed) {
diff --git a/vendor/github.com/go-critic/go-critic/checkers/paramTypeCombine_checker.go b/vendor/github.com/go-critic/go-critic/checkers/paramTypeCombine_checker.go
index f9f9d6c5a..8cdad4eee 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/paramTypeCombine_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/paramTypeCombine_checker.go
@@ -16,8 +16,8 @@ func init() {
info.Before = `func foo(a, b int, c, d int, e, f int, g int) {}`
info.After = `func foo(a, b, c, d, e, f, g int) {}`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForFuncDecl(&paramTypeCombineChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForFuncDecl(&paramTypeCombineChecker{ctx: ctx}), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/ptrToRefParam_checker.go b/vendor/github.com/go-critic/go-critic/checkers/ptrToRefParam_checker.go
index 2716fe04b..88c8f4cb3 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/ptrToRefParam_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/ptrToRefParam_checker.go
@@ -16,8 +16,8 @@ func init() {
info.Before = `func f(m *map[string]int) (*chan *int)`
info.After = `func f(m map[string]int) (chan *int)`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForFuncDecl(&ptrToRefParamChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForFuncDecl(&ptrToRefParamChecker{ctx: ctx}), nil
})
}
@@ -35,7 +35,7 @@ func (c *ptrToRefParamChecker) VisitFuncDecl(fn *ast.FuncDecl) {
func (c *ptrToRefParamChecker) checkParams(params []*ast.Field) {
for _, param := range params {
- ptr, ok := c.ctx.TypesInfo.TypeOf(param.Type).(*types.Pointer)
+ ptr, ok := c.ctx.TypeOf(param.Type).(*types.Pointer)
if !ok {
continue
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/rangeExprCopy_checker.go b/vendor/github.com/go-critic/go-critic/checkers/rangeExprCopy_checker.go
index 90b5987ab..5615af467 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/rangeExprCopy_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/rangeExprCopy_checker.go
@@ -36,11 +36,11 @@ for _, x := range &xs { // No copy
}`
info.Note = "See Go issue for details: https://github.com/golang/go/issues/15812."
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
c := &rangeExprCopyChecker{ctx: ctx}
c.sizeThreshold = int64(info.Params.Int("sizeThreshold"))
c.skipTestFuncs = info.Params.Bool("skipTestFuncs")
- return astwalk.WalkerForStmt(c)
+ return astwalk.WalkerForStmt(c), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/rangeValCopy_checker.go b/vendor/github.com/go-critic/go-critic/checkers/rangeValCopy_checker.go
index 57dcc3151..b34aa5c28 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/rangeValCopy_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/rangeValCopy_checker.go
@@ -35,11 +35,11 @@ for i := range xs {
// Loop body.
}`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
c := &rangeValCopyChecker{ctx: ctx}
c.sizeThreshold = int64(info.Params.Int("sizeThreshold"))
c.skipTestFuncs = info.Params.Bool("skipTestFuncs")
- return astwalk.WalkerForStmt(c)
+ return astwalk.WalkerForStmt(c), nil
})
}
@@ -61,7 +61,7 @@ func (c *rangeValCopyChecker) VisitStmt(stmt ast.Stmt) {
if !ok || rng.Value == nil {
return
}
- typ := c.ctx.TypesInfo.TypeOf(rng.Value)
+ typ := c.ctx.TypeOf(rng.Value)
if typ == nil {
return
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/regexpMust_checker.go b/vendor/github.com/go-critic/go-critic/checkers/regexpMust_checker.go
index 411932ee5..600aa73d0 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/regexpMust_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/regexpMust_checker.go
@@ -18,8 +18,8 @@ func init() {
info.Before = `re, _ := regexp.Compile("const pattern")`
info.After = `re := regexp.MustCompile("const pattern")`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForExpr(&regexpMustChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForExpr(&regexpMustChecker{ctx: ctx}), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/regexpPattern_checker.go b/vendor/github.com/go-critic/go-critic/checkers/regexpPattern_checker.go
index 018ab42d1..31dc4aad3 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/regexpPattern_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/regexpPattern_checker.go
@@ -18,7 +18,7 @@ func init() {
info.Before = "regexp.MustCompile(`google.com|yandex.ru`)"
info.After = "regexp.MustCompile(`google\\.com|yandex\\.ru`)"
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
domains := []string{
"com",
"org",
@@ -33,7 +33,7 @@ func init() {
return astwalk.WalkerForExpr(&regexpPatternChecker{
ctx: ctx,
domainRE: domainRE,
- })
+ }), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/regexpSimplify_checker.go b/vendor/github.com/go-critic/go-critic/checkers/regexpSimplify_checker.go
index 10dcb327f..b7dd15948 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/regexpSimplify_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/regexpSimplify_checker.go
@@ -26,7 +26,7 @@ func init() {
// `[[:digit:]] -> \d`
// `[A-Za-z0-9_]` -> `\w`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
opts := &syntax.ParserOptions{
NoLiterals: true,
}
@@ -35,7 +35,7 @@ func init() {
parser: syntax.NewParser(opts),
out: &strings.Builder{},
}
- return astwalk.WalkerForExpr(c)
+ return astwalk.WalkerForExpr(c), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/ruleguard_checker.go b/vendor/github.com/go-critic/go-critic/checkers/ruleguard_checker.go
index d9799102d..19e265887 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/ruleguard_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/ruleguard_checker.go
@@ -2,10 +2,14 @@ package checkers
import (
"bytes"
+ "fmt"
"go/ast"
"go/token"
"io/ioutil"
"log"
+ "os"
+ "path/filepath"
+ "strings"
"github.com/go-critic/go-critic/framework/linter"
"github.com/quasilyte/go-ruleguard/ruleguard"
@@ -18,7 +22,15 @@ func init() {
info.Params = linter.CheckerParams{
"rules": {
Value: "",
- Usage: "path to a gorules file",
+ Usage: "comma-separated list of gorule file paths. Glob patterns such as 'rules-*.go' may be specified",
+ },
+ "debug": {
+ Value: "",
+ Usage: "enable debug for the specified named rules group",
+ },
+ "failOnError": {
+ Value: false,
+ Usage: "If true, panic when the gorule files contain a syntax error. If false, log and skip rules that contain an error",
},
}
info.Summary = "Runs user-defined rules using ruleguard linter"
@@ -27,17 +39,21 @@ func init() {
info.After = `N/A`
info.Note = "See https://github.com/quasilyte/go-ruleguard."
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
return newRuleguardChecker(&info, ctx)
})
}
-func newRuleguardChecker(info *linter.CheckerInfo, ctx *linter.CheckerContext) *ruleguardChecker {
- c := &ruleguardChecker{ctx: ctx}
- rulesFilename := info.Params.String("rules")
- if rulesFilename == "" {
- return c
+func newRuleguardChecker(info *linter.CheckerInfo, ctx *linter.CheckerContext) (*ruleguardChecker, error) {
+ c := &ruleguardChecker{
+ ctx: ctx,
+ debugGroup: info.Params.String("debug"),
}
+ rulesFlag := info.Params.String("rules")
+ if rulesFlag == "" {
+ return c, nil
+ }
+ failOnErrorFlag := info.Params.Bool("failOnError")
// TODO(quasilyte): handle initialization errors better when we make
// a transition to the go/analysis framework.
@@ -45,35 +61,65 @@ func newRuleguardChecker(info *linter.CheckerInfo, ctx *linter.CheckerContext) *
// For now, we log error messages and return a ruleguard checker
// with an empty rules set.
- data, err := ioutil.ReadFile(rulesFilename)
- if err != nil {
- log.Printf("ruleguard init error: %+v", err)
- return c
+ engine := ruleguard.NewEngine()
+ fset := token.NewFileSet()
+ filePatterns := strings.Split(rulesFlag, ",")
+
+ parseContext := &ruleguard.ParseContext{
+ Fset: fset,
}
- fset := token.NewFileSet()
- rset, err := ruleguard.ParseRules(rulesFilename, fset, bytes.NewReader(data))
- if err != nil {
- log.Printf("ruleguard init error: %+v", err)
- return c
+ loaded := 0
+ for _, filePattern := range filePatterns {
+ filenames, err := filepath.Glob(strings.TrimSpace(filePattern))
+ if err != nil {
+ // The only possible returned error is ErrBadPattern, when pattern is malformed.
+ log.Printf("ruleguard init error: %+v", err)
+ continue
+ }
+ for _, filename := range filenames {
+ data, err := ioutil.ReadFile(filename)
+ if err != nil {
+ if failOnErrorFlag {
+ return nil, fmt.Errorf("ruleguard init error: %+v", err)
+ }
+ log.Printf("ruleguard init error: %+v", err)
+ continue
+ }
+ if err := engine.Load(parseContext, filename, bytes.NewReader(data)); err != nil {
+ if failOnErrorFlag {
+ return nil, fmt.Errorf("ruleguard init error: %+v", err)
+ }
+ log.Printf("ruleguard init error: %+v", err)
+ continue
+ }
+ loaded++
+ }
}
- c.rset = rset
- return c
+ if loaded != 0 {
+ c.engine = engine
+ }
+ return c, nil
}
type ruleguardChecker struct {
ctx *linter.CheckerContext
- rset *ruleguard.GoRuleSet
+ debugGroup string
+ engine *ruleguard.Engine
}
func (c *ruleguardChecker) WalkFile(f *ast.File) {
- if c.rset == nil {
+ if c.engine == nil {
return
}
- ctx := &ruleguard.Context{
+ ctx := &ruleguard.RunContext{
+ Debug: c.debugGroup,
+ DebugPrint: func(s string) {
+ fmt.Fprintln(os.Stderr, s)
+ },
Pkg: c.ctx.Pkg,
Types: c.ctx.TypesInfo,
Sizes: c.ctx.SizesInfo,
@@ -85,8 +131,7 @@ func (c *ruleguardChecker) WalkFile(f *ast.File) {
},
}
- err := ruleguard.RunRules(ctx, f, c.rset)
- if err != nil {
+ if err := c.engine.Run(ctx, f); err != nil {
// Normally this should never happen, but since
// we don't have a better mechanism to report errors,
// emit a warning.
diff --git a/vendor/github.com/go-critic/go-critic/checkers/singleCaseSwitch_checker.go b/vendor/github.com/go-critic/go-critic/checkers/singleCaseSwitch_checker.go
index abead3fa2..b369a4344 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/singleCaseSwitch_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/singleCaseSwitch_checker.go
@@ -24,8 +24,8 @@ if x, ok := x.(int); ok {
body()
}`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForStmt(&singleCaseSwitchChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForStmt(&singleCaseSwitchChecker{ctx: ctx}), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/sloppyLen_checker.go b/vendor/github.com/go-critic/go-critic/checkers/sloppyLen_checker.go
index e12545ffe..a08ef0a5c 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/sloppyLen_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/sloppyLen_checker.go
@@ -23,8 +23,8 @@ len(arr) < 0 // Doesn't make sense at all`
len(arr) > 0
len(arr) == 0`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForExpr(&sloppyLenChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForExpr(&sloppyLenChecker{ctx: ctx}), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/sloppyReassign_checker.go b/vendor/github.com/go-critic/go-critic/checkers/sloppyReassign_checker.go
index d099450d1..2f9ac62e1 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/sloppyReassign_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/sloppyReassign_checker.go
@@ -19,8 +19,8 @@ func init() {
info.Before = `if err = f(); err != nil { return err }`
info.After = `if err := f(); err != nil { return err }`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForStmt(&sloppyReassignChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForStmt(&sloppyReassignChecker{ctx: ctx}), nil
})
}
@@ -37,12 +37,12 @@ func (c *sloppyReassignChecker) VisitStmt(stmt ast.Stmt) {
return
}
- // TODO(Quasilyte): is handling of multi-value assignments worthwhile?
+ // TODO(quasilyte): is handling of multi-value assignments worthwhile?
if len(assign.Lhs) != 1 || len(assign.Rhs) != 1 {
return
}
- // TODO(Quasilyte): handle not only the simplest, return-only case.
+ // TODO(quasilyte): handle not only the simplest, return-only case.
body := ifStmt.Body.List
if len(body) != 1 {
return
@@ -54,7 +54,7 @@ func (c *sloppyReassignChecker) VisitStmt(stmt ast.Stmt) {
return
}
- // TODO(Quasilyte): handle not only nil comparisons.
+ // TODO(quasilyte): handle not only nil comparisons.
eqToNil := &ast.BinaryExpr{
Op: token.NEQ,
X: reAssigned,
diff --git a/vendor/github.com/go-critic/go-critic/checkers/sloppyTypeAssert_checker.go b/vendor/github.com/go-critic/go-critic/checkers/sloppyTypeAssert_checker.go
index 4abfcbab4..39b968898 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/sloppyTypeAssert_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/sloppyTypeAssert_checker.go
@@ -25,8 +25,8 @@ function f(r io.Reader) interface{} {
}
`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForExpr(&sloppyTypeAssertChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForExpr(&sloppyTypeAssertChecker{ctx: ctx}), nil
})
}
@@ -41,8 +41,8 @@ func (c *sloppyTypeAssertChecker) VisitExpr(expr ast.Expr) {
return
}
- toType := c.ctx.TypesInfo.TypeOf(expr)
- fromType := c.ctx.TypesInfo.TypeOf(assert.X)
+ toType := c.ctx.TypeOf(expr)
+ fromType := c.ctx.TypeOf(assert.X)
if types.Identical(toType, fromType) {
c.warnIdentical(expr)
diff --git a/vendor/github.com/go-critic/go-critic/checkers/sortSlice_checker.go b/vendor/github.com/go-critic/go-critic/checkers/sortSlice_checker.go
index b80c17873..29550da3f 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/sortSlice_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/sortSlice_checker.go
@@ -21,8 +21,8 @@ func init() {
info.Before = `sort.Slice(xs, func(i, j) bool { return keys[i] < keys[j] })`
info.After = `sort.Slice(kv, func(i, j) bool { return kv[i].key < kv[j].key })`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForExpr(&sortSliceChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForExpr(&sortSliceChecker{ctx: ctx}), nil
})
}
@@ -87,7 +87,7 @@ func (c *sortSliceChecker) VisitExpr(expr ast.Expr) {
}
}
-func (c *sortSliceChecker) paramIdents(e *ast.FuncType) (*ast.Ident, *ast.Ident) {
+func (c *sortSliceChecker) paramIdents(e *ast.FuncType) (ivar, jvar *ast.Ident) {
// Covers both `i, j int` and `i int, j int`.
idents := make([]*ast.Ident, 0, 2)
for _, field := range e.Params.List {
diff --git a/vendor/github.com/go-critic/go-critic/checkers/sqlQuery_checker.go b/vendor/github.com/go-critic/go-critic/checkers/sqlQuery_checker.go
index 697a82ccf..eb3b49d88 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/sqlQuery_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/sqlQuery_checker.go
@@ -17,8 +17,8 @@ func init() {
info.Before = `_, err := db.Query("UPDATE ...")`
info.After = `_, err := db.Exec("UPDATE ...")`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForStmt(&sqlQueryChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForStmt(&sqlQueryChecker{ctx: ctx}), nil
})
}
@@ -49,7 +49,7 @@ func (c *sqlQueryChecker) VisitStmt(stmt ast.Stmt) {
return
}
- if c.typeHasExecMethod(c.ctx.TypesInfo.TypeOf(funcExpr.X)) {
+ if c.typeHasExecMethod(c.ctx.TypeOf(funcExpr.X)) {
c.warnAndSuggestExec(funcExpr)
} else {
c.warnRowsIgnored(funcExpr)
@@ -71,7 +71,7 @@ func (c *sqlQueryChecker) funcIsQuery(funcExpr *ast.SelectorExpr) bool {
// To avoid false positives (unrelated types can have Query method)
// check that the 1st returned type has Row-like name.
- typ, ok := c.ctx.TypesInfo.TypeOf(funcExpr).Underlying().(*types.Signature)
+ typ, ok := c.ctx.TypeOf(funcExpr).Underlying().(*types.Signature)
if !ok || typ.Results() == nil || typ.Results().Len() != 2 {
return false
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/stringXbytes_checker.go b/vendor/github.com/go-critic/go-critic/checkers/stringXbytes_checker.go
index 57e4084f6..bb9f16c07 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/stringXbytes_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/stringXbytes_checker.go
@@ -16,8 +16,8 @@ func init() {
info.Before = `copy(b, []byte(s))`
info.After = `copy(b, s)`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForExpr(&stringXbytes{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForExpr(&stringXbytes{ctx: ctx}), nil
})
}
@@ -28,7 +28,7 @@ type stringXbytes struct {
func (c *stringXbytes) VisitExpr(expr ast.Expr) {
x, ok := expr.(*ast.CallExpr)
- if !ok || qualifiedName(x.Fun) != "copy" {
+ if !ok || qualifiedName(x.Fun) != "copy" || len(x.Args) != 2 {
return
}
@@ -36,7 +36,7 @@ func (c *stringXbytes) VisitExpr(expr ast.Expr) {
byteCast, ok := src.(*ast.CallExpr)
if ok && typep.IsTypeExpr(c.ctx.TypesInfo, byteCast.Fun) &&
- typep.HasStringProp(c.ctx.TypesInfo.TypeOf(byteCast.Args[0])) {
+ typep.HasStringProp(c.ctx.TypeOf(byteCast.Args[0])) {
c.warn(byteCast, byteCast.Args[0])
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/switchTrue_checker.go b/vendor/github.com/go-critic/go-critic/checkers/switchTrue_checker.go
index 5390360c5..0501a0ba1 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/switchTrue_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/switchTrue_checker.go
@@ -21,8 +21,8 @@ switch {
case x > y:
}`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForStmt(&switchTrueChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForStmt(&switchTrueChecker{ctx: ctx}), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/truncateCmp_checker.go b/vendor/github.com/go-critic/go-critic/checkers/truncateCmp_checker.go
index a5b7bdd32..cd2346c78 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/truncateCmp_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/truncateCmp_checker.go
@@ -31,10 +31,10 @@ func f(x int32, int16) bool {
return x < int32(y)
}`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
c := &truncateCmpChecker{ctx: ctx}
c.skipArchDependent = info.Params.Bool("skipArchDependent")
- return astwalk.WalkerForExpr(c)
+ return astwalk.WalkerForExpr(c), nil
})
}
@@ -87,11 +87,11 @@ func (c *truncateCmpChecker) checkCmp(cmpX, cmpY ast.Expr) {
y := cmpY
// Check that both x and y are signed or unsigned int-typed.
- xtyp, ok := c.ctx.TypesInfo.TypeOf(x).Underlying().(*types.Basic)
+ xtyp, ok := c.ctx.TypeOf(x).Underlying().(*types.Basic)
if !ok || xtyp.Info()&types.IsInteger == 0 {
return
}
- ytyp, ok := c.ctx.TypesInfo.TypeOf(y).Underlying().(*types.Basic)
+ ytyp, ok := c.ctx.TypeOf(y).Underlying().(*types.Basic)
if !ok || xtyp.Info() != ytyp.Info() {
return
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/typeAssertChain_checker.go b/vendor/github.com/go-critic/go-critic/checkers/typeAssertChain_checker.go
index 2940e57f9..d87657c3b 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/typeAssertChain_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/typeAssertChain_checker.go
@@ -35,8 +35,8 @@ default:
// Code C, uses x.
}`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForStmt(&typeAssertChainChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForStmt(&typeAssertChainChecker{ctx: ctx}), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/typeDefFirst_checker.go b/vendor/github.com/go-critic/go-critic/checkers/typeDefFirst_checker.go
new file mode 100644
index 000000000..491e71dfd
--- /dev/null
+++ b/vendor/github.com/go-critic/go-critic/checkers/typeDefFirst_checker.go
@@ -0,0 +1,88 @@
+package checkers
+
+import (
+ "go/ast"
+ "go/token"
+
+ "github.com/go-critic/go-critic/checkers/internal/astwalk"
+ "github.com/go-critic/go-critic/framework/linter"
+)
+
+func init() {
+ var info linter.CheckerInfo
+ info.Name = "typeDefFirst"
+ info.Tags = []string{"style", "experimental"}
+ info.Summary = "Detects method declarations preceding the type definition itself"
+ info.Before = `
+func (r rec) Method() {}
+type rec struct{}
+`
+ info.After = `
+type rec struct{}
+func (r rec) Method() {}
+`
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return &typeDefFirstChecker{
+ ctx: ctx,
+ }, nil
+ })
+}
+
+type typeDefFirstChecker struct {
+ astwalk.WalkHandler
+ ctx *linter.CheckerContext
+ trackedTypes map[string]bool
+}
+
+func (c *typeDefFirstChecker) WalkFile(f *ast.File) {
+ if len(f.Decls) == 0 {
+ return
+ }
+
+ c.trackedTypes = make(map[string]bool)
+ for _, decl := range f.Decls {
+ c.walkDecl(decl)
+ }
+}
+
+func (c *typeDefFirstChecker) walkDecl(decl ast.Decl) {
+ switch decl := decl.(type) {
+ case *ast.FuncDecl:
+ if decl.Recv == nil {
+ return
+ }
+ receiver := decl.Recv.List[0]
+ typeName := c.receiverType(receiver.Type)
+ c.trackedTypes[typeName] = true
+
+ case *ast.GenDecl:
+ if decl.Tok != token.TYPE {
+ return
+ }
+ for _, spec := range decl.Specs {
+ spec, ok := spec.(*ast.TypeSpec)
+ if !ok {
+ return
+ }
+ typeName := spec.Name.Name
+ if val, ok := c.trackedTypes[typeName]; ok && val {
+ c.warn(decl, typeName)
+ }
+ }
+ }
+}
+
+func (c *typeDefFirstChecker) receiverType(e ast.Expr) string {
+ switch e := e.(type) {
+ case *ast.StarExpr:
+ return c.receiverType(e.X)
+ case *ast.Ident:
+ return e.Name
+ default:
+ panic("unreachable")
+ }
+}
+
+func (c *typeDefFirstChecker) warn(cause ast.Node, typeName string) {
+ c.ctx.Warn(cause, "definition of type '%s' should appear before its methods", typeName)
+}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/typeSwitchVar_checker.go b/vendor/github.com/go-critic/go-critic/checkers/typeSwitchVar_checker.go
index 2ade4a954..6bbec5037 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/typeSwitchVar_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/typeSwitchVar_checker.go
@@ -34,8 +34,8 @@ default:
return 0
}`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForStmt(&typeSwitchVarChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForStmt(&typeSwitchVarChecker{ctx: ctx}), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/typeUnparen_checker.go b/vendor/github.com/go-critic/go-critic/checkers/typeUnparen_checker.go
index 620d2d797..a3f02e14c 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/typeUnparen_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/typeUnparen_checker.go
@@ -19,8 +19,8 @@ func init() {
info.Before = `type foo [](func([](func())))`
info.After = `type foo []func([]func())`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForTypeExpr(&typeUnparenChecker{ctx: ctx}, ctx.TypesInfo)
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForTypeExpr(&typeUnparenChecker{ctx: ctx}, ctx.TypesInfo), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/underef_checker.go b/vendor/github.com/go-critic/go-critic/checkers/underef_checker.go
index 561270c7c..d0426a9a5 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/underef_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/underef_checker.go
@@ -28,10 +28,10 @@ v := (*a)[5] // only if a is array`
k.field = 5
v := a[5]`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
c := &underefChecker{ctx: ctx}
c.skipRecvDeref = info.Params.Bool("skipRecvDeref")
- return astwalk.WalkerForExpr(c)
+ return astwalk.WalkerForExpr(c), nil
})
}
@@ -69,7 +69,7 @@ func (c *underefChecker) VisitExpr(expr ast.Expr) {
}
func (c *underefChecker) isPtrRecvMethodCall(fn *ast.Ident) bool {
- typ, ok := c.ctx.TypesInfo.TypeOf(fn).(*types.Signature)
+ typ, ok := c.ctx.TypeOf(fn).(*types.Signature)
if ok && typ != nil && typ.Recv() != nil {
_, ok := typ.Recv().Type().(*types.Pointer)
return ok
@@ -104,7 +104,7 @@ func (c *underefChecker) warnArray(expr *ast.IndexExpr) {
// checkStarExpr checks if ast.StarExpr could be simplified.
func (c *underefChecker) checkStarExpr(expr *ast.StarExpr) bool {
- typ, ok := c.ctx.TypesInfo.TypeOf(expr.X).Underlying().(*types.Pointer)
+ typ, ok := c.ctx.TypeOf(expr.X).Underlying().(*types.Pointer)
if !ok {
return false
}
@@ -118,7 +118,7 @@ func (c *underefChecker) checkStarExpr(expr *ast.StarExpr) bool {
}
func (c *underefChecker) checkArray(expr *ast.StarExpr) bool {
- typ, ok := c.ctx.TypesInfo.TypeOf(expr.X).(*types.Pointer)
+ typ, ok := c.ctx.TypeOf(expr.X).(*types.Pointer)
if !ok {
return false
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/unlabelStmt_checker.go b/vendor/github.com/go-critic/go-critic/checkers/unlabelStmt_checker.go
index 83c5b1484..fab864ec5 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/unlabelStmt_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/unlabelStmt_checker.go
@@ -28,8 +28,8 @@ for x := range xs {
}
}`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForStmt(&unlabelStmtChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForStmt(&unlabelStmtChecker{ctx: ctx}), nil
})
}
@@ -42,7 +42,7 @@ func (c *unlabelStmtChecker) EnterFunc(fn *ast.FuncDecl) bool {
if fn.Body == nil {
return false
}
- // TODO(Quasilyte): should not do additional traversal here.
+ // TODO(quasilyte): should not do additional traversal here.
// For now, skip all functions that contain goto statement.
return !lintutil.ContainsNode(fn.Body, func(n ast.Node) bool {
br, ok := n.(*ast.BranchStmt)
diff --git a/vendor/github.com/go-critic/go-critic/checkers/unlambda_checker.go b/vendor/github.com/go-critic/go-critic/checkers/unlambda_checker.go
index 946227c2f..cce995d7a 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/unlambda_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/unlambda_checker.go
@@ -2,12 +2,15 @@ package checkers
import (
"go/ast"
+ "go/token"
"go/types"
"github.com/go-critic/go-critic/checkers/internal/astwalk"
+ "github.com/go-critic/go-critic/checkers/internal/lintutil"
"github.com/go-critic/go-critic/framework/linter"
"github.com/go-toolsmith/astcast"
"github.com/go-toolsmith/astequal"
+ "github.com/go-toolsmith/typep"
)
func init() {
@@ -18,8 +21,8 @@ func init() {
info.Before = `func(x int) int { return fn(x) }`
info.After = `fn`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForExpr(&unlambdaChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForExpr(&unlambdaChecker{ctx: ctx}), nil
})
}
@@ -47,20 +50,38 @@ func (c *unlambdaChecker) VisitExpr(x ast.Expr) {
if isBuiltin(callable) {
return // See #762
}
- if id, ok := result.Fun.(*ast.Ident); ok {
- obj := c.ctx.TypesInfo.ObjectOf(id)
- if _, ok := obj.(*types.Var); ok {
- return // See #888
+ hasVars := lintutil.ContainsNode(result.Fun, func(n ast.Node) bool {
+ id, ok := n.(*ast.Ident)
+ if !ok {
+ return false
}
+ obj, ok := c.ctx.TypesInfo.ObjectOf(id).(*types.Var)
+ if !ok {
+ return false
+ }
+ // Permit only non-pointer struct method values.
+ return !typep.IsStruct(obj.Type().Underlying())
+ })
+ if hasVars {
+ return // See #888 #1007
}
- fnType := c.ctx.TypesInfo.TypeOf(fn)
- resultType := c.ctx.TypesInfo.TypeOf(result.Fun)
+
+ fnType := c.ctx.TypeOf(fn)
+ resultType := c.ctx.TypeOf(result.Fun)
if !types.Identical(fnType, resultType) {
return
}
// Now check that all arguments match the parameters.
n := 0
for _, params := range fn.Type.Params.List {
+ if _, ok := params.Type.(*ast.Ellipsis); ok {
+ if result.Ellipsis == token.NoPos {
+ return
+ }
+ n++
+ continue
+ }
+
for _, id := range params.Names {
if !astequal.Expr(id, result.Args[n]) {
return
diff --git a/vendor/github.com/go-critic/go-critic/checkers/unnamedResult_checker.go b/vendor/github.com/go-critic/go-critic/checkers/unnamedResult_checker.go
index f053842ec..3149d9e87 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/unnamedResult_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/unnamedResult_checker.go
@@ -22,10 +22,10 @@ func init() {
info.Before = `func f() (float64, float64)`
info.After = `func f() (x, y float64)`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
c := &unnamedResultChecker{ctx: ctx}
c.checkExported = info.Params.Bool("checkExported")
- return astwalk.WalkerForFuncDecl(c)
+ return astwalk.WalkerForFuncDecl(c), nil
})
}
@@ -48,7 +48,7 @@ func (c *unnamedResultChecker) VisitFuncDecl(decl *ast.FuncDecl) {
return // Skip named results
}
- typeName := func(x ast.Expr) string { return c.typeName(c.ctx.TypesInfo.TypeOf(x)) }
+ typeName := func(x ast.Expr) string { return c.typeName(c.ctx.TypeOf(x)) }
isError := func(x ast.Expr) bool { return qualifiedName(x) == "error" }
isBool := func(x ast.Expr) bool { return qualifiedName(x) == "bool" }
diff --git a/vendor/github.com/go-critic/go-critic/checkers/unnecessaryBlock_checker.go b/vendor/github.com/go-critic/go-critic/checkers/unnecessaryBlock_checker.go
index acc9fadbf..72807ddbf 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/unnecessaryBlock_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/unnecessaryBlock_checker.go
@@ -22,8 +22,8 @@ x := 1
x := 1
print(x)`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForStmtList(&unnecessaryBlockChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForStmtList(&unnecessaryBlockChecker{ctx: ctx}), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/unnecessaryDefer_checker.go b/vendor/github.com/go-critic/go-critic/checkers/unnecessaryDefer_checker.go
index ee706e099..ef72142a1 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/unnecessaryDefer_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/unnecessaryDefer_checker.go
@@ -22,8 +22,8 @@ func() {
os.Remove(filename)
}`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForFuncDecl(&unnecessaryDeferChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForFuncDecl(&unnecessaryDeferChecker{ctx: ctx}), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/unslice_checker.go b/vendor/github.com/go-critic/go-critic/checkers/unslice_checker.go
index 73f67bc8e..26a4de061 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/unslice_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/unslice_checker.go
@@ -21,8 +21,8 @@ copy(b[:], values...) // b is []byte`
f(s)
copy(b, values...)`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForExpr(&unsliceChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForExpr(&unsliceChecker{ctx: ctx}), nil
})
}
@@ -46,7 +46,7 @@ func (c *unsliceChecker) unslice(expr ast.Expr) ast.Expr {
// because it's only permitted if expr.High is not nil.
return expr
}
- switch c.ctx.TypesInfo.TypeOf(slice.X).(type) {
+ switch c.ctx.TypeOf(slice.X).(type) {
case *types.Slice, *types.Basic:
// Basic kind catches strings, Slice cathes everything else.
return c.unslice(slice.X)
diff --git a/vendor/github.com/go-critic/go-critic/checkers/valSwap_checker.go b/vendor/github.com/go-critic/go-critic/checkers/valSwap_checker.go
index 4dd494ecf..d03e11223 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/valSwap_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/valSwap_checker.go
@@ -21,8 +21,8 @@ tmp := *x
*y = tmp`
info.After = `*x, *y = *y, *x`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForStmtList(&valSwapChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForStmtList(&valSwapChecker{ctx: ctx}), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/weakCond_checker.go b/vendor/github.com/go-critic/go-critic/checkers/weakCond_checker.go
index 1d6ee58ef..831857c41 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/weakCond_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/weakCond_checker.go
@@ -21,8 +21,8 @@ func init() {
info.Before = `xs != nil && xs[0] != nil`
info.After = `len(xs) != 0 && xs[0] != nil`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForExpr(&weakCondChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForExpr(&weakCondChecker{ctx: ctx}), nil
})
}
@@ -46,7 +46,7 @@ func (c *weakCondChecker) VisitExpr(expr ast.Expr) {
// lhs is `x <op> nil`
x := lhs.X
- if !typep.IsSlice(c.ctx.TypesInfo.TypeOf(x)) {
+ if !typep.IsSlice(c.ctx.TypeOf(x)) {
return
}
if astcast.ToIdent(lhs.Y).Name != "nil" {
diff --git a/vendor/github.com/go-critic/go-critic/checkers/whyNoLint_checker.go b/vendor/github.com/go-critic/go-critic/checkers/whyNoLint_checker.go
index cc5c5172e..260039f2b 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/whyNoLint_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/whyNoLint_checker.go
@@ -19,11 +19,11 @@ func init() {
}
re := regexp.MustCompile(`^// *nolint(?::[^ ]+)? *(.*)$`)
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
return astwalk.WalkerForComment(&whyNoLintChecker{
ctx: ctx,
re: re,
- })
+ }), nil
})
}
@@ -44,7 +44,7 @@ func (c whyNoLintChecker) VisitComment(cg *ast.CommentGroup) {
continue
}
- if s := sl[1]; !strings.HasPrefix(s, "//") || len(strings.TrimPrefix(s, "//")) == 0 {
+ if s := sl[1]; !strings.HasPrefix(s, "//") || strings.TrimPrefix(s, "//") == "" {
c.ctx.Warn(cg, "include an explanation for nolint directive")
return
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/wrapperFunc_checker.go b/vendor/github.com/go-critic/go-critic/checkers/wrapperFunc_checker.go
index bc543e648..d474989d0 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/wrapperFunc_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/wrapperFunc_checker.go
@@ -19,7 +19,7 @@ func init() {
info.Before = `wg.Add(-1)`
info.After = `wg.Done()`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
type arg struct {
index int
value string
@@ -190,7 +190,7 @@ func init() {
}
}
- typ := c.ctx.TypesInfo.TypeOf(x)
+ typ := c.ctx.TypeOf(x)
tn, ok := typ.(*types.Named)
if !ok {
return ""
@@ -202,7 +202,7 @@ func init() {
m.typPatterns)
}
- return astwalk.WalkerForExpr(c)
+ return astwalk.WalkerForExpr(c), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/checkers/yodaStyleExpr_checker.go b/vendor/github.com/go-critic/go-critic/checkers/yodaStyleExpr_checker.go
index b4672fcca..c533d143b 100644
--- a/vendor/github.com/go-critic/go-critic/checkers/yodaStyleExpr_checker.go
+++ b/vendor/github.com/go-critic/go-critic/checkers/yodaStyleExpr_checker.go
@@ -18,8 +18,8 @@ func init() {
info.Before = `return nil != ptr`
info.After = `return ptr != nil`
- collection.AddChecker(&info, func(ctx *linter.CheckerContext) linter.FileWalker {
- return astwalk.WalkerForLocalExpr(&yodaStyleExprChecker{ctx: ctx})
+ collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) {
+ return astwalk.WalkerForLocalExpr(&yodaStyleExprChecker{ctx: ctx}), nil
})
}
diff --git a/vendor/github.com/go-critic/go-critic/framework/linter/checkers_db.go b/vendor/github.com/go-critic/go-critic/framework/linter/checkers_db.go
index b4bebe443..0a3fc0292 100644
--- a/vendor/github.com/go-critic/go-critic/framework/linter/checkers_db.go
+++ b/vendor/github.com/go-critic/go-critic/framework/linter/checkers_db.go
@@ -11,7 +11,7 @@ import (
type checkerProto struct {
info *CheckerInfo
- constructor func(*Context) *Checker
+ constructor func(*Context) (*Checker, error)
}
// prototypes is a set of registered checkers that are not yet instantiated.
@@ -31,7 +31,7 @@ func getCheckersInfo() []*CheckerInfo {
return infoList
}
-func addChecker(info *CheckerInfo, constructor func(*CheckerContext) FileWalker) {
+func addChecker(info *CheckerInfo, constructor func(*CheckerContext) (FileWalker, error)) {
if _, ok := prototypes[info.Name]; ok {
panic(fmt.Sprintf("checker with name %q already registered", info.Name))
}
@@ -68,22 +68,23 @@ func addChecker(info *CheckerInfo, constructor func(*CheckerContext) FileWalker)
proto := checkerProto{
info: info,
- constructor: func(ctx *Context) *Checker {
+ constructor: func(ctx *Context) (*Checker, error) {
var c Checker
c.Info = info
c.ctx = CheckerContext{
Context: ctx,
printer: astfmt.NewPrinter(ctx.FileSet),
}
- c.fileWalker = constructor(&c.ctx)
- return &c
+ var err error
+ c.fileWalker, err = constructor(&c.ctx)
+ return &c, err
},
}
prototypes[info.Name] = proto
}
-func newChecker(ctx *Context, info *CheckerInfo) *Checker {
+func newChecker(ctx *Context, info *CheckerInfo) (*Checker, error) {
proto, ok := prototypes[info.Name]
if !ok {
panic(fmt.Sprintf("checker with name %q not registered", info.Name))
@@ -116,7 +117,7 @@ func validateCheckerName(info *CheckerInfo) error {
}
func validateCheckerDocumentation(info *CheckerInfo) error {
- // TODO(Quasilyte): validate documentation.
+ // TODO(quasilyte): validate documentation.
return nil
}
diff --git a/vendor/github.com/go-critic/go-critic/framework/linter/lintpack.go b/vendor/github.com/go-critic/go-critic/framework/linter/lintpack.go
index 1f984d146..5c8662c69 100644
--- a/vendor/github.com/go-critic/go-critic/framework/linter/lintpack.go
+++ b/vendor/github.com/go-critic/go-critic/framework/linter/lintpack.go
@@ -22,7 +22,7 @@ type CheckerCollection struct {
//
// If checker is never needed, for example if it is disabled,
// constructor will not be called.
-func (coll *CheckerCollection) AddChecker(info *CheckerInfo, constructor func(*CheckerContext) FileWalker) {
+func (coll *CheckerCollection) AddChecker(info *CheckerInfo, constructor func(*CheckerContext) (FileWalker, error)) {
if coll == nil {
panic("adding checker to a nil collection")
}
@@ -138,8 +138,9 @@ type Warning struct {
// NewChecker returns initialized checker identified by an info.
// info must be non-nil.
-// Panics if info describes a checker that was not properly registered.
-func NewChecker(ctx *Context, info *CheckerInfo) *Checker {
+// Returns an error if info describes a checker that was not properly registered,
+// or if checker fails to initialize.
+func NewChecker(ctx *Context, info *CheckerInfo) (*Checker, error) {
return newChecker(ctx, info)
}
@@ -238,6 +239,27 @@ func (ctx *CheckerContext) Warn(node ast.Node, format string, args ...interface{
})
}
+// UnknownType is a special sentinel value that is returned from the CheckerContext.TypeOf
+// method instead of the nil type.
+var UnknownType types.Type = types.Typ[types.Invalid]
+
+// TypeOf returns the type of expression x.
+//
+// Unlike TypesInfo.TypeOf, it never returns nil.
+// Instead, it returns the Invalid type as a sentinel UnknownType value.
+func (ctx *CheckerContext) TypeOf(x ast.Expr) types.Type {
+ typ := ctx.TypesInfo.TypeOf(x)
+ if typ != nil {
+ return typ
+ }
+ // Usually it means that some incorrect type info was loaded
+ // or the analyzed package was only partially (?) correct.
+ // To avoid nil pointer panics we can return a sentinel value
+ // that will fail most type assertions as well as kind checks
+ // (if the call side expects a *types.Basic).
+ return UnknownType
+}
+
// FileWalker is an interface every checker should implement.
//
// The WalkFile method is executed for every Go file inside the