github.com/amarpal/go-tools@v0.0.0-20240422043104-40142f59f616/staticcheck/sa4013/sa4013.go (about) 1 package sa4013 2 3 import ( 4 "go/ast" 5 6 "github.com/amarpal/go-tools/analysis/code" 7 "github.com/amarpal/go-tools/analysis/edit" 8 "github.com/amarpal/go-tools/analysis/lint" 9 "github.com/amarpal/go-tools/analysis/report" 10 "github.com/amarpal/go-tools/pattern" 11 12 "golang.org/x/tools/go/analysis" 13 "golang.org/x/tools/go/analysis/passes/inspect" 14 ) 15 16 var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{ 17 Analyzer: &analysis.Analyzer{ 18 Name: "SA4013", 19 Run: run, 20 Requires: []*analysis.Analyzer{inspect.Analyzer}, 21 }, 22 Doc: &lint.Documentation{ 23 Title: `Negating a boolean twice (\'!!b\') is the same as writing \'b\'. This is either redundant, or a typo.`, 24 Since: "2017.1", 25 Severity: lint.SeverityWarning, 26 MergeIf: lint.MergeIfAny, 27 }, 28 }) 29 30 var Analyzer = SCAnalyzer.Analyzer 31 32 var checkDoubleNegationQ = pattern.MustParse(`(UnaryExpr "!" single@(UnaryExpr "!" x))`) 33 34 func run(pass *analysis.Pass) (interface{}, error) { 35 fn := func(node ast.Node) { 36 if m, ok := code.Match(pass, checkDoubleNegationQ, node); ok { 37 report.Report(pass, node, "negating a boolean twice has no effect; is this a typo?", report.Fixes( 38 edit.Fix("turn into single negation", edit.ReplaceWithNode(pass.Fset, node, m.State["single"].(ast.Node))), 39 edit.Fix("remove double negation", edit.ReplaceWithNode(pass.Fset, node, m.State["x"].(ast.Node))))) 40 } 41 } 42 code.Preorder(pass, fn, (*ast.UnaryExpr)(nil)) 43 return nil, nil 44 }