1package checkers 2 3import ( 4 "go/ast" 5 6 "github.com/go-critic/go-critic/checkers/internal/astwalk" 7 "github.com/go-critic/go-critic/checkers/internal/lintutil" 8 "github.com/go-critic/go-critic/framework/linter" 9 "github.com/go-toolsmith/astcast" 10 "golang.org/x/tools/go/ast/astutil" 11) 12 13func init() { 14 var info linter.CheckerInfo 15 info.Name = "newDeref" 16 info.Tags = []string{"style"} 17 info.Summary = "Detects immediate dereferencing of `new` expressions" 18 info.Before = `x := *new(bool)` 19 info.After = `x := false` 20 21 collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { 22 return astwalk.WalkerForExpr(&newDerefChecker{ctx: ctx}), nil 23 }) 24} 25 26type newDerefChecker struct { 27 astwalk.WalkHandler 28 ctx *linter.CheckerContext 29} 30 31func (c *newDerefChecker) VisitExpr(expr ast.Expr) { 32 deref := astcast.ToStarExpr(expr) 33 call := astcast.ToCallExpr(deref.X) 34 if astcast.ToIdent(call.Fun).Name == "new" { 35 typ := c.ctx.TypeOf(call.Args[0]) 36 zv := lintutil.ZeroValueOf(astutil.Unparen(call.Args[0]), typ) 37 if zv != nil { 38 c.warn(expr, zv) 39 } 40 } 41} 42 43func (c *newDerefChecker) warn(cause, suggestion ast.Expr) { 44 c.ctx.Warn(cause, "replace `%s` with `%s`", cause, suggestion) 45} 46