diff --git a/.golangci.yml b/.golangci.yml index efec4e1b..5dd21c48 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -41,10 +41,11 @@ linters-settings: - performance - style disabled-checks: - - wrapperFunc - dupImport # https://github.com/go-critic/go-critic/issues/845 - ifElseChain - octalLiteral + - whyNoLint + - wrapperFunc funlen: lines: 100 statements: 50 diff --git a/README.md b/README.md index 211001b1..176664cd 100644 --- a/README.md +++ b/README.md @@ -957,10 +957,11 @@ linters-settings: - performance - style disabled-checks: - - wrapperFunc - dupImport # https://github.com/go-critic/go-critic/issues/845 - ifElseChain - octalLiteral + - whyNoLint + - wrapperFunc funlen: lines: 100 statements: 50 diff --git a/go.mod b/go.mod index 3553df4e..c557911d 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/OpenPeeDeeP/depguard v1.0.1 github.com/bombsimon/wsl/v2 v2.0.0 github.com/fatih/color v1.7.0 - github.com/go-critic/go-critic v0.3.5-0.20190904082202-d79a9f0c64db + github.com/go-critic/go-critic v0.4.0 github.com/go-lintpack/lintpack v0.5.2 github.com/gofrs/flock v0.0.0-20190320160742-5135e617513b github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 diff --git a/go.sum b/go.sum index cad7d5f8..4dd0446a 100644 --- a/go.sum +++ b/go.sum @@ -33,8 +33,8 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-critic/go-critic v0.3.5-0.20190904082202-d79a9f0c64db h1:GYXWx7Vr3+zv833u+8IoXbNnQY0AdXsxAgI0kX7xcwA= -github.com/go-critic/go-critic v0.3.5-0.20190904082202-d79a9f0c64db/go.mod h1:+sE8vrLDS2M0pZkBk0wy6+nLdKexVDrl/jBqQOTDThA= +github.com/go-critic/go-critic v0.4.0 h1:sXD3pix0wDemuPuSlrXpJNNYXlUiKiysLrtPVQmxkzI= +github.com/go-critic/go-critic v0.4.0/go.mod h1:7/14rZGnZbY6E38VEGk2kVhoq6itzc1E68facVDK23g= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-lintpack/lintpack v0.5.2 h1:DI5mA3+eKdWeJ40nU4d6Wc26qmdG8RCi/btYq0TuRN0= github.com/go-lintpack/lintpack v0.5.2/go.mod h1:NwZuYi2nUHho8XEIZ6SIxihrnPoqBTDqfpXvXAN0sXM= @@ -53,6 +53,7 @@ github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CY github.com/go-toolsmith/astfmt v0.0.0-20180903215011-8f8ee99c3086/go.mod h1:mP93XdblcopXwlyN4X4uodxXQhldPGZbcEJIimQHrkg= github.com/go-toolsmith/astfmt v1.0.0 h1:A0vDDXt+vsvLEdbMFJAUBI/uTbRw1ffOPnxsILnFL6k= github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw= +github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21 h1:wP6mXeB2V/d1P1K7bZ5vDUO3YqEzcvOREOxZPEu3gVI= github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU= github.com/go-toolsmith/astp v0.0.0-20180903215135-0af7e3c24f30/go.mod h1:SV2ur98SGypH1UjcPpCatrV5hPazG6+IfNHbkDXBRrk= github.com/go-toolsmith/astp v1.0.0 h1:alXE75TXgcmupDsMK1fRAy0YUzLzqPVvBKoyWV+KPXg= @@ -112,6 +113,7 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= @@ -157,6 +159,7 @@ github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaa github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/goveralls v0.0.2 h1:7eJB6EqsPhRVxvwEXGnqdO2sJI0PTsrWoTMXEk9/OQc= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= @@ -175,6 +178,7 @@ github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -191,6 +195,7 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c h1:JoUA0uz9U0FVFq5p4LjEq4C0VgQ0El320s3Ms0V4eww= github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= diff --git a/vendor/github.com/go-critic/go-critic/checkers/internal/lintutil/lintutil.go b/vendor/github.com/go-critic/go-critic/checkers/internal/lintutil/lintutil.go deleted file mode 100644 index 333543b1..00000000 --- a/vendor/github.com/go-critic/go-critic/checkers/internal/lintutil/lintutil.go +++ /dev/null @@ -1,37 +0,0 @@ -package lintutil - -import ( - "go/ast" - "go/types" -) - -// TODO: this package is a way to reuse code between lint and astwalk. -// Would be good to find it a better name. - -// IsTypeExpr reports whether x represents type expression. -// -// Type expression does not evaluate to any run time value, -// but rather describes type that is used inside Go expression. -// For example, (*T)(v) is a CallExpr that "calls" (*T). -// (*T) is a type expression that tells Go compiler type v should be converted to. -func IsTypeExpr(info *types.Info, x ast.Expr) bool { - switch x := x.(type) { - case *ast.StarExpr: - return IsTypeExpr(info, x.X) - case *ast.ParenExpr: - return IsTypeExpr(info, x.X) - case *ast.SelectorExpr: - return IsTypeExpr(info, x.Sel) - case *ast.Ident: - // Identifier may be a type expression if object - // it reffers to is a type name. - _, ok := info.ObjectOf(x).(*types.TypeName) - return ok - - case *ast.FuncType, *ast.StructType, *ast.InterfaceType, *ast.ArrayType, *ast.MapType: - return true - - default: - return false - } -} 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 new file mode 100644 index 00000000..f4cb9e86 --- /dev/null +++ b/vendor/github.com/go-critic/go-critic/checkers/truncateCmp_checker.go @@ -0,0 +1,117 @@ +package checkers + +import ( + "go/ast" + "go/token" + "go/types" + + "github.com/go-lintpack/lintpack" + "github.com/go-lintpack/lintpack/astwalk" + "github.com/go-toolsmith/astcast" + "github.com/go-toolsmith/astp" +) + +func init() { + var info lintpack.CheckerInfo + info.Name = "truncateCmp" + info.Tags = []string{"diagnostic", "experimental"} + info.Params = lintpack.CheckerParams{ + "skipArchDependent": { + Value: true, + Usage: "whether to skip int/uint/uintptr types", + }, + } + info.Summary = "Detects potential truncation issues when comparing ints of different sizes" + info.Before = ` +func f(x int32, y int16) bool { + return int16(x) < y +}` + info.After = ` +func f(x int32, int16) bool { + return x < int32(y) +}` + + collection.AddChecker(&info, func(ctx *lintpack.CheckerContext) lintpack.FileWalker { + c := &truncateCmpChecker{ctx: ctx} + c.skipArchDependent = info.Params.Bool("skipArchDependent") + return astwalk.WalkerForExpr(c) + }) +} + +type truncateCmpChecker struct { + astwalk.WalkHandler + ctx *lintpack.CheckerContext + + skipArchDependent bool +} + +func (c *truncateCmpChecker) VisitExpr(expr ast.Expr) { + cmp := astcast.ToBinaryExpr(expr) + switch cmp.Op { + case token.LSS, token.GTR, token.LEQ, token.GEQ, token.EQL, token.NEQ: + if astp.IsBasicLit(cmp.X) || astp.IsBasicLit(cmp.Y) { + return // Don't bother about untyped consts + } + leftCast := c.isTruncCast(cmp.X) + rightCast := c.isTruncCast(cmp.Y) + switch { + case leftCast && rightCast: + return + case leftCast: + c.checkCmp(cmp.X, cmp.Y) + case rightCast: + c.checkCmp(cmp.Y, cmp.X) + } + default: + return + } +} + +func (c *truncateCmpChecker) isTruncCast(x ast.Expr) bool { + switch astcast.ToIdent(astcast.ToCallExpr(x).Fun).Name { + case "int8", "int16", "int32", "uint8", "uint16", "uint32": + return true + default: + return false + } +} + +func (c *truncateCmpChecker) checkCmp(cmpX, cmpY ast.Expr) { + // Check if we have a cast to a type that can truncate. + xcast := astcast.ToCallExpr(cmpX) + if len(xcast.Args) != 1 { + return // Just in case of the shadowed builtin + } + + x := xcast.Args[0] + y := cmpY + + // Check that both x and y are signed or unsigned int-typed. + xtyp, ok := c.ctx.TypesInfo.TypeOf(x).Underlying().(*types.Basic) + if !ok || xtyp.Info()&types.IsInteger == 0 { + return + } + ytyp, ok := c.ctx.TypesInfo.TypeOf(y).Underlying().(*types.Basic) + if !ok || xtyp.Info() != ytyp.Info() { + return + } + + xsize := c.ctx.SizesInfo.Sizeof(xtyp) + ysize := c.ctx.SizesInfo.Sizeof(ytyp) + if xsize <= ysize { + return + } + + if c.skipArchDependent { + switch xtyp.Kind() { + case types.Int, types.Uint, types.Uintptr: + return + } + } + + c.warn(xcast, xsize*8, ysize*8, xtyp.String()) +} + +func (c *truncateCmpChecker) warn(cause ast.Expr, xsize, ysize int64, suggest string) { + c.ctx.Warn(cause, "truncation in comparison %d->%d bit; cast the other operand to %s instead", xsize, ysize, suggest) +} 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 846bb14d..9e01299b 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 @@ -47,6 +47,12 @@ 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 + } + } fnType := c.ctx.TypesInfo.TypeOf(fn) resultType := c.ctx.TypesInfo.TypeOf(result.Fun) if !types.Identical(fnType, resultType) { 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 new file mode 100644 index 00000000..52fefb82 --- /dev/null +++ b/vendor/github.com/go-critic/go-critic/checkers/whyNoLint_checker.go @@ -0,0 +1,52 @@ +package checkers + +import ( + "go/ast" + "regexp" + "strings" + + "github.com/go-lintpack/lintpack" + "github.com/go-lintpack/lintpack/astwalk" +) + +func init() { + info := lintpack.CheckerInfo{ + Name: "whyNoLint", + Tags: []string{"style", "experimental"}, + Summary: "Ensures that `//nolint` comments include an explanation", + Before: `//nolint`, + After: `//nolint // reason`, + } + re := regexp.MustCompile(`^// *nolint(?::[^ ]+)? *(.*)$`) + + collection.AddChecker(&info, func(ctx *lintpack.CheckerContext) lintpack.FileWalker { + return astwalk.WalkerForComment(&whyNoLintChecker{ + ctx: ctx, + re: re, + }) + }) +} + +type whyNoLintChecker struct { + astwalk.WalkHandler + + ctx *lintpack.CheckerContext + re *regexp.Regexp +} + +func (c whyNoLintChecker) VisitComment(cg *ast.CommentGroup) { + if strings.HasPrefix(cg.List[0].Text, "/*") { + return + } + for _, comment := range cg.List { + sl := c.re.FindStringSubmatch(comment.Text) + if len(sl) < 2 { + continue + } + + if s := sl[1]; !strings.HasPrefix(s, "//") || len(strings.TrimPrefix(s, "//")) == 0 { + c.ctx.Warn(cg, "include an explanation for nolint directive") + return + } + } +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 63737e1f..47906ae0 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -12,7 +12,7 @@ github.com/davecgh/go-spew/spew github.com/fatih/color # github.com/fsnotify/fsnotify v1.4.7 github.com/fsnotify/fsnotify -# github.com/go-critic/go-critic v0.3.5-0.20190904082202-d79a9f0c64db +# github.com/go-critic/go-critic v0.4.0 github.com/go-critic/go-critic/checkers github.com/go-critic/go-critic/checkers/internal/lintutil # github.com/go-lintpack/lintpack v0.5.2